Skip to content

Commit

Permalink
Merge "Revert "Remove Huawei FusionStorage Driver""
Browse files Browse the repository at this point in the history
  • Loading branch information
Zuul authored and openstack-gerrit committed Feb 27, 2020
2 parents a154a13 + c79dfa6 commit 9b99ac5
Show file tree
Hide file tree
Showing 14 changed files with 1,769 additions and 7 deletions.
3 changes: 3 additions & 0 deletions cinder/opts.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@
cinder_volume_drivers_dell_emc_xtremio
from cinder.volume.drivers.fujitsu.eternus_dx import eternus_dx_common as \
cinder_volume_drivers_fujitsu_eternus_dx_eternusdxcommon
from cinder.volume.drivers.fusionstorage import dsware as \
cinder_volume_drivers_fusionstorage_dsware
from cinder.volume.drivers.hpe import hpe_3par_common as \
cinder_volume_drivers_hpe_hpe3parcommon
from cinder.volume.drivers.hpe import hpe_lefthand_iscsi as \
Expand Down Expand Up @@ -242,6 +244,7 @@ def list_opts():
cinder_volume_driver.scst_opts,
cinder_volume_driver.backup_opts,
cinder_volume_driver.image_opts,
cinder_volume_drivers_fusionstorage_dsware.volume_opts,
cinder_volume_drivers_infortrend_raidcmd_cli_commoncli.
infortrend_opts,
cinder_volume_drivers_inspur_as13000_as13000driver.
Expand Down
Empty file.
479 changes: 479 additions & 0 deletions cinder/tests/unit/volume/drivers/fusionstorage/test_dsware.py

Large diffs are not rendered by default.

273 changes: 273 additions & 0 deletions cinder/tests/unit/volume/drivers/fusionstorage/test_fs_client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,273 @@
# Copyright (c) 2018 Huawei Technologies Co., Ltd
# All Rights Reserved
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

import json
from unittest import mock

import requests

from cinder import test
from cinder.tests.unit.volume.drivers.fusionstorage import test_utils
from cinder.volume.drivers.fusionstorage import fs_client


class FakeSession(test_utils.FakeBaseSession):
method_map = {
'get': {
'rest/version':
{'currentVersion': 'fake_version'},
'/storagePool$':
{'storagePools': [{'poolName': 'fake_pool_name',
'poolId': 'fake_pool_id'}]},
r'/storagePool\?poolId=0':
{'storagePools': [{'poolName': 'fake_pool_name1',
'poolId': 0}]},
r'/volume/queryByName\?volName=fake_name':
{'errorCode': 0, 'lunDetailInfo':
[{'volume_id': 'fake_id',
'volume_name': 'fake_name'}]},
r'/volume/queryById\?volId=fake_id':
{'errorCode': 0, 'lunDetailInfo':
[{'volume_id': 'fake_id',
'volume_name': 'fake_name'}]},
r'/lun/wwn/list\?wwn=fake_wwn':
{'errorCode': 0, 'lunDetailInfo':
[{'volume_id': 'fake_id',
'volume_wwn': 'fake_wwn'}]},
},
'post': {
'/sec/login': {},
'/sec/logout': {'res': 'fake_logout'},
'/sec/keepAlive': {'res': 'fake_keepAlive'},
'/volume/list': {'errorCode': 0, 'volumeList': [
{'volName': 'fake_name1', 'volId': 'fake_id1'},
{'volName': 'fake_name2', 'volId': 'fake_id2'}]},
'/volume/create': {'ID': 'fake_volume_create_id'},
'/volume/delete': {'ID': 'fake_volume_delete_id'},
'/volume/attach':
{'fake_name': [{'errorCode': '0', 'ip': 'fake_ip'}]},
'/volume/detach/': {'ID': 'fake_volume_detach_id'},
'/volume/expand': {'ID': 'fake_volume_expend_id'},
'/volume/snapshot/list':
{"snapshotList": [{"snapshot": "fake_name",
"size": "fake_size"}]},
'/snapshot/list': {'totalNum': 'fake_snapshot_num',
'snapshotList':
[{'snapName': 'fake_snapName'}]},
'/snapshot/create/': {'ID': 'fake_snapshot_create_id'},
'/snapshot/delete/': {'ID': 'fake_snapshot_delete_id'},
'/snapshot/rollback': {'ID': 'fake_snapshot_delete_id'},
'/snapshot/volume/create/': {'ID': 'fake_vol_from_snap_id'},
}
}


