Merge "PowerMax Driver - Rep validation fix & Retype suspension fix"
This commit is contained in:
commit
f0a3ea0246
@ -283,6 +283,7 @@ class PowerMaxCommonTest(test.TestCase):
|
||||
self.assertEqual(self.data.replication_update, update)
|
||||
self.assertEqual(self.data.rep_info_dict, info)
|
||||
|
||||
@mock.patch.object(common.PowerMaxCommon, '_validate_rdfg_status')
|
||||
@mock.patch.object(common.PowerMaxCommon, 'gather_replication_updates',
|
||||
return_value=(tpd.PowerMaxData.replication_update,
|
||||
tpd.PowerMaxData.rep_info_dict))
|
||||
@ -294,7 +295,8 @@ class PowerMaxCommonTest(test.TestCase):
|
||||
('', tpd.PowerMaxData.rep_extra_specs5,
|
||||
tpd.PowerMaxData.rep_info_dict, '')))
|
||||
def test_create_replication_enabled_volume_not_first_volume(
|
||||
self, mck_prepare, mck_create, mck_protect, mck_updates):
|
||||
self, mck_prepare, mck_create, mck_protect, mck_updates,
|
||||
mck_valid):
|
||||
array = self.data.array
|
||||
volume = self.data.test_volume
|
||||
volume_name = volume.name
|
||||
@ -315,6 +317,7 @@ class PowerMaxCommonTest(test.TestCase):
|
||||
array, volume_name, storagegroup_name, volume_size,
|
||||
rep_extra_specs, rep_info_dict)
|
||||
mck_protect.assert_not_called()
|
||||
mck_valid.assert_called_once_with(array, rep_extra_specs)
|
||||
rep_vol.update({'remote_device_id': self.data.device_id2})
|
||||
mck_updates.assert_called_once_with(
|
||||
rep_extra_specs, rep_extra_specs5, rep_vol)
|
||||
|
@ -738,6 +738,7 @@ class PowerMaxReplicationTest(test.TestCase):
|
||||
extra_specs[utils.REP_CONFIG] = self.data.rep_config_async
|
||||
volume_dict, rep_update, rep_info_dict = self.common._create_volume(
|
||||
volume, volume_name, volume_size, extra_specs)
|
||||
mck_valid.assert_not_called()
|
||||
self.assertEqual(self.data.provider_location, volume_dict)
|
||||
self.assertEqual(self.data.replication_update, rep_update)
|
||||
self.assertIsNone(rep_info_dict)
|
||||
@ -891,50 +892,63 @@ class PowerMaxReplicationTest(test.TestCase):
|
||||
target_extra_specs)
|
||||
self.assertTrue(success)
|
||||
|
||||
@mock.patch.object(common.PowerMaxCommon, 'get_volume_metadata',
|
||||
return_value='')
|
||||
@mock.patch.object(common.PowerMaxCommon, 'update_metadata',
|
||||
return_value=tpd.PowerMaxData.replication_model)
|
||||
@mock.patch.object(provision.PowerMaxProvision, 'verify_slo_workload',
|
||||
return_value=(True, True))
|
||||
@mock.patch.object(rest.PowerMaxRest, 'srdf_resume_replication')
|
||||
@mock.patch.object(common.PowerMaxCommon, '_retype_volume',
|
||||
return_value=(True, 'storage_group'))
|
||||
@mock.patch.object(common.PowerMaxCommon, 'configure_volume_replication',
|
||||
return_value=('status', 'data',
|
||||
tpd.PowerMaxData.rep_info_dict,
|
||||
tpd.PowerMaxData.rep_extra_specs_mgmt,
|
||||
True))
|
||||
@mock.patch.object(common.PowerMaxCommon, '_sync_check')
|
||||
@mock.patch.object(common.PowerMaxCommon, 'break_rdf_device_pair_session',
|
||||
return_value=(tpd.PowerMaxData.rep_extra_specs_mgmt,
|
||||
True))
|
||||
@mock.patch.object(common.PowerMaxCommon, '_validate_rdfg_status')
|
||||
@mock.patch.object(
|
||||
common.PowerMaxCommon, 'get_volume_metadata', return_value='')
|
||||
@mock.patch.object(
|
||||
common.PowerMaxCommon, '_retype_remote_volume', return_value=True)
|
||||
@mock.patch.object(
|
||||
common.PowerMaxCommon, '_retype_volume',
|
||||
return_value=(True, tpd.PowerMaxData.defaultstoragegroup_name))
|
||||
def test_migrate_volume_success_rep_to_rep(self, mck_retype, mck_remote,
|
||||
mck_get, mck_valid):
|
||||
self.common.rep_config = {'mode': utils.REP_SYNC,
|
||||
'array': self.data.array}
|
||||
array_id = self.data.array
|
||||
def test_migrate_volume_success_rep_to_rep(
|
||||
self, mck_valid, mck_break, mck_sync, mck_rep, mck_retype,
|
||||
mck_resume, mck_slo, mck_upd_meta, mck_get_meta):
|
||||
array = self.data.array
|
||||
volume = self.data.test_volume
|
||||
device_id = self.data.device_id
|
||||
srp = self.data.srp
|
||||
target_slo = self.data.slo_silver
|
||||
target_workload = self.data.workload
|
||||
volume_name = volume.name
|
||||
rep_config_sync = deepcopy(self.data.rep_config_sync)
|
||||
rep_config_sync[utils.RDF_CONS_EXEMPT] = False
|
||||
extra_specs = deepcopy(self.data.rep_extra_specs)
|
||||
extra_specs[utils.SLO] = self.data.slo_diamond
|
||||
new_type = {'extra_specs': self.data.rep_extra_specs}
|
||||
|
||||
target_extra_specs = deepcopy(new_type['extra_specs'])
|
||||
target_extra_specs.update({
|
||||
utils.SRP: srp, utils.ARRAY: array_id, utils.SLO: target_slo,
|
||||
utils.WORKLOAD: target_workload,
|
||||
utils.INTERVAL: extra_specs[utils.INTERVAL],
|
||||
utils.RETRIES: extra_specs[utils.RETRIES],
|
||||
utils.DISABLECOMPRESSION: False, utils.REP_MODE: utils.REP_SYNC,
|
||||
utils.REP_CONFIG: rep_config_sync})
|
||||
|
||||
extra_specs[utils.REP_CONFIG] = self.data.rep_config_sync
|
||||
extra_specs[utils.REPLICATION_DEVICE_BACKEND_ID] = (
|
||||
self.data.rep_config_sync[utils.BACKEND_ID])
|
||||
target_extra_specs = deepcopy(self.data.rep_extra_specs)
|
||||
target_extra_specs['rep_extra_specs'] = utils.REP_ASYNC
|
||||
target_extra_specs['rdf_group_no'] = self.data.rdf_group_name_2
|
||||
target_extra_specs[utils.REP_CONFIG] = self.data.rep_config_async
|
||||
target_extra_specs[utils.REPLICATION_DEVICE_BACKEND_ID] = (
|
||||
self.data.rep_config_async[utils.BACKEND_ID])
|
||||
new_type = {'extra_specs': target_extra_specs}
|
||||
success, model_update = self.common._migrate_volume(
|
||||
array_id, volume, device_id, srp, target_slo, target_workload,
|
||||
array, volume, device_id, srp, target_slo, target_workload,
|
||||
volume_name, new_type, extra_specs)
|
||||
mck_retype.assert_called_once_with(
|
||||
array_id, srp, device_id, volume, volume_name, extra_specs,
|
||||
target_slo, target_workload, target_extra_specs)
|
||||
mck_remote.assert_called_once_with(
|
||||
array_id, volume, device_id, volume_name, utils.REP_SYNC,
|
||||
True, target_extra_specs)
|
||||
self.assertEqual(2, mck_valid.call_count)
|
||||
mck_valid.assert_called_with(array, target_extra_specs)
|
||||
mck_break.assert_called_once_with(
|
||||
array, device_id, volume_name, extra_specs)
|
||||
mck_sync.assert_called_once_with(array, device_id, extra_specs)
|
||||
mck_rep.assert_called_once_with(
|
||||
array, volume, device_id, target_extra_specs)
|
||||
mck_retype.assert_called_once()
|
||||
self.assertEqual(2, mck_resume.call_count)
|
||||
mck_resume.assert_called_with(
|
||||
array, self.data.rep_extra_specs_mgmt['mgmt_sg_name'],
|
||||
extra_specs['rdf_group_no'], self.data.rep_extra_specs_mgmt)
|
||||
self.assertTrue(success)
|
||||
self.assertEqual(self.data.replication_model, model_update)
|
||||
|
||||
@mock.patch.object(masking.PowerMaxMasking, 'add_volume_to_storage_group')
|
||||
@mock.patch.object(provision.PowerMaxProvision, 'get_or_create_group')
|
||||
|
@ -2039,9 +2039,6 @@ class PowerMaxCommon(object):
|
||||
if self.utils.is_replication_enabled(extra_specs):
|
||||
is_re, rep_mode = True, extra_specs['rep_mode']
|
||||
|
||||
if is_re:
|
||||
self._validate_rdfg_status(array, extra_specs)
|
||||
|
||||
storagegroup_name = self.masking.get_or_create_default_storage_group(
|
||||
array, extra_specs[utils.SRP], extra_specs[utils.SLO],
|
||||
extra_specs[utils.WORKLOAD], extra_specs,
|
||||
@ -2122,6 +2119,7 @@ class PowerMaxCommon(object):
|
||||
_is_first_vol_in_replicated_sg())
|
||||
|
||||
if not is_first_volume:
|
||||
self._validate_rdfg_status(array, extra_specs)
|
||||
__, rep_extra_specs, rep_info_dict, __ = (
|
||||
self.prepare_replication_details(extra_specs))
|
||||
volume_info_dict = self.provision.create_volume_from_sg(
|
||||
@ -3679,8 +3677,10 @@ class PowerMaxCommon(object):
|
||||
:returns: bool
|
||||
"""
|
||||
model_update, success = None, False
|
||||
rep_info_dict, rep_extra_specs, rep_mode, rep_status, resume_rdf = (
|
||||
None, None, None, False, False)
|
||||
rep_info_dict, rep_extra_specs, rep_mode, rep_status = (
|
||||
None, None, None, False)
|
||||
resume_target_sg, resume_original_sg = False, False
|
||||
resume_original_sg_dict = dict()
|
||||
|
||||
target_extra_specs = new_type['extra_specs']
|
||||
target_extra_specs.update({
|
||||
@ -3726,19 +3726,26 @@ class PowerMaxCommon(object):
|
||||
# Scenario 1: Rep -> Non-Rep
|
||||
# Scenario 2: Cleanup for Rep -> Diff Rep type
|
||||
if (was_rep_enabled and not is_rep_enabled) or backend_ids_differ:
|
||||
rep_extra_specs, resume_rdf = (
|
||||
rep_extra_specs, resume_original_sg = (
|
||||
self.break_rdf_device_pair_session(
|
||||
array, device_id, volume_name, extra_specs))
|
||||
model_update = {
|
||||
'replication_status': REPLICATION_DISABLED,
|
||||
'replication_driver_data': None}
|
||||
|
||||
if resume_original_sg:
|
||||
resume_original_sg_dict = {
|
||||
utils.ARRAY: array,
|
||||
utils.SG_NAME: rep_extra_specs['mgmt_sg_name'],
|
||||
utils.RDF_GROUP_NO: rep_extra_specs['rdf_group_no'],
|
||||
utils.EXTRA_SPECS: rep_extra_specs}
|
||||
|
||||
# Scenario 1: Non-Rep -> Rep
|
||||
# Scenario 2: Rep -> Diff Rep type
|
||||
if (not was_rep_enabled and is_rep_enabled) or backend_ids_differ:
|
||||
self._sync_check(array, device_id, extra_specs)
|
||||
(rep_status, rep_driver_data, rep_info_dict,
|
||||
rep_extra_specs, resume_rdf) = (
|
||||
rep_extra_specs, resume_target_sg) = (
|
||||
self.configure_volume_replication(
|
||||
array, volume, device_id, target_extra_specs))
|
||||
model_update = {
|
||||
@ -3771,10 +3778,16 @@ class PowerMaxCommon(object):
|
||||
array, volume, device_id, volume_name,
|
||||
rep_mode, is_rep_enabled, target_extra_specs)
|
||||
|
||||
if resume_rdf:
|
||||
if resume_target_sg:
|
||||
self.rest.srdf_resume_replication(
|
||||
array, rep_extra_specs['mgmt_sg_name'],
|
||||
rep_extra_specs['rdf_group_no'], rep_extra_specs)
|
||||
if resume_original_sg and resume_original_sg_dict:
|
||||
self.rest.srdf_resume_replication(
|
||||
resume_original_sg_dict[utils.ARRAY],
|
||||
resume_original_sg_dict[utils.SG_NAME],
|
||||
resume_original_sg_dict[utils.RDF_GROUP_NO],
|
||||
resume_original_sg_dict[utils.EXTRA_SPECS])
|
||||
|
||||
if success:
|
||||
model_update = self.update_metadata(
|
||||
|
@ -78,7 +78,8 @@ RDF_FAILEDOVER_STATE = 'failed over'
|
||||
RDF_ACTIVE = 'active'
|
||||
RDF_ACTIVEACTIVE = 'activeactive'
|
||||
RDF_ACTIVEBIAS = 'activebias'
|
||||
RDF_VALID_STATES_SYNC = [RDF_SYNC_STATE, RDF_SYNCINPROG_STATE]
|
||||
RDF_VALID_STATES_SYNC = [RDF_SYNC_STATE, RDF_SUSPENDED_STATE,
|
||||
RDF_SYNCINPROG_STATE]
|
||||
RDF_VALID_STATES_ASYNC = [RDF_CONSISTENT_STATE, RDF_SUSPENDED_STATE,
|
||||
RDF_SYNCINPROG_STATE]
|
||||
RDF_VALID_STATES_METRO = [RDF_ACTIVEBIAS, RDF_ACTIVEACTIVE,
|
||||
|
Loading…
Reference in New Issue
Block a user