diff options
author | Kevin L. Mitchell <kevin.mitchell@rackspace.com> | 2012-05-11 15:30:14 -0500 |
---|---|---|
committer | Kevin L. Mitchell <kevin.mitchell@rackspace.com> | 2012-05-23 10:17:41 -0500 |
commit | b7f0946bbd071bc76809eca440ab7d21a03eb1a3 (patch) | |
tree | 4f46ad3896cb89c8747bdf09e3f33a476eccbf16 /nova/tests | |
parent | 7e15d4e28f98e13f0ea7399787c50839139d8492 (diff) | |
download | nova-b7f0946bbd071bc76809eca440ab7d21a03eb1a3.tar.gz nova-b7f0946bbd071bc76809eca440ab7d21a03eb1a3.tar.xz nova-b7f0946bbd071bc76809eca440ab7d21a03eb1a3.zip |
Finish quota refactor.
Finishes quota refactoring by making use of the new quota infrastructure.
Partially implements blueprint quota-refactor (the final piece is to
remove the old quota architecture).
This change is fairly substantial. To make it easier to review, it has been
broken up into 3 parts. This is the second part.
Change-Id: I1c8b43198f0d44e9e13a45575361aa043fd0639e
Diffstat (limited to 'nova/tests')
-rw-r--r-- | nova/tests/api/openstack/compute/contrib/test_keypairs.py | 34 | ||||
-rw-r--r-- | nova/tests/api/openstack/compute/contrib/test_quota_classes.py | 6 | ||||
-rw-r--r-- | nova/tests/api/openstack/compute/contrib/test_quotas.py | 7 | ||||
-rw-r--r-- | nova/tests/api/openstack/compute/contrib/test_security_groups.py | 2 | ||||
-rw-r--r-- | nova/tests/api/openstack/compute/test_limits.py | 7 | ||||
-rw-r--r-- | nova/tests/api/openstack/compute/test_servers.py | 4 | ||||
-rw-r--r-- | nova/tests/api/openstack/fakes.py | 23 | ||||
-rw-r--r-- | nova/tests/compute/test_compute.py | 16 | ||||
-rw-r--r-- | nova/tests/network/test_manager.py | 20 | ||||
-rw-r--r-- | nova/tests/scheduler/test_chance_scheduler.py | 23 | ||||
-rw-r--r-- | nova/tests/scheduler/test_filter_scheduler.py | 12 | ||||
-rw-r--r-- | nova/tests/scheduler/test_rpcapi.py | 6 | ||||
-rw-r--r-- | nova/tests/scheduler/test_scheduler.py | 6 | ||||
-rw-r--r-- | nova/tests/test_quota.py | 79 | ||||
-rw-r--r-- | nova/tests/test_volume.py | 16 |
15 files changed, 191 insertions, 70 deletions
diff --git a/nova/tests/api/openstack/compute/contrib/test_keypairs.py b/nova/tests/api/openstack/compute/contrib/test_keypairs.py index da8c44f86..8a9849d2c 100644 --- a/nova/tests/api/openstack/compute/contrib/test_keypairs.py +++ b/nova/tests/api/openstack/compute/contrib/test_keypairs.py @@ -22,10 +22,14 @@ from nova.api.openstack.compute.contrib import keypairs from nova.api.openstack import wsgi from nova import db from nova import exception +from nova import quota from nova import test from nova.tests.api.openstack import fakes +QUOTAS = quota.QUOTAS + + def fake_keypair(name): return {'public_key': 'FAKE_KEY', 'fingerprint': 'FAKE_FINGERPRINT', @@ -120,11 +124,10 @@ class KeypairsTest(test.TestCase): def test_keypair_create_quota_limit(self): - def db_key_pair_count_by_user_max(self, user_id): + def fake_quotas_count(self, context, resource, *args, **kwargs): return 100 - self.stubs.Set(db, "key_pair_count_by_user", - db_key_pair_count_by_user_max) + self.stubs.Set(QUOTAS, "count", fake_quotas_count) req = webob.Request.blank('/v2/fake/os-keypairs') req.method = 'POST' @@ -163,11 +166,10 @@ class KeypairsTest(test.TestCase): def test_keypair_import_quota_limit(self): - def db_key_pair_count_by_user_max(self, user_id): + def fake_quotas_count(self, context, resource, *args, **kwargs): return 100 - self.stubs.Set(db, "key_pair_count_by_user", - db_key_pair_count_by_user_max) + self.stubs.Set(QUOTAS, "count", fake_quotas_count) body = { 'keypair': { @@ -191,6 +193,26 @@ class KeypairsTest(test.TestCase): res = req.get_response(fakes.wsgi_app()) self.assertEqual(res.status_int, 413) + def test_keypair_create_quota_limit(self): + + def fake_quotas_count(self, context, resource, *args, **kwargs): + return 100 + + self.stubs.Set(QUOTAS, "count", fake_quotas_count) + + body = { + 'keypair': { + 'name': 'create_test', + }, + } + + req = webob.Request.blank('/v2/fake/os-keypairs') + req.method = 'POST' + req.body = json.dumps(body) + req.headers['Content-Type'] = 'application/json' + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(res.status_int, 413) + def test_keypair_create_duplicate(self): self.stubs.Set(db, "key_pair_get", db_key_pair_get) body = {'keypair': {'name': 'create_duplicate'}} diff --git a/nova/tests/api/openstack/compute/contrib/test_quota_classes.py b/nova/tests/api/openstack/compute/contrib/test_quota_classes.py index 1287b482c..b732f889c 100644 --- a/nova/tests/api/openstack/compute/contrib/test_quota_classes.py +++ b/nova/tests/api/openstack/compute/contrib/test_quota_classes.py @@ -28,7 +28,7 @@ def quota_set(class_name): 'floating_ips': 10, 'instances': 10, 'injected_files': 5, 'cores': 20, 'injected_file_content_bytes': 10240, 'security_groups': 10, 'security_group_rules': 20, - 'key_pairs': 100}} + 'key_pairs': 100, 'injected_file_path_bytes': 255}} class QuotaClassSetsTest(test.TestCase): @@ -47,6 +47,7 @@ class QuotaClassSetsTest(test.TestCase): 'metadata_items': 128, 'gigabytes': 1000, 'injected_files': 5, + 'injected_file_path_bytes': 255, 'injected_file_content_bytes': 10240, 'security_groups': 10, 'security_group_rules': 20, @@ -66,6 +67,7 @@ class QuotaClassSetsTest(test.TestCase): self.assertEqual(qs['floating_ips'], 10) self.assertEqual(qs['metadata_items'], 128) self.assertEqual(qs['injected_files'], 5) + self.assertEqual(qs['injected_file_path_bytes'], 255) self.assertEqual(qs['injected_file_content_bytes'], 10240) self.assertEqual(qs['security_groups'], 10) self.assertEqual(qs['security_group_rules'], 20) @@ -91,6 +93,7 @@ class QuotaClassSetsTest(test.TestCase): 'gigabytes': 1000, 'floating_ips': 10, 'metadata_items': 128, 'injected_files': 5, 'injected_file_content_bytes': 10240, + 'injected_file_path_bytes': 255, 'security_groups': 10, 'security_group_rules': 20, 'key_pairs': 100, @@ -130,6 +133,7 @@ class QuotaTemplateXMLSerializerTest(test.TestCase): exemplar = dict(quota_class_set=dict( id='test_class', metadata_items=10, + injected_file_path_bytes=255, injected_file_content_bytes=20, volumes=30, gigabytes=40, diff --git a/nova/tests/api/openstack/compute/contrib/test_quotas.py b/nova/tests/api/openstack/compute/contrib/test_quotas.py index fac37897c..f628535a7 100644 --- a/nova/tests/api/openstack/compute/contrib/test_quotas.py +++ b/nova/tests/api/openstack/compute/contrib/test_quotas.py @@ -30,7 +30,7 @@ def quota_set(id): 'instances': 10, 'injected_files': 5, 'cores': 20, 'injected_file_content_bytes': 10240, 'security_groups': 10, 'security_group_rules': 20, - 'key_pairs': 100}} + 'key_pairs': 100, 'injected_file_path_bytes': 255}} class QuotaSetsTest(test.TestCase): @@ -49,6 +49,7 @@ class QuotaSetsTest(test.TestCase): 'metadata_items': 128, 'gigabytes': 1000, 'injected_files': 5, + 'injected_file_path_bytes': 255, 'injected_file_content_bytes': 10240, 'security_groups': 10, 'security_group_rules': 20, @@ -67,6 +68,7 @@ class QuotaSetsTest(test.TestCase): self.assertEqual(qs['floating_ips'], 10) self.assertEqual(qs['metadata_items'], 128) self.assertEqual(qs['injected_files'], 5) + self.assertEqual(qs['injected_file_path_bytes'], 255) self.assertEqual(qs['injected_file_content_bytes'], 10240) self.assertEqual(qs['security_groups'], 10) self.assertEqual(qs['security_group_rules'], 20) @@ -88,6 +90,7 @@ class QuotaSetsTest(test.TestCase): 'floating_ips': 10, 'metadata_items': 128, 'injected_files': 5, + 'injected_file_path_bytes': 255, 'injected_file_content_bytes': 10240, 'security_groups': 10, 'security_group_rules': 20, @@ -114,6 +117,7 @@ class QuotaSetsTest(test.TestCase): 'gigabytes': 1000, 'floating_ips': 10, 'metadata_items': 128, 'injected_files': 5, 'injected_file_content_bytes': 10240, + 'injected_file_path_bytes': 255, 'security_groups': 10, 'security_group_rules': 20, 'key_pairs': 100}} @@ -161,6 +165,7 @@ class QuotaXMLSerializerTest(test.TestCase): exemplar = dict(quota_set=dict( id='project_id', metadata_items=10, + injected_file_path_bytes=255, injected_file_content_bytes=20, volumes=30, gigabytes=40, diff --git a/nova/tests/api/openstack/compute/contrib/test_security_groups.py b/nova/tests/api/openstack/compute/contrib/test_security_groups.py index 8cc4cc672..f864ab648 100644 --- a/nova/tests/api/openstack/compute/contrib/test_security_groups.py +++ b/nova/tests/api/openstack/compute/contrib/test_security_groups.py @@ -224,7 +224,7 @@ class TestSecurityGroups(test.TestCase): def test_create_security_group_quota_limit(self): req = fakes.HTTPRequest.blank('/v2/fake/os-security-groups') - for num in range(1, FLAGS.quota_security_groups): + for num in range(1, FLAGS.quota_security_groups + 1): name = 'test%s' % num sg = security_group_template(name=name) res_dict = self.controller.create(req, {'security_group': sg}) diff --git a/nova/tests/api/openstack/compute/test_limits.py b/nova/tests/api/openstack/compute/test_limits.py index aa48e5b3d..e104c148d 100644 --- a/nova/tests/api/openstack/compute/test_limits.py +++ b/nova/tests/api/openstack/compute/test_limits.py @@ -57,10 +57,11 @@ class BaseLimitTestSuite(test.TestCase): self.stubs.Set(limits.Limit, "_get_time", self._get_time) self.absolute_limits = {} - def stub_get_project_quotas(context, project_id): - return self.absolute_limits + def stub_get_project_quotas(context, project_id, usages=True): + return dict((k, dict(limit=v)) + for k, v in self.absolute_limits.items()) - self.stubs.Set(nova.quota, "get_project_quotas", + self.stubs.Set(nova.quota.QUOTAS, "get_project_quotas", stub_get_project_quotas) def _get_time(self): diff --git a/nova/tests/api/openstack/compute/test_servers.py b/nova/tests/api/openstack/compute/test_servers.py index 5d8030434..14d1dff75 100644 --- a/nova/tests/api/openstack/compute/test_servers.py +++ b/nova/tests/api/openstack/compute/test_servers.py @@ -1287,6 +1287,7 @@ class ServersControllerTest(test.TestCase): self.assertEqual(s['name'], 'server%d' % (i + 1)) def test_delete_server_instance(self): + fakes.stub_out_instance_quota(self.stubs, 0) req = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % FAKE_UUID) req.method = 'DELETE' @@ -1304,6 +1305,7 @@ class ServersControllerTest(test.TestCase): self.assertEqual(self.server_delete_called, True) def test_delete_server_instance_while_building(self): + fakes.stub_out_instance_quota(self.stubs, 0) req = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % FAKE_UUID) req.method = 'DELETE' @@ -2338,7 +2340,7 @@ class ServersControllerCreateTest(test.TestCase): req.headers["content-type"] = "application/json" try: server = self.controller.create(req, body).obj['server'] - fail('excepted quota to be exceeded') + self.fail('expected quota to be exceeded') except webob.exc.HTTPRequestEntityTooLarge as e: self.assertEquals(e.explanation, _('Quota exceeded: already used 1 of 1 instances')) diff --git a/nova/tests/api/openstack/fakes.py b/nova/tests/api/openstack/fakes.py index 4fc55d730..44e76f146 100644 --- a/nova/tests/api/openstack/fakes.py +++ b/nova/tests/api/openstack/fakes.py @@ -17,13 +17,12 @@ import datetime +from glance import client as glance_client import routes import webob import webob.dec import webob.request -from glance import client as glance_client - from nova.api import auth as api_auth from nova.api import openstack as openstack_api from nova.api.openstack import auth @@ -40,12 +39,16 @@ from nova.db.sqlalchemy import models from nova import exception as exc import nova.image.fake from nova.openstack.common import jsonutils +from nova import quota from nova.tests import fake_network from nova.tests.glance import stubs as glance_stubs from nova import utils from nova import wsgi +QUOTAS = quota.QUOTAS + + FAKE_UUID = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa' FAKE_UUIDS = {} @@ -142,9 +145,19 @@ def stub_out_rate_limiting(stubs): def stub_out_instance_quota(stubs, allowed): - def fake_allowed_instances(context, max_count, instance_type): - return allowed - stubs.Set(nova.quota, 'allowed_instances', fake_allowed_instances) + def fake_reserve(context, **deltas): + instances = deltas.pop('instances', 0) + if instances > allowed: + raise exc.OverQuota(overs=['instances'], quotas=dict( + instances=allowed, + cores=10000, + ram=10000 * 1024, + ), usages=dict( + instances=dict(in_use=0, reserved=0), + cores=dict(in_use=0, reserved=0), + ram=dict(in_use=0, reserved=0), + )) + stubs.Set(QUOTAS, 'reserve', fake_reserve) def stub_out_networking(stubs): diff --git a/nova/tests/compute/test_compute.py b/nova/tests/compute/test_compute.py index 7af2c7ef1..51e36daab 100644 --- a/nova/tests/compute/test_compute.py +++ b/nova/tests/compute/test_compute.py @@ -45,6 +45,7 @@ from nova import log as logging from nova.notifier import test_notifier from nova.openstack.common import importutils import nova.policy +from nova import quota from nova import rpc from nova.rpc import common as rpc_common from nova.scheduler import driver as scheduler_driver @@ -54,6 +55,7 @@ from nova import utils import nova.volume +QUOTAS = quota.QUOTAS LOG = logging.getLogger(__name__) FLAGS = flags.FLAGS flags.DECLARE('stub_network', 'nova.compute.manager') @@ -71,13 +73,14 @@ def rpc_call_wrapper(context, topic, msg, do_cast=True): if (topic == FLAGS.scheduler_topic and msg['method'] == 'run_instance'): request_spec = msg['args']['request_spec'] + reservations = msg['args'].get('reservations') scheduler = scheduler_driver.Scheduler num_instances = request_spec.get('num_instances', 1) instances = [] for num in xrange(num_instances): request_spec['instance_properties']['launch_index'] = num instance = scheduler().create_instance_db_entry( - context, request_spec) + context, request_spec, reservations) encoded = scheduler_driver.encode_instance(instance) instances.append(encoded) return instances @@ -148,6 +151,7 @@ class BaseTestCase(test.TestCase): inst['instance_type_id'] = type_id inst['ami_launch_index'] = 0 inst['memory_mb'] = 0 + inst['vcpus'] = 0 inst['root_gb'] = 0 inst['ephemeral_gb'] = 0 inst.update(params) @@ -4123,10 +4127,9 @@ class KeypairAPITestCase(BaseTestCase): self.ctxt, self.ctxt.user_id, 'foo') def test_create_keypair_quota_limit(self): - def db_key_pair_count_by_user_max(self, user_id): + def fake_quotas_count(self, context, resource, *args, **kwargs): return FLAGS.quota_key_pairs - self.stubs.Set(db, "key_pair_count_by_user", - db_key_pair_count_by_user_max) + self.stubs.Set(QUOTAS, "count", fake_quotas_count) self.assertRaises(exception.KeypairLimitExceeded, self.keypair_api.create_key_pair, self.ctxt, self.ctxt.user_id, 'foo') @@ -4158,10 +4161,9 @@ class KeypairAPITestCase(BaseTestCase): '* BAD CHARACTERS! *', self.pub_key) def test_import_keypair_quota_limit(self): - def db_key_pair_count_by_user_max(self, user_id): + def fake_quotas_count(self, context, resource, *args, **kwargs): return FLAGS.quota_key_pairs - self.stubs.Set(db, "key_pair_count_by_user", - db_key_pair_count_by_user_max) + self.stubs.Set(QUOTAS, "count", fake_quotas_count) self.assertRaises(exception.KeypairLimitExceeded, self.keypair_api.import_key_pair, self.ctxt, self.ctxt.user_id, 'foo', self.pub_key) diff --git a/nova/tests/network/test_manager.py b/nova/tests/network/test_manager.py index 2158ea566..f6931a876 100644 --- a/nova/tests/network/test_manager.py +++ b/nova/tests/network/test_manager.py @@ -551,26 +551,12 @@ class VlanNetworkTestCase(test.TestCase): ctxt = context.RequestContext('testuser', 'testproject', is_admin=False) - def fake1(*args, **kwargs): + def fake_allocate_address(*args, **kwargs): return {'address': '10.0.0.1', 'project_id': ctxt.project_id} - def fake2(*args, **kwargs): - return 25 - - def fake3(*args, **kwargs): - return 0 - - self.stubs.Set(self.network.db, 'floating_ip_allocate_address', fake1) - - # this time should raise - self.stubs.Set(self.network.db, 'floating_ip_count_by_project', fake2) - self.assertRaises(exception.QuotaError, - self.network.allocate_floating_ip, - ctxt, - ctxt.project_id) + self.stubs.Set(self.network.db, 'floating_ip_allocate_address', + fake_allocate_address) - # this time should not - self.stubs.Set(self.network.db, 'floating_ip_count_by_project', fake3) self.network.allocate_floating_ip(ctxt, ctxt.project_id) def test_deallocate_floating_ip(self): diff --git a/nova/tests/scheduler/test_chance_scheduler.py b/nova/tests/scheduler/test_chance_scheduler.py index a9bb7a08e..ec853594b 100644 --- a/nova/tests/scheduler/test_chance_scheduler.py +++ b/nova/tests/scheduler/test_chance_scheduler.py @@ -71,13 +71,14 @@ class ChanceSchedulerTestCase(test_scheduler.SchedulerTestCase): instance2 = {'uuid': 'fake-uuid2'} instance1_encoded = {'uuid': 'fake-uuid1', '_is_precooked': False} instance2_encoded = {'uuid': 'fake-uuid2', '_is_precooked': False} + reservations = ['resv1', 'resv2'] # create_instance_db_entry() usually does this, but we're # stubbing it. - def _add_uuid1(ctxt, request_spec): + def _add_uuid1(ctxt, request_spec, reservations): request_spec['instance_properties']['uuid'] = 'fake-uuid1' - def _add_uuid2(ctxt, request_spec): + def _add_uuid2(ctxt, request_spec, reservations): request_spec['instance_properties']['uuid'] = 'fake-uuid2' self.mox.StubOutWithMock(ctxt, 'elevated') @@ -92,8 +93,8 @@ class ChanceSchedulerTestCase(test_scheduler.SchedulerTestCase): self.driver.hosts_up(ctxt_elevated, 'compute').AndReturn( ['host1', 'host2', 'host3', 'host4']) random.random().AndReturn(.5) - self.driver.create_instance_db_entry(ctxt, - request_spec).WithSideEffects(_add_uuid1).AndReturn( + self.driver.create_instance_db_entry(ctxt, request_spec, + reservations).WithSideEffects(_add_uuid1).AndReturn( instance1) driver.cast_to_compute_host(ctxt, 'host3', 'run_instance', instance_uuid=instance1['uuid'], **fake_kwargs) @@ -103,8 +104,8 @@ class ChanceSchedulerTestCase(test_scheduler.SchedulerTestCase): self.driver.hosts_up(ctxt_elevated, 'compute').AndReturn( ['host1', 'host2', 'host3', 'host4']) random.random().AndReturn(.2) - self.driver.create_instance_db_entry(ctxt, - request_spec).WithSideEffects(_add_uuid2).AndReturn( + self.driver.create_instance_db_entry(ctxt, request_spec, + reservations).WithSideEffects(_add_uuid2).AndReturn( instance2) driver.cast_to_compute_host(ctxt, 'host1', 'run_instance', instance_uuid=instance2['uuid'], **fake_kwargs) @@ -112,7 +113,7 @@ class ChanceSchedulerTestCase(test_scheduler.SchedulerTestCase): self.mox.ReplayAll() result = self.driver.schedule_run_instance(ctxt, request_spec, - *fake_args, **fake_kwargs) + reservations, *fake_args, **fake_kwargs) expected = [instance1_encoded, instance2_encoded] self.assertEqual(result, expected) @@ -128,7 +129,7 @@ class ChanceSchedulerTestCase(test_scheduler.SchedulerTestCase): # stubbing it. def _add_uuid(num): """Return a function that adds the provided uuid number.""" - def _add_uuid_num(_, spec): + def _add_uuid_num(_, spec, reservations): spec['instance_properties']['uuid'] = 'fake-uuid%d' % num return _add_uuid_num @@ -150,7 +151,7 @@ class ChanceSchedulerTestCase(test_scheduler.SchedulerTestCase): # instance 1 self.driver._schedule(ctxt, 'compute', request_spec).AndReturn('host') self.driver.create_instance_db_entry( - ctxt, mox.Func(_has_launch_index(0)) + ctxt, mox.Func(_has_launch_index(0)), None ).WithSideEffects(_add_uuid(1)).AndReturn(instance1) driver.cast_to_compute_host(ctxt, 'host', 'run_instance', instance_uuid=instance1['uuid']) @@ -158,14 +159,14 @@ class ChanceSchedulerTestCase(test_scheduler.SchedulerTestCase): # instance 2 self.driver._schedule(ctxt, 'compute', request_spec).AndReturn('host') self.driver.create_instance_db_entry( - ctxt, mox.Func(_has_launch_index(1)) + ctxt, mox.Func(_has_launch_index(1)), None ).WithSideEffects(_add_uuid(2)).AndReturn(instance2) driver.cast_to_compute_host(ctxt, 'host', 'run_instance', instance_uuid=instance2['uuid']) driver.encode_instance(instance2).AndReturn(instance2) self.mox.ReplayAll() - self.driver.schedule_run_instance(ctxt, request_spec) + self.driver.schedule_run_instance(ctxt, request_spec, None) def test_basic_schedule_run_instance_no_hosts(self): ctxt = context.RequestContext('fake', 'fake', False) diff --git a/nova/tests/scheduler/test_filter_scheduler.py b/nova/tests/scheduler/test_filter_scheduler.py index 0256f2aa3..168906bdf 100644 --- a/nova/tests/scheduler/test_filter_scheduler.py +++ b/nova/tests/scheduler/test_filter_scheduler.py @@ -51,7 +51,7 @@ class FilterSchedulerTestCase(test_scheduler.SchedulerTestCase): 'ephemeral_gb': 0}, 'instance_properties': {'project_id': 1}} self.assertRaises(exception.NoValidHost, sched.schedule_run_instance, - fake_context, request_spec) + fake_context, request_spec, None) def test_run_instance_non_admin(self): """Test creating an instance locally using run_instance, passing @@ -72,7 +72,7 @@ class FilterSchedulerTestCase(test_scheduler.SchedulerTestCase): request_spec = {'instance_type': {'memory_mb': 1, 'local_gb': 1}, 'instance_properties': {'project_id': 1}} self.assertRaises(exception.NoValidHost, sched.schedule_run_instance, - fake_context, request_spec) + fake_context, request_spec, None) self.assertTrue(self.was_admin) def test_schedule_bad_topic(self): @@ -117,14 +117,16 @@ class FilterSchedulerTestCase(test_scheduler.SchedulerTestCase): # instance 1 self.driver._provision_resource( ctxt, 'host1', - mox.Func(_has_launch_index(0)), fake_kwargs).AndReturn(instance1) + mox.Func(_has_launch_index(0)), None, + fake_kwargs).AndReturn(instance1) # instance 2 self.driver._provision_resource( ctxt, 'host2', - mox.Func(_has_launch_index(1)), fake_kwargs).AndReturn(instance2) + mox.Func(_has_launch_index(1)), None, + fake_kwargs).AndReturn(instance2) self.mox.ReplayAll() - self.driver.schedule_run_instance(context_fake, request_spec, + self.driver.schedule_run_instance(context_fake, request_spec, None, **fake_kwargs) def test_schedule_happy_day(self): diff --git a/nova/tests/scheduler/test_rpcapi.py b/nova/tests/scheduler/test_rpcapi.py index 3f5a77fac..3617cecdf 100644 --- a/nova/tests/scheduler/test_rpcapi.py +++ b/nova/tests/scheduler/test_rpcapi.py @@ -68,14 +68,16 @@ class SchedulerRpcAPITestCase(test.TestCase): topic='fake_topic', request_spec='fake_request_spec', admin_password='pw', injected_files='fake_injected_files', requested_networks='fake_requested_networks', - is_first_time=True, filter_properties='fake_filter_properties') + is_first_time=True, filter_properties='fake_filter_properties', + reservations=None) def test_run_instance_cast(self): self._test_scheduler_api('run_instance', rpc_method='cast', topic='fake_topic', request_spec='fake_request_spec', admin_password='pw', injected_files='fake_injected_files', requested_networks='fake_requested_networks', - is_first_time=True, filter_properties='fake_filter_properties') + is_first_time=True, filter_properties='fake_filter_properties', + reservations=None) def test_prep_resize(self): self._test_scheduler_api('prep_resize', rpc_method='cast', diff --git a/nova/tests/scheduler/test_scheduler.py b/nova/tests/scheduler/test_scheduler.py index a662d6930..23b553d64 100644 --- a/nova/tests/scheduler/test_scheduler.py +++ b/nova/tests/scheduler/test_scheduler.py @@ -389,10 +389,10 @@ class SchedulerTestCase(test.TestCase): self.driver.compute_api.create_db_entry_for_new_instance( self.context, instance_type, image, base_options, security_group, - block_device_mapping).AndReturn(fake_instance) + block_device_mapping, None).AndReturn(fake_instance) self.mox.ReplayAll() instance = self.driver.create_instance_db_entry(self.context, - request_spec) + request_spec, None) self.mox.VerifyAll() self.assertEqual(instance, fake_instance) @@ -407,7 +407,7 @@ class SchedulerTestCase(test.TestCase): self.mox.ReplayAll() instance = self.driver.create_instance_db_entry(self.context, - request_spec) + request_spec, None) self.assertEqual(instance, fake_instance) def _live_migration_instance(self): diff --git a/nova/tests/test_quota.py b/nova/tests/test_quota.py index d4005fe98..4bb0e8b2e 100644 --- a/nova/tests/test_quota.py +++ b/nova/tests/test_quota.py @@ -297,7 +297,8 @@ class OldQuotaTestCase(test.TestCase): scheduler = scheduler_driver.Scheduler instance = scheduler().create_instance_db_entry( context, - msg['args']['request_spec']) + msg['args']['request_spec'], + None) return [scheduler_driver.encode_instance(instance)] else: return orig_rpc_call(context, topic, msg) @@ -1840,7 +1841,10 @@ class QuotaReserveSqlAlchemyTestCase(test.TestCase): def sync(context, project_id, session): self.sync_called.add(res_name) if res_name in self.usages: - return {res_name: self.usages[res_name].in_use - 1} + if self.usages[res_name].in_use < 0: + return {res_name: 2} + else: + return {res_name: self.usages[res_name].in_use - 1} return {res_name: 0} return sync @@ -2008,6 +2012,57 @@ class QuotaReserveSqlAlchemyTestCase(test.TestCase): delta=2 * 1024), ]) + def test_quota_reserve_negative_in_use(self): + self.init_usage('test_project', 'instances', -1, 0, until_refresh=1) + self.init_usage('test_project', 'cores', -1, 0, until_refresh=1) + self.init_usage('test_project', 'ram', -1, 0, until_refresh=1) + context = FakeContext('test_project', 'test_class') + quotas = dict( + instances=5, + cores=10, + ram=10 * 1024, + ) + deltas = dict( + instances=2, + cores=4, + ram=2 * 1024, + ) + result = sqa_api.quota_reserve(context, self.resources, quotas, + deltas, self.expire, 5, 0) + + self.assertEqual(self.sync_called, set(['instances', 'cores', 'ram'])) + self.compare_usage(self.usages, [ + dict(resource='instances', + project_id='test_project', + in_use=2, + reserved=2, + until_refresh=5), + dict(resource='cores', + project_id='test_project', + in_use=2, + reserved=4, + until_refresh=5), + dict(resource='ram', + project_id='test_project', + in_use=2, + reserved=2 * 1024, + until_refresh=5), + ]) + self.assertEqual(self.usages_created, {}) + self.compare_reservation(result, [ + dict(resource='instances', + usage_id=self.usages['instances'], + project_id='test_project', + delta=2), + dict(resource='cores', + usage_id=self.usages['cores'], + project_id='test_project', + delta=4), + dict(resource='ram', + usage_id=self.usages['ram'], + delta=2 * 1024), + ]) + def test_quota_reserve_until_refresh(self): self.init_usage('test_project', 'instances', 3, 0, until_refresh=1) self.init_usage('test_project', 'cores', 3, 0, until_refresh=1) @@ -2181,10 +2236,8 @@ class QuotaReserveSqlAlchemyTestCase(test.TestCase): cores=-4, ram=-2 * 1024, ) - self.assertRaises(exception.InvalidQuotaValue, - sqa_api.quota_reserve, - context, self.resources, quotas, - deltas, self.expire, 0, 0) + result = sqa_api.quota_reserve(context, self.resources, quotas, + deltas, self.expire, 0, 0) self.assertEqual(self.sync_called, set([])) self.compare_usage(self.usages, [ @@ -2205,7 +2258,19 @@ class QuotaReserveSqlAlchemyTestCase(test.TestCase): until_refresh=None), ]) self.assertEqual(self.usages_created, {}) - self.assertEqual(self.reservations_created, {}) + self.compare_reservation(result, [ + dict(resource='instances', + usage_id=self.usages['instances'], + project_id='test_project', + delta=-2), + dict(resource='cores', + usage_id=self.usages['cores'], + project_id='test_project', + delta=-4), + dict(resource='ram', + usage_id=self.usages['ram'], + delta=-2 * 1024), + ]) def test_quota_reserve_overs(self): self.init_usage('test_project', 'instances', 4, 0) diff --git a/nova/tests/test_volume.py b/nova/tests/test_volume.py index 607b0d49c..f9b54badc 100644 --- a/nova/tests/test_volume.py +++ b/nova/tests/test_volume.py @@ -32,10 +32,12 @@ from nova import log as logging from nova.notifier import test_notifier from nova.openstack.common import importutils import nova.policy +from nova import quota from nova import rpc from nova import test import nova.volume.api +QUOTAS = quota.QUOTAS FLAGS = flags.FLAGS LOG = logging.getLogger(__name__) @@ -90,6 +92,20 @@ class VolumeTestCase(test.TestCase): def test_create_delete_volume(self): """Test volume can be created and deleted.""" + # Need to stub out reserve, commit, and rollback + def fake_reserve(context, expire=None, **deltas): + return ["RESERVATION"] + + def fake_commit(context, reservations): + pass + + def fake_rollback(context, reservations): + pass + + self.stubs.Set(QUOTAS, "reserve", fake_reserve) + self.stubs.Set(QUOTAS, "commit", fake_commit) + self.stubs.Set(QUOTAS, "rollback", fake_rollback) + volume = self._create_volume() volume_id = volume['id'] self.assertEquals(len(test_notifier.NOTIFICATIONS), 0) |