You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
272 lines
13 KiB
272 lines
13 KiB
# 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 |
|
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)
|
|
|