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:
		@@ -103,14 +103,19 @@ class CRUDClient(object):
 | 
			
		||||
        return self.resource_class(self, response.json(), loaded=True)
 | 
			
		||||
 | 
			
		||||
    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)
 | 
			
		||||
        url = self.build_url(path_arguments=kwargs)
 | 
			
		||||
        response = self.session.get(url, params=kwargs)
 | 
			
		||||
        return [
 | 
			
		||||
            self.resource_class(self, item, loaded=True)
 | 
			
		||||
            for item in response.json()
 | 
			
		||||
        ]
 | 
			
		||||
        response_generator = self.session.paginate(
 | 
			
		||||
            url,
 | 
			
		||||
            autopaginate=autopaginate,
 | 
			
		||||
            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):
 | 
			
		||||
        """Update the item based on the keyword arguments provided."""
 | 
			
		||||
 
 | 
			
		||||
@@ -232,3 +232,49 @@ class Session(object):
 | 
			
		||||
            raise exc.error_from(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',
 | 
			
		||||
              default=False,
 | 
			
		||||
              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',
 | 
			
		||||
              metavar='<field>',
 | 
			
		||||
              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. '
 | 
			
		||||
                   'Only these fields will be fetched from the server. '
 | 
			
		||||
                   '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):
 | 
			
		||||
    """Print list of cells which are registered with the Craton service."""
 | 
			
		||||
    params = {}
 | 
			
		||||
@@ -68,6 +78,8 @@ def do_cell_list(cc, args):
 | 
			
		||||
                                   'non-negative limit, got {0}'
 | 
			
		||||
                                   .format(args.limit))
 | 
			
		||||
        params['limit'] = args.limit
 | 
			
		||||
    if args.all is True:
 | 
			
		||||
        params['limit'] = 100
 | 
			
		||||
 | 
			
		||||
    if args.fields and args.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_dir'] = args.sort_dir
 | 
			
		||||
    params['region_id'] = args.region
 | 
			
		||||
    params['marker'] = args.marker
 | 
			
		||||
    params['autopaginate'] = args.all
 | 
			
		||||
 | 
			
		||||
    listed_cells = cc.cells.list(**params)
 | 
			
		||||
    cliutils.print_list(listed_cells, list(fields))
 | 
			
		||||
 
 | 
			
		||||
@@ -44,10 +44,6 @@ def do_host_show(cc, args):
 | 
			
		||||
              action='store_true',
 | 
			
		||||
              default=False,
 | 
			
		||||
              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',
 | 
			
		||||
              metavar='<field>',
 | 
			
		||||
              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. '
 | 
			
		||||
                   'Only these fields will be fetched from the server. '
 | 
			
		||||
                   '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):
 | 
			
		||||
    """Print list of hosts which are registered with the Craton service."""
 | 
			
		||||
    params = {}
 | 
			
		||||
@@ -75,6 +85,8 @@ def do_host_list(cc, args):
 | 
			
		||||
                                   'non-negative limit, got {0}'
 | 
			
		||||
                                   .format(args.limit))
 | 
			
		||||
        params['limit'] = args.limit
 | 
			
		||||
    if args.all is True:
 | 
			
		||||
        params['limit'] = 100
 | 
			
		||||
 | 
			
		||||
    if args.fields and args.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_dir'] = args.sort_dir
 | 
			
		||||
    params['region_id'] = args.region
 | 
			
		||||
    params['marker'] = args.marker
 | 
			
		||||
    params['autopaginate'] = args.all
 | 
			
		||||
 | 
			
		||||
    host_list = cc.hosts.list(**params)
 | 
			
		||||
    cliutils.print_list(host_list, list(fields))
 | 
			
		||||
 
 | 
			
		||||
@@ -36,10 +36,6 @@ def do_project_show(cc, args):
 | 
			
		||||
              action='store_true',
 | 
			
		||||
              default=False,
 | 
			
		||||
              help='Show detailed information about the projects.')
 | 
			
		||||
@cliutils.arg('--limit',
 | 
			
		||||
              metavar='<limit>',
 | 
			
		||||
              type=int,
 | 
			
		||||
              help='Maximum number of projects to return.')
 | 
			
		||||
