Merge "tempest-api: Skip test if deployment has not enough agents"
diff --git a/neutron/tests/tempest/api/admin/test_external_network_extension.py b/neutron/tests/tempest/api/admin/test_external_network_extension.py
index bcdb0bd..6f6c94d 100644
--- a/neutron/tests/tempest/api/admin/test_external_network_extension.py
+++ b/neutron/tests/tempest/api/admin/test_external_network_extension.py
@@ -27,7 +27,7 @@
     @classmethod
     def resource_setup(cls):
         super(ExternalNetworksRBACTestJSON, cls).resource_setup()
-        cls.client2 = cls.alt_manager.network_client
+        cls.client2 = cls.os_alt.network_client
 
     def _create_network(self, external=True):
         post_body = {'name': data_utils.rand_name('network-')}
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 764da2c..e997380 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
@@ -34,7 +34,7 @@
         super(FloatingIPAdminTestJSON, cls).resource_setup()
         cls.ext_net_id = CONF.network.public_network_id
         cls.floating_ip = cls.create_floatingip(cls.ext_net_id)
-        cls.alt_client = cls.alt_manager.network_client
+        cls.alt_client = cls.os_alt.network_client
         cls.network = cls.create_network()
         cls.subnet = cls.create_subnet(cls.network)
         cls.router = cls.create_router(data_utils.rand_name('router-'),
diff --git a/neutron/tests/tempest/api/admin/test_routers_dvr.py b/neutron/tests/tempest/api/admin/test_routers_dvr.py
index 5fa22cc..8f03cc6 100644
--- a/neutron/tests/tempest/api/admin/test_routers_dvr.py
+++ b/neutron/tests/tempest/api/admin/test_routers_dvr.py
@@ -90,10 +90,12 @@
         name = data_utils.rand_name('router')
         # router needs to be in admin state down in order to be upgraded to DVR
         router = self.admin_client.create_router(name, distributed=False,
+                                                 ha=False,
                                                  admin_state_up=False)
         self.addCleanup(self.admin_client.delete_router,
                         router['router']['id'])
         self.assertFalse(router['router']['distributed'])
+        self.assertFalse(router['router']['ha'])
         router = self.admin_client.update_router(router['router']['id'],
                                                  distributed=True)
         self.assertTrue(router['router']['distributed'])
diff --git a/neutron/tests/tempest/api/admin/test_routers_flavors.py b/neutron/tests/tempest/api/admin/test_routers_flavors.py
index d0c2f28..4153c2d 100644
--- a/neutron/tests/tempest/api/admin/test_routers_flavors.py
+++ b/neutron/tests/tempest/api/admin/test_routers_flavors.py
@@ -11,7 +11,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from neutron_lib import constants
+from neutron_lib.plugins import constants
 from tempest.lib import decorators
 from tempest.lib import exceptions as lib_exc
 import testtools
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 341ba28..458a6f1 100644
--- a/neutron/tests/tempest/api/admin/test_shared_network_extension.py
+++ b/neutron/tests/tempest/api/admin/test_shared_network_extension.py
@@ -179,7 +179,7 @@
     @classmethod
     def resource_setup(cls):
         super(RBACSharedNetworksTest, cls).resource_setup()
-        cls.client2 = cls.alt_manager.network_client
+        cls.client2 = cls.os_alt.network_client
 
     def _make_admin_net_and_subnet_shared_to_tenant_id(self, tenant_id):
         net = self.admin_client.create_network(
diff --git a/neutron/tests/tempest/api/base.py b/neutron/tests/tempest/api/base.py
index 46b2849..d0b8382 100644
--- a/neutron/tests/tempest/api/base.py
+++ b/neutron/tests/tempest/api/base.py
@@ -343,7 +343,7 @@
 
     @classmethod
     def create_admin_router(cls, *args, **kwargs):
-        return cls._create_router_with_client(cls.admin_manager.network_client,
+        return cls._create_router_with_client(cls.os_admin.network_client,
                                               *args, **kwargs)
 
     @classmethod
diff --git a/neutron/tests/tempest/api/test_qos.py b/neutron/tests/tempest/api/test_qos.py
index 93f96b7..f35abd8 100644
--- a/neutron/tests/tempest/api/test_qos.py
+++ b/neutron/tests/tempest/api/test_qos.py
@@ -156,29 +156,21 @@
 
     def _test_list_rule_types(self, client):
         # List supported rule types
-        # TODO(QoS): since in gate we run both ovs and linuxbridge ml2 drivers,
-        # and since Linux Bridge ml2 driver does not have QoS support yet, ml2
-        # plugin reports no rule types are supported. Once linuxbridge will
-        # receive support for QoS, the list of expected rule types will change.
+        # Since returned rule types depends on loaded backend drivers this test
+        # is checking only if returned keys are same as expected keys
         #
         # In theory, we could make the test conditional on which ml2 drivers
         # are enabled in gate (or more specifically, on which supported qos
         # rules are claimed by core plugin), but that option doesn't seem to be
         # available through tempest.lib framework
-        expected_rule_types = []
-        expected_rule_details = ['type']
+        expected_rule_keys = ['type']
 
         rule_types = client.list_qos_rule_types()
         actual_list_rule_types = rule_types['rule_types']
-        actual_rule_types = [rule['type'] for rule in actual_list_rule_types]
 
         # Verify that only required fields present in rule details
         for rule in actual_list_rule_types:
-            self.assertEqual(tuple(rule.keys()), tuple(expected_rule_details))
-
-        # Verify if expected rules are present in the actual rules list
-        for rule in expected_rule_types:
-            self.assertIn(rule, actual_rule_types)
+            self.assertEqual(tuple(expected_rule_keys), tuple(rule.keys()))
 
     def _disassociate_network(self, client, network_id):
         updated_network = client.update_network(network_id,
@@ -569,7 +561,7 @@
     @classmethod
     def resource_setup(cls):
         super(RbacSharedQosPoliciesTest, cls).resource_setup()
-        cls.client2 = cls.alt_manager.network_client
+        cls.client2 = cls.os_alt.network_client
 
     def _create_qos_policy(self, tenant_id=None):
         args = {'name': data_utils.rand_name('test-policy'),
diff --git a/neutron/tests/tempest/api/test_routers.py b/neutron/tests/tempest/api/test_routers.py
index 4275729..8572196 100644
--- a/neutron/tests/tempest/api/test_routers.py
+++ b/neutron/tests/tempest/api/test_routers.py
@@ -242,8 +242,15 @@
 
     @decorators.idempotent_id('644d7a4a-01a1-4b68-bb8d-0c0042cb1729')
     def test_convert_centralized_router(self):
-        router = self._create_router(data_utils.rand_name('router'))
-        self.assertNotIn('distributed', router)
+        router_args = {'tenant_id': self.client.tenant_id,
+                       'distributed': False, 'ha': False}
+        router = self.admin_client.create_router(
+            data_utils.rand_name('router'), admin_state_up=False,
+            **router_args)['router']
+        self.addCleanup(self.admin_client.delete_router,
+                        router['id'])
+        self.assertFalse(router['distributed'])
+        self.assertFalse(router['ha'])
         update_body = self.admin_client.update_router(router['id'],
                                                       distributed=True)
         self.assertTrue(update_body['router']['distributed'])
@@ -251,6 +258,7 @@
         self.assertTrue(show_body['router']['distributed'])
         show_body = self.client.show_router(router['id'])
         self.assertNotIn('distributed', show_body['router'])
+        self.assertNotIn('ha', show_body['router'])
 
 
 class HaRoutersTest(base_routers.BaseRouterTest):
diff --git a/neutron/tests/tempest/api/test_tag.py b/neutron/tests/tempest/api/test_tag.py
index dc78e60..f819671 100644
--- a/neutron/tests/tempest/api/test_tag.py
+++ b/neutron/tests/tempest/api/test_tag.py
@@ -177,7 +177,7 @@
     @classmethod
     def setup_clients(cls):
         super(TagFilterTestJSON, cls).setup_clients()
-        cls.client = cls.alt_manager.network_client
+        cls.client = cls.os_alt.network_client
 
     def _assertEqualResources(self, expected, res):
         actual = [n['name'] for n in res if n['name'].startswith('tag-res')]
diff --git a/neutron/tests/tempest/api/test_trunk.py b/neutron/tests/tempest/api/test_trunk.py
index 3e035a0..aef82e7 100644
--- a/neutron/tests/tempest/api/test_trunk.py
+++ b/neutron/tests/tempest/api/test_trunk.py
@@ -108,18 +108,18 @@
     @decorators.idempotent_id('4ce46c22-a2b6-4659-bc5a-0ef2463cab32')
     def test_create_update_trunk(self):
         trunk = self._create_trunk_with_network_and_parent(None)
-        self.assertEqual(1, trunk['trunk']['revision_number'])
+        rev = trunk['trunk']['revision_number']
         trunk_id = trunk['trunk']['id']
         res = self._show_trunk(trunk_id)
         self.assertTrue(res['trunk']['admin_state_up'])
-        self.assertEqual(1, res['trunk']['revision_number'])
+        self.assertEqual(rev, res['trunk']['revision_number'])
         self.assertEqual("", res['trunk']['name'])
         self.assertEqual("", res['trunk']['description'])
         res = self.client.update_trunk(
             trunk_id, name='foo', admin_state_up=False)
         self.assertFalse(res['trunk']['admin_state_up'])
         self.assertEqual("foo", res['trunk']['name'])
-        self.assertGreater(res['trunk']['revision_number'], 1)
+        self.assertGreater(res['trunk']['revision_number'], rev)
         # enable the trunk so that it can be managed
         self.client.update_trunk(trunk_id, admin_state_up=True)
 
diff --git a/neutron/tests/tempest/scenario/base.py b/neutron/tests/tempest/scenario/base.py
index 15a722a..5ccbd1c 100644
--- a/neutron/tests/tempest/scenario/base.py
+++ b/neutron/tests/tempest/scenario/base.py
@@ -41,7 +41,7 @@
     @classmethod
     def resource_cleanup(cls):
         for keypair in cls.keypairs:
-            cls.manager.keypairs_client.delete_keypair(
+            cls.os_primary.keypairs_client.delete_keypair(
                 keypair_name=keypair['name'])
 
         super(BaseTempestTestCase, cls).resource_cleanup()
@@ -89,7 +89,7 @@
 
     @classmethod
     def create_keypair(cls, client=None):
-        client = client or cls.manager.keypairs_client
+        client = client or cls.os_primary.keypairs_client
         name = data_utils.rand_name('keypair-test')
         body = client.create_keypair(name=name)
         cls.keypairs.append(body['keypair'])
@@ -97,7 +97,7 @@
 
     @classmethod
     def create_secgroup_rules(cls, rule_list, secgroup_id=None):
-        client = cls.manager.network_client
+        client = cls.os_primary.network_client
         if not secgroup_id:
             sgs = client.list_security_groups()['security_groups']
             for sg in sgs:
diff --git a/neutron/tests/tempest/scenario/test_dvr.py b/neutron/tests/tempest/scenario/test_dvr.py
index 049aa8f..0b03276 100644
--- a/neutron/tests/tempest/scenario/test_dvr.py
+++ b/neutron/tests/tempest/scenario/test_dvr.py
@@ -40,7 +40,7 @@
         port_id = self.client.list_ports(
             network_id=network_id,
             device_owner=constants.DEVICE_OWNER_ROUTER_SNAT)['ports'][0]['id']
-        self.admin_manager.network_client.update_port(
+        self.os_admin.network_client.update_port(
             port_id, admin_state_up=False)
 
 
diff --git a/neutron/tests/tempest/scenario/test_floatingip.py b/neutron/tests/tempest/scenario/test_floatingip.py
index 1ccb6ac..fe6ce3e 100644
--- a/neutron/tests/tempest/scenario/test_floatingip.py
+++ b/neutron/tests/tempest/scenario/test_floatingip.py
@@ -19,6 +19,7 @@
 from tempest.lib import decorators
 from tempest import test
 import testscenarios
+from testscenarios.scenarios import multiply_scenarios
 
 from neutron.tests.tempest.common import ssh
 from neutron.tests.tempest import config
@@ -45,7 +46,7 @@
         cls.create_router_interface(cls.router['id'], cls.subnet['id'])
         cls.keypair = cls.create_keypair()
 
-        cls.secgroup = cls.manager.network_client.create_security_group(
+        cls.secgroup = cls.os_primary.network_client.create_security_group(
             name=data_utils.rand_name('secgroup-'))['security_group']
         cls.security_groups.append(cls.secgroup)
         cls.create_loginable_secgroup_rule(secgroup_id=cls.secgroup['id'])
@@ -77,18 +78,34 @@
             image_ref=CONF.compute.image_ref,
             key_name=self.keypair['name'],
             networks=[{'port': port['id']}])['server']
-        waiters.wait_for_server_status(self.manager.servers_client,
+        waiters.wait_for_server_status(self.os_primary.servers_client,
                                        server['id'],
                                        constants.SERVER_STATUS_ACTIVE)
         return {'port': port, 'fip': fip, 'server': server}
 
     def _test_east_west(self):
+        # The proxy VM is used to control the source VM when it doesn't
+        # have a floating-ip.
+        if self.src_has_fip:
+            proxy = None
+            proxy_client = None
+        else:
+            proxy = self._create_server()
+            proxy_client = ssh.Client(proxy['fip']['floating_ip_address'],
+                                      CONF.validation.image_ssh_user,
+                                      pkey=self.keypair['private_key'])
+
         # Source VM
-        server1 = self._create_server()
-        server1_ip = server1['fip']['floating_ip_address']
-        ssh_client = ssh.Client(server1_ip,
+        if self.src_has_fip:
+            src_server = self._create_server()
+            src_server_ip = src_server['fip']['floating_ip_address']
+        else:
+            src_server = self._create_server(create_floating_ip=False)
+            src_server_ip = src_server['port']['fixed_ips'][0]['ip_address']
+        ssh_client = ssh.Client(src_server_ip,
                                 CONF.validation.image_ssh_user,
-                                pkey=self.keypair['private_key'])
+                                pkey=self.keypair['private_key'],
+                                proxy_client=proxy_client)
 
         # Destination VM
         if self.dest_has_fip:
@@ -107,11 +124,13 @@
 
 class FloatingIpSameNetwork(FloatingIpTestCasesMixin,
                             base.BaseTempestTestCase):
-    # REVISIT(yamamoto): 'SRC without FIP' case is possible?
-    scenarios = [
+    scenarios = multiply_scenarios([
+        ('SRC with FIP', dict(src_has_fip=True)),
+        ('SRC without FIP', dict(src_has_fip=False)),
+    ], [
         ('DEST with FIP', dict(dest_has_fip=True)),
         ('DEST without FIP', dict(dest_has_fip=False)),
-    ]
+    ])
 
     same_network = True
 
@@ -122,11 +141,13 @@
 
 class FloatingIpSeparateNetwork(FloatingIpTestCasesMixin,
                                 base.BaseTempestTestCase):
-    # REVISIT(yamamoto): 'SRC without FIP' case is possible?
-    scenarios = [
+    scenarios = multiply_scenarios([
+        ('SRC with FIP', dict(src_has_fip=True)),
+        ('SRC without FIP', dict(src_has_fip=False)),
+    ], [
         ('DEST with FIP', dict(dest_has_fip=True)),
         ('DEST without FIP', dict(dest_has_fip=False)),
-    ]
+    ])
 
     same_network = False
 
diff --git a/neutron/tests/tempest/scenario/test_migration.py b/neutron/tests/tempest/scenario/test_migration.py
index db89716..4951c61 100644
--- a/neutron/tests/tempest/scenario/test_migration.py
+++ b/neutron/tests/tempest/scenario/test_migration.py
@@ -32,7 +32,7 @@
         super(NetworkMigrationTestBase, cls).skip_checks()
 
     def _check_update(self, router, is_dvr, is_ha):
-        router = self.admin_manager.network_client.show_router(router['id'])
+        router = self.os_admin.network_client.show_router(router['id'])
         self.assertEqual(is_dvr, router['router']['distributed'])
         self.assertEqual(is_ha, router['router']['ha'])
 
@@ -44,13 +44,13 @@
         self.setup_network_and_server(router=router)
         self._check_connectivity()
 
-        self.admin_manager.network_client.update_router(
+        self.os_admin.network_client.update_router(
             router_id=router['id'], admin_state_up=False)
-        self.admin_manager.network_client.update_router(
+        self.os_admin.network_client.update_router(
             router_id=router['id'], distributed=after_dvr, ha=after_ha)
         self._check_update(router, after_dvr, after_ha)
 
-        self.admin_manager.network_client.update_router(
+        self.os_admin.network_client.update_router(
             router_id=router['id'], admin_state_up=True)
         self._check_connectivity()
 
diff --git a/neutron/tests/tempest/scenario/test_trunk.py b/neutron/tests/tempest/scenario/test_trunk.py
index 8ad9078..5d775ef 100644
--- a/neutron/tests/tempest/scenario/test_trunk.py
+++ b/neutron/tests/tempest/scenario/test_trunk.py
@@ -55,7 +55,7 @@
         router = cls.create_router_by_client()
         cls.create_router_interface(router['id'], cls.subnet['id'])
         cls.keypair = cls.create_keypair()
-        cls.secgroup = cls.manager.network_client.create_security_group(
+        cls.secgroup = cls.os_primary.network_client.create_security_group(
             name=data_utils.rand_name('secgroup-'))
         cls.security_groups.append(cls.secgroup['security_group'])
         cls.create_loginable_secgroup_rule(