def test_init_from_volume(self): vol = objects.Volume(self.backend, name='vol_name', description='vol_desc', size=10) vol2 = objects.Volume(vol, name='new_name', size=11) self.assertEqual(self.backend, vol2.backend) self.assertEqual('new_name', vol2.name) self.assertEqual('new_name', vol2.display_name) self.assertEqual(vol.description, vol2.description) self.assertEqual(11, vol2.size) self.assertIsNotNone(vol2.id) self.assertNotEqual(vol.id, vol2.id)
def test_connections_lazy_loading_from_ovo(self, get_all_mock): """Test we don't reload connections if data is in OVO.""" vol = objects.Volume(self.backend, size=10) vol._connections = None delattr(vol._ovo, '_obj_volume_attachment') conns = [objects.Connection(self.backend, connector={'k': 'v'}, volume_id=vol.id, status='attached', attach_mode='rw', connection_info={'conn': {}}, name='my_snap')] ovo_conns = [conn._ovo for conn in conns] ovo_attach_list = cinder_ovos.VolumeAttachmentList(objects=ovo_conns) get_all_mock.return_value = ovo_attach_list mock_get_conns = self.persistence.get_connections ovo_result = vol._ovo.volume_attachment mock_get_conns.not_called() self.assertEqual(ovo_attach_list, ovo_result) # Cinderlib object doesn't have the connections yet self.assertIsNone(vol._connections) self.assertEqual(1, len(vol._ovo.volume_attachment)) self.assertEqual(vol._ovo.volume_attachment[0], ovo_result[0]) # There is no second call when we access the cinderlib object, as the # data is retrieved from the OVO that already has it result = vol.connections mock_get_conns.not_called() # Confirm we used the OVO self.assertIs(ovo_conns[0], result[0]._ovo)
def test__remove_export(self): vol = objects.Volume(self.backend_name, status='in-use', size=10) vol._remove_export() self.backend.driver.remove_export.assert_called_once_with( vol._context, vol._ovo)
def create_volume(self, size, name='', description='', bootable=False, **kwargs): vol = objects.Volume(self, size=size, name=name, description=description, bootable=bootable, **kwargs) vol.create() return vol
def test__connection_removed_not_loaded(self): vol = objects.Volume(self.backend, name='vol_name', description='vol_desc', size=10) vol._connections = None conn = objects.Connection(self.backend, connection_info={'conn': {}}) # Just check it doesn't break vol._connection_removed(conn)
def test_connections_lazy_loading(self): vol = objects.Volume(self.backend, size=10) vol._connections = None conns = [ objects.Connection(self.backend, connector={'k': 'v'}, volume_id=vol.id, status='attached', attach_mode='rw', connection_info={'conn': {}}, name='my_snap') ] mock_get_conns = self.persistence.get_connections mock_get_conns.return_value = conns result = vol.connections mock_get_conns.called_once_with(volume_id=vol.id) self.assertEqual(conns, result) self.assertEqual(conns, vol._connections) self.assertEqual(1, len(vol._ovo.volume_attachment)) self.assertEqual(vol._ovo.volume_attachment[0], result[0]._ovo) # There is no second call when we reference it again mock_get_conns.reset_mock() result = vol.connections self.assertEqual(conns, result) mock_get_conns.not_called()
def test__snapshot_removed_not_loaded(self): vol = objects.Volume(self.backend, name='vol_name', description='vol_desc', size=10) vol._snapshots = None snap = objects.Snapshot(vol) # Just check it doesn't break vol._snapshot_removed(snap)
def get_volumes(self, volume_id=None, volume_name=None, backend_name=None): filters = self._build_filter(id=volume_id, display_name=volume_name, availability_zone=backend_name) LOG.debug('get_volumes for %s', filters) ovos = cinder_objs.VolumeList.get_all(objects.CONTEXT, filters=filters) result = [objects.Volume(ovo.availability_zone, __ovo=ovo) for ovo in ovos.objects] return result
def test_extend(self): vol = objects.Volume(self.backend_name, status='available', size=10) vol.extend(11) self.backend.driver.extend_volume.assert_called_once_with(vol._ovo, 11) self.persistence.set_volume.assert_called_once_with(vol) self.assertEqual('available', vol.status) self.assertEqual(11, vol.size)
def test__disconnect(self, mock_remove_export, mock_conn_removed): vol = objects.Volume(self.backend_name, status='in-use', size=10) vol._disconnect(mock.sentinel.connection) mock_remove_export.assert_called_once_with() mock_conn_removed.assert_called_once_with(mock.sentinel.connection) self.assertEqual('available', vol.status) self.persistence.set_volume.assert_called_once_with(vol)
def test_init_from_args_backend(self): vol = objects.Volume(self.backend, name='vol_name', description='vol_desc', size=10) self.assertEqual(self.backend, vol.backend) self.assertEqual('vol_name', vol.name) self.assertEqual('vol_name', vol.display_name) self.assertEqual('vol_desc', vol.description) self.assertEqual(10, vol.size) self.assertIsNotNone(vol.id)
def test_snap_to_and_from(self): vol = objects.Volume(self.backend, size=10) snap = objects.Snapshot(vol, name='disk') json_data = snap.json # Confirm vol.json property is equivalent to the non simplified version self.assertEqual(json_data, snap.to_json(simplified=False)) snap2 = objects.Snapshot.load(json_data) self.assertEqual(snap.json, snap2.json)
def test_cleanup(self, mock_remove_export): vol = objects.Volume(self.backend_name, status='in-use', size=10) connections = [mock.Mock(), mock.Mock()] vol._connections = connections vol.cleanup() mock_remove_export.assert_called_once_with() for c in connections: c.detach.asssert_called_once_with()
def test_detach(self): vol = objects.Volume(self.backend_name, status='available', size=10) mock_conn = mock.Mock() vol.local_attach = mock_conn vol.detach(mock.sentinel.force, mock.sentinel.ignore_errors) mock_conn.detach.assert_called_once_with(mock.sentinel.force, mock.sentinel.ignore_errors, mock.ANY) mock_conn.disconnect.assert_called_once_with(mock.sentinel.force)
def test_delete_error(self): vol = objects.Volume(self.backend_name, name='vol_name', description='vol_desc', size=10) self.backend.driver.delete_volume.side_effect = exception.NotFound with self.assertRaises(exception.NotFound) as assert_context: vol.delete() self.assertEqual(vol, assert_context.exception.resource) self.backend.driver.delete_volume.assert_called_once_with(vol._ovo) self.assertEqual('error_deleting', vol._ovo.status)
def test__snapshot_removed_not_present(self): vol = objects.Volume(self.backend, name='vol_name', description='vol_desc', size=10) snap = objects.Snapshot(vol) snap2 = objects.Snapshot(vol) vol._snapshots = [snap2] vol._ovo.snapshots.objects = [snap2._ovo] # Just check it doesn't break or remove any other snaps vol._snapshot_removed(snap) self.assertEqual([snap2], vol._snapshots) self.assertEqual([snap2._ovo], vol._ovo.snapshots.objects)
def test_extend_error(self): vol = objects.Volume(self.backend_name, status='available', size=10) self.backend.driver.extend_volume.side_effect = exception.NotFound with self.assertRaises(exception.NotFound) as assert_context: vol.extend(11) self.assertEqual(vol, assert_context.exception.resource) self.backend.driver.extend_volume.assert_called_once_with(vol._ovo, 11) self.persistence.set_volume.assert_called_once_with(vol) self.assertEqual('error', vol.status) self.assertEqual(10, vol.size)
def test__connection_removed_not_present(self): vol = objects.Volume(self.backend, name='vol_name', description='vol_desc', size=10) conn = objects.Connection(self.backend, connection_info={'conn': {}}) conn2 = objects.Connection(self.backend, connection_info={'conn': {}}) vol._connections = [conn2] vol._ovo.volume_attachment.objects = [conn2._ovo] # Just check it doesn't break or remove any other snaps vol._connection_removed(conn) self.assertEqual([conn2], vol._connections) self.assertEqual([conn2._ovo], vol._ovo.volume_attachment.objects)
def test_attach(self, mock_connect, mock_conn_props): vol = objects.Volume(self.backend_name, status='available', size=10) res = vol.attach() mock_conn_props.assert_called_once_with( self.backend.configuration.use_multipath_for_image_xfer, self.backend.configuration.enforce_multipath_for_image_xfer) mock_connect.assert_called_once_with(mock_conn_props.return_value) mock_connect.return_value.attach.assert_called_once_with() self.assertEqual(mock_connect.return_value, res)
def test_extend_attached(self): vol = objects.Volume(self.backend_name, status='in-use', size=10) vol.local_attach = mock.Mock() res = vol.extend(11) self.assertEqual(vol.local_attach.extend.return_value, res) self.backend.driver.extend_volume.assert_called_once_with(vol._ovo, 11) vol.local_attach.extend.assert_called_once_with() self.persistence.set_volume.assert_called_once_with(vol) self.assertEqual('in-use', vol.status) self.assertEqual(11, vol.size)
def test_datetime_non_subsecond(self): """Test rehydration of DateTime field without microsecond.""" vol = objects.Volume(self.backend, size=1, name='disk') vol._ovo.created_at = vol.created_at.replace(microsecond=123456) with mock.patch.object(vol._ovo.fields['created_at'], 'to_primitive', return_value='2021-06-28T17:14:59Z'): json_data = vol.json vol2 = objects.Volume.load(json_data) self.assertEqual(0, vol2.created_at.microsecond)
def test_datetime_subsecond(self): """Test microsecond serialization of DateTime fields.""" microsecond = 123456 vol = objects.Volume(self.backend, size=1, name='disk') vol._ovo.created_at = vol.created_at.replace(microsecond=microsecond) created_at = vol.created_at json_data = vol.json vol2 = objects.Volume.load(json_data) self.assertEqual(created_at, vol2.created_at) self.assertEqual(microsecond, vol2.created_at.microsecond)
def setUp(self): super(TestSnapshot, self).setUp() self.vol = objects.Volume(self.backend_name, size=10, extra_specs={'e': 'v'}, qos_specs={'q': 'qv'}) self.snap = objects.Snapshot(self.vol, name='my_snap', description='my_desc') self.vol._snapshots.append(self.snap) self.vol._ovo.snapshots.objects.append(self.snap._ovo)
def test_attach_error_connect(self, mock_connect, mock_conn_props): vol = objects.Volume(self.backend_name, status='available', size=10) mock_connect.side_effect = exception.NotFound self.assertRaises(exception.NotFound, vol.attach) mock_conn_props.assert_called_once_with( self.backend.configuration.use_multipath_for_image_xfer, self.backend.configuration.enforce_multipath_for_image_xfer) mock_connect.assert_called_once_with(mock_conn_props.return_value) mock_connect.return_value.attach.assert_not_called()
def test_create_snapshot_error(self): vol = objects.Volume(self.backend_name, status='available', size=10) mock_create = self.backend.driver.create_snapshot mock_create.side_effect = exception.NotFound self.assertRaises(exception.NotFound, vol.create_snapshot) self.assertEqual(1, len(vol.snapshots)) snap = vol.snapshots[0] self.persistence.set_snapshot.assert_called_once_with(snap) self.assertEqual('error', snap.status) mock_create.assert_called_once_with(snap._ovo)
def test_detach_error_disconnect(self): vol = objects.Volume(self.backend_name, status='available', size=10) mock_conn = mock.Mock() mock_conn.disconnect.side_effect = exception.NotFound vol.local_attach = mock_conn self.assertRaises(objects.brick_exception.ExceptionChainer, vol.detach, mock.sentinel.force, False) mock_conn.detach.assert_called_once_with(mock.sentinel.force, False, mock.ANY) mock_conn.disconnect.assert_called_once_with(mock.sentinel.force)
def test_create_snapshot(self): vol = objects.Volume(self.backend_name, status='available', size=10) mock_create = self.backend.driver.create_snapshot mock_create.return_value = None snap = vol.create_snapshot() self.assertEqual([snap], vol.snapshots) self.assertEqual([snap._ovo], vol._ovo.snapshots.objects) mock_create.assert_called_once_with(snap._ovo) self.assertEqual('available', snap.status) self.assertEqual(10, snap.volume_size) self.persistence.set_snapshot.assert_called_once_with(snap)
def test_detach_error_detach(self): vol = objects.Volume(self.backend_name, status='available', size=10) mock_conn = mock.Mock() mock_conn.detach.side_effect = exception.NotFound vol.local_attach = mock_conn self.assertRaises(exception.NotFound, vol.detach, False, mock.sentinel.ignore_errors) mock_conn.detach.assert_called_once_with(False, mock.sentinel.ignore_errors, mock.ANY) mock_conn.disconnect.assert_not_called()
def test_conn_to_and_from(self): vol = objects.Volume(self.backend, size=1, name='disk') conn = objects.Connection(self.backend, volume=vol, connector={}, connection_info={'conn': { 'data': {} }}) json_data = conn.json # Confirm vol.json property is equivalent to the non simplified version self.assertEqual(json_data, conn.to_json(simplified=False)) conn2 = objects.Connection.load(json_data) self.assertEqual(conn.json, conn2.json)
def test_connect_error(self, mock_connect, mock_remove_export): vol = objects.Volume(self.backend_name, status='available', size=10) mock_export = self.backend.driver.create_export mock_export.return_value = None mock_connect.side_effect = exception.NotFound self.assertRaises(exception.NotFound, vol.connect, mock.sentinel.conn_dict) mock_connect.assert_called_once_with(vol, mock.sentinel.conn_dict) self.assertEqual('available', vol.status) self.persistence.set_volume.assert_not_called() mock_remove_export.assert_called_once_with()