diff --git a/cinder/tests/unit/volume/drivers/solidfire/test_solidfire.py b/cinder/tests/unit/volume/drivers/solidfire/test_solidfire.py index c1665e0cf7f..e6e92e4becc 100644 --- a/cinder/tests/unit/volume/drivers/solidfire/test_solidfire.py +++ b/cinder/tests/unit/volume/drivers/solidfire/test_solidfire.py @@ -27,6 +27,8 @@ from cinder import context from cinder import exception from cinder.objects import fields from cinder import test +from cinder.tests.unit import fake_group_snapshot +from cinder.tests.unit import fake_snapshot from cinder.tests.unit.image import fake as fake_image from cinder.tests.unit import utils as test_utils from cinder.volume import configuration as conf @@ -1797,8 +1799,8 @@ class SolidFireVolumeTestCase(test.TestCase): source = {'group_snapshot_id': 'typical_cgsnap_id', 'volume_id': 'typical_vol_id', 'id': 'no_id_4_u'} - name = (self.configuration.sf_volume_prefix - + source.get('group_snapshot_id')) + name = (self.configuration.sf_volume_prefix + + source.get('group_snapshot_id')) with mock.patch.object(sfv, '_get_group_snapshot_by_name', return_value={}) as get,\ @@ -1819,6 +1821,36 @@ class SolidFireVolumeTestCase(test.TestCase): {'status': fields.GroupStatus.AVAILABLE}) group_cg_test.assert_called_once_with(group) + @mock.patch('cinder.volume.utils.is_group_a_cg_snapshot_type') + def test_delete_group_snap_cg(self, group_cg_test): + sfv = solidfire.SolidFireDriver(configuration=self.configuration) + group_cg_test.return_value = True + cgsnapshot = fake_group_snapshot.fake_group_snapshot_obj( + mock.MagicMock()) + snapshots = fake_snapshot.fake_snapshot_obj(mock.MagicMock()) + + with mock.patch.object(sfv, '_delete_cgsnapshot', + return_value={}) as _del_mock: + model_update = sfv.delete_group_snapshot(self.ctxt, + cgsnapshot, snapshots) + _del_mock.assert_called_once_with(self.ctxt, cgsnapshot, snapshots) + self.assertEqual({}, model_update) + + @mock.patch('cinder.volume.utils.is_group_a_cg_snapshot_type') + def test_delete_group_snap(self, group_cg_test): + sfv = solidfire.SolidFireDriver(configuration=self.configuration) + group_cg_test.return_value = False + cgsnapshot = fake_group_snapshot.fake_group_snapshot_obj( + mock.MagicMock()) + snapshots = fake_snapshot.fake_snapshot_obj(mock.MagicMock()) + + with mock.patch.object(sfv, '_delete_cgsnapshot', + return_value={}) as _del_mock: + + self.assertRaises(NotImplementedError, sfv.delete_group_snapshot, + self.ctxt, cgsnapshot, snapshots) + _del_mock.assert_not_called() + @mock.patch('cinder.volume.utils.is_group_a_cg_snapshot_type') def test_create_group_rainy(self, group_cg_test): sfv = solidfire.SolidFireDriver(configuration=self.configuration) diff --git a/cinder/volume/drivers/solidfire.py b/cinder/volume/drivers/solidfire.py index 65f4eaaf200..a18e759b43b 100644 --- a/cinder/volume/drivers/solidfire.py +++ b/cinder/volume/drivers/solidfire.py @@ -1833,6 +1833,13 @@ class SolidFireDriver(san.SanISCSIDriver): self._delete_cgsnapshot_by_name(snap_name) return None, None + def delete_group_snapshot(self, context, group_snapshot, snapshots): + if vol_utils.is_group_a_cg_snapshot_type(group_snapshot): + return self._delete_cgsnapshot(context, group_snapshot, snapshots) + + # Default implementation handles other scenarios. + raise NotImplementedError() + def _delete_consistencygroup(self, ctxt, group, volumes): # TODO(chris_morrell): exception handling and return correctly updated # volume_models. diff --git a/releasenotes/notes/fix-netapp-cg-da4fd6c396e5bedb.yaml b/releasenotes/notes/fix-netapp-cg-da4fd6c396e5bedb.yaml new file mode 100644 index 00000000000..3161337b8ba --- /dev/null +++ b/releasenotes/notes/fix-netapp-cg-da4fd6c396e5bedb.yaml @@ -0,0 +1,4 @@ +--- +fixes: + - Fixes a bug in NetApp SolidFire where the deletion of group snapshots + was failing.