From 343c00ae871a6abf2293f0049802297f5c3f8b02 Mon Sep 17 00:00:00 2001 From: Tom Swanson Date: Wed, 12 Apr 2017 13:38:53 -0500 Subject: [PATCH] Dell EMC SC: Raise on _init_volume create_snapshot failure If init_volume fails to activate a volume when creating a snapshot we now raise an exception with the message 'Unable to create snapshot from empty volume.' Change-Id: I6c6e0ce990f1c251ca1332f5d131e08275b55f03 Closes-Bug: #1682194 --- .../unit/volume/drivers/dell/test_dellscapi.py | 18 ++++++++++++++++++ .../drivers/dell/dell_storagecenter_api.py | 17 +++++++++++++++-- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/cinder/tests/unit/volume/drivers/dell/test_dellscapi.py b/cinder/tests/unit/volume/drivers/dell/test_dellscapi.py index 05111043329..68f638cbdad 100644 --- a/cinder/tests/unit/volume/drivers/dell/test_dellscapi.py +++ b/cinder/tests/unit/volume/drivers/dell/test_dellscapi.py @@ -4291,17 +4291,21 @@ class DellSCSanAPITestCase(test.TestCase): return_value=RPLAY) @mock.patch.object(dell_storagecenter_api.StorageCenterApi, '_init_volume') + @mock.patch.object(dell_storagecenter_api.StorageCenterApi, + 'get_volume') @mock.patch.object(dell_storagecenter_api.HttpClient, 'post', return_value=RESPONSE_200) def test_create_replay_inact_vol(self, mock_post, + mock_get_volume, mock_init_volume, mock_first_result, mock_close_connection, mock_open_connection, mock_init): # Test case where the specified volume is inactive + mock_get_volume.return_value = self.VOLUME res = self.scapi.create_replay(self.INACTIVE_VOLUME, 'Test Replay', 60) @@ -4310,6 +4314,20 @@ class DellSCSanAPITestCase(test.TestCase): self.assertTrue(mock_first_result.called) self.assertEqual(self.RPLAY, res, 'Unexpected ScReplay') + @mock.patch.object(dell_storagecenter_api.StorageCenterApi, + '_init_volume') + @mock.patch.object(dell_storagecenter_api.StorageCenterApi, + 'get_volume') + def test_create_replay_inact_vol_init_fail( + self, mock_get_volume, mock_init_volume, mock_close_connection, + mock_open_connection, mock_init): + # Test case where the specified volume is inactive + mock_get_volume.return_value = self.INACTIVE_VOLUME + self.assertRaises(exception.VolumeBackendAPIException, + self.scapi.create_replay, + self.INACTIVE_VOLUME, 'Test Replay', 60) + mock_init_volume.assert_called_once_with(self.INACTIVE_VOLUME) + @mock.patch.object(dell_storagecenter_api.StorageCenterApi, '_first_result', return_value=RPLAY) diff --git a/cinder/volume/drivers/dell/dell_storagecenter_api.py b/cinder/volume/drivers/dell/dell_storagecenter_api.py index 2d0f7d4bd1a..83ad7c94db4 100644 --- a/cinder/volume/drivers/dell/dell_storagecenter_api.py +++ b/cinder/volume/drivers/dell/dell_storagecenter_api.py @@ -1983,6 +1983,12 @@ class StorageCenterApi(object): storageusage = self._get_json(r) return storageusage + def _is_active(self, scvolume): + if (scvolume.get('active') is not True or + scvolume.get('replayAllowed') is not True): + return False + return True + def create_replay(self, scvolume, replayid, expire): """Takes a snapshot of a volume. @@ -1999,12 +2005,19 @@ class StorageCenterApi(object): cloning a volume we will snap it right before creating the clone. :returns: The Dell replay object or None. + :raises VolumeBackendAPIException: On failure to intialize volume. """ replay = None if scvolume is not None: - if (scvolume.get('active') is not True or - scvolume.get('replayAllowed') is not True): + if not self._is_active(scvolume): self._init_volume(scvolume) + scvolume = self.get_volume(self._get_id(scvolume)) + if not self._is_active(scvolume): + raise exception.VolumeBackendAPIException( + message=( + _('Unable to create snapshot from empty volume.' + ' %s') % scvolume['name'])) + # We have a volume and it is initialized. payload = {} payload['description'] = replayid payload['expireTime'] = expire