Merge "Add assumption for dvr tests"
diff --git a/.zuul.yaml b/.zuul.yaml
index 1d7e323..32e565c 100644
--- a/.zuul.yaml
+++ b/.zuul.yaml
@@ -1,4 +1,86 @@
 - job:
+    name: neutron-tempest-plugin-scenario
+    parent: devstack-tempest
+    abstract: true
+    description: |
+        Perform setup common to all tempest scenario test jobs.
+    roles:
+      - zuul: openstack-dev/devstack
+    required-projects:
+      - openstack-infra/devstack-gate
+      - openstack/neutron
+      - openstack/neutron-tempest-plugin
+      - openstack/tempest
+    vars:
+      tempest_test_regex: ^neutron_tempest_plugin\.scenario
+      tempest_concurrency: 4
+      tox_envlist: all
+      devstack_localrc:
+          TEMPEST_PLUGINS: /opt/stack/neutron-tempest-plugin
+          PHYSICAL_NETWORK: default
+          DOWNLOAD_DEFAULT_IMAGES: false
+          IMAGE_URLS: "http://cloud-images.ubuntu.com/releases/16.04/release-20170113/ubuntu-16.04-server-cloudimg-amd64-disk1.img,"
+          DEFAULT_INSTANCE_TYPE: ds512M
+          DEFAULT_INSTANCE_USER: ubuntu
+          BUILD_TIMEOUT: 784
+      devstack_plugins:
+        neutron: git://git.openstack.org/openstack/neutron.git
+        neutron-tempest-plugin: git://git.openstack.org/openstack/neutron-tempest-plugin.git
+      devstack_services:
+        cinder: true
+        tempest: true
+        neutron-dns: true
+        neutron-qos: true
+        neutron-segments: true
+        neutron-trunk: true
+      devstack_local_conf:
+        post-config:
+          $NEUTRON_CONF:
+            QUOTAS:
+              quota_router: 100
+              quota_floatingip: 500
+              quota_security_group: 100
+              quota_security_group_rule: 1000
+          # NOTE(slaweq): We can get rid of this hardcoded absolute path when
+          # devstack-tempest job will be switched to use lib/neutron instead of
+          # lib/neutron-legacy
+          "/$NEUTRON_CORE_PLUGIN_CONF":
+            ml2:
+              type_drivers: flat,vlan,local,vxlan
+            ml2_type_vlan:
+              network_vlan_ranges: foo:1:10
+            ml2_type_vxlan:
+              vni_ranges: 1:2000
+          $NEUTRON_L3_CONF:
+            agent:
+              availability_zone: nova
+          $NEUTRON_DHCP_CONF:
+            agent:
+              availability_zone: nova
+          "/etc/neutron/api-paste.ini":
+            "composite:neutronapi_v2_0":
+              use: "call:neutron.auth:pipeline_factory"
+              noauth: "cors request_id catch_errors osprofiler extensions neutronapiapp_v2_0"
+              keystone: "cors request_id catch_errors osprofiler authtoken keystonecontext extensions neutronapiapp_v2_0"
+        test-config:
+          $TEMPEST_CONFIG:
+            neutron_plugin_options:
+              provider_vlans: foo,
+              agent_availability_zone: nova
+              image_is_advanced: true
+              available_type_drivers: flat,vlan,local,vxlan
+    irrelevant-files:
+      - ^(test-|)requirements.txt$
+      - ^releasenotes/.*$
+      - ^doc/.*$
+      - ^setup.cfg$
+      - ^.*\.rst$
+      - ^neutron/locale/.*$
+      - ^neutron/tests/unit/.*$
+      - ^tools/.*$
+      - ^tox.ini$
+
+- job:
     name: neutron-tempest-plugin-api
     parent: legacy-dsvm-base
     run: playbooks/neutron-tempest-plugin-api/run.yaml
@@ -22,25 +104,19 @@
 
 - job:
     name: neutron-tempest-plugin-scenario-linuxbridge
-    parent: legacy-dsvm-base
-    run: playbooks/neutron-tempest-plugin-scenario-linuxbridge/run.yaml
-    post-run: playbooks/neutron-tempest-plugin-scenario-linuxbridge/post.yaml
+    parent: neutron-tempest-plugin-scenario
     timeout: 10000
