Merge "Update queries to use proper offset and limit"

This commit is contained in:
Jenkins 2015-06-27 00:34:31 +00:00 committed by Gerrit Code Review
commit 1b18effda0
11 changed files with 171 additions and 52 deletions

View File

@ -135,6 +135,7 @@ class ContainersController(controllers.ACLMixin):
project_id,
offset_arg=kw.get('offset', 0),
limit_arg=kw.get('limit', None),
name_arg=kw.get('name', None),
suppress_exception=True
)

View File

@ -158,7 +158,8 @@ class OrdersController(controllers.ACLMixin):
result = self.order_repo.get_by_create_date(
external_project_id, offset_arg=kw.get('offset', 0),
limit_arg=kw.get('limit', None), suppress_exception=True)
limit_arg=kw.get('limit', None), meta_arg=kw.get('meta', None),
suppress_exception=True)
orders, offset, limit, total = result
if not orders:

View File

@ -831,8 +831,8 @@ class OrderRepo(BaseRepo):
"""Repository for the Order entity."""
def get_by_create_date(self, external_project_id, offset_arg=None,
limit_arg=None, suppress_exception=False,
session=None):
limit_arg=None, meta_arg=None,
suppress_exception=False, session=None):
"""Returns a list of orders
The list is ordered by the date they were created at and paged
@ -842,6 +842,7 @@ class OrderRepo(BaseRepo):
:param offset_arg: The entity number where the query result should
start.
:param limit_arg: The maximum amount of entities in the result set.
:param meta_arg: Optional meta field used to filter results.
:param suppress_exception: Whether NoResultFound exceptions should be
suppressed.
:param session: SQLAlchemy session object.
@ -856,6 +857,10 @@ class OrderRepo(BaseRepo):
query = session.query(models.Order)
query = query.order_by(models.Order.created_at)
query = query.filter_by(deleted=False)
if meta_arg:
query = query.filter(models.Order.meta.contains(meta_arg))
query = query.join(models.Project, models.Order.project)
query = query.filter(models.Project.external_id == external_project_id)
@ -863,7 +868,7 @@ class OrderRepo(BaseRepo):
end = offset + limit
LOG.debug('Retrieving from %s to %s', start, end)
total = query.count()
entities = query[start:end]
entities = query.offset(start).limit(limit).all()
LOG.debug('Number entities retrieved: %s out of %s',
len(entities), total
)
@ -1045,7 +1050,7 @@ class OrderRetryTaskRepo(BaseRepo):
end = offset + limit
LOG.debug('Retrieving from %s to %s', start, end)
total = query.count()
entities = query[start:end]
entities = query.offset(start).limit(limit).all()
LOG.debug('Number entities retrieved: %s out of %s',
len(entities), total
)
@ -1074,8 +1079,8 @@ class ContainerRepo(BaseRepo):
"""Repository for the Container entity."""
def get_by_create_date(self, external_project_id, offset_arg=None,
limit_arg=None, suppress_exception=False,
session=None):
limit_arg=None, name_arg=None,
suppress_exception=False, session=None):
"""Returns a list of containers
The list is ordered by the date they were created at and paged
@ -1090,6 +1095,10 @@ class ContainerRepo(BaseRepo):
query = session.query(models.Container)
query = query.order_by(models.Container.created_at)
query = query.filter_by(deleted=False)
if name_arg:
query = query.filter(models.Container.name.like(name_arg))
query = query.join(models.Project, models.Container.project)
query = query.filter(models.Project.external_id == external_project_id)
@ -1097,7 +1106,7 @@ class ContainerRepo(BaseRepo):
end = offset + limit
LOG.debug('Retrieving from %s to %s', start, end)
total = query.count()
entities = query[start:end]
entities = query.offset(start).limit(limit).all()
LOG.debug('Number entities retrieved: %s out of %s',
len(entities), total
)
@ -1195,7 +1204,7 @@ class ContainerConsumerRepo(BaseRepo):
end = offset + limit
LOG.debug('Retrieving from %s to %s', start, end)
total = query.count()
entities = query[start:end]
entities = query.offset(start).limit(limit).all()
LOG.debug('Number entities retrieved: %s out of %s',
len(entities), total
)
@ -1299,7 +1308,7 @@ class TransportKeyRepo(BaseRepo):
end = offset + limit
LOG.debug('Retrieving from %s to %s', start, end)
total = query.count()
entities = query[start:end]
entities = query.offset(start).limit(limit).all()
LOG.debug('Number of entities retrieved: %s out of %s',
len(entities), total)
@ -1365,7 +1374,7 @@ class CertificateAuthorityRepo(BaseRepo):
end = offset + limit
LOG.debug('Retrieving from %s to %s', start, end)
total = query.count()
entities = query[start:end]
entities = query.offset(start).limit(limit).all()
LOG.debug('Number entities retrieved: %s out of %s',
len(entities), total
)
@ -1519,7 +1528,7 @@ class ProjectCertificateAuthorityRepo(BaseRepo):
end = offset + limit
LOG.debug('Retrieving from %s to %s', start, end)
total = query.count()
entities = query[start:end]
entities = query.offset(start).limit(limit).all()
LOG.debug('Number entities retrieved: %s out of %s',
len(entities), total
)
@ -1586,7 +1595,7 @@ class PreferredCertificateAuthorityRepo(BaseRepo):
end = offset + limit
LOG.debug('Retrieving from %s to %s', start, end)
total = query.count()
entities = query[start:end]
entities = query.offset(start).limit(limit).all()
LOG.debug('Number entities retrieved: %s out of %s',
len(entities), total
)

