From 609298cce7c4878420a844de21158b9b5e7ca8fe Mon Sep 17 00:00:00 2001 From: ghanshyam Date: Thu, 20 Jul 2017 09:15:33 +0000 Subject: [PATCH] Fix object storage bulk middleware client return value All service clients methods return their response wrapped in ResponseBody, ResponseBodyData or ResponseBodyList. But object storage service clients were left out of this because response from object storage APIs are not same way other service return. Some APIs return is as string etc. This commit makes bulk_middleware_client to return ResponseBodyData object with consistency to other service clients. This is step to move these clients to lib. Partially implements blueprint consistent-service-method-names Change-Id: Iade0a1afd0e28ea42f12df175f55eadb1bea7071 --- .../api/object_storage/test_account_bulk.py | 41 ++++++------ .../object_storage/bulk_middleware_client.py | 10 +-- tempest/tests/lib/services/base.py | 7 +- .../test_bulk_middleware_client.py | 66 +++++++++++++++++++ 4 files changed, 97 insertions(+), 27 deletions(-) create mode 100644 tempest/tests/services/object_storage/test_bulk_middleware_client.py diff --git a/tempest/api/object_storage/test_account_bulk.py b/tempest/api/object_storage/test_account_bulk.py index e76541434e..7c538e8f33 100644 --- a/tempest/api/object_storage/test_account_bulk.py +++ b/tempest/api/object_storage/test_account_bulk.py @@ -58,9 +58,9 @@ class BulkTest(base.BaseObjectTest): # upload an archived file with open(filepath) as fh: mydata = fh.read() - resp, body = self.bulk_client.upload_archive( + resp = self.bulk_client.upload_archive( upload_path='', data=mydata, archive_file_format='tar') - return resp, body + return resp def _check_contents_deleted(self, container_name): param = {'format': 'txt'} @@ -73,21 +73,20 @@ class BulkTest(base.BaseObjectTest): def test_extract_archive(self): # Test bulk operation of file upload with an archived file filepath, container_name, object_name = self._create_archive() - resp, _ = self._upload_archive(filepath) - + resp = self._upload_archive(filepath) self.containers.append(container_name) # When uploading an archived file with the bulk operation, the response # does not contain 'content-length' header. This is the special case, # therefore the existence of response headers is checked without # custom matcher. - self.assertIn('transfer-encoding', resp) - self.assertIn('content-type', resp) - self.assertIn('x-trans-id', resp) - self.assertIn('date', resp) + self.assertIn('transfer-encoding', resp.response) + self.assertIn('content-type', resp.response) + self.assertIn('x-trans-id', resp.response) + self.assertIn('date', resp.response) # Check only the format of common headers with custom matcher - self.assertThat(resp, custom_matchers.AreAllWellFormatted()) + self.assertThat(resp.response, custom_matchers.AreAllWellFormatted()) param = {'format': 'json'} resp, body = self.account_client.list_account_containers(param) @@ -112,19 +111,19 @@ class BulkTest(base.BaseObjectTest): self._upload_archive(filepath) data = '%s/%s\n%s' % (container_name, object_name, container_name) - resp, _ = self.bulk_client.delete_bulk_data(data=data) + resp = self.bulk_client.delete_bulk_data(data=data) # When deleting multiple files using the bulk operation, the response # does not contain 'content-length' header. This is the special case, # therefore the existence of response headers is checked without # custom matcher. - self.assertIn('transfer-encoding', resp) - self.assertIn('content-type', resp) - self.assertIn('x-trans-id', resp) - self.assertIn('date', resp) + self.assertIn('transfer-encoding', resp.response) + self.assertIn('content-type', resp.response) + self.assertIn('x-trans-id', resp.response) + self.assertIn('date', resp.response) # Check only the format of common headers with custom matcher - self.assertThat(resp, custom_matchers.AreAllWellFormatted()) + self.assertThat(resp.response, custom_matchers.AreAllWellFormatted()) # Check if uploaded contents are completely deleted self._check_contents_deleted(container_name) @@ -138,19 +137,19 @@ class BulkTest(base.BaseObjectTest): data = '%s/%s\n%s' % (container_name, object_name, container_name) - resp, _ = self.bulk_client.delete_bulk_data_with_post(data=data) + resp = self.bulk_client.delete_bulk_data_with_post(data=data) # When deleting multiple files using the bulk operation, the response # does not contain 'content-length' header. This is the special case, # therefore the existence of response headers is checked without # custom matcher. - self.assertIn('transfer-encoding', resp) - self.assertIn('content-type', resp) - self.assertIn('x-trans-id', resp) - self.assertIn('date', resp) + self.assertIn('transfer-encoding', resp.response) + self.assertIn('content-type', resp.response) + self.assertIn('x-trans-id', resp.response) + self.assertIn('date', resp.response) # Check only the format of common headers with custom matcher - self.assertThat(resp, custom_matchers.AreAllWellFormatted()) + self.assertThat(resp.response, custom_matchers.AreAllWellFormatted()) # Check if uploaded contents are completely deleted self._check_contents_deleted(container_name) diff --git a/tempest/services/object_storage/bulk_middleware_client.py b/tempest/services/object_storage/bulk_middleware_client.py index c194ea9090..4e8d629707 100644 --- a/tempest/services/object_storage/bulk_middleware_client.py +++ b/tempest/services/object_storage/bulk_middleware_client.py @@ -31,7 +31,7 @@ class BulkMiddlewareClient(rest_client.RestClient): headers = {} resp, body = self.put(url, data, headers) self.expected_success(200, resp.status) - return resp, body + return rest_client.ResponseBodyData(resp, body) def delete_bulk_data(self, data=None, headers=None): """Delete multiple objects or containers from their account. @@ -43,9 +43,9 @@ class BulkMiddlewareClient(rest_client.RestClient): if headers is None: headers = {} - resp, body = self.delete(url, headers=headers, body=data) + resp, body = self.delete(url, headers, data) self.expected_success(200, resp.status) - return resp, body + return rest_client.ResponseBodyData(resp, body) def delete_bulk_data_with_post(self, data=None, headers=None): """Delete multiple objects or containers with POST request. @@ -57,6 +57,6 @@ class BulkMiddlewareClient(rest_client.RestClient): if headers is None: headers = {} - resp, body = self.post(url, headers=headers, body=data) + resp, body = self.post(url, data, headers) self.expected_success([200, 204], resp.status) - return resp, body + return rest_client.ResponseBodyData(resp, body) diff --git a/tempest/tests/lib/services/base.py b/tempest/tests/lib/services/base.py index 778c966049..924f9f2062 100644 --- a/tempest/tests/lib/services/base.py +++ b/tempest/tests/lib/services/base.py @@ -32,6 +32,7 @@ class BaseServiceTest(base.TestCase): def check_service_client_function(self, function, function2mock, body, to_utf=False, status=200, headers=None, mock_args=None, + resp_as_string=False, **kwargs): """Mock a service client function for unit testing. @@ -53,6 +54,9 @@ class BaseServiceTest(base.TestCase): ``assert_called_once_with(foo='bar')`` is called. * If mock_args='foo' then ``assert_called_once_with('foo')`` is called. + :param resp_as_string: Whether response body is retruned as string. + This is for service client methods which return ResponseBodyData + object. :param kwargs: kwargs that are passed to function. """ mocked_response = self.create_response(body, to_utf, status, headers) @@ -62,8 +66,9 @@ class BaseServiceTest(base.TestCase): resp = function(**kwargs) else: resp = function() + if resp_as_string: + resp = resp.data self.assertEqual(body, resp) - if isinstance(mock_args, list): fixture.mock.assert_called_once_with(*mock_args) elif isinstance(mock_args, dict): diff --git a/tempest/tests/services/object_storage/test_bulk_middleware_client.py b/tempest/tests/services/object_storage/test_bulk_middleware_client.py new file mode 100644 index 0000000000..163b48e6f4 --- /dev/null +++ b/tempest/tests/services/object_storage/test_bulk_middleware_client.py @@ -0,0 +1,66 @@ +# Copyright 2017 NEC Corporation. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from tempest.services.object_storage import bulk_middleware_client +from tempest.tests.lib import fake_auth_provider +from tempest.tests.lib.services import base + + +class TestBulkMiddlewareClient(base.BaseServiceTest): + + def setUp(self): + super(TestBulkMiddlewareClient, self).setUp() + fake_auth = fake_auth_provider.FakeAuthProvider() + self.client = bulk_middleware_client.BulkMiddlewareClient( + fake_auth, 'object-storage', 'regionOne') + + def test_upload_archive(self): + url = 'test_path?extract-archive=tar' + data = 'test_data' + self.check_service_client_function( + self.client.upload_archive, + 'tempest.lib.common.rest_client.RestClient.put', + {}, + mock_args=[url, data, {}], + resp_as_string=True, + upload_path='test_path', data=data, archive_file_format='tar') + + def test_delete_bulk_data(self): + url = '?bulk-delete' + data = 'test_data' + self.check_service_client_function( + self.client.delete_bulk_data, + 'tempest.lib.common.rest_client.RestClient.delete', + {}, + mock_args=[url, {}, data], + resp_as_string=True, + data=data) + + def _test_delete_bulk_data_with_post(self, status): + url = '?bulk-delete' + data = 'test_data' + self.check_service_client_function( + self.client.delete_bulk_data_with_post, + 'tempest.lib.common.rest_client.RestClient.post', + {}, + mock_args=[url, data, {}], + resp_as_string=True, + status=status, + data=data) + + def test_delete_bulk_data_with_post_200(self): + self._test_delete_bulk_data_with_post(200) + + def test_delete_bulk_data_with_post_204(self): + self._test_delete_bulk_data_with_post(204)