From f329dfdd9804ac7f9562ed757d39d7583c9b30b7 Mon Sep 17 00:00:00 2001 From: Richard Lee Date: Mon, 3 Feb 2014 14:19:37 -0500 Subject: [PATCH] Alter stack_count_all_by_tenant to stack_count_all Preparing the database for the unscoped list stacks, this removes stack_count_all_by_tenant in favor of a single function that is tenant aware. This way, you can call stack_count_all(tenant_safe=False) and count all stacks, regardless of the tenants. tenant_safe defaults to True. Co-Authored-By: Anderson Mesquita Implements: blueprint management-api (partial) Change-Id: Ic44b884120290b6ceaf4936e015ef6661aaf6694 --- heat/db/api.py | 5 ++-- heat/db/sqlalchemy/api.py | 4 +-- heat/engine/service.py | 4 +-- heat/tests/test_engine_service.py | 2 +- heat/tests/test_sqlalchemy_api.py | 41 +++++++++++++++++++++++-------- 5 files changed, 39 insertions(+), 17 deletions(-) diff --git a/heat/db/api.py b/heat/db/api.py index 5bb36f254c..541bc4eb17 100644 --- a/heat/db/api.py +++ b/heat/db/api.py @@ -130,8 +130,9 @@ def stack_get_all_by_owner_id(context, owner_id): return IMPL.stack_get_all_by_owner_id(context, owner_id) -def stack_count_all_by_tenant(context, filters=None): - return IMPL.stack_count_all_by_tenant(context, filters=filters) +def stack_count_all(context, filters=None, tenant_safe=True): + return IMPL.stack_count_all(context, filters=filters, + tenant_safe=tenant_safe) def stack_create(context, values): diff --git a/heat/db/sqlalchemy/api.py b/heat/db/sqlalchemy/api.py index 5a1a14c4ae..40c9900730 100644 --- a/heat/db/sqlalchemy/api.py +++ b/heat/db/sqlalchemy/api.py @@ -354,8 +354,8 @@ def _filter_and_page_query(context, query, limit=None, sort_keys=None, whitelisted_sort_keys, marker, sort_dir) -def stack_count_all_by_tenant(context, filters=None): - query = _query_stack_get_all(context) +def stack_count_all(context, filters=None, tenant_safe=True): + query = _query_stack_get_all(context, tenant_safe=tenant_safe) query = db_filters.exact_filter(query, models.Stack, filters) return query.count() diff --git a/heat/engine/service.py b/heat/engine/service.py index 972b35432d..8e3903e441 100644 --- a/heat/engine/service.py +++ b/heat/engine/service.py @@ -342,7 +342,7 @@ class EngineService(service.Service): :param filters: a dict of ATTR:VALUE to match against stacks :returns: a integer representing the number of matched stacks """ - return db_api.stack_count_all_by_tenant(cnxt, filters=filters) + return db_api.stack_count_all(cnxt, filters=filters) def _validate_deferred_auth_context(self, cnxt, stack): if cfg.CONF.deferred_auth_method != 'password': @@ -361,7 +361,7 @@ class EngineService(service.Service): raise exception.StackExists(stack_name=stack_name) tenant_limit = cfg.CONF.max_stacks_per_tenant - if db_api.stack_count_all_by_tenant(cnxt) >= tenant_limit: + if db_api.stack_count_all(cnxt) >= tenant_limit: message = _("You have reached the maximum stacks per tenant, %d." " Please delete some stacks.") % tenant_limit raise exception.RequestLimitExceeded(message=message) diff --git a/heat/tests/test_engine_service.py b/heat/tests/test_engine_service.py index 40f19f291a..4f43f750a1 100644 --- a/heat/tests/test_engine_service.py +++ b/heat/tests/test_engine_service.py @@ -2551,7 +2551,7 @@ class StackServiceTest(HeatTestCase): self.assertRaises(exception.StackExists, self.eng._validate_new_stack, self.ctx, 'test_existing_stack', 'parsed_template') - @mock.patch.object(service.db_api, 'stack_count_all_by_tenant') + @mock.patch.object(service.db_api, 'stack_count_all') def test_validate_new_stack_checks_stack_limit(self, mock_db_count): cfg.CONF.set_override('max_stacks_per_tenant', 99) mock_db_count.return_value = 99 diff --git a/heat/tests/test_sqlalchemy_api.py b/heat/tests/test_sqlalchemy_api.py index 64a17c51fb..7459c7cee8 100644 --- a/heat/tests/test_sqlalchemy_api.py +++ b/heat/tests/test_sqlalchemy_api.py @@ -457,27 +457,27 @@ class SqlAlchemyTest(HeatTestCase): db_api.stack_get_all(self.ctx, sort_keys=sort_keys) self.assertEqual(['id'], sort_keys) - def test_stack_count_all_by_tenant(self): + def test_stack_count_all(self): stacks = [self._setup_test_stack('stack', x)[1] for x in UUIDs] - st_db = db_api.stack_count_all_by_tenant(self.ctx) + st_db = db_api.stack_count_all(self.ctx) self.assertEqual(3, st_db) stacks[0].delete() - st_db = db_api.stack_count_all_by_tenant(self.ctx) + st_db = db_api.stack_count_all(self.ctx) self.assertEqual(2, st_db) stacks[1].delete() - st_db = db_api.stack_count_all_by_tenant(self.ctx) + st_db = db_api.stack_count_all(self.ctx) self.assertEqual(1, st_db) - def test_stack_count_all_by_tenant_with_filters(self): + def test_stack_count_all_with_filters(self): self._setup_test_stack('foo', UUID1) self._setup_test_stack('bar', UUID2) self._setup_test_stack('bar', UUID3) filters = {'name': 'bar'} - st_db = db_api.stack_count_all_by_tenant(self.ctx, filters=filters) + st_db = db_api.stack_count_all(self.ctx, filters=filters) self.assertEqual(2, st_db) def test_event_get_all_by_stack(self): @@ -1066,15 +1066,36 @@ class DBAPIStackTest(HeatTestCase): stacks = db_api.stack_get_all(self.ctx, tenant_safe=False) self.assertEqual(5, len(stacks)) - def test_stack_count_all_by_tenant(self): + def test_stack_count_all_with_regular_tenant(self): values = [ - {'tenant': self.ctx.tenant_id}, - {'tenant': self.ctx.tenant_id}, + {'tenant': UUID1}, + {'tenant': UUID1}, + {'tenant': UUID2}, + {'tenant': UUID2}, + {'tenant': UUID2}, ] [create_stack(self.ctx, self.template, self.user_creds, **val) for val in values] - self.assertEqual(2, db_api.stack_count_all_by_tenant(self.ctx)) + self.ctx.tenant_id = UUID1 + self.assertEqual(2, db_api.stack_count_all(self.ctx)) + + self.ctx.tenant_id = UUID2 + self.assertEqual(3, db_api.stack_count_all(self.ctx)) + + def test_stack_count_all_with_tenant_safe_false(self): + values = [ + {'tenant': UUID1}, + {'tenant': UUID1}, + {'tenant': UUID2}, + {'tenant': UUID2}, + {'tenant': UUID2}, + ] + [create_stack(self.ctx, self.template, self.user_creds, + **val) for val in values] + + self.assertEqual(5, + db_api.stack_count_all(self.ctx, tenant_safe=False)) def test_purge_deleted(self): now = datetime.now()