Move the object client to tempest.lib and cleanup the last bits of code that were required to manage internal-only tempest service clients. Change-Id: Ia9aeab78e530c798dfa7b7d6f71e4b3ea3a84b7fchanges/41/510841/7
parent
f36476e65a
commit
986407ddd3
@ -0,0 +1,25 @@
|
||||
# Copyright (c) 2016 Hewlett-Packard Enterprise Development Company, L.P.
|
||||
#
|
||||
# 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.lib.services.object_storage.account_client import AccountClient
|
||||
from tempest.lib.services.object_storage.bulk_middleware_client import \
|
||||
BulkMiddlewareClient
|
||||
from tempest.lib.services.object_storage.capabilities_client import \
|
||||
CapabilitiesClient
|
||||
from tempest.lib.services.object_storage.container_client import \
|
||||
ContainerClient
|
||||
from tempest.lib.services.object_storage.object_client import ObjectClient
|
||||
|
||||
__all__ = ['AccountClient', 'BulkMiddlewareClient', 'CapabilitiesClient',
|
||||
'ContainerClient', 'ObjectClient']
|
@ -1,25 +0,0 @@
|
||||
# Copyright (c) 2016 Hewlett-Packard Enterprise Development Company, L.P.
|
||||
#
|
||||
# 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.lib.services.object_storage.account_client import AccountClient
|
||||
from tempest.lib.services.object_storage.bulk_middleware_client import \
|
||||
BulkMiddlewareClient
|
||||
from tempest.lib.services.object_storage.capabilities_client import \
|
||||
CapabilitiesClient
|
||||
from tempest.lib.services.object_storage.container_client import \
|
||||
ContainerClient
|
||||
from tempest.services.object_storage.object_client import ObjectClient
|
||||
|
||||
__all__ = ['AccountClient', 'BulkMiddlewareClient', 'CapabilitiesClient',
|
||||
'ContainerClient', 'ObjectClient']
|
@ -0,0 +1,108 @@
|
||||
# Copyright 2016 IBM Corp.
|
||||
# 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.
|
||||
|
||||
|
||||
import mock
|
||||
|
||||
from tempest.lib import exceptions
|
||||
from tempest.lib.services.object_storage import object_client
|
||||
from tempest.tests import base
|
||||
from tempest.tests.lib import fake_auth_provider
|
||||
|
||||
|
||||
class TestObjectClient(base.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestObjectClient, self).setUp()
|
||||
self.fake_auth = fake_auth_provider.FakeAuthProvider()
|
||||
self.url = self.fake_auth.base_url(None)
|
||||
self.object_client = object_client.ObjectClient(self.fake_auth,
|
||||
'swift', 'region1')
|
||||
|
||||
@mock.patch.object(object_client, '_create_connection')
|
||||
def test_create_object_continue_no_data(self, mock_poc):
|
||||
self._validate_create_object_continue(None, mock_poc)
|
||||
|
||||
@mock.patch.object(object_client, '_create_connection')
|
||||
def test_create_object_continue_with_data(self, mock_poc):
|
||||
self._validate_create_object_continue('hello', mock_poc)
|
||||
|
||||
@mock.patch.object(object_client, '_create_connection')
|
||||
def test_create_continue_with_no_continue_received(self, mock_poc):
|
||||
self._validate_create_object_continue('hello', mock_poc,
|
||||
initial_status=201)
|
||||
|
||||
def _validate_create_object_continue(self, req_data,
|
||||
mock_poc, initial_status=100):
|
||||
|
||||
expected_hdrs = {
|
||||
'X-Auth-Token': self.fake_auth.get_token(),
|
||||
'content-length': 0 if req_data is None else len(req_data),
|
||||
'Expect': '100-continue'}
|
||||
|
||||
# Setup the Mocks prior to invoking the object creation
|
||||
mock_resp_cls = mock.Mock()
|
||||
mock_resp_cls._read_status.return_value = ("1", initial_status, "OK")
|
||||
|
||||
mock_poc.return_value.response_class.return_value = mock_resp_cls
|
||||
|
||||
# This is the final expected return value
|
||||
mock_poc.return_value.getresponse.return_value.status = 201
|
||||
mock_poc.return_value.getresponse.return_value.reason = 'OK'
|
||||
|
||||
# Call method to PUT object using expect:100-continue
|
||||
cnt = "container1"
|
||||
obj = "object1"
|
||||
path = "/%s/%s" % (cnt, obj)
|
||||
|
||||
# If the expected initial status is not 100, then an exception
|
||||
# should be thrown and the connection closed
|
||||
if initial_status is 100:
|
||||
status, reason = \
|
||||
self.object_client.create_object_continue(cnt, obj, req_data)
|
||||
else:
|
||||
self.assertRaises(exceptions.UnexpectedResponseCode,
|
||||
self.object_client.create_object_continue, cnt,
|
||||
obj, req_data)
|
||||
mock_poc.return_value.close.assert_called_once_with()
|
||||
|
||||
# Verify that putrequest is called 1 time with the appropriate values
|
||||
mock_poc.return_value.putrequest.assert_called_once_with('PUT', path)
|
||||
|
||||
# Verify that headers were written, including "Expect:100-continue"
|
||||
calls = []
|
||||
|
||||
for header, value in expected_hdrs.items():
|
||||
calls.append(mock.call(header, value))
|
||||
|
||||
mock_poc.return_value.putheader.assert_has_calls(calls, False)
|
||||
mock_poc.return_value.endheaders.assert_called_once_with()
|
||||
|
||||
# The following steps are only taken if the initial status is 100
|
||||
if initial_status is 100:
|
||||
# Verify that the method returned what it was supposed to
|
||||
self.assertEqual(status, 201)
|
||||
|
||||
# Verify that _safe_read was called once to remove the CRLF
|
||||
# after the 100 response
|
||||
mock_rc = mock_poc.return_value.response_class.return_value
|
||||
mock_rc._safe_read.assert_called_once_with(2)
|
||||
|
||||
# Verify the actual data was written via send
|
||||
mock_poc.return_value.send.assert_called_once_with(req_data)
|
||||
|
||||
# Verify that the getresponse method was called to receive
|
||||
# the final
|
||||
mock_poc.return_value.getresponse.assert_called_once_with()
|
Loading…
Reference in new issue