From 5704227cf0c1adf6c1d8a321b60eb6c5e8461ced Mon Sep 17 00:00:00 2001 From: Chris Dearborn Date: Mon, 8 Jun 2015 15:17:46 -0400 Subject: [PATCH] Fix DRAC driver job completion detection The DRAC driver code determined job completion by comparing the returned JobStatus to "completed" and "failed". Testing with hardware showed that JobStatus can also return "Completed with Errors". This change updates the DRAC driver so that it recognizes a job with "Completed with Errors" for the JobStatus as a completed job. Change-Id: I051d6703194231712f0234f31b0b49208bf0e6ec Closes-Bug: 1462513 --- ironic/drivers/modules/drac/management.py | 5 ++++- ironic/tests/drivers/drac/test_management.py | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/ironic/drivers/modules/drac/management.py b/ironic/drivers/modules/drac/management.py index c89974a190..7c18cdb76f 100644 --- a/ironic/drivers/modules/drac/management.py +++ b/ironic/drivers/modules/drac/management.py @@ -166,8 +166,11 @@ def _check_for_config_job(node): i, 'JobStatus', resource_uris.DCIM_LifecycleJob).text # If job is already completed or failed we can # create another one. + # The 'Completed with Errors' JobStatus can be returned by + # configuration jobs that set NIC or BIOS attributes. # Job Control Documentation: http://goo.gl/o1dDD3 (Section 7.2.3.2) - if job_status.lower() not in ('completed', 'failed'): + if job_status.lower() not in ('completed', 'completed with errors', + 'failed'): job_id = drac_common.find_xml(i, 'InstanceID', resource_uris.DCIM_LifecycleJob).text raise exception.DracPendingConfigJobExists(job_id=job_id, diff --git a/ironic/tests/drivers/drac/test_management.py b/ironic/tests/drivers/drac/test_management.py index f48ac09908..1a6586606b 100644 --- a/ironic/tests/drivers/drac/test_management.py +++ b/ironic/tests/drivers/drac/test_management.py @@ -116,6 +116,26 @@ class DracManagementInternalMethodsTestCase(db_base.DbTestCase): mock_pywsman.enumerate.assert_called_once_with( mock.ANY, mock.ANY, resource_uris.DCIM_LifecycleJob) + def test__check_for_config_job_not_exist(self, mock_client_pywsman): + job_statuses = ["Completed", "Completed with Errors", "Failed"] + for job_status in job_statuses: + result_xml = test_utils.build_soap_xml( + [{'DCIM_LifecycleJob': {'Name': 'BIOS.Setup.1-1', + 'JobStatus': job_status, + 'InstanceID': 'fake'}}], + resource_uris.DCIM_LifecycleJob) + + mock_xml = test_utils.mock_wsman_root(result_xml) + mock_pywsman = mock_client_pywsman.Client.return_value + mock_pywsman.enumerate.return_value = mock_xml + + try: + drac_mgmt._check_for_config_job(self.node) + except (exception.DracClientError, + exception.DracPendingConfigJobExists): + self.fail("Failed to detect completed job due to " + "\"{}\" job status".format(job_status)) + def test__create_config_job(self, mock_client_pywsman): result_xml = test_utils.build_soap_xml( [{'ReturnValue': drac_client.RET_CREATED}],