Coverage for manila/tests/test_quota.py: 99%
346 statements
« prev ^ index » next coverage.py v7.11.0, created at 2026-02-18 22:19 +0000
« prev ^ index » next coverage.py v7.11.0, created at 2026-02-18 22:19 +0000
1# Copyright 2017 Mirantis Inc.
2# All Rights Reserved.
3#
4# Licensed under the Apache License, Version 2.0 (the "License"); you may
5# not use this file except in compliance with the License. You may obtain
6# a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13# License for the specific language governing permissions and limitations
14# under the License.
16from unittest import mock
18import ddt
19from oslo_config import cfg
21from manila import exception
22from manila import quota
23from manila import test
25CONF = cfg.CONF
28@ddt.ddt
29class DbQuotaDriverTestCase(test.TestCase):
31 def setUp(self):
32 super(DbQuotaDriverTestCase, self).setUp()
33 self.project_id = 'fake_project_id'
34 self.user_id = 'fake_user_id'
35 self.share_type_id = 'fake_share_type_id'
36 self.ctxt = type(
37 'FakeContext', (object, ),
38 {'project_id': self.project_id, 'user_id': self.user_id,
39 'quota_class': 'fake_quota_class', 'elevated': mock.Mock()})
40 self.driver = quota.DbQuotaDriver()
41 self.reservations = ['foo', 'bar']
42 self.resources = {k: quota.BaseResource(k) for k in ('foo', 'bar')}
44 def test_get_by_class(self):
45 self.mock_object(quota.db, 'quota_class_get')
47 result = self.driver.get_by_class(
48 self.ctxt, 'fake_quota_class', 'fake_res')
50 self.assertEqual(quota.db.quota_class_get.return_value, result)
51 quota.db.quota_class_get.assert_called_once_with(
52 self.ctxt, 'fake_quota_class', 'fake_res')
54 def test_get_defaults(self):
55 self.mock_object(
56 quota.db, 'quota_class_get_default',
57 mock.Mock(return_value={'foo': 13}))
59 result = self.driver.get_defaults(self.ctxt, self.resources)
61 self.assertEqual(
62 {'foo': 13, 'bar': self.resources['bar'].default}, result)
63 quota.db.quota_class_get_default.assert_called_once_with(self.ctxt)
65 @ddt.data(True, False)
66 def test_get_class_quotas(self, defaults):
67 self.mock_object(
68 quota.db, 'quota_class_get_all_by_name',
69 mock.Mock(return_value={'foo': 13}))
71 result = self.driver.get_class_quotas(
72 self.ctxt, self.resources, 'fake_quota_class', defaults)
74 expected = {'foo': 13, 'bar': -1} if defaults else {'foo': 13}
75 self.assertEqual(expected, result)
76 quota.db.quota_class_get_all_by_name.assert_called_once_with(
77 self.ctxt, 'fake_quota_class')
79 @ddt.data(
80 ('fake_project_id', {'foo': 20}, None, True, None, True),
81 ('fake_different_project_id', {'bar': 40}, 'fake_quota_class', True,
82 {'foo': {'in_use': 3, 'reserved': 2}}, False),
83 ('fake_project_id', {'bar': 30}, 'fake_quota_class', True, None, False)
84 )
85 @ddt.unpack
86 def test__process_quotas(self, project_id, quotas, quota_class, defaults,
87 usages, remains):
88 self.mock_object(quota.db, 'quota_get_all', mock.Mock(return_value=[]))
89 self.mock_object(quota.db, 'quota_class_get_all_by_name')
90 self.mock_object(
91 self.driver, 'get_defaults',
92 mock.Mock(return_value={'foo': 11, 'bar': 12}))
93 self.mock_object(
94 quota.db, 'quota_get_all',
95 mock.Mock(return_value=[]))
97 result = self.driver._process_quotas(
98 self.ctxt, self.resources, project_id, quotas, quota_class,
99 defaults, usages, remains)
101 expected = {key: {'limit': mock.ANY} for key in ('foo', 'bar')}
102 if usages:
103 for res in self.resources.values():
104 usage = usages.get(res.name, {})
105 expected[res.name].update(
106 in_use=usage.get('in_use', 0),
107 reserved=usage.get('reserved', 0))
108 if remains:
109 quota.db.quota_get_all.assert_called_once_with(
110 self.ctxt, project_id)
111 for res in self.resources.values():
112 expected[res.name]['remains'] = mock.ANY
113 else:
114 self.assertEqual(0, quota.db.quota_get_all.call_count)
116 self.assertEqual(expected, result)
117 if quota_class or project_id == self.ctxt.project_id: 117 ↛ 121line 117 didn't jump to line 121 because the condition on line 117 was always true
118 quota.db.quota_class_get_all_by_name.assert_called_once_with(
119 self.ctxt, quota_class or self.ctxt.quota_class)
120 else:
121 self.assertEqual(
122 0, quota.db.quota_class_get_all_by_name.call_count)
124 @ddt.data(
125 ('fake_quota_class', True, None, 'fake_remains'),
126 (None, False, 'fake_usages', False),
127 )
128 @ddt.unpack
129 def test_get_project_quotas(self, quota_class, defaults, usages, remains):
130 self.mock_object(quota.db, 'quota_get_all_by_project')
131 self.mock_object(quota.db, 'quota_usage_get_all_by_project')
132 self.mock_object(self.driver, '_process_quotas')
134 result = self.driver.get_project_quotas(
135 self.ctxt, self.resources, self.project_id,
136 quota_class, defaults, usages, remains)
138 self.assertEqual(
139 result, self.driver._process_quotas.return_value)
140 project_usages = None
141 if usages:
142 project_usages = (
143 quota.db.quota_usage_get_all_by_project.return_value)
144 self.driver._process_quotas.assert_called_once_with(
145 self.ctxt, self.resources, self.project_id,
146 quota.db.quota_get_all_by_project.return_value,
147 quota_class, defaults=defaults, usages=project_usages,
148 remains=remains)
149 quota.db.quota_get_all_by_project.assert_called_once_with(
150 self.ctxt, self.project_id)
151 if usages:
152 quota.db.quota_usage_get_all_by_project.assert_called_once_with(
153 self.ctxt, self.project_id)
154 else:
155 self.assertEqual(
156 0, quota.db.quota_usage_get_all_by_project.call_count)
158 @ddt.data(
159 (None, True, True),
160 ('fake_quota_class', False, True),
161 ('fake_quota_class', True, False),
162 )
163 @ddt.unpack
164 def test_get_user_quotas(self, quota_class, defaults, usages):
165 project_quotas = {'fake_resource': 5}
166 self.mock_object(
167 quota.db, 'quota_get_all_by_project',
168 mock.Mock(return_value=project_quotas))
169 self.mock_object(
170 quota.db, 'quota_get_all_by_project_and_user',
171 mock.Mock(return_value={'fake_user_defined_resource': 14}))
172 mock_user_usages = self.mock_object(
173 quota.db, 'quota_usage_get_all_by_project_and_user')
174 self.mock_object(self.driver, '_process_quotas')
176 result = self.driver.get_user_quotas(
177 self.ctxt, self.resources, self.project_id, self.user_id,
178 quota_class, defaults, usages)
180 self.assertEqual(
181 self.driver._process_quotas.return_value, result)
182 quota.db.quota_get_all_by_project.assert_called_once_with(
183 self.ctxt, self.project_id)
184 quota.db.quota_get_all_by_project_and_user.assert_called_once_with(
185 self.ctxt, self.project_id, self.user_id)
186 if usages:
187 user_usages = mock_user_usages.return_value
188 mock_user_usages.assert_called_once_with(
189 self.ctxt, self.project_id, self.user_id)
190 else:
191 user_usages = None
192 self.assertEqual(0, mock_user_usages.call_count)
193 expected_user_quotas = {'fake_user_defined_resource': 14}
194 expected_user_quotas.update(project_quotas)
195 self.driver._process_quotas.assert_called_once_with(
196 self.ctxt, self.resources, self.project_id, expected_user_quotas,
197 quota_class, defaults=defaults, usages=user_usages)
199 @ddt.data(
200 (None, True, True),
201 ('fake_quota_class', False, True),
202 ('fake_quota_class', True, False),
203 )
204 @ddt.unpack
205 def test_get_share_type_quotas(self, quota_class, defaults, usages):
206 project_quotas = {'fake_resource': 5}
207 self.mock_object(
208 quota.db, 'quota_get_all_by_project',
209 mock.Mock(return_value=project_quotas))
210 mock_st_quotas = self.mock_object(
211 quota.db, 'quota_get_all_by_project_and_share_type',
212 mock.Mock(return_value={'fake_st_defined_resource': 14}))
213 mock_st_usages = self.mock_object(
214 quota.db, 'quota_usage_get_all_by_project_and_share_type')
215 self.mock_object(self.driver, '_process_quotas')
217 result = self.driver.get_share_type_quotas(
218 self.ctxt, self.resources, self.project_id, self.share_type_id,
219 quota_class, defaults, usages)
221 self.assertEqual(
222 self.driver._process_quotas.return_value, result)
223 quota.db.quota_get_all_by_project.assert_called_once_with(
224 self.ctxt, self.project_id)
225 mock_st_quotas.assert_called_once_with(
226 self.ctxt, self.project_id, self.share_type_id)
227 if usages:
228 st_usages = mock_st_usages.return_value
229 mock_st_usages.assert_called_once_with(
230 self.ctxt, self.project_id, self.share_type_id)
231 else:
232 st_usages = None
233 self.assertEqual(0, mock_st_usages.call_count)
234 expected_st_quotas = {'fake_st_defined_resource': 14}
235 expected_st_quotas.update(project_quotas)
236 self.driver._process_quotas.assert_called_once_with(
237 self.ctxt, self.resources, self.project_id, expected_st_quotas,
238 quota_class, defaults=defaults, usages=st_usages)
240 @ddt.data((None, None), (None, 'foo_st_id'), ('foo_user_id', None))
241 @ddt.unpack
242 def test_get_settable_quotas(self, user_id, st_id):
243 project_quotas = {'fake': {
244 'limit': 13, 'in_use': 7, 'reserved': 5, 'remains': 1,
245 }}
246 user_or_st_quotas = {'fake': {
247 'limit': 11, 'in_use': 5, 'reserved': 2,
248 }}
249 self.mock_object(
250 self.driver, 'get_project_quotas',
251 mock.Mock(return_value=project_quotas))
252 self.mock_object(
253 self.driver, 'get_user_quotas',
254 mock.Mock(return_value=user_or_st_quotas))
255 self.mock_object(
256 self.driver, 'get_share_type_quotas',
257 mock.Mock(return_value=user_or_st_quotas))
259 result = self.driver.get_settable_quotas(
260 self.ctxt, self.resources, self.project_id, user_id, st_id)
262 if user_id:
263 self.driver.get_user_quotas.assert_called_once_with(
264 self.ctxt, self.resources, self.project_id, user_id)
265 else:
266 self.assertEqual(0, self.driver.get_user_quotas.call_count)
267 if st_id:
268 self.driver.get_share_type_quotas.assert_called_once_with(
269 self.ctxt, self.resources, self.project_id, st_id)
270 else:
271 self.assertEqual(0, self.driver.get_share_type_quotas.call_count)
272 if user_id or st_id:
273 expected_settable_quotas = {'fake': {'maximum': 13, 'minimum': 7}}
274 else:
275 expected_settable_quotas = {'fake': {'maximum': -1, 'minimum': 12}}
276 self.driver.get_project_quotas.assert_called_once_with(
277 self.ctxt, self.resources, self.project_id, remains=True)
278 self.assertEqual(expected_settable_quotas, result)
280 @ddt.data((None, None), (None, 'fake_st_id'), ('fake_user_id', None))
281 @ddt.unpack
282 def test__get_quotas(self, user_id, st_id):
283 quotas = {'foo': {'limit': 5}, 'bar': {'limit': 13}}
284 self.mock_object(
285 self.driver, 'get_project_quotas', mock.Mock(return_value=quotas))
286 self.mock_object(
287 self.driver, 'get_user_quotas', mock.Mock(return_value=quotas))
288 self.mock_object(
289 self.driver, 'get_share_type_quotas',
290 mock.Mock(return_value=quotas))
292 result = self.driver._get_quotas(
293 self.ctxt, self.resources, ('foo', 'bar'), False,
294 self.project_id, user_id, st_id)
296 expected = {k: v['limit'] for k, v in quotas.items()}
297 self.assertEqual(expected, result)
298 sub_resources = {k: v for k, v in self.resources.items()}
299 if user_id:
300 self.driver.get_user_quotas.assert_called_once_with(
301 self.ctxt, sub_resources, self.project_id, user_id,
302 self.ctxt.quota_class, usages=False)
303 self.assertEqual(0, self.driver.get_project_quotas.call_count)
304 self.assertEqual(0, self.driver.get_share_type_quotas.call_count)
305 elif st_id:
306 self.driver.get_share_type_quotas.assert_called_once_with(
307 self.ctxt, sub_resources, self.project_id, st_id,
308 self.ctxt.quota_class, usages=False)
309 self.assertEqual(0, self.driver.get_project_quotas.call_count)
310 self.assertEqual(0, self.driver.get_user_quotas.call_count)
311 else:
312 self.driver.get_project_quotas.assert_called_once_with(
313 self.ctxt, sub_resources, self.project_id,
314 self.ctxt.quota_class, usages=False)
315 self.assertEqual(0, self.driver.get_user_quotas.call_count)
316 self.assertEqual(0, self.driver.get_share_type_quotas.call_count)
318 def test__get_quotas_unknown(self):
319 quotas = {'foo': {'limit': 5}, 'bar': {'limit': 13}}
320 self.mock_object(
321 self.driver, 'get_project_quotas', mock.Mock(return_value=quotas))
322 self.mock_object(
323 self.driver, 'get_user_quotas', mock.Mock(return_value=quotas))
324 self.mock_object(
325 self.driver, 'get_share_type_quotas',
326 mock.Mock(return_value=quotas))
328 self.assertRaises(
329 exception.QuotaResourceUnknown,
330 self.driver._get_quotas,
331 self.ctxt, self.resources, ['foo', 'bar'], True,
332 self.project_id, self.user_id, self.share_type_id)
334 self.assertEqual(0, self.driver.get_project_quotas.call_count)
335 self.assertEqual(0, self.driver.get_user_quotas.call_count)
336 self.assertEqual(0, self.driver.get_share_type_quotas.call_count)
338 @ddt.data(
339 {}, {'project_id': 'fake_project'}, {'user_id': 'fake_user'},
340 {'share_type_id': 'fake_share_type_id'},
341 )
342 def test_reserve(self, kwargs):
343 self.mock_object(quota.db, 'quota_reserve')
344 deltas = {'delta1': 1, 'delta2': 2}
345 quotas, user_quotas, st_quotas = 'fake1', 'fake2', 'fake3'
346 self.mock_object(
347 self.driver, '_get_quotas', mock.Mock(
348 side_effect=[quotas, user_quotas, st_quotas]))
350 result = self.driver.reserve(
351 self.ctxt, self.resources, deltas, None, **kwargs)
353 expected_kwargs = {
354 'project_id': self.ctxt.project_id,
355 'user_id': self.ctxt.user_id,
356 'share_type_id': None,
357 'overquota_allowed': False
358 }
359 expected_kwargs.update(kwargs)
360 st_quotas = st_quotas if kwargs.get('share_type_id') else {}
361 self.assertEqual(quota.db.quota_reserve.return_value, result)
362 quota.db.quota_reserve.assert_called_once_with(
363 self.ctxt, self.resources, quotas, user_quotas, st_quotas,
364 deltas, mock.ANY, CONF.quota.until_refresh, CONF.quota.max_age,
365 **expected_kwargs)
366 self.assertEqual(
367 3 if kwargs.get('share_type_id') else 2,
368 self.driver._get_quotas.call_count)
370 def test_reserve_wrong_expire(self):
371 self.assertRaises(
372 exception.InvalidReservationExpiration,
373 self.driver.reserve,
374 self.ctxt, self.resources, 'fake_deltas', 'fake_expire')
376 def test_commit(self):
377 self.mock_object(quota.db, 'reservation_commit')
379 result = self.driver.commit(
380 self.ctxt, self.reservations, self.project_id, self.user_id,
381 self.share_type_id)
383 self.assertIsNone(result)
384 quota.db.reservation_commit.assert_called_once_with(
385 self.ctxt, self.reservations, project_id=self.project_id,
386 user_id=self.user_id, share_type_id=self.share_type_id)
388 @ddt.data(
389 (None, None),
390 ('fake_project_id', 'fake_user_id'),
391 )
392 @ddt.unpack
393 def test_rollback(self, project_id, user_id):
394 self.mock_object(quota.db, 'reservation_rollback')
396 result = self.driver.rollback(
397 self.ctxt, self.reservations, project_id, user_id,
398 self.share_type_id)
400 expected_project_id = project_id or self.ctxt.project_id
401 expected_user_id = user_id or self.ctxt.user_id
402 self.assertIsNone(result)
403 quota.db.reservation_rollback.assert_called_once_with(
404 self.ctxt, self.reservations, project_id=expected_project_id,
405 user_id=expected_user_id, share_type_id=self.share_type_id)
407 def test_usage_reset(self):
408 self.mock_object(
409 quota.db, 'quota_usage_update',
410 mock.Mock(side_effect=[
411 'foo',
412 exception.QuotaUsageNotFound(project_id=self.project_id)]))
414 result = self.driver.usage_reset(self.ctxt, ['foo', 'bar'])
416 self.assertIsNone(result)
417 quota.db.quota_usage_update.assert_has_calls([
418 mock.call(
419 self.ctxt.elevated.return_value, self.ctxt.project_id,
420 self.ctxt.user_id, res, in_use=-1)
421 for res in ('foo', 'bar')
422 ])
424 def test_destroy_all_by_project(self):
425 self.mock_object(quota.db, 'quota_destroy_all_by_project')
427 result = self.driver.destroy_all_by_project(self.ctxt, self.project_id)
429 self.assertIsNone(result)
430 quota.db.quota_destroy_all_by_project.assert_called_once_with(
431 self.ctxt, self.project_id)
433 def test_destroy_all_by_project_and_user(self):
434 self.mock_object(quota.db, 'quota_destroy_all_by_project_and_user')
436 result = self.driver.destroy_all_by_project_and_user(
437 self.ctxt, self.project_id, self.user_id)
439 self.assertIsNone(result)
440 quota.db.quota_destroy_all_by_project_and_user.assert_called_once_with(
441 self.ctxt, self.project_id, self.user_id)
443 def test_destroy_all_by_project_and_share_type(self):
444 mock_destroy_all = self.mock_object(
445 quota.db, 'quota_destroy_all_by_share_type')
447 result = self.driver.destroy_all_by_project_and_share_type(
448 self.ctxt, self.project_id, self.share_type_id)
450 self.assertIsNone(result)
451 mock_destroy_all.assert_called_once_with(
452 self.ctxt, self.share_type_id, project_id=self.project_id)
454 def test_expire(self):
455 self.mock_object(quota.db, 'reservation_expire')
457 result = self.driver.expire(self.ctxt)
459 self.assertIsNone(result)
460 quota.db.reservation_expire.assert_called_once_with(self.ctxt)
463@ddt.ddt
464class QuotaEngineTestCase(test.TestCase):
466 def setUp(self):
467 super(QuotaEngineTestCase, self).setUp()
468 self.ctxt = 'fake_context'
469 self.mock_class('manila.quota.DbQuotaDriver')
470 self.engine = quota.QuotaEngine()
471 self.driver = self.engine._driver
472 self.resources = [quota.BaseResource('foo'), quota.BaseResource('bar')]
473 self.project_id = 'fake_project_id'
474 self.user_id = 'fake_user_id'
475 self.share_type_id = 'fake_share_type_id'
476 self.quota_class = 'fake_quota_class'
478 def test_register_resource(self):
479 self.assertNotIn(self.resources[0].name, self.engine)
480 self.engine.register_resource(self.resources[0])
481 self.assertIn(self.resources[0].name, self.engine)
483 def test_register_resources(self):
484 for res in self.resources:
485 self.assertNotIn(res.name, self.engine)
486 self.engine.register_resources(self.resources)
487 for res in self.resources:
488 self.assertIn(res.name, self.engine)
490 def test_get_by_class(self):
491 result = self.engine.get_by_class(
492 self.ctxt, self.quota_class, 'fake_res')
494 self.assertEqual(result, self.driver.get_by_class.return_value)
495 self.driver.get_by_class.assert_called_once_with(
496 self.ctxt, self.quota_class, 'fake_res')
498 def test_get_defaults(self):
499 result = self.engine.get_defaults(self.ctxt)
501 self.assertEqual(result, self.driver.get_defaults.return_value)
502 self.driver.get_defaults.assert_called_once_with(
503 self.ctxt, self.engine._resources)
505 @ddt.data(None, True, False)
506 def test_get_class_quotas(self, defaults):
507 kwargs = {}
508 if defaults is not None:
509 kwargs['defaults'] = defaults
511 result = self.engine.get_class_quotas(
512 self.ctxt, self.quota_class, **kwargs)
514 self.assertEqual(result, self.driver.get_class_quotas.return_value)
515 kwargs['defaults'] = defaults if defaults is not None else True
516 self.driver.get_class_quotas.assert_called_once_with(
517 self.ctxt, self.engine._resources, self.quota_class, **kwargs)
519 @ddt.data(
520 {},
521 {'quota_class': 'foo'},
522 {'defaults': False},
523 {'usages': False},
524 )
525 def test_get_user_quotas(self, kwargs):
526 expected_kwargs = {
527 'quota_class': None,
528 'defaults': True,
529 'usages': True,
530 }
531 expected_kwargs.update(kwargs)
533 result = self.engine.get_user_quotas(
534 self.ctxt, self.project_id, self.user_id, **kwargs)
536 self.assertEqual(result, self.driver.get_user_quotas.return_value)
537 self.driver.get_user_quotas.assert_called_once_with(
538 self.ctxt, self.engine._resources,
539 self.project_id, self.user_id, **expected_kwargs)
541 @ddt.data(
542 {},
543 {'quota_class': 'foo'},
544 {'defaults': False},
545 {'usages': False},
546 )
547 def test_get_share_type_quotas(self, kwargs):
548 expected_kwargs = {
549 'quota_class': None,
550 'defaults': True,
551 'usages': True,
552 }
553 expected_kwargs.update(kwargs)
555 result = self.engine.get_share_type_quotas(
556 self.ctxt, self.project_id, self.share_type_id, **kwargs)
558 self.assertEqual(
559 result, self.driver.get_share_type_quotas.return_value)
560 self.driver.get_share_type_quotas.assert_called_once_with(
561 self.ctxt, self.engine._resources,
562 self.project_id, self.share_type_id, **expected_kwargs)
564 @ddt.data(
565 {},
566 {'quota_class': 'foo'},
567 {'defaults': False},
568 {'usages': False},
569 {'remains': True},
570 )
571 def test_get_project_quotas(self, kwargs):
572 expected_kwargs = {
573 'quota_class': None,
574 'defaults': True,
575 'usages': True,
576 'remains': False,
577 }
578 expected_kwargs.update(kwargs)
580 result = self.engine.get_project_quotas(
581 self.ctxt, self.project_id, **kwargs)
583 self.assertEqual(result, self.driver.get_project_quotas.return_value)
584 self.driver.get_project_quotas.assert_called_once_with(
585 self.ctxt, self.engine._resources,
586 self.project_id, **expected_kwargs)
588 @ddt.data(
589 {},
590 {'user_id': 'fake_user_id'},
591 {'share_type_id': 'fake_share_type_id'},
592 )
593 def test_get_settable_quotas(self, kwargs):
594 expected_kwargs = {'user_id': None, 'share_type_id': None}
595 expected_kwargs.update(kwargs)
597 result = self.engine.get_settable_quotas(
598 self.ctxt, self.project_id, **kwargs)
600 self.assertEqual(result, self.driver.get_settable_quotas.return_value)
601 self.driver.get_settable_quotas.assert_called_once_with(
602 self.ctxt, self.engine._resources,
603 self.project_id, **expected_kwargs)
605 def test_count(self):
606 mock_count = mock.Mock()
607 resource = quota.CountableResource('FakeCountableResource', mock_count)
608 self.engine.register_resource(resource)
610 result = self.engine.count(self.ctxt, resource.name)
612 self.assertEqual(mock_count.return_value, result)
614 def test_count_unknown_resource(self):
615 self.assertRaises(
616 exception.QuotaResourceUnknown,
617 self.engine.count,
618 self.ctxt, 'nonexistent_resource', 'foo_arg', foo='kwarg')
620 def test_reserve(self):
621 result = self.engine.reserve(
622 self.ctxt, 'fake_expire', self.project_id, self.user_id,
623 self.share_type_id, delta1=1, delta2=2)
625 self.assertEqual(self.driver.reserve.return_value, result)
626 self.driver.reserve.assert_called_once_with(
627 self.ctxt, self.engine._resources, {'delta1': 1, 'delta2': 2},
628 expire='fake_expire', project_id=self.project_id,
629 user_id=self.user_id, share_type_id=self.share_type_id,
630 overquota_allowed=False)
632 @ddt.data(Exception('FakeException'), [None])
633 def test_commit(self, side_effect):
634 fake_reservations = ['foo', 'bar']
635 self.driver.commit.side_effect = side_effect
636 self.mock_object(quota.LOG, 'exception')
638 result = self.engine.commit(
639 self.ctxt, fake_reservations, 'fake_project_id',
640 'fake_user_id', 'fake_share_type_id')
642 self.assertIsNone(result)
643 self.driver.commit.assert_called_once_with(
644 self.ctxt, fake_reservations, project_id='fake_project_id',
645 user_id='fake_user_id', share_type_id='fake_share_type_id')
646 if side_effect == [None]:
647 self.assertEqual(0, quota.LOG.exception.call_count)
648 else:
649 quota.LOG.exception.assert_called_once_with(
650 mock.ANY, fake_reservations)
652 @ddt.data(Exception('FakeException'), [None])
653 def test_rollback(self, side_effect):
654 fake_reservations = ['foo', 'bar']
655 self.driver.rollback.side_effect = side_effect
656 self.mock_object(quota.LOG, 'exception')
658 result = self.engine.rollback(
659 self.ctxt, fake_reservations, 'fake_project_id',
660 'fake_user_id', 'fake_share_type_id')
662 self.assertIsNone(result)
663 self.driver.rollback.assert_called_once_with(
664 self.ctxt, fake_reservations, project_id='fake_project_id',
665 user_id='fake_user_id', share_type_id='fake_share_type_id')
666 if side_effect == [None]:
667 self.assertEqual(0, quota.LOG.exception.call_count)
668 else:
669 quota.LOG.exception.assert_called_once_with(
670 mock.ANY, fake_reservations)
672 def test_usage_reset(self):
673 result = self.engine.usage_reset(self.ctxt, 'fake_resources')
675 self.assertIsNone(result)
676 self.driver.usage_reset.assert_called_once_with(
677 self.ctxt, 'fake_resources')
679 def test_destroy_all_by_project_and_user(self):
680 result = self.engine.destroy_all_by_project_and_user(
681 self.ctxt, 'fake_project_id', 'fake_user_id')
683 self.assertIsNone(result)
684 self.driver.destroy_all_by_project_and_user.assert_called_once_with(
685 self.ctxt, 'fake_project_id', 'fake_user_id')
687 def test_destroy_all_by_project_and_share_type(self):
688 result = self.engine.destroy_all_by_project_and_share_type(
689 self.ctxt, 'fake_project_id', 'fake_st_id')
691 self.assertIsNone(result)
692 mock_destroy_all_by_project_and_share_type = (
693 self.driver.destroy_all_by_project_and_share_type)
694 mock_destroy_all_by_project_and_share_type.assert_called_once_with(
695 self.ctxt, 'fake_project_id', 'fake_st_id')
697 def test_destroy_all_by_project(self):
698 result = self.engine.destroy_all_by_project(
699 self.ctxt, 'fake_project_id')
701 self.assertIsNone(result)
702 self.driver.destroy_all_by_project.assert_called_once_with(
703 self.ctxt, 'fake_project_id')
705 def test_expire(self):
706 result = self.engine.expire(self.ctxt)
708 self.assertIsNone(result)
709 self.driver.expire.assert_called_once_with(self.ctxt)
711 def test_resources(self):
712 self.engine.register_resources(self.resources)
713 self.assertEqual(['bar', 'foo'], self.engine.resources)
715 def test_current_common_resources(self):
716 self.assertEqual(
717 sorted(['gigabytes', 'per_share_gigabytes', 'replica_gigabytes',
718 'share_group_snapshots', 'share_groups', 'share_networks',
719 'share_replicas', 'shares', 'snapshot_gigabytes',
720 'snapshots', 'backups', 'backup_gigabytes',
721 'encryption_keys']),
722 quota.QUOTAS.resources)