'Check list pagination functionality for a resource.
This method requests the list of resources and follows pagination
links.
If an iterable is supplied in ids it will check that all ids are
retrieved and that only those are listed, that we will get a next
link for an empty page if the number of items is divisible by used
limit (this is expected behavior).
We can specify number of items per request using limit argument.'

def _test_pagination(self, resource, ids=None, limit=1, **kwargs):

    client = getattr(self, (resource + '_client'))
    method = getattr(client, ('list_' + resource))
    params = kwargs.pop('params', {})
    params['limit'] = limit
    if (ids is not None):
        remaining = list(ids)
    else:
        remaining = None
    next = None
    while True:
        response = method(params=params, **kwargs)
        if (remaining is not None):
            num_expected = min(len(remaining), limit)
            self.assertEqual(num_expected, len(response[resource]), ('Requested    %(#expect)d    but    got    %(#received)d    ' % {'#expect': num_expected, '#received': len(response[resource])}))
            for element in response[resource]:
                element_id = element['id']
                self.assertIn(element_id, ids, ('Id    %(id)s    is    not    in    expected    ids    %(ids)s' % {'id': element_id, 'ids': ids}))
                self.assertIn(element_id, remaining, ('Id    %s    was    received    twice' % element_id))
                remaining.remove(element_id)
        if next:
            self.assertEqual(next, response.response['content-location'])
        next = None
        for link in response.get((resource + '_links'), ()):
            if (link['rel'] == 'next'):
                next = link['href']
                break
        if (remaining is not None):
            if (remaining or (num_expected and ((len(ids) % limit) == 0))):
                self.assertIsNotNone(next, 'Missing    link    to    next    page')
            else:
                self.assertIsNone(next, 'Unexpected    link    to    next    page')
        if next:
            params = parse.urlparse(next).query
        else:
            self.assertEmpty((remaining or []), ('No    more    pages    reported,    but    still    missing    ids    %s' % remaining))
            break
