Merge "Minor improvement in: test_qos_basic_and_update"
diff --git a/neutron_tempest_plugin/api/admin/test_dhcp_agent_scheduler.py b/neutron_tempest_plugin/api/admin/test_dhcp_agent_scheduler.py
index d0adcb8..9dc4438 100644
--- a/neutron_tempest_plugin/api/admin/test_dhcp_agent_scheduler.py
+++ b/neutron_tempest_plugin/api/admin/test_dhcp_agent_scheduler.py
@@ -13,6 +13,7 @@
# under the License.
from neutron_lib import constants
+from neutron_lib.utils import test
from tempest.lib import decorators
from neutron_tempest_plugin.api import base
@@ -33,6 +34,7 @@
cls.cidr = cls.subnet['cidr']
cls.port = cls.create_port(cls.network)
+ @test.unstable_test("bug 1906654")
@decorators.idempotent_id('f164801e-1dd8-4b8b-b5d3-cc3ac77cfaa5')
def test_dhcp_port_status_active(self):
diff --git a/neutron_tempest_plugin/api/admin/test_ports.py b/neutron_tempest_plugin/api/admin/test_ports.py
index 9c94322..6f51b1c 100644
--- a/neutron_tempest_plugin/api/admin/test_ports.py
+++ b/neutron_tempest_plugin/api/admin/test_ports.py
@@ -14,7 +14,6 @@
# under the License.
import netaddr
-import six
from neutron_lib import constants as const
from tempest.common import utils
@@ -123,8 +122,8 @@
self.assertIn('resource_request', port)
vnic_trait = 'CUSTOM_VNIC_TYPE_%s' % vnic_type.upper()
physnet_trait = 'CUSTOM_PHYSNET_%s' % self.physnet_name.upper()
- six.assertCountEqual(self, [physnet_trait, vnic_trait],
- port['resource_request']['required'])
+ self.assertCountEqual([physnet_trait, vnic_trait],
+ port['resource_request']['required'])
self.assertEqual(
{'NET_BW_EGR_KILOBIT_PER_SEC': self.EGRESS_KBPS,
diff --git a/neutron_tempest_plugin/api/admin/test_quotas.py b/neutron_tempest_plugin/api/admin/test_quotas.py
index ae773c8..0cf474e 100644
--- a/neutron_tempest_plugin/api/admin/test_quotas.py
+++ b/neutron_tempest_plugin/api/admin/test_quotas.py
@@ -13,7 +13,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-import six
from tempest.common import utils
from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
@@ -145,7 +144,7 @@
# as requested for tenant
quota_set = self.admin_client.show_details_quota(tenant_id)
quota_set = quota_set['quota']
- for key, value in six.iteritems(new_quotas):
+ for key, value in new_quotas.items():
self.assertEqual(new_quotas[key]['limit'],
quota_set[key]['limit'])
self.assertEqual(new_quotas[key]['reserved'],
@@ -155,5 +154,5 @@
# validate 'default' action for old extension
quota_limit = self.admin_client.show_quotas(tenant_id)['quota']
- for key, value in six.iteritems(new_quotas):
+ for key, value in new_quotas.items():
self.assertEqual(new_quotas[key]['limit'], quota_limit[key])
diff --git a/neutron_tempest_plugin/api/admin/test_tag.py b/neutron_tempest_plugin/api/admin/test_tag.py
index 7879b4c..eae7977 100644
--- a/neutron_tempest_plugin/api/admin/test_tag.py
+++ b/neutron_tempest_plugin/api/admin/test_tag.py
@@ -28,13 +28,13 @@
def _get_and_compare_tags(self, tags):
res_body = self.client.get_tags(self.resource, self.res_id)
- self.assertItemsEqual(tags, res_body['tags'])
+ self.assertCountEqual(tags, res_body['tags'])
def _test_tag_operations(self):
# create and get tags
tags = ['red', 'blue']
res_body = self.client.update_tags(self.resource, self.res_id, tags)
- self.assertItemsEqual(tags, res_body['tags'])
+ self.assertCountEqual(tags, res_body['tags'])
self._get_and_compare_tags(tags)
# add a tag
@@ -52,7 +52,7 @@
# replace tags
tags = ['red', 'yellow', 'purple']
res_body = self.client.update_tags(self.resource, self.res_id, tags)
- self.assertItemsEqual(tags, res_body['tags'])
+ self.assertCountEqual(tags, res_body['tags'])
self._get_and_compare_tags(tags)
# get tag
@@ -477,7 +477,7 @@
# nothing specific about networks here, just a resource that is
# available in all setups
res_body = self.client.get_tags('networks', res_id)
- self.assertItemsEqual(tags, res_body['tags'])
+ self.assertCountEqual(tags, res_body['tags'])
@decorators.attr(type='smoke')
@decorators.idempotent_id('74c56fb1-a3b1-4a62-a8d2-d04dca6bd4cd')
diff --git a/neutron_tempest_plugin/api/base.py b/neutron_tempest_plugin/api/base.py
index 7cf8dd4..4833c71 100644
--- a/neutron_tempest_plugin/api/base.py
+++ b/neutron_tempest_plugin/api/base.py
@@ -140,6 +140,17 @@
cls.conntrack_helpers = []
@classmethod
+ def reserve_external_subnet_cidrs(cls):
+ client = cls.os_admin.network_client
+ ext_nets = client.list_networks(
+ **{"router:external": True})['networks']
+ for ext_net in ext_nets:
+ ext_subnets = client.list_subnets(
+ network_id=ext_net['id'])['subnets']
+ for ext_subnet in ext_subnets:
+ cls.reserve_subnet_cidr(ext_subnet['cidr'])
+
+ @classmethod
def resource_cleanup(cls):
if CONF.service_available.neutron:
# Clean up trunks
@@ -702,6 +713,12 @@
return pf
@classmethod
+ def update_port_forwarding(cls, fip_id, pf_id, client=None, **kwargs):
+ """Wrapper utility for update_port_forwarding."""
+ client = client or cls.client
+ return client.update_port_forwarding(fip_id, pf_id, **kwargs)
+
+ @classmethod
def delete_port_forwarding(cls, pf, client=None):
"""Delete port forwarding
diff --git a/neutron_tempest_plugin/api/test_allowed_address_pair.py b/neutron_tempest_plugin/api/test_allowed_address_pair.py
index dd48382..7b11638 100644
--- a/neutron_tempest_plugin/api/test_allowed_address_pair.py
+++ b/neutron_tempest_plugin/api/test_allowed_address_pair.py
@@ -81,7 +81,7 @@
body = self.client.update_port(
port_id, allowed_address_pairs=allowed_address_pairs)
allowed_address_pair = body['port']['allowed_address_pairs']
- self.assertItemsEqual(allowed_address_pair, allowed_address_pairs)
+ self.assertCountEqual(allowed_address_pair, allowed_address_pairs)
@decorators.idempotent_id('9599b337-272c-47fd-b3cf-509414414ac4')
def test_update_port_with_address_pair(self):
diff --git a/neutron_tempest_plugin/api/test_port_forwarding_negative.py b/neutron_tempest_plugin/api/test_port_forwarding_negative.py
index 76dd6ee..386cbed 100644
--- a/neutron_tempest_plugin/api/test_port_forwarding_negative.py
+++ b/neutron_tempest_plugin/api/test_port_forwarding_negative.py
@@ -12,6 +12,7 @@
# 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.utils import data_utils
from tempest.lib import decorators
from tempest.lib import exceptions
@@ -81,3 +82,43 @@
internal_ip_address=port['fixed_ips'][0]['ip_address'],
internal_port=1111, external_port=5555,
protocol="tcp")
+
+ @decorators.attr(type='negative')
+ @decorators.idempotent_id('e9d3ffb6-e5bf-421d-acaa-ee6010dfbf14')
+ def test_out_of_range_ports(self):
+ port = self.create_port(self.network)
+ fip_for_pf = self.create_floatingip()
+
+ pf_params = {
+ 'internal_port_id': port['id'],
+ 'internal_ip_address': port['fixed_ips'][0]['ip_address'],
+ 'internal_port': 1111,
+ 'external_port': 3333,
+ 'protocol': "tcp"}
+ pf = self.create_port_forwarding(fip_for_pf['id'], **pf_params)
+
+ # Check: Invalid input for external_port update
+ self.assertRaises(
+ exceptions.BadRequest,
+ self.update_port_forwarding,
+ fip_for_pf['id'], pf['id'], external_port=108343)
+
+ # Check: Invalid input for internal_port update
+ self.assertRaises(
+ exceptions.BadRequest,
+ self.update_port_forwarding,
+ fip_for_pf['id'], pf['id'], internal_port=108343)
+
+ # Check: Invalid input for external_port create
+ pf_params['internal_port'] = 4444
+ pf_params['external_port'] = 333333
+ self.assertRaises(
+ exceptions.BadRequest,
+ self.create_port_forwarding, fip_for_pf['id'], **pf_params)
+
+ # Check: Invalid input for internal_port create
+ pf_params['internal_port'] = 444444
+ pf_params['external_port'] = 3333
+ self.assertRaises(
+ exceptions.BadRequest,
+ self.create_port_forwarding, fip_for_pf['id'], **pf_params)
diff --git a/neutron_tempest_plugin/api/test_port_forwardings.py b/neutron_tempest_plugin/api/test_port_forwardings.py
index 82c3a34..79cce39 100644
--- a/neutron_tempest_plugin/api/test_port_forwardings.py
+++ b/neutron_tempest_plugin/api/test_port_forwardings.py
@@ -124,31 +124,10 @@
fip = self.client.show_floatingip(fip['id'])['floatingip']
self.assertEqual(0, len(fip['port_forwardings']))
- @decorators.idempotent_id('8202cded-7e82-4420-9585-c091105404f6')
- def test_associate_2_port_forwardings_to_floating_ip(self):
- fip = self.create_floatingip()
- forwardings_data = [(1111, 2222), (3333, 4444)]
- created_pfs = []
- for data in forwardings_data:
- internal_port = data[0]
- external_port = data[1]
- port = self.create_port(self.network)
- created_pf = self.create_port_forwarding(
- fip['id'],
- internal_port_id=port['id'],
- internal_ip_address=port['fixed_ips'][0]['ip_address'],
- internal_port=internal_port, external_port=external_port,
- protocol="tcp")
- self.assertEqual(internal_port, created_pf['internal_port'])
- self.assertEqual(external_port, created_pf['external_port'])
- self.assertEqual('tcp', created_pf['protocol'])
- self.assertEqual(port['fixed_ips'][0]['ip_address'],
- created_pf['internal_ip_address'])
- created_pfs.append(created_pf)
-
+ def _verify_created_pfs(self, fip_id, created_pfs):
# Check that all PFs are visible in Floating IP details
- fip = self.client.show_floatingip(fip['id'])['floatingip']
- self.assertEqual(len(forwardings_data), len(fip['port_forwardings']))
+ fip = self.client.show_floatingip(fip_id)['floatingip']
+ self.assertEqual(len(created_pfs), len(fip['port_forwardings']))
for pf in created_pfs:
expected_pf = {
'external_port': pf['external_port'],
@@ -160,13 +139,73 @@
# Test list of port forwardings
port_forwardings = self.client.list_port_forwardings(
fip['id'])['port_forwardings']
- self.assertEqual(len(forwardings_data), len(port_forwardings))
+ self.assertEqual(len(created_pfs), len(port_forwardings))
for pf in created_pfs:
expected_pf = pf.copy()
expected_pf.pop('client')
expected_pf.pop('floatingip_id')
self.assertIn(expected_pf, port_forwardings)
+ def _create_and_validate_pf(self, fip_id, internal_port_id,
+ internal_ip_address, internal_port,
+ external_port, protocol):
+ created_pf = self.create_port_forwarding(
+ fip_id,
+ internal_port_id=internal_port_id,
+ internal_ip_address=internal_ip_address,
+ internal_port=internal_port,
+ external_port=external_port,
+ protocol=protocol)
+ self.assertEqual(internal_port, created_pf['internal_port'])
+ self.assertEqual(external_port, created_pf['external_port'])
+ self.assertEqual(protocol, created_pf['protocol'])
+ self.assertEqual(internal_ip_address,
+ created_pf['internal_ip_address'])
+ return created_pf
+
+ @decorators.idempotent_id('8202cded-7e82-4420-9585-c091105404f6')
+ def test_associate_2_port_forwardings_to_floating_ip(self):
+ fip = self.create_floatingip()
+ forwardings_data = [(1111, 2222), (3333, 4444)]
+ created_pfs = []
+ for data in forwardings_data:
+ internal_port = data[0]
+ external_port = data[1]
+ port = self.create_port(self.network)
+ created_pf = self._create_and_validate_pf(
+ fip_id=fip['id'],
+ internal_port_id=port['id'],
+ internal_ip_address=port['fixed_ips'][0]['ip_address'],
+ internal_port=internal_port, external_port=external_port,
+ protocol="tcp")
+ created_pfs.append(created_pf)
+ self._verify_created_pfs(fip['id'], created_pfs)
+
+ @decorators.idempotent_id('a7e6cc48-8a9b-49be-82fb-cef6f5c29381')
+ def test_associate_port_forwarding_to_2_fixed_ips(self):
+ fip = self.create_floatingip()
+ port = self.create_port(self.network)
+ internal_subnet_id = port['fixed_ips'][0]['subnet_id']
+ # Add a second fixed_ip address to port (same subnet)
+ port['fixed_ips'].append({'subnet_id': internal_subnet_id})
+ port = self.update_port(port, fixed_ips=port['fixed_ips'])
+ internal_ip_address1 = port['fixed_ips'][0]['ip_address']
+ internal_ip_address2 = port['fixed_ips'][1]['ip_address']
+ forwardings_data = [(4001, internal_ip_address1),
+ (4002, internal_ip_address2)]
+ created_pfs = []
+ for data in forwardings_data:
+ external_port = data[0]
+ internal_ip_address = data[1]
+ created_pf = self._create_and_validate_pf(
+ fip_id=fip['id'],
+ internal_port_id=port['id'],
+ internal_ip_address=internal_ip_address,
+ internal_port=123, external_port=external_port,
+ protocol="tcp")
+ created_pfs.append(created_pf)
+ self._verify_created_pfs(fip['id'], created_pfs)
+
@decorators.idempotent_id('6a34e811-66d1-4f63-aa4d-9013f15deb62')
def test_associate_port_forwarding_to_used_floating_ip(self):
port_for_fip = self.create_port(self.network)
diff --git a/neutron_tempest_plugin/api/test_ports_negative.py b/neutron_tempest_plugin/api/test_ports_negative.py
new file mode 100644
index 0000000..e327c25
--- /dev/null
+++ b/neutron_tempest_plugin/api/test_ports_negative.py
@@ -0,0 +1,76 @@
+# 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 neutron_lib.db import constants as db_const
+from oslo_utils import uuidutils
+from tempest.lib import decorators
+from tempest.lib import exceptions as lib_exc
+
+from neutron_tempest_plugin.api import base
+
+LONG_NAME_NG = 'z' * (db_const.NAME_FIELD_SIZE + 1)
+LONG_DESCRIPTION_NG = 'z' * (db_const.LONG_DESCRIPTION_FIELD_SIZE + 1)
+
+
+class PortsNegativeTestJSON(base.BaseNetworkTest):
+
+ @classmethod
+ def resource_setup(cls):
+ super(PortsNegativeTestJSON, cls).resource_setup()
+ cls.network = cls.create_network()
+
+ @decorators.attr(type='negative')
+ @decorators.idempotent_id('0cbd256a-a6d4-4afa-a039-44cc13704bab')
+ def test_add_port_with_too_long_name(self):
+ self.assertRaises(lib_exc.BadRequest,
+ self.create_port,
+ self.network, name=LONG_NAME_NG)
+
+ @decorators.attr(type='negative')
+ @decorators.idempotent_id('e10da38c-1071-49c9-95c2-0c451e18ae31')
+ def test_add_port_with_too_long_description(self):
+ self.assertRaises(lib_exc.BadRequest,
+ self.create_port,
+ self.network, description=LONG_DESCRIPTION_NG)
+
+ @decorators.attr(type='negative')
+ @decorators.idempotent_id('5b69a905-3a84-43a4-807a-1a67ab85caeb')
+ def test_add_port_with_nonexist_tenant_id(self):
+ self.assertRaises(lib_exc.BadRequest,
+ self.create_port,
+ self.network,
+ project_id=uuidutils.generate_uuid())
+
+ @decorators.attr(type='negative')
+ @decorators.idempotent_id('7cf473ae-7ec8-4834-ae17-9ef6ec6b8a32')
+ def test_add_port_with_nonexist_network_id(self):
+ network = self.network
+ network['id'] = uuidutils.generate_uuid()
+ self.assertRaises(lib_exc.NotFound,
+ self.create_port,
+ network)
+
+ @decorators.attr(type='negative')
+ @decorators.idempotent_id('cad2d349-25fa-490e-9675-cd2ea24164bc')
+ def test_add_port_with_nonexist_security_groups_id(self):
+ self.assertRaises(lib_exc.NotFound,
+ self.create_port,
+ self.network,
+ security_groups=[uuidutils.generate_uuid()])
+
+ @decorators.attr(type='negative')
+ @decorators.idempotent_id('9b0a4152-9aa4-4169-9b2c-579609e2fb4a')
+ def test_add_port_with_illegal_ip(self):
+ self.assertRaises(lib_exc.BadRequest,
+ self.create_port,
+ self.network,
+ allowed_address_pairs=[{"ip_address: 12.12.12.a"}])
diff --git a/neutron_tempest_plugin/bgpvpn/scenario/test_bgpvpn_basic.py b/neutron_tempest_plugin/bgpvpn/scenario/test_bgpvpn_basic.py
index 937b0dc..14b0572 100644
--- a/neutron_tempest_plugin/bgpvpn/scenario/test_bgpvpn_basic.py
+++ b/neutron_tempest_plugin/bgpvpn/scenario/test_bgpvpn_basic.py
@@ -353,6 +353,7 @@
self._update_l3_bgpvpn(rts=[self.RT1], import_rts=[], export_rts=[])
self._check_l3_bgpvpn()
+ @test.unstable_test("bug 1897408")
@decorators.idempotent_id('c8bfd695-f731-47a6-86e3-3dfa492e08e0')
@utils.services('compute', 'network')
def test_bgpvpn_update_rt_and_keep_local_connectivity_variant1(self):
@@ -404,6 +405,7 @@
self._check_l3_bgpvpn(self.servers[0], self.servers[2])
self._check_l3_bgpvpn(self.servers[1], self.servers[3])
+ @test.unstable_test("bug 1897408")
@decorators.idempotent_id('758a8731-5070-4b1e-9a66-d6ff05bb5be1')
@utils.services('compute', 'network')
def test_bgpvpn_update_rt_and_keep_local_connectivity_variant2(self):
@@ -544,6 +546,7 @@
to_server_ip=IP_C_S1_1,
validate_server=destination_srv_2)
+ @test.unstable_test("bug 1897408")
@decorators.idempotent_id('f762e6ac-920e-4d0f-aa67-02bdd4ab8433')
@utils.services('compute', 'network')
def test_bgpvpn_tenant_separation_and_local_connectivity(self):
diff --git a/neutron_tempest_plugin/common/ip.py b/neutron_tempest_plugin/common/ip.py
index 83cd3d9..d981770 100644
--- a/neutron_tempest_plugin/common/ip.py
+++ b/neutron_tempest_plugin/common/ip.py
@@ -36,13 +36,19 @@
sudo = 'sudo'
ip_path = '/sbin/ip'
- def __init__(self, ssh_client=None, timeout=None):
+ def __init__(self, ssh_client=None, timeout=None, namespace=None):
self.ssh_client = ssh_client
self.timeout = timeout
+ self.namespace = namespace
def get_command(self, obj, *command):
- command_line = '{sudo!s} {ip_path!r} {object!s} {command!s}'.format(
- sudo=self.sudo, ip_path=self.ip_path, object=obj,
+ command_line = '{sudo!s} {ip_path!r} '.format(sudo=self.sudo,
+ ip_path=self.ip_path)
+ if self.namespace:
+ command_line += 'netns exec {ns_name!s} {ip_path!r} '.format(
+ ns_name=self.namespace, ip_path=self.ip_path)
+ command_line += '{object!s} {command!s}'.format(
+ object=obj,
command=subprocess.list2cmdline([str(c) for c in command]))
return command_line
@@ -84,6 +90,13 @@
self.add_address(address=subport_ip, device=subport_device)
return subport_device
+ def list_namespaces(self):
+ namespaces_output = self.execute("netns")
+ ns_list = []
+ for ns_line in namespaces_output.split("\n"):
+ ns_list.append(ns_line.split(" ", 1)[0])
+ return ns_list
+
def list_addresses(self, device=None, ip_addresses=None, port=None,
subnets=None):
command = ['list']
@@ -308,20 +321,24 @@
netaddr.IPNetwork(subnet['cidr']).prefixlen)
-def arp_table():
+def arp_table(namespace=None):
# 192.168.0.16 0x1 0x2 dc:a6:32:06:56:51 * enp0s31f6
regex_str = (r"([^ ]+)\s+(0x\d+)\s+(0x\d+)\s+(\w{2}\:\w{2}\:\w{2}\:\w{2}\:"
r"\w{2}\:\w{2})\s+([\w+\*]+)\s+([\-\w]+)")
regex = re.compile(regex_str)
arp_table = []
- with open('/proc/net/arp', 'r') as proc_file:
- for line in proc_file.readlines():
- m = regex.match(line)
- if m:
- arp_table.append(ARPregister(
- ip_address=m.group(1), hw_type=m.group(2),
- flags=m.group(3), mac_address=m.group(4),
- mask=m.group(5), device=m.group(6)))
+ cmd = ""
+ if namespace:
+ cmd = "sudo ip netns exec %s " % namespace
+ cmd += "cat /proc/net/arp"
+ arp_entries = shell.execute(cmd).stdout.split("\n")
+ for line in arp_entries:
+ m = regex.match(line)
+ if m:
+ arp_table.append(ARPregister(
+ ip_address=m.group(1), hw_type=m.group(2),
+ flags=m.group(3), mac_address=m.group(4),
+ mask=m.group(5), device=m.group(6)))
return arp_table
diff --git a/neutron_tempest_plugin/common/ssh.py b/neutron_tempest_plugin/common/ssh.py
index fa731d8..8334521 100644
--- a/neutron_tempest_plugin/common/ssh.py
+++ b/neutron_tempest_plugin/common/ssh.py
@@ -19,7 +19,6 @@
from oslo_log import log
import paramiko
-import six
from tempest.lib.common import ssh
from tempest.lib import exceptions
import tenacity
@@ -33,13 +32,7 @@
RETRY_EXCEPTIONS = (exceptions.TimeoutException, paramiko.SSHException,
- socket.error)
-if six.PY2:
- # NOTE(ralonsoh): TimeoutError was added in 3.3 and corresponds to
- # OSError(errno.ETIMEDOUT)
- RETRY_EXCEPTIONS += (OSError, )
-else:
- RETRY_EXCEPTIONS += (TimeoutError, )
+ socket.error, TimeoutError)
class Client(ssh.Client):
@@ -293,6 +286,13 @@
command=shell, host=self.host, script=script, stderr=stderr,
stdout=stdout, exit_status=exit_status)
+ def get_hostname(self):
+ """Retrieve the remote machine hostname"""
+ try:
+ return self.exec_command('hostname')
+ except exceptions.SSHExecCommandFailed:
+ return self.exec_command('cat /etc/hostname')
+
def _buffer_to_string(data_buffer, encoding):
return data_buffer.decode(encoding).replace("\r\n", "\n").replace(
diff --git a/neutron_tempest_plugin/config.py b/neutron_tempest_plugin/config.py
index c0e21c1..2290d0f 100644
--- a/neutron_tempest_plugin/config.py
+++ b/neutron_tempest_plugin/config.py
@@ -120,18 +120,6 @@
'This is required if advanced image has to be used in '
'tests.'),
- # Enable/disable metadata over IPv6 tests. This feature naturally
- # does not have an API extension, but at the time of first implementation
- # it works only on victoria+ deployments with dhcp- and/or l3-agents
- # (which in the gate is the same as non-ovn jobs).
- cfg.BoolOpt('ipv6_metadata',
- default=True,
- help='Enable metadata over IPv6 tests where the feature is '
- 'implemented, disable where it is not. Use this instead '
- 'of network-feature-enabled.api_extensions, since API '
- 'extensions do not make sense for a feature not '
- 'exposed on the API.'),
-
# Option for creating QoS policies configures as "shared".
# The default is false in order to prevent undesired usage
# while testing in parallel.
diff --git a/neutron_tempest_plugin/fwaas/api/test_fwaasv2_extensions.py b/neutron_tempest_plugin/fwaas/api/test_fwaasv2_extensions.py
index f085e6d..0dd18f1 100644
--- a/neutron_tempest_plugin/fwaas/api/test_fwaasv2_extensions.py
+++ b/neutron_tempest_plugin/fwaas/api/test_fwaasv2_extensions.py
@@ -13,7 +13,6 @@
# under the License.
import netaddr
-import six
from tempest.common import utils
from tempest import config
@@ -212,7 +211,7 @@
# show a created firewall rule
fw_rule = self.firewall_rules_client.show_firewall_rule(
self.fw_rule_1['id'])
- for key, value in six.iteritems(fw_rule['firewall_rule']):
+ for key, value in fw_rule['firewall_rule'].items():
if key != 'firewall_policy_id':
self.assertEqual(self.fw_rule_1[key], value)
# This check is placed because we cannot modify policy during
@@ -258,7 +257,7 @@
fw_policy = self.firewall_policies_client.show_firewall_policy(
self.fw_policy_1['id'])
fw_policy = fw_policy['firewall_policy']
- for key, value in six.iteritems(fw_policy):
+ for key, value in fw_policy.items():
self.assertEqual(self.fw_policy_1[key], value)
@decorators.idempotent_id('48dfcd75-3924-479d-bb65-b3ed33397663')
@@ -283,7 +282,7 @@
fwg_id)
fwg = firewall_group['firewall_group']
- for key, value in six.iteritems(fwg):
+ for key, value in fwg.items():
if key == 'status':
continue
self.assertEqual(created_firewall_group[key], value)
diff --git a/neutron_tempest_plugin/neutron_dynamic_routing/scenario/base.py b/neutron_tempest_plugin/neutron_dynamic_routing/scenario/base.py
index f752436..b4be57b 100644
--- a/neutron_tempest_plugin/neutron_dynamic_routing/scenario/base.py
+++ b/neutron_tempest_plugin/neutron_dynamic_routing/scenario/base.py
@@ -19,7 +19,6 @@
import time
import netaddr
-import six
from os_ken.tests.integrated.common import docker_base as ctn_base
from tempest.common import utils
@@ -125,10 +124,10 @@
while True:
with self.lock:
try:
- yield (i, str(six.next(subnet_gen)))
+ yield (i, str(next(subnet_gen)))
except StopIteration:
subnet_gen = netaddr.iter_iprange(start, end, step=step)
- yield (i, str(six.next(subnet_gen)))
+ yield (i, str(next(subnet_gen)))
i += 1
def net_resource_cleanup(self):
diff --git a/neutron_tempest_plugin/neutron_dynamic_routing/scenario/base_test_proto.py b/neutron_tempest_plugin/neutron_dynamic_routing/scenario/base_test_proto.py
index 1bcf5b1..643620f 100644
--- a/neutron_tempest_plugin/neutron_dynamic_routing/scenario/base_test_proto.py
+++ b/neutron_tempest_plugin/neutron_dynamic_routing/scenario/base_test_proto.py
@@ -14,7 +14,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-import six
from tempest import config
from neutron_tempest_plugin.neutron_dynamic_routing.scenario import base
@@ -28,7 +27,7 @@
def _test_check_neighbor_established(self, ip_version):
self.bgp_peer_args[0]['peer_ip'] = self.r_as_ip[0].split('/')[0]
- num, subnet = six.next(self.tnet_gen)
+ num, subnet = next(self.tnet_gen)
mask = '/' + str(self.TPool.prefixlen)
TNet = base.Net(name='', net=subnet, mask=self.TPool.prefixlen,
cidr=subnet + mask, router=None)
@@ -47,7 +46,7 @@
def _test_check_advertised_tenant_network(self, ip_version):
self.bgp_peer_args[0]['peer_ip'] = self.r_as_ip[0].split('/')[0]
- num, subnet = six.next(self.tnet_gen)
+ num, subnet = next(self.tnet_gen)
mask = '/' + str(self.TPool.prefixlen)
TNet = base.Net(name='', net=subnet, mask=self.TPool.prefixlen,
cidr=subnet + mask, router=None)
@@ -73,7 +72,7 @@
tnets = []
tnets_cidr = []
for i in range(0, 3):
- num, subnet = six.next(self.tnet_gen)
+ num, subnet = next(self.tnet_gen)
mask = '/' + str(self.TPool.prefixlen)
TNet = base.Net(name='', net=subnet, mask=self.TPool.prefixlen,
cidr=subnet + mask, router=None)
@@ -102,7 +101,7 @@
for (bgp_peer_args, r_as_ip) in zip(self.bgp_peer_args,
self.r_as_ip):
bgp_peer_args['peer_ip'] = r_as_ip.split('/')[0]
- num, subnet = six.next(self.tnet_gen)
+ num, subnet = next(self.tnet_gen)
mask = '/' + str(self.TPool.prefixlen)
TNet = base.Net(name='', net=subnet, mask=self.TPool.prefixlen,
cidr=subnet + mask, router=None)
@@ -124,7 +123,7 @@
for (bgp_peer_args, r_as_ip) in zip(self.bgp_peer_args,
self.r_as_ip):
bgp_peer_args['peer_ip'] = r_as_ip.split('/')[0]
- num, subnet = six.next(self.tnet_gen)
+ num, subnet = next(self.tnet_gen)
mask = '/' + str(self.TPool.prefixlen)
TNet = base.Net(name='', net=subnet, mask=self.TPool.prefixlen,
cidr=subnet + mask, router=None)
diff --git a/neutron_tempest_plugin/neutron_dynamic_routing/scenario/basic/test_basic.py b/neutron_tempest_plugin/neutron_dynamic_routing/scenario/basic/test_basic.py
index 1c680f9..90a6815 100644
--- a/neutron_tempest_plugin/neutron_dynamic_routing/scenario/basic/test_basic.py
+++ b/neutron_tempest_plugin/neutron_dynamic_routing/scenario/basic/test_basic.py
@@ -15,7 +15,6 @@
# under the License.
from os_ken.tests.integrated.common import docker_base as ctn_base
-import six
from tempest import config
from tempest.lib import decorators
@@ -31,7 +30,7 @@
@decorators.idempotent_id('cc615252-c6cb-4d75-a70e-608fb2c3736a')
def test_schedule_added_speaker(self):
self.bgp_peer_args[0]['peer_ip'] = self.r_as_ip[0].split('/')[0]
- num, subnet = six.next(self.tnet_gen)
+ num, subnet = next(self.tnet_gen)
mask = '/' + str(self.TPool.prefixlen)
TNet = s_base.Net(name='', net=subnet, mask=self.TPool.prefixlen,
cidr=subnet + mask, router=None)
@@ -51,7 +50,7 @@
@decorators.idempotent_id('ce98c33c-0ffa-49ae-b365-da836406793b')
def test_unschedule_deleted_speaker(self):
self.bgp_peer_args[0]['peer_ip'] = self.r_as_ip[0].split('/')[0]
- num, subnet = six.next(self.tnet_gen)
+ num, subnet = next(self.tnet_gen)
mask = '/' + str(self.TPool.prefixlen)
TNet = s_base.Net(name='', net=subnet, mask=self.TPool.prefixlen,
cidr=subnet + mask, router=None)
@@ -77,7 +76,7 @@
@decorators.idempotent_id('aa6c565c-ded3-413b-8dc9-3928b3b0e38f')
def test_remove_add_speaker_agent(self):
self.bgp_peer_args[0]['peer_ip'] = self.r_as_ip[0].split('/')[0]
- num, subnet = six.next(self.tnet_gen)
+ num, subnet = next(self.tnet_gen)
mask = '/' + str(self.TPool.prefixlen)
TNet = s_base.Net(name='', net=subnet, mask=self.TPool.prefixlen,
cidr=subnet + mask, router=None)
diff --git a/neutron_tempest_plugin/scenario/base.py b/neutron_tempest_plugin/scenario/base.py
index 78b766b..752e536 100644
--- a/neutron_tempest_plugin/scenario/base.py
+++ b/neutron_tempest_plugin/scenario/base.py
@@ -21,6 +21,7 @@
from neutron_lib.api import validators
from neutron_lib import constants as neutron_lib_constants
from oslo_log import log
+from paramiko import ssh_exception as ssh_exc
from tempest.common.utils import net_utils
from tempest.common import waiters
from tempest.lib.common.utils import data_utils
@@ -121,9 +122,11 @@
if not kwargs.get('security_groups'):
kwargs['security_groups'] = [{'name': 'default'}]
- client = self.os_primary.servers_client
- if kwargs.get('availability_zone'):
- client = self.os_admin.servers_client
+ client = kwargs.pop('client', None)
+ if client is None:
+ client = self.os_primary.servers_client
+ if kwargs.get('availability_zone'):
+ client = self.os_admin.servers_client
server = client.create_server(
flavorRef=flavor_ref,
@@ -139,6 +142,10 @@
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
client.delete_server,
server['server']['id'])
+
+ self.wait_for_server_active(server['server'], client=client)
+ self.wait_for_guest_os_ready(server['server'], client=client)
+
return server
@classmethod
@@ -252,19 +259,20 @@
server_kwargs['name'] = server_name
self.server = self.create_server(**server_kwargs)
- self.wait_for_server_active(self.server['server'])
self.port = self.client.list_ports(network_id=self.network['id'],
device_id=self.server[
'server']['id'])['ports'][0]
self.fip = self.create_floatingip(port=self.port)
- def check_connectivity(self, host, ssh_user, ssh_key,
- servers=None, ssh_timeout=None):
- ssh_client = ssh.Client(host, ssh_user,
- pkey=ssh_key, timeout=ssh_timeout)
+ def check_connectivity(self, host, ssh_user=None, ssh_key=None,
+ servers=None, ssh_timeout=None, ssh_client=None):
+ # Either ssh_client or ssh_user+ssh_key is mandatory.
+ if ssh_client is None:
+ ssh_client = ssh.Client(host, ssh_user,
+ pkey=ssh_key, timeout=ssh_timeout)
try:
ssh_client.test_connection_auth()
- except lib_exc.SSHTimeout as ssh_e:
+ except (lib_exc.SSHTimeout, ssh_exc.AuthenticationException) as ssh_e:
LOG.debug(ssh_e)
self._log_console_output(servers)
self._log_local_network_status()
@@ -294,10 +302,26 @@
"for the console log", server['id'])
def _log_local_network_status(self):
- local_routes = ip_utils.IPCommand().list_routes()
- LOG.debug('Local routes:\n%s', '\n'.join(str(r) for r in local_routes))
- arp_table = ip_utils.arp_table()
- LOG.debug('Local ARP table:\n%s', '\n'.join(str(r) for r in arp_table))
+ self._log_ns_network_status()
+ for ns_name in ip_utils.IPCommand().list_namespaces():
+ self._log_ns_network_status(ns_name=ns_name)
+
+ def _log_ns_network_status(self, ns_name=None):
+ try:
+ local_ips = ip_utils.IPCommand(namespace=ns_name).list_addresses()
+ local_routes = ip_utils.IPCommand(namespace=ns_name).list_routes()
+ arp_table = ip_utils.arp_table()
+ except exceptions.ShellCommandFailed:
+ LOG.debug('Namespace %s has been deleted synchronously during the '
+ 'host network collection process', ns_name)
+ return
+
+ LOG.debug('Namespace %s; IP Addresses:\n%s',
+ ns_name, '\n'.join(str(r) for r in local_ips))
+ LOG.debug('Namespace %s; Local routes:\n%s',
+ ns_name, '\n'.join(str(r) for r in local_routes))
+ LOG.debug('Namespace %s; Local ARP table:\n%s',
+ ns_name, '\n'.join(str(r) for r in arp_table))
def _check_remote_connectivity(self, source, dest, count,
should_succeed=True,
@@ -379,12 +403,14 @@
fragmentation,
timeout=timeout, pattern=pattern,
forbid_packet_loss=forbid_packet_loss))
- except lib_exc.SSHTimeout as ssh_e:
+ except (lib_exc.SSHTimeout, ssh_exc.AuthenticationException) as ssh_e:
LOG.debug(ssh_e)
self._log_console_output(servers)
+ self._log_local_network_status()
raise
except AssertionError:
self._log_console_output(servers)
+ self._log_local_network_status()
raise
def ping_ip_address(self, ip_address, should_succeed=True,
@@ -452,7 +478,30 @@
self.wait_for_server_status(
server, constants.SERVER_STATUS_ACTIVE, client)
- def check_servers_hostnames(self, servers, timeout=None, log_errors=True):
+ def wait_for_guest_os_ready(self, server, client=None):
+ if not CONF.compute_feature_enabled.console_output:
+ LOG.debug('Console output not supported, cannot check if server '
+ '%s is ready.', server['id'])
+ return
+
+ client = client or self.os_primary.servers_client
+
+ def system_booted():
+ console_output = client.get_console_output(server['id'])['output']
+ for line in console_output.split('\n'):
+ if 'login:' in line.lower():
+ return True
+ return False
+
+ try:
+ utils.wait_until_true(system_booted, sleep=5)
+ except utils.WaitTimeout:
+ LOG.debug("No correct output in console of server %s found. "
+ "Guest operating system status can't be checked.",
+ server['id'])
+
+ def check_servers_hostnames(self, servers, timeout=None, log_errors=True,
+ external_port=None):
"""Compare hostnames of given servers with their names."""
try:
for server in servers:
@@ -460,7 +509,7 @@
if timeout:
kwargs['timeout'] = timeout
try:
- kwargs['port'] = (
+ kwargs['port'] = external_port or (
server['port_forwarding_tcp']['external_port'])
except KeyError:
pass
@@ -470,16 +519,18 @@
pkey=self.keypair['private_key'],
**kwargs)
self.assertIn(server['name'],
- ssh_client.exec_command('hostname'))
- except lib_exc.SSHTimeout as ssh_e:
+ ssh_client.get_hostname())
+ except (lib_exc.SSHTimeout, ssh_exc.AuthenticationException) as ssh_e:
LOG.debug(ssh_e)
if log_errors:
self._log_console_output(servers)
+ self._log_local_network_status()
raise
except AssertionError as assert_e:
LOG.debug(assert_e)
if log_errors:
self._log_console_output(servers)
+ self._log_local_network_status()
raise
def ensure_nc_listen(self, ssh_client, port, protocol, echo_msg=None,
@@ -504,9 +555,10 @@
return ssh_client.execute_script(
get_ncat_server_cmd(port, protocol, echo_msg),
become_root=True, combine_stderr=True)
- except lib_exc.SSHTimeout as ssh_e:
+ except (lib_exc.SSHTimeout, ssh_exc.AuthenticationException) as ssh_e:
LOG.debug(ssh_e)
self._log_console_output(servers)
+ self._log_local_network_status()
raise
def nc_client(self, ip_address, port, protocol):
diff --git a/neutron_tempest_plugin/scenario/test_connectivity.py b/neutron_tempest_plugin/scenario/test_connectivity.py
index 1a7468a..66c4789 100644
--- a/neutron_tempest_plugin/scenario/test_connectivity.py
+++ b/neutron_tempest_plugin/scenario/test_connectivity.py
@@ -65,6 +65,7 @@
for vm in vms:
self.wait_for_server_active(vm['server'])
+ self.wait_for_guest_os_ready(vm['server'])
return vms
@@ -231,6 +232,7 @@
networks=[{'uuid': network['id']}],
security_groups=[{'name': self.secgroup['name']}])
self.wait_for_server_active(vm['server'])
+ self.wait_for_guest_os_ready(vm['server'])
vm_port = self.client.list_ports(
network_id=network['id'], device_id=vm['server']['id'])['ports'][0]
diff --git a/neutron_tempest_plugin/scenario/test_dhcp.py b/neutron_tempest_plugin/scenario/test_dhcp.py
new file mode 100644
index 0000000..b95eaa2
--- /dev/null
+++ b/neutron_tempest_plugin/scenario/test_dhcp.py
@@ -0,0 +1,94 @@
+# 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 oslo_log import log
+from paramiko import ssh_exception as ssh_exc
+from tempest.common import utils
+from tempest.lib.common.utils import data_utils
+from tempest.lib import decorators
+from tempest.lib import exceptions as lib_exc
+
+from neutron_tempest_plugin.common import ssh
+from neutron_tempest_plugin import config
+from neutron_tempest_plugin.scenario import base
+
+CONF = config.CONF
+LOG = log.getLogger(__name__)
+
+
+class DHCPTest(base.BaseTempestTestCase):
+
+ credentials = ['primary', 'admin']
+ force_tenant_isolation = False
+
+ @classmethod
+ def resource_setup(cls):
+ super(DHCPTest, cls).resource_setup()
+ cls.rand_name = data_utils.rand_name(
+ cls.__name__.rsplit('.', 1)[-1])
+ cls.network = cls.create_network(name=cls.rand_name)
+ cls.subnet = cls.create_subnet(
+ network=cls.network, name=cls.rand_name)
+ cls.router = cls.create_router_by_client()
+ cls.create_router_interface(cls.router['id'], cls.subnet['id'])
+ cls.keypair = cls.create_keypair(name=cls.rand_name)
+ cls.security_group = cls.create_security_group(name=cls.rand_name)
+ cls.create_loginable_secgroup_rule(cls.security_group['id'])
+
+ @utils.requires_ext(extension='extra_dhcp_opt', service='network')
+ @decorators.idempotent_id('58f7c094-1980-4e03-b0d3-6c4dd27217b1')
+ def test_extra_dhcp_opts(self):
+ """This test case tests DHCP extra options configured for Neutron port.
+
+ Test is checking just extra option "15" which is domain-name
+ according to the RFC 2132:
+ https://tools.ietf.org/html/rfc2132#section-5.3
+
+ To test that option, there is spawned VM connected to the port with
+ configured extra_dhcp_opts and test asserts that search domain name is
+ configured inside VM in /etc/resolv.conf file
+ """
+
+ test_domain = "test.domain"
+ extra_dhcp_opts = [
+ {'opt_name': 'domain-name',
+ 'opt_value': '"%s"' % test_domain}]
+ port = self.create_port(
+ network=self.network, name=self.rand_name,
+ security_groups=[self.security_group['id']],
+ extra_dhcp_opts=extra_dhcp_opts)
+ floating_ip = self.create_floatingip(port=port)
+
+ server = self.create_server(
+ flavor_ref=CONF.compute.flavor_ref,
+ image_ref=CONF.compute.image_ref,
+ key_name=self.keypair['name'],
+ networks=[{'port': port['id']}])
+ self.wait_for_server_active(server['server'])
+ self.wait_for_guest_os_ready(server['server'])
+
+ try:
+ ssh_client = ssh.Client(
+ floating_ip['floating_ip_address'],
+ CONF.validation.image_ssh_user,
+ pkey=self.keypair['private_key'])
+ vm_resolv_conf = ssh_client.exec_command(
+ "cat /etc/resolv.conf")
+ self.assertIn(test_domain, vm_resolv_conf)
+ except (lib_exc.SSHTimeout,
+ ssh_exc.AuthenticationException,
+ AssertionError) as error:
+ LOG.debug(error)
+ self._log_console_output([server])
+ self._log_local_network_status()
+ raise
diff --git a/neutron_tempest_plugin/scenario/test_floatingip.py b/neutron_tempest_plugin/scenario/test_floatingip.py
index 6d4d830..262f429 100644
--- a/neutron_tempest_plugin/scenario/test_floatingip.py
+++ b/neutron_tempest_plugin/scenario/test_floatingip.py
@@ -341,6 +341,15 @@
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)
+
@decorators.idempotent_id('5eb48aea-eaba-4c20-8a6f-7740070a0aa3')
def test_qos(self):
"""Test floating IP is binding to a QoS policy with
@@ -351,6 +360,8 @@
received / elapsed time.
"""
+ self.skip_if_no_extension_enabled_in_l3_agents("fip_qos")
+
self._test_basic_resources()
policy_id = self._create_qos_policy()
ssh_client = self._create_ssh_client()
@@ -417,6 +428,7 @@
servers.append(server)
for server in servers:
self.wait_for_server_active(server)
+ self.wait_for_guest_os_ready(server)
self.fip = self.create_floatingip(port=ports[0])
self.check_connectivity(self.fip['floating_ip_address'],
diff --git a/neutron_tempest_plugin/scenario/test_internal_dns.py b/neutron_tempest_plugin/scenario/test_internal_dns.py
index d19286c..406af3d 100644
--- a/neutron_tempest_plugin/scenario/test_internal_dns.py
+++ b/neutron_tempest_plugin/scenario/test_internal_dns.py
@@ -52,13 +52,14 @@
{'name': self.security_groups[-1]['name']}],
name='leia')
self.wait_for_server_active(leia['server'])
+ self.wait_for_guest_os_ready(leia['server'])
ssh_client = ssh.Client(
self.fip['floating_ip_address'],
CONF.validation.image_ssh_user,
pkey=self.keypair['private_key'])
- self.assertIn('luke', ssh_client.exec_command('hostname'))
+ self.assertIn('luke', ssh_client.get_hostname())
leia_port = self.client.list_ports(
network_id=self.network['id'],
diff --git a/neutron_tempest_plugin/scenario/test_ipv6.py b/neutron_tempest_plugin/scenario/test_ipv6.py
index 02e2846..4237d4f 100644
--- a/neutron_tempest_plugin/scenario/test_ipv6.py
+++ b/neutron_tempest_plugin/scenario/test_ipv6.py
@@ -15,6 +15,7 @@
from neutron_lib import constants as lib_constants
from oslo_log import log
+from paramiko import ssh_exception as ssh_exc
from tempest.common import utils as tempest_utils
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
@@ -83,6 +84,7 @@
@tempest_utils.requires_ext(extension="router", service="network")
def resource_setup(cls):
super(IPv6Test, cls).resource_setup()
+ cls.reserve_external_subnet_cidrs()
cls._setup_basic_resources()
@classmethod
@@ -108,16 +110,22 @@
return True
return False
- # Set NIC with IPv6 to be UP and wait until IPv6 address will be
- # configured on this NIC
- turn_nic6_on(ssh_client, ipv6_port)
- # And check if IPv6 address will be properly configured on this NIC
- utils.wait_until_true(
- lambda: guest_has_address(ipv6_address),
- timeout=120,
- exception=RuntimeError(
- "Timed out waiting for IP address {!r} to be configured in "
- "the VM {!r}.".format(ipv6_address, vm['id'])))
+ try:
+ # Set NIC with IPv6 to be UP and wait until IPv6 address will be
+ # configured on this NIC
+ turn_nic6_on(ssh_client, ipv6_port)
+ # And check if IPv6 address will be properly configured on this NIC
+ utils.wait_until_true(
+ lambda: guest_has_address(ipv6_address),
+ timeout=120,
+ exception=RuntimeError(
+ "Timed out waiting for IP address {!r} to be configured "
+ "in the VM {!r}.".format(ipv6_address, vm['id'])))
+ except (lib_exc.SSHTimeout, ssh_exc.AuthenticationException) as ssh_e:
+ LOG.debug(ssh_e)
+ self._log_console_output([vm])
+ self._log_local_network_status()
+ raise
def _test_ipv6_hotplug(self, ra_mode, address_mode):
ipv6_networks = [self.create_network() for _ in range(2)]
@@ -138,6 +146,7 @@
}
vm = self.create_server(**server_kwargs)['server']
self.wait_for_server_active(vm)
+ self.wait_for_guest_os_ready(vm)
ipv4_port = self.client.list_ports(
network_id=self.network['id'],
device_id=vm['id'])['ports'][0]
diff --git a/neutron_tempest_plugin/scenario/test_metadata.py b/neutron_tempest_plugin/scenario/test_metadata.py
index c78ff69..91ecc97 100644
--- a/neutron_tempest_plugin/scenario/test_metadata.py
+++ b/neutron_tempest_plugin/scenario/test_metadata.py
@@ -16,6 +16,7 @@
from neutron_lib import constants as nlib_const
from oslo_log import log as logging
+from tempest.common import utils
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
import testtools
@@ -45,10 +46,17 @@
force_tenant_isolation = False
@classmethod
+ def skip_checks(cls):
+ super(MetadataTest, cls).skip_checks()
+ if not utils.is_network_feature_enabled('ipv6_metadata'):
+ raise cls.skipException("Metadata over IPv6 is not enabled")
+
+ @classmethod
def resource_setup(cls):
super(MetadataTest, cls).resource_setup()
cls.rand_name = data_utils.rand_name(
cls.__name__.rsplit('.', 1)[-1])
+ cls.reserve_external_subnet_cidrs()
cls.network = cls.create_network(name=cls.rand_name)
cls.subnet_v4 = cls.create_subnet(
network=cls.network, name=cls.rand_name)
@@ -113,11 +121,9 @@
return interface
@testtools.skipUnless(
- (CONF.neutron_plugin_options.ipv6_metadata and
- (CONF.neutron_plugin_options.advanced_image_ref or
- CONF.neutron_plugin_options.default_image_is_advanced)),
- 'Advanced image and neutron_plugin_options.ipv6_metadata=True '
- 'is required to run this test.')
+ CONF.neutron_plugin_options.advanced_image_ref or
+ CONF.neutron_plugin_options.default_image_is_advanced,
+ 'Advanced image is required to run this test.')
@decorators.idempotent_id('e680949a-f1cc-11ea-b49a-cba39bbbe5ad')
def test_metadata_routed(self):
use_advanced_image = (
@@ -126,6 +132,7 @@
vm = self._create_server_with_network(
self.network, use_advanced_image=use_advanced_image)
self.wait_for_server_active(server=vm.server)
+ self.wait_for_guest_os_ready(vm.server)
self._assert_has_ssh_connectivity(vm.ssh_client)
interface = self._get_primary_interface(vm.ssh_client)
diff --git a/neutron_tempest_plugin/scenario/test_multicast.py b/neutron_tempest_plugin/scenario/test_multicast.py
index b2ea8ae..79f835e 100644
--- a/neutron_tempest_plugin/scenario/test_multicast.py
+++ b/neutron_tempest_plugin/scenario/test_multicast.py
@@ -201,6 +201,7 @@
security_groups=[{'name': self.secgroup['security_group']['name']}]
)['server']
self.wait_for_server_active(server)
+ self.wait_for_guest_os_ready(server)
port = self.client.list_ports(
network_id=self.network['id'], device_id=server['id'])['ports'][0]
server['fip'] = self.create_floatingip(port=port)
diff --git a/neutron_tempest_plugin/scenario/test_port_forwardings.py b/neutron_tempest_plugin/scenario/test_port_forwardings.py
index 3158ea0..a4711ae 100644
--- a/neutron_tempest_plugin/scenario/test_port_forwardings.py
+++ b/neutron_tempest_plugin/scenario/test_port_forwardings.py
@@ -45,9 +45,14 @@
cls.secgroup = cls.create_security_group(
name=data_utils.rand_name("test_port_secgroup"))
cls.create_loginable_secgroup_rule(secgroup_id=cls.secgroup['id'])
+ udp_sg_rule = {'protocol': constants.PROTO_NAME_UDP,
+ 'direction': constants.INGRESS_DIRECTION,
+ 'remote_ip_prefix': '0.0.0.0/0'}
+ cls.create_secgroup_rules(
+ [udp_sg_rule], secgroup_id=cls.secgroup['id'])
cls.keypair = cls.create_keypair()
- def _prepare_resources(self, num_servers, internal_tcp_port, protocol,
+ def _prepare_resources(self, num_servers, internal_tcp_port=22,
external_port_base=1025):
servers = []
for i in range(1, num_servers + 1):
@@ -65,6 +70,7 @@
networks=[{'port': port['id']}])['server']
server['name'] = name
self.wait_for_server_active(server)
+ self.wait_for_guest_os_ready(server)
server['port_forwarding_tcp'] = self.create_port_forwarding(
self.fip['id'],
internal_port_id=port['id'],
@@ -82,7 +88,7 @@
servers.append(server)
return servers
- def _test_udp_port_forwarding(self, servers):
+ def _test_udp_port_forwarding(self, servers, timeout=None):
def _message_received(server, ssh_client, expected_msg):
self.nc_listen(ssh_client,
@@ -103,50 +109,38 @@
CONF.validation.image_ssh_user,
pkey=self.keypair['private_key'],
port=server['port_forwarding_tcp']['external_port'])
+ wait_params = {
+ 'exception': RuntimeError(
+ "Timed out waiting for message from server {!r} ".format(
+ server['id']))
+ }
+ if timeout:
+ wait_params['timeout'] = timeout
utils.wait_until_true(
lambda: _message_received(server, ssh_client, expected_msg),
- exception=RuntimeError(
- "Timed out waiting for message from server {!r} ".format(
- server['id'])))
+ **wait_params)
- @test.unstable_test("bug 1896735")
@decorators.idempotent_id('ab40fc48-ca8d-41a0-b2a3-f6679c847bfe')
def test_port_forwarding_to_2_servers(self):
- udp_sg_rule = {'protocol': constants.PROTO_NAME_UDP,
- 'direction': constants.INGRESS_DIRECTION,
- 'remote_ip_prefix': '0.0.0.0/0'}
- self.create_secgroup_rules(
- [udp_sg_rule], secgroup_id=self.secgroup['id'])
- servers = self._prepare_resources(
- num_servers=2, internal_tcp_port=22,
- protocol=constants.PROTO_NAME_TCP)
+ servers = self._prepare_resources(num_servers=2,
+ external_port_base=1035)
# Test TCP port forwarding by SSH to each server
self.check_servers_hostnames(servers)
# And now test UDP port forwarding using nc
self._test_udp_port_forwarding(servers)
- @test.unstable_test("bug 1896735")
@decorators.idempotent_id('aa19d46c-a4a6-11ea-bb37-0242ac130002')
def test_port_forwarding_editing_and_deleting_tcp_rule(self):
- server = self._prepare_resources(
- num_servers=1, internal_tcp_port=22,
- protocol=constants.PROTO_NAME_TCP,
- external_port_base=1035)
+ test_ext_port = 3333
+ server = self._prepare_resources(num_servers=1,
+ external_port_base=1045)
fip_id = server[0]['port_forwarding_tcp']['floatingip_id']
pf_id = server[0]['port_forwarding_tcp']['id']
# Check connectivity with the original parameters
self.check_servers_hostnames(server)
- # Use a reasonable timeout to verify that connections will not
- # happen. Default would be 196 seconds, which is an overkill.
- test_ssh_connect_timeout = 6
-
- # Update external port and check connectivity with original parameters
- # Port under server[0]['port_forwarding_tcp']['external_port'] should
- # not answer at this point.
-
- def fip_pf_connectivity():
+ def fip_pf_connectivity(test_ssh_connect_timeout=60):
try:
self.check_servers_hostnames(
server, timeout=test_ssh_connect_timeout)
@@ -155,9 +149,13 @@
return False
def no_fip_pf_connectivity():
- return not fip_pf_connectivity()
+ return not fip_pf_connectivity(6)
- self.client.update_port_forwarding(fip_id, pf_id, external_port=3333)
+ # Update external port and check connectivity with original parameters
+ # Port under server[0]['port_forwarding_tcp']['external_port'] should
+ # not answer at this point.
+ self.client.update_port_forwarding(fip_id, pf_id,
+ external_port=test_ext_port)
utils.wait_until_true(
no_fip_pf_connectivity,
exception=RuntimeError(
@@ -167,7 +165,7 @@
server[0]['port_forwarding_tcp']['external_port'])))
# Check connectivity with the new parameters
- server[0]['port_forwarding_tcp']['external_port'] = 3333
+ server[0]['port_forwarding_tcp']['external_port'] = test_ext_port
utils.wait_until_true(
fip_pf_connectivity,
exception=RuntimeError(
@@ -187,3 +185,106 @@
"port {!r} is still possible.".format(
server[0]['id'],
server[0]['port_forwarding_tcp']['external_port'])))
+
+ @test.unstable_test("bug 1896735")
+ @decorators.idempotent_id('6d05b1b2-6109-4c30-b402-1503f4634acb')
+ def test_port_forwarding_editing_and_deleting_udp_rule(self):
+ test_ext_port = 3344
+ server = self._prepare_resources(num_servers=1,
+ external_port_base=1055)
+ fip_id = server[0]['port_forwarding_udp']['floatingip_id']
+ pf_id = server[0]['port_forwarding_udp']['id']
+
+ # Check connectivity with the original parameters
+ self.check_servers_hostnames(server)
+
+ def fip_pf_udp_connectivity(test_udp_timeout=60):
+ try:
+ self._test_udp_port_forwarding(server, test_udp_timeout)
+ return True
+ except (AssertionError, RuntimeError):
+ return False
+
+ def no_fip_pf_udp_connectivity():
+ return not fip_pf_udp_connectivity(6)
+
+ # Update external port and check connectivity with original parameters
+ # Port under server[0]['port_forwarding_udp']['external_port'] should
+ # not answer at this point.
+ self.client.update_port_forwarding(fip_id, pf_id,
+ external_port=test_ext_port)
+ utils.wait_until_true(
+ no_fip_pf_udp_connectivity,
+ exception=RuntimeError(
+ "Connection to the server {!r} through "
+ "port {!r} is still possible.".format(
+ server[0]['id'],
+ server[0]['port_forwarding_udp']['external_port'])))
+
+ # Check connectivity with the new parameters
+ server[0]['port_forwarding_udp']['external_port'] = test_ext_port
+ utils.wait_until_true(
+ fip_pf_udp_connectivity,
+ exception=RuntimeError(
+ "Connection to the server {!r} through "
+ "port {!r} is not possible.".format(
+ server[0]['id'],
+ server[0]['port_forwarding_udp']['external_port'])))
+
+ # Remove port forwarding and ensure connection stops working.
+ self.client.delete_port_forwarding(fip_id, pf_id)
+ self.assertRaises(lib_exc.NotFound, self.client.get_port_forwarding,
+ fip_id, pf_id)
+ utils.wait_until_true(
+ no_fip_pf_udp_connectivity,
+ exception=RuntimeError(
+ "Connection to the server {!r} through "
+ "port {!r} is still possible.".format(
+ server[0]['id'],
+ server[0]['port_forwarding_udp']['external_port'])))
+
+ @test.unstable_test("bug 1896735")
+ @decorators.idempotent_id('5971881d-06a0-459e-b636-ce5d1929e2d4')
+ def test_port_forwarding_to_2_fixed_ips(self):
+ port = self.create_port(self.network,
+ security_groups=[self.secgroup['id']])
+ name = data_utils.rand_name("server-0")
+ server = self.create_server(flavor_ref=CONF.compute.flavor_ref,
+ image_ref=CONF.compute.image_ref, key_name=self.keypair['name'],
+ name=name, networks=[{'port': port['id']}])['server']
+ server['name'] = name
+ self.wait_for_server_active(server)
+ self.wait_for_guest_os_ready(server)
+
+ # Add a second fixed_ip address to port (same subnet)
+ internal_subnet_id = port['fixed_ips'][0]['subnet_id']
+ port['fixed_ips'].append({'subnet_id': internal_subnet_id})
+ port = self.update_port(port, fixed_ips=port['fixed_ips'])
+ internal_ip_address1 = port['fixed_ips'][0]['ip_address']
+ internal_ip_address2 = port['fixed_ips'][1]['ip_address']
+ pfs = []
+ for ip_address, external_port in [(internal_ip_address1, 1066),
+ (internal_ip_address2, 1067)]:
+ pf = self.create_port_forwarding(
+ self.fip['id'], internal_port_id=port['id'],
+ internal_ip_address=ip_address,
+ internal_port=22, external_port=external_port,
+ protocol=constants.PROTO_NAME_TCP)
+ pfs.append(pf)
+
+ test_ssh_connect_timeout = 32
+ number_of_connects = 0
+ for pf in pfs:
+ try:
+ self.check_servers_hostnames(
+ [server], timeout=test_ssh_connect_timeout,
+ external_port=pf['external_port'])
+ number_of_connects += 1
+ except (AssertionError, lib_exc.SSHTimeout):
+ pass
+
+ # TODO(flaviof): Quite possibly, the server is using only one of the
+ # fixed ips associated with the neutron port. Being so, we should not
+ # fail the test, as long as at least one connection was successful.
+ self.assertGreaterEqual(
+ number_of_connects, 1, "Did not connect via FIP port forwarding")
diff --git a/neutron_tempest_plugin/scenario/test_qos.py b/neutron_tempest_plugin/scenario/test_qos.py
index 9e1f436..77520a7 100644
--- a/neutron_tempest_plugin/scenario/test_qos.py
+++ b/neutron_tempest_plugin/scenario/test_qos.py
@@ -175,6 +175,7 @@
server = self.create_server(**server_kwargs)
self.wait_for_server_active(server['server'])
+ self.wait_for_guest_os_ready(server['server'])
self.check_connectivity(self.fip['floating_ip_address'],
CONF.validation.image_ssh_user,
keypair['private_key'])
diff --git a/neutron_tempest_plugin/scenario/test_security_groups.py b/neutron_tempest_plugin/scenario/test_security_groups.py
index 23a5224..9059a2f 100644
--- a/neutron_tempest_plugin/scenario/test_security_groups.py
+++ b/neutron_tempest_plugin/scenario/test_security_groups.py
@@ -33,13 +33,15 @@
required_extensions = ['router', 'security-group']
def _verify_http_connection(self, ssh_client, ssh_server,
- test_ip, test_port, should_pass=True):
+ test_ip, test_port, servers, should_pass=True):
"""Verify if HTTP connection works using remote hosts.
:param ssh.Client ssh_client: The client host active SSH client.
:param ssh.Client ssh_server: The HTTP server host active SSH client.
:param string test_ip: IP address of HTTP server
:param string test_port: Port of HTTP server
+ :param list servers: List of servers for which console output will be
+ logged in case when test case
:param bool should_pass: Wheter test should pass or not.
:return: if passed or not
@@ -57,6 +59,8 @@
except Exception as e:
if not should_pass:
return
+ self._log_console_output(servers)
+ self._log_local_network_status()
raise e
@classmethod
@@ -378,6 +382,7 @@
ssh_clients[0],
ssh_clients[2],
test_ip, port,
+ servers,
should_pass=False)
# add two remote-group rules with port-ranges
@@ -399,7 +404,8 @@
self._verify_http_connection(
ssh_clients[0],
ssh_clients[2],
- test_ip, port)
+ test_ip, port,
+ servers)
@decorators.idempotent_id('f07d0159-8f9e-4faa-87f5-a869ab0ad490')
def test_intra_sg_isolation(self):
diff --git a/neutron_tempest_plugin/scenario/test_trunk.py b/neutron_tempest_plugin/scenario/test_trunk.py
index 585af06..8f260ea 100644
--- a/neutron_tempest_plugin/scenario/test_trunk.py
+++ b/neutron_tempest_plugin/scenario/test_trunk.py
@@ -15,6 +15,7 @@
import collections
from neutron_lib import constants
+from neutron_lib.utils import test
from oslo_log import log as logging
from tempest.common import utils as tutils
from tempest.lib.common.utils import data_utils
@@ -161,6 +162,7 @@
def _configure_vlan_subport(self, vm, vlan_tag, vlan_subnet):
self.wait_for_server_active(server=vm.server)
+ self.wait_for_guest_os_ready(vm.server)
self._wait_for_trunk(trunk=vm.trunk)
self._wait_for_port(port=vm.port)
self._wait_for_port(port=vm.subport)
@@ -199,6 +201,7 @@
vm2 = self._create_server_with_trunk_port()
for vm in (vm1, vm2):
self.wait_for_server_active(server=vm.server)
+ self.wait_for_guest_os_ready(vm.server)
self._wait_for_trunk(vm.trunk)
self._assert_has_ssh_connectivity(vm.ssh_client)
@@ -244,6 +247,7 @@
self._wait_for_trunk(vm.trunk)
self._assert_has_ssh_connectivity(vm1.ssh_client)
+ @test.unstable_test("bug 1897796")
@testtools.skipUnless(
(CONF.neutron_plugin_options.advanced_image_ref or
CONF.neutron_plugin_options.default_image_is_advanced),
@@ -267,6 +271,9 @@
use_advanced_image=use_advanced_image)
for vm in [vm1, vm2]:
+ self.check_connectivity(
+ host=vm.floating_ip['floating_ip_address'],
+ ssh_client=vm.ssh_client)
self._configure_vlan_subport(vm=vm,
vlan_tag=vlan_tag,
vlan_subnet=vlan_subnet)
@@ -325,6 +332,7 @@
use_advanced_image=use_advanced_image)
for role in ['migrate', 'connection_test']:
self.wait_for_server_active(servers[role].server)
+ self.wait_for_guest_os_ready(servers[role].server)
self._configure_vlan_subport(vm=servers[role],
vlan_tag=vlan_tag,
vlan_subnet=vlan_subnet)
@@ -377,6 +385,7 @@
vlan_subnet=vlan_subnet)
for vm in vms:
self.wait_for_server_active(vm.server)
+ self.wait_for_guest_os_ready(vm.server)
# allow ICMP traffic
sg_rule = self.create_pingable_secgroup_rule(self.security_group['id'])
diff --git a/neutron_tempest_plugin/services/network/json/network_client.py b/neutron_tempest_plugin/services/network/json/network_client.py
index f056c7f..2678d73 100644
--- a/neutron_tempest_plugin/services/network/json/network_client.py
+++ b/neutron_tempest_plugin/services/network/json/network_client.py
@@ -11,9 +11,9 @@
# under the License.
import time
+from urllib import parse as urlparse
from oslo_serialization import jsonutils
-from six.moves.urllib import parse as urlparse
from tempest.lib.common import rest_client as service_client
from tempest.lib import exceptions as lib_exc
@@ -923,8 +923,6 @@
return service_client.ResponseBody(resp, body)
def list_security_groups(self, **kwargs):
- post_body = {'security_groups': kwargs}
- body = jsonutils.dumps(post_body)
uri = '%s/security-groups' % self.uri_prefix
if kwargs:
uri += '?' + urlparse.urlencode(kwargs, doseq=1)
@@ -941,8 +939,6 @@
return service_client.ResponseBody(resp, body)
def list_ports(self, **kwargs):
- post_body = {'ports': kwargs}
- body = jsonutils.dumps(post_body)
uri = '%s/ports' % self.uri_prefix
if kwargs:
uri += '?' + urlparse.urlencode(kwargs, doseq=1)
@@ -952,8 +948,6 @@
return service_client.ResponseBody(resp, body)
def list_floatingips(self, **kwargs):
- post_body = {'floatingips': kwargs}
- body = jsonutils.dumps(post_body)
uri = '%s/floatingips' % self.uri_prefix
if kwargs:
uri += '?' + urlparse.urlencode(kwargs, doseq=1)
diff --git a/requirements.txt b/requirements.txt
index 3edf7dc..47dd923 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -11,7 +11,6 @@
oslo.serialization!=2.19.1,>=2.18.0 # Apache-2.0
oslo.utils>=3.33.0 # Apache-2.0
paramiko>=2.0.0 # LGPLv2.1+
-six>=1.10.0 # MIT
tempest>=17.1.0 # Apache-2.0
tenacity>=3.2.1 # Apache-2.0
ddt>=1.0.1 # MIT
diff --git a/tox.ini b/tox.ini
index eecd16e..3c18fbf 100644
--- a/tox.ini
+++ b/tox.ini
@@ -14,7 +14,7 @@
OS_STDOUT_CAPTURE={env:OS_STDOUT_CAPTURE:true}
OS_STDERR_CAPTURE={env:OS_STDERR_CAPTURE:true}
deps =
- -c{env:UPPER_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master}
+ -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master}
-r{toxinidir}/test-requirements.txt
commands = stestr run --slowest {posargs}
diff --git a/zuul.d/base.yaml b/zuul.d/base.yaml
index 77947fa..cc1479b 100644
--- a/zuul.d/base.yaml
+++ b/zuul.d/base.yaml
@@ -25,7 +25,6 @@
tempest_plugins:
- neutron-tempest-plugin
devstack_services:
- tls-proxy: false
tempest: true
neutron-dns: true
neutron-qos: true
@@ -38,6 +37,17 @@
neutron-tag-ports-during-bulk-creation: true
br-ex-tcpdump: true
br-int-flows: true
+ # Cinder services
+ c-api: false
+ c-bak: false
+ c-sch: false
+ c-vol: false
+ cinder: false
+ # We don't need Swift to be run in the Neutron jobs
+ s-account: false
+ s-container: false
+ s-object: false
+ s-proxy: false
devstack_local_conf:
post-config:
$NEUTRON_CONF:
@@ -64,11 +74,6 @@
$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:
@@ -99,7 +104,10 @@
# default test timeout set to 1200 seconds may be not enough if job is
# run on slow node
tempest_test_timeout: 2400
- tempest_test_regex: ^neutron_tempest_plugin\.scenario
+ tempest_test_regex: "\
+ (^neutron_tempest_plugin.scenario)|\
+ (^tempest.api.compute.servers.test_attach_interfaces)|\
+ (^tempest.api.compute.servers.test_multiple_create)"
devstack_localrc:
PHYSICAL_NETWORK: default
CIRROS_VERSION: 0.5.1
@@ -108,6 +116,4 @@
ADVANCED_INSTANCE_TYPE: ds512M
ADVANCED_INSTANCE_USER: ubuntu
BUILD_TIMEOUT: 784
- devstack_services:
- cinder: true
-
+ tempest_concurrency: 3 # out of 4
diff --git a/zuul.d/master_jobs.yaml b/zuul.d/master_jobs.yaml
index 71dfcb2..5325f67 100644
--- a/zuul.d/master_jobs.yaml
+++ b/zuul.d/master_jobs.yaml
@@ -79,9 +79,13 @@
- uplink-status-propagation
network_api_extensions_tempest:
- dvr
+ network_available_features: &available_features
+ - ipv6_metadata
tempest_test_regex: ^neutron_tempest_plugin\.api
devstack_services:
neutron-log: true
+ devstack_localrc:
+ NEUTRON_DEPLOY_MOD_WSGI: true
devstack_local_conf:
post-config:
# NOTE(slaweq): We can get rid of this hardcoded absolute path when
@@ -99,6 +103,7 @@
timeout: 10000
vars:
network_api_extensions: *api_extensions
+ network_available_features: *available_features
devstack_localrc:
Q_AGENT: openvswitch
NETWORK_API_EXTENSIONS: "{{ network_api_extensions | join(',') }}"
@@ -118,6 +123,8 @@
bridge_mappings: public:br-ex
test-config:
$TEMPEST_CONFIG:
+ network-feature-enabled:
+ available_features: "{{ network_available_features | join(',') }}"
neutron_plugin_options:
available_type_drivers: flat,vlan,local,vxlan
@@ -127,6 +134,7 @@
timeout: 10000
vars:
network_api_extensions: *api_extensions
+ network_available_features: *available_features
# TODO(slaweq): remove trunks subport_connectivity test from blacklist
# when bug https://bugs.launchpad.net/neutron/+bug/1838760 will be fixed
tempest_black_regex: "(^neutron_tempest_plugin.scenario.test_trunk.TrunkTest.test_subport_connectivity)"
@@ -151,6 +159,8 @@
firewall_driver: iptables_hybrid
test-config:
$TEMPEST_CONFIG:
+ network-feature-enabled:
+ available_features: "{{ network_available_features | join(',') }}"
neutron_plugin_options:
available_type_drivers: flat,vlan,local,vxlan
@@ -163,6 +173,7 @@
pre-run: playbooks/linuxbridge-scenario-pre-run.yaml
vars:
network_api_extensions: *api_extensions
+ network_available_features: *available_features
devstack_localrc:
Q_AGENT: linuxbridge
NETWORK_API_EXTENSIONS: "{{ network_api_extensions | join(',') }}"
@@ -181,6 +192,8 @@
type_drivers: flat,vlan,local,vxlan
test-config:
$TEMPEST_CONFIG:
+ network-feature-enabled:
+ available_features: "{{ network_available_features | join(',') }}"
neutron_plugin_options:
available_type_drivers: flat,vlan,local,vxlan
q_agent: linuxbridge
@@ -191,9 +204,17 @@
timeout: 10000
vars:
network_api_extensions: *api_extensions
- # TODO(haleyb): Remove this blacklist when
+ # TODO(haleyb): Remove IPv6Test from blacklist when
# https://bugs.launchpad.net/neutron/+bug/1881558 is fixed.
- tempest_black_regex: "(?:neutron_tempest_plugin.scenario.test_ipv6.IPv6Test)"
+ # TODO(slaweq): Remove test_trunk_subport_lifecycle test from the
+ # blacklist when bug https://bugs.launchpad.net/neutron/+bug/1885900 will
+ # be fixed
+ # TODO(jlibosva): Remove the NetworkWritableMtuTest test from the list
+ # once east/west fragmentation is supported in core OVN
+ tempest_black_regex: "\
+ (?:neutron_tempest_plugin.scenario.test_ipv6.IPv6Test)|\
+ (^neutron_tempest_plugin.scenario.test_trunk.TrunkTest.test_trunk_subport_lifecycle)|\
+ (^neutron_tempest_plugin.scenario.test_mtu.NetworkWritableMtuTest)"
devstack_localrc:
Q_AGENT: ovn
NETWORK_API_EXTENSIONS: "{{ network_api_extensions | join(',') }}"
@@ -220,13 +241,19 @@
q-l3: false
q-meta: false
q-metering: false
+ q-qos: true
+ tls-proxy: true
+ # Cinder services
+ c-api: false
+ c-bak: false
+ c-sch: false
+ c-vol: false
+ cinder: false
s-account: false
s-container-sync: false
s-container: false
s-object: false
s-proxy: false
- tls-proxy: true
- q-qos: true
devstack_local_conf:
post-config:
$NEUTRON_CONF:
@@ -237,9 +264,10 @@
type_drivers: local,flat,vlan,geneve
test-config:
$TEMPEST_CONFIG:
+ network-feature-enabled:
+ available_features: ""
neutron_plugin_options:
available_type_drivers: local,flat,vlan,geneve
- ipv6_metadata: False
is_igmp_snooping_enabled: True
- job:
@@ -291,7 +319,17 @@
neutron-trunk: true
neutron-log: true
neutron-port-forwarding: true
- cinder: true
+ # Cinder services
+ c-api: false
+ c-bak: false
+ c-sch: false
+ c-vol: false
+ cinder: false
+ # We don't need Swift to be run in the Neutron jobs
+ s-account: false
+ s-container: false
+ s-object: false
+ s-proxy: false
devstack_local_conf:
post-config:
$NEUTRON_CONF:
@@ -337,6 +375,8 @@
keystone: "cors request_id catch_errors osprofiler authtoken keystonecontext extensions neutronapiapp_v2_0"
test-config:
$TEMPEST_CONFIG:
+ network-feature-enabled:
+ available_features: *available_features
neutron_plugin_options:
provider_vlans: foo,
agent_availability_zone: nova
@@ -354,6 +394,14 @@
neutron-trunk: true
neutron-log: true
neutron-port-forwarding: true
+ # Cinder services
+ c-bak: false
+ c-vol: false
+ # We don't need Swift to be run in the Neutron jobs
+ s-account: false
+ s-container: false
+ s-object: false
+ s-proxy: false
devstack_localrc:
USE_PYTHON3: true
devstack_local_conf:
diff --git a/zuul.d/project.yaml b/zuul.d/project.yaml
index afab1d3..dc6e56c 100644
--- a/zuul.d/project.yaml
+++ b/zuul.d/project.yaml
@@ -136,6 +136,30 @@
- neutron-tempest-plugin-dvr-multinode-scenario-ussuri
+- project-template:
+ name: neutron-tempest-plugin-jobs-victoria
+ check:
+ jobs:
+ - neutron-tempest-plugin-api-victoria
+ - neutron-tempest-plugin-designate-scenario-victoria:
+ # TODO(slaweq): switch it to be voting when bug
+ # https://bugs.launchpad.net/neutron/+bug/1891309
+ # will be fixed
+ voting: false
+ - neutron-tempest-plugin-scenario-linuxbridge-victoria
+ - neutron-tempest-plugin-scenario-openvswitch-victoria
+ - neutron-tempest-plugin-scenario-openvswitch-iptables_hybrid-victoria
+ - neutron-tempest-plugin-scenario-ovn-victoria
+ gate:
+ jobs:
+ - neutron-tempest-plugin-api-victoria
+ #TODO(slaweq): Move neutron-tempest-plugin-dvr-multinode-scenario out of
+ # the experimental queue when it will be more stable
+ experimental:
+ jobs:
+ - neutron-tempest-plugin-dvr-multinode-scenario-victoria
+
+
- project:
templates:
- build-openstack-docs-pti
@@ -143,6 +167,7 @@
- neutron-tempest-plugin-jobs-stein
- neutron-tempest-plugin-jobs-train
- neutron-tempest-plugin-jobs-ussuri
+ - neutron-tempest-plugin-jobs-victoria
- check-requirements
- tempest-plugin-jobs
- release-notes-jobs-python3
@@ -151,17 +176,11 @@
- neutron-tempest-plugin-sfc
- neutron-tempest-plugin-sfc-train
- neutron-tempest-plugin-sfc-ussuri
- - neutron-tempest-plugin-bgpvpn-bagpipe:
- # TODO(slaweq): switch it to be voting when bug
- # https://bugs.launchpad.net/networking-bagpipe/+bug/1897408
- # will be fixed
- voting: false
+ - neutron-tempest-plugin-sfc-victoria
+ - neutron-tempest-plugin-bgpvpn-bagpipe
- neutron-tempest-plugin-bgpvpn-bagpipe-train
- - neutron-tempest-plugin-bgpvpn-bagpipe-ussuri:
- # TODO(slaweq): switch it to be voting when bug
- # https://bugs.launchpad.net/networking-bagpipe/+bug/1897408
- # will be fixed
- voting: false
+ - neutron-tempest-plugin-bgpvpn-bagpipe-ussuri
+ - neutron-tempest-plugin-bgpvpn-bagpipe-victoria
- neutron-tempest-plugin-fwaas-train:
# TODO(slaweq): switch it to be voting when bug
# https://bugs.launchpad.net/neutron/+bug/1858645 will be fixed
@@ -172,14 +191,13 @@
voting: false
- neutron-tempest-plugin-dynamic-routing
- neutron-tempest-plugin-dynamic-routing-ussuri
+ - neutron-tempest-plugin-dynamic-routing-victoria
- neutron-tempest-plugin-vpnaas
- neutron-tempest-plugin-vpnaas-ussuri
+ - neutron-tempest-plugin-vpnaas-victoria
gate:
jobs:
- neutron-tempest-plugin-sfc
- # TODO(slaweq): make bgpvpn-bagpipe job gating again when
- # https://bugs.launchpad.net/networking-bagpipe/+bug/1897408
- # will be fixed
- #- neutron-tempest-plugin-bgpvpn-bagpipe
+ - neutron-tempest-plugin-bgpvpn-bagpipe
- neutron-tempest-plugin-dynamic-routing
diff --git a/zuul.d/queens_jobs.yaml b/zuul.d/queens_jobs.yaml
index 2b52978..e1ecc00 100644
--- a/zuul.d/queens_jobs.yaml
+++ b/zuul.d/queens_jobs.yaml
@@ -65,8 +65,12 @@
- trunk-details
network_api_extensions_tempest:
- dvr
+ network_available_features: &available_features
+ -
devstack_localrc:
+ NEUTRON_DEPLOY_MOD_WSGI: false
USE_PYTHON3: false
+ CIRROS_VERSION: 0.3.5
NETWORK_API_EXTENSIONS: "{{ (network_api_extensions_common + network_api_extensions_tempest) | join(',') }}"
TEMPEST_PLUGINS: /opt/stack/neutron-tempest-plugin
@@ -86,6 +90,7 @@
vars:
branch_override: stable/queens
network_api_extensions: *api_extensions
+ network_available_features: *available_features
# TODO(slaweq): remove trunks subport_connectivity test from blacklist
# when bug https://bugs.launchpad.net/neutron/+bug/1838760 will be fixed
# NOTE(bcafarel): remove DNS test as queens pinned version does not have
@@ -95,13 +100,17 @@
(^neutron_tempest_plugin.scenario.test_internal_dns.InternalDNSTest.test_dns_domain_and_name)"
devstack_localrc:
USE_PYTHON3: false
+ CIRROS_VERSION: 0.3.5
NETWORK_API_EXTENSIONS: "{{ network_api_extensions | join(',') }}"
TEMPEST_PLUGINS: /opt/stack/neutron-tempest-plugin
- job:
name: neutron-tempest-plugin-scenario-linuxbridge-queens
- parent: neutron-tempest-plugin-scenario-linuxbridge
+ parent: neutron-tempest-plugin-scenario
nodeset: openstack-single-node-xenial
+ timeout: 10000
+ roles:
+ - zuul: openstack/neutron
override-checkout: stable/queens
required-projects:
- openstack/devstack-gate
@@ -112,21 +121,37 @@
vars:
branch_override: stable/queens
network_api_extensions: *api_extensions
+ network_available_features: *available_features
# NOTE(bcafarel): remove DNS test as queens pinned version does not have
# fix for https://bugs.launchpad.net/neutron/+bug/1826419
tempest_black_regex: "\
(^neutron_tempest_plugin.scenario.test_internal_dns.InternalDNSTest.test_dns_domain_and_name)"
devstack_localrc:
USE_PYTHON3: false
+ CIRROS_VERSION: 0.3.5
+ Q_AGENT: linuxbridge
NETWORK_API_EXTENSIONS: "{{ network_api_extensions | join(',') }}"
TEMPEST_PLUGINS: /opt/stack/neutron-tempest-plugin
devstack_local_conf:
+ post-config:
+ $NEUTRON_CONF:
+ DEFAULT:
+ enable_dvr: false
+ AGENT:
+ debug_iptables_rules: true
+ # 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
test-config:
# NOTE: ignores linux bridge's trunk delete on bound port test
- # for queens branch (as https://review.opendev.org/#/c/605589/
- # fix will not apply for queens branch)
+ # for rocky branch (as https://review.opendev.org/#/c/605589/
+ # fix will not apply for rocky branch)
$TEMPEST_CONFIG:
neutron_plugin_options:
+ available_type_drivers: flat,vlan,local,vxlan
q_agent: None
- job:
@@ -152,6 +177,7 @@
(^neutron_tempest_plugin.scenario.test_internal_dns.InternalDNSTest.test_dns_domain_and_name)"
devstack_localrc:
USE_PYTHON3: false
+ CIRROS_VERSION: 0.3.5
TEMPEST_PLUGINS: /opt/stack/neutron-tempest-plugin
- job:
@@ -176,4 +202,5 @@
(^neutron_tempest_plugin.scenario.test_internal_dns.InternalDNSTest.test_dns_domain_and_name)"
devstack_localrc:
USE_PYTHON3: false
+ CIRROS_VERSION: 0.3.5
TEMPEST_PLUGINS: '"/opt/stack/designate-tempest-plugin /opt/stack/neutron-tempest-plugin"'
diff --git a/zuul.d/rocky_jobs.yaml b/zuul.d/rocky_jobs.yaml
index a45cae8..4b6145b 100644
--- a/zuul.d/rocky_jobs.yaml
+++ b/zuul.d/rocky_jobs.yaml
@@ -75,6 +75,7 @@
network_api_extensions_tempest:
- dvr
devstack_localrc:
+ NEUTRON_DEPLOY_MOD_WSGI: false
USE_PYTHON3: false
NETWORK_API_EXTENSIONS: "{{ (network_api_extensions_common + network_api_extensions_tempest) | join(',') }}"
TEMPEST_PLUGINS: /opt/stack/neutron-tempest-plugin
@@ -108,6 +109,8 @@
vars: &scenario_vars_rocky
branch_override: stable/rocky
network_api_extensions: *api_extensions
+ network_available_features: &available_features
+ -
devstack_localrc:
USE_PYTHON3: false
NETWORK_API_EXTENSIONS: "{{ network_api_extensions | join(',') }}"
@@ -176,10 +179,13 @@
- job:
name: neutron-tempest-plugin-scenario-linuxbridge-rocky
- parent: neutron-tempest-plugin-scenario-linuxbridge
+ parent: neutron-tempest-plugin-scenario
+ timeout: 10000
description: |
This job run on py2 for stable/rocky gate.
nodeset: openstack-single-node-xenial
+ roles:
+ - zuul: openstack/neutron
override-checkout: stable/rocky
required-projects: *required-projects-rocky
vars: &linuxbridge_vars_rocky
@@ -187,15 +193,29 @@
network_api_extensions: *api_extensions
devstack_localrc:
USE_PYTHON3: false
+ Q_AGENT: linuxbridge
NETWORK_API_EXTENSIONS: "{{ network_api_extensions | join(',') }}"
TEMPEST_PLUGINS: /opt/stack/neutron-tempest-plugin
devstack_local_conf:
+ post-config:
+ $NEUTRON_CONF:
+ DEFAULT:
+ enable_dvr: false
+ AGENT:
+ debug_iptables_rules: true
+ # 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
test-config:
# NOTE: ignores linux bridge's trunk delete on bound port test
# for rocky branch (as https://review.opendev.org/#/c/605589/
# fix will not apply for rocky branch)
$TEMPEST_CONFIG:
neutron_plugin_options:
+ available_type_drivers: flat,vlan,local,vxlan
q_agent: None
# NOTE(bcafarel): newer tests, unstable on rocky branch
tempest_black_regex: "\
@@ -206,17 +226,23 @@
- job:
name: neutron-tempest-plugin-scenario-linuxbridge-rocky
- parent: neutron-tempest-plugin-scenario-linuxbridge
+ parent: neutron-tempest-plugin-scenario
nodeset: openstack-single-node-xenial
+ timeout: 10000
description: |
This job run on py3 for other than stable/rocky gate
which is nothing but neutron-tempest-pluign master gate.
+ roles:
+ - zuul: openstack/neutron
override-checkout: stable/rocky
required-projects: *required-projects-rocky
vars:
<<: *linuxbridge_vars_rocky
devstack_localrc:
USE_PYTHON3: True
+ Q_AGENT: linuxbridge
+ NETWORK_API_EXTENSIONS: "{{ network_api_extensions | join(',') }}"
+ TEMPEST_PLUGINS: /opt/stack/neutron-tempest-plugin
branches: ^(?!stable/rocky).*$
- job:
diff --git a/zuul.d/stein_jobs.yaml b/zuul.d/stein_jobs.yaml
index ff6ed38..9de8384 100644
--- a/zuul.d/stein_jobs.yaml
+++ b/zuul.d/stein_jobs.yaml
@@ -73,7 +73,10 @@
- uplink-status-propagation
network_api_extensions_tempest:
- dvr
+ network_available_features: &available_features
+ -
devstack_localrc:
+ NEUTRON_DEPLOY_MOD_WSGI: false
NETWORK_API_EXTENSIONS: "{{ (network_api_extensions_common + network_api_extensions_tempest) | join(',') }}"
- job:
@@ -84,11 +87,14 @@
vars:
branch_override: stable/stein
network_api_extensions: *api_extensions
+ network_available_features: *available_features
devstack_localrc:
NETWORK_API_EXTENSIONS: "{{ network_api_extensions | join(',') }}"
devstack_local_conf:
test-config:
$TEMPEST_CONFIG:
+ network-feature-enabled:
+ available_features: ""
neutron_plugin_options:
ipv6_metadata: False
@@ -100,11 +106,14 @@
vars:
branch_override: stable/stein
network_api_extensions: *api_extensions
+ network_available_features: *available_features
devstack_localrc:
NETWORK_API_EXTENSIONS: "{{ network_api_extensions | join(',') }}"
devstack_local_conf:
test-config:
$TEMPEST_CONFIG:
+ network-feature-enabled:
+ available_features: ""
neutron_plugin_options:
ipv6_metadata: False
@@ -116,11 +125,14 @@
vars:
branch_override: stable/stein
network_api_extensions: *api_extensions
+ network_available_features: *available_features
devstack_localrc:
NETWORK_API_EXTENSIONS: "{{ network_api_extensions | join(',') }}"
devstack_local_conf:
test-config:
$TEMPEST_CONFIG:
+ network-feature-enabled:
+ available_features: ""
neutron_plugin_options:
ipv6_metadata: False
diff --git a/zuul.d/train_jobs.yaml b/zuul.d/train_jobs.yaml
index a9cc5be..0785924 100644
--- a/zuul.d/train_jobs.yaml
+++ b/zuul.d/train_jobs.yaml
@@ -78,7 +78,10 @@
- uplink-status-propagation
network_api_extensions_tempest:
- dvr
+ network_available_features: &available_features
+ -
devstack_localrc:
+ NEUTRON_DEPLOY_MOD_WSGI: false
NETWORK_API_EXTENSIONS: "{{ (network_api_extensions_common + network_api_extensions_tempest) | join(',') }}"
- job:
@@ -89,11 +92,14 @@
vars:
branch_override: stable/train
network_api_extensions: *api_extensions
+ network_available_features: *available_features
devstack_localrc:
NETWORK_API_EXTENSIONS: "{{ network_api_extensions | join(',') }}"
devstack_local_conf:
test-config:
$TEMPEST_CONFIG:
+ network-feature-enabled:
+ available_features: ""
neutron_plugin_options:
ipv6_metadata: False
@@ -105,11 +111,14 @@
vars:
branch_override: stable/train
network_api_extensions: *api_extensions
+ network_available_features: *available_features
devstack_localrc:
NETWORK_API_EXTENSIONS: "{{ network_api_extensions | join(',') }}"
devstack_local_conf:
test-config:
$TEMPEST_CONFIG:
+ network-feature-enabled:
+ available_features: ""
neutron_plugin_options:
ipv6_metadata: False
@@ -121,11 +130,14 @@
vars:
branch_override: stable/train
network_api_extensions: *api_extensions
+ network_available_features: *available_features
devstack_localrc:
NETWORK_API_EXTENSIONS: "{{ network_api_extensions | join(',') }}"
devstack_local_conf:
test-config:
$TEMPEST_CONFIG:
+ network-feature-enabled:
+ available_features: ""
neutron_plugin_options:
ipv6_metadata: False
diff --git a/zuul.d/ussuri_jobs.yaml b/zuul.d/ussuri_jobs.yaml
index 135d9f5..b71a460 100644
--- a/zuul.d/ussuri_jobs.yaml
+++ b/zuul.d/ussuri_jobs.yaml
@@ -82,9 +82,13 @@
- uplink-status-propagation
network_api_extensions_tempest:
- dvr
+ network_available_features: &available_features
+ -
devstack_localrc:
+ NEUTRON_DEPLOY_MOD_WSGI: false
NETWORK_API_EXTENSIONS: "{{ (network_api_extensions_common + network_api_extensions_tempest) | join(',') }}"
+
- job:
name: neutron-tempest-plugin-scenario-openvswitch-ussuri
parent: neutron-tempest-plugin-scenario-openvswitch
@@ -93,14 +97,18 @@
vars:
branch_override: stable/ussuri
network_api_extensions: *api_extensions
+ network_available_features: *available_features
devstack_localrc:
NETWORK_API_EXTENSIONS: "{{ network_api_extensions | join(',') }}"
devstack_local_conf:
test-config:
$TEMPEST_CONFIG:
+ network-feature-enabled:
+ available_features: ""
neutron_plugin_options:
ipv6_metadata: False
+
- job:
name: neutron-tempest-plugin-scenario-openvswitch-iptables_hybrid-ussuri
parent: neutron-tempest-plugin-scenario-openvswitch-iptables_hybrid
@@ -109,11 +117,14 @@
vars:
branch_override: stable/ussuri
network_api_extensions: *api_extensions
+ network_available_features: *available_features
devstack_localrc:
NETWORK_API_EXTENSIONS: "{{ network_api_extensions | join(',') }}"
devstack_local_conf:
test-config:
$TEMPEST_CONFIG:
+ network-feature-enabled:
+ available_features: ""
neutron_plugin_options:
ipv6_metadata: False
@@ -125,11 +136,14 @@
vars:
branch_override: stable/ussuri
network_api_extensions: *api_extensions
+ network_available_features: *available_features
devstack_localrc:
NETWORK_API_EXTENSIONS: "{{ network_api_extensions | join(',') }}"
devstack_local_conf:
test-config:
$TEMPEST_CONFIG:
+ network-feature-enabled:
+ available_features: ""
neutron_plugin_options:
ipv6_metadata: False
diff --git a/zuul.d/victoria_jobs.yaml b/zuul.d/victoria_jobs.yaml
new file mode 100644
index 0000000..5543ea7
--- /dev/null
+++ b/zuul.d/victoria_jobs.yaml
@@ -0,0 +1,205 @@
+- job:
+ name: neutron-tempest-plugin-api-victoria
+ parent: neutron-tempest-plugin-api
+ override-checkout: stable/victoria
+ vars:
+ branch_override: stable/victoria
+ # TODO(slaweq): find a way to put this list of extensions in
+ # neutron repository and keep it different per branch,
+ # then it could be removed from here
+ network_api_extensions_common: &api_extensions
+ - address-scope
+ - agent
+ - allowed-address-pairs
+ - auto-allocated-topology
+ - availability_zone
+ - binding
+ - default-subnetpools
+ - dhcp_agent_scheduler
+ - dns-domain-ports
+ - dns-integration
+ - empty-string-filtering
+ - expose-port-forwarding-in-fip
+ - expose-l3-conntrack-helper
+ - ext-gw-mode
+ - external-net
+ - extra_dhcp_opt
+ - extraroute
+ - extraroute-atomic
+ - filter-validation
+ - fip-port-details
+ - flavors
+ - floating-ip-port-forwarding
+ - floatingip-pools
+ - ip-substring-filtering
+ - l3-conntrack-helper
+ - l3-flavors
+ - l3-ha
+ - l3_agent_scheduler
+ - logging
+ - metering
+ - multi-provider
+ - net-mtu
+ - net-mtu-writable
+ - network-ip-availability
+ - network_availability_zone
+ - network-segment-range
+ - pagination
+ - port-resource-request
+ - port-mac-address-regenerate
+ - port-security
+ - port-security-groups-filtering
+ - project-id
+ - provider
+ - qos
+ - qos-bw-minimum-ingress
+ - qos-fip
+ - quotas
+ - quota_details
+ - rbac-address-scope
+ - rbac-policies
+ - rbac-security-groups
+ - rbac-subnetpool
+ - router
+ - router-admin-state-down-before-update
+ - router_availability_zone
+ - security-group
+ - segment
+ - service-type
+ - sorting
+ - standard-attr-description
+ - standard-attr-revisions
+ - standard-attr-segment
+ - standard-attr-tag
+ - standard-attr-timestamp
+ - subnet_allocation
+ - subnet-dns-publish-fixed-ip
+ - subnetpool-prefix-ops
+ - tag-ports-during-bulk-creation
+ - trunk
+ - trunk-details
+ - uplink-status-propagation
+ network_api_extensions_tempest:
+ - dvr
+ network_available_features: &available_features
+ - ipv6_metadata
+ devstack_localrc:
+ NEUTRON_DEPLOY_MOD_WSGI: false
+ NETWORK_API_EXTENSIONS: "{{ (network_api_extensions_common + network_api_extensions_tempest) | join(',') }}"
+
+- job:
+ name: neutron-tempest-plugin-scenario-openvswitch-victoria
+ parent: neutron-tempest-plugin-scenario-openvswitch
+ override-checkout: stable/victoria
+ vars:
+ branch_override: stable/victoria
+ network_api_extensions: *api_extensions
+ network_available_features: *available_features
+ devstack_localrc:
+ NETWORK_API_EXTENSIONS: "{{ network_api_extensions | join(',') }}"
+ devstack_local_conf:
+ test-config:
+ $TEMPEST_CONFIG:
+ network-feature-enabled:
+ available_features: "{{ network_available_features | join(',') }}"
+ neutron_plugin_options:
+ ipv6_metadata: False
+
+- job:
+ name: neutron-tempest-plugin-scenario-openvswitch-iptables_hybrid-victoria
+ parent: neutron-tempest-plugin-scenario-openvswitch-iptables_hybrid
+ override-checkout: stable-victoria
+ vars:
+ branch_override: stable-victoria
+ network_api_extensions: *api_extensions
+ network_available_features: *available_features
+ devstack_localrc:
+ NETWORK_API_EXTENSIONS: "{{ network_api_extensions | join(',') }}"
+ devstack_local_conf:
+ test-config:
+ $TEMPEST_CONFIG:
+ network-feature-enabled:
+ available_features: "{{ network_available_features | join(',') }}"
+ neutron_plugin_options:
+ ipv6_metadata: False
+
+- job:
+ name: neutron-tempest-plugin-scenario-linuxbridge-victoria
+ parent: neutron-tempest-plugin-scenario-linuxbridge
+ override-checkout: stable/victoria
+ vars:
+ branch_override: stable/victoria
+ network_api_extensions: *api_extensions
+ network_available_features: *available_features
+ devstack_localrc:
+ NETWORK_API_EXTENSIONS: "{{ network_api_extensions | join(',') }}"
+ devstack_local_conf:
+ test-config:
+ $TEMPEST_CONFIG:
+ network-feature-enabled:
+ available_features: "{{ network_available_features | join(',') }}"
+ neutron_plugin_options:
+ ipv6_metadata: False
+
+- job:
+ name: neutron-tempest-plugin-scenario-ovn-victoria
+ parent: neutron-tempest-plugin-scenario-ovn
+ override-checkout: stable/victoria
+ vars:
+ branch_override: stable/victoria
+ network_api_extensions: *api_extensions
+ devstack_localrc:
+ NETWORK_API_EXTENSIONS: "{{ network_api_extensions | join(',') }}"
+ devstack_local_conf:
+ test-config:
+ $TEMPEST_CONFIG:
+ network-feature-enabled:
+ available_features: ""
+
+- job:
+ name: neutron-tempest-plugin-dvr-multinode-scenario-victoria
+ parent: neutron-tempest-plugin-dvr-multinode-scenario
+ override-checkout: stable/victoria
+ vars:
+ network_api_extensions_common: *api_extensions
+ branch_override: stable/victoria
+
+- job:
+ name: neutron-tempest-plugin-designate-scenario-victoria
+ parent: neutron-tempest-plugin-designate-scenario
+ override-checkout: stable/victoria
+ vars:
+ branch_override: stable/victoria
+ network_api_extensions_common: *api_extensions
+
+- job:
+ name: neutron-tempest-plugin-sfc-victoria
+ parent: neutron-tempest-plugin-sfc
+ override-checkout: stable/victoria
+ vars:
+ branch_override: stable/victoria
+ network_api_extensions_common: *api_extensions
+
+- job:
+ name: neutron-tempest-plugin-bgpvpn-bagpipe-victoria
+ parent: neutron-tempest-plugin-bgpvpn-bagpipe
+ override-checkout: stable/victoria
+ vars:
+ branch_override: stable/victoria
+ network_api_extensions: *api_extensions
+
+- job:
+ name: neutron-tempest-plugin-dynamic-routing-victoria
+ parent: neutron-tempest-plugin-dynamic-routing
+ override-checkout: stable/victoria
+ vars:
+ branch_override: stable/victoria
+ network_api_extensions_common: *api_extensions
+
+- job:
+ name: neutron-tempest-plugin-vpnaas-victoria
+ parent: neutron-tempest-plugin-vpnaas
+ override-checkout: stable/victoria
+ vars:
+ branch_override: stable/victoria
+ network_api_extensions_common: *api_extensions