442
661
def test_allowed_injected_file_path_bytes(self):
443
662
self.assertEqual(
444
663
quota.allowed_injected_file_path_bytes(self.context),
445
FLAGS.quota_max_injected_file_path_bytes)
664
FLAGS.quota_injected_file_path_bytes)
447
666
def test_max_injected_file_path_bytes(self):
448
max = FLAGS.quota_max_injected_file_path_bytes
667
max = FLAGS.quota_injected_file_path_bytes
449
668
path = ''.join(['a' for i in xrange(max)])
450
669
files = [(path, 'config = quotatest')]
451
670
self._create_with_injected_files(files) # no QuotaError
453
672
def test_too_many_injected_file_path_bytes(self):
454
max = FLAGS.quota_max_injected_file_path_bytes
673
max = FLAGS.quota_injected_file_path_bytes
455
674
path = ''.join(['a' for i in xrange(max + 1)])
456
675
files = [(path, 'config = quotatest')]
457
676
self.assertRaises(exception.QuotaError,
458
677
self._create_with_injected_files, files)
679
def test_quota_class_unlimited(self):
680
self.flags(quota_floating_ips=10)
681
items = quota.allowed_floating_ips(self.context, 10)
682
self.assertEqual(items, 10)
683
self.context.quota_class = 'foo'
684
db.quota_class_create(self.context, 'foo', 'floating_ips', -1)
685
items = quota.allowed_floating_ips(self.context, 100)
686
self.assertEqual(items, 100)
689
class FakeContext(object):
690
def __init__(self, project_id, quota_class):
691
self.is_admin = False
692
self.user_id = 'fake_user'
693
self.project_id = project_id
694
self.quota_class = quota_class
697
elevated = self.__class__(self.project_id, self.quota_class)
698
elevated.is_admin = True
702
class FakeDriver(object):
703
def __init__(self, by_project=None, by_class=None, reservations=None):
705
self.by_project = by_project or {}
706
self.by_class = by_class or {}
707
self.reservations = reservations or []
709
def get_by_project(self, context, project_id, resource):
710
self.called.append(('get_by_project', context, project_id, resource))
712
return self.by_project[project_id][resource]
714
raise exception.ProjectQuotaNotFound(project_id=project_id)
716
def get_by_class(self, context, quota_class, resource):
717
self.called.append(('get_by_class', context, quota_class, resource))
719
return self.by_class[quota_class][resource]
721
raise exception.QuotaClassNotFound(class_name=quota_class)
723
def get_defaults(self, context, resources):
724
self.called.append(('get_defaults', context, resources))
727
def get_class_quotas(self, context, resources, quota_class,
729
self.called.append(('get_class_quotas', context, resources,
730
quota_class, defaults))
733
def get_project_quotas(self, context, resources, project_id,
734
quota_class=None, defaults=True, usages=True):
735
self.called.append(('get_project_quotas', context, resources,
736
project_id, quota_class, defaults, usages))
739
def limit_check(self, context, resources, values):
740
self.called.append(('limit_check', context, resources, values))
742
def reserve(self, context, resources, deltas, expire=None):
743
self.called.append(('reserve', context, resources, deltas, expire))
744
return self.reservations
746
def commit(self, context, reservations):
747
self.called.append(('commit', context, reservations))
749
def rollback(self, context, reservations):
750
self.called.append(('rollback', context, reservations))
752
def destroy_all_by_project(self, context, project_id):
753
self.called.append(('destroy_all_by_project', context, project_id))
755
def expire(self, context):
756
self.called.append(('expire', context))
759
class BaseResourceTestCase(test.TestCase):
760
def test_no_flag(self):
761
resource = quota.BaseResource('test_resource')
763
self.assertEqual(resource.name, 'test_resource')
764
self.assertEqual(resource.flag, None)
765
self.assertEqual(resource.default, -1)
767
def test_with_flag(self):
768
# We know this flag exists, so use it...
769
self.flags(quota_instances=10)
770
resource = quota.BaseResource('test_resource', 'quota_instances')
772
self.assertEqual(resource.name, 'test_resource')
773
self.assertEqual(resource.flag, 'quota_instances')
774
self.assertEqual(resource.default, 10)
776
def test_with_flag_no_quota(self):
777
self.flags(quota_instances=-1)
778
resource = quota.BaseResource('test_resource', 'quota_instances')
780
self.assertEqual(resource.name, 'test_resource')
781
self.assertEqual(resource.flag, 'quota_instances')
782
self.assertEqual(resource.default, -1)
784
def test_quota_no_project_no_class(self):
785
self.flags(quota_instances=10)
786
resource = quota.BaseResource('test_resource', 'quota_instances')
787
driver = FakeDriver()
788
context = FakeContext(None, None)
789
quota_value = resource.quota(driver, context)
791
self.assertEqual(quota_value, 10)
793
def test_quota_with_project_no_class(self):
794
self.flags(quota_instances=10)
795
resource = quota.BaseResource('test_resource', 'quota_instances')
796
driver = FakeDriver(by_project=dict(
797
test_project=dict(test_resource=15),
799
context = FakeContext('test_project', None)
800
quota_value = resource.quota(driver, context)
802
self.assertEqual(quota_value, 15)
804
def test_quota_no_project_with_class(self):
805
self.flags(quota_instances=10)
806
resource = quota.BaseResource('test_resource', 'quota_instances')
807
driver = FakeDriver(by_class=dict(
808
test_class=dict(test_resource=20),
810
context = FakeContext(None, 'test_class')
811
quota_value = resource.quota(driver, context)
813
self.assertEqual(quota_value, 20)
815
def test_quota_with_project_with_class(self):
816
self.flags(quota_instances=10)
817
resource = quota.BaseResource('test_resource', 'quota_instances')
818
driver = FakeDriver(by_project=dict(
819
test_project=dict(test_resource=15),
822
test_class=dict(test_resource=20),
824
context = FakeContext('test_project', 'test_class')
825
quota_value = resource.quota(driver, context)
827
self.assertEqual(quota_value, 15)
829
def test_quota_override_project_with_class(self):
830
self.flags(quota_instances=10)
831
resource = quota.BaseResource('test_resource', 'quota_instances')
832
driver = FakeDriver(by_project=dict(
833
test_project=dict(test_resource=15),
834
override_project=dict(test_resource=20),
836
context = FakeContext('test_project', 'test_class')
837
quota_value = resource.quota(driver, context,
838
project_id='override_project')
840
self.assertEqual(quota_value, 20)
842
def test_quota_with_project_override_class(self):
843
self.flags(quota_instances=10)
844
resource = quota.BaseResource('test_resource', 'quota_instances')
845
driver = FakeDriver(by_class=dict(
846
test_class=dict(test_resource=15),
847
override_class=dict(test_resource=20),
849
context = FakeContext('test_project', 'test_class')
850
quota_value = resource.quota(driver, context,
851
quota_class='override_class')
853
self.assertEqual(quota_value, 20)
856
class QuotaEngineTestCase(test.TestCase):
858
quota_obj = quota.QuotaEngine()
860
self.assertEqual(quota_obj._resources, {})
861
self.assertTrue(isinstance(quota_obj._driver, quota.DbQuotaDriver))
863
def test_init_override_string(self):
864
quota_obj = quota.QuotaEngine(
865
quota_driver_class='nova.tests.test_quota.FakeDriver')
867
self.assertEqual(quota_obj._resources, {})
868
self.assertTrue(isinstance(quota_obj._driver, FakeDriver))
870
def test_init_override_obj(self):
871
quota_obj = quota.QuotaEngine(quota_driver_class=FakeDriver)
873
self.assertEqual(quota_obj._resources, {})
874
self.assertEqual(quota_obj._driver, FakeDriver)
876
def test_register_resource(self):
877
quota_obj = quota.QuotaEngine()
878
resource = quota.AbsoluteResource('test_resource')
879
quota_obj.register_resource(resource)
881
self.assertEqual(quota_obj._resources, dict(test_resource=resource))
883
def test_register_resources(self):
884
quota_obj = quota.QuotaEngine()
886
quota.AbsoluteResource('test_resource1'),
887
quota.AbsoluteResource('test_resource2'),
888
quota.AbsoluteResource('test_resource3'),
890
quota_obj.register_resources(resources)
892
self.assertEqual(quota_obj._resources, dict(
893
test_resource1=resources[0],
894
test_resource2=resources[1],
895
test_resource3=resources[2],
898
def test_sync_predeclared(self):
899
quota_obj = quota.QuotaEngine()
901
def spam(*args, **kwargs):
904
resource = quota.ReservableResource('test_resource', spam)
905
quota_obj.register_resource(resource)
907
self.assertEqual(resource.sync, spam)
909
def test_sync_multi(self):
910
quota_obj = quota.QuotaEngine()
912
def spam(*args, **kwargs):
916
quota.ReservableResource('test_resource1', spam),
917
quota.ReservableResource('test_resource2', spam),
918
quota.ReservableResource('test_resource3', spam),
919
quota.ReservableResource('test_resource4', spam),
921
quota_obj.register_resources(resources[:2])
923
self.assertEqual(resources[0].sync, spam)
924
self.assertEqual(resources[1].sync, spam)
925
self.assertEqual(resources[2].sync, spam)
926
self.assertEqual(resources[3].sync, spam)
928
def test_get_by_project(self):
929
context = FakeContext('test_project', 'test_class')
930
driver = FakeDriver(by_project=dict(
931
test_project=dict(test_resource=42)))
932
quota_obj = quota.QuotaEngine(quota_driver_class=driver)
933
result = quota_obj.get_by_project(context, 'test_project',
936
self.assertEqual(driver.called, [
937
('get_by_project', context, 'test_project', 'test_resource'),
939
self.assertEqual(result, 42)
941
def test_get_by_class(self):
942
context = FakeContext('test_project', 'test_class')
943
driver = FakeDriver(by_class=dict(
944
test_class=dict(test_resource=42)))
945
quota_obj = quota.QuotaEngine(quota_driver_class=driver)
946
result = quota_obj.get_by_class(context, 'test_class', 'test_resource')
948
self.assertEqual(driver.called, [
949
('get_by_class', context, 'test_class', 'test_resource'),
951
self.assertEqual(result, 42)
953
def _make_quota_obj(self, driver):
954
quota_obj = quota.QuotaEngine(quota_driver_class=driver)
956
quota.AbsoluteResource('test_resource4'),
957
quota.AbsoluteResource('test_resource3'),
958
quota.AbsoluteResource('test_resource2'),
959
quota.AbsoluteResource('test_resource1'),
961
quota_obj.register_resources(resources)
965
def test_get_defaults(self):
966
context = FakeContext(None, None)
967
driver = FakeDriver()
968
quota_obj = self._make_quota_obj(driver)
969
result = quota_obj.get_defaults(context)
971
self.assertEqual(driver.called, [
972
('get_defaults', context, quota_obj._resources),
974
self.assertEqual(result, quota_obj._resources)
976
def test_get_class_quotas(self):
977
context = FakeContext(None, None)
978
driver = FakeDriver()
979
quota_obj = self._make_quota_obj(driver)
980
result1 = quota_obj.get_class_quotas(context, 'test_class')
981
result2 = quota_obj.get_class_quotas(context, 'test_class', False)
983
self.assertEqual(driver.called, [
984
('get_class_quotas', context, quota_obj._resources,
986
('get_class_quotas', context, quota_obj._resources,
987
'test_class', False),
989
self.assertEqual(result1, quota_obj._resources)
990
self.assertEqual(result2, quota_obj._resources)
992
def test_get_project_quotas(self):
993
context = FakeContext(None, None)
994
driver = FakeDriver()
995
quota_obj = self._make_quota_obj(driver)
996
result1 = quota_obj.get_project_quotas(context, 'test_project')
997
result2 = quota_obj.get_project_quotas(context, 'test_project',
998
quota_class='test_class',
1002
self.assertEqual(driver.called, [
1003
('get_project_quotas', context, quota_obj._resources,
1004
'test_project', None, True, True),
1005
('get_project_quotas', context, quota_obj._resources,
1006
'test_project', 'test_class', False, False),
1008
self.assertEqual(result1, quota_obj._resources)
1009
self.assertEqual(result2, quota_obj._resources)
1011
def test_count_no_resource(self):
1012
context = FakeContext(None, None)
1013
driver = FakeDriver()
1014
quota_obj = self._make_quota_obj(driver)
1015
self.assertRaises(exception.QuotaResourceUnknown,
1016
quota_obj.count, context, 'test_resource5',
1019
def test_count_wrong_resource(self):
1020
context = FakeContext(None, None)
1021
driver = FakeDriver()
1022
quota_obj = self._make_quota_obj(driver)
1023
self.assertRaises(exception.QuotaResourceUnknown,
1024
quota_obj.count, context, 'test_resource1',
1027
def test_count(self):
1028
def fake_count(context, *args, **kwargs):
1029
self.assertEqual(args, (True,))
1030
self.assertEqual(kwargs, dict(foo='bar'))
1033
context = FakeContext(None, None)
1034
driver = FakeDriver()
1035
quota_obj = self._make_quota_obj(driver)
1036
quota_obj.register_resource(quota.CountableResource('test_resource5',
1038
result = quota_obj.count(context, 'test_resource5', True, foo='bar')
1040
self.assertEqual(result, 5)
1042
def test_limit_check(self):
1043
context = FakeContext(None, None)
1044
driver = FakeDriver()
1045
quota_obj = self._make_quota_obj(driver)
1046
quota_obj.limit_check(context, test_resource1=4, test_resource2=3,
1047
test_resource3=2, test_resource4=1)
1049
self.assertEqual(driver.called, [
1050
('limit_check', context, quota_obj._resources, dict(
1058
def test_reserve(self):
1059
context = FakeContext(None, None)
1060
driver = FakeDriver(reservations=[
1061
'resv-01', 'resv-02', 'resv-03', 'resv-04',
1063
quota_obj = self._make_quota_obj(driver)
1064
result1 = quota_obj.reserve(context, test_resource1=4,
1065
test_resource2=3, test_resource3=2,
1067
result2 = quota_obj.reserve(context, expire=3600,
1068
test_resource1=1, test_resource2=2,
1069
test_resource3=3, test_resource4=4)
1071
self.assertEqual(driver.called, [
1072
('reserve', context, quota_obj._resources, dict(
1078
('reserve', context, quota_obj._resources, dict(
1085
self.assertEqual(result1, [
1086
'resv-01', 'resv-02', 'resv-03', 'resv-04',
1088
self.assertEqual(result2, [
1089
'resv-01', 'resv-02', 'resv-03', 'resv-04',
1092
def test_commit(self):
1093
context = FakeContext(None, None)
1094
driver = FakeDriver()
1095
quota_obj = self._make_quota_obj(driver)
1096
quota_obj.commit(context, ['resv-01', 'resv-02', 'resv-03'])
1098
self.assertEqual(driver.called, [
1099
('commit', context, ['resv-01', 'resv-02', 'resv-03']),
1102
def test_rollback(self):
1103
context = FakeContext(None, None)
1104
driver = FakeDriver()
1105
quota_obj = self._make_quota_obj(driver)
1106
quota_obj.rollback(context, ['resv-01', 'resv-02', 'resv-03'])
1108
self.assertEqual(driver.called, [
1109
('rollback', context, ['resv-01', 'resv-02', 'resv-03']),
1112
def test_destroy_all_by_project(self):
1113
context = FakeContext(None, None)
1114
driver = FakeDriver()
1115
quota_obj = self._make_quota_obj(driver)
1116
quota_obj.destroy_all_by_project(context, 'test_project')
1118
self.assertEqual(driver.called, [
1119
('destroy_all_by_project', context, 'test_project'),
1122
def test_expire(self):
1123
context = FakeContext(None, None)
1124
driver = FakeDriver()
1125
quota_obj = self._make_quota_obj(driver)
1126
quota_obj.expire(context)
1128
self.assertEqual(driver.called, [
1129
('expire', context),
1132
def test_resources(self):
1133
quota_obj = self._make_quota_obj(None)
1135
self.assertEqual(quota_obj.resources,
1136
['test_resource1', 'test_resource2',
1137
'test_resource3', 'test_resource4'])
1140
class DbQuotaDriverTestCase(test.TestCase):
1142
super(DbQuotaDriverTestCase, self).setUp()
1144
self.flags(quota_instances=10,
1146
quota_ram=50 * 1024,
1148
quota_gigabytes=1000,
1149
quota_floating_ips=10,
1150
quota_metadata_items=128,
1151
quota_injected_files=5,
1152
quota_injected_file_content_bytes=10 * 1024,
1153
quota_injected_file_path_bytes=255,
1154
quota_security_groups=10,
1155
quota_security_group_rules=20,
1156
reservation_expire=86400,
1161
self.driver = quota.DbQuotaDriver()
1165
utils.set_time_override()
1168
utils.clear_time_override()
1169
super(DbQuotaDriverTestCase, self).tearDown()
1171
def test_get_defaults(self):
1172
# Use our pre-defined resources
1173
result = self.driver.get_defaults(None, quota.QUOTAS._resources)
1175
self.assertEqual(result, dict(
1184
injected_file_content_bytes=10 * 1024,
1185
injected_file_path_bytes=255,
1187
security_group_rules=20,
1191
def _stub_quota_class_get_all_by_name(self):
1192
# Stub out quota_class_get_all_by_name
1193
def fake_qcgabn(context, quota_class):
1194
self.calls.append('quota_class_get_all_by_name')
1195
self.assertEqual(quota_class, 'test_class')
1201
injected_file_content_bytes=5 * 1024,
1203
self.stubs.Set(db, 'quota_class_get_all_by_name', fake_qcgabn)
1205
def test_get_class_quotas(self):
1206
self._stub_quota_class_get_all_by_name()
1207
result = self.driver.get_class_quotas(None, quota.QUOTAS._resources,
1210
self.assertEqual(self.calls, ['quota_class_get_all_by_name'])
1211
self.assertEqual(result, dict(
1220
injected_file_content_bytes=5 * 1024,
1221
injected_file_path_bytes=255,
1223
security_group_rules=20,
1227
def test_get_class_quotas_no_defaults(self):
1228
self._stub_quota_class_get_all_by_name()
1229
result = self.driver.get_class_quotas(None, quota.QUOTAS._resources,
1230
'test_class', False)
1232
self.assertEqual(self.calls, ['quota_class_get_all_by_name'])
1233
self.assertEqual(result, dict(
1238
injected_file_content_bytes=5 * 1024,
1241
def _stub_get_by_project(self):
1242
def fake_qgabp(context, project_id):
1243
self.calls.append('quota_get_all_by_project')
1244
self.assertEqual(project_id, 'test_project')
1249
injected_file_path_bytes=127,
1252
def fake_qugabp(context, project_id):
1253
self.calls.append('quota_usage_get_all_by_project')
1254
self.assertEqual(project_id, 'test_project')
1256
instances=dict(in_use=2, reserved=2),
1257
cores=dict(in_use=4, reserved=4),
1258
ram=dict(in_use=10 * 1024, reserved=0),
1259
volumes=dict(in_use=2, reserved=0),
1260
gigabytes=dict(in_use=10, reserved=0),
1261
floating_ips=dict(in_use=2, reserved=0),
1262
metadata_items=dict(in_use=0, reserved=0),
1263
injected_files=dict(in_use=0, reserved=0),
1264
injected_file_content_bytes=dict(in_use=0, reserved=0),
1265
injected_file_path_bytes=dict(in_use=0, reserved=0),
1268
self.stubs.Set(db, 'quota_get_all_by_project', fake_qgabp)
1269
self.stubs.Set(db, 'quota_usage_get_all_by_project', fake_qugabp)
1271
self._stub_quota_class_get_all_by_name()
1273
def test_get_project_quotas(self):
1274
self._stub_get_by_project()
1275
result = self.driver.get_project_quotas(
1276
FakeContext('test_project', 'test_class'),
1277
quota.QUOTAS._resources, 'test_project')
1279
self.assertEqual(self.calls, [
1280
'quota_get_all_by_project',
1281
'quota_usage_get_all_by_project',
1282
'quota_class_get_all_by_name',
1284
self.assertEqual(result, dict(
1315
metadata_items=dict(
1320
injected_files=dict(
1325
injected_file_content_bytes=dict(
1330
injected_file_path_bytes=dict(
1335
security_groups=dict(
1340
security_group_rules=dict(
1352
def test_get_project_quotas_alt_context_no_class(self):
1353
self._stub_get_by_project()
1354
result = self.driver.get_project_quotas(
1355
FakeContext('other_project', 'other_class'),
1356
quota.QUOTAS._resources, 'test_project')
1358
self.assertEqual(self.calls, [
1359
'quota_get_all_by_project',
1360
'quota_usage_get_all_by_project',
1362
self.assertEqual(result, dict(
1393
metadata_items=dict(
1398
injected_files=dict(
1403
injected_file_content_bytes=dict(
1408
injected_file_path_bytes=dict(
1413
security_groups=dict(
1418
security_group_rules=dict(
1430
def test_get_project_quotas_alt_context_with_class(self):
1431
self._stub_get_by_project()
1432
result = self.driver.get_project_quotas(
1433
FakeContext('other_project', 'other_class'),
1434
quota.QUOTAS._resources, 'test_project', quota_class='test_class')
1436
self.assertEqual(self.calls, [
1437
'quota_get_all_by_project',
1438
'quota_usage_get_all_by_project',
1439
'quota_class_get_all_by_name',
1441
self.assertEqual(result, dict(
1472
metadata_items=dict(
1477
injected_files=dict(
1482
injected_file_content_bytes=dict(
1487
injected_file_path_bytes=dict(
1492
security_groups=dict(
1497
security_group_rules=dict(
1509
def test_get_project_quotas_no_defaults(self):
1510
self._stub_get_by_project()
1511
result = self.driver.get_project_quotas(
1512
FakeContext('test_project', 'test_class'),
1513
quota.QUOTAS._resources, 'test_project', defaults=False)
1515
self.assertEqual(self.calls, [
1516
'quota_get_all_by_project',
1517
'quota_usage_get_all_by_project',
1518
'quota_class_get_all_by_name',
1520
self.assertEqual(result, dict(
1531
injected_files=dict(
1536
injected_file_path_bytes=dict(
1543
def test_get_project_quotas_no_usages(self):
1544
self._stub_get_by_project()
1545
result = self.driver.get_project_quotas(
1546
FakeContext('test_project', 'test_class'),
1547
quota.QUOTAS._resources, 'test_project', usages=False)
1549
self.assertEqual(self.calls, [
1550
'quota_get_all_by_project',
1551
'quota_class_get_all_by_name',
1553
self.assertEqual(result, dict(
1572
metadata_items=dict(
1575
injected_files=dict(
1578
injected_file_content_bytes=dict(
1581
injected_file_path_bytes=dict(
1584
security_groups=dict(
1587
security_group_rules=dict(
1595
def _stub_get_project_quotas(self):
1596
def fake_get_project_quotas(context, resources, project_id,
1597
quota_class=None, defaults=True,
1599
self.calls.append('get_project_quotas')
1600
return dict((k, dict(limit=v.default))
1601
for k, v in resources.items())
1603
self.stubs.Set(self.driver, 'get_project_quotas',
1604
fake_get_project_quotas)
1606
def test_get_quotas_has_sync_unknown(self):
1607
self._stub_get_project_quotas()
1608
self.assertRaises(exception.QuotaResourceUnknown,
1609
self.driver._get_quotas,
1610
None, quota.QUOTAS._resources,
1612
self.assertEqual(self.calls, [])
1614
def test_get_quotas_no_sync_unknown(self):
1615
self._stub_get_project_quotas()
1616
self.assertRaises(exception.QuotaResourceUnknown,
1617
self.driver._get_quotas,
1618
None, quota.QUOTAS._resources,
1620
self.assertEqual(self.calls, [])
1622
def test_get_quotas_has_sync_no_sync_resource(self):
1623
self._stub_get_project_quotas()
1624
self.assertRaises(exception.QuotaResourceUnknown,
1625
self.driver._get_quotas,
1626
None, quota.QUOTAS._resources,
1627
['metadata_items'], True)
1628
self.assertEqual(self.calls, [])
1630
def test_get_quotas_no_sync_has_sync_resource(self):
1631
self._stub_get_project_quotas()
1632
self.assertRaises(exception.QuotaResourceUnknown,
1633
self.driver._get_quotas,
1634
None, quota.QUOTAS._resources,
1635
['instances'], False)
1636
self.assertEqual(self.calls, [])
1638
def test_get_quotas_has_sync(self):
1639
self._stub_get_project_quotas()
1640
result = self.driver._get_quotas(FakeContext('test_project',
1642
quota.QUOTAS._resources,
1643
['instances', 'cores', 'ram',
1644
'volumes', 'gigabytes',
1645
'floating_ips', 'security_groups'],
1648
self.assertEqual(self.calls, ['get_project_quotas'])
1649
self.assertEqual(result, dict(
1659
def test_get_quotas_no_sync(self):
1660
self._stub_get_project_quotas()
1661
result = self.driver._get_quotas(FakeContext('test_project',
1663
quota.QUOTAS._resources,
1664
['metadata_items', 'injected_files',
1665
'injected_file_content_bytes',
1666
'injected_file_path_bytes',
1667
'security_group_rules'], False)
1669
self.assertEqual(self.calls, ['get_project_quotas'])
1670
self.assertEqual(result, dict(
1673
injected_file_content_bytes=10 * 1024,
1674
injected_file_path_bytes=255,
1675
security_group_rules=20,
1678
def test_limit_check_under(self):
1679
self._stub_get_project_quotas()
1680
self.assertRaises(exception.InvalidQuotaValue,
1681
self.driver.limit_check,
1682
FakeContext('test_project', 'test_class'),
1683
quota.QUOTAS._resources,
1684
dict(metadata_items=-1))
1686
def test_limit_check_over(self):
1687
self._stub_get_project_quotas()
1688
self.assertRaises(exception.OverQuota,
1689
self.driver.limit_check,
1690
FakeContext('test_project', 'test_class'),
1691
quota.QUOTAS._resources,
1692
dict(metadata_items=129))
1694
def test_limit_check_unlimited(self):
1695
self.flags(quota_metadata_items=-1)
1696
self._stub_get_project_quotas()
1697
self.driver.limit_check(FakeContext('test_project', 'test_class'),
1698
quota.QUOTAS._resources,
1699
dict(metadata_items=32767))
1701
def test_limit_check(self):
1702
self._stub_get_project_quotas()
1703
self.driver.limit_check(FakeContext('test_project', 'test_class'),
1704
quota.QUOTAS._resources,
1705
dict(metadata_items=128))
1707
def _stub_quota_reserve(self):
1708
def fake_quota_reserve(context, resources, quotas, deltas, expire,
1709
until_refresh, max_age):
1710
self.calls.append(('quota_reserve', expire, until_refresh,
1712
return ['resv-1', 'resv-2', 'resv-3']
1713
self.stubs.Set(db, 'quota_reserve', fake_quota_reserve)
1715
def test_reserve_bad_expire(self):
1716
self._stub_get_project_quotas()
1717
self._stub_quota_reserve()
1718
self.assertRaises(exception.InvalidReservationExpiration,
1719
self.driver.reserve,
1720
FakeContext('test_project', 'test_class'),
1721
quota.QUOTAS._resources,
1722
dict(instances=2), expire='invalid')
1723
self.assertEqual(self.calls, [])
1725
def test_reserve_default_expire(self):
1726
self._stub_get_project_quotas()
1727
self._stub_quota_reserve()
1728
result = self.driver.reserve(FakeContext('test_project', 'test_class'),
1729
quota.QUOTAS._resources,
1732
expire = utils.utcnow() + datetime.timedelta(seconds=86400)
1733
self.assertEqual(self.calls, [
1734
'get_project_quotas',
1735
('quota_reserve', expire, 0, 0),
1737
self.assertEqual(result, ['resv-1', 'resv-2', 'resv-3'])
1739
def test_reserve_int_expire(self):
1740
self._stub_get_project_quotas()
1741
self._stub_quota_reserve()
1742
result = self.driver.reserve(FakeContext('test_project', 'test_class'),
1743
quota.QUOTAS._resources,
1744
dict(instances=2), expire=3600)
1746
expire = utils.utcnow() + datetime.timedelta(seconds=3600)
1747
self.assertEqual(self.calls, [
1748
'get_project_quotas',
1749
('quota_reserve', expire, 0, 0),
1751
self.assertEqual(result, ['resv-1', 'resv-2', 'resv-3'])
1753
def test_reserve_timedelta_expire(self):
1754
self._stub_get_project_quotas()
1755
self._stub_quota_reserve()
1756
expire_delta = datetime.timedelta(seconds=60)
1757
result = self.driver.reserve(FakeContext('test_project', 'test_class'),
1758
quota.QUOTAS._resources,
1759
dict(instances=2), expire=expire_delta)
1761
expire = utils.utcnow() + expire_delta
1762
self.assertEqual(self.calls, [
1763
'get_project_quotas',
1764
('quota_reserve', expire, 0, 0),
1766
self.assertEqual(result, ['resv-1', 'resv-2', 'resv-3'])
1768
def test_reserve_datetime_expire(self):
1769
self._stub_get_project_quotas()
1770
self._stub_quota_reserve()
1771
expire = utils.utcnow() + datetime.timedelta(seconds=120)
1772
result = self.driver.reserve(FakeContext('test_project', 'test_class'),
1773
quota.QUOTAS._resources,
1774
dict(instances=2), expire=expire)
1776
self.assertEqual(self.calls, [
1777
'get_project_quotas',
1778
('quota_reserve', expire, 0, 0),
1780
self.assertEqual(result, ['resv-1', 'resv-2', 'resv-3'])
1782
def test_reserve_until_refresh(self):
1783
self._stub_get_project_quotas()
1784
self._stub_quota_reserve()
1785
self.flags(until_refresh=500)
1786
expire = utils.utcnow() + datetime.timedelta(seconds=120)
1787
result = self.driver.reserve(FakeContext('test_project', 'test_class'),
1788
quota.QUOTAS._resources,
1789
dict(instances=2), expire=expire)
1791
self.assertEqual(self.calls, [
1792
'get_project_quotas',
1793
('quota_reserve', expire, 500, 0),
1795
self.assertEqual(result, ['resv-1', 'resv-2', 'resv-3'])
1797
def test_reserve_max_age(self):
1798
self._stub_get_project_quotas()
1799
self._stub_quota_reserve()
1800
self.flags(max_age=86400)
1801
expire = utils.utcnow() + datetime.timedelta(seconds=120)
1802
result = self.driver.reserve(FakeContext('test_project', 'test_class'),
1803
quota.QUOTAS._resources,
1804
dict(instances=2), expire=expire)
1806
self.assertEqual(self.calls, [
1807
'get_project_quotas',
1808
('quota_reserve', expire, 0, 86400),
1810
self.assertEqual(result, ['resv-1', 'resv-2', 'resv-3'])
1813
class FakeSession(object):
1817
def __enter__(self):
1820
def __exit__(self, exc_type, exc_value, exc_traceback):
1824
class FakeUsage(sqa_models.QuotaUsage):
1825
def save(self, *args, **kwargs):
1829
class QuotaReserveSqlAlchemyTestCase(test.TestCase):
1830
# nova.db.sqlalchemy.api.quota_reserve is so complex it needs its
1831
# own test case, and since it's a quota manipulator, this is the
1832
# best place to put it...
1835
super(QuotaReserveSqlAlchemyTestCase, self).setUp()
1837
self.sync_called = set()
1839
def make_sync(res_name):
1840
def sync(context, project_id, session):
1841
self.sync_called.add(res_name)
1842
if res_name in self.usages:
1843
return {res_name: self.usages[res_name].in_use - 1}
1844
return {res_name: 0}
1848
for res_name in ('instances', 'cores', 'ram'):
1849
res = quota.ReservableResource(res_name, make_sync(res_name))
1850
self.resources[res_name] = res
1852
self.expire = utils.utcnow() + datetime.timedelta(seconds=3600)
1855
self.usages_created = {}
1856
self.reservations_created = {}
1858
def fake_get_session():
1859
return FakeSession()
1861
def fake_get_quota_usages(context, session, keys):
1862
return self.usages.copy()
1864
def fake_quota_usage_create(context, project_id, resource, in_use,
1865
reserved, until_refresh, session=None,
1867
quota_usage_ref = self._make_quota_usage(
1868
project_id, resource, in_use, reserved, until_refresh,
1869
utils.utcnow(), utils.utcnow())
1871
self.usages_created[resource] = quota_usage_ref
1873
return quota_usage_ref
1875
def fake_reservation_create(context, uuid, usage_id, project_id,
1876
resource, delta, expire, session=None):
1877
reservation_ref = self._make_reservation(
1878
uuid, usage_id, project_id, resource, delta, expire,
1879
utils.utcnow(), utils.utcnow())
1881
self.reservations_created[resource] = reservation_ref
1883
return reservation_ref
1885
self.stubs.Set(sqa_api, 'get_session', fake_get_session)
1886
self.stubs.Set(sqa_api, '_get_quota_usages', fake_get_quota_usages)
1887
self.stubs.Set(sqa_api, 'quota_usage_create', fake_quota_usage_create)
1888
self.stubs.Set(sqa_api, 'reservation_create', fake_reservation_create)
1890
utils.set_time_override()
1892
def _make_quota_usage(self, project_id, resource, in_use, reserved,
1893
until_refresh, created_at, updated_at):
1894
quota_usage_ref = FakeUsage()
1895
quota_usage_ref.id = len(self.usages) + len(self.usages_created)
1896
quota_usage_ref.project_id = project_id
1897
quota_usage_ref.resource = resource
1898
quota_usage_ref.in_use = in_use
1899
quota_usage_ref.reserved = reserved
1900
quota_usage_ref.until_refresh = until_refresh
1901
quota_usage_ref.created_at = created_at
1902
quota_usage_ref.updated_at = updated_at
1903
quota_usage_ref.deleted_at = None
1904
quota_usage_ref.deleted = False
1906
return quota_usage_ref
1908
def init_usage(self, project_id, resource, in_use, reserved,
1909
until_refresh=None, created_at=None, updated_at=None):
1910
if created_at is None:
1911
created_at = utils.utcnow()
1912
if updated_at is None:
1913
updated_at = utils.utcnow()
1915
quota_usage_ref = self._make_quota_usage(project_id, resource, in_use,
1916
reserved, until_refresh,
1917
created_at, updated_at)
1919
self.usages[resource] = quota_usage_ref
1921
def compare_usage(self, usage_dict, expected):
1922
for usage in expected:
1923
resource = usage['resource']
1924
for key, value in usage.items():
1925
actual = getattr(usage_dict[resource], key)
1926
self.assertEqual(actual, value,
1927
"%s != %s on usage for resource %s" %
1928
(actual, value, resource))
1930
def _make_reservation(self, uuid, usage_id, project_id, resource,
1931
delta, expire, created_at, updated_at):
1932
reservation_ref = sqa_models.Reservation()
1933
reservation_ref.id = len(self.reservations_created)
1934
reservation_ref.uuid = uuid
1935
reservation_ref.usage_id = usage_id
1936
reservation_ref.project_id = project_id
1937
reservation_ref.resource = resource
1938
reservation_ref.delta = delta
1939
reservation_ref.expire = expire
1940
reservation_ref.created_at = created_at
1941
reservation_ref.updated_at = updated_at
1942
reservation_ref.deleted_at = None
1943
reservation_ref.deleted = False
1945
return reservation_ref
1947
def compare_reservation(self, reservations, expected):
1948
reservations = set(reservations)
1949
for resv in expected:
1950
resource = resv['resource']
1951
resv_obj = self.reservations_created[resource]
1953
self.assertIn(resv_obj.uuid, reservations)
1954
reservations.discard(resv_obj.uuid)
1956
for key, value in resv.items():
1957
actual = getattr(resv_obj, key)
1958
self.assertEqual(actual, value,
1959
"%s != %s on reservation for resource %s" %
1960
(actual, value, resource))
1962
self.assertEqual(len(reservations), 0)
1964
def test_quota_reserve_create_usages(self):
1965
context = FakeContext('test_project', 'test_class')
1976
result = sqa_api.quota_reserve(context, self.resources, quotas,
1977
deltas, self.expire, 0, 0)
1979
self.assertEqual(self.sync_called, set(['instances', 'cores', 'ram']))
1980
self.compare_usage(self.usages_created, [
1981
dict(resource='instances',
1982
project_id='test_project',
1985
until_refresh=None),
1986
dict(resource='cores',
1987
project_id='test_project',
1990
until_refresh=None),
1991
dict(resource='ram',
1992
project_id='test_project',
1995
until_refresh=None),
1997
self.compare_reservation(result, [
1998
dict(resource='instances',
1999
usage_id=self.usages_created['instances'],
2000
project_id='test_project',
2002
dict(resource='cores',
2003
usage_id=self.usages_created['cores'],
2004
project_id='test_project',
2006
dict(resource='ram',
2007
usage_id=self.usages_created['ram'],
2011
def test_quota_reserve_until_refresh(self):
2012
self.init_usage('test_project', 'instances', 3, 0, until_refresh=1)
2013
self.init_usage('test_project', 'cores', 3, 0, until_refresh=1)
2014
self.init_usage('test_project', 'ram', 3, 0, until_refresh=1)
2015
context = FakeContext('test_project', 'test_class')
2026
result = sqa_api.quota_reserve(context, self.resources, quotas,
2027
deltas, self.expire, 5, 0)
2029
self.assertEqual(self.sync_called, set(['instances', 'cores', 'ram']))
2030
self.compare_usage(self.usages, [
2031
dict(resource='instances',
2032
project_id='test_project',
2036
dict(resource='cores',
2037
project_id='test_project',
2041
dict(resource='ram',
2042
project_id='test_project',
2047
self.assertEqual(self.usages_created, {})
2048
self.compare_reservation(result, [
2049
dict(resource='instances',
2050
usage_id=self.usages['instances'],
2051
project_id='test_project',
2053
dict(resource='cores',
2054
usage_id=self.usages['cores'],
2055
project_id='test_project',
2057
dict(resource='ram',
2058
usage_id=self.usages['ram'],
2062
def test_quota_reserve_max_age(self):
2064
record_created = utils.utcnow() - datetime.timedelta(seconds=max_age)
2065
self.init_usage('test_project', 'instances', 3, 0,
2066
created_at=record_created, updated_at=record_created)
2067
self.init_usage('test_project', 'cores', 3, 0,
2068
created_at=record_created, updated_at=record_created)
2069
self.init_usage('test_project', 'ram', 3, 0,
2070
created_at=record_created, updated_at=record_created)
2071
context = FakeContext('test_project', 'test_class')
2082
result = sqa_api.quota_reserve(context, self.resources, quotas,
2083
deltas, self.expire, 0, max_age)
2085
self.assertEqual(self.sync_called, set(['instances', 'cores', 'ram']))
2086
self.compare_usage(self.usages, [
2087
dict(resource='instances',
2088
project_id='test_project',
2091
until_refresh=None),
2092
dict(resource='cores',
2093
project_id='test_project',
2096
until_refresh=None),
2097
dict(resource='ram',
2098
project_id='test_project',
2101
until_refresh=None),
2103
self.assertEqual(self.usages_created, {})
2104
self.compare_reservation(result, [
2105
dict(resource='instances',
2106
usage_id=self.usages['instances'],
2107
project_id='test_project',
2109
dict(resource='cores',
2110
usage_id=self.usages['cores'],
2111
project_id='test_project',
2113
dict(resource='ram',
2114
usage_id=self.usages['ram'],
2118
def test_quota_reserve_no_refresh(self):
2119
self.init_usage('test_project', 'instances', 3, 0)
2120
self.init_usage('test_project', 'cores', 3, 0)
2121
self.init_usage('test_project', 'ram', 3, 0)
2122
context = FakeContext('test_project', 'test_class')
2133
result = sqa_api.quota_reserve(context, self.resources, quotas,
2134
deltas, self.expire, 0, 0)
2136
self.assertEqual(self.sync_called, set([]))
2137
self.compare_usage(self.usages, [
2138
dict(resource='instances',
2139
project_id='test_project',
2142
until_refresh=None),
2143
dict(resource='cores',
2144
project_id='test_project',
2147
until_refresh=None),
2148
dict(resource='ram',
2149
project_id='test_project',
2152
until_refresh=None),
2154
self.assertEqual(self.usages_created, {})
2155
self.compare_reservation(result, [
2156
dict(resource='instances',
2157
usage_id=self.usages['instances'],
2158
project_id='test_project',
2160
dict(resource='cores',
2161
usage_id=self.usages['cores'],
2162
project_id='test_project',
2164
dict(resource='ram',
2165
usage_id=self.usages['ram'],
2169
def test_quota_reserve_unders(self):
2170
self.init_usage('test_project', 'instances', 1, 0)
2171
self.init_usage('test_project', 'cores', 3, 0)
2172
self.init_usage('test_project', 'ram', 1 * 1024, 0)
2173
context = FakeContext('test_project', 'test_class')
2184
self.assertRaises(exception.InvalidQuotaValue,
2185
sqa_api.quota_reserve,
2186
context, self.resources, quotas,
2187
deltas, self.expire, 0, 0)
2189
self.assertEqual(self.sync_called, set([]))
2190
self.compare_usage(self.usages, [
2191
dict(resource='instances',
2192
project_id='test_project',
2195
until_refresh=None),
2196
dict(resource='cores',
2197
project_id='test_project',
2200
until_refresh=None),
2201
dict(resource='ram',
2202
project_id='test_project',
2205
until_refresh=None),
2207
self.assertEqual(self.usages_created, {})
2208
self.assertEqual(self.reservations_created, {})
2210
def test_quota_reserve_overs(self):
2211
self.init_usage('test_project', 'instances', 4, 0)
2212
self.init_usage('test_project', 'cores', 8, 0)
2213
self.init_usage('test_project', 'ram', 10 * 1024, 0)
2214
context = FakeContext('test_project', 'test_class')
2225
self.assertRaises(exception.OverQuota,
2226
sqa_api.quota_reserve,
2227
context, self.resources, quotas,
2228
deltas, self.expire, 0, 0)
2230
self.assertEqual(self.sync_called, set([]))
2231
self.compare_usage(self.usages, [
2232
dict(resource='instances',
2233
project_id='test_project',
2236
until_refresh=None),
2237
dict(resource='cores',
2238
project_id='test_project',
2241
until_refresh=None),
2242
dict(resource='ram',
2243
project_id='test_project',
2246
until_refresh=None),
2248
self.assertEqual(self.usages_created, {})
2249
self.assertEqual(self.reservations_created, {})
2251
def test_quota_reserve_reduction(self):
2252
self.init_usage('test_project', 'instances', 10, 0)
2253
self.init_usage('test_project', 'cores', 20, 0)
2254
self.init_usage('test_project', 'ram', 20 * 1024, 0)
2255
context = FakeContext('test_project', 'test_class')
2266
result = sqa_api.quota_reserve(context, self.resources, quotas,
2267
deltas, self.expire, 0, 0)
2269
self.assertEqual(self.sync_called, set([]))
2270
self.compare_usage(self.usages, [
2271
dict(resource='instances',
2272
project_id='test_project',
2275
until_refresh=None),
2276
dict(resource='cores',
2277
project_id='test_project',
2280
until_refresh=None),
2281
dict(resource='ram',
2282
project_id='test_project',
2285
until_refresh=None),
2287
self.assertEqual(self.usages_created, {})
2288
self.compare_reservation(result, [
2289
dict(resource='instances',
2290
usage_id=self.usages['instances'],
2291
project_id='test_project',
2293
dict(resource='cores',
2294
usage_id=self.usages['cores'],
2295
project_id='test_project',
2297
dict(resource='ram',
2298
usage_id=self.usages['ram'],
2299
project_id='test_project',