"Fossies" - the Fresh Open Source Software Archive 
Member "manila-8.1.4/manila/tests/share/test_driver.py" (19 Nov 2020, 48930 Bytes) of package /linux/misc/openstack/manila-8.1.4.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style:
standard) with prefixed line numbers.
Alternatively you can here
view or
download the uninterpreted source code file.
See also the latest
Fossies "Diffs" side-by-side code changes report for "test_driver.py":
8.1.3_vs_8.1.4.
1 # Copyright 2012 NetApp
2 # Copyright 2014 Mirantis Inc.
3 # All Rights Reserved.
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License"); you may
6 # not use this file except in compliance with the License. You may obtain
7 # a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 # License for the specific language governing permissions and limitations
15 # under the License.
16 """Unit tests for the Share driver module."""
17
18 import time
19
20 import ddt
21 import mock
22 from mock import PropertyMock
23
24 from manila import exception
25 from manila import network
26 from manila.share import configuration
27 from manila.share import driver
28 from manila import test
29 from manila.tests import utils as test_utils
30 from manila import utils
31
32
33 def fake_execute_with_raise(*cmd, **kwargs):
34 raise exception.ProcessExecutionError
35
36
37 def fake_sleep(duration):
38 pass
39
40
41 class ShareDriverWithExecuteMixin(driver.ShareDriver, driver.ExecuteMixin):
42 pass
43
44
45 @ddt.ddt
46 class ShareDriverTestCase(test.TestCase):
47 _SNAPSHOT_METHOD_NAMES = ["create_snapshot", "delete_snapshot"]
48
49 def setUp(self):
50 super(ShareDriverTestCase, self).setUp()
51 self.utils = utils
52 self.mock_object(self.utils, 'execute', fake_execute_with_raise)
53 self.time = time
54 self.mock_object(self.time, 'sleep', fake_sleep)
55 driver.CONF.set_default('driver_handles_share_servers', True)
56
57 def test__try_execute(self):
58 execute_mixin = ShareDriverWithExecuteMixin(
59 True, configuration=configuration.Configuration(None))
60 self.assertRaises(exception.ProcessExecutionError,
61 execute_mixin._try_execute)
62
63 def test_verify_share_driver_mode_option_type(self):
64 data = {'DEFAULT': {'driver_handles_share_servers': 'True'}}
65 with test_utils.create_temp_config_with_opts(data):
66 share_driver = driver.ShareDriver([True, False])
67 self.assertTrue(share_driver.driver_handles_share_servers)
68
69 def _instantiate_share_driver(self, network_config_group,
70 driver_handles_share_servers,
71 admin_network_config_group=None):
72 self.mock_object(network, 'API')
73 config = mock.Mock()
74 config.append_config_values = mock.Mock()
75 config.config_group = 'fake_config_group'
76 config.network_config_group = network_config_group
77 if admin_network_config_group:
78 config.admin_network_config_group = admin_network_config_group
79 config.safe_get = mock.Mock(return_value=driver_handles_share_servers)
80
81 share_driver = driver.ShareDriver([True, False], configuration=config)
82
83 self.assertTrue(hasattr(share_driver, 'configuration'))
84 config.append_config_values.assert_called_once_with(driver.share_opts)
85 if driver_handles_share_servers:
86 calls = []
87 if network_config_group:
88 calls.append(mock.call(
89 config_group_name=config.network_config_group))
90 else:
91 calls.append(mock.call(
92 config_group_name=config.config_group))
93 if admin_network_config_group:
94 calls.append(mock.call(
95 config_group_name=config.admin_network_config_group,
96 label='admin'))
97 network.API.assert_has_calls(calls)
98 self.assertTrue(hasattr(share_driver, 'network_api'))
99 self.assertTrue(hasattr(share_driver, 'admin_network_api'))
100 self.assertIsNotNone(share_driver.network_api)
101 self.assertIsNotNone(share_driver.admin_network_api)
102 else:
103 self.assertFalse(hasattr(share_driver, 'network_api'))
104 self.assertTrue(hasattr(share_driver, 'admin_network_api'))
105 self.assertIsNone(share_driver.admin_network_api)
106 self.assertFalse(network.API.called)
107 return share_driver
108
109 def test_instantiate_share_driver(self):
110 self._instantiate_share_driver(None, True)
111
112 def test_instantiate_share_driver_another_config_group(self):
113 self._instantiate_share_driver("fake_network_config_group", True)
114
115 def test_instantiate_share_driver_with_admin_network(self):
116 self._instantiate_share_driver(
117 "fake_network_config_group", True,
118 "fake_admin_network_config_group")
119
120 def test_instantiate_share_driver_no_configuration(self):
121 self.mock_object(network, 'API')
122
123 share_driver = driver.ShareDriver(True, configuration=None)
124
125 self.assertIsNone(share_driver.configuration)
126 network.API.assert_called_once_with(config_group_name=None)
127
128 def test_get_share_stats_refresh_false(self):
129 share_driver = driver.ShareDriver(True, configuration=None)
130 share_driver._stats = {'fake_key': 'fake_value'}
131
132 result = share_driver.get_share_stats(False)
133
134 self.assertEqual(share_driver._stats, result)
135
136 def test_get_share_stats_refresh_true(self):
137 conf = configuration.Configuration(None)
138 expected_keys = [
139 'qos', 'driver_version', 'share_backend_name',
140 'free_capacity_gb', 'total_capacity_gb',
141 'driver_handles_share_servers',
142 'reserved_percentage', 'vendor_name', 'storage_protocol',
143 'snapshot_support', 'mount_snapshot_support',
144 ]
145 share_driver = driver.ShareDriver(True, configuration=conf)
146 fake_stats = {'fake_key': 'fake_value'}
147 share_driver._stats = fake_stats
148
149 result = share_driver.get_share_stats(True)
150
151 self.assertNotEqual(fake_stats, result)
152 for key in expected_keys:
153 self.assertIn(key, result)
154 self.assertEqual('Open Source', result['vendor_name'])
155
156 @ddt.data(
157 {'opt': True, 'allowed': True},
158 {'opt': True, 'allowed': (True, False)},
159 {'opt': True, 'allowed': [True, False]},
160 {'opt': True, 'allowed': set([True, False])},
161 {'opt': False, 'allowed': False},
162 {'opt': False, 'allowed': (True, False)},
163 {'opt': False, 'allowed': [True, False]},
164 {'opt': False, 'allowed': set([True, False])})
165 @ddt.unpack
166 def test__verify_share_server_handling_valid_cases(self, opt, allowed):
167 conf = configuration.Configuration(None)
168 self.mock_object(conf, 'safe_get', mock.Mock(return_value=opt))
169 share_driver = driver.ShareDriver(allowed, configuration=conf)
170 self.assertTrue(conf.safe_get.called)
171 self.assertEqual(opt, share_driver.driver_handles_share_servers)
172
173 @ddt.data(
174 {'opt': False, 'allowed': True},
175 {'opt': True, 'allowed': False},
176 {'opt': None, 'allowed': True},
177 {'opt': 'True', 'allowed': True},
178 {'opt': 'False', 'allowed': False},
179 {'opt': [], 'allowed': True},
180 {'opt': True, 'allowed': []},
181 {'opt': True, 'allowed': ['True']},
182 {'opt': False, 'allowed': ['False']})
183 @ddt.unpack
184 def test__verify_share_server_handling_invalid_cases(self, opt, allowed):
185 conf = configuration.Configuration(None)
186 self.mock_object(conf, 'safe_get', mock.Mock(return_value=opt))
187 self.assertRaises(
188 exception.ManilaException,
189 driver.ShareDriver, allowed, configuration=conf)
190 self.assertTrue(conf.safe_get.called)
191
192 def test_setup_server_handling_disabled(self):
193 share_driver = self._instantiate_share_driver(None, False)
194 # We expect successful execution, nothing to assert
195 share_driver.setup_server('Nothing is expected to happen.')
196
197 def test_setup_server_handling_enabled(self):
198 share_driver = self._instantiate_share_driver(None, True)
199 self.assertRaises(
200 NotImplementedError,
201 share_driver.setup_server,
202 'fake_network_info')
203
204 def test_teardown_server_handling_disabled(self):
205 share_driver = self._instantiate_share_driver(None, False)
206 # We expect successful execution, nothing to assert
207 share_driver.teardown_server('Nothing is expected to happen.')
208
209 def test_teardown_server_handling_enabled(self):
210 share_driver = self._instantiate_share_driver(None, True)
211 self.assertRaises(
212 NotImplementedError,
213 share_driver.teardown_server,
214 'fake_share_server_details')
215
216 def _assert_is_callable(self, obj, attr):
217 self.assertTrue(callable(getattr(obj, attr)))
218
219 @ddt.data('manage_existing',
220 'unmanage')
221 def test_drivers_methods_needed_by_manage_functionality(self, method):
222 share_driver = self._instantiate_share_driver(None, False)
223
224 self._assert_is_callable(share_driver, method)
225
226 @ddt.data('manage_existing_snapshot',
227 'unmanage_snapshot')
228 def test_drivers_methods_needed_by_manage_snapshot_functionality(
229 self, method):
230 share_driver = self._instantiate_share_driver(None, False)
231
232 self._assert_is_callable(share_driver, method)
233
234 @ddt.data('revert_to_snapshot',
235 'revert_to_replicated_snapshot')
236 def test_drivers_methods_needed_by_share_revert_to_snapshot_functionality(
237 self, method):
238 share_driver = self._instantiate_share_driver(None, False)
239
240 self._assert_is_callable(share_driver, method)
241
242 @ddt.data(True, False)
243 def test_get_share_server_pools(self, value):
244 driver.CONF.set_default('driver_handles_share_servers', value)
245 share_driver = driver.ShareDriver(value)
246 self.assertEqual([],
247 share_driver.get_share_server_pools('fake_server'))
248
249 @ddt.data(0.8, 1.0, 10.5, 20.0, None, '1', '1.1')
250 def test_check_for_setup_error(self, value):
251 driver.CONF.set_default('driver_handles_share_servers', False)
252 share_driver = driver.ShareDriver(False)
253 share_driver.configuration = configuration.Configuration(None)
254 self.mock_object(share_driver.configuration, 'safe_get',
255 mock.Mock(return_value=value))
256 if value and float(value) >= 1.0:
257 share_driver.check_for_setup_error()
258 else:
259 self.assertRaises(exception.InvalidParameterValue,
260 share_driver.check_for_setup_error)
261
262 def test_snapshot_support_exists(self):
263 driver.CONF.set_default('driver_handles_share_servers', True)
264 fake_method = lambda *args, **kwargs: None
265 child_methods = {
266 "create_snapshot": fake_method,
267 "delete_snapshot": fake_method,
268 }
269 child_class_instance = type(
270 "NotRedefined", (driver.ShareDriver, ), child_methods)(True)
271 self.mock_object(child_class_instance, "configuration")
272
273 child_class_instance._update_share_stats()
274
275 self.assertTrue(child_class_instance._stats["snapshot_support"])
276 self.assertTrue(child_class_instance.configuration.safe_get.called)
277
278 @ddt.data(
279 ([], [], False),
280 (_SNAPSHOT_METHOD_NAMES, [], True),
281 (_SNAPSHOT_METHOD_NAMES, _SNAPSHOT_METHOD_NAMES, True),
282 (_SNAPSHOT_METHOD_NAMES[0:1], _SNAPSHOT_METHOD_NAMES[1:], True),
283 ([], _SNAPSHOT_METHOD_NAMES, True),
284 )
285 @ddt.unpack
286 def test_check_redefined_driver_methods(self, common_drv_meth_names,
287 child_drv_meth_names,
288 expected_result):
289 # This test covers the case of drivers inheriting other drivers or
290 # common classes.
291
292 driver.CONF.set_default('driver_handles_share_servers', True)
293
294 common_drv_methods, child_drv_methods = [
295 {method_name: lambda *args, **kwargs: None
296 for method_name in method_names}
297 for method_names in (common_drv_meth_names,
298 child_drv_meth_names)]
299
300 common_drv = type(
301 "NotRedefinedCommon", (driver.ShareDriver, ), common_drv_methods)
302 child_drv_instance = type("NotRedefined", (common_drv, ),
303 child_drv_methods)(True)
304
305 has_redefined_methods = (
306 child_drv_instance._has_redefined_driver_methods(
307 self._SNAPSHOT_METHOD_NAMES))
308
309 self.assertEqual(expected_result, has_redefined_methods)
310
311 @ddt.data(
312 (),
313 ("create_snapshot"),
314 ("delete_snapshot"),
315 ("create_snapshot", "delete_snapshotFOO"),
316 )
317 def test_snapshot_support_absent(self, methods):
318 driver.CONF.set_default('driver_handles_share_servers', True)
319 fake_method = lambda *args, **kwargs: None
320 child_methods = {}
321 for method in methods:
322 child_methods[method] = fake_method
323 child_class_instance = type(
324 "NotRedefined", (driver.ShareDriver, ), child_methods)(True)
325 self.mock_object(child_class_instance, "configuration")
326
327 child_class_instance._update_share_stats()
328
329 self.assertFalse(child_class_instance._stats["snapshot_support"])
330 self.assertTrue(child_class_instance.configuration.safe_get.called)
331
332 @ddt.data(True, False)
333 def test_snapshot_support_not_exists_and_set_explicitly(
334 self, snapshots_are_supported):
335 driver.CONF.set_default('driver_handles_share_servers', True)
336 child_class_instance = type(
337 "NotRedefined", (driver.ShareDriver, ), {})(True)
338 self.mock_object(child_class_instance, "configuration")
339
340 child_class_instance._update_share_stats(
341 {"snapshot_support": snapshots_are_supported})
342
343 self.assertEqual(
344 snapshots_are_supported,
345 child_class_instance._stats["snapshot_support"])
346 self.assertTrue(child_class_instance.configuration.safe_get.called)
347
348 @ddt.data(True, False)
349 def test_snapshot_support_exists_and_set_explicitly(
350 self, snapshots_are_supported):
351 driver.CONF.set_default('driver_handles_share_servers', True)
352 fake_method = lambda *args, **kwargs: None
353 child_methods = {
354 "create_snapshot": fake_method,
355 "delete_snapshot": fake_method,
356 }
357 child_class_instance = type(
358 "NotRedefined", (driver.ShareDriver, ), child_methods)(True)
359 self.mock_object(child_class_instance, "configuration")
360
361 child_class_instance._update_share_stats(
362 {"snapshot_support": snapshots_are_supported})
363
364 self.assertEqual(
365 snapshots_are_supported,
366 child_class_instance._stats["snapshot_support"])
367 self.assertTrue(child_class_instance.configuration.safe_get.called)
368
369 def test_create_share_from_snapshot_support_exists(self):
370 driver.CONF.set_default('driver_handles_share_servers', True)
371 fake_method = lambda *args, **kwargs: None
372 child_methods = {
373 "create_share_from_snapshot": fake_method,
374 "create_snapshot": fake_method,
375 "delete_snapshot": fake_method,
376 }
377 child_class_instance = type(
378 "NotRedefined", (driver.ShareDriver, ), child_methods)(True)
379 self.mock_object(child_class_instance, "configuration")
380
381 child_class_instance._update_share_stats()
382
383 self.assertTrue(
384 child_class_instance._stats["create_share_from_snapshot_support"])
385 self.assertTrue(child_class_instance.configuration.safe_get.called)
386
387 @ddt.data(
388 (),
389 ("create_snapshot"),
390 ("create_share_from_snapshotFOO"),
391 )
392 def test_create_share_from_snapshot_support_absent(self, methods):
393 driver.CONF.set_default('driver_handles_share_servers', True)
394 fake_method = lambda *args, **kwargs: None
395 child_methods = {}
396 for method in methods:
397 child_methods[method] = fake_method
398 child_class_instance = type(
399 "NotRedefined", (driver.ShareDriver, ), child_methods)(True)
400 self.mock_object(child_class_instance, "configuration")
401
402 child_class_instance._update_share_stats()
403
404 self.assertFalse(
405 child_class_instance._stats["create_share_from_snapshot_support"])
406 self.assertTrue(child_class_instance.configuration.safe_get.called)
407
408 @ddt.data(True, False)
409 def test_create_share_from_snapshot_not_exists_and_set_explicitly(
410 self, creating_shares_from_snapshot_is_supported):
411 driver.CONF.set_default('driver_handles_share_servers', True)
412 child_class_instance = type(
413 "NotRedefined", (driver.ShareDriver, ), {})(True)
414 self.mock_object(child_class_instance, "configuration")
415
416 child_class_instance._update_share_stats({
417 "create_share_from_snapshot_support":
418 creating_shares_from_snapshot_is_supported,
419 })
420
421 self.assertEqual(
422 creating_shares_from_snapshot_is_supported,
423 child_class_instance._stats["create_share_from_snapshot_support"])
424 self.assertTrue(child_class_instance.configuration.safe_get.called)
425
426 @ddt.data(True, False)
427 def test_create_share_from_snapshot_exists_and_set_explicitly(
428 self, create_share_from_snapshot_supported):
429 driver.CONF.set_default('driver_handles_share_servers', True)
430 fake_method = lambda *args, **kwargs: None
431 child_methods = {"create_share_from_snapshot": fake_method}
432 child_class_instance = type(
433 "NotRedefined", (driver.ShareDriver, ), child_methods)(True)
434 self.mock_object(child_class_instance, "configuration")
435
436 child_class_instance._update_share_stats({
437 "create_share_from_snapshot_support":
438 create_share_from_snapshot_supported,
439 })
440
441 self.assertEqual(
442 create_share_from_snapshot_supported,
443 child_class_instance._stats["create_share_from_snapshot_support"])
444 self.assertTrue(child_class_instance.configuration.safe_get.called)
445
446 def test_get_periodic_hook_data(self):
447 share_driver = self._instantiate_share_driver(None, False)
448 share_instances = ["list", "of", "share", "instances"]
449
450 result = share_driver.get_periodic_hook_data(
451 "fake_context", share_instances)
452
453 self.assertEqual(share_instances, result)
454
455 def test_get_admin_network_allocations_number(self):
456 share_driver = self._instantiate_share_driver(None, True)
457
458 self.assertEqual(
459 0, share_driver.get_admin_network_allocations_number())
460
461 def test_allocate_admin_network_count_None(self):
462 share_driver = self._instantiate_share_driver(None, True)
463 ctxt = 'fake_context'
464 share_server = 'fake_share_server'
465 mock_get_admin_network_allocations_number = self.mock_object(
466 share_driver,
467 'get_admin_network_allocations_number',
468 mock.Mock(return_value=0))
469 self.mock_object(
470 share_driver.admin_network_api,
471 'allocate_network',
472 mock.Mock(side_effect=Exception('ShouldNotBeRaised')))
473
474 share_driver.allocate_admin_network(ctxt, share_server)
475
476 mock_get_admin_network_allocations_number.assert_called_once_with()
477 self.assertFalse(
478 share_driver.admin_network_api.allocate_network.called)
479
480 def test_allocate_admin_network_count_0(self):
481 share_driver = self._instantiate_share_driver(None, True)
482 ctxt = 'fake_context'
483 share_server = 'fake_share_server'
484 self.mock_object(
485 share_driver,
486 'get_admin_network_allocations_number',
487 mock.Mock(return_value=0))
488 self.mock_object(
489 share_driver.admin_network_api,
490 'allocate_network',
491 mock.Mock(side_effect=Exception('ShouldNotBeRaised')))
492
493 share_driver.allocate_admin_network(ctxt, share_server, count=0)
494
495 self.assertFalse(
496 share_driver.get_admin_network_allocations_number.called)
497 self.assertFalse(
498 share_driver.admin_network_api.allocate_network.called)
499
500 def test_allocate_admin_network_count_1_api_initialized(self):
501 share_driver = self._instantiate_share_driver(None, True)
502 ctxt = 'fake_context'
503 share_server = 'fake_share_server'
504 mock_get_admin_network_allocations_number = self.mock_object(
505 share_driver,
506 'get_admin_network_allocations_number',
507 mock.Mock(return_value=1))
508 self.mock_object(
509 share_driver.admin_network_api,
510 'allocate_network',
511 mock.Mock())
512
513 share_driver.allocate_admin_network(ctxt, share_server)
514
515 mock_get_admin_network_allocations_number.assert_called_once_with()
516 (share_driver.admin_network_api.allocate_network.
517 assert_called_once_with(ctxt, share_server, count=1))
518
519 def test_allocate_admin_network_count_1_api_not_initialized(self):
520 share_driver = self._instantiate_share_driver(None, True, None)
521 ctxt = 'fake_context'
522 share_server = 'fake_share_server'
523 share_driver._admin_network_api = None
524 mock_get_admin_network_allocations_number = self.mock_object(
525 share_driver,
526 'get_admin_network_allocations_number',
527 mock.Mock(return_value=1))
528
529 self.assertRaises(
530 exception.NetworkBadConfigurationException,
531 share_driver.allocate_admin_network,
532 ctxt, share_server,
533 )
534 mock_get_admin_network_allocations_number.assert_called_once_with()
535
536 def test_migration_start(self):
537
538 driver.CONF.set_default('driver_handles_share_servers', False)
539 share_driver = driver.ShareDriver(False)
540
541 self.assertRaises(NotImplementedError, share_driver.migration_start,
542 None, None, None, None, None, None, None)
543
544 def test_migration_continue(self):
545
546 driver.CONF.set_default('driver_handles_share_servers', False)
547 share_driver = driver.ShareDriver(False)
548
549 self.assertRaises(NotImplementedError, share_driver.migration_continue,
550 None, None, None, None, None, None, None)
551
552 def test_migration_complete(self):
553
554 driver.CONF.set_default('driver_handles_share_servers', False)
555 share_driver = driver.ShareDriver(False)
556
557 self.assertRaises(NotImplementedError, share_driver.migration_complete,
558 None, None, None, None, None, None, None)
559
560 def test_migration_cancel(self):
561
562 driver.CONF.set_default('driver_handles_share_servers', False)
563 share_driver = driver.ShareDriver(False)
564
565 self.assertRaises(NotImplementedError, share_driver.migration_cancel,
566 None, None, None, None, None, None, None)
567
568 def test_migration_get_progress(self):
569
570 driver.CONF.set_default('driver_handles_share_servers', False)
571 share_driver = driver.ShareDriver(False)
572
573 self.assertRaises(NotImplementedError,
574 share_driver.migration_get_progress,
575 None, None, None, None, None, None, None)
576
577 @ddt.data(True, False)
578 def test_connection_get_info(self, admin):
579
580 expected = {
581 'mount': 'mount -vt nfs %(options)s /fake/fake_id %(path)s',
582 'unmount': 'umount -v %(path)s',
583 'access_mapping': {
584 'ip': ['nfs']
585 }
586 }
587
588 fake_share = {
589 'id': 'fake_id',
590 'share_proto': 'nfs',
591 'export_locations': [{
592 'path': '/fake/fake_id',
593 'is_admin_only': admin
594 }]
595 }
596
597 driver.CONF.set_default('driver_handles_share_servers', False)
598 share_driver = driver.ShareDriver(False)
599 share_driver.configuration = configuration.Configuration(None)
600
601 connection_info = share_driver.connection_get_info(
602 None, fake_share, "fake_server")
603
604 self.assertEqual(expected, connection_info)
605
606 def test_migration_check_compatibility(self):
607
608 driver.CONF.set_default('driver_handles_share_servers', False)
609 share_driver = driver.ShareDriver(False)
610 share_driver.configuration = configuration.Configuration(None)
611 expected = {
612 'compatible': False,
613 'writable': False,
614 'preserve_metadata': False,
615 'nondisruptive': False,
616 'preserve_snapshots': False,
617 }
618
619 result = share_driver.migration_check_compatibility(
620 None, None, None, None, None)
621
622 self.assertEqual(expected, result)
623
624 def test_update_access(self):
625 share_driver = driver.ShareDriver(True, configuration=None)
626 self.assertRaises(
627 NotImplementedError,
628 share_driver.update_access,
629 'ctx',
630 'fake_share',
631 'fake_access_rules',
632 'fake_add_rules',
633 'fake_delete_rules'
634 )
635
636 def test_create_replica(self):
637 share_driver = self._instantiate_share_driver(None, True)
638 self.assertRaises(NotImplementedError,
639 share_driver.create_replica,
640 'fake_context', ['r1', 'r2'],
641 'fake_new_replica', [], [])
642
643 def test_delete_replica(self):
644 share_driver = self._instantiate_share_driver(None, True)
645 self.assertRaises(NotImplementedError,
646 share_driver.delete_replica,
647 'fake_context', ['r1', 'r2'],
648 'fake_replica', [])
649
650 def test_promote_replica(self):
651 share_driver = self._instantiate_share_driver(None, True)
652 self.assertRaises(NotImplementedError,
653 share_driver.promote_replica,
654 'fake_context', [], 'fake_replica', [])
655
656 def test_update_replica_state(self):
657 share_driver = self._instantiate_share_driver(None, True)
658 self.assertRaises(NotImplementedError,
659 share_driver.update_replica_state,
660 'fake_context', ['r1', 'r2'], 'fake_replica', [], [])
661
662 def test_create_replicated_snapshot(self):
663 share_driver = self._instantiate_share_driver(None, False)
664 self.assertRaises(NotImplementedError,
665 share_driver.create_replicated_snapshot,
666 'fake_context', ['r1', 'r2'], ['s1', 's2'])
667
668 def test_delete_replicated_snapshot(self):
669 share_driver = self._instantiate_share_driver(None, False)
670 self.assertRaises(NotImplementedError,
671 share_driver.delete_replicated_snapshot,
672 'fake_context', ['r1', 'r2'], ['s1', 's2'])
673
674 def test_update_replicated_snapshot(self):
675 share_driver = self._instantiate_share_driver(None, False)
676 self.assertRaises(NotImplementedError,
677 share_driver.update_replicated_snapshot,
678 'fake_context', ['r1', 'r2'], 'r1',
679 ['s1', 's2'], 's1')
680
681 @ddt.data(True, False)
682 def test_share_group_snapshot_support_exists_and_equals_snapshot_support(
683 self, snapshots_are_supported):
684 driver.CONF.set_default('driver_handles_share_servers', True)
685 child_class_instance = driver.ShareDriver(True)
686 child_class_instance._snapshots_are_supported = snapshots_are_supported
687 self.mock_object(child_class_instance, "configuration")
688
689 child_class_instance._update_share_stats()
690
691 self.assertEqual(
692 snapshots_are_supported,
693 child_class_instance._stats["snapshot_support"])
694 self.assertTrue(child_class_instance.configuration.safe_get.called)
695
696 def test_create_share_group_from_share_group_snapshot(self):
697 share_driver = self._instantiate_share_driver(None, False)
698 fake_shares = [
699 {'id': 'fake_share_%d' % i,
700 'source_share_group_snapshot_member_id': 'fake_member_%d' % i}
701 for i in (1, 2)]
702 fake_share_group_dict = {
703 'source_share_group_snapshot_id': 'some_fake_uuid_abc',
704 'shares': fake_shares,
705 'id': 'some_fake_uuid_def',
706 }
707 fake_share_group_snapshot_dict = {
708 'share_group_snapshot_members': [
709 {'id': 'fake_member_1'}, {'id': 'fake_member_2'}],
710 'id': 'fake_share_group_snapshot_id',
711 }
712 mock_create = self.mock_object(
713 share_driver, 'create_share_from_snapshot',
714 mock.Mock(side_effect=['fake_export1', 'fake_export2']))
715 expected_share_updates = [
716 {
717 'id': 'fake_share_1',
718 'export_locations': 'fake_export1',
719 },
720 {
721 'id': 'fake_share_2',
722 'export_locations': 'fake_export2',
723 },
724 ]
725
726 share_group_update, share_update = (
727 share_driver.create_share_group_from_share_group_snapshot(
728 'fake_context', fake_share_group_dict,
729 fake_share_group_snapshot_dict))
730
731 mock_create.assert_has_calls([
732 mock.call(
733 'fake_context',
734 {'id': 'fake_share_1',
735 'source_share_group_snapshot_member_id': 'fake_member_1'},
736 {'id': 'fake_member_1'}),
737 mock.call(
738 'fake_context',
739 {'id': 'fake_share_2',
740 'source_share_group_snapshot_member_id': 'fake_member_2'},
741 {'id': 'fake_member_2'})
742 ])
743 self.assertIsNone(share_group_update)
744 self.assertEqual(expected_share_updates, share_update)
745
746 def test_create_share_group_from_share_group_snapshot_dhss(self):
747 share_driver = self._instantiate_share_driver(None, True)
748 mock_share_server = mock.Mock()
749 fake_shares = [
750 {'id': 'fake_share_1',
751 'source_share_group_snapshot_member_id': 'foo_member_1'},
752 {'id': 'fake_share_2',
753 'source_share_group_snapshot_member_id': 'foo_member_2'}]
754 fake_share_group_dict = {
755 'source_share_group_snapshot_id': 'some_fake_uuid',
756 'shares': fake_shares,
757 'id': 'eda52174-0442-476d-9694-a58327466c14',
758 }
759 fake_share_group_snapshot_dict = {
760 'share_group_snapshot_members': [
761 {'id': 'foo_member_1'}, {'id': 'foo_member_2'}],
762 'id': 'fake_share_group_snapshot_id'
763 }
764 mock_create = self.mock_object(
765 share_driver, 'create_share_from_snapshot',
766 mock.Mock(side_effect=['fake_export1', 'fake_export2']))
767 expected_share_updates = [
768 {'id': 'fake_share_1', 'export_locations': 'fake_export1'},
769 {'id': 'fake_share_2', 'export_locations': 'fake_export2'},
770 ]
771
772 share_group_update, share_update = (
773 share_driver.create_share_group_from_share_group_snapshot(
774 'fake_context',
775 fake_share_group_dict,
776 fake_share_group_snapshot_dict, share_server=mock_share_server,
777 )
778 )
779
780 mock_create.assert_has_calls([
781 mock.call(
782 'fake_context',
783 {'id': 'fake_share_%d' % i,
784 'source_share_group_snapshot_member_id': 'foo_member_%d' % i},
785 {'id': 'foo_member_%d' % i},
786 share_server=mock_share_server)
787 for i in (1, 2)
788 ])
789 self.assertIsNone(share_group_update)
790 self.assertEqual(expected_share_updates, share_update)
791
792 def test_create_share_group_from_sg_snapshot_with_no_members(self):
793 share_driver = self._instantiate_share_driver(None, False)
794 fake_share_group_dict = {}
795 fake_share_group_snapshot_dict = {'share_group_snapshot_members': []}
796
797 share_group_update, share_update = (
798 share_driver.create_share_group_from_share_group_snapshot(
799 'fake_context', fake_share_group_dict,
800 fake_share_group_snapshot_dict))
801
802 self.assertIsNone(share_group_update)
803 self.assertIsNone(share_update)
804
805 def test_create_share_group_snapshot(self):
806 fake_snap_member_1 = {
807 'id': '6813e06b-a8f5-4784-b17d-f3e91afa370e',
808 'share_id': 'a3ebdba5-b4e1-46c8-a0ea-a9ac8daf5296',
809 'share_group_snapshot_id': 'fake_share_group_snapshot_id',
810 'share_instance_id': 'fake_share_instance_id_1',
811 'provider_location': 'should_not_be_used_1',
812 'share_name': 'share_fake_share_instance_id_1',
813 'name': 'share-snapshot-6813e06b-a8f5-4784-b17d-f3e91afa370e',
814 'share': {
815 'id': '420f978b-dbf6-4b3c-92fe-f5b17a0bb5e2',
816 'size': 3,
817 'share_proto': 'fake_share_proto',
818 },
819 }
820 fake_snap_member_2 = {
821 'id': '1e010dfe-545b-432d-ab95-4ef03cd82f89',
822 'share_id': 'a3ebdba5-b4e1-46c8-a0ea-a9ac8daf5296',
823 'share_group_snapshot_id': 'fake_share_group_snapshot_id',
824 'share_instance_id': 'fake_share_instance_id_2',
825 'provider_location': 'should_not_be_used_2',
826 'share_name': 'share_fake_share_instance_id_2',
827 'name': 'share-snapshot-1e010dfe-545b-432d-ab95-4ef03cd82f89',
828 'share': {
829 'id': '420f978b-dbf6-4b3c-92fe-f5b17a0bb5e2',
830 'size': '2',
831 'share_proto': 'fake_share_proto',
832 },
833 }
834 fake_snap_dict = {
835 'status': 'available',
836 'project_id': '13c0be6290934bd98596cfa004650049',
837 'user_id': 'a0314a441ca842019b0952224aa39192',
838 'description': None,
839 'deleted': '0',
840 'share_group_id': '4b04fdc3-00b9-4909-ba1a-06e9b3f88b67',
841 'share_group_snapshot_members': [
842 fake_snap_member_1, fake_snap_member_2],
843 'deleted_at': None,
844 'id': 'f6aa3b59-57eb-421e-965c-4e182538e36a',
845 'name': None
846 }
847 share_driver = self._instantiate_share_driver(None, False)
848 share_driver._stats['snapshot_support'] = True
849 mock_create_snap = self.mock_object(
850 share_driver, 'create_snapshot',
851 mock.Mock(side_effect=lambda *args, **kwargs: {
852 'foo_k': 'foo_v', 'bar_k': 'bar_v_%s' % args[1]['id']}))
853
854 share_group_snapshot_update, member_update_list = (
855 share_driver.create_share_group_snapshot(
856 'fake_context', fake_snap_dict))
857
858 mock_create_snap.assert_has_calls([
859 mock.call(
860 'fake_context',
861 {'snapshot_id': member['share_group_snapshot_id'],
862 'share_id': member['share_id'],
863 'share_instance_id': member['share']['id'],
864 'id': member['id'],
865 'share': member['share'],
866 'share_name': member['share_name'],
867 'name': member['name'],
868 'size': member['share']['size'],
869 'share_size': member['share']['size'],
870 'share_proto': member['share']['share_proto'],
871 'provider_location': None},
872 share_server=None)
873 for member in (fake_snap_member_1, fake_snap_member_2)
874 ])
875 self.assertIsNone(share_group_snapshot_update)
876 self.assertEqual(
877 [{'id': member['id'], 'foo_k': 'foo_v',
878 'bar_k': 'bar_v_%s' % member['id']}
879 for member in (fake_snap_member_1, fake_snap_member_2)],
880 member_update_list,
881 )
882
883 def test_create_share_group_snapshot_failed_snapshot(self):
884 fake_snap_member_1 = {
885 'id': '6813e06b-a8f5-4784-b17d-f3e91afa370e',
886 'share_id': 'a3ebdba5-b4e1-46c8-a0ea-a9ac8daf5296',
887 'share_group_snapshot_id': 'fake_share_group_snapshot_id',
888 'share_instance_id': 'fake_share_instance_id_1',
889 'provider_location': 'should_not_be_used_1',
890 'share_name': 'share_fake_share_instance_id_1',
891 'name': 'share-snapshot-6813e06b-a8f5-4784-b17d-f3e91afa370e',
892 'share': {
893 'id': '420f978b-dbf6-4b3c-92fe-f5b17a0bb5e2',
894 'size': 3,
895 'share_proto': 'fake_share_proto',
896 },
897 }
898 fake_snap_member_2 = {
899 'id': '1e010dfe-545b-432d-ab95-4ef03cd82f89',
900 'share_id': 'a3ebdba5-b4e1-46c8-a0ea-a9ac8daf5296',
901 'share_group_snapshot_id': 'fake_share_group_snapshot_id',
902 'share_instance_id': 'fake_share_instance_id_2',
903 'provider_location': 'should_not_be_used_2',
904 'share_name': 'share_fake_share_instance_id_2',
905 'name': 'share-snapshot-1e010dfe-545b-432d-ab95-4ef03cd82f89',
906 'share': {
907 'id': '420f978b-dbf6-4b3c-92fe-f5b17a0bb5e2',
908 'size': '2',
909 'share_proto': 'fake_share_proto',
910 },
911 }
912 fake_snap_dict = {
913 'status': 'available',
914 'project_id': '13c0be6290934bd98596cfa004650049',
915 'user_id': 'a0314a441ca842019b0952224aa39192',
916 'description': None,
917 'deleted': '0',
918 'share_group_id': '4b04fdc3-00b9-4909-ba1a-06e9b3f88b67',
919 'share_group_snapshot_members': [
920 fake_snap_member_1, fake_snap_member_2],
921 'deleted_at': None,
922 'id': 'f6aa3b59-57eb-421e-965c-4e182538e36a',
923 'name': None
924 }
925 expected_exception = exception.ManilaException
926
927 share_driver = self._instantiate_share_driver(None, False)
928 share_driver._stats['snapshot_support'] = True
929 mock_create_snap = self.mock_object(
930 share_driver, 'create_snapshot',
931 mock.Mock(side_effect=[None, expected_exception]))
932 mock_delete_snap = self.mock_object(share_driver, 'delete_snapshot')
933
934 self.assertRaises(
935 expected_exception,
936 share_driver.create_share_group_snapshot,
937 'fake_context', fake_snap_dict)
938
939 fake_snap_member_1_expected = {
940 'snapshot_id': fake_snap_member_1['share_group_snapshot_id'],
941 'share_id': fake_snap_member_1['share_id'],
942 'share_instance_id': fake_snap_member_1['share']['id'],
943 'id': fake_snap_member_1['id'],
944 'share': fake_snap_member_1['share'],
945 'share_name': fake_snap_member_1['share_name'],
946 'name': fake_snap_member_1['name'],
947 'size': fake_snap_member_1['share']['size'],
948 'share_size': fake_snap_member_1['share']['size'],
949 'share_proto': fake_snap_member_1['share']['share_proto'],
950 'provider_location': None,
951 }
952 mock_create_snap.assert_has_calls([
953 mock.call(
954 'fake_context',
955 {'snapshot_id': member['share_group_snapshot_id'],
956 'share_id': member['share_id'],
957 'share_instance_id': member['share']['id'],
958 'id': member['id'],
959 'share': member['share'],
960 'share_name': member['share_name'],
961 'name': member['name'],
962 'size': member['share']['size'],
963 'share_size': member['share']['size'],
964 'share_proto': member['share']['share_proto'],
965 'provider_location': None},
966 share_server=None)
967 for member in (fake_snap_member_1, fake_snap_member_2)
968 ])
969 mock_delete_snap.assert_called_with(
970 'fake_context', fake_snap_member_1_expected, share_server=None)
971
972 def test_create_share_group_snapshot_no_support(self):
973 fake_snap_dict = {
974 'status': 'available',
975 'project_id': '13c0be6290934bd98596cfa004650049',
976 'user_id': 'a0314a441ca842019b0952224aa39192',
977 'description': None,
978 'deleted': '0',
979 'share_group_id': '4b04fdc3-00b9-4909-ba1a-06e9b3f88b67',
980 'share_group_snapshot_members': [
981 {
982 'status': 'available',
983 'share_type_id': '1a9ed31e-ee70-483d-93ba-89690e028d7f',
984 'user_id': 'a0314a441ca842019b0952224aa39192',
985 'deleted': 'False',
986 'share_proto': 'NFS',
987 'project_id': '13c0be6290934bd98596cfa004650049',
988 'share_group_snapshot_id':
989 'f6aa3b59-57eb-421e-965c-4e182538e36a',
990 'deleted_at': None,
991 'id': '6813e06b-a8f5-4784-b17d-f3e91afa370e',
992 'size': 1
993 },
994 ],
995 'deleted_at': None,
996 'id': 'f6aa3b59-57eb-421e-965c-4e182538e36a',
997 'name': None
998 }
999 share_driver = self._instantiate_share_driver(None, False)
1000 share_driver._stats['snapshot_support'] = False
1001
1002 self.assertRaises(
1003 exception.ShareGroupSnapshotNotSupported,
1004 share_driver.create_share_group_snapshot,
1005 'fake_context', fake_snap_dict)
1006
1007 def test_create_share_group_snapshot_no_members(self):
1008 fake_snap_dict = {
1009 'status': 'available',
1010 'project_id': '13c0be6290934bd98596cfa004650049',
1011 'user_id': 'a0314a441ca842019b0952224aa39192',
1012 'description': None,
1013 'deleted': '0',
1014 'share_group_id': '4b04fdc3-00b9-4909-ba1a-06e9b3f88b67',
1015 'share_group_snapshot_members': [],
1016 'deleted_at': None,
1017 'id': 'f6aa3b59-57eb-421e-965c-4e182538e36a',
1018 'name': None
1019 }
1020 share_driver = self._instantiate_share_driver(None, False)
1021 share_driver._stats['snapshot_support'] = True
1022
1023 share_group_snapshot_update, member_update_list = (
1024 share_driver.create_share_group_snapshot(
1025 'fake_context', fake_snap_dict))
1026
1027 self.assertIsNone(share_group_snapshot_update)
1028 self.assertIsNone(member_update_list)
1029
1030 def test_delete_share_group_snapshot(self):
1031 fake_snap_member_1 = {
1032 'id': '6813e06b-a8f5-4784-b17d-f3e91afa370e',
1033 'share_id': 'a3ebdba5-b4e1-46c8-a0ea-a9ac8daf5296',
1034 'share_group_snapshot_id': 'fake_share_group_snapshot_id',
1035 'share_instance_id': 'fake_share_instance_id_1',
1036 'provider_location': 'fake_provider_location_2',
1037 'share_name': 'share_fake_share_instance_id_1',
1038 'name': 'share-snapshot-6813e06b-a8f5-4784-b17d-f3e91afa370e',
1039 'share': {
1040 'id': '420f978b-dbf6-4b3c-92fe-f5b17a0bb5e2',
1041 'size': 3,
1042 'share_proto': 'fake_share_proto',
1043 },
1044 }
1045 fake_snap_member_2 = {
1046 'id': '1e010dfe-545b-432d-ab95-4ef03cd82f89',
1047 'share_id': 'a3ebdba5-b4e1-46c8-a0ea-a9ac8daf5296',
1048 'share_group_snapshot_id': 'fake_share_group_snapshot_id',
1049 'share_instance_id': 'fake_share_instance_id_2',
1050 'provider_location': 'fake_provider_location_2',
1051 'share_name': 'share_fake_provider_location_2',
1052 'name': 'share-snapshot-1e010dfe-545b-432d-ab95-4ef03cd82f89',
1053 'share': {
1054 'id': '420f978b-dbf6-4b3c-92fe-f5b17a0bb5e2',
1055 'size': '2',
1056 'share_proto': 'fake_share_proto',
1057 },
1058 }
1059 fake_snap_dict = {
1060 'status': 'available',
1061 'project_id': '13c0be6290934bd98596cfa004650049',
1062 'user_id': 'a0314a441ca842019b0952224aa39192',
1063 'description': None,
1064 'deleted': '0',
1065 'share_group_id': '4b04fdc3-00b9-4909-ba1a-06e9b3f88b67',
1066 'share_group_snapshot_members': [
1067 fake_snap_member_1, fake_snap_member_2],
1068 'deleted_at': None,
1069 'id': 'f6aa3b59-57eb-421e-965c-4e182538e36a',
1070 'name': None
1071 }
1072
1073 share_driver = self._instantiate_share_driver(None, False)
1074 share_driver._stats['share_group_snapshot_support'] = True
1075 mock_delete_snap = self.mock_object(share_driver, 'delete_snapshot')
1076
1077 share_group_snapshot_update, member_update_list = (
1078 share_driver.delete_share_group_snapshot(
1079 'fake_context', fake_snap_dict))
1080
1081 mock_delete_snap.assert_has_calls([
1082 mock.call(
1083 'fake_context',
1084 {'snapshot_id': member['share_group_snapshot_id'],
1085 'share_id': member['share_id'],
1086 'share_instance_id': member['share']['id'],
1087 'id': member['id'],
1088 'share': member['share'],
1089 'size': member['share']['size'],
1090 'share_size': member['share']['size'],
1091 'share_name': member['share_name'],
1092 'name': member['name'],
1093 'share_proto': member['share']['share_proto'],
1094 'provider_location': member['provider_location']},
1095 share_server=None)
1096 for member in (fake_snap_member_1, fake_snap_member_2)
1097 ])
1098 self.assertIsNone(share_group_snapshot_update)
1099 self.assertIsNone(member_update_list)
1100
1101 def test_snapshot_update_access(self):
1102 share_driver = self._instantiate_share_driver(None, False)
1103 self.assertRaises(NotImplementedError,
1104 share_driver.snapshot_update_access,
1105 'fake_context', 'fake_snapshot', ['r1', 'r2'],
1106 [], [])
1107
1108 @ddt.data({'user_networks': set([4]), 'conf': [4],
1109 'expected': {'ipv4': True, 'ipv6': False}},
1110 {'user_networks': set([6]), 'conf': [4],
1111 'expected': {'ipv4': False, 'ipv6': False}},
1112 {'user_networks': set([4, 6]), 'conf': [4],
1113 'expected': {'ipv4': True, 'ipv6': False}},
1114 {'user_networks': set([4]), 'conf': [6],
1115 'expected': {'ipv4': False, 'ipv6': False}},
1116 {'user_networks': set([6]), 'conf': [6],
1117 'expected': {'ipv4': False, 'ipv6': True}},
1118 {'user_networks': set([4, 6]), 'conf': [6],
1119 'expected': {'ipv4': False, 'ipv6': True}},
1120 {'user_networks': set([4]), 'conf': [4, 6],
1121 'expected': {'ipv4': True, 'ipv6': False}},
1122 {'user_networks': set([6]), 'conf': [4, 6],
1123 'expected': {'ipv4': False, 'ipv6': True}},
1124 {'user_networks': set([4, 6]), 'conf': [4, 6],
1125 'expected': {'ipv4': True, 'ipv6': True}},
1126 )
1127 @ddt.unpack
1128 def test_add_ip_version_capability_if_dhss_true(self,
1129 user_networks,
1130 conf,
1131 expected):
1132 share_driver = self._instantiate_share_driver(None, True)
1133 self.mock_object(share_driver, 'get_configured_ip_versions',
1134 mock.Mock(return_value=conf))
1135 versions = PropertyMock(return_value=user_networks)
1136 type(share_driver.network_api).enabled_ip_versions = versions
1137 data = {'share_backend_name': 'fake_backend'}
1138
1139 result = share_driver.add_ip_version_capability(data)
1140
1141 self.assertIsNotNone(result['ipv4_support'])
1142 self.assertEqual(expected['ipv4'], result['ipv4_support'])
1143 self.assertIsNotNone(result['ipv6_support'])
1144 self.assertEqual(expected['ipv6'], result['ipv6_support'])
1145
1146 @ddt.data({'conf': [4],
1147 'expected': {'ipv4': True, 'ipv6': False}},
1148 {'conf': [6],
1149 'expected': {'ipv4': False, 'ipv6': True}},
1150 {'conf': [4, 6],
1151 'expected': {'ipv4': True, 'ipv6': True}},
1152 )
1153 @ddt.unpack
1154 def test_add_ip_version_capability_if_dhss_false(self, conf, expected):
1155 share_driver = self._instantiate_share_driver(None, False)
1156 self.mock_object(share_driver, 'get_configured_ip_versions',
1157 mock.Mock(return_value=conf))
1158 data = {'share_backend_name': 'fake_backend'}
1159 result = share_driver.add_ip_version_capability(data)
1160
1161 self.assertIsNotNone(result['ipv4_support'])
1162 self.assertEqual(expected['ipv4'], result['ipv4_support'])
1163 self.assertIsNotNone(result['ipv6_support'])
1164 self.assertEqual(expected['ipv6'], result['ipv6_support'])