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
diff --git a/tempest/api/object_storage/test_account_bulk.py b/tempest/api/object_storage/test_account_bulk.py
index e765414..7c538e8 100644
--- a/tempest/api/object_storage/test_account_bulk.py
+++ b/tempest/api/object_storage/test_account_bulk.py
@@ -58,9 +58,9 @@
         # 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 @@
     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 @@
         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 @@
 
         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 c194ea9..4e8d629 100644
--- a/tempest/services/object_storage/bulk_middleware_client.py
+++ b/tempest/services/object_storage/bulk_middleware_client.py
@@ -31,7 +31,7 @@
             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 @@
 
         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 @@
 
         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 778c966..924f9f2 100644
--- a/tempest/tests/lib/services/base.py
+++ b/tempest/tests/lib/services/base.py
@@ -32,6 +32,7 @@
     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 @@
                  ``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 @@
             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 0000000..163b48e
--- /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)