Merge "Fix simple typos"
diff --git a/neutron/tests/tempest/api/base.py b/neutron/tests/tempest/api/base.py
index 1d804ee..2d836d6 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_auto_allocated_topology.py b/neutron/tests/tempest/api/test_auto_allocated_topology.py
index 1610c85..2c2dfc6 100644
--- a/neutron/tests/tempest/api/test_auto_allocated_topology.py
+++ b/neutron/tests/tempest/api/test_auto_allocated_topology.py
@@ -87,6 +87,8 @@
 
         network_id1 = topology['id']
         self.assertIsNotNone(network_id1)
+        network = self.client.show_network(topology['id'])['network']
+        self.assertTrue(network['admin_state_up'])
         resources_after1 = self._count_topology_resources()
         # One network, two subnets (v4 and v6) and one router
         self.assertEqual((1, self.num_subnetpools, 1), resources_after1)
diff --git a/neutron/tests/tempest/api/test_qos.py b/neutron/tests/tempest/api/test_qos.py
index 4040c0b..6c6a95a 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/api/test_routers.py b/neutron/tests/tempest/api/test_routers.py
index 65fda89..d0a38aa 100644
--- a/neutron/tests/tempest/api/test_routers.py
+++ b/neutron/tests/tempest/api/test_routers.py
@@ -18,13 +18,14 @@
 from tempest.lib.common.utils import data_utils
 from tempest import test
 
-from neutron.tests.tempest.api import base_routers as base
+from neutron.tests.tempest.api import base
+from neutron.tests.tempest.api import base_routers
 from neutron.tests.tempest import config
 
 CONF = config.CONF
 
 
-class RoutersTest(base.BaseRouterTest):
+class RoutersTest(base_routers.BaseRouterTest):
 
     @classmethod
     @test.requires_ext(extension="router", service="network")
@@ -216,7 +217,7 @@
     _ip_version = 6
 
 
-class DvrRoutersTest(base.BaseRouterTest):
+class DvrRoutersTest(base_routers.BaseRouterTest):
 
     @classmethod
     @test.requires_ext(extension="dvr", service="network")
@@ -244,3 +245,64 @@
         self.assertTrue(show_body['router']['distributed'])
         show_body = self.client.show_router(router['id'])
         self.assertNotIn('distributed', show_body['router'])
+
+
+class RoutersSearchCriteriaTest(base.BaseSearchCriteriaTest):
+
+    resource = 'router'
+
+    @classmethod
+    @test.requires_ext(extension="router", service="network")
+    def skip_checks(cls):
+        super(RoutersSearchCriteriaTest, cls).skip_checks()
+
+    @classmethod
+    def resource_setup(cls):
+        super(RoutersSearchCriteriaTest, cls).resource_setup()
+        for name in cls.resource_names:
+            cls.create_router(router_name=name)
+
+    @test.attr(type='smoke')
+    @test.idempotent_id('03a69efb-90a7-435b-bb5c-3add3612085a')
+    def test_list_sorts_asc(self):
+        self._test_list_sorts_asc()
+
+    @test.attr(type='smoke')
+    @test.idempotent_id('95913d30-ff41-4b17-9f44-5258c651e78c')
+    def test_list_sorts_desc(self):
+        self._test_list_sorts_desc()
+
+    @test.attr(type='smoke')
+    @test.idempotent_id('7f7d40b1-e165-4817-8dc5-02f8e2f0dff3')
+    def test_list_pagination(self):
+        self._test_list_pagination()
+
+    @test.attr(type='smoke')
+    @test.idempotent_id('a5b83e83-3d98-45bb-a2c7-0ee179ffd42c')
+    def test_list_pagination_with_marker(self):
+        self._test_list_pagination_with_marker()
+
+    @test.attr(type='smoke')
+    @test.idempotent_id('40804af8-c25d-45f8-b8a8-b4c70345215d')
+    def test_list_pagination_with_href_links(self):
+        self._test_list_pagination_with_href_links()
+
+    @test.attr(type='smoke')
+    @test.idempotent_id('77b9676c-d3cb-43af-a0e8-a5b8c6099e70')
+    def test_list_pagination_page_reverse_asc(self):
+        self._test_list_pagination_page_reverse_asc()
+
+    @test.attr(type='smoke')
+    @test.idempotent_id('3133a2c5-1bb9-4fc7-833e-cf9a1d160255')
+    def test_list_pagination_page_reverse_desc(self):
+        self._test_list_pagination_page_reverse_desc()
+
+    @test.attr(type='smoke')
+    @test.idempotent_id('8252e2f0-b3da-4738-8e25-f6f8d878a2da')
+    def test_list_pagination_page_reverse_with_href_links(self):
+        self._test_list_pagination_page_reverse_with_href_links()
+
+    @test.attr(type='smoke')
+    @test.idempotent_id('fb102124-20f8-4cb3-8c81-f16f5e41d192')
+    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))