diff --git a/dracclient/resources/raid.py b/dracclient/resources/raid.py index 52972c7..058e3e3 100644 --- a/dracclient/resources/raid.py +++ b/dracclient/resources/raid.py @@ -94,6 +94,8 @@ VirtualDisk = collections.namedtuple( 'status', 'raid_status', 'span_depth', 'span_length', 'pending_operations', 'physical_disks']) +NO_FOREIGN_DRIVE = "STOR018" + class RAIDManagement(object): @@ -791,7 +793,34 @@ class RAIDManagement(object): doc = self.client.invoke(uris.DCIM_RAIDService, 'ClearForeignConfig', selectors, properties, - expected_return_value=utils.RET_SUCCESS) + check_return_value=False) - return utils.build_return_dict(doc, uris.DCIM_RAIDService, - is_commit_required_value=True) + is_commit_required_value = True + is_reboot_required_value = None + + ret_value = utils.find_xml(doc, + 'ReturnValue', + uris.DCIM_RAIDService).text + + if ret_value == utils.RET_ERROR: + message_id = utils.find_xml(doc, + 'MessageID', + uris.DCIM_RAIDService).text + + # A MessageID 'STOR018' indicates no foreign drive was + # detected. Return a value which informs the caller nothing + # further needs to be done. + if message_id == NO_FOREIGN_DRIVE: + is_commit_required_value = False + is_reboot_required_value = constants.RebootRequired.false + else: + message = utils.find_xml(doc, + 'Message', + uris.DCIM_RAIDService).text + raise exceptions.DRACOperationFailed( + drac_messages=message) + + return utils.build_return_dict( + doc, uris.DCIM_RAIDService, + is_commit_required_value=is_commit_required_value, + is_reboot_required_value=is_reboot_required_value) diff --git a/dracclient/tests/test_raid.py b/dracclient/tests/test_raid.py index 43cc022..a93a77a 100644 --- a/dracclient/tests/test_raid.py +++ b/dracclient/tests/test_raid.py @@ -632,6 +632,7 @@ class ClientRAIDManagementTestCase(base.BaseTest): mock_invoke.return_value = lxml.etree.fromstring( test_utils.RAIDInvocations[uris.DCIM_RAIDService][ 'ClearForeignConfig']['ok']) + result = self.drac_client.clear_foreign_config( self.raid_controller_fqdd) self.assertEqual({'is_commit_required': True, @@ -641,21 +642,49 @@ class ClientRAIDManagementTestCase(base.BaseTest): mock_invoke.assert_called_once_with( mock.ANY, uris.DCIM_RAIDService, 'ClearForeignConfig', expected_selectors, expected_properties, - expected_return_value=utils.RET_SUCCESS) + check_return_value=False) + + @mock.patch.object(dracclient.client.WSManClient, 'invoke', + spec_set=True, autospec=True) + def test_clear_foreign_config_with_no_foreign_drive(self, + mock_requests, + mock_invoke): + expected_selectors = {'SystemCreationClassName': 'DCIM_ComputerSystem', + 'CreationClassName': 'DCIM_RAIDService', + 'SystemName': 'DCIM:ComputerSystem', + 'Name': 'DCIM:RAIDService'} + expected_properties = {'Target': self.raid_controller_fqdd} + mock_invoke.return_value = lxml.etree.fromstring( + test_utils.RAIDInvocations[uris.DCIM_RAIDService][ + 'ClearForeignConfig']['no_foreign_drive']) + + result = self.drac_client.clear_foreign_config( + self.raid_controller_fqdd) + self.assertEqual({'is_commit_required': False, + 'is_reboot_required': + constants.RebootRequired.false}, + result) + mock_invoke.assert_called_once_with( + mock.ANY, uris.DCIM_RAIDService, 'ClearForeignConfig', + expected_selectors, expected_properties, + check_return_value=False) @mock.patch.object(dracclient.client.WSManClient, 'wait_until_idrac_is_ready', spec_set=True, autospec=True) - def test_clear_foreign_config_fail(self, mock_requests, - mock_wait_until_idrac_is_ready): + def test_clear_foreign_config_with_invalid_controller_id( + self, + mock_requests, + mock_wait_until_idrac_is_ready): mock_requests.post( 'https://1.2.3.4:443/wsman', text=test_utils.RAIDInvocations[ - uris.DCIM_RAIDService]['ClearForeignConfig']['error']) + uris.DCIM_RAIDService]['ClearForeignConfig'] + ['invalid_controller_id']) self.assertRaises( exceptions.DRACOperationFailed, - self.drac_client.clear_foreign_config, self.raid_controller_fqdd) + self.drac_client.clear_foreign_config, 'bad') @mock.patch.object(dracclient.resources.job.JobManagement, 'create_config_job', spec_set=True, autospec=True) diff --git a/dracclient/tests/utils.py b/dracclient/tests/utils.py index 136c190..49acc2f 100644 --- a/dracclient/tests/utils.py +++ b/dracclient/tests/utils.py @@ -263,8 +263,10 @@ RAIDInvocations = { 'ClearForeignConfig': { 'ok': load_wsman_xml( 'raid_service-invoke-clear_foreign_config-ok'), - 'error': load_wsman_xml( - 'raid_service-invoke-clear_foreign_config-error'), + 'no_foreign_drive': load_wsman_xml( + 'raid_service-invoke-clear_foreign_config-no_foreign_drive'), + 'invalid_controller_id': load_wsman_xml( + 'raid_service-invoke-clear_foreign_config-invalid_controller'), } } } diff --git a/dracclient/tests/wsman_mocks/raid_service-invoke-clear_foreign_config-invalid_controller.xml b/dracclient/tests/wsman_mocks/raid_service-invoke-clear_foreign_config-invalid_controller.xml new file mode 100644 index 0000000..d60acb2 --- /dev/null +++ b/dracclient/tests/wsman_mocks/raid_service-invoke-clear_foreign_config-invalid_controller.xml @@ -0,0 +1,17 @@ + + + http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous + http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_RAIDService/ClearForeignConfigResponse + uuid:f9487fcf-103a-103a-8002-fd0aa2bdb228 + uuid:000852e6-1040-1040-8997-a36fc6fe83b0 + + + + Controller not found + STOR030 + 2 + + + diff --git a/dracclient/tests/wsman_mocks/raid_service-invoke-clear_foreign_config-error.xml b/dracclient/tests/wsman_mocks/raid_service-invoke-clear_foreign_config-no_foreign_drive.xml similarity index 93% rename from dracclient/tests/wsman_mocks/raid_service-invoke-clear_foreign_config-error.xml rename to dracclient/tests/wsman_mocks/raid_service-invoke-clear_foreign_config-no_foreign_drive.xml index 59494a5..6ab74d7 100644 --- a/dracclient/tests/wsman_mocks/raid_service-invoke-clear_foreign_config-error.xml +++ b/dracclient/tests/wsman_mocks/raid_service-invoke-clear_foreign_config-no_foreign_drive.xml @@ -9,7 +9,7 @@ - >No foreign drives detected + No foreign drives detected STOR018 2