Merge "Add test for negative security group range scenario"
diff --git a/.zuul.yaml b/.zuul.yaml
index 7e8e532..9a7405b 100644
--- a/.zuul.yaml
+++ b/.zuul.yaml
@@ -1,9 +1,66 @@
-- project:
- name: openstack/neutron-tempest-plugin
+- job:
+ name: neutron-tempest-plugin-api
+ parent: legacy-dsvm-base
+ run: playbooks/neutron-tempest-plugin-api/run.yaml
+ post-run: playbooks/neutron-tempest-plugin-api/post.yaml
+ timeout: 10000
+ required-projects:
+ - openstack-infra/devstack-gate
+ - openstack/neutron
+ - openstack/neutron-tempest-plugin
+ - openstack/tempest
+ irrelevant-files:
+ - ^(test-|)requirements.txt$
+ - ^releasenotes/.*$
+ - ^setup.cfg$
+
+- 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
+ timeout: 10000
+ required-projects:
+ - openstack-infra/devstack-gate
+ - openstack/neutron
+ - openstack/neutron-tempest-plugin
+ - openstack/tempest
+ irrelevant-files:
+ - ^(test-|)requirements.txt$
+ - ^releasenotes/.*$
+ - ^setup.cfg$
+ voting: false
+
+- job:
+ name: neutron-tempest-plugin-dvr-multinode-scenario
+ parent: legacy-dsvm-base-multinode
+ run: playbooks/neutron-tempest-plugin-dvr-multinode-scenario/run.yaml
+ post-run: playbooks/neutron-tempest-plugin-dvr-multinode-scenario/post.yaml
+ nodeset: legacy-ubuntu-xenial-2-node
+ timeout: 10800
+ required-projects:
+ - openstack-infra/devstack-gate
+ - openstack/neutron
+ - openstack/neutron-tempest-plugin
+ - openstack/tempest
+ irrelevant-files:
+ - ^(test-|)requirements.txt$
+ - ^releasenotes/.*$
+ - ^setup.cfg$
+ voting: false
+
+- project-template:
+ name: neutron-tempest-plugin-jobs
check:
jobs:
- # These jobs are defined in http://git.openstack.org/cgit/openstack/neutron/tree/.zuul.yaml
- # They are all non-voting.
+ - neutron-tempest-plugin-api
- neutron-tempest-plugin-dvr-multinode-scenario
- neutron-tempest-plugin-scenario-linuxbridge
+ gate:
+ jobs:
- neutron-tempest-plugin-api
+
+- project:
+ name: openstack/neutron-tempest-plugin
+ templates:
+ - neutron-tempest-plugin-jobs
diff --git a/neutron_tempest_plugin/api/clients.py b/neutron_tempest_plugin/api/clients.py
index 272f5be..875992e 100644
--- a/neutron_tempest_plugin/api/clients.py
+++ b/neutron_tempest_plugin/api/clients.py
@@ -13,6 +13,8 @@
# License for the specific language governing permissions and limitations
# under the License.
+from tempest.lib.services.compute import availability_zone_client
+from tempest.lib.services.compute import hypervisor_client
from tempest.lib.services.compute import keypairs_client
from tempest.lib.services.compute import servers_client
from tempest.lib.services.identity.v2 import tenants_client
@@ -74,6 +76,10 @@
**params)
self.keypairs_client = keypairs_client.KeyPairsClient(
self.auth_provider, **params)
+ self.hv_client = hypervisor_client.HypervisorClient(
+ self.auth_provider, **params)
+ self.az_client = availability_zone_client.AvailabilityZoneClient(
+ self.auth_provider, **params)
def _set_identity_clients(self):
params = {
diff --git a/neutron_tempest_plugin/scenario/admin/__init__.py b/neutron_tempest_plugin/scenario/admin/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/neutron_tempest_plugin/scenario/admin/__init__.py
diff --git a/neutron_tempest_plugin/scenario/admin/test_floatingip.py b/neutron_tempest_plugin/scenario/admin/test_floatingip.py
new file mode 100644
index 0000000..e58be83
--- /dev/null
+++ b/neutron_tempest_plugin/scenario/admin/test_floatingip.py
@@ -0,0 +1,109 @@
+# Copyright 2017 Red Hat, Inc.
+# 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.common import utils
+from tempest.common import waiters
+from tempest.lib.common.utils import data_utils
+from tempest.lib import decorators
+
+from neutron_tempest_plugin.common import ssh
+from neutron_tempest_plugin import config
+from neutron_tempest_plugin.scenario import base
+from neutron_tempest_plugin.scenario import constants as const
+
+CONF = config.CONF
+
+
+class FloatingIpTestCasesAdmin(base.BaseTempestTestCase):
+ credentials = ['primary', 'admin']
+
+ @classmethod
+ @utils.requires_ext(extension="router", service="network")
+ def resource_setup(cls):
+ super(FloatingIpTestCasesAdmin, cls).resource_setup()
+ cls.network = cls.create_network()
+ cls.create_subnet(cls.network)
+ router = cls.create_router_by_client()
+ cls.create_router_interface(router['id'], cls.subnets[0]['id'])
+ # Create keypair with admin privileges
+ cls.keypair = cls.create_keypair(client=cls.os_admin.keypairs_client)
+ # Create security group with admin privileges
+ cls.secgroup = cls.os_admin.network_client.create_security_group(
+ name=data_utils.rand_name('secgroup'))['security_group']
+ # Execute funcs to achieve ssh and ICMP capabilities
+ funcs = [cls.create_loginable_secgroup_rule,
+ cls.create_pingable_secgroup_rule]
+ for func in funcs:
+ func(secgroup_id=cls.secgroup['id'],
+ client=cls.os_admin.network_client)
+
+ @classmethod
+ def resource_cleanup(cls):
+ # Cleanup for security group
+ cls.os_admin.network_client.delete_security_group(
+ security_group_id=cls.secgroup['id'])
+ super(FloatingIpTestCasesAdmin, cls).resource_cleanup()
+
+ def _list_hypervisors(self):
+ # List of hypervisors
+ return self.os_admin.hv_client.list_hypervisors()['hypervisors']
+
+ def _list_availability_zones(self):
+ # List of availability zones
+ func = self.os_admin.az_client.list_availability_zones
+ return func()['availabilityZoneInfo']
+
+ def _create_vms(self, hyper, avail_zone, num_servers=2):
+ servers, fips, server_ssh_clients = ([], [], [])
+ # Create the availability zone with default zone and
+ # a specific mentioned hypervisor.
+ az = avail_zone + ':' + hyper
+ for i in range(num_servers):
+ servers.append(self.create_server(
+ flavor_ref=CONF.compute.flavor_ref,
+ image_ref=CONF.compute.image_ref,
+ key_name=self.keypair['name'],
+ networks=[{'uuid': self.network['id']}],
+ security_groups=[{'name': self.secgroup['name']}],
+ availability_zone=az))
+ for i, server in enumerate(servers):
+ waiters.wait_for_server_status(
+ self.os_admin.servers_client, server['server']['id'],
+ const.SERVER_STATUS_ACTIVE)
+ port = self.client.list_ports(
+ network_id=self.network['id'],
+ device_id=server['server']['id']
+ )['ports'][0]
+ fips.append(self.create_and_associate_floatingip(
+ port['id'], client=self.os_admin.network_client))
+ server_ssh_clients.append(ssh.Client(
+ fips[i]['floating_ip_address'], CONF.validation.image_ssh_user,
+ pkey=self.keypair['private_key']))
+ self.addCleanup(self.os_admin.network_client.delete_floatingip,
+ fips[i]['id'])
+ return server_ssh_clients, fips
+
+ @decorators.idempotent_id('6bba729b-3fb6-494b-9e1e-82bbd89a1045')
+ def test_two_vms_fips(self):
+ """This test verifies the ability of two instances
+ that were created in the same compute node and same availability zone
+ to reach each other.
+ """
+ # Get hypervisor list to pass it for vm creation
+ hyper = self._list_hypervisors()[0]['hypervisor_hostname']
+ # Get availability zone list to pass it for vm creation
+ avail_zone = self._list_availability_zones()[0]['zoneName']
+ server_ssh_clients, fips = self._create_vms(hyper, avail_zone)
+ self.check_remote_connectivity(
+ server_ssh_clients[0], fips[1]['floating_ip_address'])
diff --git a/neutron_tempest_plugin/scenario/base.py b/neutron_tempest_plugin/scenario/base.py
index 5cc085f..50f6b54 100644
--- a/neutron_tempest_plugin/scenario/base.py
+++ b/neutron_tempest_plugin/scenario/base.py
@@ -42,15 +42,17 @@
@classmethod
def resource_cleanup(cls):
for keypair in cls.keypairs:
- cls.os_primary.keypairs_client.delete_keypair(
- keypair_name=keypair['name'])
+ client = keypair['client']
+ client.delete_keypair(
+ keypair_name=keypair['keypair']['name'])
super(BaseTempestTestCase, cls).resource_cleanup()
def create_server(self, flavor_ref, image_ref, key_name, networks,
- name=None, security_groups=None):
+ **kwargs):
"""Create a server using tempest lib
All the parameters are the ones used in Compute API
+ * - Kwargs that require admin privileges
Args:
flavor_ref(str): The flavor of the server to be provisioned.
@@ -61,30 +63,48 @@
an interface to be attached to the server. For network
it should be {'uuid': network_uuid} and for port it should
be {'port': port_uuid}
+ kwargs:
name(str): Name of the server to be provisioned.
security_groups(list): List of dictionaries where
the keys is 'name' and the value is the name of
the security group. If it's not passed the default
security group will be used.
+ availability_zone(str)*: The availability zone that
+ the instance will be in.
+ You can request a specific az without actually creating one,
+ Just pass 'X:Y' where X is the default availability
+ zone, and Y is the compute host name.
"""
- name = name or data_utils.rand_name('server-test')
+ name = kwargs.get('name', data_utils.rand_name('server-test'))
+ security_groups = kwargs.get('security_groups')
if not security_groups:
security_groups = [{'name': 'default'}]
+ availability_zone = kwargs.get('availability_zone')
- server = self.os_primary.servers_client.create_server(
- name=name,
- flavorRef=flavor_ref,
- imageRef=image_ref,
- key_name=key_name,
- networks=networks,
- security_groups=security_groups)
+ server_args = {
+ 'name': name,
+ 'flavorRef': flavor_ref,
+ 'imageRef': image_ref,
+ 'key_name': key_name,
+ 'networks': networks,
+ 'security_groups': security_groups
+ }
+
+ if availability_zone:
+ server_args['availability_zone'] = availability_zone
+ client = self.os_admin.servers_client
+ else:
+ client = self.os_primary.servers_client
+
+ server = client.create_server(**server_args)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
- waiters.wait_for_server_termination,
- self.os_primary.servers_client, server['server']['id'])
+ waiters.wait_for_server_termination,
+ client,
+ server['server']['id'])
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
- self.os_primary.servers_client.delete_server,
+ client.delete_server,
server['server']['id'])
return server
@@ -93,12 +113,16 @@
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'])
+ body.update(client=client)
+ if client is cls.os_primary.keypairs_client:
+ cls.keypairs.append(body)
+
return body['keypair']
@classmethod
- def create_secgroup_rules(cls, rule_list, secgroup_id=None):
- client = cls.os_primary.network_client
+ def create_secgroup_rules(cls, rule_list, secgroup_id=None,
+ client=None):
+ client = client or cls.os_primary.network_client
if not secgroup_id:
sgs = client.list_security_groups()['security_groups']
for sg in sgs:
@@ -114,7 +138,8 @@
**rule)
@classmethod
- def create_loginable_secgroup_rule(cls, secgroup_id=None):
+ def create_loginable_secgroup_rule(cls, secgroup_id=None,
+ client=None):
"""This rule is intended to permit inbound ssh
Allowing ssh traffic traffic from all sources, so no group_id is
@@ -128,10 +153,13 @@
'port_range_min': 22,
'port_range_max': 22,
'remote_ip_prefix': '0.0.0.0/0'}]
- cls.create_secgroup_rules(rule_list, secgroup_id=secgroup_id)
+ client = client or cls.os_primary.network_client
+ cls.create_secgroup_rules(rule_list, client=client,
+ secgroup_id=secgroup_id)
@classmethod
- def create_pingable_secgroup_rule(cls, secgroup_id=None):
+ def create_pingable_secgroup_rule(cls, secgroup_id=None,
+ client=None):
"""This rule is intended to permit inbound ping
"""
@@ -140,7 +168,9 @@
'port_range_min': 8, # type
'port_range_max': 0, # code
'remote_ip_prefix': '0.0.0.0/0'}]
- cls.create_secgroup_rules(rule_list, secgroup_id=secgroup_id)
+ client = client or cls.os_primary.network_client
+ cls.create_secgroup_rules(rule_list, client=client,
+ secgroup_id=secgroup_id)
@classmethod
def create_router_by_client(cls, is_admin=False, **kwargs):
@@ -155,11 +185,13 @@
cls.routers.append(router)
return router
- def create_and_associate_floatingip(self, port_id):
- fip = self.os_primary.network_client.create_floatingip(
+ def create_and_associate_floatingip(self, port_id, client=None):
+ client = client or self.os_primary.network_client
+ fip = client.create_floatingip(
CONF.network.public_network_id,
port_id=port_id)['floatingip']
- self.floating_ips.append(fip)
+ if client is self.os_primary.network_client:
+ self.floating_ips.append(fip)
return fip
def setup_network_and_server(self, router=None, **kwargs):
diff --git a/playbooks/neutron-tempest-plugin-api/post.yaml b/playbooks/neutron-tempest-plugin-api/post.yaml
new file mode 100644
index 0000000..dac8753
--- /dev/null
+++ b/playbooks/neutron-tempest-plugin-api/post.yaml
@@ -0,0 +1,80 @@
+- 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-api/run.yaml b/playbooks/neutron-tempest-plugin-api/run.yaml
new file mode 100644
index 0000000..3470bd4
--- /dev/null
+++ b/playbooks/neutron-tempest-plugin-api/run.yaml
@@ -0,0 +1,68 @@
+- hosts: all
+ name: neutron-tempest-plugin-api
+ 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]]
+ TEMPEST_PLUGINS='/opt/stack/new/neutron-tempest-plugin'
+ 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_NEUTRON=1
+ export DEVSTACK_GATE_EXERCISES=0
+ export DEVSTACK_GATE_TEMPEST_REGEX="neutron_tempest_plugin.api"
+ 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 api
+ }
+ export -f gate_hook
+
+ function post_test_hook {
+ bash -xe $BASE/new/neutron/neutron/tests/contrib/post_test_hook.sh api
+ }
+ 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/playbooks/neutron-tempest-plugin-dvr-multinode-scenario/post.yaml b/playbooks/neutron-tempest-plugin-dvr-multinode-scenario/post.yaml
new file mode 100644
index 0000000..e07f551
--- /dev/null
+++ b/playbooks/neutron-tempest-plugin-dvr-multinode-scenario/post.yaml
@@ -0,0 +1,15 @@
+- 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=/logs/**
+ - --include=*/
+ - --exclude=*
+ - --prune-empty-dirs
diff --git a/playbooks/neutron-tempest-plugin-dvr-multinode-scenario/run.yaml b/playbooks/neutron-tempest-plugin-dvr-multinode-scenario/run.yaml
new file mode 100644
index 0000000..d68747c
--- /dev/null
+++ b/playbooks/neutron-tempest-plugin-dvr-multinode-scenario/run.yaml
@@ -0,0 +1,71 @@
+- hosts: all
+ name: neutron-tempest-plugin-dvr-multinode-scenario
+ 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]]
+ TEMPEST_PLUGINS='/opt/stack/new/neutron-tempest-plugin'
+ 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_NEUTRON=1
+ export DEVSTACK_GATE_CONFIGDRIVE=0
+ export DEVSTACK_GATE_TEMPEST_REGEX="(neutron_tempest_plugin.scenario)"
+ export TEMPEST_CONCURRENCY=2
+ # Test DVR works multinode
+ export DEVSTACK_GATE_NEUTRON_DVR=1
+ export BRANCH_OVERRIDE=default
+ if [ "$BRANCH_OVERRIDE" != "default" ] ; then
+ export OVERRIDE_ZUUL_BRANCH=$BRANCH_OVERRIDE
+ fi
+ export DEVSTACK_GATE_TOPOLOGY="multinode"
+ export PROJECTS="openstack/neutron-tempest-plugin $PROJECTS"
+
+ function gate_hook {
+ bash -xe $BASE/new/neutron/neutron/tests/contrib/gate_hook.sh dsvm-scenario-ovs
+ }
+ export -f gate_hook
+
+ function post_test_hook {
+ bash -xe $BASE/new/neutron/neutron/tests/contrib/post_test_hook.sh dsvm-scenario-ovs
+ }
+ 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/playbooks/neutron-tempest-plugin-scenario-linuxbridge/post.yaml b/playbooks/neutron-tempest-plugin-scenario-linuxbridge/post.yaml
new file mode 100644
index 0000000..dac8753
--- /dev/null
+++ b/playbooks/neutron-tempest-plugin-scenario-linuxbridge/post.yaml
@@ -0,0 +1,80 @@
+- 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
new file mode 100644
index 0000000..f2be130
--- /dev/null
+++ b/playbooks/neutron-tempest-plugin-scenario-linuxbridge/run.yaml
@@ -0,0 +1,71 @@
+- 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
+ TEMPEST_PLUGINS='/opt/stack/new/neutron-tempest-plugin'
+
+ 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_NEUTRON=1
+ export DEVSTACK_GATE_EXERCISES=0
+ export DEVSTACK_GATE_TEMPEST_REGEX="(neutron_tempest_plugin.scenario)"
+ export BRANCH_OVERRIDE=default
+ if [ "$BRANCH_OVERRIDE" != "default" ] ; then
+ export OVERRIDE_ZUUL_BRANCH=$BRANCH_OVERRIDE
+ fi
+
+ export TEMPEST_CONCURRENCY=2
+ 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 }}'