class TestFsclient(test.TestCase):
def setUp(self):
super(TestFsclient, self).setUp()
self.mock_object(requests, 'Session', FakeSession)
self.client = fs_client.RestCommon('https://fake_rest_site',
'fake_user',
'fake_password')
self.client.login()

def tearDown(self):
super(TestFsclient, self).tearDown()

def test_login(self):
self.assertEqual('fake_version',
self.client.version)
self.assertEqual('fake_token',
self.client.session.headers['X-Auth-Token'])

def test_keep_alive(self):
retval = self.client.keep_alive()
self.assertIsNone(retval)

def test_logout(self):
self.assertIsNone(self.client.logout())

def test_query_all_pool_info(self):
with mock.patch.object(self.client.session, 'get',
wraps=self.client.session.get) as mocker:
retval = self.client.query_pool_info()
mocker.assert_called_once_with(
'https://fake_rest_site/dsware/service/'
'fake_version/storagePool', timeout=50)
self.assertListEqual(
[{'poolName': 'fake_pool_name',
'poolId': 'fake_pool_id'}], retval)

def test_query_pool_info(self):
with mock.patch.object(self.client.session, 'get',
wraps=self.client.session.get) as mocker:
retval = self.client.query_pool_info(pool_id=0)
mocker.assert_called_once_with(
'https://fake_rest_site/dsware/service/'
'fake_version/storagePool?poolId=0', timeout=50)
self.assertListEqual(
[{'poolName': 'fake_pool_name1', 'poolId': 0}], retval)

def test_query_volume_by_name(self):
with mock.patch.object(self.client.session, 'get',
wraps=self.client.session.get) as mocker:
retval = self.client.query_volume_by_name(vol_name='fake_name')
mocker.assert_called_once_with(
'https://fake_rest_site/dsware/service/fake_version/'
'volume/queryByName?volName=fake_name', timeout=50)
self.assertListEqual(
[{'volume_id': 'fake_id', 'volume_name': 'fake_name'}], retval)

def test_query_volume_by_id(self):
with mock.patch.object(self.client.session, 'get',
wraps=self.client.session.get) as mocker:
retval = self.client.query_volume_by_id(vol_id='fake_id')
mocker.assert_called_once_with(
'https://fake_rest_site/dsware/service/fake_version/'
'volume/queryById?volId=fake_id', timeout=50)
self.assertListEqual(
[{'volume_id': 'fake_id', 'volume_name': 'fake_name'}], retval)

def test_create_volume(self):
with mock.patch.object(self.client.session, 'post',
wraps=self.client.session.post) as mocker:
retval = self.client.create_volume(
vol_name='fake_name', vol_size=1, pool_id='fake_id')
except_data = json.dumps(
{"volName": "fake_name", "volSize": 1, "poolId": "fake_id"})
mocker.assert_called_once_with(
'https://fake_rest_site/dsware/service/fake_version/'
'volume/create', data=except_data, timeout=50)
self.assertIsNone(retval)

def test_delete_volume(self):
with mock.patch.object(self.client.session, 'post',
wraps=self.client.session.post) as mocker:
retval = self.client.delete_volume(vol_name='fake_name')
except_data = json.dumps({"volNames": ['fake_name']})
mocker.assert_called_once_with(
'https://fake_rest_site/dsware/service/fake_version/'
'volume/delete', data=except_data, timeout=50)
self.assertIsNone(retval)

def test_attach_volume(self):
with mock.patch.object(self.client.session, 'post',
wraps=self.client.session.post) as mocker:
retval = self.client.attach_volume(
vol_name='fake_name', manage_ip='fake_ip')
except_data = json.dumps(
{"volName": ['fake_name'], "ipList": ['fake_ip']})
mocker.assert_called_once_with(
'https://fake_rest_site/dsware/service/fake_version/'
'volume/attach', data=except_data, timeout=50)
self.assertDictEqual(
{'result': 0,
'fake_name': [{'errorCode': '0', 'ip': 'fake_ip'}]},
retval)

