tests: cover port with existing sorting/pagination api tests

This is based on existing network api tests for the features that were
implemented in an extensible way.

Existing list_kwargs is decoupled from the base test class because they
are network test specific. Also removed generic handling for
create_method because each resource has its own signature for creation
methods, so it's easier to implement it per resource than trying to come
up with a generic solution.

Related-Bug: #1566514
Change-Id: I648851b48d0481c97054e1280b60a119b42dfd38
diff --git a/neutron/tests/tempest/api/base.py b/neutron/tests/tempest/api/base.py
index 033ac67..31d6c3a 100644
--- a/neutron/tests/tempest/api/base.py
+++ b/neutron/tests/tempest/api/base.py
@@ -488,26 +488,16 @@
     # This should be defined by subclasses to reflect resource name to test
     resource = None
 
-    # also test a case when there are multiple resources with the same name
+    # NOTE(ihrachys): some names, like those starting with an underscore (_)
+    # are sorted differently depending on whether the plugin implements native
+    # sorting support, or not. So we avoid any such cases here, sticking to
+    # alphanumeric. Also test a case when there are multiple resources with the
+    # same name
     resource_names = ('test1', 'abc1', 'test10', '123test') + ('test1',)
 
-    list_kwargs = {'shared': False}
-
     force_tenant_isolation = True
 
-    @classmethod
-    def resource_setup(cls):
-        super(BaseSearchCriteriaTest, cls).resource_setup()
-
-        cls.create_method = getattr(cls, 'create_%s' % cls.resource)
-
-        # NOTE(ihrachys): some names, like those starting with an underscore
-        # (_) are sorted differently depending on whether the plugin implements
-        # native sorting support, or not. So we avoid any such cases here,
-        # sticking to alphanumeric.
-        for name in cls.resource_names:
-            args = {'%s_name' % cls.resource: name}
-            cls.create_method(**args)
+    list_kwargs = {}
 
     def list_method(self, *args, **kwargs):
         method = getattr(self.client, 'list_%ss' % self.resource)
diff --git a/neutron/tests/tempest/api/test_networks.py b/neutron/tests/tempest/api/test_networks.py
index 4816d79..7b133b1 100644
--- a/neutron/tests/tempest/api/test_networks.py
+++ b/neutron/tests/tempest/api/test_networks.py
@@ -95,6 +95,14 @@
 
     resource = 'network'
 
+    list_kwargs = {'shared': False}
+
+    @classmethod
+    def resource_setup(cls):
+        super(NetworksSearchCriteriaTest, cls).resource_setup()
+        for name in cls.resource_names:
+            cls.create_network(network_name=name)
+
     @test.attr(type='smoke')
     @test.idempotent_id('de27d34a-bd9d-4516-83d6-81ef723f7d0d')
     def test_list_sorts_asc(self):
diff --git a/neutron/tests/tempest/api/test_ports.py b/neutron/tests/tempest/api/test_ports.py
index 7bf4790..a8e8c4d 100644
--- a/neutron/tests/tempest/api/test_ports.py
+++ b/neutron/tests/tempest/api/test_ports.py
@@ -46,3 +46,40 @@
         self.create_port(self.network)
         self.client.update_subnet(s['id'], enable_dhcp=True)
         self.create_port(self.network)
+
+
+class PortsSearchCriteriaTest(base.BaseSearchCriteriaTest):
+
+    resource = 'port'
+
+    @classmethod
+    def resource_setup(cls):
+        super(PortsSearchCriteriaTest, cls).resource_setup()
+        net = cls.create_network(network_name='port-search-test-net')
+        for name in cls.resource_names:
+            cls.create_port(net, name=name)
+
+    @test.attr(type='smoke')
+    @test.idempotent_id('9ab73df4-960a-4ae3-87d3-60992b8d3e2d')
+    def test_list_sorts_asc(self):
+        self._test_list_sorts_asc()
+
+    @test.attr(type='smoke')
+    @test.idempotent_id('b426671d-7270-430f-82ff-8f33eec93010')
+    def test_list_sorts_desc(self):
+        self._test_list_sorts_desc()
+
+    @test.attr(type='smoke')
+    @test.idempotent_id('a202fdc8-6616-45df-b6a0-463932de6f94')
+    def test_list_pagination(self):
+        self._test_list_pagination()
+
+    @test.attr(type='smoke')
+    @test.idempotent_id('f4723b8e-8186-4b9a-bf9e-57519967e048')
+    def test_list_pagination_with_marker(self):
+        self._test_list_pagination_with_marker()
+
+    @test.attr(type='smoke')
+    @test.idempotent_id('3afe7024-77ab-4cfe-824b-0b2bf4217727')
+    def test_list_no_pagination_limit_0(self):
+        self._test_list_no_pagination_limit_0()