def test__http_request_client_fallback_success(self, mock_negotiate): # Test when fallback to a supported version succeeds mock_negotiate.return_value = '1.6' error_body = _get_error_body() bad_resp = utils.mockSessionResponse( {'X-OpenStack-Ironic-API-Minimum-Version': '1.1', 'X-OpenStack-Ironic-API-Maximum-Version': '1.6', 'content-type': 'text/plain', }, error_body, version=1, status_code=http_client.NOT_ACCEPTABLE) good_resp = utils.mockSessionResponse( {'X-OpenStack-Ironic-API-Minimum-Version': '1.1', 'X-OpenStack-Ironic-API-Maximum-Version': '1.6', 'content-type': 'text/plain', }, "We got some text", version=1, status_code=http_client.OK) client = http.HTTPClient('http://localhost/') with mock.patch.object(client, 'session', autospec=True) as mock_session: mock_session.request.side_effect = iter([bad_resp, good_resp]) response, body_iter = client._http_request('/v1/resources', 'GET') self.assertEqual(http_client.OK, response.status_code) self.assertEqual(1, mock_negotiate.call_count)
def test__http_request_client_fallback_success(self, mock_negotiate): # Test when fallback to a supported version succeeds mock_negotiate.return_value = '1.6' error_body = _get_error_body() bad_resp = utils.mockSessionResponse( { 'X-OpenStack-Ironic-API-Minimum-Version': '1.1', 'X-OpenStack-Ironic-API-Maximum-Version': '1.6', 'content-type': 'text/plain', }, error_body, version=1, status_code=http_client.NOT_ACCEPTABLE) good_resp = utils.mockSessionResponse( { 'X-OpenStack-Ironic-API-Minimum-Version': '1.1', 'X-OpenStack-Ironic-API-Maximum-Version': '1.6', 'content-type': 'text/plain', }, "We got some text", version=1, status_code=http_client.OK) client = http.HTTPClient('http://localhost/') with mock.patch.object(client, 'session', autospec=True) as mock_session: mock_session.request.side_effect = iter([bad_resp, good_resp]) response, body_iter = client._http_request('/v1/resources', 'GET') self.assertEqual(http_client.OK, response.status_code) self.assertEqual(1, mock_negotiate.call_count)
def test_session_retry(self): error_body = _get_error_body() fake_resp = utils.mockSessionResponse( {'Content-Type': 'application/json'}, error_body, http_client.CONFLICT) ok_resp = utils.mockSessionResponse( {'Content-Type': 'application/json'}, b"OK", http_client.OK) fake_session = utils.mockSession({}) fake_session.request.side_effect = iter((fake_resp, ok_resp)) client = _session_client(session=fake_session) client.json_request('GET', '/v1/resources') self.assertEqual(2, fake_session.request.call_count)
def test_session_retry_503(self): error_body = _get_error_body() fake_resp = utils.mockSessionResponse( {'Content-Type': 'application/json'}, error_body, http_client.SERVICE_UNAVAILABLE) ok_resp = utils.mockSessionResponse( {'Content-Type': 'application/json'}, b"OK", http_client.OK) fake_session = mock.Mock(spec=requests.Session) fake_session.request.side_effect = iter((fake_resp, ok_resp)) client = _session_client(session=fake_session) client.json_request('GET', '/v1/resources') self.assertEqual(2, fake_session.request.call_count)
def _test_endpoint_override(self, endpoint): fake_session = utils.mockSession({'content-type': 'application/json'}, status_code=http_client.NO_CONTENT) request_mock = mock.Mock() fake_session.request = request_mock request_mock.return_value = utils.mockSessionResponse( headers={'content-type': 'application/json'}, status_code=http_client.NO_CONTENT) client = _session_client(session=fake_session, endpoint_override=endpoint) client.json_request('DELETE', '/v1/nodes/aa/maintenance') expected_args_dict = { 'headers': { 'Content-Type': 'application/json', 'Accept': 'application/json', 'X-OpenStack-Ironic-API-Version': '1.6' }, 'auth': None, 'user_agent': 'python-ironicclient', 'endpoint_filter': { 'interface': 'publicURL', 'service_type': 'baremetal', 'region_name': '' } } if isinstance(endpoint, six.string_types): trimmed = http._trim_endpoint_api_version(endpoint) expected_args_dict['endpoint_override'] = trimmed request_mock.assert_called_once_with('/v1/nodes/aa/maintenance', 'DELETE', raise_exc=False, **expected_args_dict)
def _test_endpoint_override(self, endpoint): fake_session = utils.mockSession({'content-type': 'application/json'}, status_code=http_client.NO_CONTENT) request_mock = mock.Mock() fake_session.request = request_mock request_mock.return_value = utils.mockSessionResponse( headers={'content-type': 'application/json'}, status_code=http_client.NO_CONTENT) client = _session_client(session=fake_session, endpoint_override=endpoint) client.json_request('DELETE', '/v1/nodes/aa/maintenance') expected_args_dict = { 'headers': { 'Content-Type': 'application/json', 'Accept': 'application/json', 'X-OpenStack-Ironic-API-Version': '1.6' }, 'auth': None, 'user_agent': 'python-ironicclient', 'endpoint_filter': { 'interface': 'publicURL', 'service_type': 'baremetal', 'region_name': '' } } if isinstance(endpoint, six.string_types): trimmed = http._trim_endpoint_api_version(endpoint) expected_args_dict['endpoint_override'] = trimmed request_mock.assert_called_once_with( '/v1/nodes/aa/maintenance', 'DELETE', raise_exc=False, **expected_args_dict )
def test_session_retry_503(self): error_body = _get_error_body() fake_resp = utils.mockSessionResponse( {'Content-Type': 'application/json'}, error_body, http_client.SERVICE_UNAVAILABLE) ok_resp = utils.mockSessionResponse( {'Content-Type': 'application/json'}, b"OK", http_client.OK) fake_session = mock.Mock(spec=requests.Session) fake_session.request.side_effect = iter((fake_resp, ok_resp)) client = _session_client(session=fake_session) client.json_request('GET', '/v1/resources') self.assertEqual(2, fake_session.request.call_count)
def test_session_retry_retriable_connection_failure(self): ok_resp = utils.mockSessionResponse( {'Content-Type': 'application/json'}, b"OK", http_client.OK) fake_session = mock.Mock(spec=requests.Session) fake_session.request.side_effect = iter( (kexc.RetriableConnectionFailure(), ok_resp)) client = _session_client(session=fake_session) client.json_request('GET', '/v1/resources') self.assertEqual(2, fake_session.request.call_count)
def test_session_retry_connection_refused(self): ok_resp = utils.mockSessionResponse( {'Content-Type': 'application/json'}, b"OK", http_client.OK) fake_session = utils.mockSession({}) fake_session.request.side_effect = iter( (exc.ConnectionRefused(), ok_resp)) client = _session_client(session=fake_session) client.json_request('GET', '/v1/resources') self.assertEqual(2, fake_session.request.call_count)
def test_http_retry_503(self): error_body = _get_error_body() bad_resp = utils.mockSessionResponse( {'Content-Type': 'text/plain'}, error_body, version=1, status_code=http_client.SERVICE_UNAVAILABLE) good_resp = utils.mockSessionResponse({'Content-Type': 'text/plain'}, "meow", version=1, status_code=http_client.OK) client = http.HTTPClient('http://localhost/') with mock.patch.object(client, 'session', autospec=True) as mock_session: mock_session.request.side_effect = iter([bad_resp, good_resp]) response, body_iter = client._http_request('/v1/resources', 'GET') self.assertEqual(http_client.OK, response.status_code) self.assertEqual(2, mock_session.request.call_count)
def test_session_retry_retriable_connection_failure(self): ok_resp = utils.mockSessionResponse( {'Content-Type': 'application/json'}, b"OK", http_client.OK) fake_session = mock.Mock(spec=requests.Session) fake_session.request.side_effect = iter( (kexc.RetriableConnectionFailure(), ok_resp)) client = _session_client(session=fake_session) client.json_request('GET', '/v1/resources') self.assertEqual(2, fake_session.request.call_count)
def test_http_retry_503(self): error_body = _get_error_body() bad_resp = utils.mockSessionResponse( {'Content-Type': 'text/plain'}, error_body, version=1, status_code=http_client.SERVICE_UNAVAILABLE) good_resp = utils.mockSessionResponse( {'Content-Type': 'text/plain'}, "meow", version=1, status_code=http_client.OK) client = http.HTTPClient('http://localhost/') with mock.patch.object(client, 'session', autospec=True) as mock_session: mock_session.request.side_effect = iter([bad_resp, good_resp]) response, body_iter = client._http_request('/v1/resources', 'GET') self.assertEqual(http_client.OK, response.status_code) self.assertEqual(2, mock_session.request.call_count)
def test__http_request_explicit_version(self, mock_negotiate, mock_session): headers = {'User-Agent': 'python-ironicclient', 'X-OpenStack-Ironic-API-Version': '1.28'} kwargs = {'os_ironic_api_version': '1.30', 'api_version_select_state': 'negotiated'} mock_session.return_value = utils.mockSessionResponse( {}, status_code=http_client.NO_CONTENT, version=1) client = http.HTTPClient('http://localhost/', **kwargs) response, body_iter = client._http_request('/v1/resources', 'GET', headers=headers) mock_session.assert_called_once_with(mock.ANY, 'GET', 'http://localhost/v1/resources', headers=headers)
def test__http_request_explicit_version(self, mock_negotiate, mock_session): headers = {'User-Agent': 'python-ironicclient', 'X-OpenStack-Ironic-API-Version': '1.28'} kwargs = {'os_ironic_api_version': '1.30', 'api_version_select_state': 'negotiated'} mock_session.return_value = utils.mockSessionResponse( {}, status_code=http_client.NO_CONTENT, version=1) client = http.HTTPClient('http://localhost/', **kwargs) response, body_iter = client._http_request('/v1/resources', 'GET', headers=headers) mock_session.assert_called_once_with(mock.ANY, 'GET', 'http://localhost/v1/resources', headers=headers)
def test_http_no_retry(self): error_body = _get_error_body() bad_resp = utils.mockSessionResponse( {'Content-Type': 'text/plain'}, error_body, version=1, status_code=http_client.CONFLICT) client = http.HTTPClient('http://localhost/', max_retries=0) with mock.patch.object(client.session, 'request', autospec=True, return_value=bad_resp) as mock_request: self.assertRaises(exc.Conflict, client._http_request, '/v1/resources', 'GET') self.assertEqual(1, mock_request.call_count)
def test_http_no_retry(self): error_body = _get_error_body() bad_resp = utils.mockSessionResponse( {'Content-Type': 'text/plain'}, error_body, version=1, status_code=http_client.CONFLICT) client = http.HTTPClient('http://localhost/', max_retries=0) with mock.patch.object(client.session, 'request', autospec=True, return_value=bad_resp) as mock_request: self.assertRaises(exc.Conflict, client._http_request, '/v1/resources', 'GET') self.assertEqual(1, mock_request.call_count)
def test_session_retry_fail(self): error_body = _get_error_body() fake_resp = utils.mockSessionResponse( {'Content-Type': 'application/json'}, error_body, http_client.CONFLICT) fake_session = mock.Mock(spec=requests.Session) fake_session.request.return_value = fake_resp client = _session_client(session=fake_session) self.assertRaises(exc.Conflict, client.json_request, 'GET', '/v1/resources') self.assertEqual(http.DEFAULT_MAX_RETRIES + 1, fake_session.request.call_count)
def test_http_max_retries_none(self): error_body = _get_error_body() bad_resp = utils.mockSessionResponse({'content-type': 'text/plain'}, error_body, version=1, status_code=http_client.CONFLICT) client = http.HTTPClient('http://localhost/', max_retries=None) with mock.patch.object(client, 'session', autospec=True) as mock_session: mock_session.request.return_value = bad_resp self.assertRaises(exc.Conflict, client._http_request, '/v1/resources', 'GET') self.assertEqual(http.DEFAULT_MAX_RETRIES + 1, mock_session.request.call_count)
def test_http_retry_connection_refused(self): good_resp = utils.mockSessionResponse({'content-type': 'text/plain'}, "meow", version=1, status_code=http_client.OK) client = http.HTTPClient('http://localhost/') with mock.patch.object(client, 'session', autospec=True) as mock_session: mock_session.request.side_effect = iter( [exc.ConnectionRefused(), good_resp]) response, body_iter = client._http_request('/v1/resources', 'GET') self.assertEqual(http_client.OK, response.status_code) self.assertEqual(2, mock_session.request.call_count)
def test__parse_version_headers(self): # Test parsing of version headers from HTTPClient error_body = _get_error_body() expected_result = ('1.1', '1.6') client = http.HTTPClient('http://localhost/') fake_resp = utils.mockSessionResponse( {'X-OpenStack-Ironic-API-Minimum-Version': '1.1', 'X-OpenStack-Ironic-API-Maximum-Version': '1.6', 'Content-Type': 'text/plain', }, error_body, version=1, status_code=http_client.NOT_ACCEPTABLE) result = client._parse_version_headers(fake_resp) self.assertEqual(expected_result, result)
def test_http_retry_connection_refused(self): good_resp = utils.mockSessionResponse( {'content-type': 'text/plain'}, "meow", version=1, status_code=http_client.OK) client = http.HTTPClient('http://localhost/') with mock.patch.object(client, 'session', autospec=True) as mock_session: mock_session.request.side_effect = iter([exc.ConnectionRefused(), good_resp]) response, body_iter = client._http_request('/v1/resources', 'GET') self.assertEqual(http_client.OK, response.status_code) self.assertEqual(2, mock_session.request.call_count)
def test_http_max_retries_none(self): error_body = _get_error_body() bad_resp = utils.mockSessionResponse( {'content-type': 'text/plain'}, error_body, version=1, status_code=http_client.CONFLICT) client = http.HTTPClient('http://localhost/', max_retries=None) with mock.patch.object(client, 'session', autospec=True) as mock_session: mock_session.request.return_value = bad_resp self.assertRaises(exc.Conflict, client._http_request, '/v1/resources', 'GET') self.assertEqual(http.DEFAULT_MAX_RETRIES + 1, mock_session.request.call_count)
def test_session_retry_fail(self): error_body = _get_error_body() fake_resp = utils.mockSessionResponse( {'Content-Type': 'application/json'}, error_body, http_client.CONFLICT) fake_session = mock.Mock(spec=requests.Session) fake_session.request.return_value = fake_resp client = _session_client(session=fake_session) self.assertRaises(exc.Conflict, client.json_request, 'GET', '/v1/resources') self.assertEqual(http.DEFAULT_MAX_RETRIES + 1, fake_session.request.call_count)
def test_session_change_max_retries(self): error_body = _get_error_body() fake_resp = utils.mockSessionResponse( {'Content-Type': 'application/json'}, error_body, http_client.CONFLICT) fake_session = utils.mockSession({}) fake_session.request.return_value = fake_resp client = _session_client(session=fake_session) client.conflict_max_retries = http.DEFAULT_MAX_RETRIES + 1 self.assertRaises(exc.Conflict, client.json_request, 'GET', '/v1/resources') self.assertEqual(http.DEFAULT_MAX_RETRIES + 2, fake_session.request.call_count)
def test__parse_version_headers(self): # Test parsing of version headers from HTTPClient error_body = _get_error_body() expected_result = ('1.1', '1.6') client = http.HTTPClient('http://localhost/') fake_resp = utils.mockSessionResponse( {'X-OpenStack-Ironic-API-Minimum-Version': '1.1', 'X-OpenStack-Ironic-API-Maximum-Version': '1.6', 'Content-Type': 'text/plain', }, error_body, version=1, status_code=http_client.NOT_ACCEPTABLE) result = client._parse_version_headers(fake_resp) self.assertEqual(expected_result, result)