@cliutils.arg('--fields',
 | 
			
		||||
              nargs='+',
 | 
			
		||||
              metavar='<fields>',
 | 
			
		||||
@@ -47,6 +43,20 @@ def do_project_show(cc, args):
 | 
			
		||||
              help='Comma-separated list of fields to display. '
 | 
			
		||||
                   'Only these fields will be fetched from the server. '
 | 
			
		||||
                   '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):
 | 
			
		||||
    """Print list of projects which are registered with the Craton service."""
 | 
			
		||||
    params = {}
 | 
			
		||||
@@ -57,6 +67,8 @@ def do_project_list(cc, args):
 | 
			
		||||
                                   'non-negative limit, got {0}'
 | 
			
		||||
                                   .format(args.limit))
 | 
			
		||||
        params['limit'] = args.limit
 | 
			
		||||
    if args.all is True:
 | 
			
		||||
        params['limit'] = 100
 | 
			
		||||
 | 
			
		||||
    if args.fields and args.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]))
 | 
			
		||||
    else:
 | 
			
		||||
        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)
 | 
			
		||||
    cliutils.print_list(listed_projects, list(fields))
 | 
			
		||||
 
 | 
			
		||||
@@ -33,10 +33,6 @@ def do_region_create(cc, args):
 | 
			
		||||
    cliutils.print_dict(data, wrap=72)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@cliutils.arg('--limit',
 | 
			
		||||
              metavar='<limit>',
 | 
			
		||||
              type=int,
 | 
			
		||||
              help='Maximum number of regions to return.')
 | 
			
		||||
@cliutils.arg('--fields',
 | 
			
		||||
              nargs='+',
 | 
			
		||||
              metavar='<fields>',
 | 
			
		||||
@@ -44,6 +40,20 @@ def do_region_create(cc, args):
 | 
			
		||||
              help='Comma-separated list of fields to display. '
 | 
			
		||||
                   'Only these fields will be fetched from the server. '
 | 
			
		||||
                   '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):
 | 
			
		||||
    """List all regions."""
 | 
			
		||||
    params = {}
 | 
			
		||||
@@ -54,6 +64,8 @@ def do_region_list(cc, args):
 | 
			
		||||
                                   'non-negative limit, got {0}'
 | 
			
		||||
                                   .format(args.limit))
 | 
			
		||||
        params['limit'] = args.limit
 | 
			
		||||
    if args.all is True:
 | 
			
		||||
        params['limit'] = 100
 | 
			
		||||
 | 
			
		||||
    if args.fields:
 | 
			
		||||
        try:
 | 
			
		||||
@@ -62,6 +74,8 @@ def do_region_list(cc, args):
 | 
			
		||||
            raise exc.CommandError('Invalid field "{}"'.format(err.args[0]))
 | 
			
		||||
    else:
 | 
			
		||||
        fields = default_fields
 | 
			
		||||
    params['marker'] = args.marker
 | 
			
		||||
    params['autopaginate'] = args.all
 | 
			
		||||
 | 
			
		||||
    regions_list = cc.regions.list(**params)
 | 
			
		||||
    cliutils.print_list(regions_list, list(fields))
 | 
			
		||||
 
 | 
			
		||||
@@ -62,6 +62,8 @@ class TestCellsShell(base.ShellTestCase):
 | 
			
		||||
            limit=0,
 | 
			
		||||
            sort_dir='asc',
 | 
			
		||||
            region_id=1,
 | 
			
		||||
            autopaginate=False,
 | 
			
		||||
            marker=None,
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    @mock.patch('cratonclient.v1.cells.CellManager.list')
 | 
			
		||||
@@ -75,6 +77,8 @@ class TestCellsShell(base.ShellTestCase):
 | 
			
		||||
            limit=1,
 | 
			
		||||
            sort_dir='asc',
 | 
			
		||||
            region_id=1,
 | 
			
		||||
            autopaginate=False,
 | 
			
		||||
            marker=None,
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    def test_cell_list_limit_negative_num_failure(self):
 | 
			
		||||
