diff options
-rw-r--r-- | nova/db/sqlalchemy/api.py | 24 | ||||
-rw-r--r-- | nova/tests/test_instance_types.py | 61 |
2 files changed, 71 insertions, 14 deletions
diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 4b350e516..5a215e3a6 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -3671,7 +3671,7 @@ def instance_type_destroy(context, name): @require_context def _instance_type_access_query(context, session=None): return model_query(context, models.InstanceTypeProjects, session=session, - read_deleted="yes") + read_deleted="no") @require_admin_context @@ -3687,6 +3687,8 @@ def instance_type_access_get_by_flavor_id(context, flavor_id): @require_admin_context def instance_type_access_add(context, flavor_id, project_id): """Add given tenant to the flavor access list.""" + # NOTE(boris-42): There is a race condition in this method and it will be + # rewritten after bp/db-unique-keys implementation. session = get_session() with session.begin(): instance_type_ref = instance_type_get_by_flavor_id(context, flavor_id, @@ -3694,21 +3696,16 @@ def instance_type_access_add(context, flavor_id, project_id): instance_type_id = instance_type_ref['id'] access_ref = _instance_type_access_query(context, session=session).\ filter_by(instance_type_id=instance_type_id).\ - filter_by(project_id=project_id).first() - - if not access_ref: - access_ref = models.InstanceTypeProjects() - access_ref.instance_type_id = instance_type_id - access_ref.project_id = project_id - access_ref.save(session=session) - elif access_ref.deleted: - access_ref.update({'deleted': False, - 'deleted_at': None}) - access_ref.save(session=session) - else: + filter_by(project_id=project_id).\ + first() + if access_ref: raise exception.FlavorAccessExists(flavor_id=flavor_id, project_id=project_id) + access_ref = models.InstanceTypeProjects() + access_ref.update({"instance_type_id": instance_type_id, + "project_id": project_id}) + access_ref.save(session=session) return access_ref @@ -3724,7 +3721,6 @@ def instance_type_access_remove(context, flavor_id, project_id): filter_by(instance_type_id=instance_type_id).\ filter_by(project_id=project_id).\ soft_delete() - if count == 0: raise exception.FlavorAccessNotFound(flavor_id=flavor_id, project_id=project_id) diff --git a/nova/tests/test_instance_types.py b/nova/tests/test_instance_types.py index 4a136cf13..b70b96b7f 100644 --- a/nova/tests/test_instance_types.py +++ b/nova/tests/test_instance_types.py @@ -142,6 +142,67 @@ class InstanceTypeTestCase(test.TestCase): self.assertRaises(exception.InvalidInput, instance_types.create, name, 256, 1, 120, 100, flavorid) + def test_add_instance_type_access(self): + user_id = 'fake' + project_id = 'fake' + ctxt = context.RequestContext(user_id, project_id, is_admin=True) + flavor_id = 'flavor1' + type_ref = instance_types.create('some flavor', 256, 1, 120, 100, + flavorid=flavor_id) + access_ref = instance_types.add_instance_type_access(flavor_id, + project_id, + ctxt=ctxt) + self.assertEqual(access_ref["project_id"], project_id) + self.assertEqual(access_ref["instance_type_id"], type_ref["id"]) + + def test_add_instance_type_access_already_exists(self): + user_id = 'fake' + project_id = 'fake' + ctxt = context.RequestContext(user_id, project_id, is_admin=True) + flavor_id = 'flavor1' + type_ref = instance_types.create('some flavor', 256, 1, 120, 100, + flavorid=flavor_id) + access_ref = instance_types.add_instance_type_access(flavor_id, + project_id, + ctxt=ctxt) + self.assertRaises(exception.FlavorAccessExists, + instance_types.add_instance_type_access, + flavor_id, project_id, ctxt) + + def test_add_instance_type_access_invalid_flavor(self): + user_id = 'fake' + project_id = 'fake' + ctxt = context.RequestContext(user_id, project_id, is_admin=True) + flavor_id = 'no_such_flavor' + self.assertRaises(exception.FlavorNotFound, + instance_types.add_instance_type_access, + flavor_id, project_id, ctxt) + + def test_remove_instance_type_access(self): + user_id = 'fake' + project_id = 'fake' + ctxt = context.RequestContext(user_id, project_id, is_admin=True) + flavor_id = 'flavor1' + it = instance_types + type_ref = it.create('some flavor', 256, 1, 120, 100, + flavorid=flavor_id) + access_ref = it.add_instance_type_access(flavor_id, project_id, ctxt) + it.remove_instance_type_access(flavor_id, project_id, ctxt) + + projects = it.get_instance_type_access_by_flavor_id(flavor_id, ctxt) + self.assertEqual([], projects) + + def test_remove_instance_type_access_doesnt_exists(self): + user_id = 'fake' + project_id = 'fake' + ctxt = context.RequestContext(user_id, project_id, is_admin=True) + flavor_id = 'flavor1' + type_ref = instance_types.create('some flavor', 256, 1, 120, 100, + flavorid=flavor_id) + self.assertRaises(exception.FlavorAccessNotFound, + instance_types.remove_instance_type_access, + flavor_id, project_id, ctxt=ctxt) + def test_get_all_instance_types(self): # Ensures that all instance types can be retrieved. session = sql_session.get_session() |