-    required-projects:
-      - openstack-infra/devstack-gate
-      - openstack/neutron
-      - openstack/neutron-tempest-plugin
-      - openstack/tempest
-    irrelevant-files:
-      - ^(test-|)requirements.txt$
-      - ^releasenotes/.*$
-      - ^doc/.*$
-      - ^setup.cfg$
-      - ^.*\.rst$
-      - ^neutron/locale/.*$
-      - ^neutron/tests/unit/.*$
-      - ^tools/.*$
-      - ^tox.ini$
+    vars:
+      devstack_localrc:
+          NETWORK_API_EXTENSIONS: "address-scope,agent,allowed-address-pairs,auto-allocated-topology,availability_zone,binding,default-subnetpools,dhcp_agent_scheduler,dns-integration,ext-gw-mode,external-net,extra_dhcp_opt,extraroute,flavors,ip-substring-filtering,l3-flavors,l3-ha,l3_agent_scheduler,logging,metering,multi-provider,net-mtu,net-mtu-writable,network-ip-availability,network_availability_zone,pagination,port-security,project-id,provider,qos,quotas,quota_details,rbac-policies,router,router_availability_zone,security-group,port-security-groups-filtering,segment,service-type,sorting,standard-attr-description,standard-attr-revisions,standard-attr-timestamp,standard-attr-tag,subnet_allocation,tag,tag-ext,trunk,trunk-details"
+          Q_AGENT: linuxbridge
+      devstack_local_conf:
+        post-config:
+          $NEUTRON_CONF:
+            DEFAULT:
+              enable_dvr: false
+            AGENT:
+              debug_iptables_rules: true
 
 - job:
     name: neutron-tempest-plugin-dvr-multinode-scenario
@@ -68,32 +144,24 @@
 
 - job:
     name: neutron-tempest-plugin-designate-scenario
-    parent: devstack-tempest
+    parent: neutron-tempest-plugin-scenario
     description: Neutron designate integration scenario
     required-projects:
       - openstack/designate
       - openstack/designate-dashboard
       - openstack/designate-tempest-plugin
-      - openstack/neutron
-      - openstack/neutron-tempest-plugin
-      - openstack/tempest
     timeout: 3600
-    roles:
-      - zuul: openstack-dev/devstack
     vars:
       devstack_localrc:
+        TEMPEST_PLUGINS: '"/opt/stack/designate-tempest-plugin
+                           /opt/stack/neutron-tempest-plugin"'
         DESIGNATE_BACKEND_DRIVER: bind9
       devstack_plugins:
         designate: git://git.openstack.org/openstack/designate.git
-        neutron: git://git.openstack.org/openstack/neutron.git
-        neutron-tempest-plugin: git://git.openstack.org/openstack/neutron-tempest-plugin.git
       devstack_services:
         cinder: false
         designate: true
-        neutron-dns: true
-        tempest: true
       tempest_test_regex: ^neutron_tempest_plugin\.scenario\.test_dns_integration
-      tox_envlist: all-plugin
     irrelevant-files:
       - ^(test-|)requirements.txt$
       - ^releasenotes/.*$
diff --git a/neutron_tempest_plugin/api/admin/test_shared_network_extension.py b/neutron_tempest_plugin/api/admin/test_shared_network_extension.py
index 876bd32..16375ec 100644
--- a/neutron_tempest_plugin/api/admin/test_shared_network_extension.py
+++ b/neutron_tempest_plugin/api/admin/test_shared_network_extension.py
@@ -263,25 +263,9 @@
         with testtools.ExpectedException(lib_exc.Conflict):
             self.admin_client.delete_rbac_policy(res['policy']['id'])
 
-        # a wildcard policy should allow the specific policy to be deleted
-        # since it allows the remaining port
-        wild = self.admin_client.create_rbac_policy(
-            object_type='network', object_id=res['network']['id'],
-            action='access_as_shared', target_tenant='*')['rbac_policy']
-        self.admin_client.delete_rbac_policy(res['policy']['id'])
-
-        # now that wildcard is the only remaining, it should be subjected to
-        # to the same restriction
-        with testtools.ExpectedException(lib_exc.Conflict):
-            self.admin_client.delete_rbac_policy(wild['id'])
-        # similarly, we can't update the policy to a different tenant
-        with testtools.ExpectedException(lib_exc.Conflict):
-            self.admin_client.update_rbac_policy(
-                wild['id'], target_tenant=self.client2.tenant_id)
-
         self.client.delete_port(port['id'])
         # anchor is gone, delete should pass
-        self.admin_client.delete_rbac_policy(wild['id'])
+        self.admin_client.delete_rbac_policy(res['policy']['id'])
 
     @decorators.idempotent_id('34d627da-a732-68c0-2e1a-bc4a19246698')
     def test_delete_self_share_rule(self):
