diff --git a/mixmatch/proxy.py b/mixmatch/proxy.py index ad6b220..4ab6196 100644 --- a/mixmatch/proxy.py +++ b/mixmatch/proxy.py @@ -203,19 +203,16 @@ class RequestHandler(object): return resp def _finalize(self, response): - if not self.stream: - final_response = flask.Response( - response.text, - response.status_code - ) - for key, value in response.headers.items(): - final_response.headers[key] = value + if self.stream: + text = flask.stream_with_context(stream_response(response)) else: - final_response = flask.Response( - flask.stream_with_context(stream_response(response)), - response.status_code, - content_type=response.headers['content-type'] - ) + text = response.text + + final_response = flask.Response( + text, + response.status_code, + headers=self._prepare_headers(response.headers) + ) LOG.info(format_for_log(title='Response from proxy', status_code=final_response.status_code, url=response.url, @@ -298,8 +295,11 @@ class RequestHandler(object): headers = dict() headers['Accept'] = user_headers.get('Accept', '') headers['Content-Type'] = user_headers.get('Content-Type', '') + accepted_headers = ['openstack-api-version'] for key, value in user_headers.items(): - if key.lower().startswith('x-') and not is_token_header_key(key): + k = key.lower() + if ((k.startswith('x-') and not is_token_header_key(key)) or + k in accepted_headers): headers[key] = value return headers diff --git a/mixmatch/tests/functional/tempest_blacklist.txt b/mixmatch/tests/functional/tempest_blacklist.txt index e99e926..286a624 100644 --- a/mixmatch/tests/functional/tempest_blacklist.txt +++ b/mixmatch/tests/functional/tempest_blacklist.txt @@ -17,11 +17,6 @@ tempest.api.volume.test_volumes_list.VolumesListTestJSON.test_volume_list_detail tempest.api.volume.test_volumes_snapshots.VolumesSnapshotTestJSON.test_snapshot_create_with_volume_in_use tempest.api.image.v2.test_images.BasicOperationsImagesTest.test_deactivate_reactivate_image -# These fail with Object not found because we do not handle /volume/v3//messages -tempest.api.volume.admin.test_user_messages.UserMessagesTest.test_show_message -tempest.api.volume.admin.test_user_messages.UserMessagesTest.test_list_messages -tempest.api.volume.admin.test_user_messages.UserMessagesTest.test_delete_message - # TODO(knikolla): Investigate these failures tempest.api.object_storage.test_container_sync_middleware.ContainerSyncMiddlewareTest tempest.api.compute.images.test_images_oneserver.ImagesOneServerTestJSON.test_create_image_specify_multibyte_character_image_name diff --git a/mixmatch/tests/unit/test_request_handler.py b/mixmatch/tests/unit/test_request_handler.py index 2cbb641..a8fba2c 100644 --- a/mixmatch/tests/unit/test_request_handler.py +++ b/mixmatch/tests/unit/test_request_handler.py @@ -43,14 +43,17 @@ class TestRequestHandler(BaseTest): 'extra cheese': 'x-tra cheese', 'y-auth-token': 'x-auth-token', 'xauth-token': 'x-auth-token', - 'start-x': 'startx' + 'start-x': 'startx', + + 'OpenStack-API-Version': 'volume 3.0' } expected_headers = { 'x-tra cheese': 'extra cheese', 'x-goth-token': 'x-auth-token', 'X-MEN': 'X MEN', 'Accept': '', - 'Content-Type': '' + 'Content-Type': '', + 'OpenStack-API-Version': 'volume 3.0' } headers = proxy.RequestHandler._prepare_headers(user_headers) self.assertEqual(expected_headers, headers) diff --git a/mixmatch/tests/unit/test_volumes.py b/mixmatch/tests/unit/test_volumes.py index 8cbbb02..0c86830 100644 --- a/mixmatch/tests/unit/test_volumes.py +++ b/mixmatch/tests/unit/test_volumes.py @@ -22,6 +22,69 @@ from mixmatch.model import insert, ResourceMapping from mixmatch.tests.unit import samples +class TestVolumesV3(base.BaseTest): + def setUp(self): + super(TestVolumesV3, self).setUp() + # TODO(knikolla): load_auth_fixtures() should be done in the base + # class, but may conflict with the other tests which haven't been + # migrated to these fixtures. + self.load_auth_fixtures() + + def _construct_url(self, auth=None, target=None, sp=None, + resource_type='volumes'): + if not sp: + url = '/volume' + else: + url = self.service_providers[sp]['volume_endpoint'] + + if auth: + url = '%(url)s/v3/%(project_id)s/%(resource_type)s' % { + 'url': url, + 'project_id': auth.get_project_id(), + 'resource_type': resource_type + } + if target: + url = '%s/%s' % (url, target) + + return url + + def test_get_messages(self): + fake_message_list = uuid.uuid4().hex + + self.requests_fixture.get( + self._construct_url(self.auth, + resource_type='messages', + sp='default'), + request_headers=self.auth.get_headers(), + text=six.u(fake_message_list), + headers={'CONTENT-TYPE': 'application/json'} + ) + response = self.app.get( + self._construct_url(self.auth, resource_type='messages'), + headers=self.auth.get_headers() + ) + self.assertEqual(response.data, six.b(fake_message_list)) + + def test_get_message(self): + fake_message = uuid.uuid4().hex + + self.requests_fixture.get( + self._construct_url(self.auth, + fake_message, + resource_type='messages', + sp='default'), + request_headers=self.auth.get_headers(), + text=six.u(fake_message), + headers={'CONTENT-TYPE': 'application/json'} + ) + response = self.app.get( + self._construct_url(self.auth, fake_message, + resource_type='messages'), + headers=self.auth.get_headers() + ) + self.assertEqual(response.data, six.b(fake_message)) + + class TestVolumesV2(base.BaseTest): def setUp(self): super(TestVolumesV2, self).setUp()