From cb6c11b0a87ba99e01eff52204b2406e8517aeaa Mon Sep 17 00:00:00 2001
From: Huanxuan Ao <huanxuan.ao@easystack.cn>
Date: Tue, 6 Sep 2016 15:15:01 +0800
Subject: [PATCH] Multi REST API calls error handling of "volume unset" command

Support multi REST API calls error handling for "volume unset"
command follow the rule in doc/source/command-errors.rst.
Also add a unit test for testing the error handling

Change-Id: I2de7a7bd5a7a5e39817ed5cf6952abf4afba75e4
---
 .../tests/unit/volume/v2/test_volume.py       | 27 +++++++++++++++++++
 openstackclient/volume/v2/volume.py           | 22 ++++++++++++---
 2 files changed, 45 insertions(+), 4 deletions(-)

diff --git a/openstackclient/tests/unit/volume/v2/test_volume.py b/openstackclient/tests/unit/volume/v2/test_volume.py
index 66f8f74d42..e9f1629e81 100644
--- a/openstackclient/tests/unit/volume/v2/test_volume.py
+++ b/openstackclient/tests/unit/volume/v2/test_volume.py
@@ -964,3 +964,30 @@ class TestVolumeUnset(TestVolume):
 
         self.volumes_mock.delete_image_metadata.assert_called_with(
             self.new_volume.id, parsed_args_unset.image_property)
+
+    def test_volume_unset_image_property_fail(self):
+        self.volumes_mock.delete_image_metadata.side_effect = (
+            exceptions.CommandError())
+        arglist = [
+            '--image-property', 'Alpha',
+            '--property', 'Beta',
+            self.new_volume.id,
+        ]
+        verifylist = [
+            ('image_property', ['Alpha']),
+            ('property', ['Beta']),
+            ('volume', self.new_volume.id),
+        ]
+        parsed_args = self.check_parser(
+            self.cmd_unset, arglist, verifylist)
+
+        try:
+            self.cmd_unset.take_action(parsed_args)
+            self.fail('CommandError should be raised.')
+        except exceptions.CommandError as e:
+            self.assertEqual('One or more of the unset operations failed',
+                             str(e))
+        self.volumes_mock.delete_image_metadata.assert_called_with(
+            self.new_volume.id, parsed_args.image_property)
+        self.volumes_mock.delete_metadata.assert_called_with(
+            self.new_volume.id, parsed_args.property)
diff --git a/openstackclient/volume/v2/volume.py b/openstackclient/volume/v2/volume.py
index bd201e0041..0f85b5d4a0 100644
--- a/openstackclient/volume/v2/volume.py
+++ b/openstackclient/volume/v2/volume.py
@@ -511,9 +511,23 @@ class UnsetVolume(command.Command):
         volume = utils.find_resource(
             volume_client.volumes, parsed_args.volume)
 
+        result = 0
         if parsed_args.property:
-            volume_client.volumes.delete_metadata(
-                volume.id, parsed_args.property)
+            try:
+                volume_client.volumes.delete_metadata(
+                    volume.id, parsed_args.property)
+            except Exception as e:
+                LOG.error(_("Failed to unset volume property: %s"), e)
+                result += 1
+
         if parsed_args.image_property:
-            volume_client.volumes.delete_image_metadata(
-                volume.id, parsed_args.image_property)
+            try:
+                volume_client.volumes.delete_image_metadata(
+                    volume.id, parsed_args.image_property)
+            except Exception as e:
+                LOG.error(_("Failed to unset image property: %s"), e)
+                result += 1
+
+        if result > 0:
+            raise exceptions.CommandError(_("One or more of the "
+                                          "unset operations failed"))