diff --git a/neutron_tempest_plugin/scenario/constants.py b/neutron_tempest_plugin/scenario/constants.py
index 258c587..ddd45ff 100644
--- a/neutron_tempest_plugin/scenario/constants.py
+++ b/neutron_tempest_plugin/scenario/constants.py
@@ -15,4 +15,5 @@
 SERVER_STATUS_ACTIVE = 'ACTIVE'
 DEFAULT_SECURITY_GROUP = 'default'
 LIMIT_KILO_BITS_PER_SECOND = 1000
+LIMIT_KILO_BYTES = 1000
 SOCKET_CONNECT_TIMEOUT = 60
diff --git a/neutron_tempest_plugin/scenario/test_floatingip.py b/neutron_tempest_plugin/scenario/test_floatingip.py
index b253890..94ce482 100644
--- a/neutron_tempest_plugin/scenario/test_floatingip.py
+++ b/neutron_tempest_plugin/scenario/test_floatingip.py
@@ -14,6 +14,8 @@
 #    under the License.
 
 import netaddr
+from neutron_lib import constants as lib_constants
+from neutron_lib.services.qos import constants as qos_consts
 from tempest.common import utils
 from tempest.common import waiters
 from tempest.lib.common.utils import data_utils
@@ -21,12 +23,13 @@
 import testscenarios
 from testscenarios.scenarios import multiply_scenarios
 
-from neutron_lib import constants as lib_constants
+from neutron_tempest_plugin.api import base as base_api
 from neutron_tempest_plugin.common import ssh
 from neutron_tempest_plugin.common import utils as common_utils
 from neutron_tempest_plugin import config
 from neutron_tempest_plugin.scenario import base
 from neutron_tempest_plugin.scenario import constants
+from neutron_tempest_plugin.scenario import test_qos
 
 
 CONF = config.CONF
@@ -196,3 +199,72 @@
                                 proxy_client=proxy_client)
         self.check_remote_connectivity(ssh_client,
                                        gateway_external_ip)
+
+
+class FloatingIPQosTest(FloatingIpTestCasesMixin,
+                        test_qos.QoSTest):
+
+    same_network = True
+
+    @classmethod
+    @utils.requires_ext(extension="router", service="network")
+    @utils.requires_ext(extension="qos", service="network")
+    @utils.requires_ext(extension="qos-fip", service="network")
+    @base_api.require_qos_rule_type(qos_consts.RULE_TYPE_BANDWIDTH_LIMIT)
+    def resource_setup(cls):
+        super(FloatingIPQosTest, cls).resource_setup()
+
+    @classmethod
+    def skip_checks(cls):
+        super(FloatingIPQosTest, cls).skip_checks()
+        if utils.is_extension_enabled("dvr", "network"):
+            raise cls.skipException(
+                "Skip until bug "
+                "https://bugs.launchpad.net/neutron/+bug/1758316 "
+                "will be fixed.")
+
+    @decorators.idempotent_id('5eb48aea-eaba-4c20-8a6f-7740070a0aa3')
+    def test_qos(self):
+        """Test floating IP is binding to a QoS policy with
+
+           ingress and egress bandwidth limit rules. And it applied correctly
+           by sending a file from the instance to the test node.
+           Then calculating the bandwidth every ~1 sec by the number of bits
+           received / elapsed time.
+        """
+
+        self._test_basic_resources()
+        policy_id = self._create_qos_policy()
+        ssh_client = self._create_ssh_client()
+        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,
+            direction=lib_constants.INGRESS_DIRECTION)
+        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,
+            direction=lib_constants.EGRESS_DIRECTION)
+
+        rules = self.os_admin.network_client.list_bandwidth_limit_rules(
+            policy_id)
+        self.assertEqual(2, len(rules['bandwidth_limit_rules']))
+
+        fip = self.os_admin.network_client.get_floatingip(
+            self.fip['id'])['floatingip']
+        self.assertEqual(self.port['id'], fip['port_id'])
+
+        self.os_admin.network_client.update_floatingip(
+            self.fip['id'],
+            qos_policy_id=policy_id)
+
+        fip = self.os_admin.network_client.get_floatingip(
+            self.fip['id'])['floatingip']
+        self.assertEqual(policy_id, fip['qos_policy_id'])
+
+        self._create_file_for_bw_tests(ssh_client)
+        common_utils.wait_until_true(lambda: self._check_bw(
+            ssh_client,
+            self.fip['floating_ip_address'],
+            port=self.NC_PORT),
+            timeout=120,
+            sleep=1)
diff --git a/neutron_tempest_plugin/scenario/test_qos.py b/neutron_tempest_plugin/scenario/test_qos.py
index 67c00c2..58accb0 100644
--- a/neutron_tempest_plugin/scenario/test_qos.py
+++ b/neutron_tempest_plugin/scenario/test_qos.py
@@ -79,6 +79,8 @@
                        * TOLERANCE_FACTOR / 8.0)
     FILE_PATH = "/tmp/img"
 
