Merge "Change the set of jobs in the stable branches"
diff --git a/manila_tempest_tests/services/share/json/shares_client.py b/manila_tempest_tests/services/share/json/shares_client.py
index 3413387..1e3aa6e 100644
--- a/manila_tempest_tests/services/share/json/shares_client.py
+++ b/manila_tempest_tests/services/share/json/shares_client.py
@@ -23,6 +23,7 @@
 from tempest.lib import exceptions
 
 from manila_tempest_tests import share_exceptions
+from manila_tempest_tests import utils
 
 
 CONF = config.CONF
@@ -42,6 +43,9 @@
         self.share_network_id = CONF.share.share_network_id
         self.share_size = CONF.share.share_size
 
+    def _parse_resp(self, body, verify_top_key=None):
+        return utils._parse_resp(body, verify_top_key=verify_top_key)
+
     def create_share(self, share_protocol=None, size=None,
                      name=None, snapshot_id=None, description=None,
                      metadata=None, share_network_id=None,
@@ -446,7 +450,7 @@
     def get_metadata_item(self, share_id, key):
         resp, body = self.get("shares/%s/metadata/%s" % (share_id, key))
         self.expected_success(200, resp.status)
-        return self._parse_resp(body)
+        return self._parse_resp(body, verify_top_key='meta')
 
 ###############
 
diff --git a/manila_tempest_tests/tests/api/test_metadata.py b/manila_tempest_tests/tests/api/test_metadata.py
index c8529a3..d2ae326 100644
--- a/manila_tempest_tests/tests/api/test_metadata.py
+++ b/manila_tempest_tests/tests/api/test_metadata.py
@@ -34,14 +34,15 @@
     def _verify_share_metadata(self, share, md):
 
         # get metadata of share
-        metadata = self.shares_client.get_metadata(share["id"])['metadata']
+        metadata = self.shares_v2_client.get_metadata(share["id"])['metadata']
 
         # verify metadata
         self.assertEqual(md, metadata)
 
         # verify metadata items
         for key in md:
-            get_value = self.shares_client.get_metadata_item(share["id"], key)
+            get_value = self.shares_v2_client.get_metadata_item(share["id"],
+                                                                key)
             self.assertEqual(md[key], get_value[key])
 
     @decorators.idempotent_id('9070249f-6e94-4a38-a036-08debee547c3')
@@ -69,17 +70,18 @@
                                   cleanup_in_class=False)
 
         # set metadata
-        self.shares_client.set_metadata(share["id"], md)
+        self.shares_v2_client.set_metadata(share["id"], md)
 
         # verify metadata
         self._verify_share_metadata(share, md)
 
         # delete metadata
         for key in md.keys():
-            self.shares_client.delete_metadata(share["id"], key)
+            self.shares_v2_client.delete_metadata(share["id"], key)
 
         # verify deletion of metadata
-        get_metadata = self.shares_client.get_metadata(share["id"])['metadata']
+        get_metadata = self.shares_v2_client.get_metadata(share["id"])[
+            'metadata']
         self.assertEmpty(get_metadata)
 
     @decorators.idempotent_id('4e5f8159-62b6-4d5c-f729-d8b1f029d7de')
@@ -93,13 +95,13 @@
                                   cleanup_in_class=False)
 
         # set metadata
-        self.shares_client.set_metadata(share["id"], md1)
+        self.shares_v2_client.set_metadata(share["id"], md1)
 
         # verify metadata
         self._verify_share_metadata(share, md1)
 
         # set metadata again
-        self.shares_client.set_metadata(share["id"], md2)
+        self.shares_v2_client.set_metadata(share["id"], md2)
 
         # verify metadata
         md1.update(md2)
@@ -110,10 +112,11 @@
 
         # delete metadata
         for key in md.keys():
-            self.shares_client.delete_metadata(share["id"], key)
+            self.shares_v2_client.delete_metadata(share["id"], key)
 
         # verify deletion of metadata
-        get_metadata = self.shares_client.get_metadata(share["id"])['metadata']
+        get_metadata = self.shares_v2_client.get_metadata(
+            share["id"])['metadata']
         self.assertEmpty(get_metadata)
 
     @decorators.idempotent_id('2ec70ba5-050b-3b17-c862-c149e53543c0')
@@ -127,13 +130,13 @@
                                   cleanup_in_class=False)
 
         # set metadata
-        self.shares_client.set_metadata(share["id"], md1)
+        self.shares_v2_client.set_metadata(share["id"], md1)
 
         # verify metadata
         self._verify_share_metadata(share, md1)
 
         # set metadata again
-        self.shares_client.set_metadata(share["id"], md2)
+        self.shares_v2_client.set_metadata(share["id"], md2)
 
         # verify metadata
         md = {u"key9": u"value13", u"key10": u"value10",
@@ -142,10 +145,11 @@
 
         # delete metadata
         for key in md.keys():
-            self.shares_client.delete_metadata(share["id"], key)
+            self.shares_v2_client.delete_metadata(share["id"], key)
 
         # verify deletion of metadata
-        get_metadata = self.shares_client.get_metadata(share["id"])['metadata']
+        get_metadata = self.shares_v2_client.get_metadata(
+            share["id"])['metadata']
         self.assertEmpty(get_metadata)
 
     @decorators.idempotent_id('c94851f4-2559-4712-9297-9912db1da7ff')
@@ -160,10 +164,10 @@
                                   cleanup_in_class=False)
 
         # set metadata
-        self.shares_client.set_metadata(share["id"], md1)
+        self.shares_v2_client.set_metadata(share["id"], md1)
 
         # update metadata
-        self.shares_client.update_all_metadata(share["id"], md2)
+        self.shares_v2_client.update_all_metadata(share["id"], md2)
 
         # verify metadata
         self._verify_share_metadata(share, md2)
@@ -173,9 +177,9 @@
     def test_set_metadata_min_size_key(self):
         data = {"k": "value"}
 
-        self.shares_client.set_metadata(self.share["id"], data)
+        self.shares_v2_client.set_metadata(self.share["id"], data)
 
-        body_get = self.shares_client.get_metadata(
+        body_get = self.shares_v2_client.get_metadata(
             self.share["id"])['metadata']
         self.assertEqual(data['k'], body_get.get('k'))
 
@@ -185,9 +189,9 @@
         max_key = "k" * 255
         data = {max_key: "value"}
 
-        self.shares_client.set_metadata(self.share["id"], data)
+        self.shares_v2_client.set_metadata(self.share["id"], data)
 
-        body_get = self.shares_client.get_metadata(
+        body_get = self.shares_v2_client.get_metadata(
             self.share["id"])['metadata']
         self.assertIn(max_key, body_get)
         self.assertEqual(data[max_key], body_get.get(max_key))
@@ -197,9 +201,9 @@
     def test_set_metadata_min_size_value(self):
         data = {"key": "v"}
 
-        self.shares_client.set_metadata(self.share["id"], data)
+        self.shares_v2_client.set_metadata(self.share["id"], data)
 
-        body_get = self.shares_client.get_metadata(
+        body_get = self.shares_v2_client.get_metadata(
             self.share["id"])['metadata']
         self.assertEqual(data['key'], body_get['key'])
 
@@ -209,9 +213,9 @@
         max_value = "v" * 1023
         data = {"key": max_value}
 
-        self.shares_client.set_metadata(self.share["id"], data)
+        self.shares_v2_client.set_metadata(self.share["id"], data)
 
-        body_get = self.shares_client.get_metadata(
+        body_get = self.shares_v2_client.get_metadata(
             self.share["id"])['metadata']
         self.assertEqual(data['key'], body_get['key'])
 
@@ -220,9 +224,9 @@
     def test_upd_metadata_min_size_key(self):
         data = {"k": "value"}
 
-        self.shares_client.update_all_metadata(self.share["id"], data)
+        self.shares_v2_client.update_all_metadata(self.share["id"], data)
 
-        body_get = self.shares_client.get_metadata(
+        body_get = self.shares_v2_client.get_metadata(
             self.share["id"])['metadata']
         self.assertEqual(data, body_get)
 
@@ -232,9 +236,9 @@
         max_key = "k" * 255
         data = {max_key: "value"}
 
-        self.shares_client.update_all_metadata(self.share["id"], data)
+        self.shares_v2_client.update_all_metadata(self.share["id"], data)
 
-        body_get = self.shares_client.get_metadata(
+        body_get = self.shares_v2_client.get_metadata(
             self.share["id"])['metadata']
         self.assertEqual(data, body_get)
 
@@ -243,9 +247,9 @@
     def test_upd_metadata_min_size_value(self):
         data = {"key": "v"}
 
-        self.shares_client.update_all_metadata(self.share["id"], data)
+        self.shares_v2_client.update_all_metadata(self.share["id"], data)
 
-        body_get = self.shares_client.get_metadata(
+        body_get = self.shares_v2_client.get_metadata(
             self.share["id"])['metadata']
         self.assertEqual(data, body_get)
 
@@ -255,8 +259,8 @@
         max_value = "v" * 1023
         data = {"key": max_value}
 
-        self.shares_client.update_all_metadata(self.share["id"], data)
+        self.shares_v2_client.update_all_metadata(self.share["id"], data)
 
-        body_get = self.shares_client.get_metadata(
+        body_get = self.shares_v2_client.get_metadata(
             self.share["id"])['metadata']
         self.assertEqual(data, body_get)
diff --git a/manila_tempest_tests/tests/api/test_metadata_negative.py b/manila_tempest_tests/tests/api/test_metadata_negative.py
index 93a3628..caa34ac 100644
--- a/manila_tempest_tests/tests/api/test_metadata_negative.py
+++ b/manila_tempest_tests/tests/api/test_metadata_negative.py
@@ -61,14 +61,14 @@
     @tc.attr(base.TAG_NEGATIVE, base.TAG_API_WITH_BACKEND)
     def test_try_set_metadata_with_empty_key(self):
         self.assertRaises(lib_exc.BadRequest,
-                          self.shares_client.set_metadata,
+                          self.shares_v2_client.set_metadata,
                           self.share["id"], {"": "value"})
 
     @decorators.idempotent_id('759ca34d-1c87-43f3-8da2-8e1d373049ac')
     @tc.attr(base.TAG_NEGATIVE, base.TAG_API_WITH_BACKEND)
     def test_try_upd_metadata_with_empty_key(self):
         self.assertRaises(lib_exc.BadRequest,
-                          self.shares_client.update_all_metadata,
+                          self.shares_v2_client.update_all_metadata,
                           self.share["id"], {"": "value"})
 
     @decorators.idempotent_id('94c7ebb3-14c3-4ff1-9839-ae3acb318cd0')
@@ -77,7 +77,7 @@
         too_big_key = "x" * 256
         md = {too_big_key: "value"}
         self.assertRaises(lib_exc.BadRequest,
-                          self.shares_client.set_metadata,
+                          self.shares_v2_client.set_metadata,
                           self.share["id"], md)
 
     @decorators.idempotent_id('33ef3047-6ca3-4547-a681-b52314382dcb')
@@ -86,7 +86,7 @@
         too_big_key = "x" * 256
         md = {too_big_key: "value"}
         self.assertRaises(lib_exc.BadRequest,
-                          self.shares_client.update_all_metadata,
+                          self.shares_v2_client.update_all_metadata,
                           self.share["id"], md)
 
     @decorators.idempotent_id('1114970a-1b45-4c56-b20a-e13e1764e3c4')
@@ -95,7 +95,7 @@
         too_big_value = "x" * 1024
         md = {"key": too_big_value}
         self.assertRaises(lib_exc.BadRequest,
-                          self.shares_client.set_metadata,
+                          self.shares_v2_client.set_metadata,
                           self.share["id"], md)
 
     @decorators.idempotent_id('c2eddcf0-cf81-4f9f-b06d-c9165ab8553e')
@@ -104,12 +104,12 @@
         too_big_value = "x" * 1024
         md = {"key": too_big_value}
         self.assertRaises(lib_exc.BadRequest,
-                          self.shares_client.update_all_metadata,
+                          self.shares_v2_client.update_all_metadata,
                           self.share["id"], md)
 
     @decorators.idempotent_id('14df3262-5a2b-4de4-b335-422329b22b07')
     @tc.attr(base.TAG_NEGATIVE, base.TAG_API_WITH_BACKEND)
     def test_try_delete_unexisting_metadata(self):
         self.assertRaises(lib_exc.NotFound,
-                          self.shares_client.delete_metadata,
+                          self.shares_v2_client.delete_metadata,
                           self.share["id"], "wrong_key")
diff --git a/manila_tempest_tests/tests/api/test_scheduler_hints.py b/manila_tempest_tests/tests/api/test_scheduler_hints.py
index 83e5a1a..5012f17 100644
--- a/manila_tempest_tests/tests/api/test_scheduler_hints.py
+++ b/manila_tempest_tests/tests/api/test_scheduler_hints.py
@@ -70,10 +70,10 @@
         self.assertEqual(backend_a, backend_b)
 
         # get metadata of share
-        metadata_a = self.shares_client.get_metadata(
+        metadata_a = self.shares_v2_client.get_metadata(
             self.share_a["id"])['metadata']
         md_a = {"__affinity_same_host": "%s" % share_b["id"]}
-        metadata_b = self.shares_client.get_metadata(
+        metadata_b = self.shares_v2_client.get_metadata(
             share_b["id"])['metadata']
         md_b = {"__affinity_same_host": "%s" % self.share_a["id"]}
 
diff --git a/manila_tempest_tests/utils.py b/manila_tempest_tests/utils.py
index 5ecfb36..29d6096 100644
--- a/manila_tempest_tests/utils.py
+++ b/manila_tempest_tests/utils.py
@@ -14,6 +14,7 @@
 #    under the License.
 
 from collections import OrderedDict
+import json
 import random
 import re
 
@@ -225,3 +226,43 @@
         headers = EXPERIMENTAL
         extra_headers = True
     return headers, extra_headers
+
+
+def _parse_resp(body, verify_top_key=None):
+    try:
+        body = json.loads(body)
+    except ValueError:
+        return body
+
+    # We assume, that if the first value of the deserialized body's
+    # item set is a dict or a list, that we just return the first value
+    # of deserialized body.
+    # Essentially "cutting out" the first placeholder element in a body
+    # that looks like this:
+    #
+    #  {
+    #    "users": [
+    #      ...
+    #    ]
+    #  }
+    try:
+        # Ensure there are not more than one top-level keys
+        # NOTE(freerunner): Ensure, that JSON is not nullable to
+        # to prevent StopIteration Exception
+        if not hasattr(body, "keys") or len(body.keys()) != 1:
+            return body
+        # Just return the "wrapped" element
+        first_key, first_item = tuple(body.items())[0]
+        if isinstance(first_item, (dict, list)):
+            if verify_top_key is not None:
+                assert_msg = (
+                    "The expected top level key is '%(top_key)s' but we "
+                    "found '%(actual_key)s'." % {
+                        'top_key': verify_top_key,
+                        'actual_key': first_key
+                    })
+                assert verify_top_key == first_key, assert_msg
+            return first_item
+    except (ValueError, IndexError):
+        pass
+    return body