Merge "Add tempest test for l3-ha extension"
diff --git a/neutron/tests/tempest/api/admin/test_floating_ips_admin_actions.py b/neutron/tests/tempest/api/admin/test_floating_ips_admin_actions.py
index 72cacfa..764da2c 100644
--- a/neutron/tests/tempest/api/admin/test_floating_ips_admin_actions.py
+++ b/neutron/tests/tempest/api/admin/test_floating_ips_admin_actions.py
@@ -45,6 +45,9 @@
     @test.attr(type='negative')
     @decorators.idempotent_id('11116ee9-4e99-5b15-b8e1-aa7df92ca589')
     def test_associate_floating_ip_with_port_from_another_tenant(self):
+        if not CONF.identity_feature_enabled.api_v2_admin:
+            # TODO(ihrachys) adopt to v3
+            raise self.skipException('Identity v2 admin not available')
         body = self.admin_client.create_floatingip(
             floating_network_id=self.ext_net_id)
         floating_ip = body['floatingip']
diff --git a/neutron/tests/tempest/api/admin/test_quotas.py b/neutron/tests/tempest/api/admin/test_quotas.py
index 99ef2c3..ee53aa8 100644
--- a/neutron/tests/tempest/api/admin/test_quotas.py
+++ b/neutron/tests/tempest/api/admin/test_quotas.py
@@ -19,6 +19,9 @@
 from tempest import test
 
 from neutron.tests.tempest.api import base
+from neutron.tests.tempest import config
+
+CONF = config.CONF
 
 
 class QuotasTestBase(base.BaseAdminNetworkTest):
@@ -26,6 +29,9 @@
     @classmethod
     @test.requires_ext(extension="quotas", service="network")
     def resource_setup(cls):
+        if not CONF.identity_feature_enabled.api_v2_admin:
+            # TODO(ihrachys) adopt to v3
+            raise cls.skipException('Identity v2 admin not available')
         super(QuotasTestBase, cls).resource_setup()
 
     def _create_tenant(self):
diff --git a/neutron/tests/tempest/api/admin/test_shared_network_extension.py b/neutron/tests/tempest/api/admin/test_shared_network_extension.py
index 042a73e..5557c24 100644
--- a/neutron/tests/tempest/api/admin/test_shared_network_extension.py
+++ b/neutron/tests/tempest/api/admin/test_shared_network_extension.py
@@ -50,6 +50,10 @@
         self.assertNotEmpty(items)
         self.assertTrue(all(n['shared'] == shared for n in items))
 
+    def _list_subnets_ids(self, client, shared):
+        body = client.list_subnets(shared=shared)
+        return [subnet['id'] for subnet in body['subnets']]
+
     @decorators.idempotent_id('6661d219-b96d-4597-ad10-51672353421a')
     def test_filtering_shared_subnets(self):
         # shared subnets need to be tested because their shared status isn't
@@ -59,7 +63,8 @@
         priv = self.create_subnet(reg, client=self.client)
         shared = self.create_subnet(self.shared_network,
                                     client=self.admin_client)
