mock_invoke.assert_not_called()
+ @mock.patch.object(library, 'LOG', mock.Mock())
+ def test_create_volume_fail_clean(self):
+ """Test volume creation fail w/o a partial volume being created.
+
+ Test the failed creation of a volume where a partial volume with
+ the name has not been created, thus no cleanup is required.
+ """
+ self.library._get_volume = mock.Mock(
+ side_effect = exception.VolumeNotFound(message=''))
+ self.library._client.create_volume = mock.Mock(
+ side_effect = exception.NetAppDriverException)
+ self.library._client.delete_volume = mock.Mock()
+ fake_volume = copy.deepcopy(get_fake_volume())
+
+ self.assertRaises(exception.NetAppDriverException,
+ self.library.create_volume, fake_volume)
+
+ self.assertTrue(self.library._get_volume.called)
+ self.assertFalse(self.library._client.delete_volume.called)
+ self.assertEqual(1, library.LOG.error.call_count)
+
+ @mock.patch.object(library, 'LOG', mock.Mock())
+ def test_create_volume_fail_dirty(self):
+ """Test volume creation fail where a partial volume has been created.
+
+ Test scenario where the creation of a volume fails and a partial
+ volume is created with the name/id that was supplied by to the
+ original creation call. In this situation the partial volume should
+ be detected and removed.
+ """
+ fake_volume = copy.deepcopy(get_fake_volume())
+ self.library._get_volume = mock.Mock(return_value=fake_volume)
+ self.library._client.list_volume = mock.Mock(return_value=fake_volume)
+ self.library._client.create_volume = mock.Mock(
+ side_effect = exception.NetAppDriverException)
+ self.library._client.delete_volume = mock.Mock()
+
+ self.assertRaises(exception.NetAppDriverException,
+ self.library.create_volume, fake_volume)
+
+ self.assertTrue(self.library._get_volume.called)
+ self.assertTrue(self.library._client.delete_volume.called)
+ self.library._client.delete_volume.assert_called_once_with(
+ fake_volume["id"])
+ self.assertEqual(1, library.LOG.error.call_count)
+
+ @mock.patch.object(library, 'LOG', mock.Mock())
+ def test_create_volume_fail_dirty_fail_delete(self):
+ """Volume creation fail with partial volume deletion fails
+
+ Test scenario where the creation of a volume fails and a partial
+ volume is created with the name/id that was supplied by to the
+ original creation call. The partial volume is detected but when
+ the cleanup deletetion of that fragment volume is attempted it fails.
+ """
+ fake_volume = copy.deepcopy(get_fake_volume())
+ self.library._get_volume = mock.Mock(return_value=fake_volume)
+ self.library._client.list_volume = mock.Mock(return_value=fake_volume)
+ self.library._client.create_volume = mock.Mock(
+ side_effect = exception.NetAppDriverException)
+ self.library._client.delete_volume = mock.Mock(
+ side_effect = exception.NetAppDriverException)
+
+ self.assertRaises(exception.NetAppDriverException,
+ self.library.create_volume, fake_volume)
+
+ self.assertTrue(self.library._get_volume.called)
+ self.assertTrue(self.library._client.delete_volume.called)
+ self.library._client.delete_volume.assert_called_once_with(
+ fake_volume["id"])
+ self.assertEqual(2, library.LOG.error.call_count)
+
@ddt.ddt
class NetAppEseriesLibraryMultiAttachTestCase(test.TestCase):
except exception.NetAppDriverException as e:
with excutils.save_and_reraise_exception():
LOG.error(_LE("Error creating volume. Msg - %s."), e)
+ # There was some kind failure creating the volume, make sure no
+ # partial flawed work exists
+ try:
+ bad_vol = self._get_volume(eseries_volume_label)
+ except Exception:
+ # Swallowing the exception intentionally because this is
+ # emergency cleanup to make sure no intermediate volumes
+ # were left. In this whole error situation, the more
+ # common route would be for no volume to have been created.
+ pass
+ else:
+ # Some sort of partial volume was created despite the
+ # error. Lets clean it out so no partial state volumes or
+ # orphans are left.
+ try:
+ self._client.delete_volume(bad_vol["id"])
+ except exception.NetAppDriverException as e2:
+ LOG.error(_LE(
+ "Error cleaning up failed volume creation. "
+ "Msg - %s."), e2)
return vol