Add support to the client for autopagination
This adds pagination support to the underlying client as well as autopagination support on the CLI. This adds --all and --marker to the associated {cells,hosts,projects,regions}-list commands. Depends-On: I11c5c6053e5f0873ee53df5b7dcb9b2ed25a0b64 Change-Id: Ic1f8f01e052ff7870f731d6c8a5d47d58d9dcfe9
This commit is contained in:
parent
78b6473ef7
commit
892cba1651
@ -103,14 +103,19 @@ class CRUDClient(object):
|
|||||||
return self.resource_class(self, response.json(), loaded=True)
|
return self.resource_class(self, response.json(), loaded=True)
|
||||||
|
|
||||||
def list(self, skip_merge=False, **kwargs):
|
def list(self, skip_merge=False, **kwargs):
|
||||||
"""List the items from this endpoint."""
|
"""Generate the items from this endpoint."""
|
||||||
|
autopaginate = kwargs.pop('autopaginate', True)
|
||||||
self.merge_request_arguments(kwargs, skip_merge)
|
self.merge_request_arguments(kwargs, skip_merge)
|
||||||
url = self.build_url(path_arguments=kwargs)
|
url = self.build_url(path_arguments=kwargs)
|
||||||
response = self.session.get(url, params=kwargs)
|
response_generator = self.session.paginate(
|
||||||
return [
|
url,
|
||||||
self.resource_class(self, item, loaded=True)
|
autopaginate=autopaginate,
|
||||||
for item in response.json()
|
items_key=(self.key + 's'),
|
||||||
]
|
params=kwargs,
|
||||||
|
)
|
||||||
|
for response, items in response_generator:
|
||||||
|
for item in items:
|
||||||
|
yield self.resource_class(self, item, loaded=True)
|
||||||
|
|
||||||
def update(self, item_id=None, skip_merge=True, **kwargs):
|
def update(self, item_id=None, skip_merge=True, **kwargs):
|
||||||
"""Update the item based on the keyword arguments provided."""
|
"""Update the item based on the keyword arguments provided."""
|
||||||
|
@ -232,3 +232,49 @@ class Session(object):
|
|||||||
raise exc.error_from(response)
|
raise exc.error_from(response)
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
def paginate(self, url, items_key, autopaginate=True, **kwargs):
|
||||||
|
"""Make a GET request to a paginated resource.
|
||||||
|
|
||||||
|
If :param:`autopaginate` is set to ``True``, this will automatically
|
||||||
|
handle finding and retrieving the next page of items.
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
>>> from cratonclient import session as craton
|
||||||
|
>>> session = craton.Session(
|
||||||
|
... username='demo',
|
||||||
|
... token='p@##w0rd',
|
||||||
|
... project_id='84363597-721c-4068-9731-8824692b51bb',
|
||||||
|
... )
|
||||||
|
>>> url = 'https://example.com/v1/hosts'
|
||||||
|
>>> for response in session.paginate(url, items_key='hosts'):
|
||||||
|
... print("Received status {}".format(response.status_code))
|
||||||
|
... print("Received {} items".format(len(items)))
|
||||||
|
|
||||||
|
:param bool autopaginate:
|
||||||
|
Determines whether or not this method continues requesting items
|
||||||
|
automatically after the first page.
|
||||||
|
"""
|
||||||
|
response = self.get(url, **kwargs)
|
||||||
|
json_body = response.json()
|
||||||
|
items = json_body[items_key]
|
||||||
|
links = json_body['links']
|
||||||
|
yield response, items
|
||||||
|
while autopaginate and len(items) > 0:
|
||||||
|
url = _find_next_link(links)
|
||||||
|
if url is None:
|
||||||
|
break
|
||||||
|
response = self.get(url)
|
||||||
|
json_body = response.json()
|
||||||
|
items = json_body[items_key]
|
||||||
|
links = json_body['links']
|
||||||
|
yield response, items
|
||||||
|
|
||||||
|
|
||||||
|
def _find_next_link(links):
|
||||||
|
for link in links:
|
||||||
|
if link['rel'] == 'next':
|
||||||
|
return link['href']
|
||||||
|
|
||||||
|
return None
|
||||||
|
@ -39,10 +39,6 @@ def do_cell_show(cc, args):
|
|||||||
action='store_true',
|
action='store_true',
|
||||||
default=False,
|
default=False,
|
||||||
help='Show detailed information about the cells.')
|
help='Show detailed information about the cells.')
|
||||||
@cliutils.arg('--limit',
|
|
||||||
metavar='<limit>',
|
|
||||||
type=int,
|
|
||||||
help='Maximum number of cells to return.')
|
|
||||||
@cliutils.arg('--sort-key',
|
@cliutils.arg('--sort-key',
|
||||||
metavar='<field>',
|
metavar='<field>',
|
||||||
help='Cell field that will be used for sorting.')
|
help='Cell field that will be used for sorting.')
|
||||||
@ -58,6 +54,20 @@ def do_cell_show(cc, args):
|
|||||||
help='Comma-separated list of fields to display. '
|
help='Comma-separated list of fields to display. '
|
||||||
'Only these fields will be fetched from the server. '
|
'Only these fields will be fetched from the server. '
|
||||||
'Can not be used when "--detail" is specified')
|
'Can not be used when "--detail" is specified')
|
||||||
|
@cliutils.arg('--all',
|
||||||
|
action='store_true',
|
||||||
|
default=False,
|
||||||
|
help='Retrieve and show all cells. This will override '
|
||||||
|
'the provided value for --limit and automatically '
|
||||||
|
'retrieve each page of results.')
|
||||||
|
@cliutils.arg('--limit',
|
||||||
|
metavar='<limit>',
|
||||||
|
type=int,
|
||||||
|
help='Maximum number of cells to return.')
|
||||||
|
@cliutils.arg('--marker',
|
||||||
|
metavar='<marker>',
|
||||||
|
default=None,
|
||||||
|
help='ID of the cell to use to resume listing cells.')
|
||||||
def do_cell_list(cc, args):
|
def do_cell_list(cc, args):
|
||||||
"""Print list of cells which are registered with the Craton service."""
|
"""Print list of cells which are registered with the Craton service."""
|
||||||
params = {}
|
params = {}
|
||||||
@ -68,6 +78,8 @@ def do_cell_list(cc, args):
|
|||||||
'non-negative limit, got {0}'
|
'non-negative limit, got {0}'
|
||||||
.format(args.limit))
|
.format(args.limit))
|
||||||
params['limit'] = args.limit
|
params['limit'] = args.limit
|
||||||
|
if args.all is True:
|
||||||
|
params['limit'] = 100
|
||||||
|
|
||||||
if args.fields and args.detail:
|
if args.fields and args.detail:
|
||||||
raise exc.CommandError('Cannot specify both --fields and --detail.')
|
raise exc.CommandError('Cannot specify both --fields and --detail.')
|
||||||
@ -95,6 +107,8 @@ def do_cell_list(cc, args):
|
|||||||
params['sort_key'] = sort_key
|
params['sort_key'] = sort_key
|
||||||
params['sort_dir'] = args.sort_dir
|
params['sort_dir'] = args.sort_dir
|
||||||
params['region_id'] = args.region
|
params['region_id'] = args.region
|
||||||
|
params['marker'] = args.marker
|
||||||
|
params['autopaginate'] = args.all
|
||||||
|
|
||||||
listed_cells = cc.cells.list(**params)
|
listed_cells = cc.cells.list(**params)
|
||||||
cliutils.print_list(listed_cells, list(fields))
|
cliutils.print_list(listed_cells, list(fields))
|
||||||
|
@ -44,10 +44,6 @@ def do_host_show(cc, args):
|
|||||||
action='store_true',
|
action='store_true',
|
||||||
default=False,
|
default=False,
|
||||||
help='Show detailed information about the hosts.')
|
help='Show detailed information about the hosts.')
|
||||||
@cliutils.arg('--limit',
|
|
||||||
metavar='<limit>',
|
|
||||||
type=int,
|
|
||||||
help='Maximum number of hosts to return.')
|
|
||||||
@cliutils.arg('--sort-key',
|
@cliutils.arg('--sort-key',
|
||||||
metavar='<field>',
|
metavar='<field>',
|
||||||
help='Host field that will be used for sorting.')
|
help='Host field that will be used for sorting.')
|
||||||
@ -63,6 +59,20 @@ def do_host_show(cc, args):
|
|||||||
help='Comma-separated list of fields to display. '
|
help='Comma-separated list of fields to display. '
|
||||||
'Only these fields will be fetched from the server. '
|
'Only these fields will be fetched from the server. '
|
||||||
'Can not be used when "--detail" is specified')
|
'Can not be used when "--detail" is specified')
|
||||||
|
@cliutils.arg('--all',
|
||||||
|
action='store_true',
|
||||||
|
default=False,
|
||||||
|
help='Retrieve and show all hosts. This will override '
|
||||||
|
'the provided value for --limit and automatically '
|
||||||
|
'retrieve each page of results.')
|
||||||
|
@cliutils.arg('--limit',
|
||||||
|
metavar='<limit>',
|
||||||
|
type=int,
|
||||||
|
help='Maximum number of hosts to return.')
|
||||||
|
@cliutils.arg('--marker',
|
||||||
|
metavar='<marker>',
|
||||||
|
default=None,
|
||||||
|
help='ID of the cell to use to resume listing hosts.')
|
||||||
def do_host_list(cc, args):
|
def do_host_list(cc, args):
|
||||||
"""Print list of hosts which are registered with the Craton service."""
|
"""Print list of hosts which are registered with the Craton service."""
|
||||||
params = {}
|
params = {}
|
||||||
@ -75,6 +85,8 @@ def do_host_list(cc, args):
|
|||||||
'non-negative limit, got {0}'
|
'non-negative limit, got {0}'
|
||||||
.format(args.limit))
|
.format(args.limit))
|
||||||
params['limit'] = args.limit
|
params['limit'] = args.limit
|
||||||
|
if args.all is True:
|
||||||
|
params['limit'] = 100
|
||||||
|
|
||||||
if args.fields and args.detail:
|
if args.fields and args.detail:
|
||||||
raise exc.CommandError('Cannot specify both --fields and --detail.')
|
raise exc.CommandError('Cannot specify both --fields and --detail.')
|
||||||
@ -101,6 +113,8 @@ def do_host_list(cc, args):
|
|||||||
params['sort_key'] = sort_key
|
params['sort_key'] = sort_key
|
||||||
params['sort_dir'] = args.sort_dir
|
params['sort_dir'] = args.sort_dir
|
||||||
params['region_id'] = args.region
|
params['region_id'] = args.region
|
||||||
|
params['marker'] = args.marker
|
||||||
|
params['autopaginate'] = args.all
|
||||||
|
|
||||||
host_list = cc.hosts.list(**params)
|
host_list = cc.hosts.list(**params)
|
||||||
cliutils.print_list(host_list, list(fields))
|
cliutils.print_list(host_list, list(fields))
|
||||||
|
@ -36,10 +36,6 @@ def do_project_show(cc, args):
|
|||||||
action='store_true',
|
action='store_true',
|
||||||
default=False,
|
default=False,
|
||||||
help='Show detailed information about the projects.')
|
help='Show detailed information about the projects.')
|
||||||
@cliutils.arg('--limit',
|
|
||||||
metavar='<limit>',
|
|
||||||
type=int,
|
|
||||||
help='Maximum number of projects to return.')
|
|
||||||
@cliutils.arg('--fields',
|
@cliutils.arg('--fields',
|
||||||
nargs='+',
|
nargs='+',
|
||||||
metavar='<fields>',
|
metavar='<fields>',
|
||||||
@ -47,6 +43,20 @@ def do_project_show(cc, args):
|
|||||||
help='Comma-separated list of fields to display. '
|
help='Comma-separated list of fields to display. '
|
||||||
'Only these fields will be fetched from the server. '
|
'Only these fields will be fetched from the server. '
|
||||||
'Can not be used when "--detail" is specified')
|
'Can not be used when "--detail" is specified')
|
||||||
|
@cliutils.arg('--all',
|
||||||
|
action='store_true',
|
||||||
|
default=False,
|
||||||
|
help='Retrieve and show all projects. This will override '
|
||||||
|
'the provided value for --limit and automatically '
|
||||||
|
'retrieve each page of results.')
|
||||||
|
@cliutils.arg('--limit',
|
||||||
|
metavar='<limit>',
|
||||||
|
type=int,
|
||||||
|
help='Maximum number of projects to return.')
|
||||||
|
@cliutils.arg('--marker',
|
||||||
|
metavar='<marker>',
|
||||||
|
default=None,
|
||||||
|
help='ID of the cell to use to resume listing projects.')
|
||||||
def do_project_list(cc, args):
|
def do_project_list(cc, args):
|
||||||
"""Print list of projects which are registered with the Craton service."""
|
"""Print list of projects which are registered with the Craton service."""
|
||||||
params = {}
|
params = {}
|
||||||
@ -57,6 +67,8 @@ def do_project_list(cc, args):
|
|||||||
'non-negative limit, got {0}'
|
'non-negative limit, got {0}'
|
||||||
.format(args.limit))
|
.format(args.limit))
|
||||||
params['limit'] = args.limit
|
params['limit'] = args.limit
|
||||||
|
if args.all is True:
|
||||||
|
params['limit'] = 100
|
||||||
|
|
||||||
if args.fields and args.detail:
|
if args.fields and args.detail:
|
||||||
raise exc.CommandError('Cannot specify both --fields and --detail.')
|
raise exc.CommandError('Cannot specify both --fields and --detail.')
|
||||||
@ -72,6 +84,8 @@ def do_project_list(cc, args):
|
|||||||
raise exc.CommandError('Invalid field "{}"'.format(keyerr.args[0]))
|
raise exc.CommandError('Invalid field "{}"'.format(keyerr.args[0]))
|
||||||
else:
|
else:
|
||||||
fields = {x: projects.PROJECT_FIELDS[x] for x in default_fields}
|
fields = {x: projects.PROJECT_FIELDS[x] for x in default_fields}
|
||||||
|
params['marker'] = args.marker
|
||||||
|
params['autopaginate'] = args.all
|
||||||
|
|
||||||
listed_projects = cc.projects.list(**params)
|
listed_projects = cc.projects.list(**params)
|
||||||
cliutils.print_list(listed_projects, list(fields))
|
cliutils.print_list(listed_projects, list(fields))
|
||||||
|
@ -33,10 +33,6 @@ def do_region_create(cc, args):
|
|||||||
cliutils.print_dict(data, wrap=72)
|
cliutils.print_dict(data, wrap=72)
|
||||||
|
|
||||||
|
|
||||||
@cliutils.arg('--limit',
|
|
||||||
metavar='<limit>',
|
|
||||||
type=int,
|
|
||||||
help='Maximum number of regions to return.')
|
|
||||||
@cliutils.arg('--fields',
|
@cliutils.arg('--fields',
|
||||||
nargs='+',
|
nargs='+',
|
||||||
metavar='<fields>',
|
metavar='<fields>',
|
||||||
@ -44,6 +40,20 @@ def do_region_create(cc, args):
|
|||||||
help='Comma-separated list of fields to display. '
|
help='Comma-separated list of fields to display. '
|
||||||
'Only these fields will be fetched from the server. '
|
'Only these fields will be fetched from the server. '
|
||||||
'Can not be used when "--detail" is specified')
|
'Can not be used when "--detail" is specified')
|
||||||
|
@cliutils.arg('--all',
|
||||||
|
action='store_true',
|
||||||
|
default=False,
|
||||||
|
help='Retrieve and show all regions. This will override '
|
||||||
|
'the provided value for --limit and automatically '
|
||||||
|
'retrieve each page of results.')
|
||||||
|
@cliutils.arg('--limit',
|
||||||
|
metavar='<limit>',
|
||||||
|
type=int,
|
||||||
|
help='Maximum number of regions to return.')
|
||||||
|
@cliutils.arg('--marker',
|
||||||
|
metavar='<marker>',
|
||||||
|
default=None,
|
||||||
|
help='ID of the cell to use to resume listing regions.')
|
||||||
def do_region_list(cc, args):
|
def do_region_list(cc, args):
|
||||||
"""List all regions."""
|
"""List all regions."""
|
||||||
params = {}
|
params = {}
|
||||||
@ -54,6 +64,8 @@ def do_region_list(cc, args):
|
|||||||
'non-negative limit, got {0}'
|
'non-negative limit, got {0}'
|
||||||
.format(args.limit))
|
.format(args.limit))
|
||||||
params['limit'] = args.limit
|
params['limit'] = args.limit
|
||||||
|
if args.all is True:
|
||||||
|
params['limit'] = 100
|
||||||
|
|
||||||
if args.fields:
|
if args.fields:
|
||||||
try:
|
try:
|
||||||
@ -62,6 +74,8 @@ def do_region_list(cc, args):
|
|||||||
raise exc.CommandError('Invalid field "{}"'.format(err.args[0]))
|
raise exc.CommandError('Invalid field "{}"'.format(err.args[0]))
|
||||||
else:
|
else:
|
||||||
fields = default_fields
|
fields = default_fields
|
||||||
|
params['marker'] = args.marker
|
||||||
|
params['autopaginate'] = args.all
|
||||||
|
|
||||||
regions_list = cc.regions.list(**params)
|
regions_list = cc.regions.list(**params)
|
||||||
cliutils.print_list(regions_list, list(fields))
|
cliutils.print_list(regions_list, list(fields))
|
||||||
|
@ -62,6 +62,8 @@ class TestCellsShell(base.ShellTestCase):
|
|||||||
limit=0,
|
limit=0,
|
||||||
sort_dir='asc',
|
sort_dir='asc',
|
||||||
region_id=1,
|
region_id=1,
|
||||||
|
autopaginate=False,
|
||||||
|
marker=None,
|
||||||
)
|
)
|
||||||
|
|
||||||
@mock.patch('cratonclient.v1.cells.CellManager.list')
|
@mock.patch('cratonclient.v1.cells.CellManager.list')
|
||||||
@ -75,6 +77,8 @@ class TestCellsShell(base.ShellTestCase):
|
|||||||
limit=1,
|
limit=1,
|
||||||
sort_dir='asc',
|
sort_dir='asc',
|
||||||
region_id=1,
|
region_id=1,
|
||||||
|
autopaginate=False,
|
||||||
|
marker=None,
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_cell_list_limit_negative_num_failure(self):
|
def test_cell_list_limit_negative_num_failure(self):
|
||||||
@ -94,6 +98,8 @@ class TestCellsShell(base.ShellTestCase):
|
|||||||
detail=True,
|
detail=True,
|
||||||
region_id=1,
|
region_id=1,
|
||||||
sort_dir='asc',
|
sort_dir='asc',
|
||||||
|
autopaginate=False,
|
||||||
|
marker=None,
|
||||||
)
|
)
|
||||||
|
|
||||||
@mock.patch('cratonclient.v1.cells.CellManager.list')
|
@mock.patch('cratonclient.v1.cells.CellManager.list')
|
||||||
@ -104,6 +110,8 @@ class TestCellsShell(base.ShellTestCase):
|
|||||||
mock_list.assert_called_once_with(
|
mock_list.assert_called_once_with(
|
||||||
sort_dir='asc',
|
sort_dir='asc',
|
||||||
region_id=1,
|
region_id=1,
|
||||||
|
autopaginate=False,
|
||||||
|
marker=None,
|
||||||
)
|
)
|
||||||
mock_printlist.assert_called_once_with(mock.ANY,
|
mock_printlist.assert_called_once_with(mock.ANY,
|
||||||
list({'id': 'ID',
|
list({'id': 'ID',
|
||||||
@ -117,6 +125,8 @@ class TestCellsShell(base.ShellTestCase):
|
|||||||
sort_key='name',
|
sort_key='name',
|
||||||
sort_dir='asc',
|
sort_dir='asc',
|
||||||
region_id=1,
|
region_id=1,
|
||||||
|
autopaginate=False,
|
||||||
|
marker=None,
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_cell_list_sort_key_invalid(self):
|
def test_cell_list_sort_key_invalid(self):
|
||||||
@ -133,6 +143,8 @@ class TestCellsShell(base.ShellTestCase):
|
|||||||
sort_key='name',
|
sort_key='name',
|
||||||
sort_dir='asc',
|
sort_dir='asc',
|
||||||
region_id=1,
|
region_id=1,
|
||||||
|
autopaginate=False,
|
||||||
|
marker=None,
|
||||||
)
|
)
|
||||||
|
|
||||||
@mock.patch('cratonclient.v1.cells.CellManager.list')
|
@mock.patch('cratonclient.v1.cells.CellManager.list')
|
||||||
@ -143,6 +155,8 @@ class TestCellsShell(base.ShellTestCase):
|
|||||||
sort_key='name',
|
sort_key='name',
|
||||||
sort_dir='desc',
|
sort_dir='desc',
|
||||||
region_id=1,
|
region_id=1,
|
||||||
|
autopaginate=False,
|
||||||
|
marker=None,
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_cell_list_sort_dir_invalid_value(self):
|
def test_cell_list_sort_dir_invalid_value(self):
|
||||||
|
@ -134,10 +134,13 @@ class TestCrudIntegration(base.TestCase):
|
|||||||
"""Verify the request to list a resource."""
|
"""Verify the request to list a resource."""
|
||||||
self.session.request.return_value = self.create_response(
|
self.session.request.return_value = self.create_response(
|
||||||
status_code=200,
|
status_code=200,
|
||||||
json_return_value=[{'name': 'Test', 'id': 1234}],
|
json_return_value={
|
||||||
|
'test_keys': [{'name': 'Test', 'id': 1234}],
|
||||||
|
'links': [],
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
resources = self.client.list(filter_by='some-attribute')
|
resources = list(self.client.list(filter_by='some-attribute'))
|
||||||
|
|
||||||
self.session.request.assert_called_once_with(
|
self.session.request.assert_called_once_with(
|
||||||
method='GET',
|
method='GET',
|
||||||
|
@ -66,6 +66,8 @@ class TestHostsShell(base.ShellTestCase):
|
|||||||
limit=0,
|
limit=0,
|
||||||
sort_dir='asc',
|
sort_dir='asc',
|
||||||
region_id=1,
|
region_id=1,
|
||||||
|
marker=None,
|
||||||
|
autopaginate=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
@mock.patch('cratonclient.v1.hosts.HostManager.list')
|
@mock.patch('cratonclient.v1.hosts.HostManager.list')
|
||||||
@ -79,6 +81,8 @@ class TestHostsShell(base.ShellTestCase):
|
|||||||
limit=1,
|
limit=1,
|
||||||
sort_dir='asc',
|
sort_dir='asc',
|
||||||
region_id=1,
|
region_id=1,
|
||||||
|
marker=None,
|
||||||
|
autopaginate=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_host_list_limit_negative_num_failure(self):
|
def test_host_list_limit_negative_num_failure(self):
|
||||||
@ -99,6 +103,8 @@ class TestHostsShell(base.ShellTestCase):
|
|||||||
cell_id=1,
|
cell_id=1,
|
||||||
sort_dir='asc',
|
sort_dir='asc',
|
||||||
region_id=1,
|
region_id=1,
|
||||||
|
marker=None,
|
||||||
|
autopaginate=False,
|
||||||
)
|
)
|
||||||
mock_list.reset_mock()
|
mock_list.reset_mock()
|
||||||
|
|
||||||
@ -110,6 +116,8 @@ class TestHostsShell(base.ShellTestCase):
|
|||||||
detail=True,
|
detail=True,
|
||||||
sort_dir='asc',
|
sort_dir='asc',
|
||||||
region_id=1,
|
region_id=1,
|
||||||
|
marker=None,
|
||||||
|
autopaginate=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
@mock.patch('cratonclient.v1.hosts.HostManager.list')
|
@mock.patch('cratonclient.v1.hosts.HostManager.list')
|
||||||
@ -120,6 +128,8 @@ class TestHostsShell(base.ShellTestCase):
|
|||||||
mock_list.assert_called_once_with(
|
mock_list.assert_called_once_with(
|
||||||
sort_dir='asc',
|
sort_dir='asc',
|
||||||
region_id=1,
|
region_id=1,
|
||||||
|
marker=None,
|
||||||
|
autopaginate=False,
|
||||||
)
|
)
|
||||||
mock_printlist.assert_called_once_with(mock.ANY,
|
mock_printlist.assert_called_once_with(mock.ANY,
|
||||||
list({'id': 'ID',
|
list({'id': 'ID',
|
||||||
@ -133,6 +143,8 @@ class TestHostsShell(base.ShellTestCase):
|
|||||||
sort_key='cell_id',
|
sort_key='cell_id',
|
||||||
sort_dir='asc',
|
sort_dir='asc',
|
||||||
region_id=1,
|
region_id=1,
|
||||||
|
marker=None,
|
||||||
|
autopaginate=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_host_list_sort_key_invalid(self):
|
def test_host_list_sort_key_invalid(self):
|
||||||
@ -148,6 +160,8 @@ class TestHostsShell(base.ShellTestCase):
|
|||||||
mock_list.assert_called_once_with(
|
mock_list.assert_called_once_with(
|
||||||
sort_dir='desc',
|
sort_dir='desc',
|
||||||
region_id=1,
|
region_id=1,
|
||||||
|
marker=None,
|
||||||
|
autopaginate=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
@mock.patch('cratonclient.v1.hosts.HostManager.list')
|
@mock.patch('cratonclient.v1.hosts.HostManager.list')
|
||||||
@ -158,6 +172,8 @@ class TestHostsShell(base.ShellTestCase):
|
|||||||
sort_key='name',
|
sort_key='name',
|
||||||
sort_dir='asc',
|
sort_dir='asc',
|
||||||
region_id=1,
|
region_id=1,
|
||||||
|
marker=None,
|
||||||
|
autopaginate=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
@mock.patch('cratonclient.v1.hosts.HostManager.list')
|
@mock.patch('cratonclient.v1.hosts.HostManager.list')
|
||||||
@ -168,6 +184,8 @@ class TestHostsShell(base.ShellTestCase):
|
|||||||
sort_key='name',
|
sort_key='name',
|
||||||
sort_dir='desc',
|
sort_dir='desc',
|
||||||
region_id=1,
|
region_id=1,
|
||||||
|
marker=None,
|
||||||
|
autopaginate=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_host_list_sort_dir_invalid_value(self):
|
def test_host_list_sort_dir_invalid_value(self):
|
||||||
|
@ -55,7 +55,9 @@ class TestProjectsShell(base.ShellTestCase):
|
|||||||
"""Verify that --limit 0 prints out all project projects."""
|
"""Verify that --limit 0 prints out all project projects."""
|
||||||
self.shell('project-list --limit 0')
|
self.shell('project-list --limit 0')
|
||||||
mock_list.assert_called_once_with(
|
mock_list.assert_called_once_with(
|
||||||
limit=0
|
limit=0,
|
||||||
|
marker=None,
|
||||||
|
autopaginate=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
@mock.patch('cratonclient.v1.projects.ProjectManager.list')
|
@mock.patch('cratonclient.v1.projects.ProjectManager.list')
|
||||||
@ -66,7 +68,9 @@ class TestProjectsShell(base.ShellTestCase):
|
|||||||
"""
|
"""
|
||||||
self.shell('project-list --limit 1')
|
self.shell('project-list --limit 1')
|
||||||
mock_list.assert_called_once_with(
|
mock_list.assert_called_once_with(
|
||||||
limit=1
|
limit=1,
|
||||||
|
marker=None,
|
||||||
|
autopaginate=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_project_list_limit_negative_num_failure(self):
|
def test_project_list_limit_negative_num_failure(self):
|
||||||
@ -82,14 +86,20 @@ class TestProjectsShell(base.ShellTestCase):
|
|||||||
def test_project_list_detail_success(self, mock_list):
|
def test_project_list_detail_success(self, mock_list):
|
||||||
"""Verify --detail argument successfully pass detail to Client."""
|
"""Verify --detail argument successfully pass detail to Client."""
|
||||||
self.shell('project-list --detail')
|
self.shell('project-list --detail')
|
||||||
mock_list.assert_called_once_with()
|
mock_list.assert_called_once_with(
|
||||||
|
marker=None,
|
||||||
|
autopaginate=False,
|
||||||
|
)
|
||||||
|
|
||||||
@mock.patch('cratonclient.v1.projects.ProjectManager.list')
|
@mock.patch('cratonclient.v1.projects.ProjectManager.list')
|
||||||
@mock.patch('cratonclient.common.cliutils.print_list')
|
@mock.patch('cratonclient.common.cliutils.print_list')
|
||||||
def test_project_list_fields_success(self, mock_printlist, mock_list):
|
def test_project_list_fields_success(self, mock_printlist, mock_list):
|
||||||
"""Verify --fields argument successfully passed to Client."""
|
"""Verify --fields argument successfully passed to Client."""
|
||||||
self.shell('project-list --fields id name')
|
self.shell('project-list --fields id name')
|
||||||
mock_list.assert_called_once_with()
|
mock_list.assert_called_once_with(
|
||||||
|
marker=None,
|
||||||
|
autopaginate=False,
|
||||||
|
)
|
||||||
mock_printlist.assert_called_once_with(mock.ANY,
|
mock_printlist.assert_called_once_with(mock.ANY,
|
||||||
list({'id': 'ID',
|
list({'id': 'ID',
|
||||||
'name': 'Name'}))
|
'name': 'Name'}))
|
||||||
|
@ -55,6 +55,8 @@ class TestDoCellList(base.TestShellCommandUsingPrintList):
|
|||||||
kwargs.setdefault('sort_key', None)
|
kwargs.setdefault('sort_key', None)
|
||||||
kwargs.setdefault('sort_dir', 'asc')
|
kwargs.setdefault('sort_dir', 'asc')
|
||||||
kwargs.setdefault('fields', [])
|
kwargs.setdefault('fields', [])
|
||||||
|
kwargs.setdefault('marker', None)
|
||||||
|
kwargs.setdefault('all', False)
|
||||||
return super(TestDoCellList, self).args_for(**kwargs)
|
return super(TestDoCellList, self).args_for(**kwargs)
|
||||||
|
|
||||||
def test_with_defaults(self):
|
def test_with_defaults(self):
|
||||||
@ -66,6 +68,8 @@ class TestDoCellList(base.TestShellCommandUsingPrintList):
|
|||||||
self.craton_client.cells.list.assert_called_once_with(
|
self.craton_client.cells.list.assert_called_once_with(
|
||||||
sort_dir='asc',
|
sort_dir='asc',
|
||||||
region_id=123,
|
region_id=123,
|
||||||
|
autopaginate=False,
|
||||||
|
marker=None,
|
||||||
)
|
)
|
||||||
self.assertTrue(self.print_list.called)
|
self.assertTrue(self.print_list.called)
|
||||||
self.assertEqual(['id', 'name'],
|
self.assertEqual(['id', 'name'],
|
||||||
@ -88,6 +92,8 @@ class TestDoCellList(base.TestShellCommandUsingPrintList):
|
|||||||
limit=5,
|
limit=5,
|
||||||
sort_dir='asc',
|
sort_dir='asc',
|
||||||
region_id=123,
|
region_id=123,
|
||||||
|
autopaginate=False,
|
||||||
|
marker=None,
|
||||||
)
|
)
|
||||||
self.assertTrue(self.print_list.called)
|
self.assertTrue(self.print_list.called)
|
||||||
self.assertEqual(['id', 'name'],
|
self.assertEqual(['id', 'name'],
|
||||||
@ -103,6 +109,8 @@ class TestDoCellList(base.TestShellCommandUsingPrintList):
|
|||||||
sort_dir='asc',
|
sort_dir='asc',
|
||||||
sort_key='name',
|
sort_key='name',
|
||||||
region_id=123,
|
region_id=123,
|
||||||
|
autopaginate=False,
|
||||||
|
marker=None,
|
||||||
)
|
)
|
||||||
self.assertTrue(self.print_list.called)
|
self.assertTrue(self.print_list.called)
|
||||||
self.assertEqual(['id', 'name'],
|
self.assertEqual(['id', 'name'],
|
||||||
@ -125,6 +133,8 @@ class TestDoCellList(base.TestShellCommandUsingPrintList):
|
|||||||
sort_dir='asc',
|
sort_dir='asc',
|
||||||
detail=True,
|
detail=True,
|
||||||
region_id=123,
|
region_id=123,
|
||||||
|
autopaginate=False,
|
||||||
|
marker=None,
|
||||||
)
|
)
|
||||||
self.assertEqual(sorted(list(cells.CELL_FIELDS)),
|
self.assertEqual(sorted(list(cells.CELL_FIELDS)),
|
||||||
sorted(self.print_list.call_args[0][-1]))
|
sorted(self.print_list.call_args[0][-1]))
|
||||||
@ -148,6 +158,8 @@ class TestDoCellList(base.TestShellCommandUsingPrintList):
|
|||||||
self.craton_client.cells.list.assert_called_once_with(
|
self.craton_client.cells.list.assert_called_once_with(
|
||||||
sort_dir='asc',
|
sort_dir='asc',
|
||||||
region_id=123,
|
region_id=123,
|
||||||
|
autopaginate=False,
|
||||||
|
marker=None,
|
||||||
)
|
)
|
||||||
self.assertEqual(['id', 'name', 'note'],
|
self.assertEqual(['id', 'name', 'note'],
|
||||||
sorted(self.print_list.call_args[0][-1]))
|
sorted(self.print_list.call_args[0][-1]))
|
||||||
@ -159,6 +171,34 @@ class TestDoCellList(base.TestShellCommandUsingPrintList):
|
|||||||
self.assertRaisesCommandErrorWith(cells_shell.do_cell_list, args)
|
self.assertRaisesCommandErrorWith(cells_shell.do_cell_list, args)
|
||||||
self.assertNothingWasCalled()
|
self.assertNothingWasCalled()
|
||||||
|
|
||||||
|
def test_autopaginate(self):
|
||||||
|
"""Verify that autopagination works."""
|
||||||
|
args = self.args_for(all=True)
|
||||||
|
|
||||||
|
cells_shell.do_cell_list(self.craton_client, args)
|
||||||
|
|
||||||
|
self.craton_client.cells.list.assert_called_once_with(
|
||||||
|
sort_dir='asc',
|
||||||
|
region_id=123,
|
||||||
|
limit=100,
|
||||||
|
autopaginate=True,
|
||||||
|
marker=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_autopagination_overrides_limit(self):
|
||||||
|
"""Verify that --all overrides --limit."""
|
||||||
|
args = self.args_for(all=True, limit=10)
|
||||||
|
|
||||||
|
cells_shell.do_cell_list(self.craton_client, args)
|
||||||
|
|
||||||
|
self.craton_client.cells.list.assert_called_once_with(
|
||||||
|
sort_dir='asc',
|
||||||
|
region_id=123,
|
||||||
|
limit=100,
|
||||||
|
autopaginate=True,
|
||||||
|
marker=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class TestDoCellCreate(base.TestShellCommandUsingPrintDict):
|
class TestDoCellCreate(base.TestShellCommandUsingPrintDict):
|
||||||
"""Unit tests for the cell create command."""
|
"""Unit tests for the cell create command."""
|
||||||
|
@ -51,6 +51,8 @@ class TestDoHostList(base.TestShellCommandUsingPrintList):
|
|||||||
kwargs.setdefault('sort_key', None)
|
kwargs.setdefault('sort_key', None)
|
||||||
kwargs.setdefault('sort_dir', 'asc')
|
kwargs.setdefault('sort_dir', 'asc')
|
||||||
kwargs.setdefault('fields', [])
|
kwargs.setdefault('fields', [])
|
||||||
|
kwargs.setdefault('marker', None)
|
||||||
|
kwargs.setdefault('all', False)
|
||||||
return super(TestDoHostList, self).args_for(**kwargs)
|
return super(TestDoHostList, self).args_for(**kwargs)
|
||||||
|
|
||||||
def test_only_required_parameters(self):
|
def test_only_required_parameters(self):
|
||||||
@ -62,6 +64,8 @@ class TestDoHostList(base.TestShellCommandUsingPrintList):
|
|||||||
self.craton_client.hosts.list.assert_called_once_with(
|
self.craton_client.hosts.list.assert_called_once_with(
|
||||||
sort_dir='asc',
|
sort_dir='asc',
|
||||||
region_id=246,
|
region_id=246,
|
||||||
|
autopaginate=False,
|
||||||
|
marker=None,
|
||||||
)
|
)
|
||||||
self.assertSortedPrintListFieldsEqualTo([
|
self.assertSortedPrintListFieldsEqualTo([
|
||||||
'active', 'cell_id', 'device_type', 'id', 'name'
|
'active', 'cell_id', 'device_type', 'id', 'name'
|
||||||
@ -77,6 +81,8 @@ class TestDoHostList(base.TestShellCommandUsingPrintList):
|
|||||||
cell_id=789,
|
cell_id=789,
|
||||||
sort_dir='asc',
|
sort_dir='asc',
|
||||||
region_id=246,
|
region_id=246,
|
||||||
|
autopaginate=False,
|
||||||
|
marker=None,
|
||||||
)
|
)
|
||||||
self.assertSortedPrintListFieldsEqualTo([
|
self.assertSortedPrintListFieldsEqualTo([
|
||||||
'active', 'cell_id', 'device_type', 'id', 'name',
|
'active', 'cell_id', 'device_type', 'id', 'name',
|
||||||
@ -92,6 +98,8 @@ class TestDoHostList(base.TestShellCommandUsingPrintList):
|
|||||||
detail=True,
|
detail=True,
|
||||||
sort_dir='asc',
|
sort_dir='asc',
|
||||||
region_id=246,
|
region_id=246,
|
||||||
|
autopaginate=False,
|
||||||
|
marker=None,
|
||||||
)
|
)
|
||||||
self.assertSortedPrintListFieldsEqualTo([
|
self.assertSortedPrintListFieldsEqualTo([
|
||||||
'active',
|
'active',
|
||||||
@ -118,6 +126,8 @@ class TestDoHostList(base.TestShellCommandUsingPrintList):
|
|||||||
limit=20,
|
limit=20,
|
||||||
sort_dir='asc',
|
sort_dir='asc',
|
||||||
region_id=246,
|
region_id=246,
|
||||||
|
autopaginate=False,
|
||||||
|
marker=None,
|
||||||
)
|
)
|
||||||
self.assertSortedPrintListFieldsEqualTo([
|
self.assertSortedPrintListFieldsEqualTo([
|
||||||
'active', 'cell_id', 'device_type', 'id', 'name'
|
'active', 'cell_id', 'device_type', 'id', 'name'
|
||||||
@ -139,6 +149,8 @@ class TestDoHostList(base.TestShellCommandUsingPrintList):
|
|||||||
self.craton_client.hosts.list.assert_called_once_with(
|
self.craton_client.hosts.list.assert_called_once_with(
|
||||||
sort_dir='asc',
|
sort_dir='asc',
|
||||||
region_id=246,
|
region_id=246,
|
||||||
|
autopaginate=False,
|
||||||
|
marker=None,
|
||||||
)
|
)
|
||||||
self.assertSortedPrintListFieldsEqualTo([
|
self.assertSortedPrintListFieldsEqualTo([
|
||||||
'cell_id', 'id', 'name',
|
'cell_id', 'id', 'name',
|
||||||
@ -163,6 +175,8 @@ class TestDoHostList(base.TestShellCommandUsingPrintList):
|
|||||||
sort_key='ip_address',
|
sort_key='ip_address',
|
||||||
sort_dir='asc',
|
sort_dir='asc',
|
||||||
region_id=246,
|
region_id=246,
|
||||||
|
autopaginate=False,
|
||||||
|
marker=None,
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_fields_and_detail_raise_command_error(self):
|
def test_fields_and_detail_raise_command_error(self):
|
||||||
@ -183,6 +197,47 @@ class TestDoHostList(base.TestShellCommandUsingPrintList):
|
|||||||
)
|
)
|
||||||
self.assertNothingWasCalled()
|
self.assertNothingWasCalled()
|
||||||
|
|
||||||
|
def test_autopagination(self):
|
||||||
|
"""Verify autopagination is controlled by --all."""
|
||||||
|
args = self.args_for(all=True)
|
||||||
|
|
||||||
|
hosts_shell.do_host_list(self.craton_client, args)
|
||||||
|
|
||||||
|
self.craton_client.hosts.list.assert_called_once_with(
|
||||||
|
region_id=246,
|
||||||
|
sort_dir='asc',
|
||||||
|
limit=100,
|
||||||
|
marker=None,
|
||||||
|
autopaginate=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_autopagination_overrides_limit(self):
|
||||||
|
"""Verify --all overrides --limit."""
|
||||||
|
args = self.args_for(all=True, limit=30)
|
||||||
|
|
||||||
|
hosts_shell.do_host_list(self.craton_client, args)
|
||||||
|
|
||||||
|
self.craton_client.hosts.list.assert_called_once_with(
|
||||||
|
region_id=246,
|
||||||
|
sort_dir='asc',
|
||||||
|
limit=100,
|
||||||
|
marker=None,
|
||||||
|
autopaginate=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_marker_pass_through(self):
|
||||||
|
"""Verify we pass our marker through to the client."""
|
||||||
|
args = self.args_for(marker=42)
|
||||||
|
|
||||||
|
hosts_shell.do_host_list(self.craton_client, args)
|
||||||
|
|
||||||
|
self.craton_client.hosts.list.assert_called_once_with(
|
||||||
|
region_id=246,
|
||||||
|
sort_dir='asc',
|
||||||
|
marker=42,
|
||||||
|
autopaginate=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class TestDoHostCreate(base.TestShellCommandUsingPrintDict):
|
class TestDoHostCreate(base.TestShellCommandUsingPrintDict):
|
||||||
"""Tests for the do_host_create shell command."""
|
"""Tests for the do_host_create shell command."""
|
||||||
|
@ -55,6 +55,8 @@ class TestDoProjectList(base.TestShellCommandUsingPrintList):
|
|||||||
kwargs.setdefault('limit', None)
|
kwargs.setdefault('limit', None)
|
||||||
kwargs.setdefault('detail', False)
|
kwargs.setdefault('detail', False)
|
||||||
kwargs.setdefault('fields', [])
|
kwargs.setdefault('fields', [])
|
||||||
|
kwargs.setdefault('marker', None)
|
||||||
|
kwargs.setdefault('all', False)
|
||||||
return super(TestDoProjectList, self).args_for(**kwargs)
|
return super(TestDoProjectList, self).args_for(**kwargs)
|
||||||
|
|
||||||
def test_with_defaults(self):
|
def test_with_defaults(self):
|
||||||
@ -63,7 +65,10 @@ class TestDoProjectList(base.TestShellCommandUsingPrintList):
|
|||||||
|
|
||||||
projects_shell.do_project_list(self.craton_client, args)
|
projects_shell.do_project_list(self.craton_client, args)
|
||||||
|
|
||||||
self.craton_client.projects.list.assert_called_once_with()
|
self.craton_client.projects.list.assert_called_once_with(
|
||||||
|
marker=None,
|
||||||
|
autopaginate=False,
|
||||||
|
)
|
||||||
self.assertTrue(self.print_list.called)
|
self.assertTrue(self.print_list.called)
|
||||||
self.assertEqual(['id', 'name'],
|
self.assertEqual(['id', 'name'],
|
||||||
sorted(self.print_list.call_args[0][-1]))
|
sorted(self.print_list.call_args[0][-1]))
|
||||||
@ -84,6 +89,8 @@ class TestDoProjectList(base.TestShellCommandUsingPrintList):
|
|||||||
|
|
||||||
self.craton_client.projects.list.assert_called_once_with(
|
self.craton_client.projects.list.assert_called_once_with(
|
||||||
limit=5,
|
limit=5,
|
||||||
|
autopaginate=False,
|
||||||
|
marker=None,
|
||||||
)
|
)
|
||||||
self.assertTrue(self.print_list.called)
|
self.assertTrue(self.print_list.called)
|
||||||
self.assertEqual(['id', 'name'],
|
self.assertEqual(['id', 'name'],
|
||||||
@ -95,7 +102,10 @@ class TestDoProjectList(base.TestShellCommandUsingPrintList):
|
|||||||
|
|
||||||
projects_shell.do_project_list(self.craton_client, args)
|
projects_shell.do_project_list(self.craton_client, args)
|
||||||
|
|
||||||
self.craton_client.projects.list.assert_called_once_with()
|
self.craton_client.projects.list.assert_called_once_with(
|
||||||
|
marker=None,
|
||||||
|
autopaginate=False,
|
||||||
|
)
|
||||||
self.assertEqual(sorted(list(projects.PROJECT_FIELDS)),
|
self.assertEqual(sorted(list(projects.PROJECT_FIELDS)),
|
||||||
sorted(self.print_list.call_args[0][-1]))
|
sorted(self.print_list.call_args[0][-1]))
|
||||||
|
|
||||||
@ -106,7 +116,9 @@ class TestDoProjectList(base.TestShellCommandUsingPrintList):
|
|||||||
projects_shell.do_project_list(self.craton_client, args)
|
projects_shell.do_project_list(self.craton_client, args)
|
||||||
|
|
||||||
self.craton_client.projects.list.assert_called_once_with(
|
self.craton_client.projects.list.assert_called_once_with(
|
||||||
name='project_1'
|
name='project_1',
|
||||||
|
autopaginate=False,
|
||||||
|
marker=None,
|
||||||
)
|
)
|
||||||
self.assertEqual(['id', 'name'],
|
self.assertEqual(['id', 'name'],
|
||||||
sorted(self.print_list.call_args[0][-1]))
|
sorted(self.print_list.call_args[0][-1]))
|
||||||
@ -127,7 +139,10 @@ class TestDoProjectList(base.TestShellCommandUsingPrintList):
|
|||||||
|
|
||||||
projects_shell.do_project_list(self.craton_client, args)
|
projects_shell.do_project_list(self.craton_client, args)
|
||||||
|
|
||||||
self.craton_client.projects.list.assert_called_once_with()
|
self.craton_client.projects.list.assert_called_once_with(
|
||||||
|
autopaginate=False,
|
||||||
|
marker=None,
|
||||||
|
)
|
||||||
self.assertEqual(['id', 'name'],
|
self.assertEqual(['id', 'name'],
|
||||||
sorted(self.print_list.call_args[0][-1]))
|
sorted(self.print_list.call_args[0][-1]))
|
||||||
|
|
||||||
@ -138,6 +153,42 @@ class TestDoProjectList(base.TestShellCommandUsingPrintList):
|
|||||||
self.assertRaisesCommandErrorWith(projects_shell.do_project_list, args)
|
self.assertRaisesCommandErrorWith(projects_shell.do_project_list, args)
|
||||||
self.assertNothingWasCalled()
|
self.assertNothingWasCalled()
|
||||||
|
|
||||||
|
def test_autopagination(self):
|
||||||
|
"""Verify autopagination is controlled by --all."""
|
||||||
|
args = self.args_for(all=True)
|
||||||
|
|
||||||
|
projects_shell.do_project_list(self.craton_client, args)
|
||||||
|
|
||||||
|
self.craton_client.projects.list.assert_called_once_with(
|
||||||
|
limit=100,
|
||||||
|
autopaginate=True,
|
||||||
|
marker=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_autopagination_overrides_limit(self):
|
||||||
|
"""Verify --all overrides --limit."""
|
||||||
|
args = self.args_for(all=True, limit=25)
|
||||||
|
|
||||||
|
projects_shell.do_project_list(self.craton_client, args)
|
||||||
|
|
||||||
|
self.craton_client.projects.list.assert_called_once_with(
|
||||||
|
limit=100,
|
||||||
|
autopaginate=True,
|
||||||
|
marker=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_marker_support(self):
|
||||||
|
"""Verify we pass through the marker."""
|
||||||
|
project_id = uuid.uuid4().hex
|
||||||
|
args = self.args_for(marker=project_id)
|
||||||
|
|
||||||
|
projects_shell.do_project_list(self.craton_client, args)
|
||||||
|
|
||||||
|
self.craton_client.projects.list.assert_called_once_with(
|
||||||
|
autopaginate=False,
|
||||||
|
marker=project_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class TestDoProjectCreate(base.TestShellCommandUsingPrintDict):
|
class TestDoProjectCreate(base.TestShellCommandUsingPrintDict):
|
||||||
"""Unit tests for the project create command."""
|
"""Unit tests for the project create command."""
|
||||||
|
@ -210,6 +210,8 @@ class TestDoRegionList(base.TestShellCommandUsingPrintList):
|
|||||||
kwargs.setdefault('detail', False)
|
kwargs.setdefault('detail', False)
|
||||||
kwargs.setdefault('limit', None)
|
kwargs.setdefault('limit', None)
|
||||||
kwargs.setdefault('fields', [])
|
kwargs.setdefault('fields', [])
|
||||||
|
kwargs.setdefault('marker', None)
|
||||||
|
kwargs.setdefault('all', False)
|
||||||
return super(TestDoRegionList, self).args_for(**kwargs)
|
return super(TestDoRegionList, self).args_for(**kwargs)
|
||||||
|
|
||||||
def test_with_defaults(self):
|
def test_with_defaults(self):
|
||||||
@ -232,6 +234,8 @@ class TestDoRegionList(base.TestShellCommandUsingPrintList):
|
|||||||
regions_shell.do_region_list(self.craton_client, args)
|
regions_shell.do_region_list(self.craton_client, args)
|
||||||
self.craton_client.regions.list.assert_called_once_with(
|
self.craton_client.regions.list.assert_called_once_with(
|
||||||
limit=5,
|
limit=5,
|
||||||
|
marker=None,
|
||||||
|
autopaginate=False,
|
||||||
)
|
)
|
||||||
self.assertTrue(self.print_list.called)
|
self.assertTrue(self.print_list.called)
|
||||||
self.assertEqual(['id', 'name'],
|
self.assertEqual(['id', 'name'],
|
||||||
@ -249,3 +253,38 @@ class TestDoRegionList(base.TestShellCommandUsingPrintList):
|
|||||||
args = self.args_for(fields=['uuid', 'not-name', 'nate'])
|
args = self.args_for(fields=['uuid', 'not-name', 'nate'])
|
||||||
self.assertRaisesCommandErrorWith(regions_shell.do_region_list, args)
|
self.assertRaisesCommandErrorWith(regions_shell.do_region_list, args)
|
||||||
self.assertNothingWasCalled()
|
self.assertNothingWasCalled()
|
||||||
|
|
||||||
|
def test_autopagination(self):
|
||||||
|
"""Verify autopagination is controlled by --all."""
|
||||||
|
args = self.args_for(all=True)
|
||||||
|
|
||||||
|
regions_shell.do_region_list(self.craton_client, args)
|
||||||
|
|
||||||
|
self.craton_client.regions.list.assert_called_once_with(
|
||||||
|
limit=100,
|
||||||
|
marker=None,
|
||||||
|
autopaginate=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_autopagination_overrides_limit(self):
|
||||||
|
"""Verify --all overrides --limit."""
|
||||||
|
args = self.args_for(all=True, limit=35)
|
||||||
|
|
||||||
|
regions_shell.do_region_list(self.craton_client, args)
|
||||||
|
|
||||||
|
self.craton_client.regions.list.assert_called_once_with(
|
||||||
|
limit=100,
|
||||||
|
marker=None,
|
||||||
|
autopaginate=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_marker_pass_through(self):
|
||||||
|
"""Verify we pass our marker through to the client."""
|
||||||
|
args = self.args_for(marker=31)
|
||||||
|
|
||||||
|
regions_shell.do_region_list(self.craton_client, args)
|
||||||
|
|
||||||
|
self.craton_client.regions.list.assert_called_once_with(
|
||||||
|
marker=31,
|
||||||
|
autopaginate=False,
|
||||||
|
)
|
||||||
|
@ -172,13 +172,16 @@ class TestCRUDClient(base.TestCase):
|
|||||||
|
|
||||||
def test_list_generates_a_get_request(self):
|
def test_list_generates_a_get_request(self):
|
||||||
"""Verify that using our list method will GET from our service."""
|
"""Verify that using our list method will GET from our service."""
|
||||||
response = self.session.get.return_value = mock.Mock()
|
response = mock.Mock()
|
||||||
response.json.return_value = [{'name': 'fake-name', 'id': 1}]
|
items = [{'name': 'fake-name', 'id': 1}]
|
||||||
|
self.session.paginate.return_value = iter([(response, items)])
|
||||||
|
|
||||||
self.client.list(sort='asc')
|
next(self.client.list(sort='asc'))
|
||||||
|
|
||||||
self.session.get.assert_called_once_with(
|
self.session.paginate.assert_called_once_with(
|
||||||
'http://example.com/v1/test',
|
'http://example.com/v1/test',
|
||||||
|
autopaginate=True,
|
||||||
|
items_key='test_keys',
|
||||||
params={'sort': 'asc'},
|
params={'sort': 'asc'},
|
||||||
)
|
)
|
||||||
self.resource_spec.assert_called_once_with(
|
self.resource_spec.assert_called_once_with(
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
"""Session specific unit tests."""
|
"""Session specific unit tests."""
|
||||||
from keystoneauth1 import session as ksa_session
|
from keystoneauth1 import session as ksa_session
|
||||||
|
import mock
|
||||||
|
|
||||||
from cratonclient import auth
|
from cratonclient import auth
|
||||||
from cratonclient import session
|
from cratonclient import session
|
||||||
@ -64,6 +65,20 @@ class TestCratonAuth(base.TestCase):
|
|||||||
class TestSession(base.TestCase):
|
class TestSession(base.TestCase):
|
||||||
"""Unit tests for cratonclient's Session abstraction."""
|
"""Unit tests for cratonclient's Session abstraction."""
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def create_response(items, next_link):
|
||||||
|
"""Create a mock mimicing requests.Response."""
|
||||||
|
response = mock.Mock()
|
||||||
|
response.status_code = 200
|
||||||
|
response.json.return_value = {
|
||||||
|
'items': items,
|
||||||
|
'links': [{
|
||||||
|
'rel': 'next',
|
||||||
|
'href': next_link,
|
||||||
|
}],
|
||||||
|
}
|
||||||
|
return response
|
||||||
|
|
||||||
def test_creates_keystoneauth_session(self):
|
def test_creates_keystoneauth_session(self):
|
||||||
"""Verify we default to keystoneauth sessions and semantics."""
|
"""Verify we default to keystoneauth sessions and semantics."""
|
||||||
craton_session = session.Session(username=TEST_USERNAME_0,
|
craton_session = session.Session(username=TEST_USERNAME_0,
|
||||||
@ -78,3 +93,72 @@ class TestSession(base.TestCase):
|
|||||||
craton_session = session.Session(session=ksa_session_obj)
|
craton_session = session.Session(session=ksa_session_obj)
|
||||||
|
|
||||||
self.assertIs(ksa_session_obj, craton_session._session)
|
self.assertIs(ksa_session_obj, craton_session._session)
|
||||||
|
|
||||||
|
def test_paginate_stops_with_first_empty_list(self):
|
||||||
|
"""Verify the behaviour of Session#paginate."""
|
||||||
|
response = self.create_response(
|
||||||
|
[], 'http://example.com/v1/items?limit=30&marker=foo'
|
||||||
|
)
|
||||||
|
mock_session = mock.Mock()
|
||||||
|
mock_session.request.return_value = response
|
||||||
|
|
||||||
|
craton_session = session.Session(session=mock_session)
|
||||||
|
paginated_items = list(craton_session.paginate(
|
||||||
|
url='http://example.com/v1/items',
|
||||||
|
items_key='items',
|
||||||
|
autopaginate=True,
|
||||||
|
))
|
||||||
|
|
||||||
|
self.assertListEqual([(response, [])], paginated_items)
|
||||||
|
mock_session.request.assert_called_once_with(
|
||||||
|
method='GET',
|
||||||
|
url='http://example.com/v1/items',
|
||||||
|
endpoint_filter={'service_type': 'fleet_management'},
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_paginate_follows_until_an_empty_list(self):
|
||||||
|
"""Verify that Session#paginate follows links."""
|
||||||
|
responses = [
|
||||||
|
self.create_response(
|
||||||
|
[{'id': _id}],
|
||||||
|
'http://example.com/v1/items?limit=30&marker={}'.format(_id),
|
||||||
|
) for _id in ['foo', 'bar', 'bogus']
|
||||||
|
]
|
||||||
|
responses.append(self.create_response([], ''))
|
||||||
|
mock_session = mock.Mock()
|
||||||
|
mock_session.request.side_effect = responses
|
||||||
|
|
||||||
|
craton_session = session.Session(session=mock_session)
|
||||||
|
paginated_items = list(craton_session.paginate(
|
||||||
|
url='http://example.com/v1/items',
|
||||||
|
items_key='items',
|
||||||
|
autopaginate=True,
|
||||||
|
))
|
||||||
|
|
||||||
|
self.assertEqual(4, len(paginated_items))
|
||||||
|
|
||||||
|
self.assertListEqual(
|
||||||
|
mock_session.request.call_args_list,
|
||||||
|
[
|
||||||
|
mock.call(
|
||||||
|
method='GET',
|
||||||
|
url='http://example.com/v1/items',
|
||||||
|
endpoint_filter={'service_type': 'fleet_management'},
|
||||||
|
),
|
||||||
|
mock.call(
|
||||||
|
method='GET',
|
||||||
|
url='http://example.com/v1/items?limit=30&marker=foo',
|
||||||
|
endpoint_filter={'service_type': 'fleet_management'},
|
||||||
|
),
|
||||||
|
mock.call(
|
||||||
|
method='GET',
|
||||||
|
url='http://example.com/v1/items?limit=30&marker=bar',
|
||||||
|
endpoint_filter={'service_type': 'fleet_management'},
|
||||||
|
),
|
||||||
|
mock.call(
|
||||||
|
method='GET',
|
||||||
|
url='http://example.com/v1/items?limit=30&marker=bogus',
|
||||||
|
endpoint_filter={'service_type': 'fleet_management'},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user