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.FakeSessionResponse( {'X-OpenStack-Ironic-API-Minimum-Version': '1.1', 'X-OpenStack-Ironic-API-Maximum-Version': '1.6', 'content-type': 'text/plain', }, six.StringIO(error_body), version=1, status_code=http_client.NOT_ACCEPTABLE) good_resp = utils.FakeSessionResponse( {'X-OpenStack-Ironic-API-Minimum-Version': '1.1', 'X-OpenStack-Ironic-API-Maximum-Version': '1.6', 'content-type': 'text/plain', }, six.StringIO("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_503(self): error_body = _get_error_body() fake_resp = utils.FakeSessionResponse( {'Content-Type': 'application/json'}, error_body, 503) ok_resp = utils.FakeSessionResponse( {'Content-Type': 'application/json'}, b"OK", 200) fake_session = mock.Mock(spec=utils.FakeSession) 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.FakeSession({'content-type': 'application/json'}, status_code=http_client.NO_CONTENT) request_mock = mock.Mock() fake_session.request = request_mock request_mock.return_value = utils.FakeSessionResponse( 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_connection_refused(self): ok_resp = utils.FakeSessionResponse( {'Content-Type': 'application/json'}, b"OK", 200) fake_session = mock.Mock(spec=utils.FakeSession) 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_session_retry_retriable_connection_failure(self): ok_resp = utils.FakeSessionResponse( {'Content-Type': 'application/json'}, b"OK", http_client.OK) fake_session = mock.Mock(spec=utils.FakeSession) 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.FakeSessionResponse( {'Content-Type': 'text/plain'}, six.StringIO(error_body), version=1, status_code=http_client.SERVICE_UNAVAILABLE) good_resp = utils.FakeSessionResponse({'Content-Type': 'text/plain'}, six.StringIO("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_fail(self): error_body = _get_error_body() fake_resp = utils.FakeSessionResponse( {'Content-Type': 'application/json'}, error_body, 409) fake_session = mock.Mock(spec=utils.FakeSession) 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_retry(self): error_body = _get_error_body() fake_resp = utils.FakeSessionResponse( {'Content-Type': 'application/json'}, error_body, 409) ok_resp = utils.FakeSessionResponse( {'Content-Type': 'application/json'}, b"OK", 200) fake_session = mock.Mock(spec=utils.FakeSession) fake_session.request.side_effect = iter((fake_resp, ok_resp)) client = http.SessionClient(session=fake_session, auth=None, interface=None, service_type='publicURL', region_name='', service_name=None) client.json_request('GET', '/v1/resources') self.assertEqual(2, fake_session.request.call_count)
def test_http_no_retry(self): error_body = _get_error_body() bad_resp = utils.FakeSessionResponse( {'Content-Type': 'text/plain'}, six.StringIO(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_max_retries_none(self): error_body = _get_error_body() bad_resp = utils.FakeSessionResponse({'content-type': 'text/plain'}, six.StringIO(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.FakeSessionResponse({'content-type': 'text/plain'}, six.StringIO("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.FakeSessionResponse( {'X-OpenStack-Ironic-API-Minimum-Version': '1.1', 'X-OpenStack-Ironic-API-Maximum-Version': '1.6', 'Content-Type': 'text/plain', }, six.StringIO(error_body), version=1, status_code=http_client.NOT_ACCEPTABLE) result = client._parse_version_headers(fake_resp) self.assertEqual(expected_result, result)
def test_session_retry_fail(self): error_body = _get_error_body() fake_resp = utils.FakeSessionResponse( {'Content-Type': 'application/json'}, error_body, 409) fake_session = mock.Mock(spec=utils.FakeSession) fake_session.request.return_value = fake_resp client = http.SessionClient(session=fake_session, auth=None, interface=None, service_type='publicURL', region_name='', service_name=None) self.assertRaises(exc.Conflict, client.json_request, 'GET', '/v1/resources') self.assertEqual(http.DEFAULT_MAX_RETRIES + 1, fake_session.request.call_count)