Merge "Add Available params in volume backup and snapshot clients"
diff --git a/HACKING.rst b/HACKING.rst
index 480650c..432db7d 100644
--- a/HACKING.rst
+++ b/HACKING.rst
@@ -160,11 +160,17 @@
 
 Negative Tests
 --------------
-TODO: Write the guideline related to negative tests.
+Error handling is an important aspect of API design and usage. Negative
+tests are a way to ensure that an application can gracefully handle
+invalid or unexpected input. However, as a black box integration test
+suite, Tempest is not suitable for handling all negative test cases, as
+the wide variety and complexity of negative tests can lead to long test
+runs and knowledge of internal implementation details. The bulk of
+negative testing should be handled with project function tests. The
+exception to this rule is API tests used for interoperability testing.
 
 Test skips because of Known Bugs
 --------------------------------
-
 If a test is broken because of a bug it is appropriate to skip the test until
 bug has been fixed. You should use the skip_because decorator so that
 Tempest's skip tracking tool can watch the bug status.
diff --git a/tempest/api/compute/servers/test_server_actions.py b/tempest/api/compute/servers/test_server_actions.py
index c65fee4..0d06119 100644
--- a/tempest/api/compute/servers/test_server_actions.py
+++ b/tempest/api/compute/servers/test_server_actions.py
@@ -381,7 +381,8 @@
             'sort_dir': 'asc'
         }
         if CONF.image_feature_enabled.api_v1:
-            params.update({'properties': properties})
+            for key, value in properties.items():
+                params['property-%s' % key] = value
             image_list = glance_client.list_images(
                 detail=True,
                 **params)['images']
diff --git a/tempest/api/identity/base.py b/tempest/api/identity/base.py
index 9187e23..7fee2bc 100644
--- a/tempest/api/identity/base.py
+++ b/tempest/api/identity/base.py
@@ -227,27 +227,24 @@
             name=data_utils.rand_name('test_role'))['role']
         self.roles.append(self.role)
 
-    @staticmethod
-    def _try_wrapper(func, item, **kwargs):
-        try:
-            test_utils.call_and_ignore_notfound_exc(func, item['id'], **kwargs)
-        except Exception:
-            LOG.exception("Unexpected exception occurred in %s deletion. "
-                          "But ignored here." % item['id'])
-
     def teardown_all(self):
         for user in self.users:
-            self._try_wrapper(self.users_client.delete_user, user)
+            test_utils.call_and_ignore_notfound_exc(
+                self.users_client.delete_user, user)
         for tenant in self.tenants:
-            self._try_wrapper(self.projects_client.delete_tenant, tenant)
+            test_utils.call_and_ignore_notfound_exc(
+                self.projects_client.delete_tenant, tenant)
         for project in reversed(self.projects):
-            self._try_wrapper(self.projects_client.delete_project, project)
+            test_utils.call_and_ignore_notfound_exc(
+                self.projects_client.delete_project, project)
         for role in self.roles:
-            self._try_wrapper(self.roles_client.delete_role, role)
+            test_utils.call_and_ignore_notfound_exc(
+                self.roles_client.delete_role, role)
         for domain in self.domains:
-            self._try_wrapper(self.domains_client.update_domain, domain,
-                              enabled=False)
-            self._try_wrapper(self.domains_client.delete_domain, domain)
+            test_utils.call_and_ignore_notfound_exc(
+                self.domains_client.update_domain, domain, enabled=False)
+            test_utils.call_and_ignore_notfound_exc(
+                self.domains_client.delete_domain, domain)
 
 
 class DataGeneratorV2(BaseDataGenerator):
diff --git a/tempest/lib/services/compute/flavors_client.py b/tempest/lib/services/compute/flavors_client.py
index e377c84..0d80a82 100644
--- a/tempest/lib/services/compute/flavors_client.py
+++ b/tempest/lib/services/compute/flavors_client.py
@@ -52,7 +52,7 @@
         """Create a new flavor or instance type.
 
         Available params: see http://developer.openstack.org/
-                              api-ref-compute-v2.1.html#create-flavors
+                              api-ref-compute-v2.1.html#createFlavor
         """
         if kwargs.get('ephemeral'):
             kwargs['OS-FLV-EXT-DATA:ephemeral'] = kwargs.pop('ephemeral')
diff --git a/tempest/services/image/v1/json/images_client.py b/tempest/services/image/v1/json/images_client.py
index 5680668..ed0a676 100644
--- a/tempest/services/image/v1/json/images_client.py
+++ b/tempest/services/image/v1/json/images_client.py
@@ -130,10 +130,6 @@
         if detail:
             url += '/detail'
 
-        properties = kwargs.pop('properties', {})
-        for key, value in six.iteritems(properties):
-            kwargs['property-%s' % key] = value
-
         if kwargs.get('changes_since'):
             kwargs['changes-since'] = kwargs.pop('changes_since')
 
diff --git a/tempest/services/volume/base/base_volumes_client.py b/tempest/services/volume/base/base_volumes_client.py
index a3a4eb6..1bc60a8 100644
--- a/tempest/services/volume/base/base_volumes_client.py
+++ b/tempest/services/volume/base/base_volumes_client.py
@@ -300,7 +300,12 @@
         return rest_client.ResponseBody(resp, body)
 
     def update_volume_image_metadata(self, volume_id, **kwargs):
-        """Update image metadata for the volume."""
+        """Update image metadata for the volume.
+
+        Available params: see http://developer.openstack.org/
+                              api-ref-blockstorage-v2.html
+                              #setVolumeimagemetadata
+        """
         post_body = json.dumps({'os-set_image_metadata': {'metadata': kwargs}})
         url = "volumes/%s/action" % (volume_id)
         resp, body = self.post(url, post_body)