def test_make_auth_headers(self): power_user = factory.make_name("power_user") power_pass = factory.make_name("power_pass") creds = "%s:%s" % (power_user, power_pass) authorization = b64encode(creds.encode("utf-8")) attributes = { b"User-Agent": [b"MAAS"], b"Accept": [b"application/json"], b"Authorization": [b"Basic " + authorization], b"Content-Type": [b"application/json; charset=utf-8"], } driver = RedfishPowerDriver() headers = driver.make_auth_headers(power_user, power_pass) self.assertEquals(headers, Headers(attributes))
def test__power_off(self): driver = RedfishPowerDriver() system_id = factory.make_name('system_id') context = make_context() url = driver.get_url(context) headers = driver.make_auth_headers(**context) node_id = context.get('node_id').encode('utf-8') mock_set_pxe_boot = self.patch(driver, 'set_pxe_boot') mock_power = self.patch(driver, 'power') yield driver.power_off(system_id, context) self.assertThat(mock_set_pxe_boot, MockCalledOnceWith( url, node_id, headers)) self.assertThat(mock_power, MockCalledOnceWith( "ForceOff", url, node_id, headers))
def test__power_off_already_off(self): driver = RedfishPowerDriver() context = make_context() url = driver.get_url(context) headers = driver.make_auth_headers(**context) node_id = b"1" mock_redfish_request = self.patch(driver, "redfish_request") mock_redfish_request.return_value = (SAMPLE_JSON_SYSTEMS, None) mock_set_pxe_boot = self.patch(driver, "set_pxe_boot") mock_power_query = self.patch(driver, "power_query") mock_power_query.return_value = "off" mock_power = self.patch(driver, "power") yield driver.power_off(node_id, context) self.assertThat(mock_set_pxe_boot, MockCalledOnceWith(url, node_id, headers)) self.assertThat(mock_power, MockNotCalled())
def test__power_off(self): driver = RedfishPowerDriver() context = make_context() url = driver.get_url(context) headers = driver.make_auth_headers(**context) node_id = b'1' mock_redfish_request = self.patch(driver, 'redfish_request') mock_redfish_request.return_value = ( SAMPLE_JSON_SYSTEMS, None) mock_set_pxe_boot = self.patch(driver, 'set_pxe_boot') mock_power = self.patch(driver, 'power') yield driver.power_off(node_id, context) self.assertThat(mock_set_pxe_boot, MockCalledOnceWith( url, node_id, headers)) self.assertThat(mock_power, MockCalledOnceWith( "ForceOff", url, node_id, headers))
def test_redfish_request_raises_error_on_response_code_above_400(self): driver = RedfishPowerDriver() context = make_context() url = driver.get_url(context) uri = join(url, b"redfish/v1/Systems") headers = driver.make_auth_headers(**context) mock_agent = self.patch(redfish_module, "Agent") mock_agent.return_value.request = Mock() expected_headers = Mock() expected_headers.code = HTTPStatus.BAD_REQUEST expected_headers.headers = "Testing Headers" mock_agent.return_value.request.return_value = succeed( expected_headers) mock_readBody = self.patch(redfish_module, "readBody") with ExpectedException(PowerActionError): yield driver.redfish_request(b"GET", uri, headers) self.assertThat(mock_readBody, MockNotCalled())
def test_redfish_request_raises_invalid_json_error(self): driver = RedfishPowerDriver() context = make_context() url = driver.get_url(context) uri = join(url, b"redfish/v1/Systems") headers = driver.make_auth_headers(**context) mock_agent = self.patch(redfish_module, "Agent") mock_agent.return_value.request = Mock() expected_headers = Mock() expected_headers.code = HTTPStatus.OK expected_headers.headers = "Testing Headers" mock_agent.return_value.request.return_value = succeed( expected_headers) mock_readBody = self.patch(redfish_module, "readBody") mock_readBody.return_value = succeed( '{"invalid": "json"'.encode("utf-8")) with ExpectedException(PowerActionError): yield driver.redfish_request(b"GET", uri, headers)
def test_redfish_request_renders_response(self): driver = RedfishPowerDriver() context = make_context() url = driver.get_url(context) uri = join(url, b"redfish/v1/Systems") headers = driver.make_auth_headers(**context) mock_agent = self.patch(redfish_module, "Agent") mock_agent.return_value.request = Mock() expected_headers = Mock() expected_headers.code = HTTPStatus.OK expected_headers.headers = "Testing Headers" mock_agent.return_value.request.return_value = succeed( expected_headers) mock_readBody = self.patch(redfish_module, "readBody") mock_readBody.return_value = succeed( json.dumps(SAMPLE_JSON_SYSTEMS).encode("utf-8")) expected_response = SAMPLE_JSON_SYSTEMS response, headers = yield driver.redfish_request(b"GET", uri, headers) self.assertEquals(expected_response, response) self.assertEquals(expected_headers.headers, headers)
def test_power_issues_power_reset(self): driver = RedfishPowerDriver() context = make_context() power_change = factory.make_name("power_change") url = driver.get_url(context) headers = driver.make_auth_headers(**context) node_id = b"1" mock_file_body_producer = self.patch(redfish_module, "FileBodyProducer") payload = FileBodyProducer( BytesIO( json.dumps({ "ResetType": "%s" % power_change }).encode("utf-8"))) mock_file_body_producer.return_value = payload mock_redfish_request = self.patch(driver, "redfish_request") expected_uri = join(url, REDFISH_POWER_CONTROL_ENDPOINT % node_id) yield driver.power(power_change, url, node_id, headers) self.assertThat( mock_redfish_request, MockCalledOnceWith(b"POST", expected_uri, headers, payload), )
def test_redfish_request_raises_failures(self): driver = RedfishPowerDriver() context = make_context() url = driver.get_url(context) uri = join(url, b"redfish/v1/Systems") headers = driver.make_auth_headers(**context) mock_agent = self.patch(redfish_module, "Agent") mock_agent.return_value.request = Mock() expected_headers = Mock() expected_headers.code = HTTPStatus.OK expected_headers.headers = "Testing Headers" mock_agent.return_value.request.return_value = succeed( expected_headers) mock_readBody = self.patch(redfish_module, "readBody") error = PartialDownloadError( response=json.dumps(SAMPLE_JSON_SYSTEMS).encode("utf-8"), code=HTTPStatus.NOT_FOUND, ) mock_readBody.return_value = fail(error) with ExpectedException(PartialDownloadError): yield driver.redfish_request(b"GET", uri, headers) self.assertThat(mock_readBody, MockCalledOnceWith(expected_headers))
def test_redfish_request_continues_partial_download_error(self): driver = RedfishPowerDriver() context = make_context() url = driver.get_url(context) uri = join(url, b"redfish/v1/Systems") headers = driver.make_auth_headers(**context) mock_agent = self.patch(redfish_module, 'Agent') mock_agent.return_value.request = Mock() expected_headers = Mock() expected_headers.code = HTTPStatus.OK expected_headers.headers = "Testing Headers" mock_agent.return_value.request.return_value = succeed( expected_headers) mock_readBody = self.patch(redfish_module, 'readBody') error = PartialDownloadError( response=json.dumps(SAMPLE_JSON_SYSTEMS).encode('utf-8'), code=HTTPStatus.OK) mock_readBody.return_value = fail(error) expected_response = SAMPLE_JSON_SYSTEMS response, headers = yield driver.redfish_request(b"GET", uri, headers) self.assertEquals(expected_response, response) self.assertEquals(expected_headers.headers, headers)
def test__set_pxe_boot(self): driver = RedfishPowerDriver() context = make_context() url = driver.get_url(context) node_id = b'1' headers = driver.make_auth_headers(**context) mock_file_body_producer = self.patch( redfish_module, 'FileBodyProducer') payload = FileBodyProducer( BytesIO( json.dumps( { 'Boot': { 'BootSourceOverrideEnabled': "Once", 'BootSourceOverrideTarget': "Pxe" } }).encode('utf-8'))) mock_file_body_producer.return_value = payload mock_redfish_request = self.patch(driver, 'redfish_request') yield driver.set_pxe_boot(url, node_id, headers) self.assertThat(mock_redfish_request, MockCalledOnceWith( b"PATCH", join(url, b"redfish/v1/Systems/%s/" % node_id), headers, payload))
def test_wrap_redfish_request_retries_404s_trailing_slash(self): driver = RedfishPowerDriver() context = make_context() url = driver.get_url(context) uri = join(url, b"redfish/v1/Systems") headers = driver.make_auth_headers(**context) mock_agent = self.patch(redfish_module, "Agent") mock_agent.return_value.request = Mock() expected_headers = Mock() expected_headers.code = HTTPStatus.NOT_FOUND expected_headers.headers = "Testing Headers" happy_headers = Mock() happy_headers.code = HTTPStatus.OK happy_headers.headers = "Testing Headers" mock_agent.return_value.request.side_effect = [ succeed(expected_headers), succeed(happy_headers), ] mock_readBody = self.patch(redfish_module, "readBody") mock_readBody.return_value = succeed( json.dumps(SAMPLE_JSON_SYSTEMS).encode("utf-8") ) expected_response = SAMPLE_JSON_SYSTEMS response, return_headers = yield driver.redfish_request( b"GET", uri, headers ) self.assertThat( mock_agent.return_value.request, MockCallsMatch( call(b"GET", uri, headers, None), call(b"GET", uri + "/".encode("utf-8"), headers, None), ), ) self.assertEqual(expected_response, response) self.assertEqual(expected_headers.headers, return_headers)