Add Functional Tests for Quota Enforcement

This commit adds functional testing for quota enforcement covering
the unlimited, limited, and disabled quota values for secrets,
containers, orders, and consumers.

Also, this commit includes a few related clean-up items:
- Change the enforce() method to take a project object instead of ID
- Add cleanup to the consumer behaviors functional tests class
- Fix cleanup in the orders behaviors functional test class

Change-Id: I4ad640a91ee0655076cddc449d40ba96548d6bb0
Implements: blueprint quota-support-on-barbican-resources
This commit is contained in:
Dave McCowan
2015-08-30 22:21:43 -04:00
parent f4c5471592
commit 7b700edb5d
12 changed files with 282 additions and 21 deletions

View File

@@ -20,12 +20,14 @@ from functionaltests.api.v1.models import consumer_model
class ConsumerBehaviors(base_behaviors.BaseBehaviors):
def create_consumer(self, model, container_ref, extra_headers=None,
use_auth=True):
user_name=None, admin=None, use_auth=True):
"""Register a consumer to a container.
:param model: The metadata for the consumer
:param container_ref: Full reference to a container
:param extra_headers: Any additional headers to pass to the request
:param user_name: The user name used to create the consumer
:param admin: The user with permission to delete the consumer
:param use_auth: Boolean for whether to send authentication headers
:return: A tuple containing the response from the create
@@ -35,18 +37,25 @@ class ConsumerBehaviors(base_behaviors.BaseBehaviors):
url = '{0}/consumers'.format(container_ref)
resp = self.client.post(url, request_model=model,
extra_headers=extra_headers, use_auth=use_auth)
extra_headers=extra_headers,
user_name=user_name, use_auth=use_auth)
if resp.status_code == 401 and not use_auth:
return resp, None
if resp.status_code == 200:
if admin is None:
admin = user_name
self.created_entities.append((container_ref, model, admin))
returned_data = self.get_json(resp)
consumer_data = returned_data.get('consumers')
return resp, consumer_data
def get_consumers(self, container_ref, limit=10, offset=0,
extra_headers=None, use_auth=True):
extra_headers=None,
user_name=None, use_auth=True):
"""Gets a list of consumers on a container.
:param container_ref: Full reference to a container
@@ -54,6 +63,7 @@ class ConsumerBehaviors(base_behaviors.BaseBehaviors):
:param offset: represents how many records to skip before retrieving
the list
:param extra_headers: Any additional headers to pass to the request
:param user_name: The user name used to get the consumer
:param use_auth: Boolean for whether to send authentication headers
:return: The response from the get and refs to the next/previous list
@@ -64,7 +74,7 @@ class ConsumerBehaviors(base_behaviors.BaseBehaviors):
params = {'limit': limit, 'offset': offset}
resp = self.client.get(url, params=params, extra_headers=extra_headers,
use_auth=use_auth)
user_name=user_name, use_auth=use_auth)
if resp.status_code == 401 and not use_auth:
return resp, None, None, None
@@ -77,12 +87,13 @@ class ConsumerBehaviors(base_behaviors.BaseBehaviors):
return resp, consumers, next_ref, prev_ref
def delete_consumer(self, model, container_ref, extra_headers=None,
use_auth=True):
user_name=None, use_auth=True):
"""Deletes a consumer from a container.
:param model: The metadata for the consumer
:param container_ref: Full reference to a container
:param extra_headers: Any additional headers to pass to the request
:param user_name: The user name used to delete the consumer
:param use_auth: Boolean for whether to send authentication headers
:return: The response from the delete
@@ -91,6 +102,7 @@ class ConsumerBehaviors(base_behaviors.BaseBehaviors):
resp = self.client.delete(url, request_model=model,
extra_headers=extra_headers,
user_name=user_name,
use_auth=use_auth)
if resp.status_code == 401 and not use_auth:
@@ -100,3 +112,9 @@ class ConsumerBehaviors(base_behaviors.BaseBehaviors):
consumer_data = returned_data['consumers']
return resp, consumer_data
def delete_all_created_consumers(self):
"""Delete all of the consumers that we have created."""
entities = list(self.created_entities)
for (container_ref, model, admin) in entities:
self.delete_consumer(model, container_ref, user_name=admin)

View File

@@ -45,6 +45,8 @@ class OrderBehaviors(base_behaviors.BaseBehaviors):
# remember this order and its admin for our housekeeping cleanup
if order_ref:
if admin is None:
admin = user_name
self.created_entities.append((order_ref, admin))
return resp, order_ref

View File

@@ -13,6 +13,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from testtools import testcase
from functionaltests.api import base
from functionaltests.api.v1.behaviors import quota_behaviors
from functionaltests.api.v1.models import quota_models
@@ -100,6 +102,7 @@ class QuotasTestCase(base.TestCase):
self.assertEqual(404, resp.status_code)
@testcase.attr('no_parallel')
class ProjectQuotasPagingTestCase(base.PagingTestCase):
def setUp(self):

View File

@@ -0,0 +1,232 @@
# Copyright (c) 2015 Cisco Systems
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from testtools import testcase
from functionaltests.api import base
from functionaltests.api.v1.behaviors import consumer_behaviors
from functionaltests.api.v1.behaviors import container_behaviors
from functionaltests.api.v1.behaviors import order_behaviors
from functionaltests.api.v1.behaviors import quota_behaviors
from functionaltests.api.v1.behaviors import secret_behaviors
from functionaltests.api.v1.models import consumer_model
from functionaltests.api.v1.models import container_models
from functionaltests.api.v1.models import order_models
from functionaltests.api.v1.models import quota_models
from functionaltests.api.v1.models import secret_models
from functionaltests.common import config
CONF = config.get_config()
admin_b = CONF.rbac_users.admin_b
service_admin = CONF.identity.service_admin
@testcase.attr('no_parallel')
class QuotaEnforcementTestCase(base.TestCase):
def setUp(self):
super(QuotaEnforcementTestCase, self).setUp()
self.quota_behaviors = quota_behaviors.QuotaBehaviors(self.client)
self.secret_behaviors = secret_behaviors.SecretBehaviors(self.client)
self.container_behaviors = container_behaviors.ContainerBehaviors(
self.client)
self.order_behaviors = order_behaviors.OrderBehaviors(self.client)
self.consumer_behaviors = consumer_behaviors.ConsumerBehaviors(
self.client)
self.secret_data = self.get_default_secret_data()
self.quota_data = self.get_default_quota_data()
self.project_id = self.quota_behaviors.get_project_id_from_name(
admin_b)
self.order_secrets = []
def tearDown(self):
self.quota_behaviors.delete_all_created_quotas()
self.consumer_behaviors.delete_all_created_consumers()
self.container_behaviors.delete_all_created_containers()
self.secret_behaviors.delete_all_created_secrets()
for secret_ref in self.order_secrets:
resp = self.secret_behaviors.delete_secret(
secret_ref, user_name=admin_b)
self.assertEqual(204, resp.status_code)
self.order_behaviors.delete_all_created_orders()
super(QuotaEnforcementTestCase, self).tearDown()
def test_secrets_unlimited(self):
self.set_quotas('secrets', -1)
self.create_secrets(count=5)
def test_secrets_disabled(self):
self.set_quotas('secrets', 0)
self.create_secrets(expected_return=403)
def test_secrets_limited_one(self):
self.set_quotas('secrets', 1)
self.create_secrets(count=1)
self.create_secrets(expected_return=403)
def test_secrets_limited_five(self):
self.set_quotas('secrets', 5)
self.create_secrets(count=5)
self.create_secrets(expected_return=403)
def test_containers_unlimited(self):
self.set_quotas('containers', -1)
self.create_containers(count=5)
def test_containers_disabled(self):
self.set_quotas('containers', 0)
self.create_containers(expected_return=403)
def test_containers_limited_one(self):
self.set_quotas('containers', 1)
self.create_containers(count=1)
self.create_containers(expected_return=403)
def test_containers_limited_five(self):
self.set_quotas('containers', 5)
self.create_containers(count=5)
self.create_containers(expected_return=403)
def test_orders_unlimited(self):
self.set_quotas('orders', -1)
self.create_orders(count=5)
def test_orders_disabled(self):
self.set_quotas('orders', 0)
self.create_orders(expected_return=403)
def test_orders_limited_one(self):
self.set_quotas('orders', 1)
self.create_orders(count=1)
self.create_orders(expected_return=403)
def test_orders_limited_five(self):
self.set_quotas('orders', 5)
self.create_orders(count=5)
self.create_orders(expected_return=403)
def test_consumers_unlimited(self):
self.set_quotas('consumers', -1)
self.create_consumers(count=5)
def test_consumers_disabled(self):
self.set_quotas('consumers', 0)
self.create_consumers(expected_return=403)
def test_consumers_limited_one(self):
self.set_quotas('consumers', 1)
self.create_consumers(count=1)
self.create_consumers(expected_return=403)
def test_consumers_limited_five(self):
self.set_quotas('consumers', 5)
self.create_consumers(count=5)
self.create_consumers(expected_return=403)
# ----------------------- Helper Functions ---------------------------
def get_default_quota_data(self):
return {"project_quotas":
{"secrets": -1,
"orders": -1,
"containers": -1,
"consumers": -1}}
def set_quotas(self, resource, quota):
"""Utility function to set resource quotas"""
self.quota_data["project_quotas"][resource] = quota
request_model = quota_models.ProjectQuotaRequestModel(
**self.quota_data)
resp = self.quota_behaviors.set_project_quotas(self.project_id,
request_model,
user_name=service_admin)
self.assertEqual(204, resp.status_code)
def get_default_secret_data(self):
return {
"name": "AES key",
"expiration": "2050-02-28T19:14:44.180394",
"algorithm": "aes",
"bit_length": 256,
"mode": "cbc",
"payload": "Z0Y2K2xMb0Yzb2hBOWFQUnB0KzZiUT09",
"payload_content_type": "application/octet-stream",
"payload_content_encoding": "base64",
}
def create_secrets(self, count=1, expected_return=201):
"""Utility function to create secrets"""
secret_ref = None
for _ in range(count):
test_model = secret_models.SecretModel(**self.secret_data)
resp, secret_ref = self.secret_behaviors.create_secret(
test_model, user_name=admin_b)
self.assertEqual(expected_return, resp.status_code)
return secret_ref
def get_container_req(self, secret_ref):
return {"name": "test_container",
"type": "generic",
"secret_refs": [{'name': 'secret1', 'secret_ref': secret_ref}]}
def create_containers(self, count=1, expected_return=201):
"""Utility function to create containers"""
container_ref = None
for _ in range(count):
secret_ref = self.create_secrets()
test_model = container_models.ContainerModel(
**self.get_container_req(secret_ref))
resp, container_ref = self.container_behaviors.create_container(
test_model, user_name=admin_b)
self.assertEqual(expected_return, resp.status_code)
return container_ref
def get_default_order_data(self):
return {'type': 'key',
"meta": {
"name": "barbican functional test order name",
"algorithm": "aes",
"bit_length": 256,
"mode": "cbc"}}
def create_orders(self, count=1, expected_return=202):
"""Utility function to create orders"""
for _ in range(count):
order_data = self.get_default_order_data()
test_model = order_models.OrderModel(**order_data)
resp, order_ref = self.order_behaviors.create_order(
test_model, user_name=admin_b)
self.assertEqual(expected_return, resp.status_code)
if resp.status_code == 202:
order_resp = self.order_behaviors.get_order(
order_ref, user_name=admin_b)
self.assertEqual(order_resp.status_code, 200)
self.order_secrets.append(order_resp.model.secret_ref)
def get_default_consumer_data(self):
return {"name": "consumer_name",
"URL": "consumer_url"}
def create_consumers(self, count=1, expected_return=200):
"""Utility function to create consumers"""
for _ in range(count):
container_ref = self.create_containers()
model = consumer_model.ConsumerModel(
**self.get_default_consumer_data())
resp, consumer_dat = self.consumer_behaviors.create_consumer(
model, container_ref, user_name=admin_b)
self.assertEqual(expected_return, resp.status_code)

View File

@@ -35,7 +35,7 @@ retval=$?
testr slowest
# run the tests in parallel
SKIP=^\(\?\!\.\*ProjectQuotasPagingTestCase\)
SKIP=^\(\?\!\.\*\(ProjectQuotasPagingTestCase\|QuotaEnforcementTestCase\)\)
testr init
testr run $SKIP --parallel --subunit | subunit-trace --no-failure-debug -f
retval=$?