summaryrefslogtreecommitdiff
path: root/openstackclient
diff options
context:
space:
mode:
authorDean Troyer <dtroyer@gmail.com>2014-09-18 00:54:52 -0500
committerSteve Martinelli <stevemar@ca.ibm.com>2014-10-01 13:50:13 -0400
commit31018bf7c2c57c530d55ed1dd90b9b65d489d557 (patch)
tree79f991b2c0b6c54c54b97c54cdf6db00a904cf86 /openstackclient
parente3b9b9658805f274283a498ed82014dce3833fe3 (diff)
downloadpython-openstackclient-31018bf7c2c57c530d55ed1dd90b9b65d489d557.tar.gz
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
Diffstat (limited to 'openstackclient')
-rw-r--r--openstackclient/api/object_store_v1.py381
-rw-r--r--openstackclient/object/client.py22
-rw-r--r--openstackclient/object/v1/container.py29
-rw-r--r--openstackclient/object/v1/lib/container.py170
-rw-r--r--openstackclient/object/v1/lib/object.py221
-rw-r--r--openstackclient/object/v1/object.py42
-rw-r--r--openstackclient/tests/api/test_object_store_v1.py326
-rw-r--r--openstackclient/tests/object/v1/lib/__init__.py0
-rw-r--r--openstackclient/tests/object/v1/lib/test_container.py207
-rw-r--r--openstackclient/tests/object/v1/lib/test_object.py295
-rw-r--r--openstackclient/tests/object/v1/test_container.py81
-rw-r--r--openstackclient/tests/object/v1/test_container_all.py6
-rw-r--r--openstackclient/tests/object/v1/test_object.py59
13 files changed, 773 insertions, 1066 deletions
diff --git a/openstackclient/api/object_store_v1.py b/openstackclient/api/object_store_v1.py
new file mode 100644
index 00000000..f938b55e
--- /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 b81ffaaf..887aa85b 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 9d55381c..ead3df45 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 4293ff4a..00000000
--- 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 7a23fc76..00000000
--- 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 f0ea7633..cbe9da2f 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 00000000..5a376a45
--- /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 e69de29b..00000000
--- a/openstackclient/tests/object/v1/lib/__init__.py
+++ /dev/null
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 ce70b835..00000000
--- 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 f96732b4..00000000
--- 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 b72c79d6..70b88fc4 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 29d78454..53b60b9a 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 26d07b2c..22f06999 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
)