def test_detach_volume(self):
with mock.patch.object(self.client.session, 'post',
wraps=self.client.session.post) as mocker:
retval = self.client.detach_volume(
vol_name='fake_name', manage_ip='fake_ip')
except_data = json.dumps(
{"volName": ['fake_name'], "ipList": ['fake_ip']})
mocker.assert_called_once_with(
'https://fake_rest_site/dsware/service/fake_version/'
'volume/detach/', data=except_data, timeout=50)
self.assertIsNone(retval)

def test_expand_volume(self):
with mock.patch.object(self.client.session, 'post',
wraps=self.client.session.post) as mocker:
retval = self.client.expand_volume(
vol_name='fake_name', new_vol_size=2)
except_data = json.dumps({"volName": 'fake_name', "newVolSize": 2})
mocker.assert_called_once_with(
'https://fake_rest_site/dsware/service/fake_version/'
'volume/expand', data=except_data, timeout=50)
self.assertIsNone(retval)

def test_query_snapshot_by_name(self):
with mock.patch.object(self.client.session, 'post',
wraps=self.client.session.post) as mocker:
retval = self.client.query_snapshot_by_name(
pool_id='fake_id', snapshot_name='fake_name')
except_data = json.dumps(
{"poolId": 'fake_id', "pageNum": 1,
"pageSize": 1000, "filters": {"volumeName": 'fake_name'}})
mocker.assert_called_once_with(
'https://fake_rest_site/dsware/service/fake_version/'
'snapshot/list', data=except_data, timeout=50)
self.assertDictEqual(
{'result': 0, 'totalNum': 'fake_snapshot_num',
'snapshotList': [{'snapName': 'fake_snapName'}]}, retval)

def test_create_snapshot(self):
with mock.patch.object(self.client.session, 'post',
wraps=self.client.session.post) as mocker:
retval = self.client.create_snapshot(
snapshot_name='fake_snap', vol_name='fake_name')
except_data = json.dumps(
{"volName": "fake_name", "snapshotName": "fake_snap"})
mocker.assert_called_once_with(
'https://fake_rest_site/dsware/service/fake_version/'
'snapshot/create/', data=except_data, timeout=50)
self.assertIsNone(retval)

def test_delete_snapshot(self):
with mock.patch.object(self.client.session, 'post',
wraps=self.client.session.post) as mocker:
retval = self.client.delete_snapshot(snapshot_name='fake_snap')
except_data = json.dumps({"snapshotName": "fake_snap"})
mocker.assert_called_once_with(
'https://fake_rest_site/dsware/service/fake_version/'
'snapshot/delete/', data=except_data, timeout=50)
self.assertIsNone(retval)

def test_create_volume_from_snapshot(self):
with mock.patch.object(self.client.session, 'post',
wraps=self.client.session.post) as mocker:
retval = self.client.create_volume_from_snapshot(
snapshot_name='fake_snap', vol_name='fake_name', vol_size=2)
except_data = json.dumps({"src": 'fake_snap',
"volName": 'fake_name',
"volSize": 2})
mocker.assert_called_once_with(
'https://fake_rest_site/dsware/service/fake_version/'
'snapshot/volume/create/', data=except_data, timeout=50)
self.assertIsNone(retval)

@mock.patch.object(fs_client.RestCommon, 'create_snapshot')
@mock.patch.object(fs_client.RestCommon, 'create_volume_from_snapshot')
@mock.patch.object(fs_client.RestCommon, 'delete_snapshot')
def test_create_volume_from_volume(
self, mock_delete_snapshot, mock_volume_from_snapshot,
mock_create_snapshot):
vol_name = 'fake_name'
vol_size = 3
src_vol_name = 'src_fake_name'
temp_snapshot_name = "temp" + src_vol_name + "clone" + vol_name

retval = self.client.create_volume_from_volume(
vol_name, vol_size, src_vol_name)
mock_create_snapshot.assert_called_once_with(
vol_name=src_vol_name, snapshot_name=temp_snapshot_name)
mock_volume_from_snapshot.assert_called_once_with(
snapshot_name=temp_snapshot_name,
vol_name=vol_name, vol_size=vol_size)
mock_delete_snapshot.assert_called_once_with(
snapshot_name=temp_snapshot_name)
self.assertIsNone(retval)
Loading

0 comments on commit 9b99ac5

Please sign in to comment.