-        self.assertIn(shared, self.client.list_subnets(shared=True)['subnets'])
+        self.assertIn(shared['id'],
+                      self._list_subnets_ids(self.client, shared=True))
         self.assertIn(shared,
             self.admin_client.list_subnets(shared=True)['subnets'])
         self.assertNotIn(priv,
@@ -67,8 +72,8 @@
         self.assertNotIn(priv,
             self.admin_client.list_subnets(shared=True)['subnets'])
         self.assertIn(priv, self.client.list_subnets(shared=False)['subnets'])
-        self.assertIn(priv,
-            self.admin_client.list_subnets(shared=False)['subnets'])
+        self.assertIn(priv['id'],
+                      self._list_subnets_ids(self.admin_client, shared=False))
         self.assertNotIn(shared,
             self.client.list_subnets(shared=False)['subnets'])
         self.assertNotIn(shared,
diff --git a/neutron/tests/tempest/api/test_revisions.py b/neutron/tests/tempest/api/test_revisions.py
index 3db39c6..7a6443c 100644
--- a/neutron/tests/tempest/api/test_revisions.py
+++ b/neutron/tests/tempest/api/test_revisions.py
@@ -313,17 +313,21 @@
 
     @decorators.idempotent_id('afb6486c-41b5-483e-a500-3c506f4deb49')
     @test.requires_ext(extension="router", service="network")
-    @test.requires_ext(extension="dvr", service="network")
+    @test.requires_ext(extension="l3-ha", service="network")
     def test_update_router_extra_attributes_bumps_revision(self):
-        router = self.create_router(router_name='r1')
+        # updates from CVR to CVR-HA are supported on every release,
+        # but only the admin can forcibly create a non-HA router
+        router_args = {'tenant_id': self.client.tenant_id,
+                       'ha': False}
+        router = self.admin_client.create_router('r1', True,
+            **router_args)['router']
         self.addCleanup(self.client.delete_router, router['id'])
         self.assertIn('revision_number', router)
         rev1 = router['revision_number']
         router = self.admin_client.update_router(
             router['id'], admin_state_up=False)['router']
         self.assertGreater(router['revision_number'], rev1)
-        self.admin_client.update_router(router['id'],
-                                        distributed=True)['router']
+        self.admin_client.update_router(router['id'], ha=True)['router']
         updated = self.client.show_router(router['id'])['router']
         self.assertGreater(updated['revision_number'],
                            router['revision_number'])
diff --git a/neutron/tests/tempest/common/ssh.py b/neutron/tests/tempest/common/ssh.py
new file mode 100644
index 0000000..095a12d
--- /dev/null
+++ b/neutron/tests/tempest/common/ssh.py
@@ -0,0 +1,24 @@
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest.lib.common import ssh
+
+from neutron.tests.tempest import config
+
+
+class Client(ssh.Client):
+    def __init__(self, *args, **kwargs):
+        if 'timeout' not in kwargs:
+            kwargs['timeout'] = config.CONF.validation.ssh_timeout
+        super(Client, self).__init__(*args, **kwargs)
diff --git a/neutron/tests/tempest/scenario/base.py b/neutron/tests/tempest/scenario/base.py
index 62feebd..967a45e 100644
--- a/neutron/tests/tempest/scenario/base.py
+++ b/neutron/tests/tempest/scenario/base.py
@@ -17,12 +17,12 @@
 from oslo_log import log
 
 from tempest.common import waiters
-from tempest.lib.common import ssh
 from tempest.lib.common.utils import data_utils
 from tempest.lib.common.utils import test_utils
 from tempest.lib import exceptions as lib_exc
 
 from neutron.tests.tempest.api import base as base_api
+from neutron.tests.tempest.common import ssh
 from neutron.tests.tempest import config
 from neutron.tests.tempest.scenario import constants
 
diff --git a/neutron/tests/tempest/scenario/test_floatingip.py b/neutron/tests/tempest/scenario/test_floatingip.py
index 06f495d..d4ad72a 100644
--- a/neutron/tests/tempest/scenario/test_floatingip.py
+++ b/neutron/tests/tempest/scenario/test_floatingip.py
@@ -15,12 +15,12 @@
 
 import netaddr
 from tempest.common import waiters
-from tempest.lib.common import ssh
 from tempest.lib.common.utils import data_utils
 from tempest.lib import decorators
 from tempest import test
 import testscenarios
 
+from neutron.tests.tempest.common import ssh
 from neutron.tests.tempest import config
 from neutron.tests.tempest.scenario import base
 from neutron.tests.tempest.scenario import constants
diff --git a/neutron/tests/tempest/scenario/test_qos.py b/neutron/tests/tempest/scenario/test_qos.py
index b79faf8..c4d22cd 100644
--- a/neutron/tests/tempest/scenario/test_qos.py
+++ b/neutron/tests/tempest/scenario/test_qos.py
@@ -17,7 +17,6 @@
 import time
 
 from oslo_log import log as logging
-from tempest.lib.common import ssh
 from tempest.lib import decorators
 from tempest.lib import exceptions
 from tempest import test
@@ -26,6 +25,7 @@
 from neutron.common import utils
 from neutron.services.qos import qos_consts
 from neutron.tests.tempest.api import base as base_api
+from neutron.tests.tempest.common import ssh
 from neutron.tests.tempest import config
 from neutron.tests.tempest.scenario import base
 from neutron.tests.tempest.scenario import constants
diff --git a/neutron/tests/tempest/scenario/test_trunk.py b/neutron/tests/tempest/scenario/test_trunk.py
index 112c17b..122068c 100644
--- a/neutron/tests/tempest/scenario/test_trunk.py
+++ b/neutron/tests/tempest/scenario/test_trunk.py
@@ -15,12 +15,12 @@
 import netaddr
 from oslo_log import log as logging
 from tempest.common import waiters
-from tempest.lib.common import ssh
 from tempest.lib.common.utils import data_utils
 from tempest.lib import decorators
 from tempest import test
 
 from neutron.common import utils
+from neutron.tests.tempest.common import ssh
 from neutron.tests.tempest import config
 from neutron.tests.tempest.scenario import base
 from neutron.tests.tempest.scenario import constants