Object API commands using our REST API layer
* Add object-store API to ClientManager * Add object-store client * Add Object API library in openstackclient.object.v1.lib * Add Object API {container,object} list commands * Add library tests * Add command tests This should complete the Object v1 container and object list commands Change-Id: Ib1770d45efa8871959826b85faafa1e0bcef0a03
This commit is contained in:
parent
17f13f7bf4
commit
725e2543ef
@ -20,6 +20,7 @@ import logging
|
|||||||
from openstackclient.compute import client as compute_client
|
from openstackclient.compute import client as compute_client
|
||||||
from openstackclient.identity import client as identity_client
|
from openstackclient.identity import client as identity_client
|
||||||
from openstackclient.image import client as image_client
|
from openstackclient.image import client as image_client
|
||||||
|
from openstackclient.object import client as object_client
|
||||||
from openstackclient.volume import client as volume_client
|
from openstackclient.volume import client as volume_client
|
||||||
|
|
||||||
|
|
||||||
@ -44,6 +45,7 @@ class ClientManager(object):
|
|||||||
compute = ClientCache(compute_client.make_client)
|
compute = ClientCache(compute_client.make_client)
|
||||||
identity = ClientCache(identity_client.make_client)
|
identity = ClientCache(identity_client.make_client)
|
||||||
image = ClientCache(image_client.make_client)
|
image = ClientCache(image_client.make_client)
|
||||||
|
object = ClientCache(object_client.make_client)
|
||||||
volume = ClientCache(volume_client.make_client)
|
volume = ClientCache(volume_client.make_client)
|
||||||
|
|
||||||
def __init__(self, token=None, url=None, auth_url=None, project_name=None,
|
def __init__(self, token=None, url=None, auth_url=None, project_name=None,
|
||||||
|
12
openstackclient/object/__init__.py
Normal file
12
openstackclient/object/__init__.py
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# 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.
|
||||||
|
#
|
58
openstackclient/object/client.py
Normal file
58
openstackclient/object/client.py
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
# 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 client"""
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from openstackclient.common import utils
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
API_NAME = 'object-store'
|
||||||
|
API_VERSIONS = {
|
||||||
|
'1': 'openstackclient.object.client.ObjectClientv1',
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def make_client(instance):
|
||||||
|
"""Returns an object service client."""
|
||||||
|
object_client = utils.get_client_class(
|
||||||
|
API_NAME,
|
||||||
|
instance._api_version[API_NAME],
|
||||||
|
API_VERSIONS)
|
||||||
|
if instance._url:
|
||||||
|
endpoint = instance._url
|
||||||
|
else:
|
||||||
|
endpoint = instance.get_endpoint_for_service_type(API_NAME)
|
||||||
|
LOG.debug('instantiating object client')
|
||||||
|
client = object_client(
|
||||||
|
endpoint=endpoint,
|
||||||
|
token=instance._token,
|
||||||
|
)
|
||||||
|
return client
|
||||||
|
|
||||||
|
|
||||||
|
class ObjectClientv1(object):
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
endpoint_type='publicURL',
|
||||||
|
endpoint=None,
|
||||||
|
token=None,
|
||||||
|
):
|
||||||
|
self.endpoint_type = endpoint_type
|
||||||
|
self.endpoint = endpoint
|
||||||
|
self.token = token
|
12
openstackclient/object/v1/__init__.py
Normal file
12
openstackclient/object/v1/__init__.py
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# 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.
|
||||||
|
#
|
100
openstackclient/object/v1/container.py
Normal file
100
openstackclient/object/v1/container.py
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
# 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
"""Container v1 action implementations"""
|
||||||
|
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from cliff import lister
|
||||||
|
|
||||||
|
from openstackclient.common import utils
|
||||||
|
from openstackclient.object.v1.lib import container as lib_container
|
||||||
|
|
||||||
|
|
||||||
|
class ListContainer(lister.Lister):
|
||||||
|
"""List containers"""
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__ + '.ListContainer')
|
||||||
|
|
||||||
|
def get_parser(self, prog_name):
|
||||||
|
parser = super(ListContainer, self).get_parser(prog_name)
|
||||||
|
parser.add_argument(
|
||||||
|
"--prefix",
|
||||||
|
metavar="<prefix>",
|
||||||
|
help="Filter list using <prefix>",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--marker",
|
||||||
|
metavar="<marker>",
|
||||||
|
help="Anchor for paging",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--end-marker",
|
||||||
|
metavar="<end-marker>",
|
||||||
|
help="End anchor for paging",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--limit",
|
||||||
|
metavar="<limit>",
|
||||||
|
type=int,
|
||||||
|
help="Limit the number of containers returned",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--long',
|
||||||
|
action='store_true',
|
||||||
|
default=False,
|
||||||
|
help='List additional fields in output',
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--all',
|
||||||
|
action='store_true',
|
||||||
|
default=False,
|
||||||
|
help='List all containers (default is 10000)',
|
||||||
|
)
|
||||||
|
return parser
|
||||||
|
|
||||||
|
def take_action(self, parsed_args):
|
||||||
|
self.log.debug('take_action(%s)' % parsed_args)
|
||||||
|
|
||||||
|
if parsed_args.long:
|
||||||
|
columns = ('Name', 'Bytes', 'Count')
|
||||||
|
else:
|
||||||
|
columns = ('Name',)
|
||||||
|
|
||||||
|
kwargs = {}
|
||||||
|
if parsed_args.prefix:
|
||||||
|
kwargs['prefix'] = parsed_args.prefix
|
||||||
|
if parsed_args.marker:
|
||||||
|
kwargs['marker'] = parsed_args.marker
|
||||||
|
if parsed_args.end_marker:
|
||||||
|
kwargs['end_marker'] = parsed_args.end_marker
|
||||||
|
if parsed_args.limit:
|
||||||
|
kwargs['limit'] = parsed_args.limit
|
||||||
|
if parsed_args.all:
|
||||||
|
kwargs['full_listing'] = True
|
||||||
|
|
||||||
|
data = lib_container.list_containers(
|
||||||
|
self.app.restapi,
|
||||||
|
self.app.client_manager.object.endpoint,
|
||||||
|
**kwargs
|
||||||
|
)
|
||||||
|
#print "data: %s" % data
|
||||||
|
|
||||||
|
return (columns,
|
||||||
|
(utils.get_dict_properties(
|
||||||
|
s, columns,
|
||||||
|
formatters={},
|
||||||
|
) for s in data))
|
12
openstackclient/object/v1/lib/__init__.py
Normal file
12
openstackclient/object/v1/lib/__init__.py
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# 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.
|
||||||
|
#
|
77
openstackclient/object/v1/lib/container.py
Normal file
77
openstackclient/object/v1/lib/container.py
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
# 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"""
|
||||||
|
|
||||||
|
|
||||||
|
def list_containers(
|
||||||
|
api,
|
||||||
|
url,
|
||||||
|
marker=None,
|
||||||
|
limit=None,
|
||||||
|
end_marker=None,
|
||||||
|
prefix=None,
|
||||||
|
full_listing=False,
|
||||||
|
):
|
||||||
|
"""Get containers in an account
|
||||||
|
|
||||||
|
:param api: a restapi 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(
|
||||||
|
api,
|
||||||
|
url,
|
||||||
|
marker,
|
||||||
|
limit,
|
||||||
|
end_marker,
|
||||||
|
prefix,
|
||||||
|
)
|
||||||
|
while listing:
|
||||||
|
marker = listing[-1]['name']
|
||||||
|
listing = list_containers(
|
||||||
|
api,
|
||||||
|
url,
|
||||||
|
marker,
|
||||||
|
limit,
|
||||||
|
end_marker,
|
||||||
|
prefix,
|
||||||
|
)
|
||||||
|
if listing:
|
||||||
|
data.extend(listing)
|
||||||
|
return data
|
||||||
|
|
||||||
|
object_url = url
|
||||||
|
query = "format=json"
|
||||||
|
if marker:
|
||||||
|
query += '&marker=%s' % marker
|
||||||
|
if limit:
|
||||||
|
query += '&limit=%d' % limit
|
||||||
|
if end_marker:
|
||||||
|
query += '&end_marker=%s' % end_marker
|
||||||
|
if prefix:
|
||||||
|
query += '&prefix=%s' % prefix
|
||||||
|
url = "%s?%s" % (object_url, query)
|
||||||
|
response = api.request('GET', url)
|
||||||
|
return response.json()
|
97
openstackclient/object/v1/lib/object.py
Normal file
97
openstackclient/object/v1/lib/object.py
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
# 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"""
|
||||||
|
|
||||||
|
|
||||||
|
def list_objects(
|
||||||
|
api,
|
||||||
|
url,
|
||||||
|
container,
|
||||||
|
marker=None,
|
||||||
|
limit=None,
|
||||||
|
end_marker=None,
|
||||||
|
delimiter=None,
|
||||||
|
prefix=None,
|
||||||
|
path=None,
|
||||||
|
full_listing=False,
|
||||||
|
):
|
||||||
|
"""Get objects in a container
|
||||||
|
|
||||||
|
:param api: a restapi 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(
|
||||||
|
api,
|
||||||
|
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(
|
||||||
|
api,
|
||||||
|
url,
|
||||||
|
container,
|
||||||
|
marker,
|
||||||
|
limit,
|
||||||
|
end_marker,
|
||||||
|
delimiter,
|
||||||
|
prefix,
|
||||||
|
path,
|
||||||
|
)
|
||||||
|
if listing:
|
||||||
|
data.extend(listing)
|
||||||
|
return data
|
||||||
|
|
||||||
|
object_url = url
|
||||||
|
query = "format=json"
|
||||||
|
if marker:
|
||||||
|
query += '&marker=%s' % marker
|
||||||
|
if limit:
|
||||||
|
query += '&limit=%d' % limit
|
||||||
|
if end_marker:
|
||||||
|
query += '&end_marker=%s' % end_marker
|
||||||
|
if delimiter:
|
||||||
|
query += '&delimiter=%s' % delimiter
|
||||||
|
if prefix:
|
||||||
|
query += '&prefix=%s' % prefix
|
||||||
|
if path:
|
||||||
|
query += '&path=%s' % path
|
||||||
|
url = "%s/%s?%s" % (object_url, container, query)
|
||||||
|
response = api.request('GET', url)
|
||||||
|
return response.json()
|
118
openstackclient/object/v1/object.py
Normal file
118
openstackclient/object/v1/object.py
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
# 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 action implementations"""
|
||||||
|
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from cliff import lister
|
||||||
|
|
||||||
|
from openstackclient.common import utils
|
||||||
|
from openstackclient.object.v1.lib import object as lib_object
|
||||||
|
|
||||||
|
|
||||||
|
class ListObject(lister.Lister):
|
||||||
|
"""List objects"""
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__ + '.ListObject')
|
||||||
|
|
||||||
|
def get_parser(self, prog_name):
|
||||||
|
parser = super(ListObject, self).get_parser(prog_name)
|
||||||
|
parser.add_argument(
|
||||||
|
"container",
|
||||||
|
metavar="<container-name>",
|
||||||
|
help="List contents of container-name",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--prefix",
|
||||||
|
metavar="<prefix>",
|
||||||
|
help="Filter list using <prefix>",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--delimiter",
|
||||||
|
metavar="<delimiter>",
|
||||||
|
help="Roll up items with <delimiter>",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--marker",
|
||||||
|
metavar="<marker>",
|
||||||
|
help="Anchor for paging",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--end-marker",
|
||||||
|
metavar="<end-marker>",
|
||||||
|
help="End anchor for paging",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--limit",
|
||||||
|
metavar="<limit>",
|
||||||
|
type=int,
|
||||||
|
help="Limit the number of objects returned",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--long',
|
||||||
|
action='store_true',
|
||||||
|
default=False,
|
||||||
|
help='List additional fields in output',
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--all',
|
||||||
|
action='store_true',
|
||||||
|
default=False,
|
||||||
|
help='List all objects in container (default is 10000)',
|
||||||
|
)
|
||||||
|
return parser
|
||||||
|
|
||||||
|
def take_action(self, parsed_args):
|
||||||
|
self.log.debug('take_action(%s)' % parsed_args)
|
||||||
|
|
||||||
|
if parsed_args.long:
|
||||||
|
columns = (
|
||||||
|
'Name',
|
||||||
|
'Bytes',
|
||||||
|
'Hash',
|
||||||
|
'Content Type',
|
||||||
|
'Last Modified',
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
columns = ('Name',)
|
||||||
|
|
||||||
|
kwargs = {}
|
||||||
|
if parsed_args.prefix:
|
||||||
|
kwargs['prefix'] = parsed_args.prefix
|
||||||
|
if parsed_args.delimiter:
|
||||||
|
kwargs['delimiter'] = parsed_args.delimiter
|
||||||
|
if parsed_args.marker:
|
||||||
|
kwargs['marker'] = parsed_args.marker
|
||||||
|
if parsed_args.end_marker:
|
||||||
|
kwargs['end_marker'] = parsed_args.end_marker
|
||||||
|
if parsed_args.limit:
|
||||||
|
kwargs['limit'] = parsed_args.limit
|
||||||
|
if parsed_args.all:
|
||||||
|
kwargs['full_listing'] = True
|
||||||
|
|
||||||
|
data = lib_object.list_objects(
|
||||||
|
self.app.restapi,
|
||||||
|
self.app.client_manager.object.endpoint,
|
||||||
|
parsed_args.container,
|
||||||
|
**kwargs
|
||||||
|
)
|
||||||
|
|
||||||
|
return (columns,
|
||||||
|
(utils.get_dict_properties(
|
||||||
|
s, columns,
|
||||||
|
formatters={},
|
||||||
|
) for s in data))
|
@ -38,6 +38,7 @@ KEYRING_SERVICE = 'openstack'
|
|||||||
DEFAULT_COMPUTE_API_VERSION = '2'
|
DEFAULT_COMPUTE_API_VERSION = '2'
|
||||||
DEFAULT_IDENTITY_API_VERSION = '2.0'
|
DEFAULT_IDENTITY_API_VERSION = '2.0'
|
||||||
DEFAULT_IMAGE_API_VERSION = '1'
|
DEFAULT_IMAGE_API_VERSION = '1'
|
||||||
|
DEFAULT_OBJECT_API_VERSION = '1'
|
||||||
DEFAULT_VOLUME_API_VERSION = '1'
|
DEFAULT_VOLUME_API_VERSION = '1'
|
||||||
DEFAULT_DOMAIN = 'default'
|
DEFAULT_DOMAIN = 'default'
|
||||||
|
|
||||||
@ -187,6 +188,15 @@ class OpenStackShell(app.App):
|
|||||||
help='Image API version, default=' +
|
help='Image API version, default=' +
|
||||||
DEFAULT_IMAGE_API_VERSION +
|
DEFAULT_IMAGE_API_VERSION +
|
||||||
' (Env: OS_IMAGE_API_VERSION)')
|
' (Env: OS_IMAGE_API_VERSION)')
|
||||||
|
parser.add_argument(
|
||||||
|
'--os-object-api-version',
|
||||||
|
metavar='<object-api-version>',
|
||||||
|
default=env(
|
||||||
|
'OS_OBJECT_API_VERSION',
|
||||||
|
default=DEFAULT_OBJECT_API_VERSION),
|
||||||
|
help='Object API version, default=' +
|
||||||
|
DEFAULT_OBJECT_API_VERSION +
|
||||||
|
' (Env: OS_OBJECT_API_VERSION)')
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--os-volume-api-version',
|
'--os-volume-api-version',
|
||||||
metavar='<volume-api-version>',
|
metavar='<volume-api-version>',
|
||||||
@ -339,14 +349,15 @@ class OpenStackShell(app.App):
|
|||||||
'compute': self.options.os_compute_api_version,
|
'compute': self.options.os_compute_api_version,
|
||||||
'identity': self.options.os_identity_api_version,
|
'identity': self.options.os_identity_api_version,
|
||||||
'image': self.options.os_image_api_version,
|
'image': self.options.os_image_api_version,
|
||||||
|
'object-store': self.options.os_object_api_version,
|
||||||
'volume': self.options.os_volume_api_version,
|
'volume': self.options.os_volume_api_version,
|
||||||
}
|
}
|
||||||
|
|
||||||
# Add the API version-specific commands
|
# Add the API version-specific commands
|
||||||
for api in self.api_version.keys():
|
for api in self.api_version.keys():
|
||||||
version = '.v' + self.api_version[api].replace('.', '_')
|
version = '.v' + self.api_version[api].replace('.', '_')
|
||||||
self.command_manager.add_command_group(
|
cmd_group = 'openstack.' + api.replace('-', '_') + version
|
||||||
'openstack.' + api + version)
|
self.command_manager.add_command_group(cmd_group)
|
||||||
|
|
||||||
# Commands that span multiple APIs
|
# Commands that span multiple APIs
|
||||||
self.command_manager.add_command_group(
|
self.command_manager.add_command_group(
|
||||||
|
@ -44,6 +44,11 @@ class FakeClientManager(object):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class FakeRESTApi(object):
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class FakeResource(object):
|
class FakeResource(object):
|
||||||
def __init__(self, manager, info, loaded=False):
|
def __init__(self, manager, info, loaded=False):
|
||||||
self.manager = manager
|
self.manager = manager
|
||||||
|
12
openstackclient/tests/object/__init__.py
Normal file
12
openstackclient/tests/object/__init__.py
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# 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.
|
||||||
|
#
|
67
openstackclient/tests/object/fakes.py
Normal file
67
openstackclient/tests/object/fakes.py
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
# 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
container_name = 'bit-bucket'
|
||||||
|
container_bytes = 1024
|
||||||
|
container_count = 1
|
||||||
|
|
||||||
|
container_name_2 = 'archive'
|
||||||
|
container_name_3 = 'bit-blit'
|
||||||
|
|
||||||
|
CONTAINER = {
|
||||||
|
'name': container_name,
|
||||||
|
'bytes': container_bytes,
|
||||||
|
'count': container_count,
|
||||||
|
}
|
||||||
|
|
||||||
|
CONTAINER_2 = {
|
||||||
|
'name': container_name_2,
|
||||||
|
'bytes': container_bytes * 2,
|
||||||
|
'count': container_count * 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
CONTAINER_3 = {
|
||||||
|
'name': container_name_3,
|
||||||
|
'bytes': container_bytes * 3,
|
||||||
|
'count': container_count * 3,
|
||||||
|
}
|
||||||
|
|
||||||
|
object_name_1 = 'punch-card'
|
||||||
|
object_bytes_1 = 80
|
||||||
|
object_hash_1 = '1234567890'
|
||||||
|
object_content_type_1 = 'text'
|
||||||
|
object_modified_1 = 'today'
|
||||||
|
|
||||||
|
object_name_2 = 'floppy-disk'
|
||||||
|
object_bytes_2 = 1440000
|
||||||
|
object_hash_2 = '0987654321'
|
||||||
|
object_content_type_2 = 'text'
|
||||||
|
object_modified_2 = 'today'
|
||||||
|
|
||||||
|
OBJECT = {
|
||||||
|
'name': object_name_1,
|
||||||
|
'bytes': object_bytes_1,
|
||||||
|
'hash': object_hash_1,
|
||||||
|
'content_type': object_content_type_1,
|
||||||
|
'last_modified': object_modified_1,
|
||||||
|
}
|
||||||
|
|
||||||
|
OBJECT_2 = {
|
||||||
|
'name': object_name_2,
|
||||||
|
'bytes': object_bytes_2,
|
||||||
|
'hash': object_hash_2,
|
||||||
|
'content_type': object_content_type_2,
|
||||||
|
'last_modified': object_modified_2,
|
||||||
|
}
|
315
openstackclient/tests/object/test_container.py
Normal file
315
openstackclient/tests/object/test_container.py
Normal file
@ -0,0 +1,315 @@
|
|||||||
|
# Copyright 2013 OpenStack Foundation
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
#
|
||||||
|
|
||||||
|
import copy
|
||||||
|
import mock
|
||||||
|
|
||||||
|
from openstackclient.common import clientmanager
|
||||||
|
from openstackclient.object.v1 import container
|
||||||
|
from openstackclient.tests.object import fakes as object_fakes
|
||||||
|
from openstackclient.tests import utils
|
||||||
|
|
||||||
|
|
||||||
|
AUTH_TOKEN = "foobar"
|
||||||
|
AUTH_URL = "http://0.0.0.0"
|
||||||
|
|
||||||
|
|
||||||
|
class FakeClient(object):
|
||||||
|
def __init__(self, endpoint=None, **kwargs):
|
||||||
|
self.endpoint = AUTH_URL
|
||||||
|
self.token = AUTH_TOKEN
|
||||||
|
|
||||||
|
|
||||||
|
class TestObject(utils.TestCommand):
|
||||||
|
def setUp(self):
|
||||||
|
super(TestObject, self).setUp()
|
||||||
|
|
||||||
|
api_version = {"object-store": "1"}
|
||||||
|
self.app.client_manager = clientmanager.ClientManager(
|
||||||
|
token=AUTH_TOKEN,
|
||||||
|
url=AUTH_URL,
|
||||||
|
auth_url=AUTH_URL,
|
||||||
|
api_version=api_version,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class TestObjectClient(TestObject):
|
||||||
|
|
||||||
|
def test_make_client(self):
|
||||||
|
self.assertEqual(self.app.client_manager.object.endpoint, AUTH_URL)
|
||||||
|
self.assertEqual(self.app.client_manager.object.token, AUTH_TOKEN)
|
||||||
|
|
||||||
|
|
||||||
|
@mock.patch(
|
||||||
|
'openstackclient.object.v1.container.lib_container.list_containers'
|
||||||
|
)
|
||||||
|
class TestContainerList(TestObject):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestContainerList, self).setUp()
|
||||||
|
|
||||||
|
# Get the command object to test
|
||||||
|
self.cmd = container.ListContainer(self.app, None)
|
||||||
|
|
||||||
|
def test_object_list_containers_no_options(self, c_mock):
|
||||||
|
c_mock.return_value = [
|
||||||
|
copy.deepcopy(object_fakes.CONTAINER),
|
||||||
|
copy.deepcopy(object_fakes.CONTAINER_3),
|
||||||
|
copy.deepcopy(object_fakes.CONTAINER_2),
|
||||||
|
]
|
||||||
|
|
||||||
|
arglist = []
|
||||||
|
verifylist = []
|
||||||
|
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 = {
|
||||||
|
}
|
||||||
|
c_mock.assert_called_with(
|
||||||
|
self.app.restapi,
|
||||||
|
AUTH_URL,
|
||||||
|
**kwargs
|
||||||
|
)
|
||||||
|
|
||||||
|
collist = ('Name',)
|
||||||
|
self.assertEqual(columns, collist)
|
||||||
|
datalist = (
|
||||||
|
(object_fakes.container_name, ),
|
||||||
|
(object_fakes.container_name_3, ),
|
||||||
|
(object_fakes.container_name_2, ),
|
||||||
|
)
|
||||||
|
self.assertEqual(tuple(data), datalist)
|
||||||
|
|
||||||
|
def test_object_list_containers_prefix(self, c_mock):
|
||||||
|
c_mock.return_value = [
|
||||||
|
copy.deepcopy(object_fakes.CONTAINER),
|
||||||
|
copy.deepcopy(object_fakes.CONTAINER_3),
|
||||||
|
]
|
||||||
|
|
||||||
|
arglist = [
|
||||||
|
'--prefix', 'bit',
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('prefix', 'bit'),
|
||||||
|
]
|
||||||
|
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 = {
|
||||||
|
'prefix': 'bit',
|
||||||
|
}
|
||||||
|
c_mock.assert_called_with(
|
||||||
|
self.app.restapi,
|
||||||
|
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_marker(self, c_mock):
|
||||||
|
c_mock.return_value = [
|
||||||
|
copy.deepcopy(object_fakes.CONTAINER),
|
||||||
|
copy.deepcopy(object_fakes.CONTAINER_3),
|
||||||
|
]
|
||||||
|
|
||||||
|
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.restapi,
|
||||||
|
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 = [
|
||||||
|
('end_marker', object_fakes.container_name_3),
|
||||||
|
]
|
||||||
|
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 = {
|
||||||
|
'end_marker': object_fakes.container_name_3,
|
||||||
|
}
|
||||||
|
c_mock.assert_called_with(
|
||||||
|
self.app.restapi,
|
||||||
|
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_limit(self, c_mock):
|
||||||
|
c_mock.return_value = [
|
||||||
|
copy.deepcopy(object_fakes.CONTAINER),
|
||||||
|
copy.deepcopy(object_fakes.CONTAINER_3),
|
||||||
|
]
|
||||||
|
|
||||||
|
arglist = [
|
||||||
|
'--limit', '2',
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('limit', 2),
|
||||||
|
]
|
||||||
|
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 = {
|
||||||
|
'limit': 2,
|
||||||
|
}
|
||||||
|
c_mock.assert_called_with(
|
||||||
|
self.app.restapi,
|
||||||
|
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_long(self, c_mock):
|
||||||
|
c_mock.return_value = [
|
||||||
|
copy.deepcopy(object_fakes.CONTAINER),
|
||||||
|
copy.deepcopy(object_fakes.CONTAINER_3),
|
||||||
|
]
|
||||||
|
|
||||||
|
arglist = [
|
||||||
|
'--long',
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('long', True),
|
||||||
|
]
|
||||||
|
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 = {
|
||||||
|
}
|
||||||
|
c_mock.assert_called_with(
|
||||||
|
self.app.restapi,
|
||||||
|
AUTH_URL,
|
||||||
|
**kwargs
|
||||||
|
)
|
||||||
|
|
||||||
|
collist = ('Name', 'Bytes', 'Count')
|
||||||
|
self.assertEqual(columns, collist)
|
||||||
|
datalist = (
|
||||||
|
(
|
||||||
|
object_fakes.container_name,
|
||||||
|
object_fakes.container_bytes,
|
||||||
|
object_fakes.container_count,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
object_fakes.container_name_3,
|
||||||
|
object_fakes.container_bytes * 3,
|
||||||
|
object_fakes.container_count * 3,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
self.assertEqual(tuple(data), datalist)
|
||||||
|
|
||||||
|
def test_object_list_containers_all(self, c_mock):
|
||||||
|
c_mock.return_value = [
|
||||||
|
copy.deepcopy(object_fakes.CONTAINER),
|
||||||
|
copy.deepcopy(object_fakes.CONTAINER_2),
|
||||||
|
copy.deepcopy(object_fakes.CONTAINER_3),
|
||||||
|
]
|
||||||
|
|
||||||
|
arglist = [
|
||||||
|
'--all',
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('all', True),
|
||||||
|
]
|
||||||
|
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 = {
|
||||||
|
'full_listing': True,
|
||||||
|
}
|
||||||
|
c_mock.assert_called_with(
|
||||||
|
self.app.restapi,
|
||||||
|
AUTH_URL,
|
||||||
|
**kwargs
|
||||||
|
)
|
||||||
|
|
||||||
|
collist = ('Name',)
|
||||||
|
self.assertEqual(columns, collist)
|
||||||
|
datalist = (
|
||||||
|
(object_fakes.container_name, ),
|
||||||
|
(object_fakes.container_name_2, ),
|
||||||
|
(object_fakes.container_name_3, ),
|
||||||
|
)
|
||||||
|
self.assertEqual(tuple(data), datalist)
|
362
openstackclient/tests/object/test_object.py
Normal file
362
openstackclient/tests/object/test_object.py
Normal file
@ -0,0 +1,362 @@
|
|||||||
|
# Copyright 2013 OpenStack Foundation
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
#
|
||||||
|
|
||||||
|
import copy
|
||||||
|
import mock
|
||||||
|
|
||||||
|
from openstackclient.common import clientmanager
|
||||||
|
from openstackclient.object.v1 import object as obj
|
||||||
|
from openstackclient.tests.object import fakes as object_fakes
|
||||||
|
from openstackclient.tests import utils
|
||||||
|
|
||||||
|
|
||||||
|
AUTH_TOKEN = "foobar"
|
||||||
|
AUTH_URL = "http://0.0.0.0"
|
||||||
|
|
||||||
|
|
||||||
|
class FakeClient(object):
|
||||||
|
def __init__(self, endpoint=None, **kwargs):
|
||||||
|
self.endpoint = AUTH_URL
|
||||||
|
self.token = AUTH_TOKEN
|
||||||
|
|
||||||
|
|
||||||
|
class TestObject(utils.TestCommand):
|
||||||
|
def setUp(self):
|
||||||
|
super(TestObject, self).setUp()
|
||||||
|
|
||||||
|
api_version = {"object-store": "1"}
|
||||||
|
self.app.client_manager = clientmanager.ClientManager(
|
||||||
|
token=AUTH_TOKEN,
|
||||||
|
url=AUTH_URL,
|
||||||
|
auth_url=AUTH_URL,
|
||||||
|
api_version=api_version,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class TestObjectClient(TestObject):
|
||||||
|
|
||||||
|
def test_make_client(self):
|
||||||
|
self.assertEqual(self.app.client_manager.object.endpoint, AUTH_URL)
|
||||||
|
self.assertEqual(self.app.client_manager.object.token, AUTH_TOKEN)
|
||||||
|
|
||||||
|
|
||||||
|
@mock.patch(
|
||||||
|
'openstackclient.object.v1.object.lib_object.list_objects'
|
||||||
|
)
|
||||||
|
class TestObjectList(TestObject):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestObjectList, self).setUp()
|
||||||
|
|
||||||
|
# Get the command object to test
|
||||||
|
self.cmd = obj.ListObject(self.app, None)
|
||||||
|
|
||||||
|
def test_object_list_objects_no_options(self, o_mock):
|
||||||
|
o_mock.return_value = [
|
||||||
|
copy.deepcopy(object_fakes.OBJECT),
|
||||||
|
copy.deepcopy(object_fakes.OBJECT_2),
|
||||||
|
]
|
||||||
|
|
||||||
|
arglist = [
|
||||||
|
object_fakes.container_name,
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('container', 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)
|
||||||
|
|
||||||
|
o_mock.assert_called_with(
|
||||||
|
self.app.restapi,
|
||||||
|
AUTH_URL,
|
||||||
|
object_fakes.container_name,
|
||||||
|
)
|
||||||
|
|
||||||
|
collist = ('Name',)
|
||||||
|
self.assertEqual(columns, collist)
|
||||||
|
datalist = (
|
||||||
|
(object_fakes.object_name_1, ),
|
||||||
|
(object_fakes.object_name_2, ),
|
||||||
|
)
|
||||||
|
self.assertEqual(tuple(data), datalist)
|
||||||
|
|
||||||
|
def test_object_list_objects_prefix(self, o_mock):
|
||||||
|
o_mock.return_value = [
|
||||||
|
copy.deepcopy(object_fakes.OBJECT_2),
|
||||||
|
]
|
||||||
|
|
||||||
|
arglist = [
|
||||||
|
'--prefix', 'floppy',
|
||||||
|
object_fakes.container_name_2,
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('prefix', 'floppy'),
|
||||||
|
('container', object_fakes.container_name_2),
|
||||||
|
]
|
||||||
|
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 = {
|
||||||
|
'prefix': 'floppy',
|
||||||
|
}
|
||||||
|
o_mock.assert_called_with(
|
||||||
|
self.app.restapi,
|
||||||
|
AUTH_URL,
|
||||||
|
object_fakes.container_name_2,
|
||||||
|
**kwargs
|
||||||
|
)
|
||||||
|
|
||||||
|
collist = ('Name',)
|
||||||
|
self.assertEqual(columns, collist)
|
||||||
|
datalist = (
|
||||||
|
(object_fakes.object_name_2, ),
|
||||||
|
)
|
||||||
|
self.assertEqual(tuple(data), datalist)
|
||||||
|
|
||||||
|
def test_object_list_objects_delimiter(self, o_mock):
|
||||||
|
o_mock.return_value = [
|
||||||
|
copy.deepcopy(object_fakes.OBJECT_2),
|
||||||
|
]
|
||||||
|
|
||||||
|
arglist = [
|
||||||
|
'--delimiter', '=',
|
||||||
|
object_fakes.container_name_2,
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('delimiter', '='),
|
||||||
|
('container', object_fakes.container_name_2),
|
||||||
|
]
|
||||||
|
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 = {
|
||||||
|
'delimiter': '=',
|
||||||
|
}
|
||||||
|
o_mock.assert_called_with(
|
||||||
|
self.app.restapi,
|
||||||
|
AUTH_URL,
|
||||||
|
object_fakes.container_name_2,
|
||||||
|
**kwargs
|
||||||
|
)
|
||||||
|
|
||||||
|
collist = ('Name',)
|
||||||
|
self.assertEqual(columns, collist)
|
||||||
|
datalist = (
|
||||||
|
(object_fakes.object_name_2, ),
|
||||||
|
)
|
||||||
|
self.assertEqual(tuple(data), datalist)
|
||||||
|
|
||||||
|
def test_object_list_objects_marker(self, o_mock):
|
||||||
|
o_mock.return_value = [
|
||||||
|
copy.deepcopy(object_fakes.OBJECT_2),
|
||||||
|
]
|
||||||
|
|
||||||
|
arglist = [
|
||||||
|
'--marker', object_fakes.object_name_2,
|
||||||
|
object_fakes.container_name_2,
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('marker', object_fakes.object_name_2),
|
||||||
|
('container', object_fakes.container_name_2),
|
||||||
|
]
|
||||||
|
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.object_name_2,
|
||||||
|
}
|
||||||
|
o_mock.assert_called_with(
|
||||||
|
self.app.restapi,
|
||||||
|
AUTH_URL,
|
||||||
|
object_fakes.container_name_2,
|
||||||
|
**kwargs
|
||||||
|
)
|
||||||
|
|
||||||
|
collist = ('Name',)
|
||||||
|
self.assertEqual(columns, collist)
|
||||||
|
datalist = (
|
||||||
|
(object_fakes.object_name_2, ),
|
||||||
|
)
|
||||||
|
self.assertEqual(tuple(data), datalist)
|
||||||
|
|
||||||
|
def test_object_list_objects_end_marker(self, o_mock):
|
||||||
|
o_mock.return_value = [
|
||||||
|
copy.deepcopy(object_fakes.OBJECT_2),
|
||||||
|
]
|
||||||
|
|
||||||
|
arglist = [
|
||||||
|
'--end-marker', object_fakes.object_name_2,
|
||||||
|
object_fakes.container_name_2,
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('end_marker', object_fakes.object_name_2),
|
||||||
|
('container', object_fakes.container_name_2),
|
||||||
|
]
|
||||||
|
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 = {
|
||||||
|
'end_marker': object_fakes.object_name_2,
|
||||||
|
}
|
||||||
|
o_mock.assert_called_with(
|
||||||
|
self.app.restapi,
|
||||||
|
AUTH_URL,
|
||||||
|
object_fakes.container_name_2,
|
||||||
|
**kwargs
|
||||||
|
)
|
||||||
|
|
||||||
|
collist = ('Name',)
|
||||||
|
self.assertEqual(columns, collist)
|
||||||
|
datalist = (
|
||||||
|
(object_fakes.object_name_2, ),
|
||||||
|
)
|
||||||
|
self.assertEqual(tuple(data), datalist)
|
||||||
|
|
||||||
|
def test_object_list_objects_limit(self, o_mock):
|
||||||
|
o_mock.return_value = [
|
||||||
|
copy.deepcopy(object_fakes.OBJECT_2),
|
||||||
|
]
|
||||||
|
|
||||||
|
arglist = [
|
||||||
|
'--limit', '2',
|
||||||
|
object_fakes.container_name_2,
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('limit', 2),
|
||||||
|
('container', object_fakes.container_name_2),
|
||||||
|
]
|
||||||
|
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 = {
|
||||||
|
'limit': 2,
|
||||||
|
}
|
||||||
|
o_mock.assert_called_with(
|
||||||
|
self.app.restapi,
|
||||||
|
AUTH_URL,
|
||||||
|
object_fakes.container_name_2,
|
||||||
|
**kwargs
|
||||||
|
)
|
||||||
|
|
||||||
|
collist = ('Name',)
|
||||||
|
self.assertEqual(columns, collist)
|
||||||
|
datalist = (
|
||||||
|
(object_fakes.object_name_2, ),
|
||||||
|
)
|
||||||
|
self.assertEqual(tuple(data), datalist)
|
||||||
|
|
||||||
|
def test_object_list_objects_long(self, o_mock):
|
||||||
|
o_mock.return_value = [
|
||||||
|
copy.deepcopy(object_fakes.OBJECT),
|
||||||
|
copy.deepcopy(object_fakes.OBJECT_2),
|
||||||
|
]
|
||||||
|
|
||||||
|
arglist = [
|
||||||
|
'--long',
|
||||||
|
object_fakes.container_name,
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('long', True),
|
||||||
|
('container', 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 = {
|
||||||
|
}
|
||||||
|
o_mock.assert_called_with(
|
||||||
|
self.app.restapi,
|
||||||
|
AUTH_URL,
|
||||||
|
object_fakes.container_name,
|
||||||
|
**kwargs
|
||||||
|
)
|
||||||
|
|
||||||
|
collist = ('Name', 'Bytes', 'Hash', 'Content Type', 'Last Modified')
|
||||||
|
self.assertEqual(columns, collist)
|
||||||
|
datalist = (
|
||||||
|
(
|
||||||
|
object_fakes.object_name_1,
|
||||||
|
object_fakes.object_bytes_1,
|
||||||
|
object_fakes.object_hash_1,
|
||||||
|
object_fakes.object_content_type_1,
|
||||||
|
object_fakes.object_modified_1,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
object_fakes.object_name_2,
|
||||||
|
object_fakes.object_bytes_2,
|
||||||
|
object_fakes.object_hash_2,
|
||||||
|
object_fakes.object_content_type_2,
|
||||||
|
object_fakes.object_modified_2,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
self.assertEqual(tuple(data), datalist)
|
||||||
|
|
||||||
|
def test_object_list_objects_all(self, o_mock):
|
||||||
|
o_mock.return_value = [
|
||||||
|
copy.deepcopy(object_fakes.OBJECT),
|
||||||
|
copy.deepcopy(object_fakes.OBJECT_2),
|
||||||
|
]
|
||||||
|
|
||||||
|
arglist = [
|
||||||
|
'--all',
|
||||||
|
object_fakes.container_name,
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('all', True),
|
||||||
|
('container', 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 = {
|
||||||
|
'full_listing': True,
|
||||||
|
}
|
||||||
|
o_mock.assert_called_with(
|
||||||
|
self.app.restapi,
|
||||||
|
AUTH_URL,
|
||||||
|
object_fakes.container_name,
|
||||||
|
**kwargs
|
||||||
|
)
|
||||||
|
|
||||||
|
collist = ('Name',)
|
||||||
|
self.assertEqual(columns, collist)
|
||||||
|
datalist = (
|
||||||
|
(object_fakes.object_name_1, ),
|
||||||
|
(object_fakes.object_name_2, ),
|
||||||
|
)
|
||||||
|
self.assertEqual(tuple(data), datalist)
|
12
openstackclient/tests/object/v1/__init__.py
Normal file
12
openstackclient/tests/object/v1/__init__.py
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# 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.
|
||||||
|
#
|
12
openstackclient/tests/object/v1/lib/__init__.py
Normal file
12
openstackclient/tests/object/v1/lib/__init__.py
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# 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.
|
||||||
|
#
|
159
openstackclient/tests/object/v1/lib/test_container.py
Normal file
159
openstackclient/tests/object/v1/lib/test_container.py
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
# 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"""
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import mock
|
||||||
|
|
||||||
|
|
||||||
|
from openstackclient.object.v1.lib import container as lib_container
|
||||||
|
from openstackclient.tests.common import test_restapi as restapi
|
||||||
|
from openstackclient.tests import utils
|
||||||
|
|
||||||
|
|
||||||
|
fake_auth = '11223344556677889900'
|
||||||
|
fake_url = 'http://gopher.com'
|
||||||
|
|
||||||
|
fake_container = 'rainbarrel'
|
||||||
|
|
||||||
|
|
||||||
|
class FakeClient(object):
|
||||||
|
def __init__(self, endpoint=None, **kwargs):
|
||||||
|
self.endpoint = fake_url
|
||||||
|
self.token = fake_auth
|
||||||
|
|
||||||
|
|
||||||
|
class TestObject(utils.TestCommand):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestObject, self).setUp()
|
||||||
|
self.app.client_manager.object = FakeClient()
|
||||||
|
self.app.restapi = mock.MagicMock()
|
||||||
|
|
||||||
|
|
||||||
|
class TestObjectListContainers(TestObject):
|
||||||
|
|
||||||
|
def test_list_containers_no_options(self):
|
||||||
|
resp = [{'name': 'is-name'}]
|
||||||
|
self.app.restapi.request.return_value = restapi.FakeResponse(data=resp)
|
||||||
|
|
||||||
|
data = lib_container.list_containers(
|
||||||
|
self.app.restapi,
|
||||||
|
self.app.client_manager.object.endpoint,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Check expected values
|
||||||
|
self.app.restapi.request.assert_called_with(
|
||||||
|
'GET',
|
||||||
|
fake_url + '?format=json',
|
||||||
|
)
|
||||||
|
self.assertEqual(data, resp)
|
||||||
|
|
||||||
|
def test_list_containers_marker(self):
|
||||||
|
resp = [{'name': 'is-name'}]
|
||||||
|
self.app.restapi.request.return_value = restapi.FakeResponse(data=resp)
|
||||||
|
|
||||||
|
data = lib_container.list_containers(
|
||||||
|
self.app.restapi,
|
||||||
|
self.app.client_manager.object.endpoint,
|
||||||
|
marker='next',
|
||||||
|
)
|
||||||
|
|
||||||
|
# Check expected values
|
||||||
|
self.app.restapi.request.assert_called_with(
|
||||||
|
'GET',
|
||||||
|
fake_url + '?format=json&marker=next',
|
||||||
|
)
|
||||||
|
self.assertEqual(data, resp)
|
||||||
|
|
||||||
|
def test_list_containers_limit(self):
|
||||||
|
resp = [{'name': 'is-name'}]
|
||||||
|
self.app.restapi.request.return_value = restapi.FakeResponse(data=resp)
|
||||||
|
|
||||||
|
data = lib_container.list_containers(
|
||||||
|
self.app.restapi,
|
||||||
|
self.app.client_manager.object.endpoint,
|
||||||
|
limit=5,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Check expected values
|
||||||
|
self.app.restapi.request.assert_called_with(
|
||||||
|
'GET',
|
||||||
|
fake_url + '?format=json&limit=5',
|
||||||
|
)
|
||||||
|
self.assertEqual(data, resp)
|
||||||
|
|
||||||
|
def test_list_containers_end_marker(self):
|
||||||
|
resp = [{'name': 'is-name'}]
|
||||||
|
self.app.restapi.request.return_value = restapi.FakeResponse(data=resp)
|
||||||
|
|
||||||
|
data = lib_container.list_containers(
|
||||||
|
self.app.restapi,
|
||||||
|
self.app.client_manager.object.endpoint,
|
||||||
|
end_marker='last',
|
||||||
|
)
|
||||||
|
|
||||||
|
# Check expected values
|
||||||
|
self.app.restapi.request.assert_called_with(
|
||||||
|
'GET',
|
||||||
|
fake_url + '?format=json&end_marker=last',
|
||||||
|
)
|
||||||
|
self.assertEqual(data, resp)
|
||||||
|
|
||||||
|
def test_list_containers_prefix(self):
|
||||||
|
resp = [{'name': 'is-name'}]
|
||||||
|
self.app.restapi.request.return_value = restapi.FakeResponse(data=resp)
|
||||||
|
|
||||||
|
data = lib_container.list_containers(
|
||||||
|
self.app.restapi,
|
||||||
|
self.app.client_manager.object.endpoint,
|
||||||
|
prefix='foo/',
|
||||||
|
)
|
||||||
|
|
||||||
|
# Check expected values
|
||||||
|
self.app.restapi.request.assert_called_with(
|
||||||
|
'GET',
|
||||||
|
fake_url + '?format=json&prefix=foo/',
|
||||||
|
)
|
||||||
|
self.assertEqual(data, resp)
|
||||||
|
|
||||||
|
def test_list_containers_full_listing(self):
|
||||||
|
|
||||||
|
def side_effect(*args, **kwargs):
|
||||||
|
rv = self.app.restapi.request.return_value
|
||||||
|
self.app.restapi.request.return_value = restapi.FakeResponse(
|
||||||
|
data=[],
|
||||||
|
)
|
||||||
|
self.app.restapi.request.side_effect = None
|
||||||
|
return rv
|
||||||
|
|
||||||
|
resp = [{'name': 'is-name'}]
|
||||||
|
self.app.restapi.request.return_value = restapi.FakeResponse(data=resp)
|
||||||
|
self.app.restapi.request.side_effect = side_effect
|
||||||
|
|
||||||
|
data = lib_container.list_containers(
|
||||||
|
self.app.restapi,
|
||||||
|
self.app.client_manager.object.endpoint,
|
||||||
|
full_listing=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Check expected values
|
||||||
|
self.app.restapi.request.assert_called_with(
|
||||||
|
'GET',
|
||||||
|
fake_url + '?format=json&marker=is-name',
|
||||||
|
)
|
||||||
|
self.assertEqual(data, resp)
|
203
openstackclient/tests/object/v1/lib/test_object.py
Normal file
203
openstackclient/tests/object/v1/lib/test_object.py
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
# 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"""
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import mock
|
||||||
|
|
||||||
|
from openstackclient.object.v1.lib import object as lib_object
|
||||||
|
from openstackclient.tests.common import test_restapi as restapi
|
||||||
|
from openstackclient.tests import utils
|
||||||
|
|
||||||
|
|
||||||
|
fake_auth = '11223344556677889900'
|
||||||
|
fake_url = 'http://gopher.com'
|
||||||
|
|
||||||
|
fake_container = 'rainbarrel'
|
||||||
|
|
||||||
|
|
||||||
|
class FakeClient(object):
|
||||||
|
def __init__(self, endpoint=None, **kwargs):
|
||||||
|
self.endpoint = fake_url
|
||||||
|
self.token = fake_auth
|
||||||
|
|
||||||
|
|
||||||
|
class TestObject(utils.TestCommand):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestObject, self).setUp()
|
||||||
|
self.app.client_manager.object = FakeClient()
|
||||||
|
self.app.restapi = mock.MagicMock()
|
||||||
|
|
||||||
|
|
||||||
|
class TestObjectListObjects(TestObject):
|
||||||
|
|
||||||
|
def test_list_objects_no_options(self):
|
||||||
|
resp = [{'name': 'is-name'}]
|
||||||
|
self.app.restapi.request.return_value = restapi.FakeResponse(data=resp)
|
||||||
|
|
||||||
|
data = lib_object.list_objects(
|
||||||
|
self.app.restapi,
|
||||||
|
self.app.client_manager.object.endpoint,
|
||||||
|
fake_container,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Check expected values
|
||||||
|
self.app.restapi.request.assert_called_with(
|
||||||
|
'GET',
|
||||||
|
fake_url + '/' + fake_container + '?format=json',
|
||||||
|
)
|
||||||
|
self.assertEqual(data, resp)
|
||||||
|
|
||||||
|
def test_list_objects_marker(self):
|
||||||
|
resp = [{'name': 'is-name'}]
|
||||||
|
self.app.restapi.request.return_value = restapi.FakeResponse(data=resp)
|
||||||
|
|
||||||
|
data = lib_object.list_objects(
|
||||||
|
self.app.restapi,
|
||||||
|
self.app.client_manager.object.endpoint,
|
||||||
|
fake_container,
|
||||||
|
marker='next',
|
||||||
|
)
|
||||||
|
|
||||||
|
# Check expected values
|
||||||
|
self.app.restapi.request.assert_called_with(
|
||||||
|
'GET',
|
||||||
|
fake_url + '/' + fake_container + '?format=json&marker=next',
|
||||||
|
)
|
||||||
|
self.assertEqual(data, resp)
|
||||||
|
|
||||||
|
def test_list_objects_limit(self):
|
||||||
|
resp = [{'name': 'is-name'}]
|
||||||
|
self.app.restapi.request.return_value = restapi.FakeResponse(data=resp)
|
||||||
|
|
||||||
|
data = lib_object.list_objects(
|
||||||
|
self.app.restapi,
|
||||||
|
self.app.client_manager.object.endpoint,
|
||||||
|
fake_container,
|
||||||
|
limit=5,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Check expected values
|
||||||
|
self.app.restapi.request.assert_called_with(
|
||||||
|
'GET',
|
||||||
|
fake_url + '/' + fake_container + '?format=json&limit=5',
|
||||||
|
)
|
||||||
|
self.assertEqual(data, resp)
|
||||||
|
|
||||||
|
def test_list_objects_end_marker(self):
|
||||||
|
resp = [{'name': 'is-name'}]
|
||||||
|
self.app.restapi.request.return_value = restapi.FakeResponse(data=resp)
|
||||||
|
|
||||||
|
data = lib_object.list_objects(
|
||||||
|
self.app.restapi,
|
||||||
|
self.app.client_manager.object.endpoint,
|
||||||
|
fake_container,
|
||||||
|
end_marker='last',
|
||||||
|
)
|
||||||
|
|
||||||
|
# Check expected values
|
||||||
|
self.app.restapi.request.assert_called_with(
|
||||||
|
'GET',
|
||||||
|
fake_url + '/' + fake_container + '?format=json&end_marker=last',
|
||||||
|
)
|
||||||
|
self.assertEqual(data, resp)
|
||||||
|
|
||||||
|
def test_list_objects_delimiter(self):
|
||||||
|
resp = [{'name': 'is-name'}]
|
||||||
|
self.app.restapi.request.return_value = restapi.FakeResponse(data=resp)
|
||||||
|
|
||||||
|
data = lib_object.list_objects(
|
||||||
|
self.app.restapi,
|
||||||
|
self.app.client_manager.object.endpoint,
|
||||||
|
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.restapi.request.assert_called_with(
|
||||||
|
'GET',
|
||||||
|
fake_url + '/' + fake_container + '?format=json&delimiter=|',
|
||||||
|
)
|
||||||
|
self.assertEqual(data, resp)
|
||||||
|
|
||||||
|
def test_list_objects_prefix(self):
|
||||||
|
resp = [{'name': 'is-name'}]
|
||||||
|
self.app.restapi.request.return_value = restapi.FakeResponse(data=resp)
|
||||||
|
|
||||||
|
data = lib_object.list_objects(
|
||||||
|
self.app.restapi,
|
||||||
|
self.app.client_manager.object.endpoint,
|
||||||
|
fake_container,
|
||||||
|
prefix='foo/',
|
||||||
|
)
|
||||||
|
|
||||||
|
# Check expected values
|
||||||
|
self.app.restapi.request.assert_called_with(
|
||||||
|
'GET',
|
||||||
|
fake_url + '/' + fake_container + '?format=json&prefix=foo/',
|
||||||
|
)
|
||||||
|
self.assertEqual(data, resp)
|
||||||
|
|
||||||
|
def test_list_objects_path(self):
|
||||||
|
resp = [{'name': 'is-name'}]
|
||||||
|
self.app.restapi.request.return_value = restapi.FakeResponse(data=resp)
|
||||||
|
|
||||||
|
data = lib_object.list_objects(
|
||||||
|
self.app.restapi,
|
||||||
|
self.app.client_manager.object.endpoint,
|
||||||
|
fake_container,
|
||||||
|
path='next',
|
||||||
|
)
|
||||||
|
|
||||||
|
# Check expected values
|
||||||
|
self.app.restapi.request.assert_called_with(
|
||||||
|
'GET',
|
||||||
|
fake_url + '/' + fake_container + '?format=json&path=next',
|
||||||
|
)
|
||||||
|
self.assertEqual(data, resp)
|
||||||
|
|
||||||
|
def test_list_objects_full_listing(self):
|
||||||
|
|
||||||
|
def side_effect(*args, **kwargs):
|
||||||
|
rv = self.app.restapi.request.return_value
|
||||||
|
self.app.restapi.request.return_value = restapi.FakeResponse(
|
||||||
|
data=[],
|
||||||
|
)
|
||||||
|
self.app.restapi.request.side_effect = None
|
||||||
|
return rv
|
||||||
|
|
||||||
|
resp = [{'name': 'is-name'}]
|
||||||
|
self.app.restapi.request.return_value = restapi.FakeResponse(data=resp)
|
||||||
|
self.app.restapi.request.side_effect = side_effect
|
||||||
|
|
||||||
|
data = lib_object.list_objects(
|
||||||
|
self.app.restapi,
|
||||||
|
self.app.client_manager.object.endpoint,
|
||||||
|
fake_container,
|
||||||
|
full_listing=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Check expected values
|
||||||
|
self.app.restapi.request.assert_called_with(
|
||||||
|
'GET',
|
||||||
|
fake_url + '/' + fake_container + '?format=json&marker=is-name',
|
||||||
|
)
|
||||||
|
self.assertEqual(data, resp)
|
@ -71,6 +71,7 @@ class TestCommand(TestCase):
|
|||||||
self.fake_stdout = fakes.FakeStdout()
|
self.fake_stdout = fakes.FakeStdout()
|
||||||
self.app = fakes.FakeApp(self.fake_stdout)
|
self.app = fakes.FakeApp(self.fake_stdout)
|
||||||
self.app.client_manager = fakes.FakeClientManager()
|
self.app.client_manager = fakes.FakeClientManager()
|
||||||
|
self.app.restapi = fakes.FakeRESTApi()
|
||||||
|
|
||||||
def check_parser(self, cmd, args, verify_args):
|
def check_parser(self, cmd, args, verify_args):
|
||||||
cmd_parser = cmd.get_parser('check_parser')
|
cmd_parser = cmd.get_parser('check_parser')
|
||||||
|
@ -239,6 +239,10 @@ openstack.compute.v2 =
|
|||||||
server_unrescue = openstackclient.compute.v2.server:UnrescueServer
|
server_unrescue = openstackclient.compute.v2.server:UnrescueServer
|
||||||
server_unset = openstackclient.compute.v2.server:UnsetServer
|
server_unset = openstackclient.compute.v2.server:UnsetServer
|
||||||
|
|
||||||
|
openstack.object_store.v1 =
|
||||||
|
container_list = openstackclient.object.v1.container:ListContainer
|
||||||
|
object_list = openstackclient.object.v1.object:ListObject
|
||||||
|
|
||||||
openstack.volume.v1 =
|
openstack.volume.v1 =
|
||||||
snapshot_create = openstackclient.volume.v1.snapshot:CreateSnapshot
|
snapshot_create = openstackclient.volume.v1.snapshot:CreateSnapshot
|
||||||
snapshot_delete = openstackclient.volume.v1.snapshot:DeleteSnapshot
|
snapshot_delete = openstackclient.volume.v1.snapshot:DeleteSnapshot
|
||||||
|
Loading…
x
Reference in New Issue
Block a user