Coverage for manila/tests/db/sqlalchemy/test_api.py: 99%
2831 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 2013 OpenStack Foundation
2# Copyright (c) 2014 NetApp, Inc.
3# Copyright (c) 2015 Rushil Chugh
4# All Rights Reserved.
5#
6# Licensed under the Apache License, Version 2.0 (the "License"); you may
7# not use this file except in compliance with the License. You may obtain
8# a copy of the License at
9#
10# http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing, software
13# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15# License for the specific language governing permissions and limitations
16# under the License.
18"""Testing of SQLAlchemy backend."""
20import copy
21import datetime
22import random
23from unittest import mock
25import ddt
26from oslo_db import exception as db_exception
27from oslo_utils import timeutils
28from oslo_utils import uuidutils
30from manila.common import constants
31from manila import context
32from manila.db.sqlalchemy import api as db_api
33from manila.db.sqlalchemy import models
34from manila import exception
35from manila import quota
36from manila import test
37from manila.tests import db_utils
39QUOTAS = quota.QUOTAS
41security_service_dict = {
42 'id': 'fake id',
43 'project_id': 'fake project',
44 'type': 'ldap',
45 'dns_ip': 'fake dns',
46 'server': 'fake ldap server',
47 'domain': 'fake ldap domain',
48 'default_ad_site': 'fake ldap default_ad_site',
49 'ou': 'fake ldap ou',
50 'user': 'fake user',
51 'password': 'fake password',
52 'name': 'whatever',
53 'description': 'nevermind',
54}
57class BaseDatabaseAPITestCase(test.TestCase):
58 def _check_fields(self, expected, actual):
59 for key in expected:
60 self.assertEqual(expected[key], actual[key])
63@ddt.ddt
64class GenericDatabaseAPITestCase(test.TestCase):
66 def setUp(self):
67 """Run before each test."""
68 super(GenericDatabaseAPITestCase, self).setUp()
69 self.ctxt = context.get_admin_context()
71 @ddt.unpack
72 @ddt.data(
73 {'values': {'test': 'fake'}, 'call_count': 1},
74 {'values': {'test': 'fake', 'id': 'fake'}, 'call_count': 0},
75 {'values': {'test': 'fake', 'fooid': 'fake'}, 'call_count': 1},
76 {'values': {'test': 'fake', 'idfoo': 'fake'}, 'call_count': 1},
77 )
78 def test_ensure_model_values_has_id(self, values, call_count):
79 self.mock_object(uuidutils, 'generate_uuid')
81 db_api.ensure_model_dict_has_id(values)
83 self.assertEqual(call_count, uuidutils.generate_uuid.call_count)
84 self.assertIn('id', values)
86 def test_custom_query(self):
87 share = db_utils.create_share()
88 share_access = db_utils.create_access(share_id=share['id'])
90 db_api.share_instance_access_delete(
91 self.ctxt, share_access.instance_mappings[0].id)
92 self.assertRaises(exception.NotFound, db_api.share_access_get,
93 self.ctxt, share_access.id)
96@ddt.ddt
97class ShareAccessDatabaseAPITestCase(test.TestCase):
99 def setUp(self):
100 """Run before each test."""
101 super(ShareAccessDatabaseAPITestCase, self).setUp()
102 self.ctxt = context.get_admin_context()
104 @ddt.data(0, 3)
105 def test_share_access_get_all_for_share(self, len_rules):
106 share = db_utils.create_share()
107 rules = [db_utils.create_access(share_id=share['id'])
108 for i in range(0, len_rules)]
109 rule_ids = [r['id'] for r in rules]
111 result = db_api.share_access_get_all_for_share(self.ctxt, share['id'])
113 self.assertEqual(len_rules, len(result))
114 result_ids = [r['id'] for r in result]
115 self.assertEqual(rule_ids, result_ids)
117 def test_share_access_get_all_for_share_no_instance_mappings(self):
118 share = db_utils.create_share()
119 share_instance = share['instance']
120 rule = db_utils.create_access(share_id=share['id'])
121 # Mark instance mapping soft deleted
122 db_api.share_instance_access_update(
123 self.ctxt, rule['id'], share_instance['id'], {'deleted': "True"})
125 result = db_api.share_access_get_all_for_share(self.ctxt, share['id'])
127 self.assertEqual([], result)
129 def test_share_instance_access_update(self):
130 share = db_utils.create_share()
131 access = db_utils.create_access(share_id=share['id'])
133 instance_access_mapping = db_api.share_instance_access_get(
134 self.ctxt, access['id'], share.instance['id'])
135 self.assertEqual(constants.ACCESS_STATE_QUEUED_TO_APPLY,
136 access['state'])
137 self.assertIsNone(access['access_key'])
139 db_api.share_instance_access_update(
140 self.ctxt, access['id'], share.instance['id'],
141 {'state': constants.STATUS_ERROR, 'access_key': 'watson4heisman'})
143 instance_access_mapping = db_api.share_instance_access_get(
144 self.ctxt, access['id'], share.instance['id'])
145 access = db_api.share_access_get(self.ctxt, access['id'])
146 self.assertEqual(constants.STATUS_ERROR,
147 instance_access_mapping['state'])
148 self.assertEqual('watson4heisman', access['access_key'])
149 self.assertIsNotNone(access['updated_at'])
150 time_now = timeutils.utcnow()
151 self.assertTrue(access['updated_at'] < time_now)
152 self.assertTrue(instance_access_mapping['updated_at'] < time_now)
154 @ddt.data(True, False)
155 def test_share_access_get_all_for_instance_with_share_access_data(
156 self, with_share_access_data):
157 share = db_utils.create_share()
158 access_1 = db_utils.create_access(share_id=share['id'])
159 access_2 = db_utils.create_access(share_id=share['id'])
160 share_access_keys = ('access_to', 'access_type', 'access_level',
161 'share_id')
163 rules = db_api.share_access_get_all_for_instance(
164 self.ctxt, share.instance['id'],
165 with_share_access_data=with_share_access_data)
167 share_access_keys_present = True if with_share_access_data else False
168 actual_access_ids = [r['access_id'] for r in rules]
169 self.assertIsInstance(actual_access_ids, list)
170 expected = [access_1['id'], access_2['id']]
171 self.assertEqual(len(expected), len(actual_access_ids))
172 for pool in expected:
173 self.assertIn(pool, actual_access_ids)
174 for rule in rules:
175 for key in share_access_keys:
176 self.assertEqual(share_access_keys_present, key in rule)
177 self.assertIn('state', rule)
179 def test_share_access_get_all_for_instance_with_filters(self):
180 share = db_utils.create_share()
181 new_share_instance = db_utils.create_share_instance(
182 share_id=share['id'])
183 access_1 = db_utils.create_access(share_id=share['id'])
184 access_2 = db_utils.create_access(share_id=share['id'])
185 share_access_keys = ('access_to', 'access_type', 'access_level',
186 'share_id')
187 db_api.share_instance_access_update(
188 self.ctxt, access_1['id'], new_share_instance['id'],
189 {'state': constants.STATUS_ACTIVE})
191 rules = db_api.share_access_get_all_for_instance(
192 self.ctxt, new_share_instance['id'],
193 filters={'state': constants.ACCESS_STATE_QUEUED_TO_APPLY})
195 self.assertEqual(1, len(rules))
196 self.assertEqual(access_2['id'], rules[0]['access_id'])
198 for rule in rules:
199 for key in share_access_keys:
200 self.assertIn(key, rule)
202 def test_share_instance_access_delete(self):
203 share = db_utils.create_share()
204 access = db_utils.create_access(share_id=share['id'],
205 metadata={'key1': 'v1'})
206 instance_access_mapping = db_api.share_instance_access_get(
207 self.ctxt, access['id'], share.instance['id'])
209 db_api.share_instance_access_delete(
210 self.ctxt, instance_access_mapping['id'])
212 rules = db_api.share_access_get_all_for_instance(
213 self.ctxt, share.instance['id'])
214 self.assertEqual([], rules)
216 self.assertRaises(exception.NotFound, db_api.share_instance_access_get,
217 self.ctxt, access['id'], share['instance']['id'])
219 def test_share_instance_access_delete_with_locks(self):
220 share = db_utils.create_share()
221 access = db_utils.create_access(share_id=share['id'],
222 metadata={'key1': 'v1'})
224 # create a share and an access lock to ensure they'll be deleted
225 access_lock = db_utils.create_lock(resource_id=access['id'])
226 share_lock_reason = (
227 constants.SHARE_LOCKED_BY_ACCESS_LOCK_REASON %
228 {'lock_id': access_lock['id']}
229 )
230 share_lock = db_utils.create_lock(
231 resource_id=share['id'], lock_reason=share_lock_reason
232 )
234 # create another share lock, to ensure it won't be deleted
235 unrelated_share_lock = db_utils.create_lock(resource_id=share['id'])
237 instance_access_mapping = db_api.share_instance_access_get(
238 self.ctxt, access['id'], share.instance['id'])
240 db_api.share_instance_access_delete(
241 self.ctxt, instance_access_mapping['id'])
243 rules = db_api.share_access_get_all_for_instance(
244 self.ctxt, share.instance['id'])
245 unrelated_share_lock_get = (
246 db_api.resource_lock_get(self.ctxt, unrelated_share_lock['id'])
247 )
248 self.assertEqual([], rules)
249 self.assertEqual(unrelated_share_lock['id'],
250 unrelated_share_lock_get['id'])
252 # ensure the access rules and the locks have been dropped
253 self.assertRaises(exception.NotFound, db_api.share_instance_access_get,
254 self.ctxt, access['id'], share['instance']['id'])
255 self.assertRaises(exception.NotFound, db_api.resource_lock_get,
256 self.ctxt, access_lock['id'])
257 self.assertRaises(exception.NotFound, db_api.resource_lock_get,
258 self.ctxt, share_lock['id'])
260 def test_one_share_with_two_share_instance_access_delete(self):
261 metadata = {'key2': 'v2', 'key3': 'v3'}
262 share = db_utils.create_share()
263 instance = db_utils.create_share_instance(share_id=share['id'])
264 access = db_utils.create_access(share_id=share['id'],
265 metadata=metadata)
266 instance_access_mapping1 = db_api.share_instance_access_get(
267 self.ctxt, access['id'], share.instance['id'])
268 instance_access_mapping2 = db_api.share_instance_access_get(
269 self.ctxt, access['id'], instance['id'])
270 self.assertEqual(instance_access_mapping1['access_id'],
271 instance_access_mapping2['access_id'])
272 db_api.share_instance_delete(self.ctxt, instance['id'])
274 get_accesses = db_api.share_access_get_all_for_share(self.ctxt,
275 share['id'])
276 self.assertEqual(1, len(get_accesses))
277 get_metadata = (
278 get_accesses[0].get('share_access_rules_metadata') or {})
279 get_metadata = {item['key']: item['value'] for item in get_metadata}
280 self.assertEqual(metadata, get_metadata)
281 self.assertEqual(access['id'], get_accesses[0]['id'])
283 db_api.share_instance_delete(self.ctxt, share['instance']['id'])
284 self.assertRaises(exception.NotFound,
285 db_api.share_instance_access_get,
286 self.ctxt, access['id'], share['instance']['id'])
288 get_accesses = db_api.share_access_get_all_for_share(self.ctxt,
289 share['id'])
290 self.assertEqual(0, len(get_accesses))
292 @ddt.data(True, False)
293 def test_share_instance_access_get_with_share_access_data(
294 self, with_share_access_data):
295 share = db_utils.create_share()
296 access = db_utils.create_access(share_id=share['id'])
298 instance_access = db_api.share_instance_access_get(
299 self.ctxt, access['id'], share['instance']['id'],
300 with_share_access_data=with_share_access_data)
302 for key in ('share_id', 'access_type', 'access_to', 'access_level',
303 'access_key'):
304 self.assertEqual(with_share_access_data, key in instance_access)
306 @ddt.data({'existing': {'access_type': 'cephx', 'access_to': 'alice'},
307 'new': {'access_type': 'user', 'access_to': 'alice'},
308 'result': False},
309 {'existing': {'access_type': 'user', 'access_to': 'bob'},
310 'new': {'access_type': 'user', 'access_to': 'bob'},
311 'result': True},
312 {'existing': {'access_type': 'ip', 'access_to': '10.0.0.10/32'},
313 'new': {'access_type': 'ip', 'access_to': '10.0.0.10'},
314 'result': True},
315 {'existing': {'access_type': 'ip', 'access_to': '10.10.0.11'},
316 'new': {'access_type': 'ip', 'access_to': '10.10.0.11'},
317 'result': True},
318 {'existing': {'access_type': 'ip', 'access_to': 'fd21::11'},
319 'new': {'access_type': 'ip', 'access_to': 'fd21::11'},
320 'result': True},
321 {'existing': {'access_type': 'ip', 'access_to': 'fd21::10'},
322 'new': {'access_type': 'ip', 'access_to': 'fd21::10/128'},
323 'result': True},
324 {'existing': {'access_type': 'ip', 'access_to': '10.10.0.0/22'},
325 'new': {'access_type': 'ip', 'access_to': '10.10.0.0/24'},
326 'result': False},
327 {'existing': {'access_type': 'ip', 'access_to': '2620:52::/48'},
328 'new': {'access_type': 'ip',
329 'access_to': '2620:52:0:13b8::/64'},
330 'result': False})
331 @ddt.unpack
332 def test_share_access_check_for_existing_access(self, existing, new,
333 result):
334 share = db_utils.create_share()
335 db_utils.create_access(share_id=share['id'],
336 access_type=existing['access_type'],
337 access_to=existing['access_to'])
339 rule_exists = db_api.share_access_check_for_existing_access(
340 self.ctxt, share['id'], new['access_type'], new['access_to'])
342 self.assertEqual(result, rule_exists)
344 def test_share_access_get_all_for_share_with_metadata(self):
345 share = db_utils.create_share()
346 rules = [db_utils.create_access(
347 share_id=share['id'], metadata={'key1': i})
348 for i in range(0, 3)]
349 rule_ids = [r['id'] for r in rules]
351 result = db_api.share_access_get_all_for_share(self.ctxt, share['id'])
353 self.assertEqual(3, len(result))
354 result_ids = [r['id'] for r in result]
355 self.assertEqual(rule_ids, result_ids)
357 result = db_api.share_access_get_all_for_share(
358 self.ctxt, share['id'], {'metadata': {'key1': '2'}})
359 self.assertEqual(1, len(result))
360 self.assertEqual(rules[2]['id'], result[0]['id'])
362 def test_share_access_metadata_update(self):
363 share = db_utils.create_share()
364 new_metadata = {'key1': 'test_update', 'key2': 'v2'}
365 rule = db_utils.create_access(share_id=share['id'],
366 metadata={'key1': 'v1'})
367 result_metadata = db_api.share_access_metadata_update(
368 self.ctxt, rule['id'], metadata=new_metadata)
369 result = db_api.share_access_get(self.ctxt, rule['id'])
370 self.assertEqual(new_metadata, result_metadata)
371 metadata = result.get('share_access_rules_metadata')
372 if metadata: 372 ↛ 375line 372 didn't jump to line 375 because the condition on line 372 was always true
373 metadata = {item['key']: item['value'] for item in metadata}
374 else:
375 metadata = {}
376 self.assertEqual(new_metadata, metadata)
378 def test_share_access_get_with_context(self):
379 ctxt = context.RequestContext('demo', 'fake', False)
380 share = db_utils.create_share(project_id=ctxt.project_id)
381 rules = [db_utils.create_access(share_id=share['id'])]
383 result = db_api.share_access_get_with_context(ctxt, rules[0]['id'])
385 self.assertEqual(result['project_id'], ctxt.project_id)
387 def test_share_access_get_with_context_not_found(self):
389 self.assertRaises(
390 exception.NotFound,
391 db_api.share_access_get_with_context,
392 self.ctxt,
393 'fake_rule_id')
396@ddt.ddt
397class ShareDatabaseAPITestCase(test.TestCase):
399 def setUp(self):
400 """Run before each test."""
401 super(ShareDatabaseAPITestCase, self).setUp()
402 self.ctxt = context.get_admin_context()
404 def test_share_create(self):
405 share = db_api.share_create(
406 self.ctxt,
407 {'user_id': 'user', 'project_id': 'project', 'host': 'foo'},
408 )
409 self.assertEqual('user', share.user_id)
410 self.assertEqual('project', share.project_id)
411 self.assertEqual('foo', share.host)
412 self.assertEqual(1, len(share.instances))
413 self.assertIsInstance(share.instances[0], models.ShareInstance)
414 self.assertEqual(share.instances[0], share.instance)
416 def test_share_create__no_instance(self):
417 share = db_api.share_create(
418 self.ctxt,
419 {'user_id': 'user', 'project_id': 'project', 'host': 'foo'},
420 create_share_instance=False,
421 )
422 self.assertEqual('user', share.user_id)
423 self.assertEqual('project', share.project_id)
424 self.assertIsNone(share.host)
425 self.assertEqual(0, len(share.instances))
427 @ddt.data('yes', 'no', 'only')
428 def test_share_read_deleted(self, read_deleted):
429 share = db_utils.create_share()
430 test_ctxt = context.get_admin_context(read_deleted=read_deleted)
431 admin_ctxt = context.get_admin_context(read_deleted='yes')
433 if read_deleted in ('yes', 'no'):
434 self.assertIsNotNone(db_api.share_get(test_ctxt, share['id']))
435 elif read_deleted == 'only': 435 ↛ 441line 435 didn't jump to line 441 because the condition on line 435 was always true
436 self.assertRaises(exception.NotFound, db_api.share_get,
437 test_ctxt, share['id'])
439 # we don't use the to be tested context here and
440 # we need to delete the share instance before we can delete the share
441 db_api.share_instance_delete(admin_ctxt, share['instance']['id'])
442 db_api.share_delete(admin_ctxt, share['id'])
444 if read_deleted in ('yes', 'only'):
445 self.assertIsNotNone(db_api.share_get(test_ctxt, share['id']))
446 elif read_deleted == 'no': 446 ↛ exitline 446 didn't return from function 'test_share_read_deleted' because the condition on line 446 was always true
447 self.assertRaises(exception.NotFound, db_api.share_get,
448 test_ctxt, share['id'])
450 def test_share_filter_by_host_with_pools(self):
451 share_instances = [[
452 db_api.share_create(self.ctxt, {'host': value}).instance
453 for value in ('foo', 'foo#pool0')]]
455 db_utils.create_share()
456 self._assertEqualListsOfObjects(share_instances[0],
457 db_api.share_instance_get_all_by_host(
458 self.ctxt, 'foo'),
459 ignored_keys=['share_type',
460 'share_type_id',
461 'export_locations'])
463 def test_share_filter_all_by_host_with_pools_multiple_hosts(self):
464 share_instances = [[
465 db_api.share_create(self.ctxt, {'host': value}).instance
466 for value in ('foo', 'foo#pool0', 'foo', 'foo#pool1')]]
468 db_utils.create_share()
469 self._assertEqualListsOfObjects(share_instances[0],
470 db_api.share_instance_get_all_by_host(
471 self.ctxt, 'foo'),
472 ignored_keys=['share_type',
473 'share_type_id',
474 'export_locations'])
476 def test_share_filter_all_by_share_server(self):
477 share_network = db_utils.create_share_network()
478 share_server = db_utils.create_share_server()
479 share = db_utils.create_share(share_server_id=share_server['id'],
480 share_network_id=share_network['id'])
482 actual_result = db_api.share_get_all_by_share_server(
483 self.ctxt, share_server['id'])
485 self.assertEqual(1, len(actual_result))
486 self.assertEqual(share['id'], actual_result[0].id)
488 def test_share_in_recycle_bin_filter_all_by_share_server(self):
489 share_network = db_utils.create_share_network()
490 share_server = db_utils.create_share_server()
491 share = db_utils.create_share(share_server_id=share_server['id'],
492 share_network_id=share_network['id'],
493 is_soft_deleted=True)
495 actual_result = db_api.share_get_all_soft_deleted(
496 self.ctxt, share_server['id'])
498 self.assertEqual(1, len(actual_result))
499 self.assertEqual(share['id'], actual_result[0].id)
501 def test_share_in_recycle_bin_filter_all_by_share_network(self):
502 share_network = db_utils.create_share_network()
503 share_server = db_utils.create_share_server()
504 share = db_utils.create_share(share_server_id=share_server['id'],
505 share_network_id=share_network['id'],
506 is_soft_deleted=True)
508 actual_result = db_api.share_get_all_soft_deleted_by_network(
509 self.ctxt, share_network['id'])
511 self.assertEqual(1, len(actual_result))
512 self.assertEqual(share['id'], actual_result[0].id)
514 def test_share_filter_all_by_share_group(self):
515 group = db_utils.create_share_group()
516 share = db_utils.create_share(share_group_id=group['id'])
518 actual_result = db_api.share_get_all_by_share_group_id(
519 self.ctxt, group['id'])
521 self.assertEqual(1, len(actual_result))
522 self.assertEqual(share['id'], actual_result[0].id)
524 def test_share_instance_delete_with_share(self):
525 share = db_utils.create_share()
527 self.assertIsNotNone(db_api.share_get(self.ctxt, share['id']))
528 self.assertIsNotNone(db_api.share_metadata_get(self.ctxt, share['id']))
530 db_api.share_instance_delete(self.ctxt, share.instance['id'])
532 self.assertRaises(exception.NotFound, db_api.share_get,
533 self.ctxt, share['id'])
534 self.assertRaises(exception.NotFound, db_api.share_metadata_get,
535 self.ctxt, share['id'])
537 def test_share_instance_delete_with_share_need_to_update_usages(self):
538 share = db_utils.create_share()
540 self.assertIsNotNone(db_api.share_get(self.ctxt, share['id']))
541 self.assertIsNotNone(db_api.share_metadata_get(self.ctxt, share['id']))
543 self.mock_object(quota.QUOTAS, 'reserve',
544 mock.Mock(return_value='reservation'))
545 self.mock_object(quota.QUOTAS, 'commit')
547 db_api.share_instance_delete(
548 self.ctxt, share.instance['id'], need_to_update_usages=True)
550 self.assertRaises(exception.NotFound, db_api.share_get,
551 self.ctxt, share['id'])
552 self.assertRaises(exception.NotFound, db_api.share_metadata_get,
553 self.ctxt, share['id'])
554 quota.QUOTAS.reserve.assert_called_once_with(
555 self.ctxt,
556 project_id=share['project_id'],
557 shares=-1,
558 gigabytes=-share['size'],
559 share_type_id=None,
560 user_id=share['user_id']
561 )
562 quota.QUOTAS.commit.assert_called_once_with(
563 self.ctxt,
564 mock.ANY,
565 project_id=share['project_id'],
566 share_type_id=None,
567 user_id=share['user_id']
568 )
570 def test_share_instance_get(self):
571 share = db_utils.create_share()
573 instance = db_api.share_instance_get(self.ctxt, share.instance['id'])
575 self.assertEqual('share-%s' % instance['id'], instance['name'])
577 @ddt.data({'with_share_data': True, 'status': constants.STATUS_AVAILABLE},
578 {'with_share_data': False, 'status': None})
579 @ddt.unpack
580 def test_share_instance_get_all_by_host(self, with_share_data, status):
581 kwargs = {'status': status} if status else {}
582 db_utils.create_share(**kwargs)
583 instances = db_api.share_instance_get_all_by_host(
584 self.ctxt, 'fake_host', with_share_data=with_share_data,
585 status=status)
587 self.assertEqual(1, len(instances))
588 instance = instances[0]
590 self.assertEqual('share-%s' % instance['id'], instance['name'])
592 if with_share_data:
593 self.assertEqual('NFS', instance['share_proto'])
594 self.assertEqual(0, instance['size'])
595 else:
596 self.assertNotIn('share_proto', instance)
598 def test_share_instance_get_all_by_host_not_found_exception(self):
599 db_utils.create_share()
600 instances = db_api.share_instance_get_all_by_host(
601 self.ctxt, 'not_found_host', True)
603 self.assertEqual(0, len(instances))
605 @ddt.data(
606 {'status': constants.STATUS_AVAILABLE},
607 {'status': None})
608 @ddt.unpack
609 def test_share_instance_get_all_by_host_no_instance(self, status):
610 db_utils.create_share_without_instance()
611 instances = db_api.share_instance_get_all_by_host(
612 self.ctxt, "fake_host", with_share_data=True, status=status
613 )
615 self.assertEqual(0, len(instances))
617 def test_share_instance_get_all_by_share_group(self):
618 group = db_utils.create_share_group()
619 db_utils.create_share(share_group_id=group['id'])
620 db_utils.create_share()
622 instances = db_api.share_instance_get_all_by_share_group_id(
623 self.ctxt, group['id'])
625 self.assertEqual(1, len(instances))
626 instance = instances[0]
628 self.assertEqual('share-%s' % instance['id'], instance['name'])
630 @ddt.data('id', 'path')
631 def test_share_instance_get_all_by_export_location(self, type):
632 share = db_utils.create_share()
633 initial_location = ['fake_export_location']
634 db_api.export_locations_update(
635 self.ctxt, share.instance['id'], initial_location, False)
637 if type == 'id':
638 export_location = db_api.export_location_get_all_by_share_id(
639 self.ctxt, share['id'])
640 value = export_location[0]['uuid']
641 else:
642 value = 'fake_export_location'
644 instances = db_api.share_instance_get_all(
645 self.ctxt, filters={'export_location_' + type: value})
647 self.assertEqual(1, len(instances))
648 instance = instances[0]
650 self.assertEqual('share-%s' % instance['id'], instance['name'])
652 def test_share_instance_get_all_by_is_soft_deleted(self):
653 db_utils.create_share()
654 db_utils.create_share(is_soft_deleted=True)
656 instances = db_api.share_instance_get_all(
657 self.ctxt, filters={'is_soft_deleted': True})
659 self.assertEqual(1, len(instances))
660 instance = instances[0]
662 self.assertEqual('share-%s' % instance['id'], instance['name'])
664 def test_share_instance_get_all_by_status(self):
665 share = db_utils.create_share()
666 db_utils.create_share_instance(
667 share_id=share['id'], status='creating')
668 share2 = db_utils.create_share()
669 db_utils.create_share_instance(
670 share_id=share2['id'], status='error_deferred_deleting')
672 instances = db_api.share_instance_get_all(
673 self.ctxt, filters={'status': 'error_deferred_deleting'})
674 self.assertEqual(1, len(instances))
676 def test_share_instance_get_all_by_ids(self):
677 fake_share = db_utils.create_share()
678 expected_share_instance = db_utils.create_share_instance(
679 share_id=fake_share['id'])
681 # Populate the db with a dummy share
682 db_utils.create_share_instance(share_id=fake_share['id'])
684 instances = db_api.share_instance_get_all(
685 self.ctxt,
686 filters={'instance_ids': [expected_share_instance['id']]})
688 self.assertEqual(1, len(instances))
689 instance = instances[0]
691 self.assertEqual('share-%s' % instance['id'], instance['name'])
693 @ddt.data('host', 'share_group_id')
694 def test_share_get_all_sort_by_share_instance_fields(self, sort_key):
695 shares = [db_utils.create_share(**{sort_key: n, 'size': 1})
696 for n in ('test1', 'test2')]
698 actual_result = db_api.share_get_all(
699 self.ctxt, sort_key=sort_key, sort_dir='desc')
701 self.assertEqual(2, len(actual_result))
702 self.assertEqual(shares[0]['id'], actual_result[1]['id'])
704 @ddt.data('id')
705 def test_share_get_all_sort_by_share_fields(self, sort_key):
706 shares = [db_utils.create_share(**{sort_key: n, 'size': 1})
707 for n in ('FAKE_UUID1', 'FAKE_UUID2')]
709 actual_result = db_api.share_get_all(
710 self.ctxt, sort_key=sort_key, sort_dir='desc')
712 self.assertEqual(2, len(actual_result))
713 self.assertEqual(shares[0]['id'], actual_result[1]['id'])
715 @ddt.data('id', 'path')
716 def test_share_get_all_by_export_location(self, type):
717 share = db_utils.create_share()
718 initial_location = ['fake_export_location']
719 db_api.export_locations_update(
720 self.ctxt, share.instance['id'], initial_location, False)
721 if type == 'id':
722 export_location = db_api.export_location_get_all_by_share_id(
723 self.ctxt, share['id'])
724 value = export_location[0]['uuid']
725 else:
726 value = 'fake_export_location'
728 actual_result = db_api.share_get_all(
729 self.ctxt, filters={'export_location_' + type: value})
731 self.assertEqual(1, len(actual_result))
732 self.assertEqual(share['id'], actual_result[0]['id'])
734 @ddt.data('id', 'path')
735 def test_share_get_all_by_export_location_not_exist(self, type):
736 share = db_utils.create_share()
737 initial_location = ['fake_export_location']
738 db_api.export_locations_update(
739 self.ctxt, share.instance['id'], initial_location, False)
740 filter = {'export_location_' + type: 'export_location_not_exist'}
741 actual_result = db_api.share_get_all(self.ctxt, filters=filter)
743 self.assertEqual(0, len(actual_result))
745 @ddt.data((10, 5), (20, 5))
746 @ddt.unpack
747 def test_share_get_all_with_limit(self, limit, offset):
748 for i in range(limit + 5):
749 db_utils.create_share()
751 filters = {'limit': offset, 'offset': 0}
752 shares_not_requested = db_api.share_get_all(
753 self.ctxt, filters=filters)
755 filters = {'limit': limit, 'offset': offset}
756 shares_requested = db_api.share_get_all(self.ctxt, filters=filters)
758 shares_not_requested_ids = [s['id'] for s in shares_not_requested]
759 shares_requested_ids = [s['id'] for s in shares_requested]
761 self.assertEqual(offset, len(shares_not_requested_ids))
762 self.assertEqual(limit, len(shares_requested_ids))
763 self.assertEqual(0, len(
764 set(shares_requested_ids) & set(shares_not_requested_ids)))
766 @ddt.data(
767 ({'display_name~': 'fake_name'}, 3, 3),
768 ({'display_name~': 'fake_name', 'limit': 2}, 3, 2)
769 )
770 @ddt.unpack
771 def test_share_get_all_with_count(self, filters, amount_of_shares,
772 expected_shares_len):
773 c_shares = [
774 db_utils.create_share(display_name='fake_name_%s' % str(i))
775 for i in range(amount_of_shares)]
777 # create one more share instance
778 db_utils.create_share_instance(share_id=c_shares[0]['id'])
779 db_utils.create_share_instance(share_id=c_shares[1]['id'])
781 count, shares = db_api.share_get_all_with_count(
782 self.ctxt, filters=filters)
784 self.assertEqual(count, amount_of_shares)
785 for share in shares:
786 self.assertIn('fake_name', share['display_name'])
787 self.assertEqual(expected_shares_len, len(shares))
789 def test_share_get_all_by_share_group_id_with_count(self):
790 share_groups = [db_utils.create_share_group() for i in range(2)]
791 shares = [
792 db_utils.create_share(share_group_id=share_group['id'])
793 for share_group in share_groups]
795 count, result = db_api.share_get_all_by_share_group_id_with_count(
796 self.ctxt, share_groups[0]['id'])
798 self.assertEqual(count, 1)
799 self.assertEqual(shares[0]['id'], result[0]['id'])
800 self.assertEqual(1, len(result))
802 def test_share_get_all_by_share_server_with_count(self):
803 share_servers = [db_utils.create_share_server() for i in range(2)]
804 shares = [
805 db_utils.create_share(share_server_id=share_server['id'])
806 for share_server in share_servers]
808 count, result = db_api.share_get_all_by_share_server_with_count(
809 self.ctxt, share_servers[0]['id'])
811 self.assertEqual(count, 1)
812 self.assertEqual(shares[0]['id'], result[0]['id'])
813 self.assertEqual(1, len(result))
815 def test_share_get_all_by_project_with_count(self):
816 project_ids = ['fake_id_1', 'fake_id_2']
817 shares = [
818 db_utils.create_share(project_id=project_id)
819 for project_id in project_ids]
821 count, result = db_api.share_get_all_by_project_with_count(
822 self.ctxt, project_ids[0])
824 self.assertEqual(count, 1)
825 self.assertEqual(shares[0]['id'], result[0]['id'])
826 self.assertEqual(1, len(result))
828 def test_share_get_all_expired(self):
829 now_time = timeutils.utcnow()
830 time_delta = datetime.timedelta(seconds=3600)
831 time1 = now_time + time_delta
832 time2 = now_time - time_delta
833 share1 = db_utils.create_share(status=constants.STATUS_AVAILABLE,
834 is_soft_deleted=False,
835 scheduled_to_be_deleted_at=None)
836 share2 = db_utils.create_share(status=constants.STATUS_AVAILABLE,
837 is_soft_deleted=True,
838 scheduled_to_be_deleted_at=time1)
839 share3 = db_utils.create_share(status=constants.STATUS_AVAILABLE,
840 is_soft_deleted=True,
841 scheduled_to_be_deleted_at=time2)
842 shares = [share1, share2, share3]
843 result = db_api.share_get_all_expired(self.ctxt)
844 self.assertEqual(1, len(result))
845 self.assertEqual(shares[2]['id'], result[0]['id'])
847 @ddt.data(
848 ({'status': constants.STATUS_AVAILABLE}, 'status',
849 [constants.STATUS_AVAILABLE, constants.STATUS_ERROR]),
850 ({'share_group_id': 'fake_group_id'}, 'share_group_id',
851 ['fake_group_id', 'group_id']),
852 ({'snapshot_id': 'fake_snapshot_id'}, 'snapshot_id',
853 ['fake_snapshot_id', 'snapshot_id']),
854 ({'share_type_id': 'fake_type_id'}, 'share_type_id',
855 ['fake_type_id', 'type_id']),
856 ({'host': 'fakehost@fakebackend#fakepool'}, 'host',
857 ['fakehost@fakebackend#fakepool', 'foo@bar#test']),
858 ({'share_network_id': 'fake_net_id'}, 'share_network_id',
859 ['fake_net_id', 'net_id']),
860 ({'display_name': 'fake_share_name'}, 'display_name',
861 ['fake_share_name', 'share_name']),
862 ({'display_description': 'fake description'}, 'display_description',
863 ['fake description', 'description']),
864 ({'is_soft_deleted': True}, 'is_soft_deleted',
865 [True, False])
866 )
867 @ddt.unpack
868 def test_share_get_all_with_filters(self, filters, key, share_values):
869 for value in share_values:
870 kwargs = {key: value}
871 db_utils.create_share(**kwargs)
873 results = db_api.share_get_all(self.ctxt, filters=filters)
875 for share in results:
876 self.assertEqual(share[key], filters[key])
878 @ddt.data(
879 ('display_name~', 'display_name',
880 ['fake_name_1', 'fake_name_2', 'fake_name_3'], 'fake_name'),
881 ('display_description~', 'display_description',
882 ['fake desc 1', 'fake desc 2', 'fake desc 3'], 'fake desc')
883 )
884 @ddt.unpack
885 def test_share_get_all_like_filters(
886 self, filter_name, key, share_values, like_value):
887 for value in share_values:
888 kwargs = {key: value}
889 db_utils.create_share(**kwargs)
890 db_utils.create_share(
891 display_name='irrelevant_name',
892 display_description='should not be queried')
894 filters = {filter_name: like_value}
896 results = db_api.share_get_all(self.ctxt, filters=filters)
898 self.assertEqual(len(share_values), len(results))
900 @ddt.data(
901 ('display_name~', 'display_name',
902 ['fake_name_1', 'fake_name_2', 'fake_name_%'], '%'),
903 ('display_description~', 'display_description',
904 ['fake desc 1', 'fake desc 2', 'fake desc %'], '%')
905 )
906 @ddt.unpack
907 def test_share_get_all_like_filters_with_percent_sign(
908 self, filter_name, key, share_values, like_value):
909 for value in share_values:
910 kwargs = {key: value}
911 db_utils.create_share(**kwargs)
912 db_utils.create_share(
913 display_name='irrelevant_name',
914 display_description='should not be queried')
916 filters = {filter_name: like_value}
918 results = db_api.share_get_all(self.ctxt, filters=filters)
920 self.assertEqual(1, len(results))
922 @ddt.data(None, 'writable')
923 def test_share_get_has_replicas_field(self, replication_type):
924 share = db_utils.create_share(replication_type=replication_type)
926 db_share = db_api.share_get(self.ctxt, share['id'])
928 self.assertIn('has_replicas', db_share)
930 @ddt.data({'with_share_data': False, 'with_share_server': False},
931 {'with_share_data': False, 'with_share_server': True},
932 {'with_share_data': True, 'with_share_server': False},
933 {'with_share_data': True, 'with_share_server': True})
934 @ddt.unpack
935 def test_share_replicas_get_all(self, with_share_data,
936 with_share_server):
937 share_server = db_utils.create_share_server()
938 share_1 = db_utils.create_share()
939 share_2 = db_utils.create_share()
940 db_utils.create_share_replica(
941 replica_state=constants.REPLICA_STATE_ACTIVE,
942 share_id=share_1['id'],
943 share_server_id=share_server['id'])
944 db_utils.create_share_replica(
945 replica_state=constants.REPLICA_STATE_IN_SYNC,
946 share_id=share_1['id'],
947 share_server_id=share_server['id'])
948 db_utils.create_share_replica(
949 replica_state=constants.REPLICA_STATE_OUT_OF_SYNC,
950 share_id=share_2['id'],
951 share_server_id=share_server['id'])
952 db_utils.create_share_replica(share_id=share_2['id'])
953 expected_ss_keys = {
954 'backend_details', 'host', 'id',
955 'share_network_subnet_ids', 'status',
956 }
957 expected_share_keys = {
958 'project_id', 'share_type_id', 'display_name',
959 'name', 'share_proto', 'is_public',
960 'source_share_group_snapshot_member_id',
961 }
963 share_replicas = db_api.share_replicas_get_all(
964 self.ctxt, with_share_server=with_share_server,
965 with_share_data=with_share_data,
966 )
968 self.assertEqual(3, len(share_replicas))
969 for replica in share_replicas:
970 if with_share_server:
971 self.assertTrue(expected_ss_keys.issubset(
972 replica['share_server'].keys()))
973 else:
974 self.assertNotIn('share_server', replica.keys())
975 self.assertEqual(
976 with_share_data,
977 expected_share_keys.issubset(replica.keys()))
979 @ddt.data({'with_share_data': False, 'with_share_server': False},
980 {'with_share_data': False, 'with_share_server': True},
981 {'with_share_data': True, 'with_share_server': False},
982 {'with_share_data': True, 'with_share_server': True})
983 @ddt.unpack
984 def test_share_replicas_get_all_by_share(self, with_share_data,
985 with_share_server):
986 share_server = db_utils.create_share_server()
987 share = db_utils.create_share()
988 db_utils.create_share_replica(
989 replica_state=constants.REPLICA_STATE_ACTIVE,
990 share_id=share['id'],
991 share_server_id=share_server['id'])
992 db_utils.create_share_replica(
993 replica_state=constants.REPLICA_STATE_IN_SYNC,
994 share_id=share['id'],
995 share_server_id=share_server['id'])
996 db_utils.create_share_replica(
997 replica_state=constants.REPLICA_STATE_OUT_OF_SYNC,
998 share_id=share['id'],
999 share_server_id=share_server['id'])
1000 expected_ss_keys = {
1001 'backend_details', 'host', 'id',
1002 'share_network_subnet_ids', 'status',
1003 }
1004 expected_share_keys = {
1005 'project_id', 'share_type_id', 'display_name',
1006 'name', 'share_proto', 'is_public',
1007 'source_share_group_snapshot_member_id',
1008 }
1010 share_replicas = db_api.share_replicas_get_all_by_share(
1011 self.ctxt, share['id'],
1012 with_share_server=with_share_server,
1013 with_share_data=with_share_data)
1015 self.assertEqual(3, len(share_replicas))
1016 for replica in share_replicas:
1017 if with_share_server:
1018 self.assertTrue(expected_ss_keys.issubset(
1019 replica['share_server'].keys()))
1020 else:
1021 self.assertNotIn('share_server', replica.keys())
1022 self.assertEqual(with_share_data,
1023 expected_share_keys.issubset(replica.keys()))
1025 def test_share_replicas_get_available_active_replica(self):
1026 share_server = db_utils.create_share_server()
1027 share_1 = db_utils.create_share()
1028 share_2 = db_utils.create_share()
1029 share_3 = db_utils.create_share()
1030 db_utils.create_share_replica(
1031 id='Replica1',
1032 share_id=share_1['id'],
1033 status=constants.STATUS_AVAILABLE,
1034 replica_state=constants.REPLICA_STATE_ACTIVE,
1035 share_server_id=share_server['id'])
1036 db_utils.create_share_replica(
1037 id='Replica2',
1038 status=constants.STATUS_AVAILABLE,
1039 share_id=share_1['id'],
1040 replica_state=constants.REPLICA_STATE_ACTIVE,
1041 share_server_id=share_server['id'])
1042 db_utils.create_share_replica(
1043 id='Replica3',
1044 status=constants.STATUS_AVAILABLE,
1045 share_id=share_2['id'],
1046 replica_state=constants.REPLICA_STATE_ACTIVE)
1047 db_utils.create_share_replica(
1048 id='Replica4',
1049 status=constants.STATUS_ERROR,
1050 share_id=share_2['id'],
1051 replica_state=constants.REPLICA_STATE_ACTIVE)
1052 db_utils.create_share_replica(
1053 id='Replica5',
1054 status=constants.STATUS_AVAILABLE,
1055 share_id=share_2['id'],
1056 replica_state=constants.REPLICA_STATE_IN_SYNC)
1057 db_utils.create_share_replica(
1058 id='Replica6',
1059 share_id=share_3['id'],
1060 status=constants.STATUS_AVAILABLE,
1061 replica_state=constants.REPLICA_STATE_IN_SYNC)
1062 expected_ss_keys = {
1063 'backend_details', 'host', 'id',
1064 'share_network_subnet_ids', 'status',
1065 }
1066 expected_share_keys = {
1067 'project_id', 'share_type_id', 'display_name',
1068 'name', 'share_proto', 'is_public',
1069 'source_share_group_snapshot_member_id',
1070 }
1072 replica_share_1 = (
1073 db_api.share_replicas_get_available_active_replica(
1074 self.ctxt, share_1['id'], with_share_server=True,
1075 )
1076 )
1077 replica_share_2 = (
1078 db_api.share_replicas_get_available_active_replica(
1079 self.ctxt, share_2['id'], with_share_server=True,
1080 with_share_data=True)
1081 )
1082 replica_share_3 = (
1083 db_api.share_replicas_get_available_active_replica(
1084 self.ctxt, share_3['id'],
1085 )
1086 )
1088 self.assertIn(replica_share_1.get('id'), ['Replica1', 'Replica2'])
1089 self.assertTrue(expected_ss_keys.issubset(
1090 replica_share_1['share_server'].keys()))
1091 self.assertFalse(
1092 expected_share_keys.issubset(replica_share_1.keys()))
1093 self.assertEqual(replica_share_2.get('id'), 'Replica3')
1094 self.assertFalse(replica_share_2['share_server'])
1095 self.assertTrue(
1096 expected_share_keys.issubset(replica_share_2.keys()))
1097 self.assertIsNone(replica_share_3)
1099 def test_share_replica_get_exception(self):
1100 replica = db_utils.create_share_replica(share_id='FAKE_SHARE_ID')
1102 self.assertRaises(exception.ShareReplicaNotFound,
1103 db_api.share_replica_get,
1104 self.ctxt, replica['id'])
1106 def test_share_replica_get_without_share_data(self):
1107 share = db_utils.create_share()
1108 replica = db_utils.create_share_replica(
1109 share_id=share['id'],
1110 replica_state=constants.REPLICA_STATE_ACTIVE)
1111 expected_extra_keys = {
1112 'project_id', 'share_type_id', 'display_name',
1113 'name', 'share_proto', 'is_public',
1114 'source_share_group_snapshot_member_id',
1115 }
1117 share_replica = db_api.share_replica_get(self.ctxt, replica['id'])
1119 self.assertIsNotNone(share_replica['replica_state'])
1120 self.assertEqual(share['id'], share_replica['share_id'])
1121 self.assertFalse(expected_extra_keys.issubset(share_replica.keys()))
1123 def test_share_replica_get_with_share_data(self):
1124 share = db_utils.create_share()
1125 replica = db_utils.create_share_replica(
1126 share_id=share['id'],
1127 replica_state=constants.REPLICA_STATE_ACTIVE)
1128 expected_extra_keys = {
1129 'project_id', 'share_type_id', 'display_name',
1130 'name', 'share_proto', 'is_public',
1131 'source_share_group_snapshot_member_id',
1132 }
1134 share_replica = db_api.share_replica_get(
1135 self.ctxt, replica['id'], with_share_data=True)
1137 self.assertIsNotNone(share_replica['replica_state'])
1138 self.assertEqual(share['id'], share_replica['share_id'])
1139 self.assertTrue(expected_extra_keys.issubset(share_replica.keys()))
1141 def test_share_replica_get_with_share_server(self):
1142 share_server = db_utils.create_share_server()
1143 share = db_utils.create_share()
1144 replica = db_utils.create_share_replica(
1145 share_id=share['id'],
1146 replica_state=constants.REPLICA_STATE_ACTIVE,
1147 share_server_id=share_server['id']
1148 )
1149 expected_extra_keys = {
1150 'backend_details', 'host', 'id',
1151 'share_network_subnet_ids', 'status',
1152 }
1154 share_replica = db_api.share_replica_get(
1155 self.ctxt, replica['id'], with_share_server=True,
1156 )
1158 self.assertIsNotNone(share_replica['replica_state'])
1159 self.assertEqual(
1160 share_server['id'], share_replica['share_server_id'])
1161 self.assertTrue(expected_extra_keys.issubset(
1162 share_replica['share_server'].keys()))
1164 def test_share_replica_update(self):
1165 share = db_utils.create_share()
1166 replica = db_utils.create_share_replica(
1167 share_id=share['id'], replica_state=constants.REPLICA_STATE_ACTIVE)
1169 updated_replica = db_api.share_replica_update(
1170 self.ctxt, replica['id'],
1171 {'replica_state': constants.REPLICA_STATE_OUT_OF_SYNC})
1173 self.assertEqual(constants.REPLICA_STATE_OUT_OF_SYNC,
1174 updated_replica['replica_state'])
1176 def test_share_replica_delete(self):
1177 share = db_utils.create_share()
1178 share = db_api.share_get(self.ctxt, share['id'])
1179 self.mock_object(quota.QUOTAS, 'reserve',
1180 mock.Mock(return_value='reservation'))
1181 self.mock_object(quota.QUOTAS, 'commit')
1182 replica = db_utils.create_share_replica(
1183 share_id=share['id'], replica_state=constants.REPLICA_STATE_ACTIVE)
1185 self.assertEqual(1, len(
1186 db_api.share_replicas_get_all_by_share(self.ctxt, share['id'])))
1188 db_api.share_replica_delete(self.ctxt, replica['id'])
1190 self.assertEqual(
1191 [], db_api.share_replicas_get_all_by_share(self.ctxt, share['id']))
1192 share_type_id = share['instances'][0].get('share_type_id', None)
1193 quota.QUOTAS.reserve.assert_called_once_with(
1194 self.ctxt, project_id=share['project_id'],
1195 user_id=share['user_id'], share_type_id=share_type_id,
1196 share_replicas=-1, replica_gigabytes=share['size'])
1197 quota.QUOTAS.commit.assert_called_once_with(
1198 self.ctxt, 'reservation', project_id=share['project_id'],
1199 user_id=share['user_id'], share_type_id=share_type_id)
1201 @ddt.data(
1202 (True, {"share_replicas": -1, "replica_gigabytes": 0}, 'active'),
1203 (False, {"shares": -1, "gigabytes": 0}, None),
1204 (False, {"shares": -1, "gigabytes": 0,
1205 "share_replicas": -1, "replica_gigabytes": 0}, 'active')
1206 )
1207 @ddt.unpack
1208 def test_share_instance_delete_quota_error(self, is_replica, deltas,
1209 replica_state):
1210 share = db_utils.create_share(replica_state=replica_state)
1211 share = db_api.share_get(self.ctxt, share['id'])
1212 instance_id = share['instances'][0]['id']
1214 if is_replica:
1215 replica = db_utils.create_share_replica(
1216 share_id=share['id'],
1217 replica_state=constants.REPLICA_STATE_ACTIVE)
1218 instance_id = replica['id']
1219 reservation = 'fake'
1220 share_type_id = share['instances'][0]['share_type_id']
1222 self.mock_object(quota.QUOTAS, 'reserve',
1223 mock.Mock(return_value=reservation))
1224 self.mock_object(quota.QUOTAS, 'commit', mock.Mock(
1225 side_effect=exception.QuotaError('fake')))
1226 self.mock_object(quota.QUOTAS, 'rollback')
1228 # NOTE(silvacarlose): not calling with assertRaises since the
1229 # _update_share_instance_usages method is not raising an exception
1230 db_api.share_instance_delete(
1231 self.ctxt, instance_id, need_to_update_usages=True)
1233 quota.QUOTAS.reserve.assert_called_once_with(
1234 self.ctxt, project_id=share['project_id'],
1235 user_id=share['user_id'], share_type_id=share_type_id, **deltas)
1236 quota.QUOTAS.commit.assert_called_once_with(
1237 self.ctxt, reservation, project_id=share['project_id'],
1238 user_id=share['user_id'], share_type_id=share_type_id)
1239 quota.QUOTAS.rollback.assert_called_once_with(
1240 self.ctxt, reservation, share_type_id=share_type_id)
1242 def test_share_instance_access_copy(self):
1243 share = db_utils.create_share()
1244 rules = []
1245 for i in range(0, 5):
1246 rules.append(db_utils.create_access(share_id=share['id']))
1248 instance = db_utils.create_share_instance(share_id=share['id'])
1250 share_access_rules = db_api.share_instance_access_copy(
1251 self.ctxt, share['id'], instance['id'])
1252 share_access_rule_ids = [a['id'] for a in share_access_rules]
1254 self.assertEqual(5, len(share_access_rules))
1255 for rule_id in share_access_rule_ids:
1256 self.assertIsNotNone(
1257 db_api.share_instance_access_get(
1258 self.ctxt, rule_id, instance['id']))
1260 def test_share_soft_delete(self):
1261 share = db_utils.create_share()
1262 db_api.share_soft_delete(self.ctxt, share['id'])
1263 share = db_api.share_get(self.ctxt, share['id'])
1265 self.assertEqual(share['is_soft_deleted'], True)
1267 def test_share_restore(self):
1268 share = db_utils.create_share(is_soft_deleted=True)
1269 db_api.share_restore(self.ctxt, share['id'])
1270 share = db_api.share_get(self.ctxt, share['id'])
1272 self.assertEqual(share['is_soft_deleted'], False)
1274 def test_share_metadata_get(self):
1275 metadata = {'a': 'b', 'c': 'd'}
1277 share_1 = db_utils.create_share(size=1)
1278 db_api.share_metadata_update(
1279 self.ctxt, share_id=share_1['id'],
1280 metadata=metadata, delete=False)
1281 self.assertEqual(
1282 metadata, db_api.share_metadata_get(
1283 self.ctxt, share_id=share_1['id']))
1285 def test_share_metadata_get_item(self):
1286 metadata = {'a': 'b', 'c': 'd'}
1287 key = 'a'
1288 shouldbe = {'a': 'b'}
1289 share_1 = db_utils.create_share(size=1)
1290 db_api.share_metadata_update(
1291 self.ctxt, share_id=share_1['id'],
1292 metadata=metadata, delete=False)
1293 self.assertEqual(
1294 shouldbe, db_api.share_metadata_get_item(
1295 self.ctxt, share_id=share_1['id'],
1296 key=key))
1298 def test_share_metadata_update(self):
1299 metadata1 = {'a': '1', 'c': '2'}
1300 metadata2 = {'a': '3', 'd': '5'}
1301 should_be = {'a': '3', 'c': '2', 'd': '5'}
1302 share_1 = db_utils.create_share(size=1)
1303 db_api.share_metadata_update(
1304 self.ctxt, share_id=share_1['id'],
1305 metadata=metadata1, delete=False)
1306 db_api.share_metadata_update(
1307 self.ctxt, share_id=share_1['id'],
1308 metadata=metadata2, delete=False)
1309 self.assertEqual(
1310 should_be, db_api.share_metadata_get(
1311 self.ctxt, share_id=share_1['id']))
1313 def test_share_metadata_update_item(self):
1314 metadata1 = {'a': '1', 'c': '2'}
1315 metadata2 = {'a': '3'}
1316 should_be = {'a': '3', 'c': '2'}
1317 share_1 = db_utils.create_share(size=1)
1318 db_api.share_metadata_update(
1319 self.ctxt, share_id=share_1['id'],
1320 metadata=metadata1, delete=False)
1321 db_api.share_metadata_update_item(
1322 self.ctxt, share_id=share_1['id'],
1323 item=metadata2)
1324 self.assertEqual(
1325 should_be, db_api.share_metadata_get(
1326 self.ctxt, share_id=share_1['id']))
1328 def test_share_metadata_delete(self):
1329 key = 'a'
1330 metadata = {'a': '1', 'c': '2'}
1331 should_be = {'c': '2'}
1332 share_1 = db_utils.create_share(size=1)
1333 db_api.share_metadata_update(
1334 self.ctxt, share_id=share_1['id'],
1335 metadata=metadata, delete=False)
1336 db_api.share_metadata_delete(
1337 self.ctxt, share_id=share_1['id'],
1338 key=key)
1339 self.assertEqual(
1340 should_be, db_api.share_metadata_get(
1341 self.ctxt, share_id=share_1['id']))
1344@ddt.ddt
1345class ShareGroupDatabaseAPITestCase(test.TestCase):
1346 def setUp(self):
1347 """Run before each test."""
1348 super(ShareGroupDatabaseAPITestCase, self).setUp()
1349 self.ctxt = context.get_admin_context()
1351 def test_share_group_create_with_share_type(self):
1352 fake_share_types = ["fake_share_type"]
1353 share_group = db_utils.create_share_group(share_types=fake_share_types)
1354 share_group = db_api.share_group_get(self.ctxt, share_group['id'])
1356 self.assertEqual(1, len(share_group['share_types']))
1358 def test_share_group_get(self):
1359 share_group = db_utils.create_share_group()
1361 self.assertDictEqual(
1362 dict(share_group),
1363 dict(db_api.share_group_get(self.ctxt, share_group['id'])))
1365 def test_count_share_groups_in_share_network(self):
1366 share_network = db_utils.create_share_network()
1367 db_utils.create_share_group()
1368 db_utils.create_share_group(share_network_id=share_network['id'])
1370 count = db_api.count_share_groups_in_share_network(
1371 self.ctxt, share_network_id=share_network['id'])
1373 self.assertEqual(1, count)
1375 def test_share_group_get_all(self):
1376 expected_share_group = db_utils.create_share_group()
1378 share_groups = db_api.share_group_get_all(self.ctxt, detailed=False)
1380 self.assertEqual(1, len(share_groups))
1381 share_group = share_groups[0]
1382 self.assertEqual(2, len(dict(share_group).keys()))
1383 self.assertEqual(expected_share_group['id'], share_group['id'])
1384 self.assertEqual(expected_share_group['name'], share_group['name'])
1386 def test_share_group_get_all_with_detail(self):
1387 expected_share_group = db_utils.create_share_group()
1389 share_groups = db_api.share_group_get_all(self.ctxt, detailed=True)
1391 self.assertEqual(1, len(share_groups))
1392 self.assertDictEqual(dict(expected_share_group), dict(share_groups[0]))
1394 def test_share_group_get_all_by_host(self):
1395 fake_host = 'my_fake_host'
1396 expected_share_group = db_utils.create_share_group(host=fake_host)
1397 db_utils.create_share_group()
1399 share_groups = db_api.share_group_get_all_by_host(
1400 self.ctxt, fake_host, detailed=False)
1402 self.assertEqual(1, len(share_groups))
1403 share_group = share_groups[0]
1404 self.assertEqual(2, len(dict(share_group).keys()))
1405 self.assertEqual(expected_share_group['id'], share_group['id'])
1406 self.assertEqual(expected_share_group['name'], share_group['name'])
1408 def test_share_group_get_all_by_host_with_details(self):
1409 fake_host = 'my_fake_host'
1410 expected_share_group = db_utils.create_share_group(host=fake_host)
1411 db_utils.create_share_group()
1413 share_groups = db_api.share_group_get_all_by_host(
1414 self.ctxt, fake_host, detailed=True)
1416 self.assertEqual(1, len(share_groups))
1417 share_group = share_groups[0]
1418 self.assertDictEqual(dict(expected_share_group), dict(share_group))
1419 self.assertEqual(fake_host, share_group['host'])
1421 def test_share_group_get_all_by_project(self):
1422 fake_project = 'fake_project'
1423 expected_group = db_utils.create_share_group(
1424 project_id=fake_project)
1425 db_utils.create_share_group()
1427 groups = db_api.share_group_get_all_by_project(self.ctxt,
1428 fake_project,
1429 detailed=False)
1431 self.assertEqual(1, len(groups))
1432 group = groups[0]
1433 self.assertEqual(2, len(dict(group).keys()))
1434 self.assertEqual(expected_group['id'], group['id'])
1435 self.assertEqual(expected_group['name'], group['name'])
1437 def test_share_group_get_all_by_share_server(self):
1438 fake_server = 123
1439 expected_group = db_utils.create_share_group(
1440 share_server_id=fake_server)
1441 db_utils.create_share_group()
1443 groups = db_api.share_group_get_all_by_share_server(self.ctxt,
1444 fake_server)
1446 self.assertEqual(1, len(groups))
1447 group = groups[0]
1448 self.assertEqual(expected_group['id'], group['id'])
1449 self.assertEqual(expected_group['name'], group['name'])
1451 def test_share_group_get_all_by_project_with_details(self):
1452 fake_project = 'fake_project'
1453 expected_group = db_utils.create_share_group(
1454 project_id=fake_project)
1455 db_utils.create_share_group()
1457 groups = db_api.share_group_get_all_by_project(self.ctxt,
1458 fake_project,
1459 detailed=True)
1461 self.assertEqual(1, len(groups))
1462 group = groups[0]
1463 self.assertDictEqual(dict(expected_group), dict(group))
1464 self.assertEqual(fake_project, group['project_id'])
1466 @ddt.data(({'name': 'fo'}, 0), ({'description': 'd'}, 0),
1467 ({'name': 'foo', 'description': 'd'}, 0),
1468 ({'name': 'foo'}, 1), ({'description': 'ds'}, 1),
1469 ({'name~': 'foo', 'description~': 'ds'}, 2),
1470 ({'name': 'foo', 'description~': 'ds'}, 1),
1471 ({'name~': 'foo', 'description': 'ds'}, 1))
1472 @ddt.unpack
1473 def test_share_group_get_all_by_name_and_description(
1474 self, search_opts, group_number):
1475 db_utils.create_share_group(name='fo1', description='d1')
1476 expected_group1 = db_utils.create_share_group(name='foo',
1477 description='ds')
1478 expected_group2 = db_utils.create_share_group(name='foo1',
1479 description='ds2')
1481 groups = db_api.share_group_get_all(
1482 self.ctxt, detailed=True,
1483 filters=search_opts)
1485 self.assertEqual(group_number, len(groups))
1486 if group_number == 1:
1487 self.assertDictEqual(dict(expected_group1), dict(groups[0]))
1488 elif group_number == 2:
1489 self.assertDictEqual(dict(expected_group1), dict(groups[1]))
1490 self.assertDictEqual(dict(expected_group2), dict(groups[0]))
1492 def test_share_group_update(self):
1493 fake_name = "my_fake_name"
1494 expected_group = db_utils.create_share_group()
1495 expected_group['name'] = fake_name
1497 db_api.share_group_update(self.ctxt,
1498 expected_group['id'],
1499 {'name': fake_name})
1501 group = db_api.share_group_get(self.ctxt, expected_group['id'])
1502 self.assertEqual(fake_name, group['name'])
1504 def test_share_group_destroy(self):
1505 group = db_utils.create_share_group()
1506 db_api.share_group_get(self.ctxt, group['id'])
1508 db_api.share_group_destroy(self.ctxt, group['id'])
1510 self.assertRaises(exception.NotFound, db_api.share_group_get,
1511 self.ctxt, group['id'])
1513 def test_count_shares_in_share_group(self):
1514 sg = db_utils.create_share_group()
1515 db_utils.create_share(share_group_id=sg['id'])
1516 db_utils.create_share()
1518 count = db_api.count_shares_in_share_group(self.ctxt, sg['id'])
1520 self.assertEqual(1, count)
1522 def test_count_sg_snapshots_in_share_group(self):
1523 sg = db_utils.create_share_group()
1524 db_utils.create_share_group_snapshot(sg['id'])
1525 db_utils.create_share_group_snapshot(sg['id'])
1527 count = db_api.count_share_group_snapshots_in_share_group(
1528 self.ctxt, sg['id'])
1530 self.assertEqual(2, count)
1532 def test_share_group_snapshot_get(self):
1533 sg = db_utils.create_share_group()
1534 sg_snap = dict(db_utils.create_share_group_snapshot(sg['id']))
1535 sg_snap_source_group = sg_snap.pop('share_group', {})
1536 get_sg_snap = dict(
1537 db_api.share_group_snapshot_get(self.ctxt, sg_snap['id']))
1538 get_sg_snap_source_group = get_sg_snap.pop('share_group', {})
1540 self.assertDictEqual(
1541 dict(sg_snap_source_group), dict(get_sg_snap_source_group))
1542 self.assertDictEqual(sg_snap, get_sg_snap)
1544 def test_share_group_snapshot_get_all(self):
1545 sg = db_utils.create_share_group()
1546 expected_sg_snap = db_utils.create_share_group_snapshot(sg['id'])
1548 snaps = db_api.share_group_snapshot_get_all(self.ctxt, detailed=False)
1550 self.assertEqual(1, len(snaps))
1551 snap = snaps[0]
1552 self.assertEqual(2, len(dict(snap).keys()))
1553 self.assertEqual(expected_sg_snap['id'], snap['id'])
1554 self.assertEqual(expected_sg_snap['name'], snap['name'])
1556 def test_share_group_snapshot_get_all_with_detail(self):
1557 sg = db_utils.create_share_group()
1558 expected_sg_snap = dict(db_utils.create_share_group_snapshot(sg['id']))
1559 sg_snap_source_group = expected_sg_snap.pop('share_group', {})
1561 snaps = db_api.share_group_snapshot_get_all(self.ctxt, detailed=True)
1563 self.assertEqual(1, len(snaps))
1564 actual_sg_snap = dict(snaps[0])
1565 get_sg_snap_source = actual_sg_snap.pop('share_group', {})
1566 self.assertDictEqual(
1567 dict(sg_snap_source_group), dict(get_sg_snap_source))
1568 self.assertDictEqual(expected_sg_snap, actual_sg_snap)
1570 def test_share_group_snapshot_get_all_by_project(self):
1571 fake_project = uuidutils.generate_uuid()
1572 sg = db_utils.create_share_group()
1573 expected_sg_snap = db_utils.create_share_group_snapshot(
1574 sg['id'], project_id=fake_project)
1576 snaps = db_api.share_group_snapshot_get_all_by_project(
1577 self.ctxt, fake_project, detailed=False)
1579 self.assertEqual(1, len(snaps))
1580 snap = snaps[0]
1581 self.assertEqual(2, len(dict(snap).keys()))
1582 self.assertEqual(expected_sg_snap['id'], snap['id'])
1583 self.assertEqual(expected_sg_snap['name'], snap['name'])
1585 def test_share_group_snapshot_get_all_by_project_with_details(self):
1586 fake_project = uuidutils.generate_uuid()
1587 sg = db_utils.create_share_group()
1588 expected_sg_snap = dict(db_utils.create_share_group_snapshot(
1589 sg['id'], project_id=fake_project))
1590 sg_snap_source_group = expected_sg_snap.pop(
1591 'share_group', {})
1593 snaps = db_api.share_group_snapshot_get_all_by_project(
1594 self.ctxt, fake_project, detailed=True)
1596 self.assertEqual(1, len(snaps))
1597 actual_snap = dict(snaps[0])
1598 get_sg_snap_source = actual_snap.pop('share_group', {})
1599 self.assertDictEqual(
1600 dict(sg_snap_source_group), dict(get_sg_snap_source))
1601 self.assertEqual(expected_sg_snap, actual_snap)
1602 self.assertEqual(fake_project, actual_snap['project_id'])
1604 def test_share_group_snapshot_update(self):
1605 fake_name = "my_fake_name"
1606 sg = db_utils.create_share_group()
1607 expected_sg_snap = db_utils.create_share_group_snapshot(sg['id'])
1608 expected_sg_snap['name'] = fake_name
1610 db_api.share_group_snapshot_update(
1611 self.ctxt, expected_sg_snap['id'], {'name': fake_name})
1613 sg_snap = db_api.share_group_snapshot_get(
1614 self.ctxt, expected_sg_snap['id'])
1615 self.assertEqual(fake_name, sg_snap['name'])
1617 def test_share_group_snapshot_destroy(self):
1618 sg = db_utils.create_share_group()
1619 sg_snap = db_utils.create_share_group_snapshot(sg['id'])
1620 db_api.share_group_snapshot_get(self.ctxt, sg_snap['id'])
1622 db_api.share_group_snapshot_destroy(self.ctxt, sg_snap['id'])
1624 self.assertRaises(
1625 exception.NotFound,
1626 db_api.share_group_snapshot_get, self.ctxt, sg_snap['id'])
1628 def test_share_group_snapshot_members_get_all(self):
1629 sg = db_utils.create_share_group()
1630 share = db_utils.create_share(share_group_id=sg['id'])
1631 si = db_utils.create_share_instance(share_id=share['id'])
1632 sg_snap = db_utils.create_share_group_snapshot(sg['id'])
1633 expected_member = dict(db_utils.create_share_group_snapshot_member(
1634 sg_snap['id'], share_instance_id=si['id']))
1635 sg_snap_source_member = expected_member.pop(
1636 'share_group_snapshot', {})
1637 sg_snap_source_member = expected_member.pop('share_instance', {})
1639 members = db_api.share_group_snapshot_members_get_all(
1640 self.ctxt, sg_snap['id'])
1642 self.assertEqual(1, len(members))
1643 member = dict(members[0])
1644 get_sg_snap_source_member = member.pop(
1645 'share_group_snapshot', {})
1646 get_sg_snap_source_member = member.pop('share_instance', {})
1647 self.assertDictEqual(dict(
1648 sg_snap_source_member), dict(get_sg_snap_source_member))
1649 self.assertDictEqual(expected_member, member)
1651 def test_count_share_group_snapshot_members_in_share(self):
1652 sg = db_utils.create_share_group()
1653 share = db_utils.create_share(share_group_id=sg['id'])
1654 si = db_utils.create_share_instance(share_id=share['id'])
1655 share2 = db_utils.create_share(share_group_id=sg['id'])
1656 si2 = db_utils.create_share_instance(share_id=share2['id'])
1657 sg_snap = db_utils.create_share_group_snapshot(sg['id'])
1658 db_utils.create_share_group_snapshot_member(
1659 sg_snap['id'], share_instance_id=si['id'])
1660 db_utils.create_share_group_snapshot_member(
1661 sg_snap['id'], share_instance_id=si2['id'])
1663 count = db_api.count_share_group_snapshot_members_in_share(
1664 self.ctxt, share['id'])
1666 self.assertEqual(1, count)
1668 def test_share_group_snapshot_members_get(self):
1669 sg = db_utils.create_share_group()
1670 share = db_utils.create_share(share_group_id=sg['id'])
1671 si = db_utils.create_share_instance(share_id=share['id'])
1672 sg_snap = db_utils.create_share_group_snapshot(sg['id'])
1673 expected_member = dict(db_utils.create_share_group_snapshot_member(
1674 sg_snap['id'], share_instance_id=si['id']))
1675 sg_snap_source_member = expected_member.pop('share_group_snapshot', {})
1676 sg_snap_source_member = expected_member.pop('share_instance', {})
1678 member = dict(db_api.share_group_snapshot_member_get(
1679 self.ctxt, expected_member['id']))
1680 get_sg_snap_source_member = member.pop('share_group_snapshot', {})
1681 get_sg_snap_source_member = member.pop('share_instance', {})
1683 self.assertDictEqual(dict(
1684 sg_snap_source_member), dict(get_sg_snap_source_member))
1685 self.assertDictEqual(expected_member, member)
1687 def test_share_group_snapshot_members_get_not_found(self):
1688 self.assertRaises(
1689 exception.ShareGroupSnapshotMemberNotFound,
1690 db_api.share_group_snapshot_member_get, self.ctxt, 'fake_id')
1692 def test_share_group_snapshot_member_update(self):
1693 sg = db_utils.create_share_group()
1694 share = db_utils.create_share(share_group_id=sg['id'])
1695 si = db_utils.create_share_instance(share_id=share['id'])
1696 sg_snap = db_utils.create_share_group_snapshot(sg['id'])
1697 expected_member = db_utils.create_share_group_snapshot_member(
1698 sg_snap['id'], share_instance_id=si['id'])
1700 db_api.share_group_snapshot_member_update(
1701 self.ctxt, expected_member['id'],
1702 {'status': constants.STATUS_AVAILABLE})
1704 member = db_api.share_group_snapshot_member_get(
1705 self.ctxt, expected_member['id'])
1706 self.assertEqual(constants.STATUS_AVAILABLE, member['status'])
1709@ddt.ddt
1710class ShareGroupTypeAPITestCase(test.TestCase):
1712 def setUp(self):
1713 super(ShareGroupTypeAPITestCase, self).setUp()
1714 self.ctxt = context.RequestContext(
1715 user_id='user_id', project_id='project_id', is_admin=True)
1717 @ddt.data(True, False)
1718 def test_share_type_destroy_in_use(self, used_by_groups):
1719 share_type_1 = db_utils.create_share_type(name='fike')
1720 share_type_2 = db_utils.create_share_type(name='bowman')
1721 share_group_type_1 = db_utils.create_share_group_type(
1722 name='orange', is_public=False, share_types=[share_type_1['id']],
1723 group_specs={'dabo': 'allin', 'cadence': 'count'},
1724 override_defaults=True)
1725 db_api.share_group_type_access_add(self.ctxt,
1726 share_group_type_1['id'],
1727 "2018ndaetfigovnsaslcahfavmrpions")
1728 db_api.share_group_type_access_add(self.ctxt,
1729 share_group_type_1['id'],
1730 "2016ndaetfigovnsaslcahfavmrpions")
1731 share_group_type_2 = db_utils.create_share_group_type(
1732 name='regalia', share_types=[share_type_2['id']])
1733 if used_by_groups:
1734 share_group_1 = db_utils.create_share_group(
1735 share_group_type_id=share_group_type_1['id'],
1736 share_types=[share_type_1['id']])
1737 share_group_2 = db_utils.create_share_group(
1738 share_group_type_id=share_group_type_2['id'],
1739 share_types=[share_type_2['id']])
1740 self.assertRaises(exception.ShareGroupTypeInUse,
1741 db_api.share_group_type_destroy,
1742 self.ctxt, share_group_type_1['id'])
1743 self.assertRaises(exception.ShareGroupTypeInUse,
1744 db_api.share_group_type_destroy,
1745 self.ctxt, share_group_type_2['id'])
1746 # Cleanup share groups
1747 db_api.share_group_destroy(self.ctxt, share_group_1['id'])
1748 db_api.share_group_destroy(self.ctxt, share_group_2['id'])
1750 # Let's cleanup share_group_type_1 and verify it is gone
1751 self.assertIsNone(db_api.share_group_type_destroy(
1752 self.ctxt, share_group_type_1['id']))
1753 self.assertDictEqual(
1754 {}, db_api.share_group_type_specs_get(
1755 self.ctxt, share_group_type_1['id']))
1756 self.assertRaises(exception.ShareGroupTypeNotFound,
1757 db_api.share_group_type_access_get_all,
1758 self.ctxt, share_group_type_1['id'])
1759 self.assertRaises(exception.ShareGroupTypeNotFound,
1760 db_api.share_group_type_get,
1761 self.ctxt, share_group_type_1['id'])
1763 # share_group_type_2 must still be around
1764 self.assertEqual(share_group_type_2['id'],
1765 db_api.share_group_type_get(
1766 self.ctxt, share_group_type_2['id'])['id'])
1769@ddt.ddt
1770class ShareSnapshotDatabaseAPITestCase(test.TestCase):
1772 def setUp(self):
1773 """Run before each test."""
1774 super(ShareSnapshotDatabaseAPITestCase, self).setUp()
1775 self.ctxt = context.get_admin_context()
1777 self.share_instances = [
1778 db_utils.create_share_instance(
1779 status=constants.STATUS_REPLICATION_CHANGE,
1780 share_id='fake_share_id_1'),
1781 db_utils.create_share_instance(
1782 status=constants.STATUS_AVAILABLE,
1783 share_id='fake_share_id_1'),
1784 db_utils.create_share_instance(
1785 status=constants.STATUS_ERROR_DELETING,
1786 share_id='fake_share_id_2'),
1787 db_utils.create_share_instance(
1788 status=constants.STATUS_MANAGING,
1789 share_id='fake_share_id_2'),
1790 ]
1791 self.share_1 = db_utils.create_share(
1792 id='fake_share_id_1', instances=self.share_instances[0:2])
1793 self.share_2 = db_utils.create_share(
1794 id='fake_share_id_2', instances=self.share_instances[2:-1])
1795 self.snapshot_instances = [
1796 db_utils.create_snapshot_instance(
1797 'fake_snapshot_id_1',
1798 status=constants.STATUS_CREATING,
1799 share_instance_id=self.share_instances[0]['id']),
1800 db_utils.create_snapshot_instance(
1801 'fake_snapshot_id_1',
1802 status=constants.STATUS_ERROR,
1803 share_instance_id=self.share_instances[1]['id']),
1804 db_utils.create_snapshot_instance(
1805 'fake_snapshot_id_1',
1806 status=constants.STATUS_DELETING,
1807 share_instance_id=self.share_instances[2]['id']),
1808 db_utils.create_snapshot_instance(
1809 'fake_snapshot_id_2',
1810 status=constants.STATUS_AVAILABLE,
1811 id='fake_snapshot_instance_id',
1812 provider_location='hogsmeade:snapshot1',
1813 progress='87%',
1814 share_instance_id=self.share_instances[3]['id']),
1815 ]
1816 self.snapshot_1 = db_utils.create_snapshot(
1817 id='fake_snapshot_id_1', share_id=self.share_1['id'],
1818 instances=self.snapshot_instances[0:3])
1819 self.snapshot_2 = db_utils.create_snapshot(
1820 id='fake_snapshot_id_2', share_id=self.share_2['id'],
1821 instances=self.snapshot_instances[3:4], metadata={'foo': 'bar'})
1823 self.snapshot_instance_export_locations = [
1824 db_utils.create_snapshot_instance_export_locations(
1825 self.snapshot_instances[0].id,
1826 path='1.1.1.1:/fake_path',
1827 is_admin_only=True),
1828 db_utils.create_snapshot_instance_export_locations(
1829 self.snapshot_instances[1].id,
1830 path='2.2.2.2:/fake_path',
1831 is_admin_only=True),
1832 db_utils.create_snapshot_instance_export_locations(
1833 self.snapshot_instances[2].id,
1834 path='3.3.3.3:/fake_path',
1835 is_admin_only=True),
1836 db_utils.create_snapshot_instance_export_locations(
1837 self.snapshot_instances[3].id,
1838 path='4.4.4.4:/fake_path',
1839 is_admin_only=True)
1840 ]
1842 def test_create(self):
1843 share = db_utils.create_share(size=1)
1844 values = {
1845 'share_id': share['id'],
1846 'size': share['size'],
1847 'user_id': share['user_id'],
1848 'project_id': share['project_id'],
1849 'status': constants.STATUS_CREATING,
1850 'progress': '0%',
1851 'share_size': share['size'],
1852 'display_name': 'fake',
1853 'display_description': 'fake',
1854 'share_proto': share['share_proto']
1855 }
1857 actual_result = db_api.share_snapshot_create(
1858 self.ctxt, values, create_snapshot_instance=True)
1860 self.assertEqual(1, len(actual_result.instances))
1861 self.assertSubDictMatch(values, actual_result.to_dict())
1863 @ddt.data(
1864 ({'with_count': True}, 3, 3),
1865 ({'with_count': True, 'limit': 2}, 3, 2)
1866 )
1867 @ddt.unpack
1868 def test_share_snapshot_get_all_with_count(self, filters,
1869 amount_of_share_snapshots,
1870 expected_share_snapshots_len):
1871 share = db_utils.create_share(size=1)
1872 values = {
1873 'share_id': share['id'],
1874 'size': share['size'],
1875 'user_id': share['user_id'],
1876 'project_id': share['project_id'],
1877 'status': constants.STATUS_CREATING,
1878 'progress': '0%',
1879 'share_size': share['size'],
1880 'display_description': 'fake_count_test',
1881 'share_proto': share['share_proto'],
1882 }
1884 # consider only shares created in this function
1885 filters.update({'share_id': share['id']})
1887 for i in range(amount_of_share_snapshots):
1888 tmp_values = copy.deepcopy(values)
1889 tmp_values['display_name'] = 'fake_name_%s' % str(i)
1890 db_api.share_snapshot_create(self.ctxt, tmp_values)
1892 limit = filters.get('limit')
1893 count, share_snapshots = db_api.share_snapshot_get_all_with_count(
1894 self.ctxt, filters=filters, limit=limit)
1896 self.assertEqual(count, amount_of_share_snapshots)
1897 self.assertEqual(expected_share_snapshots_len, len(share_snapshots))
1899 def test_share_snapshot_get_all_with_filters_some(self):
1900 expected_status = constants.STATUS_AVAILABLE
1901 filters = {
1902 'status': expected_status,
1903 'metadata': {'foo': 'bar'}
1904 }
1905 snapshots = db_api.share_snapshot_get_all(self.ctxt, filters=filters)
1907 self.assertEqual(1, len(snapshots))
1909 for snapshot in snapshots:
1910 s = snapshot.get('share_snapshot_metadata')
1911 for k, v in filters['metadata'].items():
1912 filter_meta_key = k
1913 filter_meta_val = v
1914 self.assertEqual('fake_snapshot_id_2', snapshot['id'])
1915 self.assertEqual(snapshot['status'], filters['status'])
1916 self.assertEqual(s[0]['key'], filter_meta_key)
1917 self.assertEqual(s[0]['value'], filter_meta_val)
1919 def test_share_snapshot_get_latest_for_share(self):
1921 share = db_utils.create_share(size=1)
1922 values = {
1923 'share_id': share['id'],
1924 'size': share['size'],
1925 'user_id': share['user_id'],
1926 'project_id': share['project_id'],
1927 'status': constants.STATUS_CREATING,
1928 'progress': '0%',
1929 'share_size': share['size'],
1930 'display_description': 'fake',
1931 'share_proto': share['share_proto'],
1932 }
1933 values1 = copy.deepcopy(values)
1934 values1['display_name'] = 'snap1'
1935 db_api.share_snapshot_create(self.ctxt, values1)
1936 values2 = copy.deepcopy(values)
1937 values2['display_name'] = 'snap2'
1938 db_api.share_snapshot_create(self.ctxt, values2)
1939 values3 = copy.deepcopy(values)
1940 values3['display_name'] = 'snap3'
1941 db_api.share_snapshot_create(self.ctxt, values3)
1943 result = db_api.share_snapshot_get_latest_for_share(self.ctxt,
1944 share['id'])
1946 self.assertSubDictMatch(values3, result.to_dict())
1948 def test_get_instance(self):
1949 snapshot = db_utils.create_snapshot(with_share=True)
1951 instance = db_api.share_snapshot_instance_get(
1952 self.ctxt, snapshot.instance['id'], with_share_data=True)
1953 instance_dict = instance.to_dict()
1955 self.assertTrue(hasattr(instance, 'name'))
1956 self.assertTrue(hasattr(instance, 'share_name'))
1957 self.assertTrue(hasattr(instance, 'share_id'))
1958 self.assertIn('name', instance_dict)
1959 self.assertIn('share_name', instance_dict)
1961 @ddt.data(None, constants.STATUS_ERROR)
1962 def test_share_snapshot_instance_get_all_with_filters_some(self, status):
1963 expected_status = status or (constants.STATUS_CREATING,
1964 constants.STATUS_DELETING)
1965 expected_number = 1 if status else 2
1966 filters = {
1967 'snapshot_ids': 'fake_snapshot_id_1',
1968 'statuses': expected_status
1969 }
1970 instances = db_api.share_snapshot_instance_get_all_with_filters(
1971 self.ctxt, filters)
1973 for instance in instances:
1974 self.assertEqual('fake_snapshot_id_1', instance['snapshot_id'])
1975 self.assertIn(instance['status'], filters['statuses'])
1977 self.assertEqual(expected_number, len(instances))
1979 def test_share_snapshot_instance_get_all_with_filters_all_filters(self):
1980 filters = {
1981 'snapshot_ids': 'fake_snapshot_id_2',
1982 'instance_ids': 'fake_snapshot_instance_id',
1983 'statuses': constants.STATUS_AVAILABLE,
1984 'share_instance_ids': self.share_instances[3]['id'],
1985 }
1986 instances = db_api.share_snapshot_instance_get_all_with_filters(
1987 self.ctxt, filters, with_share_data=True)
1988 self.assertEqual(1, len(instances))
1989 self.assertEqual('fake_snapshot_instance_id', instances[0]['id'])
1990 self.assertEqual(
1991 self.share_2['id'], instances[0]['share_instance']['share_id'])
1993 def test_share_snapshot_instance_get_all_with_filters_wrong_filters(self):
1994 filters = {
1995 'some_key': 'some_value',
1996 'some_other_key': 'some_other_value',
1997 }
1998 instances = db_api.share_snapshot_instance_get_all_with_filters(
1999 self.ctxt, filters)
2000 self.assertEqual(4, len(instances))
2002 def test_share_snapshot_instance_create(self):
2003 snapshot = db_utils.create_snapshot(with_share=True)
2004 share = snapshot['share']
2005 share_instance = db_utils.create_share_instance(share_id=share['id'])
2006 values = {
2007 'snapshot_id': snapshot['id'],
2008 'share_instance_id': share_instance['id'],
2009 'status': constants.STATUS_MANAGING,
2010 'progress': '88%',
2011 'provider_location': 'whomping_willow',
2012 }
2014 actual_result = db_api.share_snapshot_instance_create(
2015 self.ctxt, snapshot['id'], values)
2017 snapshot = db_api.share_snapshot_get(self.ctxt, snapshot['id'])
2019 self.assertSubDictMatch(values, actual_result.to_dict())
2020 self.assertEqual(2, len(snapshot['instances']))
2022 def test_share_snapshot_instance_update(self):
2023 snapshot = db_utils.create_snapshot(with_share=True)
2025 values = {
2026 'snapshot_id': snapshot['id'],
2027 'status': constants.STATUS_ERROR,
2028 'progress': '18%',
2029 'provider_location': 'godrics_hollow',
2030 }
2032 actual_result = db_api.share_snapshot_instance_update(
2033 self.ctxt, snapshot['instance']['id'], values)
2035 self.assertSubDictMatch(values, actual_result.to_dict())
2037 @ddt.data(2, 1)
2038 def test_share_snapshot_instance_delete(self, instances):
2039 snapshot = db_utils.create_snapshot(with_share=True)
2040 first_instance_id = snapshot['instance']['id']
2041 if instances > 1:
2042 instance = db_utils.create_snapshot_instance(
2043 snapshot['id'],
2044 share_instance_id=snapshot['share']['instance']['id'])
2045 else:
2046 instance = snapshot['instance']
2048 retval = db_api.share_snapshot_instance_delete(
2049 self.ctxt, instance['id'])
2051 self.assertIsNone(retval)
2052 if instances == 1:
2053 self.assertRaises(exception.ShareSnapshotNotFound,
2054 db_api.share_snapshot_get,
2055 self.ctxt, snapshot['id'])
2056 else:
2057 snapshot = db_api.share_snapshot_get(self.ctxt, snapshot['id'])
2058 self.assertEqual(1, len(snapshot['instances']))
2059 self.assertEqual(first_instance_id, snapshot['instance']['id'])
2061 def test_share_snapshot_access_create(self):
2062 values = {
2063 'share_snapshot_id': self.snapshot_1['id'],
2064 }
2065 actual_result = db_api.share_snapshot_access_create(self.ctxt,
2066 values)
2068 self.assertSubDictMatch(values, actual_result.to_dict())
2070 def test_share_snapshot_instance_access_get_all(self):
2071 access = db_utils.create_snapshot_access(
2072 share_snapshot_id=self.snapshot_1['id'])
2074 # NOTE(zzzeek) the create_snapshot_access routine iterates through the
2075 # ShareSnapshot.instances collection and creates a new
2076 # ShareSnapshotInstanceAccessMapping for each ShareSnapshotInstance.
2077 # however, this collection is unordered and does not have any guarantee
2078 # that its ordering would match that of our self.snapshot_instances
2079 # collection. Therefore key the fixture values and the resulting
2080 # ShareSnapshotInstanceAccessMapping objects by share_snapshot_id
2081 # and compare individually.
2083 values_by_sid = {
2084 snapshot_instance.id: {
2085 'share_snapshot_instance_id': snapshot_instance.id,
2086 'access_id': access['id']
2087 }
2088 for snapshot_instance in self.snapshot_instances
2089 if "fake" not in snapshot_instance.id
2090 }
2092 rules_by_sid = {
2093 rule.share_snapshot_instance_id: rule
2094 for rule in db_api.share_snapshot_instance_access_get_all(
2095 self.ctxt, access['id']
2096 )
2097 }
2099 for sid in values_by_sid:
2100 self.assertSubDictMatch(
2101 values_by_sid[sid],
2102 rules_by_sid[sid].to_dict()
2103 )
2105 def test_share_snapshot_access_get(self):
2106 access = db_utils.create_snapshot_access(
2107 share_snapshot_id=self.snapshot_1['id'])
2108 values = {'share_snapshot_id': self.snapshot_1['id']}
2110 actual_value = db_api.share_snapshot_access_get(
2111 self.ctxt, access['id'])
2113 self.assertSubDictMatch(values, actual_value.to_dict())
2115 def test_share_snapshot_access_get_all_for_share_snapshot(self):
2116 access = db_utils.create_snapshot_access(
2117 share_snapshot_id=self.snapshot_1['id'])
2118 values = {'access_type': access['access_type'],
2119 'access_to': access['access_to'],
2120 'share_snapshot_id': self.snapshot_1['id']}
2122 actual_value = db_api.share_snapshot_access_get_all_for_share_snapshot(
2123 self.ctxt, self.snapshot_1['id'], {})
2125 self.assertSubDictMatch(values, actual_value[0].to_dict())
2127 @ddt.data({'existing': {'access_type': 'cephx', 'access_to': 'alice'},
2128 'new': {'access_type': 'user', 'access_to': 'alice'},
2129 'result': False},
2130 {'existing': {'access_type': 'user', 'access_to': 'bob'},
2131 'new': {'access_type': 'user', 'access_to': 'bob'},
2132 'result': True},
2133 {'existing': {'access_type': 'ip', 'access_to': '10.0.0.10/32'},
2134 'new': {'access_type': 'ip', 'access_to': '10.0.0.10'},
2135 'result': True},
2136 {'existing': {'access_type': 'ip', 'access_to': '10.10.0.11'},
2137 'new': {'access_type': 'ip', 'access_to': '10.10.0.11'},
2138 'result': True},
2139 {'existing': {'access_type': 'ip', 'access_to': 'fd21::11'},
2140 'new': {'access_type': 'ip', 'access_to': 'fd21::11'},
2141 'result': True},
2142 {'existing': {'access_type': 'ip', 'access_to': 'fd21::10'},
2143 'new': {'access_type': 'ip', 'access_to': 'fd21::10/128'},
2144 'result': True},
2145 {'existing': {'access_type': 'ip', 'access_to': '10.10.0.0/22'},
2146 'new': {'access_type': 'ip', 'access_to': '10.10.0.0/24'},
2147 'result': False},
2148 {'existing': {'access_type': 'ip', 'access_to': '2620:52::/48'},
2149 'new': {'access_type': 'ip',
2150 'access_to': '2620:52:0:13b8::/64'},
2151 'result': False})
2152 @ddt.unpack
2153 def test_share_snapshot_check_for_existing_access(self, existing, new,
2154 result):
2155 db_utils.create_snapshot_access(
2156 share_snapshot_id=self.snapshot_1['id'],
2157 access_type=existing['access_type'],
2158 access_to=existing['access_to'])
2160 rule_exists = db_api.share_snapshot_check_for_existing_access(
2161 self.ctxt, self.snapshot_1['id'], new['access_type'],
2162 new['access_to'])
2164 self.assertEqual(result, rule_exists)
2166 def test_share_snapshot_access_get_all_for_snapshot_instance(self):
2167 access = db_utils.create_snapshot_access(
2168 share_snapshot_id=self.snapshot_1['id'])
2169 values = {'access_type': access['access_type'],
2170 'access_to': access['access_to'],
2171 'share_snapshot_id': self.snapshot_1['id']}
2173 out = db_api.share_snapshot_access_get_all_for_snapshot_instance(
2174 self.ctxt, self.snapshot_instances[0].id)
2176 self.assertSubDictMatch(values, out[0].to_dict())
2178 def test_share_snapshot_instance_access_update_state(self):
2179 access = db_utils.create_snapshot_access(
2180 share_snapshot_id=self.snapshot_1['id'])
2181 values = {'state': constants.STATUS_ACTIVE,
2182 'access_id': access['id'],
2183 'share_snapshot_instance_id': self.snapshot_instances[0].id}
2185 actual_result = db_api.share_snapshot_instance_access_update(
2186 self.ctxt, access['id'], self.snapshot_1.instance['id'],
2187 {'state': constants.STATUS_ACTIVE})
2189 self.assertSubDictMatch(values, actual_result.to_dict())
2190 self.assertIsNotNone(actual_result['updated_at'])
2191 time_now = timeutils.utcnow()
2192 self.assertTrue(actual_result['updated_at'] < time_now)
2194 def test_share_snapshot_instance_access_get(self):
2195 access = db_utils.create_snapshot_access(
2196 share_snapshot_id=self.snapshot_1['id'])
2197 values = {'access_id': access['id'],
2198 'share_snapshot_instance_id': self.snapshot_instances[0].id}
2200 actual_result = db_api.share_snapshot_instance_access_get(
2201 self.ctxt, access['id'], self.snapshot_instances[0].id)
2203 self.assertSubDictMatch(values, actual_result.to_dict())
2205 def test_share_snapshot_instance_access_delete(self):
2206 access = db_utils.create_snapshot_access(
2207 share_snapshot_id=self.snapshot_1['id'])
2209 db_api.share_snapshot_instance_access_delete(
2210 self.ctxt, access['id'], self.snapshot_1.instance['id'])
2212 def test_share_snapshot_instance_export_location_create(self):
2213 values = {
2214 'share_snapshot_instance_id': self.snapshot_instances[0].id,
2215 }
2217 actual_result = db_api.share_snapshot_instance_export_location_create(
2218 self.ctxt, values)
2220 self.assertSubDictMatch(values, actual_result.to_dict())
2222 def test_share_snapshot_export_locations_get(self):
2223 out = db_api.share_snapshot_export_locations_get(
2224 self.ctxt, self.snapshot_1['id'])
2226 keys = ['share_snapshot_instance_id', 'path', 'is_admin_only']
2227 for expected, actual in zip(self.snapshot_instance_export_locations,
2228 out):
2229 [self.assertEqual(expected[k], actual[k]) for k in keys]
2231 def test_share_snapshot_instance_export_locations_get(self):
2232 out = db_api.share_snapshot_instance_export_locations_get_all(
2233 self.ctxt, self.snapshot_instances[0].id)
2235 keys = ['share_snapshot_instance_id', 'path', 'is_admin_only']
2236 for key in keys:
2237 self.assertEqual(self.snapshot_instance_export_locations[0][key],
2238 out[0][key])
2240 def test_share_snapshot_instance_export_locations_update(self):
2241 snapshot = db_utils.create_snapshot(with_share=True)
2242 initial_locations = ['fake1/1/', 'fake2/2', 'fake3/3']
2243 update_locations = ['fake4/4', 'fake2/2', 'fake3/3']
2245 # add initial locations
2246 db_api.share_snapshot_instance_export_locations_update(
2247 self.ctxt, snapshot.instance['id'], initial_locations, False)
2248 # update locations
2249 db_api.share_snapshot_instance_export_locations_update(
2250 self.ctxt, snapshot.instance['id'], update_locations, True)
2252 get_result = db_api.share_snapshot_instance_export_locations_get_all(
2253 self.ctxt, snapshot.instance['id'])
2254 result_locations = [el['path'] for el in get_result]
2256 self.assertEqual(sorted(result_locations), sorted(update_locations))
2258 def test_share_snapshot_instance_export_locations_update_wrong_type(self):
2259 snapshot = db_utils.create_snapshot(with_share=True)
2260 new_export_locations = [1]
2262 self.assertRaises(
2263 exception.ManilaException,
2264 db_api.share_snapshot_instance_export_locations_update,
2265 self.ctxt, snapshot.instance['id'], new_export_locations, False)
2267 def test_share_snapshot_metadata_get(self):
2268 metadata = {'a': 'b', 'c': 'd'}
2270 self.share_1 = db_utils.create_share(size=1)
2271 self.snapshot_1 = db_utils.create_snapshot(
2272 share_id=self.share_1['id'])
2273 db_api.share_snapshot_metadata_update(
2274 self.ctxt, share_snapshot_id=self.snapshot_1['id'],
2275 metadata=metadata, delete=False)
2276 self.assertEqual(
2277 metadata, db_api.share_snapshot_metadata_get(
2278 self.ctxt, share_snapshot_id=self.snapshot_1['id']))
2280 def test_share_snapshot_metadata_get_item(self):
2281 metadata = {'a': 'b', 'c': 'd'}
2282 key = 'a'
2283 shouldbe = {'a': 'b'}
2284 self.share_1 = db_utils.create_share(size=1)
2285 self.snapshot_1 = db_utils.create_snapshot(
2286 share_id=self.share_1['id'])
2287 db_api.share_snapshot_metadata_update(
2288 self.ctxt, share_snapshot_id=self.snapshot_1['id'],
2289 metadata=metadata, delete=False)
2290 self.assertEqual(
2291 shouldbe, db_api.share_snapshot_metadata_get_item(
2292 self.ctxt, share_snapshot_id=self.snapshot_1['id'],
2293 key=key))
2295 def test_share_snapshot_metadata_update(self):
2296 metadata1 = {'a': '1', 'c': '2'}
2297 metadata2 = {'a': '3', 'd': '5'}
2298 should_be = {'a': '3', 'c': '2', 'd': '5'}
2299 self.share_1 = db_utils.create_share(size=1)
2300 self.snapshot_1 = db_utils.create_snapshot(
2301 share_id=self.share_1['id'])
2302 db_api.share_snapshot_metadata_update(
2303 self.ctxt, share_snapshot_id=self.snapshot_1['id'],
2304 metadata=metadata1, delete=False)
2305 db_api.share_snapshot_metadata_update(
2306 self.ctxt, share_snapshot_id=self.snapshot_1['id'],
2307 metadata=metadata2, delete=False)
2308 self.assertEqual(
2309 should_be, db_api.share_snapshot_metadata_get(
2310 self.ctxt, share_snapshot_id=self.snapshot_1['id']))
2312 def test_share_snapshot_metadata_delete(self):
2313 key = 'a'
2314 metadata = {'a': '1', 'c': '2'}
2315 should_be = {'c': '2'}
2316 self.share_1 = db_utils.create_share(size=1)
2317 self.snapshot_1 = db_utils.create_snapshot(
2318 share_id=self.share_1['id'])
2319 db_api.share_snapshot_metadata_update(
2320 self.ctxt, share_snapshot_id=self.snapshot_1['id'],
2321 metadata=metadata, delete=False)
2322 db_api.share_snapshot_metadata_delete(
2323 self.ctxt, share_snapshot_id=self.snapshot_1['id'],
2324 key=key)
2325 self.assertEqual(
2326 should_be, db_api.share_snapshot_metadata_get(
2327 self.ctxt, share_snapshot_id=self.snapshot_1['id']))
2330class ShareExportLocationsDatabaseAPITestCase(test.TestCase):
2332 def setUp(self):
2333 super(ShareExportLocationsDatabaseAPITestCase, self).setUp()
2334 self.ctxt = context.get_admin_context()
2336 def test_update_valid_order(self):
2337 share = db_utils.create_share()
2338 initial_locations = ['fake1/1/', 'fake2/2', 'fake3/3']
2339 update_locations = ['fake4/4', 'fake2/2', 'fake3/3']
2341 # add initial locations
2342 db_api.export_locations_update(
2343 self.ctxt, share.instance['id'], initial_locations, False)
2344 # update locations
2345 db_api.export_locations_update(
2346 self.ctxt, share.instance['id'], update_locations, True)
2347 actual_result = db_api.export_location_get_all(
2348 self.ctxt, share['id'])
2350 # actual result should contain locations in exact same order
2351 self.assertEqual(actual_result, update_locations)
2353 def test_update_export_locations_with_metadata(self):
2354 share = db_utils.create_share()
2355 original_export_locations = [
2356 {
2357 'path': 'fake1/1/',
2358 'is_admin_only': True,
2359 'metadata': {
2360 'foo': 'bar',
2361 'preferred': '1'
2362 },
2363 },
2364 {
2365 'path': 'fake2/1/',
2366 'is_admin_only': True,
2367 'metadata': {
2368 'clem': 'son',
2369 'preferred': '0'
2370 },
2371 },
2372 ]
2374 # add initial locations
2375 db_api.export_locations_update(
2376 self.ctxt, share.instance['id'], original_export_locations, False)
2378 updated_export_locations = [
2379 {
2380 'path': 'fake1/1/',
2381 'is_admin_only': True,
2382 'metadata': {
2383 'foo': 'quz',
2384 'preferred': '0'
2385 },
2386 },
2387 {
2388 'path': 'fake2/1/',
2389 'is_admin_only': True,
2390 'metadata': {
2391 'clem': 'son',
2392 'preferred': '1',
2393 },
2394 },
2395 ]
2397 # update locations
2398 db_api.export_locations_update(
2399 self.ctxt, share.instance['id'], updated_export_locations, True)
2400 actual_result = db_api.export_location_get_all_by_share_id(
2401 self.ctxt, share['id'])
2403 actual_export_locations = [
2404 {
2405 'path': el['path'],
2406 'is_admin_only': el['is_admin_only'],
2407 'metadata': el['el_metadata'],
2408 } for el in actual_result
2409 ]
2410 self.assertEqual(updated_export_locations, actual_export_locations)
2412 def test_update_string(self):
2413 share = db_utils.create_share()
2414 initial_location = 'fake1/1/'
2416 db_api.export_locations_update(
2417 self.ctxt, share.instance['id'], initial_location, False)
2418 actual_result = db_api.export_location_get_all(
2419 self.ctxt, share['id'])
2421 self.assertEqual(actual_result, [initial_location])
2423 def test_get_admin_export_locations(self):
2424 ctxt_user = context.RequestContext(
2425 user_id='fake user', project_id='fake project', is_admin=False)
2426 share = db_utils.create_share()
2427 locations = [
2428 {'path': 'fake1/1/', 'is_admin_only': True},
2429 {'path': 'fake2/2/', 'is_admin_only': True},
2430 {'path': 'fake3/3/', 'is_admin_only': True},
2431 ]
2433 db_api.export_locations_update(
2434 self.ctxt, share.instance['id'], locations, delete=False)
2436 user_result = db_api.export_location_get_all(ctxt_user, share['id'])
2437 self.assertEqual([], user_result)
2439 admin_result = db_api.export_location_get_all(
2440 self.ctxt, share['id'])
2441 self.assertEqual(3, len(admin_result))
2442 for location in locations:
2443 self.assertIn(location['path'], admin_result)
2445 def test_get_user_export_locations(self):
2446 ctxt_user = context.RequestContext(
2447 user_id='fake user', project_id='fake project', is_admin=False)
2448 share = db_utils.create_share()
2449 locations = [
2450 {'path': 'fake1/1/', 'is_admin_only': False},
2451 {'path': 'fake2/2/', 'is_admin_only': False},
2452 {'path': 'fake3/3/', 'is_admin_only': False},
2453 ]
2455 db_api.export_locations_update(
2456 self.ctxt, share.instance['id'], locations, delete=False)
2458 user_result = db_api.export_location_get_all(ctxt_user, share['id'])
2459 self.assertEqual(3, len(user_result))
2460 for location in locations:
2461 self.assertIn(location['path'], user_result)
2463 admin_result = db_api.export_location_get_all(
2464 self.ctxt, share['id'])
2465 self.assertEqual(3, len(admin_result))
2466 for location in locations:
2467 self.assertIn(location['path'], admin_result)
2469 def test_get_user_export_locations_old_view(self):
2470 ctxt_user = context.RequestContext(
2471 user_id='fake user', project_id='fake project', is_admin=False)
2472 share = db_utils.create_share()
2473 locations = ['fake1/1/', 'fake2/2', 'fake3/3']
2475 db_api.export_locations_update(
2476 self.ctxt, share.instance['id'], locations, delete=False)
2478 user_result = db_api.export_location_get_all(ctxt_user, share['id'])
2479 self.assertEqual(locations, user_result)
2481 admin_result = db_api.export_location_get_all(
2482 self.ctxt, share['id'])
2483 self.assertEqual(locations, admin_result)
2486@ddt.ddt
2487class ShareInstanceExportLocationsMetadataDatabaseAPITestCase(test.TestCase):
2489 def setUp(self):
2490 clname = ShareInstanceExportLocationsMetadataDatabaseAPITestCase
2491 super(clname, self).setUp()
2492 self.ctxt = context.get_admin_context()
2493 share_id = 'fake_share_id'
2494 instances = [
2495 db_utils.create_share_instance(
2496 share_id=share_id,
2497 status=constants.STATUS_AVAILABLE),
2498 db_utils.create_share_instance(
2499 share_id=share_id,
2500 status=constants.STATUS_MIGRATING),
2501 db_utils.create_share_instance(
2502 share_id=share_id,
2503 status=constants.STATUS_MIGRATING_TO),
2504 ]
2505 self.share = db_utils.create_share(
2506 id=share_id,
2507 instances=instances)
2508 self.initial_locations = ['/fake/foo/', '/fake/bar', '/fake/quuz']
2509 self.shown_locations = ['/fake/foo/', '/fake/bar']
2510 for i in range(0, 3):
2511 db_api.export_locations_update(
2512 self.ctxt, instances[i]['id'], self.initial_locations[i],
2513 delete=False)
2515 def _get_export_location_uuid_by_path(self, path):
2516 els = db_api.export_location_get_all_by_share_id(
2517 self.ctxt, self.share.id)
2518 export_location_uuid = None
2519 for el in els:
2520 if el.path == path:
2521 export_location_uuid = el.uuid
2522 self.assertIsNotNone(export_location_uuid)
2523 return export_location_uuid
2525 def test_get_export_locations_by_share_id(self):
2526 els = db_api.export_location_get_all_by_share_id(
2527 self.ctxt, self.share.id)
2528 self.assertEqual(3, len(els))
2529 for path in self.shown_locations:
2530 self.assertTrue(any([path in el.path for el in els]))
2532 def test_get_export_locations_by_share_id_ignore_migration_dest(self):
2533 els = db_api.export_location_get_all_by_share_id(
2534 self.ctxt, self.share.id, ignore_migration_destination=True)
2535 self.assertEqual(2, len(els))
2536 for path in self.shown_locations:
2537 self.assertTrue(any([path in el.path for el in els]))
2539 def test_get_export_locations_by_share_instance_id(self):
2540 els = db_api.export_location_get_all_by_share_instance_id(
2541 self.ctxt, self.share.instance.id)
2542 self.assertEqual(1, len(els))
2543 for path in [self.shown_locations[1]]:
2544 self.assertTrue(any([path in el.path for el in els]))
2546 def test_export_location_metadata_update_delete(self):
2547 export_location_uuid = self._get_export_location_uuid_by_path(
2548 self.initial_locations[0])
2549 metadata = {
2550 'foo_key': 'foo_value',
2551 'bar_key': 'bar_value',
2552 'quuz_key': 'quuz_value',
2553 }
2555 db_api.export_location_metadata_update(
2556 self.ctxt, export_location_uuid, metadata, False)
2558 db_api.export_location_metadata_delete(
2559 self.ctxt, export_location_uuid, list(metadata.keys())[0:-1])
2561 result = db_api.export_location_metadata_get(
2562 self.ctxt, export_location_uuid)
2564 key = list(metadata.keys())[-1]
2565 self.assertEqual({key: metadata[key]}, result)
2567 db_api.export_location_metadata_delete(
2568 self.ctxt, export_location_uuid)
2570 result = db_api.export_location_metadata_get(
2571 self.ctxt, export_location_uuid)
2572 self.assertEqual({}, result)
2574 def test_export_location_metadata_update_get(self):
2575 # Write metadata for target export location
2576 export_location_uuid = self._get_export_location_uuid_by_path(
2577 self.initial_locations[0])
2578 metadata = {'foo_key': 'foo_value', 'bar_key': 'bar_value'}
2579 db_api.export_location_metadata_update(
2580 self.ctxt, export_location_uuid, metadata, False)
2582 # Write metadata for some concurrent export location
2583 other_export_location_uuid = self._get_export_location_uuid_by_path(
2584 self.initial_locations[1])
2585 other_metadata = {'key_from_other_el': 'value_of_key_from_other_el'}
2586 db_api.export_location_metadata_update(
2587 self.ctxt, other_export_location_uuid, other_metadata, False)
2589 result = db_api.export_location_metadata_get(
2590 self.ctxt, export_location_uuid)
2592 self.assertEqual(metadata, result)
2594 updated_metadata = {
2595 'foo_key': metadata['foo_key'],
2596 'quuz_key': 'quuz_value',
2597 }
2599 db_api.export_location_metadata_update(
2600 self.ctxt, export_location_uuid, updated_metadata, True)
2602 result = db_api.export_location_metadata_get(
2603 self.ctxt, export_location_uuid)
2605 self.assertEqual(updated_metadata, result)
2607 def test_export_location_metadata_get_item(self):
2608 export_location_uuid = self._get_export_location_uuid_by_path(
2609 self.initial_locations[0])
2610 metadata = {'foo_key': 'foo_value', 'bar_key': 'bar_value'}
2611 db_api.export_location_metadata_update(
2612 self.ctxt, export_location_uuid, metadata, False)
2613 result = db_api.export_location_metadata_get_item(
2614 self.ctxt, export_location_uuid, 'foo_key')
2615 self.assertEqual(
2616 {'foo_key': 'foo_value'}, result)
2618 def test_export_location_metadata_get_item_invalid(self):
2619 export_location_uuid = self._get_export_location_uuid_by_path(
2620 self.initial_locations[0])
2621 metadata = {'foo_key': 'foo_value', 'bar_key': 'bar_value'}
2622 db_api.export_location_metadata_update(
2623 self.ctxt, export_location_uuid, metadata, False)
2624 self.assertRaises(exception.MetadataItemNotFound,
2625 db_api.export_location_metadata_get_item,
2626 self.ctxt,
2627 export_location_uuid,
2628 'foo')
2630 @ddt.data(
2631 ("k", "v"),
2632 ("k" * 256, "v"),
2633 ("k", "v" * 1024),
2634 ("k" * 256, "v" * 1024),
2635 )
2636 @ddt.unpack
2637 def test_set_metadata_with_different_length(self, key, value):
2638 export_location_uuid = self._get_export_location_uuid_by_path(
2639 self.initial_locations[1])
2640 metadata = {key: value}
2642 db_api.export_location_metadata_update(
2643 self.ctxt, export_location_uuid, metadata, False)
2645 result = db_api.export_location_metadata_get(
2646 self.ctxt, export_location_uuid)
2648 self.assertEqual(metadata, result)
2651@ddt.ddt
2652class DriverPrivateDataDatabaseAPITestCase(test.TestCase):
2654 def setUp(self):
2655 """Run before each test."""
2656 super(DriverPrivateDataDatabaseAPITestCase, self).setUp()
2657 self.ctxt = context.get_admin_context()
2659 def _get_driver_test_data(self):
2660 return uuidutils.generate_uuid()
2662 @ddt.data({"details": {"foo": "bar", "tee": "too"},
2663 "valid": {"foo": "bar", "tee": "too"}},
2664 {"details": {"foo": "bar", "tee": ["test"]},
2665 "valid": {"foo": "bar", "tee": str(["test"])}})
2666 @ddt.unpack
2667 def test_update(self, details, valid):
2668 test_id = self._get_driver_test_data()
2670 initial_data = db_api.driver_private_data_get(self.ctxt, test_id)
2671 db_api.driver_private_data_update(self.ctxt, test_id, details)
2672 actual_data = db_api.driver_private_data_get(self.ctxt, test_id)
2674 self.assertEqual({}, initial_data)
2675 self.assertEqual(valid, actual_data)
2677 @ddt.data({'with_deleted': True, 'append': False},
2678 {'with_deleted': True, 'append': True},
2679 {'with_deleted': False, 'append': False},
2680 {'with_deleted': False, 'append': True})
2681 @ddt.unpack
2682 def test_update_with_more_values(self, with_deleted, append):
2683 test_id = self._get_driver_test_data()
2684 details = {"tee": "too"}
2685 more_details = {"foo": "bar"}
2686 result = {"tee": "too", "foo": "bar"}
2688 db_api.driver_private_data_update(self.ctxt, test_id, details)
2689 if with_deleted:
2690 db_api.driver_private_data_delete(self.ctxt, test_id)
2691 if append:
2692 more_details.update(details)
2693 if with_deleted and not append:
2694 result.pop("tee")
2695 db_api.driver_private_data_update(self.ctxt, test_id, more_details)
2697 actual_result = db_api.driver_private_data_get(self.ctxt,
2698 test_id)
2700 self.assertEqual(result, actual_result)
2702 @ddt.data(True, False)
2703 def test_update_with_duplicate(self, with_deleted):
2704 test_id = self._get_driver_test_data()
2705 details = {"tee": "too"}
2707 db_api.driver_private_data_update(self.ctxt, test_id, details)
2708 if with_deleted:
2709 db_api.driver_private_data_delete(self.ctxt, test_id)
2710 db_api.driver_private_data_update(self.ctxt, test_id, details)
2712 actual_result = db_api.driver_private_data_get(self.ctxt,
2713 test_id)
2715 self.assertEqual(details, actual_result)
2717 def test_update_with_delete_existing(self):
2718 test_id = self._get_driver_test_data()
2719 details = {"key1": "val1", "key2": "val2", "key3": "val3"}
2720 details_update = {"key1": "val1_upd", "key4": "new_val"}
2722 # Create new details
2723 db_api.driver_private_data_update(self.ctxt, test_id, details)
2724 db_api.driver_private_data_update(self.ctxt, test_id,
2725 details_update, delete_existing=True)
2727 actual_result = db_api.driver_private_data_get(
2728 self.ctxt, test_id)
2730 self.assertEqual(details_update, actual_result)
2732 def test_get(self):
2733 test_id = self._get_driver_test_data()
2734 test_key = "foo"
2735 test_keys = [test_key, "tee"]
2736 details = {test_keys[0]: "val", test_keys[1]: "val", "mee": "foo"}
2737 db_api.driver_private_data_update(self.ctxt, test_id, details)
2739 actual_result_all = db_api.driver_private_data_get(
2740 self.ctxt, test_id)
2741 actual_result_single_key = db_api.driver_private_data_get(
2742 self.ctxt, test_id, test_key)
2743 actual_result_list = db_api.driver_private_data_get(
2744 self.ctxt, test_id, test_keys)
2746 self.assertEqual(details, actual_result_all)
2747 self.assertEqual(details[test_key], actual_result_single_key)
2748 self.assertEqual(dict.fromkeys(test_keys, "val"), actual_result_list)
2750 def test_delete_single(self):
2751 test_id = self._get_driver_test_data()
2752 test_key = "foo"
2753 details = {test_key: "bar", "tee": "too"}
2754 valid_result = {"tee": "too"}
2755 db_api.driver_private_data_update(self.ctxt, test_id, details)
2757 db_api.driver_private_data_delete(self.ctxt, test_id, test_key)
2759 actual_result = db_api.driver_private_data_get(
2760 self.ctxt, test_id)
2762 self.assertEqual(valid_result, actual_result)
2764 def test_delete_all(self):
2765 test_id = self._get_driver_test_data()
2766 details = {"foo": "bar", "tee": "too"}
2767 db_api.driver_private_data_update(self.ctxt, test_id, details)
2769 db_api.driver_private_data_delete(self.ctxt, test_id)
2771 actual_result = db_api.driver_private_data_get(
2772 self.ctxt, test_id)
2774 self.assertEqual({}, actual_result)
2777@ddt.ddt
2778class ShareNetworkDatabaseAPITestCase(BaseDatabaseAPITestCase):
2780 def __init__(self, *args, **kwargs):
2781 super(ShareNetworkDatabaseAPITestCase, self).__init__(*args, **kwargs)
2782 self.fake_context = context.RequestContext(user_id='fake user',
2783 project_id='fake project',
2784 is_admin=False)
2786 def setUp(self):
2787 super(ShareNetworkDatabaseAPITestCase, self).setUp()
2788 self.share_nw_dict = {'id': 'fake network id',
2789 'project_id': self.fake_context.project_id,
2790 'user_id': 'fake_user_id',
2791 'name': 'whatever',
2792 'description': 'fake description'}
2794 def test_create_one_network(self):
2795 result = db_api.share_network_create(self.fake_context,
2796 self.share_nw_dict)
2798 self._check_fields(expected=self.share_nw_dict, actual=result)
2799 self.assertEqual(0, len(result['share_instances']))
2800 self.assertEqual(0, len(result['security_services']))
2802 def test_create_two_networks_in_different_tenants(self):
2803 share_nw_dict2 = self.share_nw_dict.copy()
2804 share_nw_dict2['id'] = None
2805 share_nw_dict2['project_id'] = 'fake project 2'
2806 result1 = db_api.share_network_create(self.fake_context,
2807 self.share_nw_dict)
2808 result2 = db_api.share_network_create(self.fake_context.elevated(),
2809 share_nw_dict2)
2811 self._check_fields(expected=self.share_nw_dict, actual=result1)
2812 self._check_fields(expected=share_nw_dict2, actual=result2)
2814 def test_create_two_networks_in_one_tenant(self):
2815 share_nw_dict2 = self.share_nw_dict.copy()
2816 share_nw_dict2['id'] += "suffix"
2817 result1 = db_api.share_network_create(self.fake_context,
2818 self.share_nw_dict)
2819 result2 = db_api.share_network_create(self.fake_context,
2820 share_nw_dict2)
2821 self._check_fields(expected=self.share_nw_dict, actual=result1)
2822 self._check_fields(expected=share_nw_dict2, actual=result2)
2824 def test_create_with_duplicated_id(self):
2825 db_api.share_network_create(self.fake_context, self.share_nw_dict)
2827 self.assertRaises(db_exception.DBDuplicateEntry,
2828 db_api.share_network_create,
2829 self.fake_context,
2830 self.share_nw_dict)
2832 def test_get(self):
2833 db_api.share_network_create(self.fake_context, self.share_nw_dict)
2834 result = db_api.share_network_get(self.fake_context,
2835 self.share_nw_dict['id'])
2837 self._check_fields(expected=self.share_nw_dict, actual=result)
2838 self.assertEqual(0, len(result['share_instances']))
2839 self.assertEqual(0, len(result['security_services']))
2841 def _create_share_network_for_project(self, project_id):
2842 ctx = context.RequestContext(user_id='fake user',
2843 project_id=project_id,
2844 is_admin=False)
2846 share_data = self.share_nw_dict.copy()
2847 share_data['project_id'] = project_id
2849 db_api.share_network_create(ctx, share_data)
2850 return share_data
2852 def test_get_other_tenant_as_admin(self):
2853 expected = self._create_share_network_for_project('fake project 2')
2854 result = db_api.share_network_get(self.fake_context.elevated(),
2855 self.share_nw_dict['id'])
2857 self._check_fields(expected=expected, actual=result)
2858 self.assertEqual(0, len(result['share_instances']))
2859 self.assertEqual(0, len(result['security_services']))
2861 def test_get_other_tenant(self):
2862 self._create_share_network_for_project('fake project 2')
2863 self.assertRaises(exception.ShareNetworkNotFound,
2864 db_api.share_network_get,
2865 self.fake_context,
2866 self.share_nw_dict['id'])
2868 @ddt.data([{'id': 'fake share id1'}],
2869 [{'id': 'fake share id1'}, {'id': 'fake share id2'}],)
2870 def test_get_with_shares(self, shares):
2871 db_api.share_network_create(self.fake_context, self.share_nw_dict)
2872 share_instances = []
2873 for share in shares:
2874 share.update({'share_network_id': self.share_nw_dict['id']})
2875 share_instances.append(
2876 db_api.share_create(self.fake_context, share).instance
2877 )
2879 result = db_api.share_network_get(self.fake_context,
2880 self.share_nw_dict['id'])
2882 self.assertEqual(len(shares), len(result['share_instances']))
2883 for index, share_instance in enumerate(share_instances):
2884 self.assertEqual(
2885 share_instance['share_network_id'],
2886 result['share_instances'][index]['share_network_id']
2887 )
2889 @ddt.data([{'id': 'fake security service id1', 'type': 'fake type'}],
2890 [{'id': 'fake security service id1', 'type': 'fake type'},
2891 {'id': 'fake security service id2', 'type': 'fake type'}])
2892 def test_get_with_security_services(self, security_services):
2893 db_api.share_network_create(self.fake_context, self.share_nw_dict)
2895 for service in security_services:
2896 service.update({'project_id': self.fake_context.project_id})
2897 db_api.security_service_create(self.fake_context, service)
2898 db_api.share_network_add_security_service(
2899 self.fake_context, self.share_nw_dict['id'], service['id'])
2901 result = db_api.share_network_get(self.fake_context,
2902 self.share_nw_dict['id'])
2904 self.assertEqual(len(security_services),
2905 len(result['security_services']))
2907 for index, service in enumerate(security_services):
2908 self._check_fields(expected=service,
2909 actual=result['security_services'][index])
2911 @ddt.data([{'id': 'fake_id_1', 'availability_zone_id': 'None'}],
2912 [{'id': 'fake_id_2', 'availability_zone_id': 'None'},
2913 {'id': 'fake_id_3', 'availability_zone_id': 'fake_az_id'}])
2914 def test_get_with_subnets(self, subnets):
2915 db_api.share_network_create(self.fake_context, self.share_nw_dict)
2917 for subnet in subnets:
2918 subnet['share_network_id'] = self.share_nw_dict['id']
2919 db_api.share_network_subnet_create(self.fake_context, subnet)
2921 result = db_api.share_network_get(self.fake_context,
2922 self.share_nw_dict['id'])
2924 self.assertEqual(len(subnets),
2925 len(result['share_network_subnets']))
2927 for index, subnet in enumerate(subnets):
2928 self._check_fields(expected=subnet,
2929 actual=result['share_network_subnets'][index])
2931 def test_get_not_found(self):
2932 self.assertRaises(exception.ShareNetworkNotFound,
2933 db_api.share_network_get,
2934 self.fake_context,
2935 'fake id')
2937 def test_delete(self):
2938 db_api.share_network_create(self.fake_context, self.share_nw_dict)
2939 db_api.share_network_delete(self.fake_context,
2940 self.share_nw_dict['id'])
2942 self.assertRaises(exception.ShareNetworkNotFound,
2943 db_api.share_network_get,
2944 self.fake_context,
2945 self.share_nw_dict['id'])
2947 @ddt.data([{'id': 'fake_id_1', 'availability_zone_id': 'None'}],
2948 [{'id': 'fake_id_2', 'availability_zone_id': 'None'},
2949 {'id': 'fake_id_3', 'availability_zone_id': 'fake_az_id'}])
2950 def test_delete_with_subnets(self, subnets):
2951 db_api.share_network_create(self.fake_context, self.share_nw_dict)
2953 for subnet in subnets:
2954 subnet['share_network_id'] = self.share_nw_dict['id']
2955 db_api.share_network_subnet_create(self.fake_context, subnet)
2957 db_api.share_network_delete(self.fake_context,
2958 self.share_nw_dict['id'])
2960 self.assertRaises(exception.ShareNetworkSubnetNotFound,
2961 db_api.share_network_subnet_get,
2962 self.fake_context,
2963 subnets[0]['id'])
2965 def test_delete_not_found(self):
2966 self.assertRaises(exception.ShareNetworkNotFound,
2967 db_api.share_network_delete,
2968 self.fake_context,
2969 'fake id')
2971 def test_update(self):
2972 new_name = 'fake_new_name'
2973 db_api.share_network_create(self.fake_context, self.share_nw_dict)
2974 result_update = db_api.share_network_update(self.fake_context,
2975 self.share_nw_dict['id'],
2976 {'name': new_name})
2977 result_get = db_api.share_network_get(self.fake_context,
2978 self.share_nw_dict['id'])
2980 self.assertEqual(new_name, result_update['name'])
2981 self._check_fields(expected=dict(result_update.items()),
2982 actual=dict(result_get.items()))
2984 def test_update_not_found(self):
2985 self.assertRaises(exception.ShareNetworkNotFound,
2986 db_api.share_network_update,
2987 self.fake_context,
2988 'fake id',
2989 {})
2991 @ddt.data(1, 2)
2992 def test_get_all_one_record(self, records_count):
2993 index = 0
2994 share_networks = []
2995 while index < records_count:
2996 share_network_dict = dict(self.share_nw_dict)
2997 fake_id = 'fake_id%s' % index
2998 share_network_dict.update({'id': fake_id,
2999 'project_id': fake_id})
3000 share_networks.append(share_network_dict)
3001 db_api.share_network_create(self.fake_context.elevated(),
3002 share_network_dict)
3003 index += 1
3005 result = db_api.share_network_get_all(self.fake_context.elevated())
3007 self.assertEqual(len(share_networks), len(result))
3008 for index, net in enumerate(share_networks):
3009 self._check_fields(expected=net, actual=result[index])
3011 def test_get_all_by_filter_with_project_id(self):
3012 db_api.share_network_create(self.fake_context, self.share_nw_dict)
3014 share_nw_dict2 = dict(self.share_nw_dict)
3015 share_nw_dict2['id'] = 'fake share nw id2'
3016 share_nw_dict2['project_id'] = 'fake project 2'
3017 new_context = context.RequestContext(user_id='fake user 2',
3018 project_id='fake project 2',
3019 is_admin=False)
3020 db_api.share_network_create(new_context, share_nw_dict2)
3022 filters = {'project_id': share_nw_dict2['project_id']}
3023 result = db_api.share_network_get_all_by_filter(
3024 self.fake_context.elevated(), filters=filters)
3026 self.assertEqual(1, len(result))
3027 self._check_fields(expected=share_nw_dict2, actual=result[0])
3029 def test_get_all_with_created_since_or_before_filter(self):
3030 now = timeutils.utcnow()
3032 share_nw1 = dict(self.share_nw_dict)
3033 share_nw2 = dict(self.share_nw_dict)
3034 share_nw3 = dict(self.share_nw_dict)
3036 share_nw1['created_at'] = (now - datetime.timedelta(seconds=1))
3037 share_nw2['created_at'] = (now + datetime.timedelta(seconds=1))
3038 share_nw3['created_at'] = (now + datetime.timedelta(seconds=2))
3040 share_nw1['id'] = 'fake share nw id1'
3041 share_nw2['id'] = 'fake share nw id2'
3042 share_nw3['id'] = 'fake share nw id3'
3044 db_api.share_network_create(self.fake_context, share_nw1)
3045 db_api.share_network_create(self.fake_context, share_nw2)
3046 db_api.share_network_create(self.fake_context, share_nw3)
3048 filters1 = {'created_before': now}
3049 filters2 = {'created_since': now}
3051 result1 = db_api.share_network_get_all_by_filter(
3052 self.fake_context.elevated(), filters=filters1)
3053 result2 = db_api.share_network_get_all_by_filter(
3054 self.fake_context.elevated(), filters=filters2)
3056 self.assertEqual(1, len(result1))
3057 self.assertEqual(2, len(result2))
3059 def test_get_all_by_project(self):
3060 db_api.share_network_create(self.fake_context, self.share_nw_dict)
3062 share_nw_dict2 = dict(self.share_nw_dict)
3063 share_nw_dict2['id'] = 'fake share nw id2'
3064 share_nw_dict2['project_id'] = 'fake project 2'
3065 new_context = context.RequestContext(user_id='fake user 2',
3066 project_id='fake project 2',
3067 is_admin=False)
3068 db_api.share_network_create(new_context, share_nw_dict2)
3070 result = db_api.share_network_get_all_by_project(
3071 self.fake_context.elevated(),
3072 share_nw_dict2['project_id'])
3074 self.assertEqual(1, len(result))
3075 self._check_fields(expected=share_nw_dict2, actual=result[0])
3077 def test_add_security_service(self):
3078 security_dict1 = {'id': 'fake security service id1',
3079 'project_id': self.fake_context.project_id,
3080 'type': 'fake type'}
3082 db_api.share_network_create(self.fake_context, self.share_nw_dict)
3083 db_api.security_service_create(self.fake_context, security_dict1)
3084 db_api.share_network_add_security_service(self.fake_context,
3085 self.share_nw_dict['id'],
3086 security_dict1['id'])
3088 with db_api.context_manager.reader.using(self.fake_context):
3089 result = (db_api.model_query(
3090 self.fake_context,
3091 models.ShareNetworkSecurityServiceAssociation).
3092 filter_by(security_service_id=security_dict1['id']).
3093 filter_by(share_network_id=self.share_nw_dict['id']).
3094 first())
3096 self.assertIsNotNone(result)
3098 def test_add_security_service_not_found_01(self):
3099 security_service_id = 'unknown security service'
3100 db_api.share_network_create(self.fake_context, self.share_nw_dict)
3102 self.assertRaises(exception.SecurityServiceNotFound,
3103 db_api.share_network_add_security_service,
3104 self.fake_context,
3105 self.share_nw_dict['id'],
3106 security_service_id)
3108 def test_add_security_service_not_found_02(self):
3109 security_dict1 = {'id': 'fake security service id1',
3110 'project_id': self.fake_context.project_id,
3111 'type': 'fake type'}
3112 share_nw_id = 'unknown share network'
3113 db_api.security_service_create(self.fake_context, security_dict1)
3115 self.assertRaises(exception.ShareNetworkNotFound,
3116 db_api.share_network_add_security_service,
3117 self.fake_context,
3118 share_nw_id,
3119 security_dict1['id'])
3121 def test_add_security_service_association_error_already_associated(self):
3122 security_dict1 = {'id': 'fake security service id1',
3123 'project_id': self.fake_context.project_id,
3124 'type': 'fake type'}
3126 db_api.share_network_create(self.fake_context, self.share_nw_dict)
3127 db_api.security_service_create(self.fake_context, security_dict1)
3128 db_api.share_network_add_security_service(self.fake_context,
3129 self.share_nw_dict['id'],
3130 security_dict1['id'])
3132 self.assertRaises(
3133 exception.ShareNetworkSecurityServiceAssociationError,
3134 db_api.share_network_add_security_service,
3135 self.fake_context,
3136 self.share_nw_dict['id'],
3137 security_dict1['id'])
3139 def test_remove_security_service(self):
3140 security_dict1 = {'id': 'fake security service id1',
3141 'project_id': self.fake_context.project_id,
3142 'type': 'fake type'}
3144 db_api.share_network_create(self.fake_context, self.share_nw_dict)
3145 db_api.security_service_create(self.fake_context, security_dict1)
3146 db_api.share_network_add_security_service(self.fake_context,
3147 self.share_nw_dict['id'],
3148 security_dict1['id'])
3150 db_api.share_network_remove_security_service(self.fake_context,
3151 self.share_nw_dict['id'],
3152 security_dict1['id'])
3154 with db_api.context_manager.reader.using(self.fake_context):
3155 result = (db_api.model_query(
3156 self.fake_context,
3157 models.ShareNetworkSecurityServiceAssociation).
3158 filter_by(security_service_id=security_dict1['id']).
3159 filter_by(share_network_id=self.share_nw_dict['id']).
3160 first())
3162 self.assertIsNone(result)
3164 share_nw_ref = db_api.share_network_get(self.fake_context,
3165 self.share_nw_dict['id'])
3166 self.assertEqual(0, len(share_nw_ref['security_services']))
3168 def test_remove_security_service_not_found_01(self):
3169 security_service_id = 'unknown security service'
3170 db_api.share_network_create(self.fake_context, self.share_nw_dict)
3172 self.assertRaises(exception.SecurityServiceNotFound,
3173 db_api.share_network_remove_security_service,
3174 self.fake_context,
3175 self.share_nw_dict['id'],
3176 security_service_id)
3178 def test_remove_security_service_not_found_02(self):
3179 security_dict1 = {'id': 'fake security service id1',
3180 'project_id': self.fake_context.project_id,
3181 'type': 'fake type'}
3182 share_nw_id = 'unknown share network'
3183 db_api.security_service_create(self.fake_context, security_dict1)
3185 self.assertRaises(exception.ShareNetworkNotFound,
3186 db_api.share_network_remove_security_service,
3187 self.fake_context,
3188 share_nw_id,
3189 security_dict1['id'])
3191 def test_remove_security_service_dissociation_error(self):
3192 security_dict1 = {'id': 'fake security service id1',
3193 'project_id': self.fake_context.project_id,
3194 'type': 'fake type'}
3196 db_api.share_network_create(self.fake_context, self.share_nw_dict)
3197 db_api.security_service_create(self.fake_context, security_dict1)
3199 self.assertRaises(
3200 exception.ShareNetworkSecurityServiceDissociationError,
3201 db_api.share_network_remove_security_service,
3202 self.fake_context,
3203 self.share_nw_dict['id'],
3204 security_dict1['id'])
3206 def test_security_services_relation(self):
3207 security_dict1 = {'id': 'fake security service id1',
3208 'project_id': self.fake_context.project_id,
3209 'type': 'fake type'}
3211 db_api.share_network_create(self.fake_context, self.share_nw_dict)
3212 db_api.security_service_create(self.fake_context, security_dict1)
3214 result = db_api.share_network_get(self.fake_context,
3215 self.share_nw_dict['id'])
3217 self.assertEqual(0, len(result['security_services']))
3219 def test_shares_relation(self):
3220 share_dict = {'id': 'fake share id1'}
3222 db_api.share_network_create(self.fake_context, self.share_nw_dict)
3223 db_api.share_create(self.fake_context, share_dict)
3225 result = db_api.share_network_get(self.fake_context,
3226 self.share_nw_dict['id'])
3228 self.assertEqual(0, len(result['share_instances']))
3230 def test_association_get(self):
3231 network = db_api.share_network_create(
3232 self.fake_context, self.share_nw_dict)
3233 security_service = db_api.security_service_create(
3234 self.fake_context, security_service_dict)
3235 network_id = network['id']
3236 security_service_id = security_service['id']
3238 db_api.share_network_add_security_service(
3239 self.fake_context, network_id, security_service_id)
3240 result = db_api.share_network_security_service_association_get(
3241 self.fake_context, network_id, security_service_id)
3243 self.assertEqual(result['share_network_id'], network_id)
3244 self.assertEqual(result['security_service_id'], security_service_id)
3246 def test_share_network_update_security_service(self):
3247 new_sec_service = copy.copy(security_service_dict)
3248 new_sec_service['id'] = 'fakeid'
3249 share_network_id = self.share_nw_dict['id']
3250 db_api.share_network_create(
3251 self.fake_context, self.share_nw_dict)
3252 db_api.security_service_create(
3253 self.fake_context, security_service_dict)
3254 db_api.security_service_create(self.fake_context, new_sec_service)
3255 db_api.share_network_add_security_service(
3256 self.fake_context, share_network_id,
3257 security_service_dict['id'])
3258 db_api.share_network_update_security_service(
3259 self.fake_context, share_network_id, security_service_dict['id'],
3260 new_sec_service['id'])
3262 association = db_api.share_network_security_service_association_get(
3263 self.fake_context, share_network_id, new_sec_service['id'])
3265 self.assertEqual(association['share_network_id'], share_network_id)
3266 self.assertEqual(
3267 association['security_service_id'], new_sec_service['id'])
3270@ddt.ddt
3271class ShareNetworkSubnetDatabaseAPITestCase(BaseDatabaseAPITestCase):
3273 def __init__(self, *args, **kwargs):
3274 super(ShareNetworkSubnetDatabaseAPITestCase, self).__init__(
3275 *args, **kwargs)
3276 self.fake_context = context.RequestContext(user_id='fake user',
3277 project_id='fake project',
3278 is_admin=False)
3280 def setUp(self):
3281 super(ShareNetworkSubnetDatabaseAPITestCase, self).setUp()
3282 self.subnet_dict = {'id': 'fake network id',
3283 'neutron_net_id': 'fake net id',
3284 'neutron_subnet_id': 'fake subnet id',
3285 'network_type': 'vlan',
3286 'segmentation_id': 1000,
3287 'share_network_id': 'fake_id',
3288 'cidr': '10.0.0.0/24',
3289 'ip_version': 4,
3290 'availability_zone_id': None}
3292 def test_create(self):
3293 result = db_api.share_network_subnet_create(
3294 self.fake_context, self.subnet_dict)
3295 self._check_fields(expected=self.subnet_dict, actual=result)
3297 def test_create_duplicated_id(self):
3298 db_api.share_network_subnet_create(self.fake_context, self.subnet_dict)
3300 self.assertRaises(db_exception.DBDuplicateEntry,
3301 db_api.share_network_subnet_create,
3302 self.fake_context,
3303 self.subnet_dict)
3305 def test_get(self):
3306 db_api.share_network_subnet_create(self.fake_context, self.subnet_dict)
3308 result = db_api.share_network_subnet_get(self.fake_context,
3309 self.subnet_dict['id'])
3310 self._check_fields(expected=self.subnet_dict, actual=result)
3312 @ddt.data([{'id': 'fake_id_1', 'identifier': 'fake_identifier',
3313 'host': 'fake_host'}],
3314 [{'id': 'fake_id_2', 'identifier': 'fake_identifier',
3315 'host': 'fake_host'},
3316 {'id': 'fake_id_3', 'identifier': 'fake_identifier',
3317 'host': 'fake_host'}])
3318 def test_get_with_share_servers(self, share_servers):
3319 share_net_subnets = [
3320 db_api.share_network_subnet_create(
3321 self.fake_context, self.subnet_dict)]
3323 for share_server in share_servers:
3324 share_server['share_network_subnets'] = share_net_subnets
3325 db_api.share_server_create(self.fake_context, share_server)
3327 result = db_api.share_network_subnet_get(self.fake_context,
3328 self.subnet_dict['id'])
3330 self.assertEqual(len(share_servers),
3331 len(result['share_servers']))
3333 for index, share_server in enumerate(share_servers):
3334 result = db_api.share_network_subnet_get_all_by_share_server_id(
3335 self.fake_context, share_server['id'])
3336 for key, value in share_server['share_network_subnets'][0].items():
3337 if key != 'share_servers':
3338 self.assertEqual(value, result[0][key])
3340 def test_get_not_found(self):
3341 db_api.share_network_subnet_create(self.fake_context, self.subnet_dict)
3343 self.assertRaises(exception.ShareNetworkSubnetNotFound,
3344 db_api.share_network_subnet_get,
3345 self.fake_context,
3346 'fake_id')
3348 def test_delete(self):
3349 db_api.share_network_subnet_create(self.fake_context, self.subnet_dict)
3350 db_api.share_network_subnet_delete(self.fake_context,
3351 self.subnet_dict['id'])
3353 self.assertRaises(exception.ShareNetworkSubnetNotFound,
3354 db_api.share_network_subnet_delete,
3355 self.fake_context,
3356 self.subnet_dict['id'])
3358 def test_delete_not_found(self):
3359 self.assertRaises(exception.ShareNetworkSubnetNotFound,
3360 db_api.share_network_subnet_delete,
3361 self.fake_context,
3362 'fake_id')
3364 def test_update(self):
3365 update_dict = {
3366 'gateway': 'fake_gateway',
3367 'ip_version': 6,
3368 'mtu': ''
3369 }
3371 db_api.share_network_subnet_create(self.fake_context, self.subnet_dict)
3372 db_api.share_network_subnet_update(
3373 self.fake_context, self.subnet_dict['id'], update_dict)
3375 result = db_api.share_network_subnet_get(self.fake_context,
3376 self.subnet_dict['id'])
3377 self._check_fields(expected=update_dict, actual=result)
3379 def test_update_not_found(self):
3380 self.assertRaises(exception.ShareNetworkSubnetNotFound,
3381 db_api.share_network_subnet_update,
3382 self.fake_context,
3383 self.subnet_dict['id'],
3384 {})
3386 @ddt.data([
3387 {
3388 'id': 'sn_id1',
3389 'project_id': 'fake project',
3390 'user_id': 'fake'
3391 }
3392 ], [
3393 {
3394 'id': 'fake_id',
3395 'project_id': 'fake project',
3396 'user_id': 'fake'
3397 },
3398 {
3399 'id': 'sn_id2',
3400 'project_id': 'fake project',
3401 'user_id': 'fake'
3402 }
3403 ])
3404 def test_get_all_by_share_network(self, share_networks):
3406 for idx, share_network in enumerate(share_networks):
3407 self.subnet_dict['share_network_id'] = share_network['id']
3408 self.subnet_dict['id'] = 'fake_id%s' % idx
3410 db_api.share_network_create(self.fake_context, share_network)
3411 db_api.share_network_subnet_create(self.fake_context,
3412 self.subnet_dict)
3413 for share_network in share_networks:
3414 subnets = db_api.share_network_subnet_get_all_by_share_network(
3415 self.fake_context, share_network['id'])
3416 self.assertEqual(1, len(subnets))
3418 def test_get_by_availability_zone_id(self):
3419 with db_api.context_manager.writer.using(self.fake_context):
3420 az = db_api._availability_zone_create_if_not_exist(
3421 self.fake_context, 'fake_zone_id',
3422 )
3423 self.subnet_dict['availability_zone_id'] = az['id']
3424 db_api.share_network_subnet_create(self.fake_context, self.subnet_dict)
3426 result = db_api.share_network_subnets_get_all_by_availability_zone_id(
3427 self.fake_context, self.subnet_dict['share_network_id'], az['id'])
3429 self._check_fields(expected=self.subnet_dict, actual=result[0])
3431 def test_get_az_subnets(self):
3432 with db_api.context_manager.writer.using(self.fake_context):
3433 az = db_api._availability_zone_create_if_not_exist(
3434 self.fake_context, 'fake_zone_id',
3435 )
3436 self.subnet_dict['availability_zone_id'] = az['id']
3437 db_api.share_network_subnet_create(self.fake_context, self.subnet_dict)
3439 result = db_api.share_network_subnet_get_all_with_same_az(
3440 self.fake_context, self.subnet_dict['id'])
3442 self.subnet_dict['share_network'] = None
3444 self._check_fields(expected=self.subnet_dict, actual=result[0])
3446 def test_get_az_subnets_not_found(self):
3447 self.assertRaises(
3448 exception.ShareNetworkSubnetNotFound,
3449 db_api.share_network_subnet_get_all_with_same_az,
3450 self.fake_context, 'share_network_subnet_id')
3452 def test_get_default_subnet(self):
3453 db_api.share_network_subnet_create(self.fake_context, self.subnet_dict)
3455 result = db_api.share_network_subnet_get_default_subnets(
3456 self.fake_context, self.subnet_dict['share_network_id'])
3458 self._check_fields(expected=self.subnet_dict, actual=result[0])
3460 def test_get_by_share_server_id_not_found(self):
3461 self.assertRaises(
3462 exception.ShareNetworkSubnetNotFoundByShareServer,
3463 db_api.share_network_subnet_get_all_by_share_server_id,
3464 self.fake_context, 'share_server_id')
3466 def test_share_network_subnet_metadata_get(self):
3467 metadata = {'a': 'b', 'c': 'd'}
3469 subnet_1 = db_api.share_network_subnet_create(
3470 self.fake_context, self.subnet_dict)
3471 db_api.share_network_subnet_metadata_update(
3472 self.fake_context, share_network_subnet_id=subnet_1['id'],
3473 metadata=metadata, delete=False)
3474 self.assertEqual(
3475 metadata, db_api.share_network_subnet_metadata_get(
3476 self.fake_context, share_network_subnet_id=subnet_1['id']))
3478 def test_share_network_subnet_metadata_get_item(self):
3479 metadata = {'a': 'b', 'c': 'd'}
3480 key = 'a'
3481 shouldbe = {'a': 'b'}
3482 subnet_1 = db_api.share_network_subnet_create(
3483 self.fake_context, self.subnet_dict)
3484 db_api.share_network_subnet_metadata_update(
3485 self.fake_context, share_network_subnet_id=subnet_1['id'],
3486 metadata=metadata, delete=False)
3487 self.assertEqual(
3488 shouldbe, db_api.share_network_subnet_metadata_get_item(
3489 self.fake_context, share_network_subnet_id=subnet_1['id'],
3490 key=key))
3492 def test_share_network_subnet_metadata_update(self):
3493 metadata1 = {'a': '1', 'c': '2'}
3494 metadata2 = {'a': '3', 'd': '5'}
3495 should_be = {'a': '3', 'c': '2', 'd': '5'}
3496 subnet_1 = db_api.share_network_subnet_create(
3497 self.fake_context, self.subnet_dict)
3498 db_api.share_network_subnet_metadata_update(
3499 self.fake_context, share_network_subnet_id=subnet_1['id'],
3500 metadata=metadata1, delete=False)
3501 db_api.share_network_subnet_metadata_update(
3502 self.fake_context, share_network_subnet_id=subnet_1['id'],
3503 metadata=metadata2, delete=False)
3504 self.assertEqual(
3505 should_be, db_api.share_network_subnet_metadata_get(
3506 self.fake_context, share_network_subnet_id=subnet_1['id']))
3508 def test_share_network_subnet_metadata_delete(self):
3509 key = 'a'
3510 metadata = {'a': '1', 'c': '2'}
3511 should_be = {'c': '2'}
3512 subnet_1 = db_api.share_network_subnet_create(
3513 self.fake_context, self.subnet_dict)
3514 db_api.share_network_subnet_metadata_update(
3515 self.fake_context, share_network_subnet_id=subnet_1['id'],
3516 metadata=metadata, delete=False)
3517 db_api.share_network_subnet_metadata_delete(
3518 self.fake_context, share_network_subnet_id=subnet_1['id'],
3519 key=key)
3520 self.assertEqual(
3521 should_be, db_api.share_network_subnet_metadata_get(
3522 self.fake_context, share_network_subnet_id=subnet_1['id']))
3525@ddt.ddt
3526class SecurityServiceDatabaseAPITestCase(BaseDatabaseAPITestCase):
3528 def __init__(self, *args, **kwargs):
3529 super(SecurityServiceDatabaseAPITestCase, self).__init__(*args,
3530 **kwargs)
3532 self.fake_context = context.RequestContext(user_id='fake user',
3533 project_id='fake project',
3534 is_admin=False)
3536 def _check_expected_fields(self, result, expected):
3537 for key in expected:
3538 self.assertEqual(expected[key], result[key])
3540 def test_create(self):
3541 result = db_api.security_service_create(self.fake_context,
3542 security_service_dict)
3544 self._check_expected_fields(result, security_service_dict)
3546 def test_create_with_duplicated_id(self):
3547 db_api.security_service_create(self.fake_context,
3548 security_service_dict)
3550 self.assertRaises(db_exception.DBDuplicateEntry,
3551 db_api.security_service_create,
3552 self.fake_context,
3553 security_service_dict)
3555 def test_get(self):
3556 db_api.security_service_create(self.fake_context,
3557 security_service_dict)
3559 result = db_api.security_service_get(self.fake_context,
3560 security_service_dict['id'])
3562 self._check_expected_fields(result, security_service_dict)
3564 def test_get_not_found(self):
3565 self.assertRaises(exception.SecurityServiceNotFound,
3566 db_api.security_service_get,
3567 self.fake_context,
3568 'wrong id')
3570 def test_get_all_by_share_network(self):
3571 dict1 = security_service_dict
3572 dict2 = security_service_dict.copy()
3573 dict2['id'] = 'fake id 2'
3574 db_api.security_service_create(self.fake_context,
3575 dict1)
3576 db_api.security_service_create(self.fake_context,
3577 dict2)
3578 share_nw_dict = {'id': 'fake network id',
3579 'project_id': 'fake project',
3580 'user_id': 'fake_user_id'}
3581 db_api.share_network_create(self.fake_context, share_nw_dict)
3582 db_api.share_network_add_security_service(
3583 self.fake_context,
3584 share_nw_dict['id'], dict1['id'])
3586 result = db_api.security_service_get_all_by_share_network(
3587 self.fake_context, share_nw_dict['id'])
3588 self._check_expected_fields(result[0], dict1)
3589 self.assertEqual(1, len(result))
3591 def test_delete(self):
3592 db_api.security_service_create(self.fake_context,
3593 security_service_dict)
3595 db_api.security_service_delete(self.fake_context,
3596 security_service_dict['id'])
3598 self.assertRaises(exception.SecurityServiceNotFound,
3599 db_api.security_service_get,
3600 self.fake_context,
3601 security_service_dict['id'])
3603 def test_update(self):
3604 update_dict = {
3605 'dns_ip': 'new dns',
3606 'server': 'new ldap server',
3607 'domain': 'new ldap domain',
3608 'default_ad_site': 'new ldap default_ad_site',
3609 'ou': 'new ldap ou',
3610 'user': 'new user',
3611 'password': 'new password',
3612 'name': 'new whatever',
3613 'description': 'new nevermind',
3614 }
3616 db_api.security_service_create(self.fake_context,
3617 security_service_dict)
3619 result = db_api.security_service_update(self.fake_context,
3620 security_service_dict['id'],
3621 update_dict)
3623 self._check_expected_fields(result, update_dict)
3625 def test_update_no_updates(self):
3626 db_api.security_service_create(self.fake_context,
3627 security_service_dict)
3629 result = db_api.security_service_update(self.fake_context,
3630 security_service_dict['id'],
3631 {})
3633 self._check_expected_fields(result, security_service_dict)
3635 def test_update_not_found(self):
3636 self.assertRaises(exception.SecurityServiceNotFound,
3637 db_api.security_service_update,
3638 self.fake_context,
3639 'wrong id',
3640 {})
3642 def test_get_all_no_records(self):
3643 result = db_api.security_service_get_all(self.fake_context)
3645 self.assertEqual(0, len(result))
3647 @ddt.data(1, 2)
3648 def test_get_all(self, records_count):
3649 index = 0
3650 services = []
3651 while index < records_count:
3652 service_dict = dict(security_service_dict)
3653 service_dict.update({'id': 'fake_id%s' % index})
3654 services.append(service_dict)
3655 db_api.security_service_create(self.fake_context, service_dict)
3656 index += 1
3658 result = db_api.security_service_get_all(self.fake_context)
3660 self.assertEqual(len(services), len(result))
3661 for index, service in enumerate(services):
3662 self._check_fields(expected=service, actual=result[index])
3664 def test_get_all_two_records(self):
3665 dict1 = security_service_dict
3666 dict2 = security_service_dict.copy()
3667 dict2['id'] = 'fake id 2'
3668 db_api.security_service_create(self.fake_context,
3669 dict1)
3670 db_api.security_service_create(self.fake_context,
3671 dict2)
3673 result = db_api.security_service_get_all(self.fake_context)
3675 self.assertEqual(2, len(result))
3677 def test_get_all_by_project(self):
3678 dict1 = security_service_dict
3679 dict2 = security_service_dict.copy()
3680 dict2['id'] = 'fake id 2'
3681 dict2['project_id'] = 'fake project 2'
3682 db_api.security_service_create(self.fake_context,
3683 dict1)
3684 db_api.security_service_create(self.fake_context,
3685 dict2)
3687 result1 = db_api.security_service_get_all_by_project(
3688 self.fake_context,
3689 dict1['project_id'])
3691 self.assertEqual(1, len(result1))
3692 self._check_expected_fields(result1[0], dict1)
3694 result2 = db_api.security_service_get_all_by_project(
3695 self.fake_context,
3696 dict2['project_id'])
3698 self.assertEqual(1, len(result2))
3699 self._check_expected_fields(result2[0], dict2)
3702@ddt.ddt
3703class ShareServerDatabaseAPITestCase(test.TestCase):
3705 def setUp(self):
3706 super(ShareServerDatabaseAPITestCase, self).setUp()
3707 self.ctxt = context.RequestContext(user_id='user_id',
3708 project_id='project_id',
3709 is_admin=True)
3710 self.share_net_subnets = [
3711 db_utils.create_share_network_subnet(
3712 id=uuidutils.generate_uuid(),
3713 share_network_id=uuidutils.generate_uuid())]
3715 def test_share_server_get(self):
3716 expected = db_utils.create_share_server(
3717 share_network_subnets=self.share_net_subnets)
3718 server = db_api.share_server_get(self.ctxt, expected['id'])
3719 self.assertEqual(expected['id'], server['id'])
3720 self.assertEqual(expected.share_network_subnets[0]['id'],
3721 server.share_network_subnets[0]['id'])
3722 self.assertEqual(
3723 expected.share_network_subnets[0]['share_network_id'],
3724 server.share_network_subnets[0]['share_network_id'])
3725 self.assertEqual(expected.host, server.host)
3726 self.assertEqual(expected.status, server.status)
3728 def test_get_not_found(self):
3729 fake_id = 'FAKE_UUID'
3730 self.assertRaises(exception.ShareServerNotFound,
3731 db_api.share_server_get, self.ctxt, fake_id)
3733 def test_create(self):
3734 server = db_utils.create_share_server(
3735 share_network_subnets=self.share_net_subnets)
3736 self.assertTrue(server['id'])
3737 self.assertEqual(server.share_network_subnets[0]['id'],
3738 server['share_network_subnets'][0]['id'])
3739 self.assertEqual(
3740 server.share_network_subnets[0]['share_network_id'],
3741 server['share_network_subnets'][0]['share_network_id'])
3742 self.assertEqual(server.host, server['host'])
3743 self.assertEqual(server.status, server['status'])
3745 def test_delete(self):
3746 server = db_utils.create_share_server()
3747 num_records = len(db_api.share_server_get_all(self.ctxt))
3748 db_api.share_server_delete(self.ctxt, server['id'])
3749 self.assertEqual(num_records - 1,
3750 len(db_api.share_server_get_all(self.ctxt)))
3752 def test_delete_not_found(self):
3753 fake_id = 'FAKE_UUID'
3754 self.assertRaises(exception.ShareServerNotFound,
3755 db_api.share_server_delete,
3756 self.ctxt, fake_id)
3758 def test_update(self):
3759 share_net_subnets_update = [
3760 db_utils.create_share_network_subnet(
3761 id=uuidutils.generate_uuid(),
3762 share_network_id=uuidutils.generate_uuid())]
3763 update = {
3764 'share_network_subnets': share_net_subnets_update,
3765 'host': 'update_host',
3766 'status': constants.STATUS_ACTIVE,
3767 }
3768 server = db_utils.create_share_server(
3769 share_network_subnets=self.share_net_subnets)
3770 updated_server = db_api.share_server_update(self.ctxt, server['id'],
3771 update)
3772 self.assertEqual(server['id'], updated_server['id'])
3773 self.assertEqual(
3774 update['share_network_subnets'][0]['share_network_id'],
3775 updated_server.share_network_subnets[0]['share_network_id'])
3776 self.assertEqual(update['host'], updated_server.host)
3777 self.assertEqual(update['status'], updated_server.status)
3779 def test_update_not_found(self):
3780 fake_id = 'FAKE_UUID'
3781 self.assertRaises(exception.ShareServerNotFound,
3782 db_api.share_server_update,
3783 self.ctxt, fake_id, {})
3785 def test_get_all_by_host_and_share_subnet_valid(self):
3786 subnet_1 = {
3787 'id': '1',
3788 'share_network_id': '1',
3789 }
3790 subnet_2 = {
3791 'id': '2',
3792 'share_network_id': '2',
3793 }
3794 share_net_subnets1 = db_utils.create_share_network_subnet(**subnet_1)
3795 share_net_subnets2 = db_utils.create_share_network_subnet(**subnet_2)
3796 valid = {
3797 'share_network_subnets': [share_net_subnets1],
3798 'host': 'host1',
3799 'status': constants.STATUS_ACTIVE,
3800 }
3801 invalid = {
3802 'share_network_subnets': [share_net_subnets2],
3803 'host': 'host1',
3804 'status': constants.STATUS_ERROR,
3805 }
3806 other = {
3807 'share_network_subnets': [share_net_subnets1],
3808 'host': 'host2',
3809 'status': constants.STATUS_ACTIVE,
3810 }
3811 valid = db_utils.create_share_server(**valid)
3812 db_utils.create_share_server(**invalid)
3813 db_utils.create_share_server(**other)
3815 servers = db_api.share_server_get_all_by_host_and_share_subnet_valid(
3816 self.ctxt,
3817 host='host1',
3818 share_subnet_id='1')
3820 self.assertEqual(valid['id'], servers[0]['id'])
3822 def test_get_all_by_host_and_share_subnet_valid_not_found(self):
3823 self.assertRaises(
3824 exception.ShareServerNotFound,
3825 db_api.share_server_get_all_by_host_and_share_subnet_valid,
3826 self.ctxt, host='fake', share_subnet_id='fake'
3827 )
3829 def test_get_all_by_host_and_share_subnet(self):
3830 subnet_1 = {
3831 'id': '1',
3832 'share_network_id': '1',
3833 }
3834 share_net_subnets1 = db_utils.create_share_network_subnet(**subnet_1)
3835 valid = {
3836 'share_network_subnets': [share_net_subnets1],
3837 'host': 'host1',
3838 'status': constants.STATUS_SERVER_NETWORK_CHANGE,
3839 }
3840 other = {
3841 'share_network_subnets': [share_net_subnets1],
3842 'host': 'host1',
3843 'status': constants.STATUS_ERROR,
3844 }
3845 invalid = {
3846 'share_network_subnets': [share_net_subnets1],
3847 'host': 'host2',
3848 'status': constants.STATUS_ACTIVE,
3849 }
3850 valid = db_utils.create_share_server(**valid)
3851 invalid = db_utils.create_share_server(**invalid)
3852 other = db_utils.create_share_server(**other)
3854 servers = db_api.share_server_get_all_by_host_and_or_share_subnet(
3855 self.ctxt,
3856 host='host1',
3857 share_subnet_id='1')
3859 self.assertEqual(2, len(servers))
3860 ids = [s['id'] for s in servers]
3861 self.assertIn(valid['id'], ids)
3862 self.assertIn(other['id'], ids)
3863 self.assertNotIn(invalid['id'], ids)
3865 def test_get_all_by_host_and_share_subnet_not_found(self):
3866 self.assertRaises(
3867 exception.ShareServerNotFound,
3868 db_api.share_server_get_all_by_host_and_or_share_subnet,
3869 self.ctxt, host='fake', share_subnet_id='fake'
3870 )
3872 def test_get_all(self):
3873 srv1 = {
3874 'host': 'host1',
3875 'status': constants.STATUS_ACTIVE,
3876 }
3877 srv2 = {
3878 'host': 'host1',
3879 'status': constants.STATUS_ERROR,
3880 }
3881 srv3 = {
3882 'host': 'host2',
3883 'status': constants.STATUS_ACTIVE,
3884 }
3885 servers = db_api.share_server_get_all(self.ctxt)
3886 self.assertEqual(0, len(servers))
3888 to_delete = db_utils.create_share_server(**srv1)
3889 db_utils.create_share_server(**srv2)
3890 db_utils.create_share_server(**srv3)
3892 servers = db_api.share_server_get_all(self.ctxt)
3893 self.assertEqual(3, len(servers))
3895 db_api.share_server_delete(self.ctxt, to_delete['id'])
3896 servers = db_api.share_server_get_all(self.ctxt)
3897 self.assertEqual(2, len(servers))
3899 def test_backend_details_set(self):
3900 details = {
3901 'value1': '1',
3902 'value2': '2',
3903 }
3904 server = db_utils.create_share_server()
3905 db_api.share_server_backend_details_set(self.ctxt, server['id'],
3906 details)
3908 self.assertDictEqual(
3909 details,
3910 db_api.share_server_get(self.ctxt, server['id'])['backend_details']
3911 )
3913 details.update({'value2': '4'})
3914 db_api.share_server_backend_details_set(self.ctxt, server['id'],
3915 details)
3916 self.assertDictEqual(
3917 details,
3918 db_api.share_server_get(self.ctxt, server['id'])['backend_details']
3919 )
3921 def test_backend_details_set_not_found(self):
3922 fake_id = 'FAKE_UUID'
3923 self.assertRaises(exception.ShareServerNotFound,
3924 db_api.share_server_backend_details_set,
3925 self.ctxt, fake_id, {})
3927 def test_get_with_details(self):
3928 values = {
3929 'share_network_subnets': [
3930 db_utils.create_share_network_subnet(
3931 id='fake_subnet_id',
3932 share_network_id='fake_share_net_id')],
3933 'host': 'hostname',
3934 'status': constants.STATUS_ACTIVE,
3935 }
3936 details = {
3937 'value1': '1',
3938 'value2': '2',
3939 }
3940 srv_id = db_utils.create_share_server(**values)['id']
3941 db_api.share_server_backend_details_set(self.ctxt, srv_id, details)
3942 server = db_api.share_server_get(self.ctxt, srv_id)
3943 self.assertEqual(srv_id, server['id'])
3944 self.assertEqual(values['share_network_subnets'][0]['id'],
3945 server.share_network_subnets[0]['id'])
3946 self.assertEqual(
3947 values['share_network_subnets'][0]['share_network_id'],
3948 server.share_network_subnets[0]['share_network_id'])
3949 self.assertEqual(values['host'], server.host)
3950 self.assertEqual(values['status'], server.status)
3951 self.assertDictEqual(server['backend_details'], details)
3952 self.assertIn('backend_details', server.to_dict())
3954 def test_delete_with_details(self):
3955 server = db_utils.create_share_server(backend_details={
3956 'value1': '1',
3957 'value2': '2',
3958 })
3960 num_records = len(db_api.share_server_get_all(self.ctxt))
3961 db_api.share_server_delete(self.ctxt, server['id'])
3962 self.assertEqual(num_records - 1,
3963 len(db_api.share_server_get_all(self.ctxt)))
3965 @ddt.data('foobar', 'fake', '-fake-', 'some_fake_', 'some-fake-',
3966 '-fake-identifier', '_fake_identifier', 'some-fake-identifier',
3967 'some_fake_identifier')
3968 def test_share_server_search_by_identifier(self, identifier):
3970 server = {
3971 'host': 'hostname',
3972 'status': constants.STATUS_ACTIVE,
3973 'is_auto_deletable': True,
3974 'updated_at': datetime.datetime(2018, 5, 1),
3975 'identifier': 'some_fake_identifier',
3976 }
3978 server = db_utils.create_share_server(**server)
3979 if identifier in ('foobar', 'fake', '-fake-', 'some_fake_',
3980 'some-fake-'):
3981 self.assertRaises(exception.ShareServerNotFound,
3982 db_api.share_server_search_by_identifier,
3983 self.ctxt, identifier)
3984 else:
3985 result = db_api.share_server_search_by_identifier(
3986 self.ctxt, identifier)
3987 self.assertEqual(server['id'], result[0]['id'])
3989 @ddt.data((True, True, True, 3),
3990 (True, True, False, 2),
3991 (True, False, False, 1),
3992 (False, False, False, 0))
3993 @ddt.unpack
3994 def test_share_server_get_all_unused_deletable(self,
3995 server_1_is_auto_deletable,
3996 server_2_is_auto_deletable,
3997 server_3_is_auto_deletable,
3998 expected_len):
3999 server1 = {
4000 'host': 'hostname',
4001 'status': constants.STATUS_ACTIVE,
4002 'is_auto_deletable': server_1_is_auto_deletable,
4003 'updated_at': datetime.datetime(2018, 5, 1)
4004 }
4005 server2 = {
4006 'host': 'hostname',
4007 'status': constants.STATUS_ACTIVE,
4008 'is_auto_deletable': server_2_is_auto_deletable,
4009 'updated_at': datetime.datetime(2018, 5, 1)
4010 }
4011 server3 = {
4012 'host': 'hostname',
4013 'status': constants.STATUS_ACTIVE,
4014 'is_auto_deletable': server_3_is_auto_deletable,
4015 'updated_at': datetime.datetime(2018, 5, 1)
4016 }
4017 db_utils.create_share_server(**server1)
4018 db_utils.create_share_server(**server2)
4019 db_utils.create_share_server(**server3)
4020 host = 'hostname'
4021 updated_before = datetime.datetime(2019, 5, 1)
4023 unused_deletable = db_api.share_server_get_all_unused_deletable(
4024 self.ctxt, host, updated_before)
4025 self.assertEqual(expected_len, len(unused_deletable))
4027 @ddt.data({'host': 'fakepool@fakehost'},
4028 {'status': constants.STATUS_SERVER_MIGRATING_TO},
4029 {'source_share_server_id': 'fake_ss_id'},
4030 {'share_network_id': uuidutils.generate_uuid()})
4031 def test_share_server_get_all_with_filters(self, filters):
4032 server_data = copy.copy(filters)
4033 share_network_id = server_data.pop('share_network_id', None)
4034 share_network_subnet = {}
4035 if share_network_id:
4036 db_utils.create_share_network(id=share_network_id)
4037 share_network_subnet = db_utils.create_share_network_subnet(
4038 id=uuidutils.generate_uuid(),
4039 share_network_id=share_network_id)
4040 server_data['share_network_subnets'] = [share_network_subnet]
4041 db_utils.create_share_server(**server_data)
4042 db_utils.create_share_server()
4043 filter_keys = filters.keys()
4045 results = db_api.share_server_get_all_with_filters(self.ctxt, filters)
4047 self.assertEqual(1, len(results))
4048 for result in results:
4049 for key in filter_keys:
4050 if key == 'share_network_id':
4051 self.assertEqual(share_network_subnet['share_network_id'],
4052 filters[key])
4053 self.assertEqual(share_network_subnet['id'],
4054 result['share_network_subnets'][0]['id'])
4055 else:
4056 self.assertEqual(result[key], filters[key])
4058 @ddt.data('fake@fake', 'host1@backend1')
4059 def test_share_server_get_all_by_host(self, host):
4060 db_utils.create_share_server(host='fake@fake')
4061 db_utils.create_share_server(host='host1@backend1')
4063 share_servers = db_api.share_server_get_all_by_host(self.ctxt, host)
4065 self.assertEqual(1, len(share_servers))
4066 for share_server in share_servers:
4067 self.assertEqual(host, share_server['host'])
4069 def test_share_servers_update(self):
4070 servers = [db_utils.create_share_server()
4071 for __ in range(1, 3)]
4072 server_ids = [server['id'] for server in servers]
4073 values = {'status': constants.STATUS_NETWORK_CHANGE}
4075 db_api.share_servers_update(
4076 self.ctxt, server_ids, values)
4078 share_servers = [
4079 db_api.share_server_get(self.ctxt, server_id)
4080 for server_id in server_ids]
4082 for ss in share_servers:
4083 self.assertEqual(constants.STATUS_NETWORK_CHANGE, ss['status'])
4085 def test_encryption_keys_get_count(self):
4086 servers = [db_utils.create_share_server(
4087 encryption_key_ref=uuidutils.generate_uuid())
4088 for __ in range(1, 4)]
4089 count = db_api.encryption_keys_get_count(context.get_admin_context())
4090 self.assertEqual(count, len(servers))
4093class ServiceDatabaseAPITestCase(test.TestCase):
4095 def setUp(self):
4096 super(ServiceDatabaseAPITestCase, self).setUp()
4097 self.ctxt = context.RequestContext(user_id='user_id',
4098 project_id='project_id',
4099 is_admin=True)
4101 self.service_data = {'host': "fake_host",
4102 'binary': "fake_binary",
4103 'topic': "fake_topic",
4104 'report_count': 0,
4105 'availability_zone': "fake_zone"}
4107 def test_create(self):
4108 """Ensure we create a new AZ if necessary."""
4109 service = db_api.service_create(self.ctxt, self.service_data)
4110 az = db_api.availability_zone_get(self.ctxt, "fake_zone")
4112 self.assertEqual(az.id, service.availability_zone_id)
4113 self.assertSubDictMatch(self.service_data, service.to_dict())
4115 def test_create__az_exists(self):
4116 """Ensure we use an AZ is it already exists."""
4117 with db_api.context_manager.writer.using(self.ctxt):
4118 az = db_api._availability_zone_create_if_not_exist(
4119 self.ctxt, 'fake_zone',
4120 )
4122 service = db_api.service_create(self.ctxt, self.service_data)
4124 self.assertEqual(az.id, service.availability_zone_id)
4125 self.assertSubDictMatch(self.service_data, service.to_dict())
4127 def test_create__az_missing(self):
4128 """Ensure we fail if AZ info is missing."""
4129 self.service_data.pop('availability_zone')
4130 exc = self.assertRaises(
4131 ValueError,
4132 db_api.service_create,
4133 self.ctxt,
4134 self.service_data,
4135 )
4136 self.assertIn(
4137 "Values dict should have 'availability_zone' field.",
4138 str(exc),
4139 )
4141 def test_update(self):
4142 az_name = 'fake_zone2'
4143 update_data = {"availability_zone": az_name}
4145 service = db_api.service_create(self.ctxt, self.service_data)
4146 db_api.service_update(self.ctxt, service['id'], update_data)
4148 service = db_api.service_get(self.ctxt, service['id'])
4149 az = db_api.availability_zone_get(self.ctxt, az_name)
4151 self.assertEqual(az.id, service.availability_zone_id)
4152 valid_values = self.service_data
4153 valid_values.update(update_data)
4154 self.assertSubDictMatch(valid_values, service.to_dict())
4157@ddt.ddt
4158class AvailabilityZonesDatabaseAPITestCase(test.TestCase):
4160 def setUp(self):
4161 super(AvailabilityZonesDatabaseAPITestCase, self).setUp()
4162 self.ctxt = context.RequestContext(user_id='user_id',
4163 project_id='project_id',
4164 is_admin=True)
4166 @ddt.data({'fake': 'fake'}, {}, {'fakeavailability_zone': 'fake'},
4167 {'availability_zone': None}, {'availability_zone': ''})
4168 def test_ensure_availability_zone_exists_invalid(self, test_values):
4169 self.assertRaises(ValueError, db_api.ensure_availability_zone_exists,
4170 self.ctxt, test_values)
4172 def test_az_get(self):
4173 az_name = 'test_az'
4174 with db_api.context_manager.writer.using(self.ctxt):
4175 az = db_api._availability_zone_create_if_not_exist(
4176 self.ctxt, az_name
4177 )
4179 az_by_id = db_api.availability_zone_get(self.ctxt, az['id'])
4180 az_by_name = db_api.availability_zone_get(self.ctxt, az_name)
4182 self.assertEqual(az_name, az_by_id['name'])
4183 self.assertEqual(az_name, az_by_name['name'])
4184 self.assertEqual(az['id'], az_by_id['id'])
4185 self.assertEqual(az['id'], az_by_name['id'])
4187 def test_az_get_all(self):
4188 with db_api.context_manager.writer.using(self.ctxt):
4189 db_api._availability_zone_create_if_not_exist(self.ctxt, 'test1')
4190 db_api._availability_zone_create_if_not_exist(self.ctxt, 'test2')
4191 db_api._availability_zone_create_if_not_exist(self.ctxt, 'test3')
4193 db_api.service_create(self.ctxt, {'availability_zone': 'test2'})
4195 actual_result = db_api.availability_zone_get_all(self.ctxt)
4197 self.assertEqual(1, len(actual_result))
4198 self.assertEqual('test2', actual_result[0]['name'])
4201@ddt.ddt
4202class NetworkAllocationsDatabaseAPITestCase(test.TestCase):
4204 def setUp(self):
4205 super(NetworkAllocationsDatabaseAPITestCase, self).setUp()
4206 self.user_id = 'user_id'
4207 self.project_id = 'project_id'
4208 self.share_server_id = 'foo_share_server_id'
4209 self.share_network_subnet_id = 'foo_share_network_subnet_id'
4210 self.ctxt = context.RequestContext(
4211 user_id=self.user_id, project_id=self.project_id, is_admin=True)
4212 self.user_network_allocations = [
4213 {'share_server_id': self.share_server_id,
4214 'ip_address': '1.1.1.1',
4215 'status': constants.STATUS_ACTIVE,
4216 'label': None,
4217 'share_network_subnet_id': self.share_network_subnet_id},
4218 {'share_server_id': self.share_server_id,
4219 'ip_address': '2.2.2.2',
4220 'status': constants.STATUS_ACTIVE,
4221 'label': 'user',
4222 'share_network_subnet_id': self.share_network_subnet_id},
4223 ]
4224 self.admin_network_allocations = [
4225 {'share_server_id': self.share_server_id,
4226 'ip_address': '3.3.3.3',
4227 'status': constants.STATUS_ACTIVE,
4228 'label': 'admin',
4229 'share_network_subnet_id': None},
4230 {'share_server_id': self.share_server_id,
4231 'ip_address': '4.4.4.4',
4232 'status': constants.STATUS_ACTIVE,
4233 'label': 'admin',
4234 'share_network_subnet_id': None},
4235 ]
4237 def _setup_network_allocations_get_for_share_server(self):
4238 # Create share network
4239 share_network_data = {
4240 'id': 'foo_share_network_id',
4241 'user_id': self.user_id,
4242 'project_id': self.project_id,
4243 }
4244 db_api.share_network_create(self.ctxt, share_network_data)
4246 # Create share network subnet
4247 share_network_subnet_data = {
4248 'id': self.share_network_subnet_id,
4249 'share_network_id': self.user_id,
4250 }
4251 db_api.share_network_subnet_create(self.ctxt,
4252 share_network_subnet_data)
4254 # Create share server
4255 share_server_data = {
4256 'id': self.share_server_id,
4257 'host': 'fake_host',
4258 'status': 'active',
4259 }
4260 db_api.share_server_create(self.ctxt, share_server_data)
4262 # Create user network allocations
4263 for user_network_allocation in self.user_network_allocations:
4264 db_api.network_allocation_create(
4265 self.ctxt, user_network_allocation)
4267 # Create admin network allocations
4268 for admin_network_allocation in self.admin_network_allocations:
4269 db_api.network_allocation_create(
4270 self.ctxt, admin_network_allocation)
4272 def test_get_only_user_network_allocations(self):
4273 self._setup_network_allocations_get_for_share_server()
4275 result = db_api.network_allocations_get_for_share_server(
4276 self.ctxt, self.share_server_id, label='user')
4278 self.assertEqual(
4279 len(self.user_network_allocations), len(result))
4280 for na in result:
4281 self.assertIn(na.label, (None, 'user'))
4283 def test_get_only_admin_network_allocations(self):
4284 self._setup_network_allocations_get_for_share_server()
4286 result = db_api.network_allocations_get_for_share_server(
4287 self.ctxt, self.share_server_id, label='admin')
4289 self.assertEqual(
4290 len(self.admin_network_allocations), len(result))
4291 for na in result:
4292 self.assertEqual(na.label, 'admin')
4294 def test_get_all_network_allocations(self):
4295 self._setup_network_allocations_get_for_share_server()
4297 result = db_api.network_allocations_get_for_share_server(
4298 self.ctxt, self.share_server_id, label=None)
4300 self.assertEqual(
4301 len(self.user_network_allocations +
4302 self.admin_network_allocations),
4303 len(result)
4304 )
4305 for na in result:
4306 self.assertIn(na.label, ('admin', 'user', None))
4308 def test_network_allocation_get(self):
4309 self._setup_network_allocations_get_for_share_server()
4311 for allocation in self.admin_network_allocations:
4312 result = db_api.network_allocation_get(self.ctxt, allocation['id'])
4314 self.assertIsInstance(result, models.NetworkAllocation)
4315 self.assertEqual(allocation['id'], result.id)
4317 for allocation in self.user_network_allocations:
4318 result = db_api.network_allocation_get(self.ctxt, allocation['id'])
4320 self.assertIsInstance(result, models.NetworkAllocation)
4321 self.assertEqual(allocation['id'], result.id)
4323 def test_network_allocation_get_no_result(self):
4324 self._setup_network_allocations_get_for_share_server()
4326 self.assertRaises(exception.NotFound,
4327 db_api.network_allocation_get,
4328 self.ctxt,
4329 id='fake')
4331 def test_network_allocation_get_by_subnet_id(self):
4332 self._setup_network_allocations_get_for_share_server()
4334 result = db_api.network_allocations_get_for_share_server(
4335 self.ctxt, self.share_server_id,
4336 subnet_id=self.share_network_subnet_id)
4338 self.assertEqual(2, len(result))
4340 for network_allocation in result:
4341 self.assertIsInstance(network_allocation, models.NetworkAllocation)
4342 self.assertEqual(self.share_network_subnet_id,
4343 network_allocation.share_network_subnet_id)
4345 @ddt.data(True, False)
4346 def test_network_allocation_get_read_deleted(self, read_deleted):
4347 self._setup_network_allocations_get_for_share_server()
4349 deleted_allocation = {
4350 'share_server_id': self.share_server_id,
4351 'ip_address': '1.1.1.1',
4352 'status': constants.STATUS_ACTIVE,
4353 'label': None,
4354 'deleted': True,
4355 }
4357 new_obj = db_api.network_allocation_create(self.ctxt,
4358 deleted_allocation)
4359 if read_deleted:
4360 result = db_api.network_allocation_get(self.ctxt, new_obj.id,
4361 read_deleted=read_deleted)
4362 self.assertIsInstance(result, models.NetworkAllocation)
4363 self.assertEqual(new_obj.id, result.id)
4364 else:
4365 self.assertRaises(exception.NotFound,
4366 db_api.network_allocation_get,
4367 self.ctxt,
4368 id=self.share_server_id)
4370 def test_network_allocation_update(self):
4371 self._setup_network_allocations_get_for_share_server()
4373 for allocation in self.admin_network_allocations:
4374 old_obj = db_api.network_allocation_get(self.ctxt,
4375 allocation['id'])
4376 self.assertEqual('False', old_obj.deleted)
4377 updated_object = db_api.network_allocation_update(
4378 self.ctxt, allocation['id'], {'deleted': 'True'})
4380 self.assertEqual('True', updated_object.deleted)
4382 @ddt.data(True, False)
4383 def test_network_allocation_update_read_deleted(self, read_deleted):
4384 self._setup_network_allocations_get_for_share_server()
4386 db_api.network_allocation_update(
4387 self.ctxt,
4388 self.admin_network_allocations[0]['id'],
4389 {'deleted': 'True'}
4390 )
4392 if read_deleted:
4393 updated_object = db_api.network_allocation_update(
4394 self.ctxt, self.admin_network_allocations[0]['id'],
4395 {'deleted': 'False'}, read_deleted=read_deleted
4396 )
4397 self.assertEqual('False', updated_object.deleted)
4398 else:
4399 self.assertRaises(exception.NotFound,
4400 db_api.network_allocation_update,
4401 self.ctxt,
4402 id=self.share_server_id,
4403 values={'deleted': read_deleted},
4404 read_deleted=read_deleted)
4407class ReservationDatabaseAPITest(test.TestCase):
4409 def setUp(self):
4410 super(ReservationDatabaseAPITest, self).setUp()
4411 self.context = context.get_admin_context()
4413 def test_reservation_expire(self):
4414 quota_usage = db_api.quota_usage_create(self.context, 'fake_project',
4415 'fake_user', 'fake_resource',
4416 0, 12, until_refresh=None)
4417 with db_api.context_manager.writer.using(self.context):
4418 for time_s in (-1, 1):
4419 reservation = db_api._reservation_create(
4420 self.context, 'fake_uuid',
4421 quota_usage, 'fake_project',
4422 'fake_user', 'fake_resource', 10,
4423 timeutils.utcnow() +
4424 datetime.timedelta(days=time_s),
4425 )
4427 db_api.reservation_expire(self.context)
4429 with db_api.context_manager.reader.using(self.context):
4430 reservations = db_api._quota_reservations_query(
4431 self.context, ['fake_uuid'],
4432 ).all()
4433 quota_usage = db_api.quota_usage_get(self.context, 'fake_project',
4434 'fake_resource')
4435 self.assertEqual(1, len(reservations))
4436 self.assertEqual(reservation['id'], reservations[0]['id'])
4437 self.assertEqual(2, quota_usage['reserved'])
4440@ddt.ddt
4441class PurgeDeletedTest(test.TestCase):
4443 def setUp(self):
4444 super(PurgeDeletedTest, self).setUp()
4445 self.context = context.get_admin_context()
4447 def _days_ago(self, begin, end):
4448 return timeutils.utcnow() - datetime.timedelta(
4449 days=random.randint(begin, end))
4451 def _turn_on_foreign_key(self):
4452 engine = db_api.get_engine()
4453 connection = engine.raw_connection()
4454 try:
4455 cursor = connection.cursor()
4456 cursor.execute("PRAGMA foreign_keys = ON")
4457 finally:
4458 connection.close()
4460 @ddt.data({"del_days": 0, "num_left": 0},
4461 {"del_days": 10, "num_left": 2},
4462 {"del_days": 20, "num_left": 4})
4463 @ddt.unpack
4464 def test_purge_records_with_del_days(self, del_days, num_left):
4465 fake_now = timeutils.utcnow()
4466 with mock.patch.object(timeutils, 'utcnow',
4467 mock.Mock(return_value=fake_now)):
4468 # create resources soft-deleted in 0~9, 10~19 days ago
4469 for start, end in ((0, 9), (10, 19)):
4470 for unused in range(2):
4471 # share type
4472 db_utils.create_share_type(id=uuidutils.generate_uuid(),
4473 deleted_at=self._days_ago(start,
4474 end))
4475 # share
4476 share = db_utils.create_share_without_instance(
4477 metadata={},
4478 deleted_at=self._days_ago(start, end))
4479 # create share network
4480 network = db_utils.create_share_network(
4481 id=uuidutils.generate_uuid(),
4482 deleted_at=self._days_ago(start, end))
4483 # create security service
4484 db_utils.create_security_service(
4485 id=uuidutils.generate_uuid(),
4486 share_network_id=network.id,
4487 deleted_at=self._days_ago(start, end))
4488 # create share instance
4489 s_instance = db_utils.create_share_instance(
4490 id=uuidutils.generate_uuid(),
4491 share_network_id=network.id,
4492 share_id=share.id)
4493 # share access
4494 db_utils.create_share_access(
4495 id=uuidutils.generate_uuid(),
4496 share_id=share['id'],
4497 deleted_at=self._days_ago(start, end))
4498 # create share server
4499 db_utils.create_share_server(
4500 id=uuidutils.generate_uuid(),
4501 deleted_at=self._days_ago(start, end))
4502 # create snapshot
4503 db_api.share_snapshot_create(
4504 self.context, {'share_id': share['id'],
4505 'deleted_at': self._days_ago(start,
4506 end)},
4507 create_snapshot_instance=False)
4508 # update share instance
4509 db_api.share_instance_update(
4510 self.context,
4511 s_instance.id,
4512 {'deleted_at': self._days_ago(start, end)})
4514 db_api.purge_deleted_records(self.context, age_in_days=del_days)
4516 for model in [models.ShareTypes, models.Share,
4517 models.ShareNetwork, models.ShareAccessMapping,
4518 models.ShareInstance, models.ShareServer,
4519 models.ShareSnapshot, models.SecurityService]:
4520 with db_api.context_manager.reader.using(self.context):
4521 rows = db_api.model_query(self.context, model).count()
4522 self.assertEqual(num_left, rows)
4524 def test_purge_records_with_illegal_args(self):
4525 self.assertRaises(TypeError, db_api.purge_deleted_records,
4526 self.context)
4527 self.assertRaises(exception.InvalidParameterValue,
4528 db_api.purge_deleted_records,
4529 self.context,
4530 age_in_days=-1)
4532 def test_purge_records_with_constraint(self):
4533 self._turn_on_foreign_key()
4534 type_id = uuidutils.generate_uuid()
4535 # create share type1
4536 db_utils.create_share_type(id=type_id,
4537 deleted_at=self._days_ago(1, 1))
4538 # create share type2
4539 db_utils.create_share_type(id=uuidutils.generate_uuid(),
4540 deleted_at=self._days_ago(1, 1))
4541 # create share
4542 share = db_utils.create_share(share_type_id=type_id)
4544 db_api.purge_deleted_records(self.context, age_in_days=0)
4545 with db_api.context_manager.reader.using(self.context):
4546 type_row = db_api.model_query(
4547 self.context, models.ShareTypes
4548 ).count()
4549 # share type1 should not be deleted
4550 self.assertEqual(1, type_row)
4551 with db_api.context_manager.writer.using(self.context):
4552 db_api.model_query(self.context, models.ShareInstance).delete()
4553 db_api.share_delete(self.context, share['id'])
4555 db_api.purge_deleted_records(self.context, age_in_days=0)
4556 with db_api.context_manager.reader.using(self.context):
4557 s_row = db_api.model_query(self.context, models.Share).count()
4558 type_row = db_api.model_query(
4559 self.context, models.ShareTypes
4560 ).count()
4561 self.assertEqual(0, s_row + type_row)
4564@ddt.ddt
4565class ShareTypeAPITestCase(test.TestCase):
4567 def setUp(self):
4568 super(ShareTypeAPITestCase, self).setUp()
4569 self.ctxt = context.RequestContext(
4570 user_id='user_id', project_id='project_id', is_admin=True)
4572 @ddt.data({'used_by_shares': True, 'used_by_group_types': False},
4573 {'used_by_shares': False, 'used_by_group_types': True},
4574 {'used_by_shares': True, 'used_by_group_types': True})
4575 @ddt.unpack
4576 def test_share_type_destroy_in_use(self, used_by_shares,
4577 used_by_group_types):
4578 share_type_1 = db_utils.create_share_type(
4579 name='orange', extra_specs={'somekey': 'someval'},
4580 is_public=False, override_defaults=True)
4581 share_type_2 = db_utils.create_share_type(
4582 name='regalia', override_defaults=True)
4583 db_api.share_type_access_add(self.ctxt,
4584 share_type_1['id'],
4585 "2018ndaetfigovnsaslcahfavmrpions")
4586 db_api.share_type_access_add(self.ctxt,
4587 share_type_1['id'],
4588 "2016ndaetfigovnsaslcahfavmrpions")
4589 if used_by_shares:
4590 share_1 = db_utils.create_share(share_type_id=share_type_1['id'])
4591 db_utils.create_share(share_type_id=share_type_2['id'])
4592 if used_by_group_types:
4593 group_type_1 = db_utils.create_share_group_type(
4594 name='crimson', share_types=[share_type_1['id']])
4595 db_utils.create_share_group_type(
4596 name='tide', share_types=[share_type_2['id']])
4597 share_group_1 = db_utils.create_share_group(
4598 share_group_type_id=group_type_1['id'],
4599 share_types=[share_type_1['id']])
4601 self.assertRaises(exception.ShareTypeInUse,
4602 db_api.share_type_destroy,
4603 self.ctxt, share_type_1['id'])
4604 self.assertRaises(exception.ShareTypeInUse,
4605 db_api.share_type_destroy,
4606 self.ctxt, share_type_2['id'])
4608 # Let's cleanup share_type_1 and verify it is gone
4609 if used_by_shares:
4610 db_api.share_instance_delete(self.ctxt, share_1.instance.id)
4611 if used_by_group_types:
4612 db_api.share_group_destroy(self.ctxt, share_group_1['id'])
4613 db_api.share_group_type_destroy(self.ctxt,
4614 group_type_1['id'])
4616 self.assertIsNone(
4617 db_api.share_type_destroy(self.ctxt, share_type_1['id']))
4618 self.assertDictEqual(
4619 {}, db_api.share_type_extra_specs_get(
4620 self.ctxt, share_type_1['id']))
4621 self.assertRaises(exception.ShareTypeNotFound,
4622 db_api.share_type_access_get_all,
4623 self.ctxt, share_type_1['id'])
4624 self.assertRaises(exception.ShareTypeNotFound,
4625 db_api.share_type_get,
4626 self.ctxt, share_type_1['id'])
4628 # share_type_2 must still be around
4629 self.assertEqual(
4630 share_type_2['id'],
4631 db_api.share_type_get(self.ctxt, share_type_2['id'])['id'])
4633 @ddt.data({'usages': False, 'reservations': False},
4634 {'usages': False, 'reservations': True},
4635 {'usages': True, 'reservations': False})
4636 @ddt.unpack
4637 def test_share_type_destroy_quotas_and_reservations(self, usages,
4638 reservations):
4639 share_type = db_utils.create_share_type(name='clemsontigers')
4640 shares_quota = db_api.quota_create(
4641 self.ctxt, "fake-project-id", 'shares', 10,
4642 share_type_id=share_type['id'])
4643 snapshots_quota = db_api.quota_create(
4644 self.ctxt, "fake-project-id", 'snapshots', 30,
4645 share_type_id=share_type['id'])
4647 if reservations:
4648 resources = {
4649 'shares': quota.ReservableResource('shares', '_sync_shares'),
4650 'snapshots': quota.ReservableResource(
4651 'snapshots', '_sync_snapshots'),
4652 }
4653 project_quotas = {
4654 'shares': shares_quota.hard_limit,
4655 'snapshots': snapshots_quota.hard_limit,
4656 }
4657 user_quotas = {
4658 'shares': shares_quota.hard_limit,
4659 'snapshots': snapshots_quota.hard_limit,
4660 }
4661 deltas = {'shares': 1, 'snapshots': 3}
4662 expire = timeutils.utcnow() + datetime.timedelta(seconds=86400)
4663 reservation_uuids = db_api.quota_reserve(
4664 self.ctxt, resources, project_quotas, user_quotas,
4665 project_quotas, deltas, expire, False, 30,
4666 project_id='fake-project-id', share_type_id=share_type['id'])
4668 with db_api.context_manager.reader.using(self.ctxt):
4669 q_reservations = db_api._quota_reservations_query(
4670 self.ctxt, reservation_uuids,
4671 ).all()
4672 # There should be 2 "user" reservations and 2 "share-type"
4673 # quota reservations
4674 self.assertEqual(4, len(q_reservations))
4675 q_share_type_reservations = [qr for qr in q_reservations
4676 if qr['share_type_id'] is not None]
4677 # There should be exactly two "share type" quota reservations
4678 self.assertEqual(2, len(q_share_type_reservations))
4679 for q_reservation in q_share_type_reservations:
4680 self.assertEqual(q_reservation['share_type_id'],
4681 share_type['id'])
4683 if usages:
4684 db_api.quota_usage_create(self.ctxt, 'fake-project-id',
4685 'fake-user-id', 'shares', 3, 2, False,
4686 share_type_id=share_type['id'])
4687 db_api.quota_usage_create(self.ctxt, 'fake-project-id',
4688 'fake-user-id', 'snapshots', 2, 2, False,
4689 share_type_id=share_type['id'])
4690 q_usages = db_api.quota_usage_get_all_by_project_and_share_type(
4691 self.ctxt, 'fake-project-id', share_type['id'])
4692 self.assertEqual(3, q_usages['shares']['in_use'])
4693 self.assertEqual(2, q_usages['shares']['reserved'])
4694 self.assertEqual(2, q_usages['snapshots']['in_use'])
4695 self.assertEqual(2, q_usages['snapshots']['reserved'])
4697 # Validate that quotas exist
4698 share_type_quotas = db_api.quota_get_all_by_project_and_share_type(
4699 self.ctxt, 'fake-project-id', share_type['id'])
4700 expected_quotas = {
4701 'project_id': 'fake-project-id',
4702 'share_type_id': share_type['id'],
4703 'shares': 10,
4704 'snapshots': 30,
4705 }
4706 self.assertDictEqual(expected_quotas, share_type_quotas)
4708 db_api.share_type_destroy(self.ctxt, share_type['id'])
4710 self.assertRaises(exception.ShareTypeNotFound,
4711 db_api.share_type_get,
4712 self.ctxt, share_type['id'])
4713 # Quotas must be gone
4714 share_type_quotas = db_api.quota_get_all_by_project_and_share_type(
4715 self.ctxt, 'fake-project-id', share_type['id'])
4716 self.assertEqual({'project_id': 'fake-project-id',
4717 'share_type_id': share_type['id']},
4718 share_type_quotas)
4720 # Check usages and reservations
4721 if usages:
4722 q_usages = db_api.quota_usage_get_all_by_project_and_share_type(
4723 self.ctxt, 'fake-project-id', share_type['id'])
4724 expected_q_usages = {'project_id': 'fake-project-id',
4725 'share_type_id': share_type['id']}
4726 self.assertDictEqual(expected_q_usages, q_usages)
4727 if reservations:
4728 with db_api.context_manager.reader.using(self.ctxt):
4729 q_reservations = db_api._quota_reservations_query(
4730 self.ctxt, reservation_uuids,
4731 ).all()
4732 # just "user" quota reservations should be left, since we didn't
4733 # clean them up.
4734 self.assertEqual(2, len(q_reservations))
4735 for q_reservation in q_reservations:
4736 self.assertIsNone(q_reservation['share_type_id'])
4738 @ddt.data(
4739 (None, None, 5),
4740 ('fake2', None, 2),
4741 (None, 'fake', 3),
4742 )
4743 @ddt.unpack
4744 def test_share_replica_data_get_for_project(
4745 self, user_id, share_type_id, expected_result):
4746 kwargs = {}
4747 if share_type_id:
4748 kwargs.update({'id': share_type_id})
4749 share_type_1 = db_utils.create_share_type(**kwargs)
4750 share_type_2 = db_utils.create_share_type()
4752 share_1 = db_utils.create_share(size=1, user_id='fake',
4753 share_type_id=share_type_1['id'])
4754 share_2 = db_utils.create_share(size=1, user_id='fake2',
4755 share_type_id=share_type_2['id'])
4756 project_id = share_1['project_id']
4757 db_utils.create_share_replica(
4758 replica_state=constants.REPLICA_STATE_ACTIVE,
4759 share_id=share_1['id'], share_type_id=share_type_1['id'])
4760 db_utils.create_share_replica(
4761 replica_state=constants.REPLICA_STATE_IN_SYNC,
4762 share_id=share_1['id'], share_type_id=share_type_1['id'])
4763 db_utils.create_share_replica(
4764 replica_state=constants.REPLICA_STATE_IN_SYNC,
4765 share_id=share_1['id'], share_type_id=share_type_1['id'])
4767 db_utils.create_share_replica(
4768 replica_state=constants.REPLICA_STATE_ACTIVE,
4769 share_id=share_2['id'], share_type_id=share_type_2['id'])
4770 db_utils.create_share_replica(
4771 replica_state=constants.REPLICA_STATE_IN_SYNC,
4772 share_id=share_2['id'], share_type_id=share_type_2['id'])
4774 kwargs = {}
4775 if user_id:
4776 kwargs.update({'user_id': user_id})
4777 if share_type_id:
4778 kwargs.update({'share_type_id': share_type_id})
4780 with db_api.context_manager.reader.using(self.ctxt):
4781 total_amt, total_size = db_api._share_replica_data_get_for_project(
4782 self.ctxt, project_id, **kwargs,
4783 )
4784 self.assertEqual(expected_result, total_amt)
4785 self.assertEqual(expected_result, total_size)
4787 def test_share_type_get_by_name_or_id_found_by_id(self):
4788 share_type = db_utils.create_share_type()
4790 result = db_api.share_type_get_by_name_or_id(
4791 self.ctxt, share_type['id'])
4793 self.assertIsNotNone(result)
4794 self.assertEqual(share_type['id'], result['id'])
4796 def test_share_type_get_by_name_or_id_found_by_name(self):
4797 name = uuidutils.generate_uuid()
4798 db_utils.create_share_type(name=name)
4800 result = db_api.share_type_get_by_name_or_id(self.ctxt, name)
4802 self.assertIsNotNone(result)
4803 self.assertEqual(name, result['name'])
4804 self.assertNotEqual(name, result['id'])
4806 def test_share_type_get_by_name_or_id_when_does_not_exist(self):
4807 fake_id = uuidutils.generate_uuid()
4809 result = db_api.share_type_get_by_name_or_id(self.ctxt, fake_id)
4811 self.assertIsNone(result)
4813 def test_share_type_get_with_none_id(self):
4814 self.assertRaises(exception.DefaultShareTypeNotConfigured,
4815 db_api.share_type_get, self.ctxt, None)
4817 @ddt.data(
4818 {'name': 'st_1', 'description': 'des_1', 'is_public': True},
4819 {'name': 'st_2', 'description': 'des_2', 'is_public': None},
4820 {'name': 'st_3', 'description': None, 'is_public': False},
4821 {'name': None, 'description': 'des_4', 'is_public': True},
4822 )
4823 @ddt.unpack
4824 def test_share_type_update(self, name, description, is_public):
4825 values = {}
4826 if name:
4827 values.update({'name': name})
4828 if description:
4829 values.update({'description': description})
4830 if is_public is not None:
4831 values.update({'is_public': is_public})
4832 share_type = db_utils.create_share_type(name='st_name')
4833 db_api.share_type_update(self.ctxt, share_type['id'], values)
4834 updated_st = db_api.share_type_get_by_name_or_id(self.ctxt,
4835 share_type['id'])
4836 if name:
4837 self.assertEqual(name, updated_st['name'])
4838 if description:
4839 self.assertEqual(description, updated_st['description'])
4840 if is_public is not None:
4841 self.assertEqual(is_public, updated_st['is_public'])
4843 def test_share_type_update_not_found(self):
4844 share_type = db_utils.create_share_type(name='st_update_test')
4845 db_api.share_type_destroy(self.ctxt, share_type['id'])
4846 values = {"name": "not_exist"}
4847 self.assertRaises(exception.ShareTypeNotFound,
4848 db_api.share_type_update,
4849 self.ctxt, share_type['id'], values)
4852class MessagesDatabaseAPITestCase(test.TestCase):
4854 def setUp(self):
4855 super(MessagesDatabaseAPITestCase, self).setUp()
4856 self.user_id = uuidutils.generate_uuid()
4857 self.project_id = uuidutils.generate_uuid()
4858 self.ctxt = context.RequestContext(
4859 user_id=self.user_id, project_id=self.project_id, is_admin=False)
4861 def test_message_create(self):
4862 result = db_utils.create_message(project_id=self.project_id,
4863 action_id='001')
4865 self.assertIsNotNone(result['id'])
4867 def test_message_delete(self):
4868 result = db_utils.create_message(project_id=self.project_id,
4869 action_id='001')
4871 db_api.message_destroy(self.ctxt, result)
4873 self.assertRaises(exception.NotFound, db_api.message_get,
4874 self.ctxt, result['id'])
4876 def test_message_get(self):
4877 message = db_utils.create_message(project_id=self.project_id,
4878 action_id='001')
4880 result = db_api.message_get(self.ctxt, message['id'])
4882 self.assertEqual(message['id'], result['id'])
4883 self.assertEqual(message['action_id'], result['action_id'])
4884 self.assertEqual(message['detail_id'], result['detail_id'])
4885 self.assertEqual(message['project_id'], result['project_id'])
4886 self.assertEqual(message['message_level'], result['message_level'])
4888 def test_message_get_not_found(self):
4889 self.assertRaises(exception.MessageNotFound, db_api.message_get,
4890 self.ctxt, 'fake_id')
4892 def test_message_get_different_project(self):
4893 message = db_utils.create_message(project_id='another-project',
4894 action_id='001')
4896 self.assertRaises(exception.MessageNotFound, db_api.message_get,
4897 self.ctxt, message['id'])
4899 def test_message_get_all(self):
4900 db_utils.create_message(project_id=self.project_id, action_id='001')
4901 db_utils.create_message(project_id=self.project_id, action_id='001')
4902 db_utils.create_message(project_id='another-project', action_id='001')
4904 result = db_api.message_get_all(self.ctxt)
4906 self.assertEqual(2, len(result))
4908 def test_message_get_all_as_admin(self):
4909 db_utils.create_message(project_id=self.project_id, action_id='001')
4910 db_utils.create_message(project_id=self.project_id, action_id='001')
4911 db_utils.create_message(project_id='another-project', action_id='001')
4913 result = db_api.message_get_all(self.ctxt.elevated())
4915 self.assertEqual(3, len(result))
4917 def test_message_get_all_with_filter(self):
4918 for i in ['001', '002', '002']:
4919 db_utils.create_message(project_id=self.project_id, action_id=i)
4921 result = db_api.message_get_all(self.ctxt,
4922 filters={'action_id': '002'})
4924 self.assertEqual(2, len(result))
4926 def test_message_get_all_with_created_since_or_before_filter(self):
4927 now = timeutils.utcnow()
4928 db_utils.create_message(project_id=self.project_id,
4929 action_id='001',
4930 created_at=now - datetime.timedelta(seconds=1))
4931 db_utils.create_message(project_id=self.project_id,
4932 action_id='001',
4933 created_at=now + datetime.timedelta(seconds=1))
4934 db_utils.create_message(project_id=self.project_id,
4935 action_id='001',
4936 created_at=now + datetime.timedelta(seconds=2))
4937 result1 = db_api.message_get_all(self.ctxt,
4938 filters={'created_before': now})
4939 result2 = db_api.message_get_all(self.ctxt,
4940 filters={'created_since': now})
4941 self.assertEqual(1, len(result1))
4942 self.assertEqual(2, len(result2))
4944 def test_message_get_all_with_invalid_sort_key(self):
4945 self.assertRaises(exception.InvalidInput, db_api.message_get_all,
4946 self.ctxt, sort_key='invalid_key')
4948 def test_message_get_all_sorted_asc(self):
4949 ids = []
4950 for i in ['001', '002', '003']:
4951 msg = db_utils.create_message(project_id=self.project_id,
4952 action_id=i)
4953 ids.append(msg.id)
4955 result = db_api.message_get_all(self.ctxt,
4956 sort_key='action_id',
4957 sort_dir='asc')
4958 result_ids = [r.id for r in result]
4959 self.assertEqual(result_ids, ids)
4961 def test_message_get_all_with_limit_and_offset(self):
4962 for i in ['001', '002']:
4963 db_utils.create_message(project_id=self.project_id,
4964 action_id=i)
4966 result = db_api.message_get_all(self.ctxt, limit=1, offset=1)
4967 self.assertEqual(1, len(result))
4969 def test_message_get_all_sorted(self):
4970 ids = []
4971 for i in ['003', '002', '001']:
4972 msg = db_utils.create_message(project_id=self.project_id,
4973 action_id=i)
4974 ids.append(msg.id)
4976 # Default the sort direction to descending
4977 result = db_api.message_get_all(self.ctxt, sort_key='action_id')
4978 result_ids = [r.id for r in result]
4979 self.assertEqual(result_ids, ids)
4981 def test_cleanup_expired_messages(self):
4982 adm_context = self.ctxt.elevated()
4984 now = timeutils.utcnow()
4985 db_utils.create_message(project_id=self.project_id,
4986 action_id='001',
4987 expires_at=now)
4988 db_utils.create_message(project_id=self.project_id,
4989 action_id='001',
4990 expires_at=now - datetime.timedelta(days=1))
4991 db_utils.create_message(project_id=self.project_id,
4992 action_id='001',
4993 expires_at=now + datetime.timedelta(days=1))
4995 with mock.patch.object(timeutils, 'utcnow') as mock_time_now:
4996 mock_time_now.return_value = now
4997 db_api.cleanup_expired_messages(adm_context)
4998 messages = db_api.message_get_all(adm_context)
4999 self.assertEqual(2, len(messages))
5002class BackendInfoDatabaseAPITestCase(test.TestCase):
5004 def setUp(self):
5005 """Run before each test."""
5006 super(BackendInfoDatabaseAPITestCase, self).setUp()
5007 self.ctxt = context.get_admin_context()
5009 def test_create(self):
5010 host = "fake_host"
5011 value = "fake_hash_value"
5013 initial_data = db_api.backend_info_get(self.ctxt, host)
5014 db_api.backend_info_update(self.ctxt, host, value)
5015 actual_data = db_api.backend_info_get(self.ctxt, host)
5017 self.assertIsNone(initial_data)
5018 self.assertEqual(value, actual_data['info_hash'])
5019 self.assertEqual(host, actual_data['host'])
5021 def test_get(self):
5022 host = "fake_host"
5023 value = "fake_hash_value"
5025 db_api.backend_info_update(self.ctxt, host, value, False)
5026 actual_result = db_api.backend_info_get(self.ctxt, host)
5028 self.assertEqual(value, actual_result['info_hash'])
5029 self.assertEqual(host, actual_result['host'])
5031 def test_delete(self):
5032 host = "fake_host"
5033 value = "fake_hash_value"
5035 db_api.backend_info_update(self.ctxt, host, value)
5036 initial_data = db_api.backend_info_get(self.ctxt, host)
5038 db_api.backend_info_update(self.ctxt, host, delete_existing=True)
5039 actual_data = db_api.backend_info_get(self.ctxt, host)
5041 self.assertEqual(value, initial_data['info_hash'])
5042 self.assertEqual(host, initial_data['host'])
5043 self.assertIsNone(actual_data)
5045 def test_double_update(self):
5046 host = "fake_host"
5047 value_1 = "fake_hash_value_1"
5048 value_2 = "fake_hash_value_2"
5050 initial_data = db_api.backend_info_get(self.ctxt, host)
5051 db_api.backend_info_update(self.ctxt, host, value_1)
5052 db_api.backend_info_update(self.ctxt, host, value_2)
5053 actual_data = db_api.backend_info_get(self.ctxt, host)
5055 self.assertIsNone(initial_data)
5056 self.assertEqual(value_2, actual_data['info_hash'])
5057 self.assertEqual(host, actual_data['host'])
5060@ddt.ddt
5061class ShareResourcesAPITestCase(test.TestCase):
5063 def setUp(self):
5064 super(ShareResourcesAPITestCase, self).setUp()
5065 self.context = context.get_admin_context()
5067 @ddt.data('controller-100', 'controller-0@otherstore03',
5068 'controller-0@otherstore01#pool200')
5069 def test_share_resources_host_update_no_matches(self, current_host):
5070 share_id = uuidutils.generate_uuid()
5071 share_network_id = uuidutils.generate_uuid()
5072 share_network_subnet_id = uuidutils.generate_uuid()
5073 share_net_subnets = [db_utils.create_share_network_subnet(
5074 id=share_network_subnet_id,
5075 share_network_id=share_network_id)]
5076 if '@' in current_host:
5077 if '#' in current_host:
5078 new_host = 'new-controller-X@backendX#poolX'
5079 else:
5080 new_host = 'new-controller-X@backendX'
5081 else:
5082 new_host = 'new-controller-X'
5083 resources = [ # noqa
5084 # share
5085 db_utils.create_share_without_instance(
5086 id=share_id,
5087 status=constants.STATUS_AVAILABLE),
5088 # share instances
5089 db_utils.create_share_instance(
5090 share_id=share_id,
5091 host='controller-0@fancystore01#pool100',
5092 status=constants.STATUS_AVAILABLE),
5093 db_utils.create_share_instance(
5094 share_id=share_id,
5095 host='controller-0@otherstore02#pool100',
5096 status=constants.STATUS_ERROR),
5097 db_utils.create_share_instance(
5098 share_id=share_id,
5099 host='controller-2@beststore07#pool200',
5100 status=constants.STATUS_DELETING),
5101 # share groups
5102 db_utils.create_share_group(
5103 share_network_id=share_network_id,
5104 host='controller-0@fancystore01#pool200',
5105 status=constants.STATUS_AVAILABLE),
5106 db_utils.create_share_group(
5107 share_network_id=share_network_id,
5108 host='controller-0@otherstore02#pool100',
5109 status=constants.STATUS_ERROR),
5110 db_utils.create_share_group(
5111 share_network_id=share_network_id,
5112 host='controller-2@beststore07#pool100',
5113 status=constants.STATUS_DELETING),
5114 # share servers
5115 db_utils.create_share_server(
5116 share_network_subnets=share_net_subnets,
5117 host='controller-0@fancystore01',
5118 status=constants.STATUS_ACTIVE),
5119 db_utils.create_share_server(
5120 share_network_subnets=share_net_subnets,
5121 host='controller-0@otherstore02#pool100',
5122 status=constants.STATUS_ERROR),
5123 db_utils.create_share_server(
5124 share_network_subnets=share_net_subnets,
5125 host='controller-2@beststore07',
5126 status=constants.STATUS_DELETING),
5128 ]
5130 updates = db_api.share_resources_host_update(self.context,
5131 current_host,
5132 new_host)
5134 expected_updates = {'instances': 0, 'servers': 0, 'groups': 0}
5135 self.assertDictEqual(expected_updates, updates)
5136 # validate that resources are unmodified:
5137 share_instances = db_api.share_instance_get_all(
5138 self.context, filters={'share_id': share_id})
5139 share_groups = db_api.share_group_get_all(
5140 self.context, filters={'share_network_id': share_network_id})
5141 with db_api.context_manager.reader.using(self.context):
5142 share_servers = db_api._share_server_get_query(
5143 self.context
5144 ).filter(
5145 models.ShareServer.share_network_subnets.any(
5146 id=share_net_subnets[0]['id']
5147 )
5148 ).all()
5149 self.assertEqual(3, len(share_instances))
5150 self.assertEqual(3, len(share_groups))
5151 self.assertEqual(3, len(share_servers))
5152 for share_instance in share_instances:
5153 self.assertTrue(not share_instance['host'].startswith(new_host))
5154 for share_group in share_groups:
5155 self.assertTrue(not share_group['host'].startswith(new_host))
5156 for share_server in share_servers:
5157 self.assertTrue(not share_server['host'].startswith(new_host))
5159 @ddt.data(
5160 {'current_host': 'controller-2',
5161 'expected_updates': {'instances': 1, 'servers': 2, 'groups': 1}},
5162 {'current_host': 'controller-0@fancystore01',
5163 'expected_updates': {'instances': 2, 'servers': 1, 'groups': 2}},
5164 {'current_host': 'controller-0@fancystore01#pool100',
5165 'expected_updates': {'instances': 1, 'servers': 1, 'groups': 0}})
5166 @ddt.unpack
5167 def test_share_resources_host_update_partial_matches(self, current_host,
5168 expected_updates):
5169 share_id = uuidutils.generate_uuid()
5170 share_network_id = uuidutils.generate_uuid()
5171 share_network_subnet_id = uuidutils.generate_uuid()
5172 share_net_subnets = [db_utils.create_share_network_subnet(
5173 id=share_network_subnet_id,
5174 share_network_id=share_network_id)]
5175 if '@' in current_host:
5176 if '#' in current_host:
5177 new_host = 'new-controller-X@backendX#poolX'
5178 else:
5179 new_host = 'new-controller-X@backendX'
5180 else:
5181 new_host = 'new-controller-X'
5182 total_updates_expected = (expected_updates['instances']
5183 + expected_updates['groups']
5184 + expected_updates['servers'])
5185 resources = [ # noqa
5186 # share
5187 db_utils.create_share_without_instance(
5188 id=share_id,
5189 status=constants.STATUS_AVAILABLE),
5190 # share instances
5191 db_utils.create_share_instance(
5192 share_id=share_id,
5193 host='controller-0@fancystore01#pool100',
5194 status=constants.STATUS_AVAILABLE),
5195 db_utils.create_share_instance(
5196 share_id=share_id,
5197 host='controller-0@fancystore01#pool200',
5198 status=constants.STATUS_ERROR),
5199 db_utils.create_share_instance(
5200 share_id=share_id,
5201 host='controller-2@beststore07#pool200',
5202 status=constants.STATUS_DELETING),
5203 # share groups
5204 db_utils.create_share_group(
5205 share_network_id=share_network_id,
5206 host='controller-0@fancystore01#pool101',
5207 status=constants.STATUS_ACTIVE),
5208 db_utils.create_share_group(
5209 share_network_id=share_network_id,
5210 host='controller-0@fancystore01#pool101',
5211 status=constants.STATUS_ERROR),
5212 db_utils.create_share_group(
5213 share_network_id=share_network_id,
5214 host='controller-2@beststore07#pool200',
5215 status=constants.STATUS_DELETING),
5216 # share servers
5217 db_utils.create_share_server(
5218 share_network_subnets=share_net_subnets,
5219 host='controller-0@fancystore01#pool100',
5220 status=constants.STATUS_ACTIVE),
5221 db_utils.create_share_server(
5222 share_network_subnets=share_net_subnets,
5223 host='controller-2@fancystore01',
5224 status=constants.STATUS_ERROR),
5225 db_utils.create_share_server(
5226 share_network_subnets=share_net_subnets,
5227 host='controller-2@beststore07#pool200',
5228 status=constants.STATUS_DELETING),
5229 ]
5231 actual_updates = db_api.share_resources_host_update(
5232 self.context, current_host, new_host)
5234 share_instances = db_api.share_instance_get_all(
5235 self.context, filters={'share_id': share_id})
5236 share_groups = db_api.share_group_get_all(
5237 self.context, filters={'share_network_id': share_network_id})
5238 with db_api.context_manager.reader.using(self.context):
5239 share_servers = db_api._share_server_get_query(
5240 self.context
5241 ).filter(
5242 models.ShareServer.share_network_subnets.any(
5243 id=share_net_subnets[0]['id']
5244 )
5245 ).all()
5247 updated_resources = [
5248 res for res in share_instances + share_groups + share_servers
5249 if res['host'].startswith(new_host)
5250 ]
5251 self.assertEqual(expected_updates, actual_updates)
5252 self.assertEqual(total_updates_expected, len(updated_resources))
5254 def test_share_instance_status_update(self):
5255 for i in range(1, 3):
5256 instances = [
5257 db_utils.create_share_instance(
5258 status=constants.STATUS_SERVER_MIGRATING, share_id='fake')
5259 for __ in range(1, 3)]
5260 share_instance_ids = [instance['id'] for instance in instances]
5261 values = {'status': constants.STATUS_AVAILABLE}
5263 db_api.share_instance_status_update(
5264 self.context, share_instance_ids, values)
5266 instances = [
5267 db_api.share_instance_get(self.context, instance_id)
5268 for instance_id in share_instance_ids]
5270 for instance in instances:
5271 self.assertEqual(constants.STATUS_AVAILABLE, instance['status'])
5273 def test_share_snapshot_instances_status_update(self):
5274 share_instance = db_utils.create_share_instance(
5275 status=constants.STATUS_AVAILABLE, share_id='fake')
5276 instances = [
5277 db_utils.create_snapshot_instance(
5278 'fake_snapshot_id_1', status=constants.STATUS_CREATING,
5279 share_instance_id=share_instance['id'])
5280 for __ in range(1, 3)]
5282 snapshot_instance_ids = [instance['id'] for instance in instances]
5283 values = {'status': constants.STATUS_AVAILABLE}
5285 db_api.share_snapshot_instances_status_update(
5286 self.context, snapshot_instance_ids, values)
5288 instances = [
5289 db_api.share_snapshot_instance_get(self.context, instance_id)
5290 for instance_id in snapshot_instance_ids]
5292 for instance in instances:
5293 self.assertEqual(constants.STATUS_AVAILABLE, instance['status'])
5295 def test_share_and_snapshot_instances_status_update(self):
5296 share_instance = db_utils.create_share_instance(
5297 status=constants.STATUS_AVAILABLE, share_id='fake')
5298 share_instance_ids = [share_instance['id']]
5299 snap_instances = [
5300 db_utils.create_snapshot_instance(
5301 'fake_snapshot_id_1', status=constants.STATUS_CREATING,
5302 share_instance_id=share_instance['id'])
5303 for __ in range(1, 3)]
5305 snapshot_instance_ids = [instance['id'] for instance in snap_instances]
5306 values = {'status': constants.STATUS_AVAILABLE}
5308 mock_update_share_instances = self.mock_object(
5309 db_api, '_share_instance_status_update',
5310 mock.Mock(return_value=[share_instance]))
5311 mock_update_snap_instances = self.mock_object(
5312 db_api, '_share_snapshot_instances_status_update',
5313 mock.Mock(return_value=snap_instances))
5315 updated_share_instances, updated_snap_instances = (
5316 db_api.share_and_snapshot_instances_status_update(
5317 self.context, values, share_instance_ids=share_instance_ids,
5318 snapshot_instance_ids=snapshot_instance_ids))
5320 mock_update_share_instances.assert_called_once_with(
5321 self.context, share_instance_ids, values)
5322 mock_update_snap_instances.assert_called_once_with(
5323 self.context, snapshot_instance_ids, values)
5324 self.assertEqual(updated_share_instances, [share_instance])
5325 self.assertEqual(updated_snap_instances, snap_instances)
5327 @ddt.data(
5328 {
5329 'share_instance_status': constants.STATUS_ERROR,
5330 'snap_instance_status': constants.STATUS_AVAILABLE,
5331 'expected_exc': exception.InvalidShareInstance
5332 },
5333 {
5334 'share_instance_status': constants.STATUS_AVAILABLE,
5335 'snap_instance_status': constants.STATUS_ERROR,
5336 'expected_exc': exception.InvalidShareSnapshotInstance
5337 }
5338 )
5339 @ddt.unpack
5340 def test_share_and_snapshot_instances_status_update_invalid_status(
5341 self, share_instance_status, snap_instance_status, expected_exc):
5342 share_instance = db_utils.create_share_instance(
5343 status=share_instance_status, share_id='fake')
5344 share_snapshot_instance = db_utils.create_snapshot_instance(
5345 'fake_snapshot_id_1', status=snap_instance_status,
5346 share_instance_id=share_instance['id'])
5347 share_instance_ids = [share_instance['id']]
5348 snap_instance_ids = [share_snapshot_instance['id']]
5349 values = {'status': constants.STATUS_AVAILABLE}
5351 mock_instances_get_all = self.mock_object(
5352 db_api, '_share_instance_get_all',
5353 mock.Mock(return_value=[share_instance]))
5354 mock_snap_instances_get_all = self.mock_object(
5355 db_api, '_share_snapshot_instance_get_all_with_filters',
5356 mock.Mock(return_value=[share_snapshot_instance]))
5358 self.assertRaises(expected_exc,
5359 db_api.share_and_snapshot_instances_status_update,
5360 self.context,
5361 values,
5362 share_instance_ids=share_instance_ids,
5363 snapshot_instance_ids=snap_instance_ids,
5364 current_expected_status=constants.STATUS_AVAILABLE)
5366 mock_instances_get_all.assert_called_once_with(
5367 self.context, filters={'instance_ids': share_instance_ids},
5368 )
5369 if snap_instance_status == constants.STATUS_ERROR:
5370 mock_snap_instances_get_all.assert_called_once_with(
5371 self.context, {'instance_ids': snap_instance_ids},
5372 )
5375@ddt.ddt
5376class AsyncOperationDatabaseAPITestCase(test.TestCase):
5378 def setUp(self):
5379 """Run before each test."""
5380 super(AsyncOperationDatabaseAPITestCase, self).setUp()
5381 self.user_id = uuidutils.generate_uuid()
5382 self.project_id = uuidutils.generate_uuid()
5383 self.ctxt = context.RequestContext(
5384 user_id=self.user_id, project_id=self.project_id, is_admin=False)
5386 def _get_async_operation_test_data(self):
5387 return uuidutils.generate_uuid()
5389 @ddt.data({"details": {"foo": "bar", "tee": "too"},
5390 "valid": {"foo": "bar", "tee": "too"}},
5391 {"details": {"foo": "bar", "tee": ["test"]},
5392 "valid": {"foo": "bar", "tee": str(["test"])}})
5393 @ddt.unpack
5394 def test_update(self, details, valid):
5395 entity_id = self._get_async_operation_test_data()
5397 initial_data = db_api.async_operation_data_get(self.ctxt, entity_id)
5398 db_api.async_operation_data_update(self.ctxt, entity_id, details)
5399 actual_data = db_api.async_operation_data_get(self.ctxt, entity_id)
5401 self.assertEqual({}, initial_data)
5402 self.assertEqual(valid, actual_data)
5404 @ddt.data({'with_deleted': True, 'append': False},
5405 {'with_deleted': True, 'append': True},
5406 {'with_deleted': False, 'append': False},
5407 {'with_deleted': False, 'append': True})
5408 @ddt.unpack
5409 def test_update_with_more_values(self, with_deleted, append):
5410 entity_id = self._get_async_operation_test_data()
5411 details = {"tee": "too"}
5412 more_details = {"foo": "bar"}
5413 result = {"tee": "too", "foo": "bar"}
5415 db_api.async_operation_data_update(self.ctxt, entity_id, details)
5416 if with_deleted:
5417 db_api.async_operation_data_delete(self.ctxt, entity_id)
5418 if append:
5419 more_details.update(details)
5420 if with_deleted and not append:
5421 result.pop("tee")
5422 db_api.async_operation_data_update(self.ctxt, entity_id, more_details)
5424 actual_result = db_api.async_operation_data_get(self.ctxt, entity_id)
5426 self.assertEqual(result, actual_result)
5428 @ddt.data(True, False)
5429 def test_update_with_duplicate(self, with_deleted):
5430 entity_id = self._get_async_operation_test_data()
5431 details = {"tee": "too"}
5433 db_api.async_operation_data_update(self.ctxt, entity_id, details)
5434 if with_deleted:
5435 db_api.async_operation_data_delete(self.ctxt, entity_id)
5436 db_api.async_operation_data_update(self.ctxt, entity_id, details)
5438 actual_result = db_api.async_operation_data_get(self.ctxt,
5439 entity_id)
5441 self.assertEqual(details, actual_result)
5443 def test_update_with_delete_existing(self):
5444 resource_id = self._get_async_operation_test_data()
5445 details = {"key1": "val1", "key2": "val2", "key3": "val3"}
5446 details_update = {"key1": "val1_upd", "key4": "new_val"}
5448 # Create new details
5449 db_api.async_operation_data_update(self.ctxt, resource_id, details)
5450 db_api.async_operation_data_update(self.ctxt, resource_id,
5451 details_update,
5452 delete_existing=True)
5454 actual_result = db_api.async_operation_data_get(self.ctxt, resource_id)
5456 self.assertEqual(details_update, actual_result)
5458 def test_get(self):
5459 resource_id = self._get_async_operation_test_data()
5460 test_key = "foo"
5461 test_keys = [test_key, "tee"]
5462 details = {test_keys[0]: "val", test_keys[1]: "val", "mee": "foo"}
5463 db_api.async_operation_data_update(self.ctxt, resource_id, details)
5465 actual_result_all = db_api.async_operation_data_get(
5466 self.ctxt, resource_id)
5467 actual_result_single_key = db_api.async_operation_data_get(
5468 self.ctxt, resource_id, test_key)
5469 actual_result_list = db_api.async_operation_data_get(
5470 self.ctxt, resource_id, test_keys)
5472 self.assertEqual(details, actual_result_all)
5473 self.assertEqual(details[test_key], actual_result_single_key)
5474 self.assertEqual(dict.fromkeys(test_keys, "val"), actual_result_list)
5476 def test_delete_single(self):
5477 test_id = self._get_async_operation_test_data()
5478 test_key = "foo"
5479 details = {test_key: "bar", "tee": "too"}
5480 valid_result = {"tee": "too"}
5481 db_api.async_operation_data_update(self.ctxt, test_id, details)
5483 db_api.async_operation_data_delete(self.ctxt, test_id, test_key)
5485 actual_result = db_api.async_operation_data_get(
5486 self.ctxt, test_id)
5488 self.assertEqual(valid_result, actual_result)
5490 def test_delete_all(self):
5491 test_id = self._get_async_operation_test_data()
5492 details = {"foo": "bar", "tee": "too"}
5493 db_api.async_operation_data_update(self.ctxt, test_id, details)
5495 db_api.async_operation_data_delete(self.ctxt, test_id)
5497 actual_result = db_api.async_operation_data_get(
5498 self.ctxt, test_id)
5500 self.assertEqual({}, actual_result)
5503class TransfersTestCase(test.TestCase):
5504 """Test case for transfers."""
5506 def setUp(self):
5507 super(TransfersTestCase, self).setUp()
5508 self.user_id = uuidutils.generate_uuid()
5509 self.project_id = uuidutils.generate_uuid()
5510 self.ctxt = context.RequestContext(user_id=self.user_id,
5511 project_id=self.project_id)
5513 @staticmethod
5514 def _create_transfer(resource_type='share',
5515 resource_id=None, source_project_id=None):
5516 """Create a transfer object."""
5517 if resource_id and source_project_id:
5518 transfer = db_utils.create_transfer(
5519 resource_type=resource_type,
5520 resource_id=resource_id,
5521 source_project_id=source_project_id)
5522 elif resource_id:
5523 transfer = db_utils.create_transfer(
5524 resource_type=resource_type,
5525 resource_id=resource_id)
5526 elif source_project_id: 5526 ↛ 5527line 5526 didn't jump to line 5527 because the condition on line 5526 was never true
5527 transfer = db_utils.create_transfer(
5528 resource_type=resource_type,
5529 source_project_id=source_project_id)
5530 else:
5531 transfer = db_utils.create_transfer(
5532 resource_type=resource_type)
5533 return transfer['id']
5535 def test_transfer_create(self):
5536 # If the resource_id is Null a KeyError exception will be raised.
5537 self.assertRaises(KeyError, self._create_transfer)
5539 share = db_utils.create_share(size=1, user_id=self.user_id,
5540 project_id=self.project_id)
5541 share_id = share['id']
5542 self._create_transfer(resource_id=share_id)
5544 def test_transfer_get(self):
5545 share_id = db_utils.create_share(size=1, user_id=self.user_id,
5546 project_id=self.project_id)['id']
5547 transfer_id = self._create_transfer(resource_id=share_id)
5549 transfer = db_api.transfer_get(self.ctxt, transfer_id)
5550 self.assertEqual(share_id, transfer['resource_id'])
5552 new_ctxt = context.RequestContext(user_id='new_user_id',
5553 project_id='new_project_id')
5554 self.assertRaises(exception.TransferNotFound,
5555 db_api.transfer_get, new_ctxt, transfer_id)
5557 transfer = db_api.transfer_get(new_ctxt.elevated(), transfer_id)
5558 self.assertEqual(share_id, transfer['resource_id'])
5560 def test_transfer_get_all(self):
5561 share_id1 = db_utils.create_share(size=1, user_id=self.user_id,
5562 project_id=self.project_id)['id']
5563 share_id2 = db_utils.create_share(size=1, user_id=self.user_id,
5564 project_id=self.project_id)['id']
5565 self._create_transfer(resource_id=share_id1,
5566 source_project_id=self.project_id)
5567 self._create_transfer(resource_id=share_id2,
5568 source_project_id=self.project_id)
5570 self.assertRaises(exception.NotAuthorized,
5571 db_api.transfer_get_all,
5572 self.ctxt)
5573 transfers = db_api.transfer_get_all(context.get_admin_context())
5574 self.assertEqual(2, len(transfers))
5576 transfers = db_api.transfer_get_all_by_project(self.ctxt,
5577 self.project_id)
5578 self.assertEqual(2, len(transfers))
5580 new_ctxt = context.RequestContext(user_id='new_user_id',
5581 project_id='new_project_id')
5582 transfers = db_api.transfer_get_all_by_project(new_ctxt,
5583 'new_project_id')
5584 self.assertEqual(0, len(transfers))
5586 def test_transfer_destroy(self):
5587 share_id1 = db_utils.create_share(size=1, user_id=self.user_id,
5588 project_id=self.project_id)['id']
5589 share_id2 = db_utils.create_share(size=1, user_id=self.user_id,
5590 project_id=self.project_id)['id']
5591 transfer_id1 = self._create_transfer(resource_id=share_id1,
5592 source_project_id=self.project_id)
5593 transfer_id2 = self._create_transfer(resource_id=share_id2,
5594 source_project_id=self.project_id)
5596 transfers = db_api.transfer_get_all(context.get_admin_context())
5597 self.assertEqual(2, len(transfers))
5599 db_api.transfer_destroy(self.ctxt, transfer_id1)
5600 transfers = db_api.transfer_get_all(context.get_admin_context())
5601 self.assertEqual(1, len(transfers))
5603 db_api.transfer_destroy(self.ctxt, transfer_id2)
5604 transfers = db_api.transfer_get_all(context.get_admin_context())
5605 self.assertEqual(0, len(transfers))
5607 def test_transfer_accept_then_rollback(self):
5608 share = db_utils.create_share(size=1, user_id=self.user_id,
5609 project_id=self.project_id)
5610 transfer_id = self._create_transfer(resource_id=share['id'],
5611 source_project_id=self.project_id)
5612 new_ctxt = context.RequestContext(user_id='new_user_id',
5613 project_id='new_project_id')
5615 transfer = db_api.transfer_get(new_ctxt.elevated(), transfer_id)
5616 self.assertEqual(share['project_id'], transfer['source_project_id'])
5617 self.assertFalse(transfer['accepted'])
5618 self.assertIsNone(transfer['destination_project_id'])
5619 # accept the transfer
5620 db_api.transfer_accept(new_ctxt.elevated(), transfer_id,
5621 'new_user_id', 'new_project_id')
5623 admin_context = new_ctxt.elevated()
5624 with db_api.context_manager.reader.using(admin_context):
5625 transfer = db_api.model_query(
5626 admin_context, models.Transfer, read_deleted='yes',
5627 ).filter_by(id=transfer_id).first()
5628 share = db_api.share_get(new_ctxt.elevated(), share['id'])
5630 self.assertEqual(share['project_id'], 'new_project_id')
5631 self.assertEqual(share['user_id'], 'new_user_id')
5632 self.assertTrue(transfer['accepted'])
5633 self.assertEqual('new_project_id', transfer['destination_project_id'])
5635 # then test rollback the transfer
5636 db_api.transfer_accept_rollback(new_ctxt.elevated(), transfer_id,
5637 self.user_id, self.project_id)
5638 with db_api.context_manager.reader.using(admin_context):
5639 transfer = db_api.model_query(
5640 admin_context, models.Transfer,
5641 ).filter_by(id=transfer_id).first()
5642 share = db_api.share_get(new_ctxt.elevated(), share['id'])
5644 self.assertEqual(share['project_id'], self.project_id)
5645 self.assertEqual(share['user_id'], self.user_id)
5646 self.assertFalse(transfer['accepted'])
5649class ShareBackupDatabaseAPITestCase(BaseDatabaseAPITestCase):
5651 def setUp(self):
5652 """Run before each test."""
5653 super(ShareBackupDatabaseAPITestCase, self).setUp()
5654 self.ctxt = context.get_admin_context()
5655 self.backup = {
5656 'id': 'fake_backup_id',
5657 'host': "fake_host",
5658 'user_id': 'fake',
5659 'project_id': 'fake',
5660 'availability_zone': 'fake_availability_zone',
5661 'status': constants.STATUS_CREATING,
5662 'progress': '0',
5663 'display_name': 'fake_name',
5664 'display_description': 'fake_description',
5665 'size': 1,
5666 }
5667 self.share_id = "fake_share_id"
5669 def test_create_share_backup(self):
5670 result = db_api.share_backup_create(
5671 self.ctxt, self.share_id, self.backup)
5672 self._check_fields(expected=self.backup, actual=result)
5674 def test_get(self):
5675 db_api.share_backup_create(
5676 self.ctxt, self.share_id, self.backup)
5677 result = db_api.share_backup_get(
5678 self.ctxt, self.backup['id'])
5679 self._check_fields(expected=self.backup, actual=result)
5681 def test_delete(self):
5682 db_api.share_backup_create(
5683 self.ctxt, self.share_id, self.backup)
5684 db_api.share_backup_delete(self.ctxt,
5685 self.backup['id'])
5687 self.assertRaises(exception.ShareBackupNotFound,
5688 db_api.share_backup_get,
5689 self.ctxt,
5690 self.backup['id'])
5692 def test_delete_not_found(self):
5693 self.assertRaises(exception.ShareBackupNotFound,
5694 db_api.share_backup_delete,
5695 self.ctxt,
5696 'fake not exist id')
5698 def test_update(self):
5699 new_status = constants.STATUS_ERROR
5700 db_api.share_backup_create(
5701 self.ctxt, self.share_id, self.backup)
5702 result_update = db_api.share_backup_update(
5703 self.ctxt, self.backup['id'],
5704 {'status': constants.STATUS_ERROR})
5705 result_get = db_api.share_backup_get(self.ctxt,
5706 self.backup['id'])
5707 self.assertEqual(new_status, result_update['status'])
5708 self._check_fields(expected=dict(result_update.items()),
5709 actual=dict(result_get.items()))
5711 def test_update_not_found(self):
5712 self.assertRaises(exception.ShareBackupNotFound,
5713 db_api.share_backup_update,
5714 self.ctxt,
5715 'fake id',
5716 {})
5719class ResourceLocksTestCase(test.TestCase):
5720 """Test case for resource locks."""
5722 def setUp(self):
5723 super(ResourceLocksTestCase, self).setUp()
5724 self.user_id = uuidutils.generate_uuid(dashed=False)
5725 self.project_id = uuidutils.generate_uuid(dashed=False)
5726 self.ctxt = context.RequestContext(user_id=self.user_id,
5727 project_id=self.project_id)
5729 def test_resource_lock_create(self):
5730 lock_data = {
5731 'resource_id': uuidutils.generate_uuid(),
5732 'resource_type': 'share',
5733 'resource_action': 'delete',
5734 'lock_context': 'user',
5735 'user_id': self.user_id,
5736 'project_id': self.project_id,
5737 'lock_reason': 'xyzzyspoon!',
5738 }
5739 lock = db_api.resource_lock_create(self.ctxt, lock_data)
5741 self.assertTrue(uuidutils.is_uuid_like(lock['id']))
5742 self.assertEqual(lock_data['user_id'], lock['user_id'])
5743 self.assertEqual(lock_data['project_id'], lock['project_id'])
5744 self.assertIsNone(lock['updated_at'])
5745 self.assertEqual('False', lock['deleted'])
5747 def test_resource_lock_update_invalid(self):
5748 self.assertRaises(exception.ResourceLockNotFound,
5749 db_api.resource_lock_update,
5750 self.ctxt,
5751 'invalid-lock-id',
5752 {'lock_reason': 'yadayada'})
5754 def test_resource_lock_update(self):
5755 lock = db_utils.create_lock(project_id=self.project_id)
5756 updated_lock = db_api.resource_lock_update(
5757 self.ctxt,
5758 lock['id'],
5759 {'lock_reason': 'new reason'},
5760 )
5762 self.assertEqual(lock['id'], updated_lock['id'])
5763 self.assertEqual('new reason', updated_lock['lock_reason'])
5764 self.assertEqual(lock['user_id'], updated_lock['user_id'])
5765 self.assertEqual(lock['project_id'], updated_lock['project_id'])
5767 lock_get = db_api.resource_lock_get(self.ctxt, lock['id'])
5769 self.assertEqual(lock['id'], lock_get['id'])
5770 self.assertEqual('new reason', lock_get['lock_reason'])
5771 self.assertEqual(lock['user_id'], lock_get['user_id'])
5772 self.assertEqual(lock['project_id'], lock_get['project_id'])
5774 def test_resource_lock_delete_invalid(self):
5775 self.assertRaises(exception.ResourceLockNotFound,
5776 db_api.resource_lock_delete,
5777 self.ctxt,
5778 'invalid-lock-id')
5780 def test_resource_lock_delete(self):
5781 lock = db_utils.create_lock(project_id=self.project_id)
5782 lock_get = db_api.resource_lock_get(self.ctxt, lock['id'])
5784 return_value = db_api.resource_lock_delete(self.ctxt, lock['id'])
5786 self.assertIsNone(return_value)
5787 with db_api.context_manager.reader.using(self.ctxt):
5788 self.assertRaises(exception.ResourceLockNotFound,
5789 db_api._resource_lock_get,
5790 self.ctxt,
5791 lock_get['id'])
5793 def test_resource_lock_get_invalid(self):
5794 self.assertRaises(exception.ResourceLockNotFound,
5795 db_api.resource_lock_get,
5796 self.ctxt,
5797 'invalid-lock-id')
5799 def test_resource_lock_get(self):
5800 lock = db_utils.create_lock(project_id=self.project_id)
5802 lock_get = db_api.resource_lock_get(self.ctxt, lock['id'])
5804 self.assertEqual(lock['id'], lock_get['id'])
5805 self.assertEqual('for the tests', lock_get['lock_reason'])
5806 self.assertEqual(lock['user_id'], lock_get['user_id'])
5807 self.assertEqual(lock['project_id'], lock_get['project_id'])
5809 def test_resource_lock_get_all_basic_filters(self):
5810 user_id_2 = uuidutils.generate_uuid(dashed=False)
5811 project_id_2 = uuidutils.generate_uuid(dashed=False)
5813 lk_1 = db_utils.create_lock(lock_reason='austin',
5814 user_id=self.user_id,
5815 project_id=self.project_id)
5816 lk_2 = db_utils.create_lock(lock_reason='bexar',
5817 user_id=self.user_id,
5818 project_id=self.project_id)
5819 lk_3 = db_utils.create_lock(lock_reason='cactus',
5820 user_id=self.user_id,
5821 project_id=self.project_id)
5822 lk_4 = db_utils.create_lock(lock_reason='diablo',
5823 user_id=user_id_2,
5824 project_id=project_id_2)
5825 lk_5 = db_utils.create_lock(lock_reason='essex')
5827 project_locks_limited_offset, count = db_api.resource_lock_get_all(
5828 self.ctxt, limit=2, offset=1, show_count=True)
5829 self.assertEqual(2, len(project_locks_limited_offset))
5830 self.assertEqual(3, count)
5831 order_expected = [lk_2['id'], lk_1['id']]
5832 self.assertEqual(order_expected,
5833 [lock['id'] for lock in project_locks_limited_offset])
5835 all_project_locks, count = db_api.resource_lock_get_all(
5836 self.ctxt, filters={'all_projects': True}, sort_dir='asc')
5837 self.assertEqual(5, len(all_project_locks))
5838 order_expected = [
5839 lk_1['id'], lk_2['id'], lk_3['id'], lk_4['id'], lk_5['id']
5840 ]
5841 self.assertEqual(order_expected,
5842 [lock['id'] for lock in all_project_locks])
5843 self.assertNotIn(lk_5['project_id'], [self.project_id, project_id_2])
5844 self.assertIsNone(count)
5846 filtered_locks, count = db_api.resource_lock_get_all(
5847 self.ctxt, filters={'lock_reason~': 'xar'})
5848 self.assertEqual(1, len(filtered_locks))
5849 self.assertIsNone(count)
5850 self.assertEqual(lk_2['id'], filtered_locks[0]['id'])
5852 def test_resource_locks_get_all_time_filters(self):
5853 now = timeutils.utcnow()
5854 lock_1 = db_utils.create_lock(
5855 lock_reason='folsom',
5856 project_id=self.project_id,
5857 created_at=now - datetime.timedelta(seconds=1),
5858 )
5859 lock_2 = db_utils.create_lock(
5860 lock_reason='grizly',
5861 project_id=self.project_id,
5862 created_at=now + datetime.timedelta(seconds=1),
5863 )
5864 lock_3 = db_utils.create_lock(
5865 lock_reason='havana',
5866 project_id=self.project_id,
5867 created_at=now + datetime.timedelta(seconds=2),
5868 )
5870 filters1 = {'created_before': now}
5871 filters2 = {'created_since': now}
5873 result1, count1 = db_api.resource_lock_get_all(
5874 self.ctxt, filters=filters1)
5875 result2, count2 = db_api.resource_lock_get_all(
5876 self.ctxt, filters=filters2)
5878 self.assertEqual(1, len(result1))
5879 self.assertEqual(lock_1['id'], result1[0]['id'])
5880 self.assertEqual(2, len(result2))
5881 self.assertEqual([lock_3['id'], lock_2['id']],
5882 [lock['id'] for lock in result2])
5883 self.assertIsNone(count1)
5884 self.assertIsNone(count2)
5886 filters1.update(filters2)
5887 result3, count3 = db_api.resource_lock_get_all(
5888 self.ctxt, filters=filters1, show_count=True)
5889 self.assertEqual(0, len(result3))
5890 self.assertEqual(0, count3)