def test_get_volume_stats(self, _mock_get_version, mock_vgs, mock_pvs, mock_get_volumes): self.volume.driver.vg = brick_lvm.LVM('cinder-volumes', 'sudo') self.volume.driver._update_volume_stats() stats = self.volume.driver._stats self.assertEqual(float('5.52'), stats['pools'][0]['total_capacity_gb']) self.assertEqual(float('0.52'), stats['pools'][0]['free_capacity_gb']) self.assertEqual(float('5.0'), stats['pools'][0]['provisioned_capacity_gb']) self.assertEqual(int('1'), stats['pools'][0]['total_volumes']) self.assertFalse(stats['sparse_copy_volume']) # Check value of sparse_copy_volume for thin enabled case. # This value is set in check_for_setup_error. self.configuration = conf.Configuration(None) self.configuration.lvm_type = 'thin' self.configuration.target_helper = 'lioadm' vg_obj = fake_lvm.FakeBrickLVM('cinder-volumes', False, None, 'default') lvm_driver = lvm.LVMVolumeDriver(configuration=self.configuration, db=db, vg_obj=vg_obj) lvm_driver.check_for_setup_error() lvm_driver.vg = brick_lvm.LVM('cinder-volumes', 'sudo') lvm_driver._update_volume_stats() stats = lvm_driver._stats self.assertTrue(stats['sparse_copy_volume'])
def test_delete_no_dev_fails(self): """Test delete snapshot with no dev file fails.""" self.mock_object(os.path, 'exists', lambda x: False) self.volume.driver.vg = fake_lvm.FakeBrickLVM('cinder-volumes', False, None, 'default') volume = tests_utils.create_volume(self.context, **self.volume_params) volume_id = volume['id'] self.volume.create_volume(self.context, volume) snapshot = create_snapshot(volume_id) snapshot_id = snapshot.id self.volume.create_snapshot(self.context, snapshot) with mock.patch.object(self.volume.driver, 'delete_snapshot', side_effect=exception.SnapshotIsBusy( snapshot_name='fake')) as mock_del_snap: self.volume.delete_snapshot(self.context, snapshot) snapshot_ref = objects.Snapshot.get_by_id(self.context, snapshot_id) self.assertEqual(snapshot_id, snapshot_ref.id) self.assertEqual(fields.SnapshotStatus.AVAILABLE, snapshot_ref.status) mock_del_snap.assert_called_once_with(snapshot)
def test_delete_busy_snapshot(self, mock_clean): """Test snapshot can be created and deleted.""" self.volume.driver.vg = fake_lvm.FakeBrickLVM('cinder-volumes', False, None, 'default') volume = tests_utils.create_volume(self.context, **self.volume_params) volume_id = volume['id'] self.volume.create_volume(self.context, volume) snapshot = create_snapshot(volume_id, size=volume['size']) self.volume.create_snapshot(self.context, snapshot) with mock.patch.object(self.volume.driver, 'delete_snapshot', side_effect=exception.SnapshotIsBusy( snapshot_name='fake')) as mock_del_snap: snapshot_id = snapshot.id self.volume.delete_snapshot(self.context, snapshot) snapshot_ref = objects.Snapshot.get_by_id(self.context, snapshot_id) self.assertEqual(snapshot_id, snapshot_ref.id) self.assertEqual(fields.SnapshotStatus.AVAILABLE, snapshot_ref.status) mock_del_snap.assert_called_once_with(snapshot) mock_clean.assert_not_called()
def test_check_for_setup_error(self, _mock_get_version, vgs): vg_obj = fake_lvm.FakeBrickLVM('cinder-volumes', False, None, 'auto') configuration = conf.Configuration(fake_opt, 'fake_group') lvm_driver = lvm.LVMVolumeDriver(configuration=configuration, vg_obj=vg_obj, db=db) lvm_driver.delete_snapshot = mock.Mock() volume = tests_utils.create_volume(self.context, host=socket.gethostname()) volume_id = volume['id'] backup = {} backup['volume_id'] = volume_id backup['user_id'] = fake.USER_ID backup['project_id'] = fake.PROJECT_ID backup['host'] = socket.gethostname() backup['availability_zone'] = '1' backup['display_name'] = 'test_check_for_setup_error' backup['display_description'] = 'test_check_for_setup_error' backup['container'] = 'fake' backup['status'] = fields.BackupStatus.CREATING backup['fail_reason'] = '' backup['service'] = 'fake' backup['parent_id'] = None backup['size'] = 5 * 1024 * 1024 backup['object_count'] = 22 db.backup_create(self.context, backup) lvm_driver.check_for_setup_error()
def test_get_volume_stats(self, _mock_get_version): def _fake_get_all_physical_volumes(obj, root_helper, vg_name): return [{}] @staticmethod def _fake_get_all_volume_groups(root_helper, vg_name=None): return [{'name': 'cinder-volumes', 'size': '5.52', 'available': '0.52', 'lv_count': '2', 'uuid': 'vR1JU3-FAKE-C4A9-PQFh-Mctm-9FwA-Xwzc1m'}] def _fake_get_volumes(obj, lv_name=None): return [{'vg': 'fake_vg', 'name': 'fake_vol', 'size': '1000'}] self.stubs.Set(brick_lvm.LVM, 'get_all_volume_groups', _fake_get_all_volume_groups) self.stubs.Set(brick_lvm.LVM, 'get_all_physical_volumes', _fake_get_all_physical_volumes) self.stubs.Set(brick_lvm.LVM, 'get_volumes', _fake_get_volumes) self.volume.driver.vg = brick_lvm.LVM('cinder-volumes', 'sudo') self.volume.driver._update_volume_stats() stats = self.volume.driver._stats self.assertEqual( float('5.52'), stats['pools'][0]['total_capacity_gb']) self.assertEqual( float('0.52'), stats['pools'][0]['free_capacity_gb']) self.assertEqual( float('5.0'), stats['pools'][0]['provisioned_capacity_gb']) self.assertEqual( int('1'), stats['pools'][0]['total_volumes']) self.assertFalse(stats['sparse_copy_volume']) # Check value of sparse_copy_volume for thin enabled case. # This value is set in check_for_setup_error. self.configuration = conf.Configuration(None) self.configuration.lvm_type = 'thin' vg_obj = fake_lvm.FakeBrickLVM('cinder-volumes', False, None, 'default') lvm_driver = lvm.LVMVolumeDriver(configuration=self.configuration, db=db, vg_obj=vg_obj) lvm_driver.check_for_setup_error() lvm_driver.vg = brick_lvm.LVM('cinder-volumes', 'sudo') lvm_driver._update_volume_stats() stats = lvm_driver._stats self.assertTrue(stats['sparse_copy_volume'])
def __init__(self, *args, **kwargs): super(FakeLoggingVolumeDriver, self).__init__(execute=self.fake_execute, *args, **kwargs) self.backend_name = 'fake' self.protocol = 'fake' self.vg = fake_lvm.FakeBrickLVM('cinder-volumes', False, None, 'default', self.fake_execute)
def _setup_stubs_for_manage_existing(self): """Helper to set up common stubs for the manage_existing tests.""" self.volume.driver.vg = fake_lvm.FakeBrickLVM('cinder-volumes', False, None, 'default') self.stubs.Set(self.volume.driver.vg, 'get_volume', self._get_manage_existing_lvs)
def test_multiattach_terminate_connection(self): # Ensure that target_driver.terminate_connection is only called when a # single active volume attachment remains per host for each volume. host1_connector = {'ip': '10.0.0.2', 'host': 'fakehost1', 'initiator': 'iqn.2012-07.org.fake:01'} host2_connector = {'ip': '10.0.0.3', 'host': 'fakehost2', 'initiator': 'iqn.2012-07.org.fake:02'} host1_attachment1 = fake_volume.volume_attachment_ovo( self.context) host1_attachment1.connector = host1_connector host1_attachment2 = fake_volume.volume_attachment_ovo( self.context) host1_attachment2.connector = host1_connector host2_attachment = fake_volume.volume_attachment_ovo(self.context) host2_attachment.connector = host2_connector # Create a multiattach volume object with two active attachments on # host1 and another single attachment on host2. vol = fake_volume.fake_volume_obj(self.context) vol.multiattach = True vol.volume_attachment.objects.append(host1_attachment1) vol.volume_attachment.objects.append(host1_attachment2) vol.volume_attachment.objects.append(host2_attachment) self.configuration = conf.Configuration(None) vg_obj = fake_lvm.FakeBrickLVM('cinder-volumes', False, None, 'default') lvm_driver = lvm.LVMVolumeDriver(configuration=self.configuration, db=db, vg_obj=vg_obj) with mock.patch.object(lvm_driver.target_driver, 'terminate_connection') as mock_term_conn: # Verify that terminate_connection is not called against host1 when # there are multiple active attachments against that host. self.assertTrue(lvm_driver.terminate_connection(vol, host1_connector)) mock_term_conn.assert_not_called() # Verify that terminate_connection is called against either host # when only one active attachment per host is present. vol.volume_attachment.objects.remove(host1_attachment1) self.assertTrue(lvm_driver.terminate_connection(vol, host1_connector)) self.assertTrue(lvm_driver.terminate_connection(vol, host2_connector)) mock_term_conn.assert_has_calls([mock.call(vol, host1_connector), mock.call(vol, host2_connector)])
def test_lvm_type_auto_no_lvs(self, *_unused_mocks): configuration = conf.Configuration(fake_opt, 'fake_group') configuration.lvm_type = 'auto' vg_obj = fake_lvm.FakeBrickLVM('cinder-volumes', False, None, 'default') lvm_driver = lvm.LVMVolumeDriver(configuration=configuration, vg_obj=vg_obj) lvm_driver.check_for_setup_error() self.assertEqual('thin', lvm_driver.configuration.lvm_type)
def test_lvm_max_over_subscription_ratio(self, global_value, lvm_value, expected_value): configuration = conf.Configuration(fake_opt, 'fake_group') configuration.max_over_subscription_ratio = global_value configuration.lvm_max_over_subscription_ratio = lvm_value fake_vg = mock.Mock( fake_lvm.FakeBrickLVM('cinder-volumes', False, None, 'default')) lvm_driver = lvm.LVMVolumeDriver(configuration=configuration, vg_obj=fake_vg, db=db) self.assertEqual(expected_value, lvm_driver.configuration.max_over_subscription_ratio)
def test_lvm_migrate_volume_same_volume_group(self, vgs): hostname = socket.gethostname() capabilities = {'location_info': 'LVMVolumeDriver:%s:' 'cinder-volumes:default:0' % hostname} host = {'capabilities': capabilities} vol = {'name': 'test', 'id': 1, 'size': 1, 'status': 'available'} self.volume.driver.vg = fake_lvm.FakeBrickLVM('cinder-volumes', False, None, 'default') self.assertRaises(exception.VolumeBackendAPIException, self.volume.driver.migrate_volume, self.context, vol, host)
def test_lvm_migrate_volume_proceed_with_thin(self): hostname = socket.gethostname() capabilities = { 'location_info': 'LVMVolumeDriver:%s:' 'cinder-volumes-2:default:0' % hostname } host = {'capabilities': capabilities} vol = {'name': 'testvol', 'id': 1, 'size': 2, 'status': 'available'} def fake_execute(*args, **kwargs): pass def get_all_volume_groups(): # NOTE(flaper87) Return just the destination # host to test the check of dest VG existence. return [{'name': 'cinder-volumes-2'}] def _fake_get_all_physical_volumes(obj, root_helper, vg_name): return [{}] self.configuration.lvm_type = 'thin' lvm_driver = lvm.LVMVolumeDriver(configuration=self.configuration, db=db) with mock.patch.object(brick_lvm.LVM, 'get_all_physical_volumes', return_value = [{}]), \ mock.patch.object(lvm_driver, '_execute') \ as mock_execute, \ mock.patch.object(volutils, 'copy_volume') as mock_copy, \ mock.patch.object(volutils, 'get_all_volume_groups', side_effect = get_all_volume_groups), \ mock.patch.object(lvm_driver, '_delete_volume'): lvm_driver.vg = fake_lvm.FakeBrickLVM('cinder-volumes', False, None, 'default') lvm_driver._sparse_copy_volume = True mock_execute.return_value = ("mock_outs", "mock_errs") moved, model_update = \ lvm_driver.migrate_volume(self.context, vol, host) self.assertTrue(moved) self.assertIsNone(model_update) mock_copy.assert_called_once_with( '/dev/mapper/cinder--volumes-testvol', '/dev/mapper/cinder--volumes--2-testvol', 2048, '1M', execute=mock_execute, sparse=True)
def test_lvm_migrate_volume_volume_copy_error(self, vgs, copy_volume, mock_delete, mock_pvs, mock_create): hostname = socket.gethostname() capabilities = {'location_info': 'LVMVolumeDriver:%s:' 'cinder-volumes:default:0' % hostname} host = {'capabilities': capabilities} vol = {'name': 'test', 'id': 1, 'size': 1, 'status': 'available'} self.volume.driver.vg = fake_lvm.FakeBrickLVM('cinder-volumes-old', False, None, 'default') self.assertRaises(processutils.ProcessExecutionError, self.volume.driver.migrate_volume, self.context, vol, host) mock_delete.assert_called_once_with(vol)
def test_delete_volume_thinlvm_snap(self, _mock_create_export, mock_copy, mock_clear): vg_obj = fake_lvm.FakeBrickLVM('cinder-volumes', False, None, 'default') self.configuration.volume_clear = 'zero' self.configuration.volume_clear_size = 0 self.configuration.lvm_type = 'thin' self.configuration.target_helper = 'tgtadm' lvm_driver = lvm.LVMVolumeDriver(configuration=self.configuration, vg_obj=vg_obj, db=db) uuid = '00000000-0000-0000-0000-c3aa7ee01536' fake_snapshot = {'name': 'volume-' + uuid, 'id': uuid, 'size': 123} lvm_driver._delete_volume(fake_snapshot, is_snapshot=True)
def test_lvm_volume_group_missing(self, vgs): hostname = socket.gethostname() capabilities = {'location_info': 'LVMVolumeDriver:%s:' 'cinder-volumes-3:default:0' % hostname} host = {'capabilities': capabilities} vol = {'name': 'test', 'id': 1, 'size': 1, 'status': 'available'} self.volume.driver.vg = fake_lvm.FakeBrickLVM('cinder-volumes', False, None, 'default') moved, model_update = self.volume.driver.migrate_volume(self.context, vol, host) self.assertFalse(moved) self.assertIsNone(model_update)
def test_create_cloned_volume_by_thin_snapshot(self, mock_extend): self.configuration.lvm_type = 'thin' fake_vg = mock.Mock(fake_lvm.FakeBrickLVM('cinder-volumes', False, None, 'default')) lvm_driver = lvm.LVMVolumeDriver(configuration=self.configuration, vg_obj=fake_vg, db=db) fake_volume = tests_utils.create_volume(self.context, size=1) fake_new_volume = tests_utils.create_volume(self.context, size=2) lvm_driver.create_cloned_volume(fake_new_volume, fake_volume) fake_vg.create_lv_snapshot.assert_called_once_with( fake_new_volume['name'], fake_volume['name'], 'thin') mock_extend.assert_called_once_with(fake_new_volume, 2) fake_vg.activate_lv.assert_called_once_with( fake_new_volume['name'], is_snapshot=True, permanent=True)
def test_do_setup_clean_temporary_dir(self): vg_obj = fake_lvm.FakeBrickLVM('cinder-volumes', False, None, 'default') self.configuration.volume_clear = 'zero' self.configuration.volume_clear_size = 0 self.configuration.lvm_type = 'thin' self.configuration.iscsi_helper = 'tgtadm' lvm_driver = lvm.LVMVolumeDriver(configuration=self.configuration, vg_obj=vg_obj, db=db) tmp_files = ['tmpFileA', 'tmpFileB'] with mock.patch('os.path.exists', return_value=True) \ as mock_path_exists, \ mock.patch('os.listdir', return_value=tmp_files), \ mock.patch('os.remove') as mock_remove: lvm_driver.do_setup('context') mock_path_exists.assert_called_once_with( CONF.image_conversion_dir) self.assertEqual(mock_remove.call_count, len(tmp_files)) calls = [args for args, kwargs in mock_remove.call_args_list] for f in tmp_files: self.assertIn((os.path.join(CONF.image_conversion_dir, f),), calls)
def test_update_migrated_volume(self): fake_volume_id = fake.VOLUME_ID fake_new_volume_id = fake.VOLUME2_ID fake_provider = 'fake_provider' original_volume_name = CONF.volume_name_template % fake_volume_id current_name = CONF.volume_name_template % fake_new_volume_id fake_volume = tests_utils.create_volume(self.context) fake_volume['id'] = fake_volume_id fake_new_volume = tests_utils.create_volume(self.context) fake_new_volume['id'] = fake_new_volume_id fake_new_volume['provider_location'] = fake_provider fake_vg = fake_lvm.FakeBrickLVM('cinder-volumes', False, None, 'default') with mock.patch.object(self.volume.driver, 'vg') as vg: vg.return_value = fake_vg vg.rename_volume.return_value = None update = self.volume.driver.update_migrated_volume( self.context, fake_volume, fake_new_volume, 'available') vg.rename_volume.assert_called_once_with(current_name, original_volume_name) self.assertEqual({ '_name_id': None, 'provider_location': None }, update) vg.rename_volume.reset_mock() vg.rename_volume.side_effect = processutils.ProcessExecutionError update = self.volume.driver.update_migrated_volume( self.context, fake_volume, fake_new_volume, 'available') vg.rename_volume.assert_called_once_with(current_name, original_volume_name) self.assertEqual( { '_name_id': fake_new_volume_id, 'provider_location': fake_provider }, update)
def __init__(self, *args, **kwargs): super(FakeISCSIDriver, self).__init__(execute=self.fake_execute, *args, **kwargs) self.vg = fake_lvm.FakeBrickLVM('cinder-volumes', False, None, 'default', self.fake_execute)