+    NC_PORT = 1234
+
     @classmethod
     @tutils.requires_ext(extension="qos", service="network")
     @base_api.require_qos_rule_type(qos_consts.RULE_TYPE_BANDWIDTH_LIMIT)
@@ -117,7 +119,7 @@
         time_elapsed = time.time() - start_time
         bytes_per_second = total_bytes_read / time_elapsed
 
-        LOG.debug("time_elapsed = %(time_elapsed)d, "
+        LOG.debug("time_elapsed = %(time_elapsed).16f, "
                   "total_bytes_read = %(total_bytes_read)d, "
                   "bytes_per_second = %(bytes_per_second)d",
                   {'time_elapsed': time_elapsed,
@@ -126,6 +128,31 @@
 
         return bytes_per_second <= QoSTest.LIMIT_BYTES_SEC
 
+    def _create_ssh_client(self):
+        return ssh.Client(self.fip['floating_ip_address'],
+                          CONF.validation.image_ssh_user,
+                          pkey=self.keypair['private_key'])
+
+    def _test_basic_resources(self):
+        self.setup_network_and_server()
+        self.check_connectivity(self.fip['floating_ip_address'],
+                                CONF.validation.image_ssh_user,
+                                self.keypair['private_key'])
+        rulesets = [{'protocol': 'tcp',
+                     'direction': 'ingress',
+                     'port_range_min': self.NC_PORT,
+                     'port_range_max': self.NC_PORT,
+                     'remote_ip_prefix': '0.0.0.0/0'}]
+        self.create_secgroup_rules(rulesets,
+                                   self.security_groups[-1]['id'])
+
+    def _create_qos_policy(self):
+        policy = self.os_admin.network_client.create_qos_policy(
+                                        name='test-policy',
+                                        description='test-qos-policy',
+                                        shared=True)
+        return policy['policy']['id']
+
     @decorators.idempotent_id('1f7ed39b-428f-410a-bd2b-db9f465680df')
     def test_qos(self):
         """This is a basic test that check that a QoS policy with
@@ -135,29 +162,9 @@
            Then calculating the bandwidth every ~1 sec by the number of bits
            received / elapsed time.
         """
-
-        NC_PORT = 1234
-
-        self.setup_network_and_server()
-        self.check_connectivity(self.fip['floating_ip_address'],
-                                CONF.validation.image_ssh_user,
-                                self.keypair['private_key'])
-        rulesets = [{'protocol': 'tcp',
-                     'direction': 'ingress',
-                     'port_range_min': NC_PORT,
-                     'port_range_max': NC_PORT,
-                     'remote_ip_prefix': '0.0.0.0/0'}]
-        self.create_secgroup_rules(rulesets,
-                                   self.security_groups[-1]['id'])
-
-        ssh_client = ssh.Client(self.fip['floating_ip_address'],
-                                CONF.validation.image_ssh_user,
-                                pkey=self.keypair['private_key'])
-        policy = self.os_admin.network_client.create_qos_policy(
-                                        name='test-policy',
-                                        description='test-qos-policy',
-                                        shared=True)
-        policy_id = policy['policy']['id']
+        self._test_basic_resources()
+        policy_id = self._create_qos_policy()
+        ssh_client = self._create_ssh_client()
         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_BITS_PER_SECOND)
@@ -170,6 +177,6 @@
         utils.wait_until_true(lambda: self._check_bw(
             ssh_client,
             self.fip['floating_ip_address'],
-            port=NC_PORT),
+            port=self.NC_PORT),
             timeout=120,
             sleep=1)
diff --git a/neutron_tempest_plugin/services/network/json/network_client.py b/neutron_tempest_plugin/services/network/json/network_client.py
index a48db36..930cbfd 100644
--- a/neutron_tempest_plugin/services/network/json/network_client.py
+++ b/neutron_tempest_plugin/services/network/json/network_client.py
@@ -910,6 +910,23 @@
         body = jsonutils.loads(body)
         return service_client.ResponseBody(resp, body)
 
+    def get_floatingip(self, fip_id):
+        uri = '%s/floatingips/%s' % (self.uri_prefix, fip_id)
+        get_resp, get_resp_body = self.get(uri)
+        self.expected_success(200, get_resp.status)
+        body = jsonutils.loads(get_resp_body)
+        return service_client.ResponseBody(get_resp, body)
+
+    def update_floatingip(self, fip_id, **kwargs):
+        uri = '%s/floatingips/%s' % (self.uri_prefix, fip_id)
+        get_resp, _ = self.get(uri)
+        self.expected_success(200, get_resp.status)
+        put_body = jsonutils.dumps({'floatingip': kwargs})
+        put_resp, resp_body = self.put(uri, put_body)
+        self.expected_success(200, put_resp.status)
+        body = jsonutils.loads(resp_body)
+        return service_client.ResponseBody(put_resp, body)
+
     def create_network_keystone_v3(self, name, project_id, tenant_id=None):
         uri = '%s/networks' % self.uri_prefix
         post_data = {
diff --git a/playbooks/neutron-tempest-plugin-scenario-linuxbridge/post.yaml b/playbooks/neutron-tempest-plugin-scenario-linuxbridge/post.yaml
deleted file mode 100644
index dac8753..0000000
--- a/playbooks/neutron-tempest-plugin-scenario-linuxbridge/post.yaml
+++ /dev/null
@@ -1,80 +0,0 @@
-- hosts: primary
-  tasks:
-
-    - name: Copy files from {{ ansible_user_dir }}/workspace/ on node
-      synchronize:
-        src: '{{ ansible_user_dir }}/workspace/'
-        dest: '{{ zuul.executor.log_root }}'
-        mode: pull
-        copy_links: true
-        verify_host: true
-        rsync_opts:
-          - --include=**/*nose_results.html
-          - --include=*/
-          - --exclude=*
-          - --prune-empty-dirs
-
-    - name: Copy files from {{ ansible_user_dir }}/workspace/ on node
-      synchronize:
-        src: '{{ ansible_user_dir }}/workspace/'
-        dest: '{{ zuul.executor.log_root }}'
-        mode: pull
-        copy_links: true
-        verify_host: true
-        rsync_opts:
-          - --include=**/*testr_results.html.gz
-          - --include=*/
-          - --exclude=*
-          - --prune-empty-dirs
-
-    - name: Copy files from {{ ansible_user_dir }}/workspace/ on node
-      synchronize:
-        src: '{{ ansible_user_dir }}/workspace/'
-        dest: '{{ zuul.executor.log_root }}'
-        mode: pull
-        copy_links: true
-        verify_host: true
-        rsync_opts:
-          - --include=/.testrepository/tmp*
-          - --include=*/
-          - --exclude=*
-          - --prune-empty-dirs
-
-    - name: Copy files from {{ ansible_user_dir }}/workspace/ on node
-      synchronize:
-        src: '{{ ansible_user_dir }}/workspace/'
-        dest: '{{ zuul.executor.log_root }}'
-        mode: pull
-        copy_links: true
-        verify_host: true
-        rsync_opts:
-          - --include=**/*testrepository.subunit.gz
-          - --include=*/
-          - --exclude=*
-          - --prune-empty-dirs
-
-    - name: Copy files from {{ ansible_user_dir }}/workspace/ on node
-      synchronize:
-        src: '{{ ansible_user_dir }}/workspace/'
-        dest: '{{ zuul.executor.log_root }}/tox'
-        mode: pull
-        copy_links: true
-        verify_host: true
-        rsync_opts:
-          - --include=/.tox/*/log/*
-          - --include=*/
-          - --exclude=*
-          - --prune-empty-dirs
-
-    - name: Copy files from {{ ansible_user_dir }}/workspace/ on node
-      synchronize:
-        src: '{{ ansible_user_dir }}/workspace/'
-        dest: '{{ zuul.executor.log_root }}'
-        mode: pull
-        copy_links: true
-        verify_host: true
-        rsync_opts:
-          - --include=/logs/**
-          - --include=*/
-          - --exclude=*
-          - --prune-empty-dirs
diff --git a/playbooks/neutron-tempest-plugin-scenario-linuxbridge/run.yaml b/playbooks/neutron-tempest-plugin-scenario-linuxbridge/run.yaml
deleted file mode 100644
index 02cdf83..0000000
--- a/playbooks/neutron-tempest-plugin-scenario-linuxbridge/run.yaml
+++ /dev/null
@@ -1,71 +0,0 @@
-- hosts: all
-  name: neutron-tempest-plugin-scenario-linuxbridge
-  tasks:
-
-    - name: Ensure legacy workspace directory
-      file:
-        path: '{{ ansible_user_dir }}/workspace'
-        state: directory
-
-    - shell:
-        cmd: |
-          set -e
-          set -x
-          cat > clonemap.yaml << EOF
-          clonemap:
-            - name: openstack-infra/devstack-gate
-              dest: devstack-gate
-          EOF
-          /usr/zuul-env/bin/zuul-cloner -m clonemap.yaml --cache-dir /opt/git \
-              git://git.openstack.org \
-              openstack-infra/devstack-gate
-        executable: /bin/bash
-        chdir: '{{ ansible_user_dir }}/workspace'
-      environment: '{{ zuul | zuul_legacy_vars }}'
-
-    - shell:
-        cmd: |
-          set -e
-          set -x
-          cat << 'EOF' >>"/tmp/dg-local.conf"
-          [[local|localrc]]
-          Q_AGENT=linuxbridge
-          PHYSICAL_NETWORK=default
-
-          EOF
-        executable: /bin/bash
-        chdir: '{{ ansible_user_dir }}/workspace'
-      environment: '{{ zuul | zuul_legacy_vars }}'
-
-    - shell:
-        cmd: |
-          set -e
-          set -x
-          export PYTHONUNBUFFERED=true
-          export DEVSTACK_GATE_TEMPEST=1
-          export DEVSTACK_GATE_TEMPEST_ALL_PLUGINS=1
-          export DEVSTACK_GATE_NEUTRON=1
-          export DEVSTACK_GATE_EXERCISES=0
-          export DEVSTACK_GATE_TEMPEST_REGEX="(neutron_tempest_plugin.scenario)"
-          export DEVSTACK_LOCAL_CONFIG="enable_plugin neutron-tempest-plugin git://git.openstack.org/openstack/neutron-tempest-plugin"
-          export BRANCH_OVERRIDE=default
-          if [ "$BRANCH_OVERRIDE" != "default" ] ; then
-              export OVERRIDE_ZUUL_BRANCH=$BRANCH_OVERRIDE
-          fi
-
-          export PROJECTS="openstack/neutron-tempest-plugin $PROJECTS"
-          function gate_hook {
-              bash -xe $BASE/new/neutron/neutron/tests/contrib/gate_hook.sh dsvm-scenario-linuxbridge dvrskip
-          }
-          export -f gate_hook
-
-          function post_test_hook {
-              bash -xe $BASE/new/neutron/neutron/tests/contrib/post_test_hook.sh dsvm-scenario-linuxbridge
-          }
-          export -f post_test_hook
-
-          cp devstack-gate/devstack-vm-gate-wrap.sh ./safe-devstack-vm-gate-wrap.sh
-          ./safe-devstack-vm-gate-wrap.sh
-        executable: /bin/bash
-        chdir: '{{ ansible_user_dir }}/workspace'
-      environment: '{{ zuul | zuul_legacy_vars }}'
diff --git a/requirements.txt b/requirements.txt
index 77875ed..63cb933 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -4,8 +4,8 @@
 
 pbr!=2.1.0,>=2.0.0 # Apache-2.0
 neutron-lib>=1.13.0 # Apache-2.0
-oslo.config>=5.1.0 # Apache-2.0
-ipaddress>=1.0.16;python_version<'3.3' # PSF
+oslo.config>=5.2.0 # Apache-2.0
+ipaddress>=1.0.17;python_version<'3.3' # PSF
 netaddr>=0.7.18 # BSD
 oslo.log>=3.36.0 # Apache-2.0
 oslo.serialization!=2.19.1,>=2.18.0 # Apache-2.0
diff --git a/test-requirements.txt b/test-requirements.txt
index f4f8c0a..b8835e3 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -6,7 +6,7 @@
 
 coverage!=4.4,>=4.0 # Apache-2.0
 python-subunit>=1.0.0 # Apache-2.0/BSD
-sphinx!=1.6.6,>=1.6.2 # BSD
+sphinx!=1.6.6,!=1.6.7,>=1.6.2 # BSD
 oslotest>=3.2.0 # Apache-2.0
 testrepository>=0.0.18 # Apache-2.0/BSD
 testtools>=2.2.0 # MIT