Merge "Explicitly set jobs to ML2/OVS"
diff --git a/neutron_tempest_plugin/scenario/base.py b/neutron_tempest_plugin/scenario/base.py
index 127701c..6910c11 100644
--- a/neutron_tempest_plugin/scenario/base.py
+++ b/neutron_tempest_plugin/scenario/base.py
@@ -207,6 +207,21 @@
         LOG.debug("Created router %s", router['name'])
         return router
 
+    @classmethod
+    def skip_if_no_extension_enabled_in_l3_agents(cls, extension):
+        l3_agents = cls.os_admin.network_client.list_agents(
+                binary='neutron-l3-agent')['agents']
+        if not l3_agents:
+            # the tests should not be skipped when neutron-l3-agent does not
+            # exist (this validation doesn't apply to the setups like
+            # e.g. ML2/OVN)
+            return
+        for agent in l3_agents:
+            if extension in agent['configurations'].get('extensions', []):
+                return
+        raise cls.skipTest("No L3 agent with '%s' extension enabled found." %
+                           extension)
+
     @removals.remove(version='Stein',
                      message="Please use create_floatingip method instead of "
                              "create_and_associate_floatingip.")
diff --git a/neutron_tempest_plugin/scenario/test_floatingip.py b/neutron_tempest_plugin/scenario/test_floatingip.py
index 262f429..5079615 100644
--- a/neutron_tempest_plugin/scenario/test_floatingip.py
+++ b/neutron_tempest_plugin/scenario/test_floatingip.py
@@ -341,14 +341,10 @@
     def resource_setup(cls):
         super(FloatingIPQosTest, cls).resource_setup()
 
-    def skip_if_no_extension_enabled_in_l3_agents(self, extension):
-        l3_agents = self.os_admin.network_client.list_agents(
-                binary='neutron-l3-agent')['agents']
-        for agent in l3_agents:
-            if extension in agent['configurations'].get('extensions', []):
-                return
-        raise self.skipTest("No L3 agent with '%s' extension enabled found." %
-                            extension)
+    @classmethod
+    def setup_clients(cls):
+        super(FloatingIPQosTest, cls).setup_clients()
+        cls.admin_client = cls.os_admin.network_client
 
     @decorators.idempotent_id('5eb48aea-eaba-4c20-8a6f-7740070a0aa3')
     def test_qos(self):
@@ -363,8 +359,12 @@
         self.skip_if_no_extension_enabled_in_l3_agents("fip_qos")
 
         self._test_basic_resources()
+
+        # Create a new QoS policy
         policy_id = self._create_qos_policy()
         ssh_client = self._create_ssh_client()
+
+        # As admin user create a new QoS rules
         self.os_admin.network_client.create_bandwidth_limit_rule(
             policy_id, max_kbps=constants.LIMIT_KILO_BITS_PER_SECOND,
             max_burst_kbps=constants.LIMIT_KILO_BYTES,
@@ -382,6 +382,7 @@
             self.fip['id'])['floatingip']
         self.assertEqual(self.port['id'], fip['port_id'])
 
+        # Associate QoS to the FIP
         self.os_admin.network_client.update_floatingip(
             self.fip['id'],
             qos_policy_id=policy_id)
@@ -390,12 +391,38 @@
             self.fip['id'])['floatingip']
         self.assertEqual(policy_id, fip['qos_policy_id'])
 
+        # Basic test, Check that actual BW while downloading file
+        # is as expected (Original BW)
         common_utils.wait_until_true(lambda: self._check_bw(
             ssh_client,
             self.fip['floating_ip_address'],
             port=self.NC_PORT),
             timeout=120,
-            sleep=1)
+            sleep=1,
+            exception=RuntimeError(
+                'Failed scenario: "Create a QoS policy associated with FIP" '
+                'Actual BW is not as expected!'))
+
+        # As admin user update QoS rules
+        for rule in rules['bandwidth_limit_rules']:
+            self.os_admin.network_client.update_bandwidth_limit_rule(
+                policy_id,
+                rule['id'],
+                max_kbps=constants.LIMIT_KILO_BITS_PER_SECOND * 2,
+                max_burst_kbps=constants.LIMIT_KILO_BITS_PER_SECOND * 2)
+
+        # Check that actual BW while downloading file
+        # is as expected (Update BW)
+        common_utils.wait_until_true(lambda: self._check_bw(
+            ssh_client,
+            self.fip['floating_ip_address'],
+            port=self.NC_PORT,
+            expected_bw=test_qos.QoSTestMixin.LIMIT_BYTES_SEC * 2),
+            timeout=120,
+            sleep=1,
+            exception=RuntimeError(
+                'Failed scenario: "Update QoS policy associated with FIP" '
+                'Actual BW is not as expected!'))
 
 
 class TestFloatingIPUpdate(FloatingIpTestCasesMixin,
diff --git a/neutron_tempest_plugin/scenario/test_port_forwardings.py b/neutron_tempest_plugin/scenario/test_port_forwardings.py
index 6a5d3c9..a3adc03 100644
--- a/neutron_tempest_plugin/scenario/test_port_forwardings.py
+++ b/neutron_tempest_plugin/scenario/test_port_forwardings.py
@@ -31,11 +31,13 @@
 
 class PortForwardingTestJSON(base.BaseTempestTestCase):
 
+    credentials = ['primary', 'admin']
     required_extensions = ['router', 'floating-ip-port-forwarding']
 
     @classmethod
     def resource_setup(cls):
         super(PortForwardingTestJSON, cls).resource_setup()
+        cls.skip_if_no_extension_enabled_in_l3_agents("port_forwarding")
         cls.network = cls.create_network()
         cls.subnet = cls.create_subnet(cls.network)
         cls.router = cls.create_router_by_client()
diff --git a/neutron_tempest_plugin/scenario/test_qos.py b/neutron_tempest_plugin/scenario/test_qos.py
index 77520a7..d00210c 100644
--- a/neutron_tempest_plugin/scenario/test_qos.py
+++ b/neutron_tempest_plugin/scenario/test_qos.py
@@ -137,6 +137,7 @@
                                         name='test-policy',
                                         description='test-qos-policy',
                                         shared=True)
+        self.qos_policies.append(policy['policy'])
         return policy['policy']['id']
 
     def _create_server_by_port(self, port=None):
@@ -189,6 +190,11 @@
     def resource_setup(cls):
         super(QoSTest, cls).resource_setup()
 
+    @classmethod
+    def setup_clients(cls):
+        super(QoSTest, cls).setup_clients()
+        cls.admin_client = cls.os_admin.network_client
+
     @decorators.idempotent_id('00682a0c-b72e-11e8-b81e-8c16450ea513')
     def test_qos_basic_and_update(self):
         """This test covers following scenarios: