qos: added api sorting/pagination tests for policies

API tests were modified to support admin listing mode. This is needed
for QoS resources because the default policy file does not allow to
create policies, and we should avoid using shared policies due to races.

Related-Bug: #1566514
Depends-On: I8b553ab22846122dde22372f9901e46a5276ee8e
Change-Id: Ie3a66d2a7c05143df3da1c56c8e8a5308d4bae91
diff --git a/neutron/tests/tempest/api/base.py b/neutron/tests/tempest/api/base.py
index 45e12f0..908b8df 100644
--- a/neutron/tests/tempest/api/base.py
+++ b/neutron/tests/tempest/api/base.py
@@ -325,7 +325,8 @@
         return interface
 
     @classmethod
-    def create_qos_policy(cls, name, description, shared, tenant_id=None):
+    def create_qos_policy(cls, name, description=None, shared=False,
+                          tenant_id=None):
         """Wrapper utility that returns a test QoS policy."""
         body = cls.admin_client.create_qos_policy(
             name, description, shared, tenant_id)
@@ -501,6 +502,8 @@
 
     list_kwargs = {}
 
+    list_as_admin = False
+
     def assertSameOrder(self, original, actual):
         # gracefully handle iterators passed
         original = list(original)
@@ -513,8 +516,12 @@
     def plural_name(self):
         return '%ss' % self.resource
 
+    @property
+    def list_client(self):
+        return self.admin_client if self.list_as_admin else self.client
+
     def list_method(self, *args, **kwargs):
-        method = getattr(self.client, 'list_%s' % self.plural_name)
+        method = getattr(self.list_client, 'list_%s' % self.plural_name)
         kwargs.update(self.list_kwargs)
         return method(*args, **kwargs)
 
@@ -617,9 +624,9 @@
                 uri = self.get_bare_url(prev_links['next'])
             else:
                 sort_args.update(self.list_kwargs)
-                uri = self.client.build_uri(
+                uri = self.list_client.build_uri(
                     self.plural_name, limit=1, **sort_args)
-            prev_links, body = self.client.get_uri_with_links(
+            prev_links, body = self.list_client.get_uri_with_links(
                 self.plural_name, uri
             )
             resources_ = self._extract_resources(body)
@@ -637,7 +644,7 @@
         resources2 = []
         for i in range(niterations):
             uri = self.get_bare_url(prev_links['previous'])
-            prev_links, body = self.client.get_uri_with_links(
+            prev_links, body = self.list_client.get_uri_with_links(
                 self.plural_name, uri
             )
             resources_ = self._extract_resources(body)
@@ -676,9 +683,9 @@
                 uri = self.get_bare_url(prev_links['previous'])
             else:
                 pagination_args.update(self.list_kwargs)
-                uri = self.client.build_uri(
+                uri = self.list_client.build_uri(
                     self.plural_name, page_reverse=True, **pagination_args)
-            prev_links, body = self.client.get_uri_with_links(
+            prev_links, body = self.list_client.get_uri_with_links(
                 self.plural_name, uri
             )
             resources_ = self._extract_resources(body)
diff --git a/neutron/tests/tempest/api/test_qos.py b/neutron/tests/tempest/api/test_qos.py
index 2d688df..579859e 100644
--- a/neutron/tests/tempest/api/test_qos.py
+++ b/neutron/tests/tempest/api/test_qos.py
@@ -831,3 +831,58 @@
         rules_ids = [r['id'] for r in rules]
         self.assertIn(rule1['id'], rules_ids)
         self.assertNotIn(rule2['id'], rules_ids)
+
+
+class QosSearchCriteriaTest(base.BaseSearchCriteriaTest,
+                            base.BaseAdminNetworkTest):
+
+    resource = 'policy'
+    plural_name = 'policies'
+
+    # Use unique description to isolate the tests from other QoS tests
+    list_kwargs = {'description': 'search-criteria-test'}
+    list_as_admin = True
+
+    @classmethod
+    @test.requires_ext(extension="qos", service="network")
+    def resource_setup(cls):
+        super(QosSearchCriteriaTest, cls).resource_setup()
+        for name in cls.resource_names:
+            cls.create_qos_policy(
+                name=name, description='search-criteria-test')
+
+    @test.idempotent_id('55fc0103-fdc1-4d34-ab62-c579bb739a91')
+    def test_list_sorts_asc(self):
+        self._test_list_sorts_asc()
+
+    @test.idempotent_id('13e08ac3-bfed-426b-892a-b3b158560c23')
+    def test_list_sorts_desc(self):
+        self._test_list_sorts_desc()
+
+    @test.idempotent_id('719e61cc-e33c-4918-aa4d-1a791e6e0e86')
+    def test_list_pagination(self):
+        self._test_list_pagination()
+
+    @test.idempotent_id('3bd8fb58-c0f8-4954-87fb-f286e1eb096a')
+    def test_list_pagination_with_marker(self):
+        self._test_list_pagination_with_marker()
+
+    @test.idempotent_id('3bad0747-8082-46e9-be4d-c428a842db41')
+    def test_list_pagination_with_href_links(self):
+        self._test_list_pagination_with_href_links()
+
+    @test.idempotent_id('d6a8bacd-d5e8-4ef3-bc55-23ca6998d208')
+    def test_list_pagination_page_reverse_asc(self):
+        self._test_list_pagination_page_reverse_asc()
+
+    @test.idempotent_id('0b9aecdc-2b27-421b-b104-53d24e905ae8')
+    def test_list_pagination_page_reverse_desc(self):
+        self._test_list_pagination_page_reverse_desc()
+
+    @test.idempotent_id('1a3dc257-dafd-4870-8c71-639ae7ddc6ea')
+    def test_list_pagination_page_reverse_with_href_links(self):
+        self._test_list_pagination_page_reverse_with_href_links()
+
+    @test.idempotent_id('40e09b53-4eb8-4526-9181-d438c8005a20')
+    def test_list_no_pagination_limit_0(self):
+        self._test_list_no_pagination_limit_0()
diff --git a/neutron/tests/tempest/services/network/json/network_client.py b/neutron/tests/tempest/services/network/json/network_client.py
index 87a77e5..d9e333c 100644
--- a/neutron/tests/tempest/services/network/json/network_client.py
+++ b/neutron/tests/tempest/services/network/json/network_client.py
@@ -535,15 +535,17 @@
         body = jsonutils.loads(body)
         return service_client.ResponseBody(resp, body)
 
-    def create_qos_policy(self, name, description, shared, tenant_id=None):
+    def create_qos_policy(self, name, description=None, shared=False,
+                          tenant_id=None):
         uri = '%s/qos/policies' % self.uri_prefix
         post_data = {
             'policy': {
                 'name': name,
-                'description': description,
                 'shared': shared
             }
         }
+        if description is not None:
+            post_data['policy']['description'] = description
         if tenant_id is not None:
             post_data['policy']['tenant_id'] = tenant_id
         resp, body = self.post(uri, self.serialize(post_data))