From 31018bf7c2c57c530d55ed1dd90b9b65d489d557 Mon Sep 17 00:00:00 2001 From: Dean Troyer Date: Thu, 18 Sep 2014 00:54:52 -0500 Subject: [PATCH] Move object-store commands to low-level API api.object_store.APIv1 now contains the formerly top-level functions implementing the object-store REST client. This replaces the old-style ObjectClientv1 that is no longer necessary. Change-Id: I7d8fea326b214481e7d6b24119bd41777c6aa968 --- openstackclient/api/object_store_v1.py | 381 ++++++++++++++++++ openstackclient/object/client.py | 22 +- openstackclient/object/v1/container.py | 29 +- openstackclient/object/v1/lib/container.py | 170 -------- openstackclient/object/v1/lib/object.py | 221 ---------- openstackclient/object/v1/object.py | 42 +- .../tests/api/test_object_store_v1.py | 326 +++++++++++++++ .../tests/object/v1/lib/__init__.py | 0 .../tests/object/v1/lib/test_container.py | 207 ---------- .../tests/object/v1/lib/test_object.py | 295 -------------- .../tests/object/v1/test_container.py | 81 +--- .../tests/object/v1/test_container_all.py | 6 +- .../tests/object/v1/test_object.py | 59 +-- 13 files changed, 773 insertions(+), 1066 deletions(-) create mode 100644 openstackclient/api/object_store_v1.py delete mode 100644 openstackclient/object/v1/lib/container.py delete mode 100644 openstackclient/object/v1/lib/object.py create mode 100644 openstackclient/tests/api/test_object_store_v1.py delete mode 100644 openstackclient/tests/object/v1/lib/__init__.py delete mode 100644 openstackclient/tests/object/v1/lib/test_container.py delete mode 100644 openstackclient/tests/object/v1/lib/test_object.py diff --git a/openstackclient/api/object_store_v1.py b/openstackclient/api/object_store_v1.py new file mode 100644 index 0000000000..f938b55ed5 --- /dev/null +++ b/openstackclient/api/object_store_v1.py @@ -0,0 +1,381 @@ +# 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. +# + +"""Object Store v1 API Library""" + +import os +import six + +try: + from urllib.parse import urlparse # noqa +except ImportError: + from urlparse import urlparse # noqa + +from openstackclient.api import api + + +class APIv1(api.BaseAPI): + """Object Store v1 API""" + + def __init__(self, **kwargs): + super(APIv1, self).__init__(**kwargs) + + def container_create( + self, + container=None, + ): + """Create a container + + :param string container: + name of container to create + :returns: + dict of returned headers + """ + + response = self.create(container, method='PUT') + url_parts = urlparse(self.endpoint) + data = { + 'account': url_parts.path.split('/')[-1], + 'container': container, + 'x-trans-id': response.headers.get('x-trans-id', None), + } + + return data + + def container_delete( + self, + container=None, + ): + """Delete a container + + :param string container: + name of container to delete + """ + + if container: + self.delete(container) + + def container_list( + self, + all_data=False, + limit=None, + marker=None, + end_marker=None, + prefix=None, + **params + ): + """Get containers in an account + + :param boolean all_data: + if True, return a full listing, else returns a max of + 10000 listings + :param integer limit: + query return count limit + :param string marker: + query marker + :param string end_marker: + query end_marker + :param string prefix: + query prefix + :returns: + list of container names + """ + + params['format'] = 'json' + + if all_data: + data = listing = self.container_list( + limit=limit, + marker=marker, + end_marker=end_marker, + prefix=prefix, + **params + ) + while listing: + marker = listing[-1]['name'] + listing = self.container_list( + limit=limit, + marker=marker, + end_marker=end_marker, + prefix=prefix, + **params + ) + if listing: + data.extend(listing) + return data + + if limit: + params['limit'] = limit + if marker: + params['marker'] = marker + if end_marker: + params['end_marker'] = end_marker + if prefix: + params['prefix'] = prefix + + return self.list('', **params) + + def container_save( + self, + container=None, + ): + """Save all the content from a container + + :param string container: + name of container to save + """ + + objects = self.object_list(container=container) + for object in objects: + self.object_save(container=container, object=object['name']) + + def container_show( + self, + container=None, + ): + """Get container details + + :param string container: + name of container to show + :returns: + dict of returned headers + """ + + response = self._request('HEAD', container) + data = { + 'account': response.headers.get('x-container-meta-owner', None), + 'container': container, + 'object_count': response.headers.get( + 'x-container-object-count', + None, + ), + 'bytes_used': response.headers.get('x-container-bytes-used', None), + 'read_acl': response.headers.get('x-container-read', None), + 'write_acl': response.headers.get('x-container-write', None), + 'sync_to': response.headers.get('x-container-sync-to', None), + 'sync_key': response.headers.get('x-container-sync-key', None), + } + return data + + def object_create( + self, + container=None, + object=None, + ): + """Create an object inside a container + + :param string container: + name of container to store object + :param string object: + local path to object + :returns: + dict of returned headers + """ + + if container is None or object is None: + # TODO(dtroyer): What exception to raise here? + return {} + + full_url = "%s/%s" % (container, object) + response = self.create(full_url, method='PUT', data=open(object)) + url_parts = urlparse(self.endpoint) + data = { + 'account': url_parts.path.split('/')[-1], + 'container': container, + 'object': object, + 'x-trans-id': response.headers.get('X-Trans-Id', None), + 'etag': response.headers.get('Etag', None), + } + + return data + + def object_delete( + self, + container=None, + object=None, + ): + """Delete an object from a container + + :param string container: + name of container that stores object + :param string object: + name of object to delete + """ + + if container is None or object is None: + return + + self.delete("%s/%s" % (container, object)) + + def object_list( + self, + container=None, + all_data=False, + limit=None, + marker=None, + end_marker=None, + delimiter=None, + prefix=None, + **params + ): + """List objects in a container + + :param string container: + container name to get a listing for + :param boolean all_data: + if True, return a full listing, else returns a max of + 10000 listings + :param integer limit: + query return count limit + :param string marker: + query marker + :param string end_marker: + query end_marker + :param string prefix: + query prefix + :param string delimiter: + string to delimit the queries on + :returns: a tuple of (response headers, a list of objects) The response + headers will be a dict and all header names will be lowercase. + """ + + if container is None or object is None: + return None + + if all_data: + data = listing = self.object_list( + container=container, + limit=limit, + marker=marker, + end_marker=end_marker, + prefix=prefix, + delimiter=delimiter, + **params + ) + while listing: + if delimiter: + marker = listing[-1].get('name', listing[-1].get('subdir')) + else: + marker = listing[-1]['name'] + listing = self.object_list( + container=container, + limit=limit, + marker=marker, + end_marker=end_marker, + prefix=prefix, + delimiter=delimiter, + **params + ) + if listing: + data.extend(listing) + return data + + params = {} + if limit: + params['limit'] = limit + if marker: + params['marker'] = marker + if end_marker: + params['end_marker'] = end_marker + if prefix: + params['prefix'] = prefix + if delimiter: + params['delimiter'] = delimiter + + return self.list(container, **params) + + def object_save( + self, + container=None, + object=None, + file=None, + ): + """Save an object stored in a container + + :param string container: + name of container that stores object + :param string object: + name of object to save + :param string file: + local name of object + """ + + if not file: + file = object + + response = self._request( + 'GET', + "%s/%s" % (container, object), + stream=True, + ) + if response.status_code == 200: + if not os.path.exists(os.path.dirname(file)): + os.makedirs(os.path.dirname(file)) + with open(file, 'wb') as f: + for chunk in response.iter_content(): + f.write(chunk) + + def object_show( + self, + container=None, + object=None, + ): + """Get object details + + :param string container: + container name for object to get + :param string object: + name of object to get + :returns: + dict of object properties + """ + + if container is None or object is None: + return {} + + response = self._request('HEAD', "%s/%s" % (container, object)) + data = { + 'account': response.headers.get('x-container-meta-owner', None), + 'container': container, + 'object': object, + 'content-type': response.headers.get('content-type', None), + } + if 'content-length' in response.headers: + data['content-length'] = response.headers.get( + 'content-length', + None, + ) + if 'last-modified' in response.headers: + data['last-modified'] = response.headers.get('last-modified', None) + if 'etag' in response.headers: + data['etag'] = response.headers.get('etag', None) + if 'x-object-manifest' in response.headers: + data['x-object-manifest'] = response.headers.get( + 'x-object-manifest', + None, + ) + for key, value in six.iteritems(response.headers): + if key.startswith('x-object-meta-'): + data[key[len('x-object-meta-'):].lower()] = value + elif key not in ( + 'content-type', + 'content-length', + 'last-modified', + 'etag', + 'date', + 'x-object-manifest', + 'x-container-meta-owner', + ): + data[key.lower()] = value + + return data diff --git a/openstackclient/object/client.py b/openstackclient/object/client.py index b81ffaaf44..887aa85b8e 100644 --- a/openstackclient/object/client.py +++ b/openstackclient/object/client.py @@ -17,6 +17,7 @@ import logging +from openstackclient.api import object_store_v1 from openstackclient.common import utils LOG = logging.getLogger(__name__) @@ -30,7 +31,7 @@ API_VERSIONS = { def make_client(instance): - """Returns an object service client.""" + """Returns an object-store API client.""" object_client = utils.get_client_class( API_NAME, @@ -42,9 +43,11 @@ def make_client(instance): endpoint = instance._url else: endpoint = instance.get_endpoint_for_service_type("object-store") - client = object_client( + + client = object_store_v1.APIv1( + session=instance.session, + service_type='object-store', endpoint=endpoint, - token=instance._token, ) return client @@ -61,16 +64,3 @@ def build_option_parser(parser): DEFAULT_OBJECT_API_VERSION + ' (Env: OS_OBJECT_API_VERSION)') return parser - - -class ObjectClientv1(object): - - def __init__( - self, - endpoint_type='publicURL', - endpoint=None, - token=None, - ): - self.endpoint_type = endpoint_type - self.endpoint = endpoint - self.token = token diff --git a/openstackclient/object/v1/container.py b/openstackclient/object/v1/container.py index 9d55381cbe..ead3df45e9 100644 --- a/openstackclient/object/v1/container.py +++ b/openstackclient/object/v1/container.py @@ -24,7 +24,6 @@ from cliff import lister from cliff import show from openstackclient.common import utils -from openstackclient.object.v1.lib import container as lib_container class CreateContainer(lister.Lister): @@ -47,10 +46,8 @@ class CreateContainer(lister.Lister): results = [] for container in parsed_args.containers: - data = lib_container.create_container( - self.app.client_manager.session, - self.app.client_manager.object_store.endpoint, - container, + data = self.app.client_manager.object_store.container_create( + container=container, ) results.append(data) @@ -81,10 +78,8 @@ class DeleteContainer(command.Command): self.log.debug('take_action(%s)', parsed_args) for container in parsed_args.containers: - lib_container.delete_container( - self.app.client_manager.session, - self.app.client_manager.object_store.endpoint, - container, + self.app.client_manager.object_store.container_delete( + container=container, ) @@ -150,9 +145,7 @@ class ListContainer(lister.Lister): if parsed_args.all: kwargs['full_listing'] = True - data = lib_container.list_containers( - self.app.client_manager.session, - self.app.client_manager.object_store.endpoint, + data = self.app.client_manager.object_store.container_list( **kwargs ) @@ -180,10 +173,8 @@ class SaveContainer(command.Command): def take_action(self, parsed_args): self.log.debug("take_action(%s)", parsed_args) - lib_container.save_container( - self.app.client_manager.session, - self.app.client_manager.object_store.endpoint, - parsed_args.container + self.app.client_manager.object_store.container_save( + container=parsed_args.container, ) @@ -204,10 +195,8 @@ class ShowContainer(show.ShowOne): def take_action(self, parsed_args): self.log.debug('take_action(%s)', parsed_args) - data = lib_container.show_container( - self.app.client_manager.session, - self.app.client_manager.object_store.endpoint, - parsed_args.container, + data = self.app.client_manager.object_store.container_show( + container=parsed_args.container, ) return zip(*sorted(six.iteritems(data))) diff --git a/openstackclient/object/v1/lib/container.py b/openstackclient/object/v1/lib/container.py deleted file mode 100644 index 4293ff4a20..0000000000 --- a/openstackclient/object/v1/lib/container.py +++ /dev/null @@ -1,170 +0,0 @@ -# Copyright 2010-2012 OpenStack Foundation -# Copyright 2013 Nebula Inc. -# -# 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. -# - -"""Object v1 API library""" - -try: - from urllib.parse import urlparse # noqa -except ImportError: - from urlparse import urlparse # noqa - -from openstackclient.object.v1.lib import object as object_lib - - -def create_container( - session, - url, - container, -): - """Create a container - - :param session: an authenticated keystoneclient.session.Session object - :param url: endpoint - :param container: name of container to create - :returns: dict of returned headers - """ - - response = session.put("%s/%s" % (url, container)) - url_parts = urlparse(url) - data = { - 'account': url_parts.path.split('/')[-1], - 'container': container, - 'x-trans-id': response.headers.get('x-trans-id', None), - } - - return data - - -def delete_container( - session, - url, - container, -): - """Delete a container - - :param session: an authenticated keystoneclient.session.Session object - :param url: endpoint - :param container: name of container to delete - """ - - session.delete("%s/%s" % (url, container)) - - -def list_containers( - session, - url, - marker=None, - limit=None, - end_marker=None, - prefix=None, - full_listing=False, -): - """Get containers in an account - - :param session: an authenticated keystoneclient.session.Session object - :param url: endpoint - :param marker: marker query - :param limit: limit query - :param end_marker: end_marker query - :param prefix: prefix query - :param full_listing: if True, return a full listing, else returns a max - of 10000 listings - :returns: list of containers - """ - - if full_listing: - data = listing = list_containers( - session, - url, - marker, - limit, - end_marker, - prefix, - ) - while listing: - marker = listing[-1]['name'] - listing = list_containers( - session, - url, - marker, - limit, - end_marker, - prefix, - ) - if listing: - data.extend(listing) - return data - - params = { - 'format': 'json', - } - if marker: - params['marker'] = marker - if limit: - params['limit'] = limit - if end_marker: - params['end_marker'] = end_marker - if prefix: - params['prefix'] = prefix - return session.get(url, params=params).json() - - -def save_container( - session, - url, - container -): - """Save all the content from a container - - :param session: an authenticated keystoneclient.session.Session object - :param url: endpoint - :param container: name of container to save - """ - - objects = object_lib.list_objects(session, url, container) - for object in objects: - object_lib.save_object(session, url, container, object['name']) - - -def show_container( - session, - url, - container, -): - """Get container details - - :param session: an authenticated keystoneclient.session.Session object - :param url: endpoint - :param container: name of container to show - :returns: dict of returned headers - """ - - response = session.head("%s/%s" % (url, container)) - data = { - 'account': response.headers.get('x-container-meta-owner', None), - 'container': container, - 'object_count': response.headers.get( - 'x-container-object-count', - None, - ), - 'bytes_used': response.headers.get('x-container-bytes-used', None), - 'read_acl': response.headers.get('x-container-read', None), - 'write_acl': response.headers.get('x-container-write', None), - 'sync_to': response.headers.get('x-container-sync-to', None), - 'sync_key': response.headers.get('x-container-sync-key', None), - } - - return data diff --git a/openstackclient/object/v1/lib/object.py b/openstackclient/object/v1/lib/object.py deleted file mode 100644 index 7a23fc7698..0000000000 --- a/openstackclient/object/v1/lib/object.py +++ /dev/null @@ -1,221 +0,0 @@ -# Copyright 2010-2012 OpenStack Foundation -# Copyright 2013 Nebula Inc. -# -# 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. -# - -"""Object v1 API library""" - -import os - -import six - -try: - from urllib.parse import urlparse # noqa -except ImportError: - from urlparse import urlparse # noqa - - -def create_object( - session, - url, - container, - object, -): - """Create an object, upload it to a container - - :param session: an authenticated keystoneclient.session.Session object - :param url: endpoint - :param container: name of container to store object - :param object: local path to object - :returns: dict of returned headers - """ - - full_url = "%s/%s/%s" % (url, container, object) - response = session.put(full_url, data=open(object)) - url_parts = urlparse(url) - data = { - 'account': url_parts.path.split('/')[-1], - 'container': container, - 'object': object, - 'x-trans-id': response.headers.get('X-Trans-Id', None), - 'etag': response.headers.get('Etag', None), - } - - return data - - -def delete_object( - session, - url, - container, - object, -): - """Delete an object stored in a container - - :param session: an authenticated keystoneclient.session.Session object - :param url: endpoint - :param container: name of container that stores object - :param container: name of object to delete - """ - - session.delete("%s/%s/%s" % (url, container, object)) - - -def list_objects( - session, - url, - container, - marker=None, - limit=None, - end_marker=None, - delimiter=None, - prefix=None, - path=None, - full_listing=False, -): - """Get objects in a container - - :param session: an authenticated keystoneclient.session.Session object - :param url: endpoint - :param container: container name to get a listing for - :param marker: marker query - :param limit: limit query - :param end_marker: marker query - :param delimiter: string to delimit the queries on - :param prefix: prefix query - :param path: path query (equivalent: "delimiter=/" and "prefix=path/") - :param full_listing: if True, return a full listing, else returns a max - of 10000 listings - :returns: a tuple of (response headers, a list of objects) The response - headers will be a dict and all header names will be lowercase. - """ - - if full_listing: - data = listing = list_objects( - session, - url, - container, - marker, - limit, - end_marker, - delimiter, - prefix, - path, - ) - while listing: - if delimiter: - marker = listing[-1].get('name', listing[-1].get('subdir')) - else: - marker = listing[-1]['name'] - listing = list_objects( - session, - url, - container, - marker, - limit, - end_marker, - delimiter, - prefix, - path, - ) - if listing: - data.extend(listing) - return data - - params = { - 'format': 'json', - } - if marker: - params['marker'] = marker - if limit: - params['limit'] = limit - if end_marker: - params['end_marker'] = end_marker - if delimiter: - params['delimiter'] = delimiter - if prefix: - params['prefix'] = prefix - if path: - params['path'] = path - requrl = "%s/%s" % (url, container) - return session.get(requrl, params=params).json() - - -def save_object( - session, - url, - container, - obj, - file=None -): - """Save an object stored in a container - - :param session: an authenticated keystoneclient.session.Session object - :param url: endpoint - :param container: name of container that stores object - :param object: name of object to save - :param file: local name of object - """ - - if not file: - file = obj - - response = session.get("%s/%s/%s" % (url, container, obj), stream=True) - if response.status_code == 200: - if not os.path.exists(os.path.dirname(file)): - os.makedirs(os.path.dirname(file)) - with open(file, 'wb') as f: - for chunk in response.iter_content(): - f.write(chunk) - - -def show_object( - session, - url, - container, - obj, -): - """Get object details - - :param session: an authenticated keystoneclient.session.Session object - :param url: endpoint - :param container: container name to get a listing for - :returns: dict of object properties - """ - - response = session.head("%s/%s/%s" % (url, container, obj)) - data = { - 'account': response.headers.get('x-container-meta-owner', None), - 'container': container, - 'object': obj, - 'content-type': response.headers.get('content-type', None), - } - if 'content-length' in response.headers: - data['content-length'] = response.headers.get('content-length', None) - if 'last-modified' in response.headers: - data['last-modified'] = response.headers.get('last-modified', None) - if 'etag' in response.headers: - data['etag'] = response.headers.get('etag', None) - if 'x-object-manifest' in response.headers: - data['x-object-manifest'] = response.headers.get( - 'x-object-manifest', None) - for key, value in six.iteritems(response.headers): - if key.startswith('x-object-meta-'): - data[key[len('x-object-meta-'):].lower()] = value - elif key not in ( - 'content-type', 'content-length', 'last-modified', - 'etag', 'date', 'x-object-manifest', 'x-container-meta-owner'): - data[key.lower()] = value - - return data diff --git a/openstackclient/object/v1/object.py b/openstackclient/object/v1/object.py index f0ea763300..cbe9da2fb4 100644 --- a/openstackclient/object/v1/object.py +++ b/openstackclient/object/v1/object.py @@ -24,7 +24,6 @@ from cliff import lister from cliff import show from openstackclient.common import utils -from openstackclient.object.v1.lib import object as lib_object class CreateObject(lister.Lister): @@ -52,11 +51,9 @@ class CreateObject(lister.Lister): results = [] for obj in parsed_args.objects: - data = lib_object.create_object( - self.app.client_manager.session, - self.app.client_manager.object_store.endpoint, - parsed_args.container, - obj, + data = self.app.client_manager.object_store.object_create( + container=parsed_args.container, + object=obj, ) results.append(data) @@ -92,12 +89,9 @@ class DeleteObject(command.Command): self.log.debug('take_action(%s)', parsed_args) for obj in parsed_args.objects: - lib_object.delete_object( - self.app.restapi, - self.app.client_manager.session, - self.app.client_manager.object_store.endpoint, - parsed_args.container, - obj, + self.app.client_manager.object_store.object_delete( + container=parsed_args.container, + object=obj, ) @@ -181,10 +175,8 @@ class ListObject(lister.Lister): if parsed_args.all: kwargs['full_listing'] = True - data = lib_object.list_objects( - self.app.client_manager.session, - self.app.client_manager.object_store.endpoint, - parsed_args.container, + data = self.app.client_manager.object_store.object_list( + container=parsed_args.container, **kwargs ) @@ -222,12 +214,10 @@ class SaveObject(command.Command): def take_action(self, parsed_args): self.log.debug("take_action(%s)", parsed_args) - lib_object.save_object( - self.app.client_manager.session, - self.app.client_manager.object_store.endpoint, - parsed_args.container, - parsed_args.object, - parsed_args.file, + self.app.client_manager.object_store.object_save( + container=parsed_args.container, + object=parsed_args.object, + file=parsed_args.file, ) @@ -253,11 +243,9 @@ class ShowObject(show.ShowOne): def take_action(self, parsed_args): self.log.debug('take_action(%s)', parsed_args) - data = lib_object.show_object( - self.app.client_manager.session, - self.app.client_manager.object_store.endpoint, - parsed_args.container, - parsed_args.object, + data = self.app.client_manager.object_store.object_show( + container=parsed_args.container, + object=parsed_args.object, ) return zip(*sorted(six.iteritems(data))) diff --git a/openstackclient/tests/api/test_object_store_v1.py b/openstackclient/tests/api/test_object_store_v1.py new file mode 100644 index 0000000000..5a376a454b --- /dev/null +++ b/openstackclient/tests/api/test_object_store_v1.py @@ -0,0 +1,326 @@ +# 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. +# + +"""Object Store v1 API Library Tests""" + +from requests_mock.contrib import fixture + +from keystoneclient import session +from openstackclient.api import object_store_v1 as object_store +from openstackclient.tests import utils + + +FAKE_ACCOUNT = 'q12we34r' +FAKE_AUTH = '11223344556677889900' +FAKE_URL = 'http://gopher.com/v1/' + FAKE_ACCOUNT + +FAKE_CONTAINER = 'rainbarrel' +FAKE_OBJECT = 'spigot' + +LIST_CONTAINER_RESP = [ + 'qaz', + 'fred', +] + +LIST_OBJECT_RESP = [ + {'name': 'fred', 'bytes': 1234, 'content_type': 'text'}, + {'name': 'wilma', 'bytes': 5678, 'content_type': 'text'}, +] + + +class TestObjectAPIv1(utils.TestCase): + + def setUp(self): + super(TestObjectAPIv1, self).setUp() + sess = session.Session() + self.api = object_store.APIv1(session=sess, endpoint=FAKE_URL) + self.requests_mock = self.useFixture(fixture.Fixture()) + + +class TestContainer(TestObjectAPIv1): + + def setUp(self): + super(TestContainer, self).setUp() + + def test_container_create(self): + headers = { + 'x-trans-id': '1qaz2wsx', + } + self.requests_mock.register_uri( + 'PUT', + FAKE_URL + '/qaz', + headers=headers, + status_code=201, + ) + ret = self.api.container_create(container='qaz') + data = { + 'account': FAKE_ACCOUNT, + 'container': 'qaz', + 'x-trans-id': '1qaz2wsx', + } + self.assertEqual(data, ret) + + def test_container_delete(self): + self.requests_mock.register_uri( + 'DELETE', + FAKE_URL + '/qaz', + status_code=204, + ) + ret = self.api.container_delete(container='qaz') + self.assertIsNone(ret) + + def test_container_list_no_options(self): + self.requests_mock.register_uri( + 'GET', + FAKE_URL, + json=LIST_CONTAINER_RESP, + status_code=200, + ) + ret = self.api.container_list() + self.assertEqual(LIST_CONTAINER_RESP, ret) + + def test_container_list_prefix(self): + self.requests_mock.register_uri( + 'GET', + FAKE_URL + '?prefix=foo%2f&format=json', + json=LIST_CONTAINER_RESP, + status_code=200, + ) + ret = self.api.container_list( + prefix='foo/', + ) + self.assertEqual(LIST_CONTAINER_RESP, ret) + + def test_container_list_marker_limit_end(self): + self.requests_mock.register_uri( + 'GET', + FAKE_URL + '?marker=next&limit=2&end_marker=stop&format=json', + json=LIST_CONTAINER_RESP, + status_code=200, + ) + ret = self.api.container_list( + marker='next', + limit=2, + end_marker='stop', + ) + self.assertEqual(LIST_CONTAINER_RESP, ret) + +# def test_container_list_full_listing(self): +# sess = self.app.client_manager.session +# +# def side_effect(*args, **kwargs): +# rv = sess.get().json.return_value +# sess.get().json.return_value = [] +# sess.get().json.side_effect = None +# return rv +# +# resp = [{'name': 'is-name'}] +# sess.get().json.return_value = resp +# sess.get().json.side_effect = side_effect +# +# data = lib_container.list_containers( +# self.app.client_manager.session, +# fake_url, +# full_listing=True, +# ) +# +# # Check expected values +# sess.get.assert_called_with( +# fake_url, +# params={ +# 'format': 'json', +# 'marker': 'is-name', +# } +# ) +# self.assertEqual(resp, data) + + def test_container_show(self): + headers = { + 'X-Container-Meta-Owner': FAKE_ACCOUNT, + 'x-container-object-count': '1', + 'x-container-bytes-used': '577', + } + resp = { + 'account': FAKE_ACCOUNT, + 'container': 'qaz', + 'object_count': '1', + 'bytes_used': '577', + 'read_acl': None, + 'write_acl': None, + 'sync_to': None, + 'sync_key': None, + } + self.requests_mock.register_uri( + 'HEAD', + FAKE_URL + '/qaz', + headers=headers, + status_code=204, + ) + ret = self.api.container_show(container='qaz') + self.assertEqual(resp, ret) + + +class TestObject(TestObjectAPIv1): + + def setUp(self): + super(TestObject, self).setUp() + + def test_object_create(self): + headers = { + 'etag': 'youreit', + 'x-trans-id': '1qaz2wsx', + } + self.requests_mock.register_uri( + 'PUT', + FAKE_URL + '/qaz/requirements.txt', + headers=headers, + status_code=201, + ) + ret = self.api.object_create( + container='qaz', + object='requirements.txt', + ) + data = { + 'account': FAKE_ACCOUNT, + 'container': 'qaz', + 'object': 'requirements.txt', + 'etag': 'youreit', + 'x-trans-id': '1qaz2wsx', + } + self.assertEqual(data, ret) + + def test_object_delete(self): + self.requests_mock.register_uri( + 'DELETE', + FAKE_URL + '/qaz/wsx', + status_code=204, + ) + ret = self.api.object_delete( + container='qaz', + object='wsx', + ) + self.assertIsNone(ret) + + def test_object_list_no_options(self): + self.requests_mock.register_uri( + 'GET', + FAKE_URL + '/qaz', + json=LIST_OBJECT_RESP, + status_code=200, + ) + ret = self.api.object_list(container='qaz') + self.assertEqual(LIST_OBJECT_RESP, ret) + + def test_object_list_delimiter(self): + self.requests_mock.register_uri( + 'GET', + FAKE_URL + '/qaz?delimiter=%7C', + json=LIST_OBJECT_RESP, + status_code=200, + ) + ret = self.api.object_list( + container='qaz', + delimiter='|', + ) + self.assertEqual(LIST_OBJECT_RESP, ret) + + def test_object_list_prefix(self): + self.requests_mock.register_uri( + 'GET', + FAKE_URL + '/qaz?prefix=foo%2f', + json=LIST_OBJECT_RESP, + status_code=200, + ) + ret = self.api.object_list( + container='qaz', + prefix='foo/', + ) + self.assertEqual(LIST_OBJECT_RESP, ret) + + def test_object_list_marker_limit_end(self): + self.requests_mock.register_uri( + 'GET', + FAKE_URL + '/qaz?marker=next&limit=2&end_marker=stop', + json=LIST_CONTAINER_RESP, + status_code=200, + ) + ret = self.api.object_list( + container='qaz', + marker='next', + limit=2, + end_marker='stop', + ) + self.assertEqual(LIST_CONTAINER_RESP, ret) + +# def test_list_objects_full_listing(self): +# sess = self.app.client_manager.session +# +# def side_effect(*args, **kwargs): +# rv = sess.get().json.return_value +# sess.get().json.return_value = [] +# sess.get().json.side_effect = None +# return rv +# +# resp = [{'name': 'is-name'}] +# sess.get().json.return_value = resp +# sess.get().json.side_effect = side_effect +# +# data = lib_object.list_objects( +# sess, +# fake_url, +# fake_container, +# full_listing=True, +# ) +# +# # Check expected values +# sess.get.assert_called_with( +# fake_url + '/' + fake_container, +# params={ +# 'format': 'json', +# 'marker': 'is-name', +# } +# ) +# self.assertEqual(resp, data) + + def test_object_show(self): + headers = { + 'content-type': 'text/alpha', + 'content-length': '577', + 'last-modified': '20130101', + 'etag': 'qaz', + 'x-container-meta-owner': FAKE_ACCOUNT, + 'x-object-meta-wife': 'Wilma', + 'x-tra-header': 'yabba-dabba-do', + } + resp = { + 'account': FAKE_ACCOUNT, + 'container': 'qaz', + 'object': FAKE_OBJECT, + 'content-type': 'text/alpha', + 'content-length': '577', + 'last-modified': '20130101', + 'etag': 'qaz', + 'wife': 'Wilma', + 'x-tra-header': 'yabba-dabba-do', + } + self.requests_mock.register_uri( + 'HEAD', + FAKE_URL + '/qaz/' + FAKE_OBJECT, + headers=headers, + status_code=204, + ) + ret = self.api.object_show( + container='qaz', + object=FAKE_OBJECT, + ) + self.assertEqual(resp, ret) diff --git a/openstackclient/tests/object/v1/lib/__init__.py b/openstackclient/tests/object/v1/lib/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/openstackclient/tests/object/v1/lib/test_container.py b/openstackclient/tests/object/v1/lib/test_container.py deleted file mode 100644 index ce70b8356b..0000000000 --- a/openstackclient/tests/object/v1/lib/test_container.py +++ /dev/null @@ -1,207 +0,0 @@ -# Copyright 2013 Nebula Inc. -# -# 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. -# - -"""Test Object API library module""" - -import mock - -from openstackclient.object.v1.lib import container as lib_container -from openstackclient.tests import fakes -from openstackclient.tests.object.v1 import fakes as object_fakes - - -fake_account = 'q12we34r' -fake_auth = '11223344556677889900' -fake_url = 'http://gopher.com/v1/' + fake_account - -fake_container = 'rainbarrel' - - -class FakeClient(object): - def __init__(self, endpoint=None, **kwargs): - self.endpoint = fake_url - self.token = fake_auth - - -class TestContainer(object_fakes.TestObjectv1): - - def setUp(self): - super(TestContainer, self).setUp() - self.app.client_manager.session = mock.MagicMock() - - -class TestContainerList(TestContainer): - - def test_container_list_no_options(self): - resp = [{'name': 'is-name'}] - self.app.client_manager.session.get().json.return_value = resp - - data = lib_container.list_containers( - self.app.client_manager.session, - fake_url, - ) - - # Check expected values - self.app.client_manager.session.get.assert_called_with( - fake_url, - params={ - 'format': 'json', - } - ) - self.assertEqual(resp, data) - - def test_container_list_marker(self): - resp = [{'name': 'is-name'}] - self.app.client_manager.session.get().json.return_value = resp - - data = lib_container.list_containers( - self.app.client_manager.session, - fake_url, - marker='next', - ) - - # Check expected values - self.app.client_manager.session.get.assert_called_with( - fake_url, - params={ - 'format': 'json', - 'marker': 'next', - } - ) - self.assertEqual(resp, data) - - def test_container_list_limit(self): - resp = [{'name': 'is-name'}] - self.app.client_manager.session.get().json.return_value = resp - - data = lib_container.list_containers( - self.app.client_manager.session, - fake_url, - limit=5, - ) - - # Check expected values - self.app.client_manager.session.get.assert_called_with( - fake_url, - params={ - 'format': 'json', - 'limit': 5, - } - ) - self.assertEqual(resp, data) - - def test_container_list_end_marker(self): - resp = [{'name': 'is-name'}] - self.app.client_manager.session.get().json.return_value = resp - - data = lib_container.list_containers( - self.app.client_manager.session, - fake_url, - end_marker='last', - ) - - # Check expected values - self.app.client_manager.session.get.assert_called_with( - fake_url, - params={ - 'format': 'json', - 'end_marker': 'last', - } - ) - self.assertEqual(resp, data) - - def test_container_list_prefix(self): - resp = [{'name': 'is-name'}] - self.app.client_manager.session.get().json.return_value = resp - - data = lib_container.list_containers( - self.app.client_manager.session, - fake_url, - prefix='foo/', - ) - - # Check expected values - self.app.client_manager.session.get.assert_called_with( - fake_url, - params={ - 'format': 'json', - 'prefix': 'foo/', - } - ) - self.assertEqual(resp, data) - - def test_container_list_full_listing(self): - sess = self.app.client_manager.session - - def side_effect(*args, **kwargs): - rv = sess.get().json.return_value - sess.get().json.return_value = [] - sess.get().json.side_effect = None - return rv - - resp = [{'name': 'is-name'}] - sess.get().json.return_value = resp - sess.get().json.side_effect = side_effect - - data = lib_container.list_containers( - self.app.client_manager.session, - fake_url, - full_listing=True, - ) - - # Check expected values - sess.get.assert_called_with( - fake_url, - params={ - 'format': 'json', - 'marker': 'is-name', - } - ) - self.assertEqual(resp, data) - - -class TestContainerShow(TestContainer): - - def test_container_show_no_options(self): - resp = { - 'X-Container-Meta-Owner': fake_account, - 'x-container-object-count': 1, - 'x-container-bytes-used': 577, - } - self.app.client_manager.session.head.return_value = \ - fakes.FakeResponse(headers=resp) - - data = lib_container.show_container( - self.app.client_manager.session, - fake_url, - 'is-name', - ) - - # Check expected values - self.app.client_manager.session.head.assert_called_with( - fake_url + '/is-name', - ) - - data_expected = { - 'account': fake_account, - 'container': 'is-name', - 'object_count': 1, - 'bytes_used': 577, - 'read_acl': None, - 'write_acl': None, - 'sync_to': None, - 'sync_key': None, - } - self.assertEqual(data_expected, data) diff --git a/openstackclient/tests/object/v1/lib/test_object.py b/openstackclient/tests/object/v1/lib/test_object.py deleted file mode 100644 index f96732b468..0000000000 --- a/openstackclient/tests/object/v1/lib/test_object.py +++ /dev/null @@ -1,295 +0,0 @@ -# Copyright 2013 Nebula Inc. -# -# 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. -# - -"""Test Object API library module""" - -import mock - -from openstackclient.object.v1.lib import object as lib_object -from openstackclient.tests import fakes -from openstackclient.tests.object.v1 import fakes as object_fakes - - -fake_account = 'q12we34r' -fake_auth = '11223344556677889900' -fake_url = 'http://gopher.com/v1/' + fake_account - -fake_container = 'rainbarrel' -fake_object = 'raindrop' - - -class FakeClient(object): - def __init__(self, endpoint=None, **kwargs): - self.endpoint = fake_url - self.token = fake_auth - - -class TestObject(object_fakes.TestObjectv1): - - def setUp(self): - super(TestObject, self).setUp() - self.app.client_manager.session = mock.MagicMock() - - -class TestObjectListObjects(TestObject): - - def test_list_objects_no_options(self): - resp = [{'name': 'is-name'}] - self.app.client_manager.session.get().json.return_value = resp - - data = lib_object.list_objects( - self.app.client_manager.session, - fake_url, - fake_container, - ) - - # Check expected values - self.app.client_manager.session.get.assert_called_with( - fake_url + '/' + fake_container, - params={ - 'format': 'json', - } - ) - self.assertEqual(resp, data) - - def test_list_objects_marker(self): - resp = [{'name': 'is-name'}] - self.app.client_manager.session.get().json.return_value = resp - - data = lib_object.list_objects( - self.app.client_manager.session, - fake_url, - fake_container, - marker='next', - ) - - # Check expected values - self.app.client_manager.session.get.assert_called_with( - fake_url + '/' + fake_container, - params={ - 'format': 'json', - 'marker': 'next', - } - ) - self.assertEqual(resp, data) - - def test_list_objects_limit(self): - resp = [{'name': 'is-name'}] - self.app.client_manager.session.get().json.return_value = resp - - data = lib_object.list_objects( - self.app.client_manager.session, - fake_url, - fake_container, - limit=5, - ) - - # Check expected values - self.app.client_manager.session.get.assert_called_with( - fake_url + '/' + fake_container, - params={ - 'format': 'json', - 'limit': 5, - } - ) - self.assertEqual(resp, data) - - def test_list_objects_end_marker(self): - resp = [{'name': 'is-name'}] - self.app.client_manager.session.get().json.return_value = resp - - data = lib_object.list_objects( - self.app.client_manager.session, - fake_url, - fake_container, - end_marker='last', - ) - - # Check expected values - self.app.client_manager.session.get.assert_called_with( - fake_url + '/' + fake_container, - params={ - 'format': 'json', - 'end_marker': 'last', - } - ) - self.assertEqual(resp, data) - - def test_list_objects_delimiter(self): - resp = [{'name': 'is-name'}] - self.app.client_manager.session.get().json.return_value = resp - - data = lib_object.list_objects( - self.app.client_manager.session, - fake_url, - fake_container, - delimiter='|', - ) - - # Check expected values - # NOTE(dtroyer): requests handles the URL encoding and we're - # mocking that so use the otherwise-not-legal - # pipe '|' char in the response. - self.app.client_manager.session.get.assert_called_with( - fake_url + '/' + fake_container, - params={ - 'format': 'json', - 'delimiter': '|', - } - ) - self.assertEqual(resp, data) - - def test_list_objects_prefix(self): - resp = [{'name': 'is-name'}] - self.app.client_manager.session.get().json.return_value = resp - - data = lib_object.list_objects( - self.app.client_manager.session, - fake_url, - fake_container, - prefix='foo/', - ) - - # Check expected values - self.app.client_manager.session.get.assert_called_with( - fake_url + '/' + fake_container, - params={ - 'format': 'json', - 'prefix': 'foo/', - } - ) - self.assertEqual(resp, data) - - def test_list_objects_path(self): - resp = [{'name': 'is-name'}] - self.app.client_manager.session.get().json.return_value = resp - - data = lib_object.list_objects( - self.app.client_manager.session, - fake_url, - fake_container, - path='next', - ) - - # Check expected values - self.app.client_manager.session.get.assert_called_with( - fake_url + '/' + fake_container, - params={ - 'format': 'json', - 'path': 'next', - } - ) - self.assertEqual(resp, data) - - def test_list_objects_full_listing(self): - sess = self.app.client_manager.session - - def side_effect(*args, **kwargs): - rv = sess.get().json.return_value - sess.get().json.return_value = [] - sess.get().json.side_effect = None - return rv - - resp = [{'name': 'is-name'}] - sess.get().json.return_value = resp - sess.get().json.side_effect = side_effect - - data = lib_object.list_objects( - sess, - fake_url, - fake_container, - full_listing=True, - ) - - # Check expected values - sess.get.assert_called_with( - fake_url + '/' + fake_container, - params={ - 'format': 'json', - 'marker': 'is-name', - } - ) - self.assertEqual(resp, data) - - -class TestObjectShowObjects(TestObject): - - def test_object_show_no_options(self): - resp = { - 'content-type': 'text/alpha', - 'x-container-meta-owner': fake_account, - } - self.app.client_manager.session.head.return_value = \ - fakes.FakeResponse(headers=resp) - - data = lib_object.show_object( - self.app.client_manager.session, - fake_url, - fake_container, - fake_object, - ) - - # Check expected values - self.app.client_manager.session.head.assert_called_with( - fake_url + '/%s/%s' % (fake_container, fake_object), - ) - - data_expected = { - 'account': fake_account, - 'container': fake_container, - 'object': fake_object, - 'content-type': 'text/alpha', - } - self.assertEqual(data_expected, data) - - def test_object_show_all_options(self): - resp = { - 'content-type': 'text/alpha', - 'content-length': 577, - 'last-modified': '20130101', - 'etag': 'qaz', - 'x-container-meta-owner': fake_account, - 'x-object-manifest': None, - 'x-object-meta-wife': 'Wilma', - 'x-tra-header': 'yabba-dabba-do', - } - self.app.client_manager.session.head.return_value = \ - fakes.FakeResponse(headers=resp) - - data = lib_object.show_object( - self.app.client_manager.session, - fake_url, - fake_container, - fake_object, - ) - - # Check expected values - self.app.client_manager.session.head.assert_called_with( - fake_url + '/%s/%s' % (fake_container, fake_object), - ) - - data_expected = { - 'account': fake_account, - 'container': fake_container, - 'object': fake_object, - 'content-type': 'text/alpha', - 'content-length': 577, - 'last-modified': '20130101', - 'etag': 'qaz', - 'x-object-manifest': None, - 'wife': 'Wilma', - 'x-tra-header': 'yabba-dabba-do', - } - self.assertEqual(data_expected, data) diff --git a/openstackclient/tests/object/v1/test_container.py b/openstackclient/tests/object/v1/test_container.py index b72c79d653..70b88fc425 100644 --- a/openstackclient/tests/object/v1/test_container.py +++ b/openstackclient/tests/object/v1/test_container.py @@ -16,6 +16,7 @@ import copy import mock +from openstackclient.api import object_store_v1 as object_store from openstackclient.object.v1 import container from openstackclient.tests.object.v1 import fakes as object_fakes @@ -30,28 +31,20 @@ class FakeClient(object): self.token = AUTH_TOKEN -class TestObject(object_fakes.TestObjectv1): +class TestContainer(object_fakes.TestObjectv1): def setUp(self): - super(TestObject, self).setUp() - - -class TestObjectClient(TestObject): - - def test_make_client(self): - self.assertEqual( - self.app.client_manager.object_store.endpoint, - AUTH_URL, - ) - self.assertEqual( - self.app.client_manager.object_store.token, - AUTH_TOKEN, + super(TestContainer, self).setUp() + self.app.client_manager.object_store = object_store.APIv1( + session=mock.Mock(), + service_type="object-store", ) + self.api = self.app.client_manager.object_store @mock.patch( - 'openstackclient.object.v1.container.lib_container.list_containers' + 'openstackclient.api.object_store_v1.APIv1.container_list' ) -class TestContainerList(TestObject): +class TestContainerList(TestContainer): def setUp(self): super(TestContainerList, self).setUp() @@ -77,8 +70,6 @@ class TestContainerList(TestObject): kwargs = { } c_mock.assert_called_with( - self.app.client_manager.session, - AUTH_URL, **kwargs ) @@ -113,8 +104,6 @@ class TestContainerList(TestObject): 'prefix': 'bit', } c_mock.assert_called_with( - self.app.client_manager.session, - AUTH_URL, **kwargs ) @@ -134,43 +123,10 @@ class TestContainerList(TestObject): arglist = [ '--marker', object_fakes.container_name, - ] - verifylist = [ - ('marker', object_fakes.container_name), - ] - parsed_args = self.check_parser(self.cmd, arglist, verifylist) - - # DisplayCommandBase.take_action() returns two tuples - columns, data = self.cmd.take_action(parsed_args) - - # Set expected values - kwargs = { - 'marker': object_fakes.container_name, - } - c_mock.assert_called_with( - self.app.client_manager.session, - AUTH_URL, - **kwargs - ) - - collist = ('Name',) - self.assertEqual(columns, collist) - datalist = ( - (object_fakes.container_name, ), - (object_fakes.container_name_3, ), - ) - self.assertEqual(tuple(data), datalist) - - def test_object_list_containers_end_marker(self, c_mock): - c_mock.return_value = [ - copy.deepcopy(object_fakes.CONTAINER), - copy.deepcopy(object_fakes.CONTAINER_3), - ] - - arglist = [ '--end-marker', object_fakes.container_name_3, ] verifylist = [ + ('marker', object_fakes.container_name), ('end_marker', object_fakes.container_name_3), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -180,11 +136,10 @@ class TestContainerList(TestObject): # Set expected values kwargs = { + 'marker': object_fakes.container_name, 'end_marker': object_fakes.container_name_3, } c_mock.assert_called_with( - self.app.client_manager.session, - AUTH_URL, **kwargs ) @@ -218,8 +173,6 @@ class TestContainerList(TestObject): 'limit': 2, } c_mock.assert_called_with( - self.app.client_manager.session, - AUTH_URL, **kwargs ) @@ -252,8 +205,6 @@ class TestContainerList(TestObject): kwargs = { } c_mock.assert_called_with( - self.app.client_manager.session, - AUTH_URL, **kwargs ) @@ -296,8 +247,6 @@ class TestContainerList(TestObject): 'full_listing': True, } c_mock.assert_called_with( - self.app.client_manager.session, - AUTH_URL, **kwargs ) @@ -312,9 +261,9 @@ class TestContainerList(TestObject): @mock.patch( - 'openstackclient.object.v1.container.lib_container.show_container' + 'openstackclient.api.object_store_v1.APIv1.container_show' ) -class TestContainerShow(TestObject): +class TestContainerShow(TestContainer): def setUp(self): super(TestContainerShow, self).setUp() @@ -341,9 +290,7 @@ class TestContainerShow(TestObject): } # lib.container.show_container(api, url, container) c_mock.assert_called_with( - self.app.client_manager.session, - AUTH_URL, - object_fakes.container_name, + container=object_fakes.container_name, **kwargs ) diff --git a/openstackclient/tests/object/v1/test_container_all.py b/openstackclient/tests/object/v1/test_container_all.py index 29d78454fa..53b60b9abb 100644 --- a/openstackclient/tests/object/v1/test_container_all.py +++ b/openstackclient/tests/object/v1/test_container_all.py @@ -16,6 +16,7 @@ import copy from requests_mock.contrib import fixture from keystoneclient import session +from openstackclient.api import object_store_v1 as object_store from openstackclient.object.v1 import container from openstackclient.tests.object.v1 import fakes as object_fakes @@ -29,7 +30,10 @@ class TestObjectAll(object_fakes.TestObjectv1): self.requests_mock = self.useFixture(fixture.Fixture()) # TODO(dtroyer): move this to object_fakes.TestObjectv1 - self.app.client_manager.object_store.endpoint = object_fakes.ENDPOINT + self.app.client_manager.object_store = object_store.APIv1( + session=self.app.client_manager.session, + endpoint=object_fakes.ENDPOINT, + ) class TestContainerCreate(TestObjectAll): diff --git a/openstackclient/tests/object/v1/test_object.py b/openstackclient/tests/object/v1/test_object.py index 26d07b2ca7..22f06999e2 100644 --- a/openstackclient/tests/object/v1/test_object.py +++ b/openstackclient/tests/object/v1/test_object.py @@ -16,6 +16,7 @@ import copy import mock +from openstackclient.api import object_store_v1 as object_store from openstackclient.object.v1 import object as obj from openstackclient.tests.object.v1 import fakes as object_fakes @@ -27,23 +28,15 @@ AUTH_URL = "http://0.0.0.0" class TestObject(object_fakes.TestObjectv1): def setUp(self): super(TestObject, self).setUp() - - -class TestObjectClient(TestObject): - - def test_make_client(self): - self.assertEqual( - self.app.client_manager.object_store.endpoint, - AUTH_URL, - ) - self.assertEqual( - self.app.client_manager.object_store.token, - AUTH_TOKEN, + self.app.client_manager.object_store = object_store.APIv1( + session=mock.Mock(), + service_type="object-store", ) + self.api = self.app.client_manager.object_store @mock.patch( - 'openstackclient.object.v1.object.lib_object.list_objects' + 'openstackclient.api.object_store_v1.APIv1.object_list' ) class TestObjectList(TestObject): @@ -71,9 +64,7 @@ class TestObjectList(TestObject): columns, data = self.cmd.take_action(parsed_args) o_mock.assert_called_with( - self.app.client_manager.session, - AUTH_URL, - object_fakes.container_name, + container=object_fakes.container_name, ) collist = ('Name',) @@ -107,9 +98,7 @@ class TestObjectList(TestObject): 'prefix': 'floppy', } o_mock.assert_called_with( - self.app.client_manager.session, - AUTH_URL, - object_fakes.container_name_2, + container=object_fakes.container_name_2, **kwargs ) @@ -143,9 +132,7 @@ class TestObjectList(TestObject): 'delimiter': '=', } o_mock.assert_called_with( - self.app.client_manager.session, - AUTH_URL, - object_fakes.container_name_2, + container=object_fakes.container_name_2, **kwargs ) @@ -179,9 +166,7 @@ class TestObjectList(TestObject): 'marker': object_fakes.object_name_2, } o_mock.assert_called_with( - self.app.client_manager.session, - AUTH_URL, - object_fakes.container_name_2, + container=object_fakes.container_name_2, **kwargs ) @@ -215,9 +200,7 @@ class TestObjectList(TestObject): 'end_marker': object_fakes.object_name_2, } o_mock.assert_called_with( - self.app.client_manager.session, - AUTH_URL, - object_fakes.container_name_2, + container=object_fakes.container_name_2, **kwargs ) @@ -251,9 +234,7 @@ class TestObjectList(TestObject): 'limit': 2, } o_mock.assert_called_with( - self.app.client_manager.session, - AUTH_URL, - object_fakes.container_name_2, + container=object_fakes.container_name_2, **kwargs ) @@ -287,9 +268,7 @@ class TestObjectList(TestObject): kwargs = { } o_mock.assert_called_with( - self.app.client_manager.session, - AUTH_URL, - object_fakes.container_name, + container=object_fakes.container_name, **kwargs ) @@ -337,9 +316,7 @@ class TestObjectList(TestObject): 'full_listing': True, } o_mock.assert_called_with( - self.app.client_manager.session, - AUTH_URL, - object_fakes.container_name, + container=object_fakes.container_name, **kwargs ) @@ -353,7 +330,7 @@ class TestObjectList(TestObject): @mock.patch( - 'openstackclient.object.v1.object.lib_object.show_object' + 'openstackclient.api.object_store_v1.APIv1.object_show' ) class TestObjectShow(TestObject): @@ -384,10 +361,8 @@ class TestObjectShow(TestObject): } # lib.container.show_container(api, url, container) c_mock.assert_called_with( - self.app.client_manager.session, - AUTH_URL, - object_fakes.container_name, - object_fakes.object_name_1, + container=object_fakes.container_name, + object=object_fakes.object_name_1, **kwargs )