@@ -94,6 +98,8 @@ class TestCellsShell(base.ShellTestCase):
 | 
			
		||||
            detail=True,
 | 
			
		||||
            region_id=1,
 | 
			
		||||
            sort_dir='asc',
 | 
			
		||||
            autopaginate=False,
 | 
			
		||||
            marker=None,
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    @mock.patch('cratonclient.v1.cells.CellManager.list')
 | 
			
		||||
@@ -104,6 +110,8 @@ class TestCellsShell(base.ShellTestCase):
 | 
			
		||||
        mock_list.assert_called_once_with(
 | 
			
		||||
            sort_dir='asc',
 | 
			
		||||
            region_id=1,
 | 
			
		||||
            autopaginate=False,
 | 
			
		||||
            marker=None,
 | 
			
		||||
        )
 | 
			
		||||
        mock_printlist.assert_called_once_with(mock.ANY,
 | 
			
		||||
                                               list({'id': 'ID',
 | 
			
		||||
@@ -117,6 +125,8 @@ class TestCellsShell(base.ShellTestCase):
 | 
			
		||||
            sort_key='name',
 | 
			
		||||
            sort_dir='asc',
 | 
			
		||||
            region_id=1,
 | 
			
		||||
            autopaginate=False,
 | 
			
		||||
            marker=None,
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    def test_cell_list_sort_key_invalid(self):
 | 
			
		||||
@@ -133,6 +143,8 @@ class TestCellsShell(base.ShellTestCase):
 | 
			
		||||
            sort_key='name',
 | 
			
		||||
            sort_dir='asc',
 | 
			
		||||
            region_id=1,
 | 
			
		||||
            autopaginate=False,
 | 
			
		||||
            marker=None,
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    @mock.patch('cratonclient.v1.cells.CellManager.list')
 | 
			
		||||
@@ -143,6 +155,8 @@ class TestCellsShell(base.ShellTestCase):
 | 
			
		||||
            sort_key='name',
 | 
			
		||||
            sort_dir='desc',
 | 
			
		||||
            region_id=1,
 | 
			
		||||
            autopaginate=False,
 | 
			
		||||
            marker=None,
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    def test_cell_list_sort_dir_invalid_value(self):
 | 
			
		||||
 
 | 
			
		||||
@@ -134,10 +134,13 @@ class TestCrudIntegration(base.TestCase):
 | 
			
		||||
        """Verify the request to list a resource."""
 | 
			
		||||
        self.session.request.return_value = self.create_response(
 | 
			
		||||
            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(
 | 
			
		||||
            method='GET',
 | 
			
		||||
 
 | 
			
		||||
@@ -66,6 +66,8 @@ class TestHostsShell(base.ShellTestCase):
 | 
			
		||||
            limit=0,
 | 
			
		||||
            sort_dir='asc',
 | 
			
		||||
            region_id=1,
 | 
			
		||||
            marker=None,
 | 
			
		||||
            autopaginate=False,
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    @mock.patch('cratonclient.v1.hosts.HostManager.list')
 | 
			
		||||
@@ -79,6 +81,8 @@ class TestHostsShell(base.ShellTestCase):
 | 
			
		||||
            limit=1,
 | 
			
		||||
            sort_dir='asc',
 | 
			
		||||
            region_id=1,
 | 
			
		||||
            marker=None,
 | 
			
		||||
            autopaginate=False,
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    def test_host_list_limit_negative_num_failure(self):
 | 
			
		||||
@@ -99,6 +103,8 @@ class TestHostsShell(base.ShellTestCase):
 | 
			
		||||
                cell_id=1,
 | 
			
		||||
                sort_dir='asc',
 | 
			
		||||
                region_id=1,
 | 
			
		||||
                marker=None,
 | 
			
		||||
                autopaginate=False,
 | 
			
		||||
            )
 | 
			
		||||
            mock_list.reset_mock()
 | 
			
		||||
 | 
			
		||||
@@ -110,6 +116,8 @@ class TestHostsShell(base.ShellTestCase):
 | 
			
		||||
            detail=True,
 | 
			
		||||
            sort_dir='asc',
 | 
			
		||||
            region_id=1,
 | 
			
		||||
            marker=None,
 | 
			
		||||
            autopaginate=False,
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    @mock.patch('cratonclient.v1.hosts.HostManager.list')
 | 
			
		||||
@@ -120,6 +128,8 @@ class TestHostsShell(base.ShellTestCase):
 | 
			
		||||
        mock_list.assert_called_once_with(
 | 
			
		||||
            sort_dir='asc',
 | 
			
		||||
            region_id=1,
 | 
			
		||||
            marker=None,
 | 
			
		||||
            autopaginate=False,
 | 
			
		||||
        )
 | 
			
		||||
        mock_printlist.assert_called_once_with(mock.ANY,
 | 
			
		||||
                                               list({'id': 'ID',
 | 
			
		||||
@@ -133,6 +143,8 @@ class TestHostsShell(base.ShellTestCase):
 | 
			
		||||
            sort_key='cell_id',
 | 
			
		||||
            sort_dir='asc',
 | 
			
		||||
            region_id=1,
 | 
			
		||||
            marker=None,
 | 
			
		||||
            autopaginate=False,
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    def test_host_list_sort_key_invalid(self):
 | 
			
		||||
@@ -148,6 +160,8 @@ class TestHostsShell(base.ShellTestCase):
 | 
			
		||||
        mock_list.assert_called_once_with(
 | 
			
		||||
            sort_dir='desc',
 | 
			
		||||
            region_id=1,
 | 
			
		||||
            marker=None,
 | 
			
		||||
            autopaginate=False,
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    @mock.patch('cratonclient.v1.hosts.HostManager.list')
 | 
			
		||||
@@ -158,6 +172,8 @@ class TestHostsShell(base.ShellTestCase):
 | 
			
		||||
            sort_key='name',
 | 
			
		||||
            sort_dir='asc',
 | 
			
		||||
            region_id=1,
 | 
			
		||||
            marker=None,
 | 
			
		||||
            autopaginate=False,
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    @mock.patch('cratonclient.v1.hosts.HostManager.list')
 | 
			
		||||
@@ -168,6 +184,8 @@ class TestHostsShell(base.ShellTestCase):
 | 
			
		||||
            sort_key='name',
 | 
			
		||||
            sort_dir='desc',
 | 
			
		||||
            region_id=1,
 | 
			
		||||
            marker=None,
 | 
			
		||||
            autopaginate=False,
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    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."""
 | 
			
		||||
        self.shell('project-list --limit 0')
 | 
			
		||||
        mock_list.assert_called_once_with(
 | 
			
		||||
            limit=0
 | 
			
		||||
            limit=0,
 | 
			
		||||
            marker=None,
 | 
			
		||||
            autopaginate=False,
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    @mock.patch('cratonclient.v1.projects.ProjectManager.list')
 | 
			
		||||
@@ -66,7 +68,9 @@ class TestProjectsShell(base.ShellTestCase):
 | 
			
		||||
        """
 | 
			
		||||
        self.shell('project-list --limit 1')
 | 
			
		||||
        mock_list.assert_called_once_with(
 | 
			
		||||
            limit=1
 | 
			
		||||
            limit=1,
 | 
			
		||||
            marker=None,
 | 
			
		||||
            autopaginate=False,
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    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):
 | 
			
		||||
        """Verify --detail argument successfully pass detail to Client."""
 | 
			
		||||
        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.common.cliutils.print_list')
 | 
			
		||||
    def test_project_list_fields_success(self, mock_printlist, mock_list):
 | 
			
		||||
        """Verify --fields argument successfully passed to Client."""
 | 
			
		||||
        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,
 | 
			
		||||
                                               list({'id': 'ID',
 | 
			
		||||
                                                     'name': 'Name'}))
 | 
			
		||||
 
 | 
			
		||||
@@ -55,6 +55,8 @@ class TestDoCellList(base.TestShellCommandUsingPrintList):
 | 
			
		||||
        kwargs.setdefault('sort_key', None)
 | 
			
		||||
        kwargs.setdefault('sort_dir', 'asc')
 | 
			
		||||
        kwargs.setdefault('fields', [])
 | 
			
		||||
        kwargs.setdefault('marker', None)
 | 
			
		||||
        kwargs.setdefault('all', False)
 | 
			
		||||
        return super(TestDoCellList, self).args_for(**kwargs)
 | 
			
		||||
 | 
			
		||||
    def test_with_defaults(self):
 | 
			
		||||
@@ -66,6 +68,8 @@ class TestDoCellList(base.TestShellCommandUsingPrintList):
 | 
			
		||||
        self.craton_client.cells.list.assert_called_once_with(
 | 
			
		||||
            sort_dir='asc',
 | 
			
		||||
            region_id=123,
 | 
			
		||||
            autopaginate=False,
 | 
			
		||||
            marker=None,
 | 
			
		||||
        )
 | 
			
		||||
        self.assertTrue(self.print_list.called)
 | 
			
		||||
        self.assertEqual(['id', 'name'],
 | 
			
		||||
@@ -88,6 +92,8 @@ class TestDoCellList(base.TestShellCommandUsingPrintList):
 | 
			
		||||
            limit=5,
 | 
			
		||||
            sort_dir='asc',
 | 
			
		||||
            region_id=123,
 | 
			
		||||
            autopaginate=False,
 | 
			
		||||
            marker=None,
 | 
			
		||||
        )
 | 
			
		||||
        self.assertTrue(self.print_list.called)
 | 
			
		||||
        self.assertEqual(['id', 'name'],
 | 
			
		||||
@@ -103,6 +109,8 @@ class TestDoCellList(base.TestShellCommandUsingPrintList):
 | 
			
		||||
            sort_dir='asc',
 | 
			
		||||
            sort_key='name',
 | 
			
		||||
            region_id=123,
 | 
			
		||||
            autopaginate=False,
 | 
			
		||||
            marker=None,
 | 
			
		||||
        )
 | 
			
		||||
        self.assertTrue(self.print_list.called)
 | 
			
		||||
        self.assertEqual(['id', 'name'],
 | 
			
		||||
@@ -125,6 +133,8 @@ class TestDoCellList(base.TestShellCommandUsingPrintList):
 | 
			
		||||
            sort_dir='asc',
 | 
			
		||||
            detail=True,
 | 
			
		||||
            region_id=123,
 | 
			
		||||
            autopaginate=False,
 | 
			
		||||
            marker=None,
 | 
			
		||||
        )
 | 
			
		||||
        self.assertEqual(sorted(list(cells.CELL_FIELDS)),
 | 
			
		||||
                         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(
 | 
			
		||||
            sort_dir='asc',
 | 
			
		||||
            region_id=123,
 | 
			
		||||
            autopaginate=False,
 | 
			
		||||
            marker=None,
 | 
			
		||||
        )
 | 
			
		||||
        self.assertEqual(['id', 'name', 'note'],
 | 
			
		||||
                         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.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):
 | 
			
		||||
    """Unit tests for the cell create command."""
 | 
			
		||||
 
 | 
			
		||||
@@ -51,6 +51,8 @@ class TestDoHostList(base.TestShellCommandUsingPrintList):
 | 
			
		||||
        kwargs.setdefault('sort_key', None)
 | 
			
		||||
        kwargs.setdefault('sort_dir', 'asc')
 | 
			
		||||
        kwargs.setdefault('fields', [])
 | 
			
		||||
        kwargs.setdefault('marker', None)
 | 
			
		||||
        kwargs.setdefault('all', False)
 | 
			
		||||
        return super(TestDoHostList, self).args_for(**kwargs)
 | 
			
		||||
 | 
			
		||||
    def test_only_required_parameters(self):
 | 
			
		||||
@@ -62,6 +64,8 @@ class TestDoHostList(base.TestShellCommandUsingPrintList):
 | 
			
		||||
        self.craton_client.hosts.list.assert_called_once_with(
 | 
			
		||||
            sort_dir='asc',
 | 
			
		||||
            region_id=246,
 | 
			
		||||
            autopaginate=False,
 | 
			
		||||
            marker=None,
 | 
			
		||||
        )
 | 
			
		||||
        self.assertSortedPrintListFieldsEqualTo([
 | 
			
		||||
            'active', 'cell_id', 'device_type', 'id', 'name'
 | 
			
		||||
@@ -77,6 +81,8 @@ class TestDoHostList(base.TestShellCommandUsingPrintList):
 | 
			
		||||
            cell_id=789,
 | 
			
		||||
            sort_dir='asc',
 | 
			
		||||
            region_id=246,
 | 
			
		||||
            autopaginate=False,
 | 
			
		||||
            marker=None,
 | 
			
		||||
        )
 | 
			
		||||
        self.assertSortedPrintListFieldsEqualTo([
 | 
			
		||||
            'active', 'cell_id', 'device_type', 'id', 'name',
 | 
			
		||||
@@ -92,6 +98,8 @@ class TestDoHostList(base.TestShellCommandUsingPrintList):
 | 
			
		||||
            detail=True,
 | 
			
		||||
            sort_dir='asc',
 | 
			
		||||
            region_id=246,
 | 
			
		||||
            autopaginate=False,
 | 
			
		||||
            marker=None,
 | 
			
		||||
        )
 | 
			
		||||
        self.assertSortedPrintListFieldsEqualTo([
 | 
			
		||||
            'active',
 | 
			
		||||
@@ -118,6 +126,8 @@ class TestDoHostList(base.TestShellCommandUsingPrintList):
 | 
			
		||||
            limit=20,
 | 
			
		||||
            sort_dir='asc',
 | 
			
		||||
            region_id=246,
 | 
			
		||||
            autopaginate=False,
 | 
			
		||||
            marker=None,
 | 
			
		||||
        )
 | 
			
		||||
        self.assertSortedPrintListFieldsEqualTo([
 | 
			
		||||
            'active', 'cell_id', 'device_type', 'id', 'name'
 | 
			
		||||
@@ -139,6 +149,8 @@ class TestDoHostList(base.TestShellCommandUsingPrintList):
 | 
			
		||||
        self.craton_client.hosts.list.assert_called_once_with(
 | 
			
		||||
            sort_dir='asc',
 | 
			
		||||
            region_id=246,
 | 
			
		||||
            autopaginate=False,
 | 
			
		||||
            marker=None,
 | 
			
		||||
        )
 | 
			
		||||
        self.assertSortedPrintListFieldsEqualTo([
 | 
			
		||||
            'cell_id', 'id', 'name',
 | 
			
		||||
@@ -163,6 +175,8 @@ class TestDoHostList(base.TestShellCommandUsingPrintList):
 | 
			
		||||
            sort_key='ip_address',
 | 
			
		||||
            sort_dir='asc',
 | 
			
		||||
            region_id=246,
 | 
			
		||||
            autopaginate=False,
 | 
			
		||||
            marker=None,
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    def test_fields_and_detail_raise_command_error(self):
 | 
			
		||||
@@ -183,6 +197,47 @@ class TestDoHostList(base.TestShellCommandUsingPrintList):
 | 
			
		||||
        )
 | 
			
		||||
        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):
 | 
			
		||||
    """Tests for the do_host_create shell command."""
 | 
			
		||||
 
 | 
			
		||||
@@ -55,6 +55,8 @@ class TestDoProjectList(base.TestShellCommandUsingPrintList):
 | 
			
		||||
        kwargs.setdefault('limit', None)
 | 
			
		||||
        kwargs.setdefault('detail', False)
 | 
			
		||||
        kwargs.setdefault('fields', [])
 | 
			
		||||
        kwargs.setdefault('marker', None)
 | 
			
		||||
        kwargs.setdefault('all', False)
 | 
			
		||||
        return super(TestDoProjectList, self).args_for(**kwargs)
 | 
			
		||||
 | 
			
		||||
    def test_with_defaults(self):
 | 
			
		||||
@@ -63,7 +65,10 @@ class TestDoProjectList(base.TestShellCommandUsingPrintList):
 | 
			
		||||
 | 
			
		||||
        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.assertEqual(['id', 'name'],
 | 
			
		||||
                         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(
 | 
			
		||||
            limit=5,
 | 
			
		||||
            autopaginate=False,
 | 
			
		||||
            marker=None,
 | 
			
		||||
        )
 | 
			
		||||
        self.assertTrue(self.print_list.called)
 | 
			
		||||
        self.assertEqual(['id', 'name'],
 | 
			
		||||
@@ -95,7 +102,10 @@ class TestDoProjectList(base.TestShellCommandUsingPrintList):
 | 
			
		||||
 | 
			
		||||
        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)),
 | 
			
		||||
                         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)
 | 
			
		||||
 | 
			
		||||
        self.craton_client.projects.list.assert_called_once_with(
 | 
			
		||||
            name='project_1'
 | 
			
		||||
            name='project_1',
 | 
			
		||||
            autopaginate=False,
 | 
			
		||||
            marker=None,
 | 
			
		||||
        )
 | 
			
		||||
        self.assertEqual(['id', 'name'],
 | 
			
		||||
                         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)
 | 
			
		||||
 | 
			
		||||
        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'],
 | 
			
		||||
                         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.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):
 | 
			
		||||
    """Unit tests for the project create command."""
 | 
			
		||||
 
 | 
			
		||||
@@ -210,6 +210,8 @@ class TestDoRegionList(base.TestShellCommandUsingPrintList):
 | 
			
		||||
        kwargs.setdefault('detail', False)
 | 
			
		||||
        kwargs.setdefault('limit', None)
 | 
			
		||||
        kwargs.setdefault('fields', [])
 | 
			
		||||
        kwargs.setdefault('marker', None)
 | 
			
		||||
        kwargs.setdefault('all', False)
 | 
			
		||||
        return super(TestDoRegionList, self).args_for(**kwargs)
 | 
			
		||||
 | 
			
		||||
    def test_with_defaults(self):
 | 
			
		||||
@@ -232,6 +234,8 @@ class TestDoRegionList(base.TestShellCommandUsingPrintList):
 | 
			
		||||
        regions_shell.do_region_list(self.craton_client, args)
 | 
			
		||||
        self.craton_client.regions.list.assert_called_once_with(
 | 
			
		||||
            limit=5,
 | 
			
		||||
            marker=None,
 | 
			
		||||
            autopaginate=False,
 | 
			
		||||
        )
 | 
			
		||||
        self.assertTrue(self.print_list.called)
 | 
			
		||||
        self.assertEqual(['id', 'name'],
 | 
			
		||||
@@ -249,3 +253,38 @@ class TestDoRegionList(base.TestShellCommandUsingPrintList):
 | 
			
		||||
        args = self.args_for(fields=['uuid', 'not-name', 'nate'])
 | 
			
		||||
        self.assertRaisesCommandErrorWith(regions_shell.do_region_list, args)
 | 
			
		||||
        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):
 | 
			
		||||
        """Verify that using our list method will GET from our service."""
 | 
			
		||||
        response = self.session.get.return_value = mock.Mock()
 | 
			
		||||
        response.json.return_value = [{'name': 'fake-name', 'id': 1}]
 | 
			
		||||
        response = mock.Mock()
 | 
			
		||||
        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',
 | 
			
		||||
            autopaginate=True,
 | 
			
		||||
            items_key='test_keys',
 | 
			
		||||
            params={'sort': 'asc'},
 | 
			
		||||
        )
 | 
			
		||||
        self.resource_spec.assert_called_once_with(
 | 
			
		||||
 
 | 
			
		||||
@@ -13,6 +13,7 @@
 | 
			
		||||
# under the License.
 | 
			
		||||
"""Session specific unit tests."""
 | 
			
		||||
from keystoneauth1 import session as ksa_session
 | 
			
		||||
import mock
 | 
			
		||||
 | 
			
		||||
from cratonclient import auth
 | 
			
		||||
from cratonclient import session
 | 
			
		||||
@@ -64,6 +65,20 @@ class TestCratonAuth(base.TestCase):
 | 
			
		||||
class TestSession(base.TestCase):
 | 
			
		||||
    """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):
 | 
			
		||||
        """Verify we default to keystoneauth sessions and semantics."""
 | 
			
		||||
        craton_session = session.Session(username=TEST_USERNAME_0,
 | 
			
		||||
@@ -78,3 +93,72 @@ class TestSession(base.TestCase):
 | 
			
		||||
        craton_session = session.Session(session=ksa_session_obj)
 | 
			
		||||
 | 
			
		||||
        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'},
 | 
			
		||||
                ),
 | 
			
		||||
            ],
 | 
			
		||||
        )
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user