"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "cinder/tests/unit/volume/drivers/test_rbd.py" between
cinder-15.0.1.tar.gz and cinder-15.1.0.tar.gz

About: OpenStack Cinder (Core Service: Block Storage) provides persistent block storage to running instances. Its pluggable driver architecture facilitates the creation and management of block storage devices.
The "Train" series (latest release).

test_rbd.py  (cinder-15.0.1):test_rbd.py  (cinder-15.1.0)
skipping to change at line 413 skipping to change at line 413
case is impossible. case is impossible.
In this test case, there are three test scenarios: In this test case, there are three test scenarios:
1. 'exclusive_lock' and 'journaling' both enabled, 1. 'exclusive_lock' and 'journaling' both enabled,
'image.features()' will not be called. 'image.features()' will not be called.
2. 'exclusive_lock' enabled, 'journaling' disabled, 2. 'exclusive_lock' enabled, 'journaling' disabled,
'image.features()' will be only called for 'journaling'. 'image.features()' will be only called for 'journaling'.
3. 'exclusice_lock' and 'journaling' are both disabled, 3. 'exclusice_lock' and 'journaling' are both disabled,
'image.features()'will be both called for 'exclusive-lock' and 'image.features()'will be both called for 'exclusive-lock' and
'journaling' in this order. 'journaling' in this order.
""" """
journaling_feat = 1
exclusive_lock_feat = 2
self.driver.rbd.RBD_FEATURE_JOURNALING = journaling_feat
self.driver.rbd.RBD_FEATURE_EXCLUSIVE_LOCK = exclusive_lock_feat
image = self.mock_proxy.return_value.__enter__.return_value image = self.mock_proxy.return_value.__enter__.return_value
image.features.return_value = 0
image_features = 0
if exclusive_lock_enabled: if exclusive_lock_enabled:
image.features.return_value += exclusive_lock_feat image_features |= self.driver.RBD_FEATURE_EXCLUSIVE_LOCK
if journaling_enabled: if journaling_enabled:
image.features.return_value += journaling_feat image_features |= self.driver.RBD_FEATURE_JOURNALING
image.features.return_value = image_features
journaling_status = str(journaling_enabled).lower() journaling_status = str(journaling_enabled).lower()
exclusive_lock_status = str(exclusive_lock_enabled).lower() exclusive_lock_status = str(exclusive_lock_enabled).lower()
expected = { expected = {
'replication_driver_data': ('{"had_exclusive_lock":%s,' 'replication_driver_data': ('{"had_exclusive_lock":%s,'
'"had_journaling":%s}' % '"had_journaling":%s}' %
(exclusive_lock_status, (exclusive_lock_status,
journaling_status)), journaling_status)),
'replication_status': 'enabled', 'replication_status': 'enabled',
} }
res = self.driver._enable_replication(self.volume_a) res = self.driver._enable_replication(self.volume_a)
self.assertEqual(expected, res) self.assertEqual(expected, res)
if exclusive_lock_enabled and journaling_enabled: if exclusive_lock_enabled and journaling_enabled:
image.update_features.assert_not_called() image.update_features.assert_not_called()
elif exclusive_lock_enabled and not journaling_enabled: elif exclusive_lock_enabled and not journaling_enabled:
image.update_features.assert_called_once_with(journaling_feat, image.update_features.assert_called_once_with(
True) self.driver.RBD_FEATURE_JOURNALING, True)
else: else:
calls = [call(exclusive_lock_feat, True), calls = [call(self.driver.RBD_FEATURE_EXCLUSIVE_LOCK, True),
call(journaling_feat, True)] call(self.driver.RBD_FEATURE_JOURNALING, True)]
image.update_features.assert_has_calls(calls, any_order=False) image.update_features.assert_has_calls(calls, any_order=False)
image.mirror_image_enable.assert_called_once_with() image.mirror_image_enable.assert_called_once_with()
@ddt.data(['false', 'true'], ['true', 'true'], ['false', 'false']) @ddt.data(['false', 'true'], ['true', 'true'], ['false', 'false'])
@ddt.unpack @ddt.unpack
@common_mocks @common_mocks
def test_disable_replication(self, had_journaling, had_exclusive_lock): def test_disable_replication(self, had_journaling, had_exclusive_lock):
driver_data = ('{"had_journaling": %s,"had_exclusive_lock": %s}' % driver_data = ('{"had_journaling": %s,"had_exclusive_lock": %s}' %
(had_journaling, had_exclusive_lock)) (had_journaling, had_exclusive_lock))
self.volume_a.replication_driver_data = driver_data self.volume_a.replication_driver_data = driver_data
skipping to change at line 464 skipping to change at line 466
res = self.driver._disable_replication(self.volume_a) res = self.driver._disable_replication(self.volume_a)
expected = {'replication_status': fields.ReplicationStatus.DISABLED, expected = {'replication_status': fields.ReplicationStatus.DISABLED,
'replication_driver_data': None} 'replication_driver_data': None}
self.assertEqual(expected, res) self.assertEqual(expected, res)
image.mirror_image_disable.assert_called_once_with(False) image.mirror_image_disable.assert_called_once_with(False)
if had_journaling == 'true' and had_exclusive_lock == 'true': if had_journaling == 'true' and had_exclusive_lock == 'true':
image.update_features.assert_not_called() image.update_features.assert_not_called()
elif had_journaling == 'false' and had_exclusive_lock == 'true': elif had_journaling == 'false' and had_exclusive_lock == 'true':
image.update_features.assert_called_once_with( image.update_features.assert_called_once_with(
self.driver.rbd.RBD_FEATURE_JOURNALING, False) self.driver.RBD_FEATURE_JOURNALING, False)
else: else:
calls = [call(self.driver.rbd.RBD_FEATURE_JOURNALING, False), calls = [call(self.driver.RBD_FEATURE_JOURNALING, False),
call(self.driver.rbd.RBD_FEATURE_EXCLUSIVE_LOCK, call(self.driver.RBD_FEATURE_EXCLUSIVE_LOCK,
False)] False)]
image.update_features.assert_has_calls(calls, any_order=False) image.update_features.assert_has_calls(calls, any_order=False)
@common_mocks @common_mocks
@mock.patch.object(driver.RBDDriver, '_enable_replication') @mock.patch.object(driver.RBDDriver, '_enable_replication')
def test_create_volume(self, mock_enable_repl): def test_create_volume(self, mock_enable_repl):
client = self.mock_client.return_value client = self.mock_client.return_value
client.__enter__.return_value = client client.__enter__.return_value = client
res = self.driver.create_volume(self.volume_a) res = self.driver.create_volume(self.volume_a)
skipping to change at line 1058 skipping to change at line 1060
res = self.driver.create_cloned_volume(self.volume_b, res = self.driver.create_cloned_volume(self.volume_b,
self.volume_a) self.volume_a)
self.assertEqual({}, res) self.assertEqual({}, res)
(self.mock_rbd.Image.return_value.create_snap (self.mock_rbd.Image.return_value.create_snap
.assert_called_once_with('.'.join( .assert_called_once_with('.'.join(
(self.volume_b.name, 'clone_snap')))) (self.volume_b.name, 'clone_snap'))))
(self.mock_rbd.Image.return_value.protect_snap (self.mock_rbd.Image.return_value.protect_snap
.assert_called_once_with('.'.join( .assert_called_once_with('.'.join(
(self.volume_b.name, 'clone_snap')))) (self.volume_b.name, 'clone_snap'))))
# We expect clone() to be called exactly once.
self.assertEqual( self.assertEqual(
1, self.mock_rbd.RBD.return_value.clone.call_count) 1, self.mock_rbd.RBD.return_value.clone.call_count)
# Without flattening, only the source volume is opened,
# so only one call to close() should occur.
self.assertEqual( self.assertEqual(
2, self.mock_rbd.Image.return_value.close.call_count) 1, self.mock_rbd.Image.return_value.close.call_count)
self.assertTrue(mock_get_clone_depth.called) self.assertTrue(mock_get_clone_depth.called)
mock_resize.assert_not_called() mock_resize.assert_not_called()
mock_enable_repl.assert_not_called() mock_enable_repl.assert_not_called()
@common_mocks @common_mocks
@mock.patch.object(driver.RBDDriver, '_get_clone_depth', return_value=1) @mock.patch.object(driver.RBDDriver, '_get_clone_depth', return_value=1)
@mock.patch.object(driver.RBDDriver, '_resize') @mock.patch.object(driver.RBDDriver, '_resize')
@mock.patch.object(driver.RBDDriver, '_enable_replication') @mock.patch.object(driver.RBDDriver, '_enable_replication')
def test_create_cloned_volume_replicated(self, def test_create_cloned_volume_replicated(self,
mock_enable_repl, mock_enable_repl,
skipping to change at line 1097 skipping to change at line 1102
self.assertEqual(expected_update, res) self.assertEqual(expected_update, res)
mock_enable_repl.assert_called_once_with(self.volume_b) mock_enable_repl.assert_called_once_with(self.volume_b)
name = self.volume_b.name name = self.volume_b.name
image = self.mock_rbd.Image.return_value image = self.mock_rbd.Image.return_value
image.create_snap.assert_called_once_with(name + '.clone_snap') image.create_snap.assert_called_once_with(name + '.clone_snap')
image.protect_snap.assert_called_once_with(name + '.clone_snap') image.protect_snap.assert_called_once_with(name + '.clone_snap')
self.assertEqual(1, self.mock_rbd.RBD.return_value.clone.call_count) self.assertEqual(1, self.mock_rbd.RBD.return_value.clone.call_count)
self.assertEqual( self.assertEqual(
2, self.mock_rbd.Image.return_value.close.call_count) 1, self.mock_rbd.Image.return_value.close.call_count)
mock_get_clone_depth.assert_called_once_with( mock_get_clone_depth.assert_called_once_with(
self.mock_client().__enter__(), self.volume_a.name) self.mock_client().__enter__(), self.volume_a.name)
mock_resize.assert_not_called() mock_resize.assert_not_called()
@common_mocks @common_mocks
@mock.patch.object(driver.RBDDriver, '_enable_replication') @mock.patch.object(driver.RBDDriver, '_enable_replication')
def test_create_cloned_volume_different_size(self, mock_enable_repl): def test_create_cloned_volume_different_size(self, mock_enable_repl):
self.cfg.rbd_max_clone_depth = 2 self.cfg.rbd_max_clone_depth = 2
with mock.patch.object(self.driver, '_get_clone_depth') as \ with mock.patch.object(self.driver, '_get_clone_depth') as \
skipping to change at line 1127 skipping to change at line 1132
self.assertEqual({}, res) self.assertEqual({}, res)
(self.mock_rbd.Image.return_value.create_snap (self.mock_rbd.Image.return_value.create_snap
.assert_called_once_with('.'.join( .assert_called_once_with('.'.join(
(self.volume_b.name, 'clone_snap')))) (self.volume_b.name, 'clone_snap'))))
(self.mock_rbd.Image.return_value.protect_snap (self.mock_rbd.Image.return_value.protect_snap
.assert_called_once_with('.'.join( .assert_called_once_with('.'.join(
(self.volume_b.name, 'clone_snap')))) (self.volume_b.name, 'clone_snap'))))
self.assertEqual( self.assertEqual(
1, self.mock_rbd.RBD.return_value.clone.call_count) 1, self.mock_rbd.RBD.return_value.clone.call_count)
self.assertEqual( self.assertEqual(
2, self.mock_rbd.Image.return_value.close.call_count) 1, self.mock_rbd.Image.return_value.close.call_count)
self.assertTrue(mock_get_clone_depth.called) self.assertTrue(mock_get_clone_depth.called)
self.assertEqual( self.assertEqual(
1, mock_resize.call_count) 1, mock_resize.call_count)
mock_enable_repl.assert_not_called() mock_enable_repl.assert_not_called()
@common_mocks @common_mocks
def test_create_cloned_volume_different_size_copy_only(self): def test_create_cloned_volume_different_size_copy_only(self):
self.cfg.rbd_max_clone_depth = 0 self.cfg.rbd_max_clone_depth = 0
with mock.patch.object(self.driver, '_get_clone_depth') as \ with mock.patch.object(self.driver, '_get_clone_depth') as \
skipping to change at line 1184 skipping to change at line 1189
1, self.mock_rbd.RBD.return_value.clone.call_count) 1, self.mock_rbd.RBD.return_value.clone.call_count)
(self.mock_rbd.Image.return_value.unprotect_snap (self.mock_rbd.Image.return_value.unprotect_snap
.assert_called_once_with('.'.join( .assert_called_once_with('.'.join(
(self.volume_b.name, 'clone_snap')))) (self.volume_b.name, 'clone_snap'))))
(self.mock_rbd.Image.return_value.remove_snap (self.mock_rbd.Image.return_value.remove_snap
.assert_called_once_with('.'.join( .assert_called_once_with('.'.join(
(self.volume_b.name, 'clone_snap')))) (self.volume_b.name, 'clone_snap'))))
# We expect the driver to close both volumes, so 2 is expected # We expect the driver to close both volumes, so 2 is expected
self.assertEqual( self.assertEqual(
3, self.mock_rbd.Image.return_value.close.call_count) 2, self.mock_rbd.Image.return_value.close.call_count)
self.assertTrue(mock_get_clone_depth.called) self.assertTrue(mock_get_clone_depth.called)
mock_enable_repl.assert_not_called() mock_enable_repl.assert_not_called()
@common_mocks @common_mocks
@mock.patch.object(driver.RBDDriver, '_enable_replication') @mock.patch.object(driver.RBDDriver, '_enable_replication')
def test_create_cloned_volume_w_clone_exception(self, mock_enable_repl): def test_create_cloned_volume_w_clone_exception(self, mock_enable_repl):
self.cfg.rbd_max_clone_depth = 2 self.cfg.rbd_max_clone_depth = 2
self.mock_rbd.RBD.return_value.clone.side_effect = ( self.mock_rbd.RBD.return_value.clone.side_effect = (
self.mock_rbd.RBD.Error) self.mock_rbd.RBD.Error)
with mock.patch.object(self.driver, '_get_clone_depth') as \ with mock.patch.object(self.driver, '_get_clone_depth') as \
skipping to change at line 2449 skipping to change at line 2454
volume_get_by_id.return_value = self.volume_a volume_get_by_id.return_value = self.volume_a
driver = self.driver driver = self.driver
self._create_backup_db_entry(fake.BACKUP_ID, self.volume_a['id'], 1) self._create_backup_db_entry(fake.BACKUP_ID, self.volume_a['id'], 1)
backup = objects.Backup.get_by_id(self.context, fake.BACKUP_ID) backup = objects.Backup.get_by_id(self.context, fake.BACKUP_ID)
backup.service = 'asdf' backup.service = 'asdf'
ret = driver.get_backup_device(self.context, backup) ret = driver.get_backup_device(self.context, backup)
self.assertEqual(ret, (self.volume_b, False)) self.assertEqual(ret, (self.volume_b, False))
@common_mocks
def test_multiattach_exclusions(self):
self.assertEqual(
self.driver.RBD_FEATURE_JOURNALING |
self.driver.RBD_FEATURE_FAST_DIFF |
self.driver.RBD_FEATURE_OBJECT_MAP |
self.driver.RBD_FEATURE_EXCLUSIVE_LOCK,
self.driver.MULTIATTACH_EXCLUSIONS)
MULTIATTACH_FULL_FEATURES = (
driver.RBDDriver.RBD_FEATURE_LAYERING |
driver.RBDDriver.RBD_FEATURE_EXCLUSIVE_LOCK |
driver.RBDDriver.RBD_FEATURE_OBJECT_MAP |
driver.RBDDriver.RBD_FEATURE_FAST_DIFF |
driver.RBDDriver.RBD_FEATURE_JOURNALING)
MULTIATTACH_REDUCED_FEATURES = (
driver.RBDDriver.RBD_FEATURE_LAYERING |
driver.RBDDriver.RBD_FEATURE_EXCLUSIVE_LOCK)
@ddt.data(MULTIATTACH_FULL_FEATURES, MULTIATTACH_REDUCED_FEATURES)
@common_mocks
def test_enable_multiattach(self, features):
image = self.mock_proxy.return_value.__enter__.return_value
image_features = features
image.features.return_value = image_features
ret = self.driver._enable_multiattach(self.volume_a)
image.update_features.assert_called_once_with(
self.driver.MULTIATTACH_EXCLUSIONS & image_features, False)
self.assertEqual(
{'provider_location':
"{\"saved_features\":%s}" % image_features}, ret)
@ddt.data(MULTIATTACH_FULL_FEATURES, MULTIATTACH_REDUCED_FEATURES)
@common_mocks
def test_disable_multiattach(self, features):
image = self.mock_proxy.return_value.__enter__.return_value
self.volume_a.provider_location = '{"saved_features": %s}' % features
ret = self.driver._disable_multiattach(self.volume_a)
image.update_features.assert_called_once_with(
self.driver.MULTIATTACH_EXCLUSIONS & features, True)
self.assertEqual({'provider_location': None}, ret)
class ManagedRBDTestCase(test_driver.BaseDriverTestCase): class ManagedRBDTestCase(test_driver.BaseDriverTestCase):
driver_name = "cinder.volume.drivers.rbd.RBDDriver" driver_name = "cinder.volume.drivers.rbd.RBDDriver"
def setUp(self): def setUp(self):
super(ManagedRBDTestCase, self).setUp() super(ManagedRBDTestCase, self).setUp()
self.volume.driver.set_initialized() self.volume.driver.set_initialized()
self.volume.stats = {'allocated_capacity_gb': 0, self.volume.stats = {'allocated_capacity_gb': 0,
'pools': {}} 'pools': {}}
self.called = [] self.called = []
 End of changes. 17 change blocks. 
18 lines changed or deleted 72 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)