View File

@ -71,6 +71,11 @@ class PagingTestCase(TestCase):
def tearDown(self):
super(PagingTestCase, self).tearDown()
def _set_filter_field(self, model):
filter = str(uuid.uuid4())
self.set_filter_field(filter, model)
return filter
def _validate_resource_group(self, resources=[], next_ref=None,
prev_ref=None,
expected_size=0,
@ -121,7 +126,11 @@ class PagingTestCase(TestCase):
pass
@abc.abstractmethod
def get_resources(self, limit=10, offset=0, name_filter=""):
def get_resources(self, limit=10, offset=0, filter=""):
pass
@abc.abstractmethod
def set_filter_field(self, filter, model):
pass
@testcase.attr('positive')
@ -132,9 +141,9 @@ class PagingTestCase(TestCase):
number_of_resource_groups = 5
resources_per_group = 10
filter = self._set_filter_field(test_model)
# create a number of resources
resource_name = str(uuid.uuid4())
test_model.name = resource_name
self.create_resources(
count=number_of_resource_groups * resources_per_group,
model=test_model)
@ -144,7 +153,7 @@ class PagingTestCase(TestCase):
resp, resources, next_ref, prev_ref = self.get_resources(
limit=resources_per_group,
offset=(i - 1) * resources_per_group,
name_filter=resource_name)
filter=filter)
self.assertEqual(200, resp.status_code)
@ -167,8 +176,7 @@ class PagingTestCase(TestCase):
res_count = 25
test_model = self.create_model()
resource_name = str(uuid.uuid4())
test_model.name = resource_name
filter = self._set_filter_field(test_model)
self.create_resources(count=res_count, model=test_model)
minimum_limit = 1
@ -177,7 +185,7 @@ class PagingTestCase(TestCase):
for limit in range(minimum_limit, maximum_limit):
resp, resources, next_ref, prev_ref = self.get_resources(
limit=limit, offset=offset, name_filter=resource_name)
limit=limit, offset=offset, filter=filter)
self.assertEqual(200, resp.status_code)
@ -202,12 +210,11 @@ class PagingTestCase(TestCase):
number_of_resources = max_allowable_limit + 10
test_model = self.create_model()
resource_name = str(uuid.uuid4())
test_model.name = resource_name
filter = self._set_filter_field(test_model)
self.create_resources(count=number_of_resources, model=test_model)
resp, resources, next_ref, prev_ref = self.get_resources(
limit=number_of_resources, offset=0, name_filter=resource_name)
limit=number_of_resources, offset=0, filter=filter)
self.assertEqual(200, resp.status_code)
self._validate_resource_group(resources=resources, next_ref=next_ref,
@ -223,7 +230,7 @@ class PagingTestCase(TestCase):
# now get the rest
resp, resources, next_ref, prev_ref = self.get_resources(
limit=limit, offset=offset, name_filter=resource_name)
limit=limit, offset=offset, filter=filter)
self.assertEqual(200, resp.status_code)
expected_size = number_of_resources - max_allowable_limit
@ -240,8 +247,7 @@ class PagingTestCase(TestCase):
number_of_resources = 150
test_model = self.create_model()
resource_name = str(uuid.uuid4())
test_model.name = resource_name
filter = self._set_filter_field(test_model)
self.create_resources(count=number_of_resources, model=test_model)
# First set of resources
@ -249,7 +255,7 @@ class PagingTestCase(TestCase):
offset = number_of_resources // 2
resp, resources, next_ref, prev_ref = self.get_resources(
limit=limit, offset=offset, name_filter=resource_name)
limit=limit, offset=offset, filter=filter)
self.assertEqual(200, resp.status_code)
self._validate_resource_group(resources=resources, next_ref=next_ref,
@ -262,7 +268,7 @@ class PagingTestCase(TestCase):
# Next set of resources
resp, resources, next_ref, prev_ref = self.get_resources(
limit=limit, offset=offset, name_filter=resource_name)
limit=limit, offset=offset, filter=filter)
self._validate_resource_group(resources=resources, next_ref=next_ref,
prev_ref=prev_ref,
@ -281,8 +287,7 @@ class PagingTestCase(TestCase):
number_of_resources = 15
test_model = self.create_model()
resource_name = str(uuid.uuid4())
test_model.name = resource_name
filter = self._set_filter_field(test_model)
self.create_resources(count=number_of_resources, model=test_model)
minimum_offset = 0
@ -291,7 +296,7 @@ class PagingTestCase(TestCase):
for offset in range(minimum_offset, maximum_offset):
resp, resources, next_ref, prev_ref = self.get_resources(
limit=limit, offset=offset, name_filter=resource_name)
limit=limit, offset=offset, filter=filter)
self.assertEqual(200, resp.status_code)
check_next = offset + limit >= number_of_resources
@ -312,15 +317,14 @@ class PagingTestCase(TestCase):
number_of_resources = 150
test_model = self.create_model()
resource_name = str(uuid.uuid4())
test_model.name = resource_name
filter = self._set_filter_field(test_model)
self.create_resources(count=number_of_resources, model=test_model)
# First set of resources
limit = number_of_resources // 10
offset = number_of_resources // 2
resp, resources, next_ref, prev_ref = self.get_resources(
limit=limit, offset=offset, name_filter=resource_name)
limit=limit, offset=offset, filter=filter)
self.assertEqual(200, resp.status_code)
self._validate_resource_group(resources=resources, next_ref=next_ref,
@ -333,7 +337,7 @@ class PagingTestCase(TestCase):
# Previous set of resources
resp, resources, next_ref, prev_ref = self.get_resources(
limit=limit, offset=offset, name_filter=resource_name)
limit=limit, offset=offset, filter=filter)
self._validate_resource_group(resources=resources, next_ref=next_ref,
prev_ref=prev_ref,
@ -349,14 +353,13 @@ class PagingTestCase(TestCase):
number_of_resources = 25
# create a number of resources
resource_name = str(uuid.uuid4())
test_model.name = resource_name
filter = self._set_filter_field(test_model)
self.create_resources(count=number_of_resources, model=test_model)
# pass in non-integer values for limit and offset
resp, resources, next_ref, prev_ref = self.get_resources(
limit='not-an-int-limit',
offset='not-an-int-offset', name_filter=resource_name)
offset='not-an-int-offset', filter=filter)
self.assertEqual(200, resp.status_code)
self._validate_resource_group(resources=resources, next_ref=next_ref,

View File

@ -59,13 +59,14 @@ class ContainerBehaviors(base_behaviors.BaseBehaviors):
return resp
def get_containers(self, limit=10, offset=0, extra_headers=None,
user_name=None):
def get_containers(self, limit=10, offset=0, filter=None,
extra_headers=None, user_name=None):
"""Handles getting a list of containers.
:param limit: limits number of returned containers
:param offset: represents how many records to skip before retrieving
the list
:param name_filter: allows you to filter results based on name
:param extra_headers: Extra headers used to retrieve a list of
containers
:param user_name: The user name used to get the list
@ -74,7 +75,12 @@ class ContainerBehaviors(base_behaviors.BaseBehaviors):
references to the next and previous list of containers.
"""
params = {'limit': limit, 'offset': offset}
if filter:
params['name'] = filter
resp = self.client.get('containers', params=params,
extra_headers=extra_headers,
user_name=user_name)
container_list = self.get_json(resp)

View File

@ -64,23 +64,24 @@ class OrderBehaviors(base_behaviors.BaseBehaviors):
extra_headers=extra_headers,
user_name=user_name, use_auth=use_auth)
def get_orders(self, limit=10, offset=0, name_filter=None,
def get_orders(self, limit=10, offset=0, filter=None,
extra_headers=None, user_name=None, use_auth=True):
"""Get a list of orders.
:param limit: limits number of returned orders (default 10)
:param offset: represents how many records to skip before retrieving
the list (default 0)
:param name_filter: optional filter to limit the returned secrets to
those whose name matches the filter.
:param filter: optional filter to limit the returned orders to
those whose metadata contains the filter.
:param extra_headers: Optional HTTP headers to add to the request
:param user_name: the user used to do the get
:param use_auth: Boolean to determine whether auth headers are sent
:return the response, a list of orders and the next/pref hrefs
"""
params = {'limit': limit, 'offset': offset}
if name_filter:
params['name'] = name_filter
if filter:
params['meta'] = filter
resp = self.client.get('orders', params=params,
extra_headers=extra_headers,

View File

@ -116,22 +116,22 @@ class SecretBehaviors(base_behaviors.BaseBehaviors):
secret_ref, response_model_type=secret_models.SecretModel,
use_auth=use_auth, user_name=user_name)
def get_secrets(self, limit=10, offset=0, name_filter=None,
def get_secrets(self, limit=10, offset=0, filter=None,
extra_headers=None, use_auth=True, user_name=None):
"""Handles getting a list of secrets.
:param limit: limits number of returned secrets
:param offset: represents how many records to skip before retrieving
the list
:param name_filter: optional filter to limit the returned secrets to
:param filter: optional filter to limit the returned secrets to
those whose name matches the filter.
:param extra_headers: Optional HTTP headers to add to the request
:param use_auth: Boolean for whether to send authentication headers
:param user_name: The user name used to list the secrets
"""
params = {'limit': limit, 'offset': offset}
if name_filter:
params['name'] = name_filter
if filter:
params['name'] = filter
resp = self.client.get('secrets', params=params,
extra_headers=extra_headers,
use_auth=use_auth, user_name=user_name)

View File

@ -23,6 +23,19 @@ from functionaltests.api.v1.behaviors import secret_behaviors
from functionaltests.api.v1.models import container_models
from functionaltests.api.v1.models import secret_models
def get_default_container_create_data(secret):
return {
"type": "generic",
"name": "generic name",
"secret_refs": [
{
"name": "a secret",
"secret_ref": secret
}
]
}
create_container_data = {
"name": "containername",
"type": "generic",
@ -306,6 +319,57 @@ class RSAContainersTestCase(BaseContainerTestCase):
self.assertNotRegexpMatches(resp.headers['location'], regex)
class ContainersPagingTestCase(base.PagingTestCase):
def setUp(self):
super(ContainersPagingTestCase, self).setUp()
self.secret_behaviors = secret_behaviors.SecretBehaviors(self.client)
self.behaviors = container_behaviors.ContainerBehaviors(self.client)
# make a local mutable copy of the default data to prevent
# possible data contamination
secret = self._create_a_secret()
self.create_default_data = get_default_container_create_data(secret)
def _create_a_secret(self):
secret_defaults_data = {
"name": "AES key",
"expiration": "2018-02-28T19:14:44.180394",
"algorithm": "aes",
"bit_length": 256,
"mode": "cbc",
"payload": "gF6+lLoF3ohA9aPRpt+6bQ==",
"payload_content_type": "application/octet-stream",
"payload_content_encoding": "base64",
}
secret_model = secret_models.SecretModel(**secret_defaults_data)
resp, secret_ref = self.secret_behaviors.create_secret(secret_model)
self.assertEqual(resp.status_code, 201)
self.assertIsNotNone(secret_ref)
return secret_ref
def tearDown(self):
self.behaviors.delete_all_created_containers()
super(ContainersPagingTestCase, self).tearDown()
def create_model(self):
return container_models.ContainerModel(**self.create_default_data)
def create_resources(self, count=0, model=None):
for x in range(0, count):
self.behaviors.create_container(model)
def get_resources(self, limit=10, offset=0, filter=filter):
return self.behaviors.get_containers(limit=limit, offset=offset,
filter=filter)
def set_filter_field(self, unique_str, model):
'''Set the name field which we use in the get_resources '''
model.name = unique_str
class ContainersUnauthedTestCase(BaseContainerTestCase):
def setUp(self):

View File

@ -559,6 +559,36 @@ class OrdersTestCase(base.TestCase):
self.assertEqual(message, plaintext)
class OrdersPagingTestCase(base.PagingTestCase):
def setUp(self):
super(OrdersPagingTestCase, self).setUp()
self.behaviors = order_behaviors.OrderBehaviors(self.client)
# make a local mutable copy of the default data to prevent
# possible data contamination
self.create_default_data = get_default_order_create_data()
def tearDown(self):
self.behaviors.delete_all_created_orders()
super(OrdersPagingTestCase, self).tearDown()
def create_model(self):
return order_models.OrderModel(**self.create_default_data)
def create_resources(self, count=0, model=None):
for x in range(0, count):
self.behaviors.create_order(model)
def get_resources(self, limit=10, offset=0, filter=None):
return self.behaviors.get_orders(limit=limit, offset=offset,
filter=filter)
def set_filter_field(self, unique_str, model):
'''Set the meta field which we use in the get_resources '''
model.meta['name'] = unique_str
class OrdersUnauthedTestCase(base.TestCase):
def setUp(self):

View File

@ -1030,9 +1030,13 @@ class SecretsPagingTestCase(base.PagingTestCase):
for x in range(0, count):
self.behaviors.create_secret(model)
def get_resources(self, limit=10, offset=0, name_filter=""):
def get_resources(self, limit=10, offset=0, filter=None):
return self.behaviors.get_secrets(limit=limit, offset=offset,
name_filter=name_filter)
filter=filter)
def set_filter_field(self, unique_str, model):
'''Set the name field which we use in the get_resources '''
model.name = unique_str
class SecretsUnauthedTestCase(base.TestCase):

View File

@ -48,7 +48,7 @@ commands=
deps =
{[testenv]deps}
nose
commands = nosetests -v --processes=-1 --process-timeout=240 {toxinidir}/functionaltests {posargs}
commands = nosetests -v --processes=-1 --process-timeout=600 {toxinidir}/functionaltests {posargs}
[flake8]
# E711 ignored because of sqlalchemy override of == None