summaryrefslogtreecommitdiff
path: root/cinder/tests/unit/volume/drivers/hpe/test_hpe3par.py
diff options
context:
space:
mode:
Diffstat (limited to 'cinder/tests/unit/volume/drivers/hpe/test_hpe3par.py')
-rw-r--r--cinder/tests/unit/volume/drivers/hpe/test_hpe3par.py199
1 files changed, 176 insertions, 23 deletions
diff --git a/cinder/tests/unit/volume/drivers/hpe/test_hpe3par.py b/cinder/tests/unit/volume/drivers/hpe/test_hpe3par.py
index 1d1e440cb..018d93694 100644
--- a/cinder/tests/unit/volume/drivers/hpe/test_hpe3par.py
+++ b/cinder/tests/unit/volume/drivers/hpe/test_hpe3par.py
@@ -675,6 +675,11 @@ class HPE3PARBaseDriver(test.TestCase):
'minor': 5,
'revision': 0}
+ wsapi_version_2023 = {'major': 1,
+ 'build': 100000050,
+ 'minor': 10,
+ 'revision': 0}
+
# Use this to point to latest version of wsapi
wsapi_version_latest = wsapi_version_for_compression
@@ -892,28 +897,41 @@ class TestHPE3PARDriverBase(HPE3PARBaseDriver):
mock_client.assert_has_calls(expected)
self.assertEqual(self.STATUS_DONE, status)
- def test_create_volume(self):
+ # (i) wsapi version is old/default
+ # (ii) wsapi version is 2023, then snapCPG isn't required
+ @ddt.data({'wsapi_version': None},
+ {'wsapi_version': HPE3PARBaseDriver.wsapi_version_2023})
+ @ddt.unpack
+ def test_create_volume(self, wsapi_version):
# setup_mock_client drive with default configuration
# and return the mock HTTP 3PAR client
- mock_client = self.setup_driver()
+ mock_client = self.setup_driver(wsapi_version=wsapi_version)
+
with mock.patch.object(hpecommon.HPE3PARCommon,
'_create_client') as mock_create_client:
mock_create_client.return_value = mock_client
- self.driver.create_volume(self.volume)
+ if not wsapi_version:
+ # (i) old/default
+ self.driver.create_volume(self.volume)
+ else:
+ # (ii) wsapi 2023
+ common = self.driver._login()
+ common.create_volume(self.volume)
comment = Comment({
"display_name": "Foo Volume",
"type": "OpenStack",
"name": "volume-d03338a9-9115-48a3-8dfc-35cdfcdc15a7",
"volume_id": "d03338a9-9115-48a3-8dfc-35cdfcdc15a7"})
+ optional = {'comment': comment,
+ 'tpvv': True,
+ 'tdvv': False}
+ if not wsapi_version:
+ optional['snapCPG'] = HPE3PAR_CPG_SNAP
expected = [
mock.call.createVolume(
self.VOLUME_3PAR_NAME,
HPE3PAR_CPG,
- 2048, {
- 'comment': comment,
- 'tpvv': True,
- 'tdvv': False,
- 'snapCPG': HPE3PAR_CPG_SNAP})]
+ 2048, optional)]
mock_client.assert_has_calls(expected)
@@ -1255,6 +1273,89 @@ class TestHPE3PARDriverBase(HPE3PARBaseDriver):
mock_client.assert_has_calls(expected)
@mock.patch.object(volume_types, 'get_volume_type')
+ def test_create_volume_replicated_periodic_2023(self, _mock_volume_types):
+ # setup_mock_client drive with default configuration
+ # and return the mock HTTP 3PAR client
+ conf = self.setup_configuration()
+ self.replication_targets[0]['replication_mode'] = 'periodic'
+ conf.replication_device = self.replication_targets
+ mock_client = self.setup_driver(conf, None, self.wsapi_version_2023)
+ mock_client.getStorageSystemInfo.return_value = (
+ {'id': self.CLIENT_ID})
+ mock_client.getRemoteCopyGroup.side_effect = (
+ hpeexceptions.HTTPNotFound)
+ mock_client.getCPG.return_value = {'domain': None}
+ mock_replicated_client = self.setup_driver(conf, None,
+ self.wsapi_version_2023)
+ mock_replicated_client.getStorageSystemInfo.return_value = (
+ {'id': self.REPLICATION_CLIENT_ID})
+
+ _mock_volume_types.return_value = {
+ 'name': 'replicated',
+ 'extra_specs': {
+ 'replication_enabled': '<is> True',
+ 'replication:mode': 'periodic',
+ 'replication:sync_period': '900',
+ 'volume_type': self.volume_type_replicated}}
+
+ with mock.patch.object(
+ hpecommon.HPE3PARCommon,
+ '_create_client') as mock_create_client, \
+ mock.patch.object(
+ hpecommon.HPE3PARCommon,
+ '_create_replication_client') as mock_replication_client:
+ mock_create_client.return_value = mock_client
+ mock_replication_client.return_value = mock_replicated_client
+
+ common = self.driver._login()
+ return_model = common.create_volume(self.volume_replicated)
+ comment = Comment({
+ "volume_type_name": "replicated",
+ "display_name": "Foo Volume",
+ "name": "volume-d03338a9-9115-48a3-8dfc-35cdfcdc15a7",
+ "volume_type_id": "be9181f1-4040-46f2-8298-e7532f2bf9db",
+ "volume_id": "d03338a9-9115-48a3-8dfc-35cdfcdc15a7",
+ "qos": {},
+ "type": "OpenStack"})
+
+ backend_id = self.replication_targets[0]['backend_id']
+ expected = [
+ mock.call.createVolume(
+ self.VOLUME_3PAR_NAME,
+ HPE3PAR_CPG,
+ 2048, {
+ 'comment': comment,
+ 'tpvv': True,
+ 'tdvv': False}),
+ mock.call.getRemoteCopyGroup(self.RCG_3PAR_NAME),
+ mock.call.getCPG(HPE3PAR_CPG),
+ mock.call.createRemoteCopyGroup(
+ self.RCG_3PAR_NAME,
+ [{'userCPG': HPE3PAR_CPG_REMOTE,
+ 'targetName': backend_id,
+ 'mode': PERIODIC_MODE}],
+ {'localUserCPG': HPE3PAR_CPG}),
+ mock.call.addVolumeToRemoteCopyGroup(
+ self.RCG_3PAR_NAME,
+ self.VOLUME_3PAR_NAME,
+ [{'secVolumeName': self.VOLUME_3PAR_NAME,
+ 'targetName': backend_id}],
+ optional={'volumeAutoCreation': True}),
+ mock.call.modifyRemoteCopyGroup(
+ self.RCG_3PAR_NAME,
+ {'targets': [{'syncPeriod': SYNC_PERIOD,
+ 'targetName': backend_id}]}),
+ mock.call.startRemoteCopy(self.RCG_3PAR_NAME)]
+ mock_client.assert_has_calls(
+ self.get_id_login +
+ self.standard_logout +
+ self.standard_login +
+ expected)
+ self.assertEqual({'replication_status': 'enabled',
+ 'provider_location': self.CLIENT_ID},
+ return_model)
+
+ @mock.patch.object(volume_types, 'get_volume_type')
def test_create_volume_replicated_sync(self, _mock_volume_types):
# setup_mock_client drive with default configuration
# and return the mock HTTP 3PAR client
@@ -3398,6 +3499,7 @@ class TestHPE3PARDriverBase(HPE3PARBaseDriver):
}
mock_client = self.setup_driver(mock_conf=conf)
+ mock_client.getVolumeSnapshots.return_value = []
with mock.patch.object(hpecommon.HPE3PARCommon,
'_create_client') as mock_create_client:
mock_create_client.return_value = mock_client
@@ -3426,6 +3528,7 @@ class TestHPE3PARDriverBase(HPE3PARBaseDriver):
{
'comment': comment,
'readOnly': False}),
+ mock.call.getVolumeSnapshots(self.VOLUME_3PAR_NAME),
mock.call.copyVolume(
osv_matcher, omv_matcher, HPE3PAR_CPG, mock.ANY),
mock.call.getTask(mock.ANY),
@@ -3449,6 +3552,7 @@ class TestHPE3PARDriverBase(HPE3PARBaseDriver):
}
mock_client = self.setup_driver(mock_conf=conf)
+ mock_client.getVolumeSnapshots.return_value = []
_mock_volume_types.return_value = {
'name': 'gold',
'extra_specs': {
@@ -3490,6 +3594,7 @@ class TestHPE3PARDriverBase(HPE3PARBaseDriver):
'comment': comment,
'readOnly': False}),
mock.call.getCPG(HPE3PAR_CPG),
+ mock.call.getVolumeSnapshots(self.VOLUME_3PAR_NAME),
mock.call.copyVolume(
osv_matcher, omv_matcher, HPE3PAR_CPG, mock.ANY),
mock.call.getTask(mock.ANY),
@@ -3606,6 +3711,7 @@ class TestHPE3PARDriverBase(HPE3PARBaseDriver):
'getVolume.return_value': {}
}
mock_client = self.setup_driver(mock_conf=conf)
+ mock_client.getVolumeSnapshots.return_value = []
volume_type_hos = copy.deepcopy(self.volume_type_hos)
volume_type_hos['extra_specs']['convert_to_base'] = True
_mock_volume_types.return_value = volume_type_hos
@@ -3635,6 +3741,7 @@ class TestHPE3PARDriverBase(HPE3PARBaseDriver):
{
'comment': comment,
'readOnly': False}),
+ mock.call.getVolumeSnapshots(self.VOLUME_3PAR_NAME),
mock.call.copyVolume(
osv_matcher, omv_matcher, HPE3PAR_CPG, mock.ANY),
mock.call.getTask(mock.ANY),
@@ -3656,6 +3763,7 @@ class TestHPE3PARDriverBase(HPE3PARBaseDriver):
'getVolume.return_value': {}
}
mock_client = self.setup_driver(mock_conf=conf)
+ mock_client.getVolumeSnapshots.return_value = []
_mock_volume_types.return_value = self.volume_type_hos
with mock.patch.object(hpecommon.HPE3PARCommon,
'_create_client') as mock_create_client:
@@ -3684,6 +3792,7 @@ class TestHPE3PARDriverBase(HPE3PARBaseDriver):
{
'comment': comment,
'readOnly': False}),
+ mock.call.getVolumeSnapshots(self.VOLUME_3PAR_NAME),
mock.call.copyVolume(
osv_matcher, omv_matcher, HPE3PAR_CPG, mock.ANY),
mock.call.getTask(mock.ANY),
@@ -3706,6 +3815,7 @@ class TestHPE3PARDriverBase(HPE3PARBaseDriver):
'getVolume.return_value': {}
}
mock_client = self.setup_driver(mock_conf=conf)
+ mock_client.getVolumeSnapshots.return_value = []
volume_type_hos = copy.deepcopy(self.volume_type_hos)
volume_type_hos['extra_specs']['convert_to_base'] = True
_mock_volume_types.return_value = volume_type_hos
@@ -3736,6 +3846,7 @@ class TestHPE3PARDriverBase(HPE3PARBaseDriver):
{
'comment': comment,
'readOnly': False}),
+ mock.call.getVolumeSnapshots(self.VOLUME_3PAR_NAME),
mock.call.copyVolume(
osv_matcher, omv_matcher, HPE3PAR_CPG, mock.ANY),
mock.call.getTask(mock.ANY),
@@ -3834,6 +3945,7 @@ class TestHPE3PARDriverBase(HPE3PARBaseDriver):
}
mock_client = self.setup_driver(mock_conf=conf)
+ mock_client.getVolumeSnapshots.return_value = []
with mock.patch.object(hpecommon.HPE3PARCommon,
'_create_client') as mock_create_client:
mock_create_client.return_value = mock_client
@@ -3857,6 +3969,7 @@ class TestHPE3PARDriverBase(HPE3PARBaseDriver):
}
mock_client = self.setup_driver(mock_conf=conf)
+ mock_client.getVolumeSnapshots.return_value = []
with mock.patch.object(hpecommon.HPE3PARCommon,
'_create_client') as mock_create_client:
mock_create_client.return_value = mock_client
@@ -3868,6 +3981,18 @@ class TestHPE3PARDriverBase(HPE3PARBaseDriver):
self.volume,
str(new_size))
+ def test__convert_to_base_volume_failure(self):
+ mock_client = self.setup_driver()
+ mock_client.getVolumeSnapshots.return_value = (
+ ['oss-nwJVbXaEQMi0w.xPutFRQw'])
+ with mock.patch.object(hpecommon.HPE3PARCommon,
+ '_create_client') as mock_create_client:
+ mock_create_client.return_value = mock_client
+ common = self.driver._login()
+ self.assertRaises(exception.VolumeIsBusy,
+ common._convert_to_base_volume,
+ self.volume)
+
@mock.patch.object(volume_types, 'get_volume_type')
def test_extend_volume_replicated(self, _mock_volume_types):
# Managed vs. unmanaged and periodic vs. sync are not relevant when
@@ -4245,10 +4370,16 @@ class TestHPE3PARDriverBase(HPE3PARBaseDriver):
expected_retype_specs)
self.assertEqual(expected_obj, obj)
+ # (i) wsapi version is old/default
+ # (ii) wsapi version is 2023, then snapCPG isn't required
+ @ddt.data({'wsapi_version': None},
+ {'wsapi_version': HPE3PARBaseDriver.wsapi_version_2023})
+ @ddt.unpack
@mock.patch.object(volume_types, 'get_volume_type')
- def test_manage_existing_with_no_snap_cpg(self, _mock_volume_types):
+ def test_manage_existing_with_no_snap_cpg(self, _mock_volume_types,
+ wsapi_version):
_mock_volume_types.return_value = self.volume_type
- mock_client = self.setup_driver()
+ mock_client = self.setup_driver(wsapi_version=wsapi_version)
new_comment = Comment({
"display_name": "Foo Volume",
@@ -4280,15 +4411,20 @@ class TestHPE3PARDriverBase(HPE3PARBaseDriver):
obj = self.driver.manage_existing(volume, existing_ref)
+ optional = {'newName': osv_matcher,
+ 'comment': new_comment}
+
+ if not wsapi_version:
+ # (i) old/default
+ # manage_existing() should be setting
+ # blank snapCPG to the userCPG
+ optional['snapCPG'] = 'testUserCpg0'
+
expected_manage = [
mock.call.getVolume(existing_ref['source-name']),
mock.call.modifyVolume(
existing_ref['source-name'],
- {'newName': osv_matcher,
- 'comment': new_comment,
- # manage_existing() should be setting
- # blank snapCPG to the userCPG
- 'snapCPG': 'testUserCpg0'})
+ optional)
]
mock_client.assert_has_calls(self.standard_login + expected_manage)
@@ -6052,16 +6188,21 @@ class TestHPE3PARDriverBase(HPE3PARBaseDriver):
mock_client.assert_has_calls(expected)
+ # (i) wsapi version is old/default
+ # (ii) wsapi version is 2023, then snapCPG isn't required
+ @ddt.data({'wsapi_version': None},
+ {'wsapi_version': HPE3PARBaseDriver.wsapi_version_2023})
+ @ddt.unpack
@mock.patch('cinder.volume.drivers.hpe.hpe_3par_common.HPE3PARCommon.'
'get_volume_settings_from_type')
@mock.patch('cinder.volume.drivers.hpe.hpe_3par_common.HPE3PARCommon.'
'is_volume_group_snap_type')
@mock.patch('cinder.volume.volume_utils.is_group_a_cg_snapshot_type')
def test_create_group_from_src_group(self, cg_ss_enable, vol_ss_enable,
- typ_info):
+ typ_info, wsapi_version):
cg_ss_enable.return_value = True
vol_ss_enable.return_value = True
- mock_client = self.setup_driver()
+ mock_client = self.setup_driver(wsapi_version=wsapi_version)
task_id = 1
mock_client.copyVolume.return_value = {'taskid': task_id}
mock_client.getStorageSystemInfo.return_value = {'id': self.CLIENT_ID}
@@ -6092,6 +6233,10 @@ class TestHPE3PARDriverBase(HPE3PARBaseDriver):
source_grp = self.fake_group_object(
grp_id=self.SRC_CONSIS_GROUP_ID)
+ optional = {'online': True,
+ 'tpvv': mock.ANY, 'tdvv': mock.ANY}
+ if not wsapi_version:
+ optional['snapCPG'] = HPE3PAR_CPG
expected = [
mock.call.getCPG(HPE3PAR_CPG),
mock.call.createVolumeSet(
@@ -6107,17 +6252,25 @@ class TestHPE3PARDriverBase(HPE3PARBaseDriver):
mock.ANY,
self.VOLUME_NAME_3PAR,
HPE3PAR_CPG,
- {'snapCPG': HPE3PAR_CPG, 'online': True,
- 'tpvv': mock.ANY, 'tdvv': mock.ANY}),
+ optional),
mock.call.addVolumeToVolumeSet(
self.CONSIS_GROUP_NAME,
self.VOLUME_NAME_3PAR)]
# Create a consistency group from a source consistency group.
- self.driver.create_group_from_src(
- context.get_admin_context(), group,
- [volume], source_group=source_grp,
- source_vols=[source_volume])
+ if not wsapi_version:
+ # (i) old/default
+ self.driver.create_group_from_src(
+ context.get_admin_context(), group,
+ [volume], source_group=source_grp,
+ source_vols=[source_volume])
+ else:
+ # (ii) wsapi 2023
+ common = self.driver._login()
+ common.create_group_from_src(
+ context.get_admin_context(), group,
+ [volume], source_group=source_grp,
+ source_vols=[source_volume])
mock_client.assert_has_calls(expected)