OpenStack Block Storage (Cinder)
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

# 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)