summaryrefslogtreecommitdiff
path: root/openstackclient
diff options
context:
space:
mode:
authorDean Troyer <dtroyer@gmail.com>2014-09-18 00:56:38 -0500
committerDean Troyer <dtroyer@gmail.com>2015-01-20 17:01:23 -0600
commit1ecf1bee2d5c1566533cdd8fad99733ea8336aa8 (patch)
treeaaf60bd664d98b17dbb703f7b14fb681ccf24aaf /openstackclient
parent95fe3fda3d041a4fa761040c80214d4ca5f29aaa (diff)
downloadpython-openstackclient-1ecf1bee2d5c1566533cdd8fad99733ea8336aa8.tar.gz
Begin low-level API for Image v1 and v2
image list for v1 and v2: * Add --public|--private to command parsers * Implement local public/private filtering for v1 image_list() * Pass public/private filter to server for v2 image_list() Change-Id: Ie7c24ea2d1bf2b3b1b7fa342eb45fee45894634d
Diffstat (limited to 'openstackclient')
-rw-r--r--openstackclient/api/api.py2
-rw-r--r--openstackclient/api/image_v1.py68
-rw-r--r--openstackclient/api/image_v2.py69
-rw-r--r--openstackclient/image/client.py28
-rw-r--r--openstackclient/image/v1/image.py25
-rw-r--r--openstackclient/image/v2/image.py25
-rw-r--r--openstackclient/tests/api/test_image_v1.py98
-rw-r--r--openstackclient/tests/api/test_image_v2.py98
-rw-r--r--openstackclient/tests/image/v1/test_image.py167
-rw-r--r--openstackclient/tests/image/v2/test_image.py94
10 files changed, 614 insertions, 60 deletions
diff --git a/openstackclient/api/api.py b/openstackclient/api/api.py
index 90b4e9c3..ba83ce4d 100644
--- a/openstackclient/api/api.py
+++ b/openstackclient/api/api.py
@@ -161,7 +161,7 @@ class BaseAPI(KeystoneSession):
):
"""Return a list of resources
- GET ${ENDPOINT}/${PATH}
+ GET ${ENDPOINT}/${PATH}?${PARAMS}
path is often the object's plural resource type
diff --git a/openstackclient/api/image_v1.py b/openstackclient/api/image_v1.py
new file mode 100644
index 00000000..f9c780a4
--- /dev/null
+++ b/openstackclient/api/image_v1.py
@@ -0,0 +1,68 @@
+# 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.
+#
+
+"""Image v1 API Library"""
+
+from openstackclient.api import api
+
+
+class APIv1(api.BaseAPI):
+ """Image v1 API"""
+
+ def __init__(self, endpoint=None, **kwargs):
+ super(APIv1, self).__init__(endpoint=endpoint, **kwargs)
+
+ # Hack this until discovery is up
+ self.endpoint = '/'.join([self.endpoint.rstrip('/'), 'v1'])
+
+ def image_list(
+ self,
+ detailed=False,
+ public=False,
+ private=False,
+ **filter
+ ):
+ """Get available images
+
+ :param detailed:
+ Retrieve detailed response from server if True
+ :param public:
+ Return public images if True
+ :param private:
+ Return private images if True
+
+ If public and private are both True or both False then all images are
+ returned. Both arguments False is equivalent to no filter and all
+ images are returned. Both arguments True is a filter that includes
+ both public and private images which is the same set as all images.
+
+ http://docs.openstack.org/api/openstack-image-service/1.1/content/requesting-a-list-of-public-vm-images.html
+ http://docs.openstack.org/api/openstack-image-service/1.1/content/requesting-detailed-metadata-on-public-vm-images.html
+ http://docs.openstack.org/api/openstack-image-service/1.1/content/filtering-images-returned-via-get-images-and-get-imagesdetail.html
+
+ TODO(dtroyer): Implement filtering
+ """
+
+ url = "/images"
+ if detailed or public or private:
+ # Because we can't all use /details
+ url += "/detail"
+
+ image_list = self.list(url, **filter)['images']
+
+ if public != private:
+ # One is True and one is False, so public represents the filter
+ # state in either case
+ image_list = [i for i in image_list if i['is_public'] == public]
+
+ return image_list
diff --git a/openstackclient/api/image_v2.py b/openstackclient/api/image_v2.py
new file mode 100644
index 00000000..c5c78431
--- /dev/null
+++ b/openstackclient/api/image_v2.py
@@ -0,0 +1,69 @@
+# 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.
+#
+
+"""Image v2 API Library"""
+
+from openstackclient.api import image_v1
+
+
+class APIv2(image_v1.APIv1):
+ """Image v2 API"""
+
+ def __init__(self, endpoint=None, **kwargs):
+ super(APIv2, self).__init__(endpoint=endpoint, **kwargs)
+
+ # Hack this until discovery is up, and ignore parent endpoint setting
+ self.endpoint = '/'.join([endpoint.rstrip('/'), 'v2'])
+
+ def image_list(
+ self,
+ detailed=False,
+ public=False,
+ private=False,
+ **filter
+ ):
+ """Get available images
+
+ can add limit/marker
+
+ :param detailed:
+ For v1 compatibility only, ignored as v2 is always 'detailed'
+ :param public:
+ Return public images if True
+ :param private:
+ Return private images if True
+
+ If public and private are both True or both False then all images are
+ returned. Both arguments False is equivalent to no filter and all
+ images are returned. Both arguments True is a filter that includes
+ both public and private images which is the same set as all images.
+
+ http://docs.openstack.org/api/openstack-image-service/2.0/content/list-images.html
+
+ TODO(dtroyer): Implement filtering
+ """
+
+ if public == private:
+ # No filtering for both False and both True cases
+ filter.pop('visibility', None)
+ elif public:
+ filter['visibility'] = 'public'
+ elif private:
+ filter['visibility'] = 'private'
+
+ url = "/images"
+ if detailed:
+ # Because we can't all use /details
+ url += "/detail"
+
+ return self.list(url, **filter)['images']
diff --git a/openstackclient/image/client.py b/openstackclient/image/client.py
index c55ff853..35779664 100644
--- a/openstackclient/image/client.py
+++ b/openstackclient/image/client.py
@@ -31,9 +31,15 @@ API_VERSIONS = {
"2": "glanceclient.v2.client.Client",
}
+IMAGE_API_TYPE = 'image'
+IMAGE_API_VERSIONS = {
+ '1': 'openstackclient.api.image_v1.APIv1',
+ '2': 'openstackclient.api.image_v2.APIv2',
+}
+
def make_client(instance):
- """Returns an image service client."""
+ """Returns an image service client"""
image_client = utils.get_client_class(
API_NAME,
instance._api_version[API_NAME],
@@ -45,13 +51,31 @@ def make_client(instance):
region_name=instance._region_name,
)
- return image_client(
+ client = image_client(
endpoint,
token=instance.auth.get_token(instance.session),
cacert=instance._cacert,
insecure=instance._insecure,
)
+ # Create the low-level API
+
+ image_api = utils.get_client_class(
+ API_NAME,
+ instance._api_version[API_NAME],
+ IMAGE_API_VERSIONS)
+ LOG.debug('Instantiating image api: %s', image_api)
+
+ client.api = image_api(
+ session=instance.session,
+ endpoint=instance.get_endpoint_for_service_type(
+ IMAGE_API_TYPE,
+ region_name=instance._region_name,
+ )
+ )
+
+ return client
+
def build_option_parser(parser):
"""Hook to add global options"""
diff --git a/openstackclient/image/v1/image.py b/openstackclient/image/v1/image.py
index d7ece254..fc70000d 100644
--- a/openstackclient/image/v1/image.py
+++ b/openstackclient/image/v1/image.py
@@ -300,6 +300,21 @@ class ListImage(lister.Lister):
metavar="<size>",
help="Number of images to request in each paginated request",
)
+ public_group = parser.add_mutually_exclusive_group()
+ public_group.add_argument(
+ "--public",
+ dest="public",
+ action="store_true",
+ default=False,
+ help="List only public images",
+ )
+ public_group.add_argument(
+ "--private",
+ dest="private",
+ action="store_true",
+ default=False,
+ help="List only private images",
+ )
parser.add_argument(
'--long',
action='store_true',
@@ -316,15 +331,21 @@ class ListImage(lister.Lister):
kwargs = {}
if parsed_args.page_size is not None:
kwargs["page_size"] = parsed_args.page_size
+ if parsed_args.public:
+ kwargs['public'] = True
+ if parsed_args.private:
+ kwargs['private'] = True
+ kwargs['detailed'] = parsed_args.long
- data = image_client.images.list(**kwargs)
if parsed_args.long:
columns = ('ID', 'Name', 'Disk Format', 'Container Format',
'Size', 'Status')
else:
columns = ("ID", "Name")
- return (columns, (utils.get_item_properties(s, columns) for s in data))
+ data = image_client.api.image_list(**kwargs)
+
+ return (columns, (utils.get_dict_properties(s, columns) for s in data))
class SaveImage(command.Command):
diff --git a/openstackclient/image/v2/image.py b/openstackclient/image/v2/image.py
index d5ee692c..2e0fd393 100644
--- a/openstackclient/image/v2/image.py
+++ b/openstackclient/image/v2/image.py
@@ -65,6 +65,21 @@ class ListImage(lister.Lister):
metavar="<size>",
help="Number of images to request in each paginated request",
)
+ public_group = parser.add_mutually_exclusive_group()
+ public_group.add_argument(
+ "--public",
+ dest="public",
+ action="store_true",
+ default=False,
+ help="List only public images",
+ )
+ public_group.add_argument(
+ "--private",
+ dest="private",
+ action="store_true",
+ default=False,
+ help="List only private images",
+ )
parser.add_argument(
'--long',
action='store_true',
@@ -81,15 +96,21 @@ class ListImage(lister.Lister):
kwargs = {}
if parsed_args.page_size is not None:
kwargs["page_size"] = parsed_args.page_size
+ if parsed_args.public:
+ kwargs['public'] = True
+ if parsed_args.private:
+ kwargs['private'] = True
+ kwargs['detailed'] = parsed_args.long
- data = image_client.images.list(**kwargs)
if parsed_args.long:
columns = ('ID', 'Name', 'Disk Format', 'Container Format',
'Size', 'Status')
else:
columns = ("ID", "Name")
- return (columns, (utils.get_item_properties(s, columns) for s in data))
+ data = image_client.api.image_list(**kwargs)
+
+ return (columns, (utils.get_dict_properties(s, columns) for s in data))
class SaveImage(command.Command):
diff --git a/openstackclient/tests/api/test_image_v1.py b/openstackclient/tests/api/test_image_v1.py
new file mode 100644
index 00000000..34fcfca4
--- /dev/null
+++ b/openstackclient/tests/api/test_image_v1.py
@@ -0,0 +1,98 @@
+# 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.
+#
+
+"""Image v1 API Library Tests"""
+
+from requests_mock.contrib import fixture
+
+from keystoneclient import session
+from openstackclient.api import image_v1
+from openstackclient.tests import utils
+
+
+FAKE_PROJECT = 'xyzpdq'
+FAKE_URL = 'http://gopher.com'
+
+
+class TestImageAPIv1(utils.TestCase):
+
+ def setUp(self):
+ super(TestImageAPIv1, self).setUp()
+
+ sess = session.Session()
+ self.api = image_v1.APIv1(session=sess, endpoint=FAKE_URL)
+ self.requests_mock = self.useFixture(fixture.Fixture())
+
+
+class TestImage(TestImageAPIv1):
+
+ PUB_PROT = {
+ 'id': '1',
+ 'name': 'pub1',
+ 'is_public': True,
+ 'protected': True,
+ }
+ PUB_NOPROT = {
+ 'id': '2',
+ 'name': 'pub2-noprot',
+ 'is_public': True,
+ 'protected': False,
+ }
+ NOPUB_PROT = {
+ 'id': '3',
+ 'name': 'priv3',
+ 'is_public': False,
+ 'protected': True,
+ }
+ NOPUB_NOPROT = {
+ 'id': '4',
+ 'name': 'priv4-noprot',
+ 'is_public': False,
+ 'protected': False,
+ }
+ LIST_IMAGE_RESP = [
+ PUB_PROT,
+ PUB_NOPROT,
+ NOPUB_PROT,
+ NOPUB_NOPROT,
+ ]
+
+ def test_image_list_no_options(self):
+ self.requests_mock.register_uri(
+ 'GET',
+ FAKE_URL + '/v1/images',
+ json={'images': self.LIST_IMAGE_RESP},
+ status_code=200,
+ )
+ ret = self.api.image_list()
+ self.assertEqual(self.LIST_IMAGE_RESP, ret)
+
+ def test_image_list_public(self):
+ self.requests_mock.register_uri(
+ 'GET',
+ FAKE_URL + '/v1/images/detail',
+ json={'images': self.LIST_IMAGE_RESP},
+ status_code=200,
+ )
+ ret = self.api.image_list(public=True)
+ self.assertEqual([self.PUB_PROT, self.PUB_NOPROT], ret)
+
+ def test_image_list_private(self):
+ self.requests_mock.register_uri(
+ 'GET',
+ FAKE_URL + '/v1/images/detail',
+ json={'images': self.LIST_IMAGE_RESP},
+ status_code=200,
+ )
+ ret = self.api.image_list(private=True)
+ self.assertEqual([self.NOPUB_PROT, self.NOPUB_NOPROT], ret)
diff --git a/openstackclient/tests/api/test_image_v2.py b/openstackclient/tests/api/test_image_v2.py
new file mode 100644
index 00000000..ddb160ee
--- /dev/null
+++ b/openstackclient/tests/api/test_image_v2.py
@@ -0,0 +1,98 @@
+# 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.
+#
+
+"""Image v2 API Library Tests"""
+
+from requests_mock.contrib import fixture
+
+from keystoneclient import session
+from openstackclient.api import image_v2
+from openstackclient.tests import utils
+
+
+FAKE_PROJECT = 'xyzpdq'
+FAKE_URL = 'http://gopher.com'
+
+
+class TestImageAPIv2(utils.TestCase):
+
+ def setUp(self):
+ super(TestImageAPIv2, self).setUp()
+
+ sess = session.Session()
+ self.api = image_v2.APIv2(session=sess, endpoint=FAKE_URL)
+ self.requests_mock = self.useFixture(fixture.Fixture())
+
+
+class TestImage(TestImageAPIv2):
+
+ PUB_PROT = {
+ 'id': '1',
+ 'name': 'pub1',
+ 'visibility': 'public',
+ 'protected': True,
+ }
+ PUB_NOPROT = {
+ 'id': '2',
+ 'name': 'pub2-noprot',
+ 'visibility': 'public',
+ 'protected': False,
+ }
+ NOPUB_PROT = {
+ 'id': '3',
+ 'name': 'priv3',
+ 'visibility': 'private',
+ 'protected': True,
+ }
+ NOPUB_NOPROT = {
+ 'id': '4',
+ 'name': 'priv4-noprot',
+ 'visibility': 'private',
+ 'protected': False,
+ }
+ LIST_IMAGE_RESP = [
+ PUB_PROT,
+ PUB_NOPROT,
+ NOPUB_PROT,
+ NOPUB_NOPROT,
+ ]
+
+ def test_image_list_no_options(self):
+ self.requests_mock.register_uri(
+ 'GET',
+ FAKE_URL + '/v2/images',
+ json={'images': self.LIST_IMAGE_RESP},
+ status_code=200,
+ )
+ ret = self.api.image_list()
+ self.assertEqual(self.LIST_IMAGE_RESP, ret)
+
+ def test_image_list_public(self):
+ self.requests_mock.register_uri(
+ 'GET',
+ FAKE_URL + '/v2/images',
+ json={'images': [self.PUB_PROT, self.PUB_NOPROT]},
+ status_code=200,
+ )
+ ret = self.api.image_list(public=True)
+ self.assertEqual([self.PUB_PROT, self.PUB_NOPROT], ret)
+
+ def test_image_list_private(self):
+ self.requests_mock.register_uri(
+ 'GET',
+ FAKE_URL + '/v2/images',
+ json={'images': [self.NOPUB_PROT, self.NOPUB_NOPROT]},
+ status_code=200,
+ )
+ ret = self.api.image_list(public=True)
+ self.assertEqual([self.NOPUB_PROT, self.NOPUB_NOPROT], ret)
diff --git a/openstackclient/tests/image/v1/test_image.py b/openstackclient/tests/image/v1/test_image.py
index 4d21ac48..95126c2d 100644
--- a/openstackclient/tests/image/v1/test_image.py
+++ b/openstackclient/tests/image/v1/test_image.py
@@ -300,6 +300,128 @@ class TestImageDelete(TestImage):
)
+class TestImageList(TestImage):
+
+ def setUp(self):
+ super(TestImageList, self).setUp()
+
+ self.api_mock = mock.Mock()
+ self.api_mock.image_list.return_value = [
+ copy.deepcopy(image_fakes.IMAGE),
+ ]
+ self.app.client_manager.image.api = self.api_mock
+
+ # Get the command object to test
+ self.cmd = image.ListImage(self.app, None)
+
+ def test_image_list_no_options(self):
+ arglist = []
+ verifylist = [
+ ('public', False),
+ ('private', False),
+ ('long', False),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # DisplayCommandBase.take_action() returns two tuples
+ columns, data = self.cmd.take_action(parsed_args)
+ self.api_mock.image_list.assert_called_with(
+ detailed=False,
+ )
+
+ collist = ('ID', 'Name')
+
+ self.assertEqual(columns, collist)
+ datalist = ((
+ image_fakes.image_id,
+ image_fakes.image_name,
+ ), )
+ self.assertEqual(datalist, tuple(data))
+
+ def test_image_list_public_option(self):
+ arglist = [
+ '--public',
+ ]
+ verifylist = [
+ ('public', True),
+ ('private', False),
+ ('long', False),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # DisplayCommandBase.take_action() returns two tuples
+ columns, data = self.cmd.take_action(parsed_args)
+ self.api_mock.image_list.assert_called_with(
+ detailed=False,
+ public=True,
+ )
+
+ collist = ('ID', 'Name')
+
+ self.assertEqual(columns, collist)
+ datalist = ((
+ image_fakes.image_id,
+ image_fakes.image_name,
+ ), )
+ self.assertEqual(datalist, tuple(data))
+
+ def test_image_list_private_option(self):
+ arglist = [
+ '--private',
+ ]
+ verifylist = [
+ ('public', False),
+ ('private', True),
+ ('long', False),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # DisplayCommandBase.take_action() returns two tuples
+ columns, data = self.cmd.take_action(parsed_args)
+ self.api_mock.image_list.assert_called_with(
+ detailed=False,
+ private=True,
+ )
+
+ collist = ('ID', 'Name')
+
+ self.assertEqual(columns, collist)
+ datalist = ((
+ image_fakes.image_id,
+ image_fakes.image_name,
+ ), )
+ self.assertEqual(datalist, tuple(data))
+
+ def test_image_list_long_option(self):
+ 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)
+ self.api_mock.image_list.assert_called_with(
+ detailed=True,
+ )
+
+ collist = ('ID', 'Name', 'Disk Format', 'Container Format',
+ 'Size', 'Status')
+
+ self.assertEqual(columns, collist)
+ datalist = ((
+ image_fakes.image_id,
+ image_fakes.image_name,
+ '',
+ '',
+ '',
+ '',
+ ), )
+ self.assertEqual(datalist, tuple(data))
+
+
class TestImageSet(TestImage):
def setUp(self):
@@ -453,48 +575,3 @@ class TestImageSet(TestImage):
image_fakes.image_id,
**kwargs
)
-
-
-class TestImageList(TestImage):
-
- def setUp(self):
- super(TestImageList, self).setUp()
-
- # This is the return value for utils.find_resource()
- self.images_mock.list.return_value = [
- fakes.FakeResource(
- None,
- copy.deepcopy(image_fakes.IMAGE),
- loaded=True,
- ),
- ]
-
- # Get the command object to test
- self.cmd = image.ListImage(self.app, None)
-
- def test_image_list_long_option(self):
- 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)
- self.images_mock.list.assert_called_with()
-
- collist = ('ID', 'Name', 'Disk Format', 'Container Format',
- 'Size', 'Status')
-
- self.assertEqual(columns, collist)
- datalist = ((
- image_fakes.image_id,
- image_fakes.image_name,
- '',
- '',
- '',
- '',
- ), )
- self.assertEqual(datalist, tuple(data))
diff --git a/openstackclient/tests/image/v2/test_image.py b/openstackclient/tests/image/v2/test_image.py
index bc61a89f..8fb31caa 100644
--- a/openstackclient/tests/image/v2/test_image.py
+++ b/openstackclient/tests/image/v2/test_image.py
@@ -14,6 +14,7 @@
#
import copy
+import mock
from openstackclient.image.v2 import image
from openstackclient.tests import fakes
@@ -68,18 +69,93 @@ class TestImageList(TestImage):
def setUp(self):
super(TestImageList, self).setUp()
- # This is the return value for utils.find_resource()
- self.images_mock.list.return_value = [
- fakes.FakeResource(
- None,
- copy.deepcopy(image_fakes.IMAGE),
- loaded=True,
- ),
+ self.api_mock = mock.Mock()
+ self.api_mock.image_list.return_value = [
+ copy.deepcopy(image_fakes.IMAGE),
]
+ self.app.client_manager.image.api = self.api_mock
# Get the command object to test
self.cmd = image.ListImage(self.app, None)
+ def test_image_list_no_options(self):
+ arglist = []
+ verifylist = [
+ ('public', False),
+ ('private', False),
+ ('long', False),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # DisplayCommandBase.take_action() returns two tuples
+ columns, data = self.cmd.take_action(parsed_args)
+ self.api_mock.image_list.assert_called_with(
+ detailed=False,
+ )
+
+ collist = ('ID', 'Name')
+
+ self.assertEqual(columns, collist)
+ datalist = ((
+ image_fakes.image_id,
+ image_fakes.image_name,
+ ), )
+ self.assertEqual(datalist, tuple(data))
+
+ def test_image_list_public_option(self):
+ arglist = [
+ '--public',
+ ]
+ verifylist = [
+ ('public', True),
+ ('private', False),
+ ('long', False),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # DisplayCommandBase.take_action() returns two tuples
+ columns, data = self.cmd.take_action(parsed_args)
+ self.api_mock.image_list.assert_called_with(
+ detailed=False,
+ public=True,
+ )
+
+ collist = ('ID', 'Name')
+
+ self.assertEqual(columns, collist)
+ datalist = ((
+ image_fakes.image_id,
+ image_fakes.image_name,
+ ), )
+ self.assertEqual(datalist, tuple(data))
+
+ def test_image_list_private_option(self):
+ arglist = [
+ '--private',
+ ]
+ verifylist = [
+ ('public', False),
+ ('private', True),
+ ('long', False),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # DisplayCommandBase.take_action() returns two tuples
+ columns, data = self.cmd.take_action(parsed_args)
+ self.api_mock.image_list.assert_called_with(
+ detailed=False,
+ private=True,
+ )
+
+ collist = ('ID', 'Name')
+
+ self.assertEqual(columns, collist)
+ datalist = ((
+ image_fakes.image_id,
+ image_fakes.image_name,
+ ), )
+ self.assertEqual(datalist, tuple(data))
+
def test_image_list_long_option(self):
arglist = [
'--long',
@@ -91,7 +167,9 @@ class TestImageList(TestImage):
# DisplayCommandBase.take_action() returns two tuples
columns, data = self.cmd.take_action(parsed_args)
- self.images_mock.list.assert_called_with()
+ self.api_mock.image_list.assert_called_with(
+ detailed=True,
+ )
collist = ('ID', 'Name', 'Disk Format', 'Container Format',
'Size', 'Status')