Merge "Improve logging of vm's console output"
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..d63dec8 100644
--- a/neutron_tempest_plugin/api/base.py
+++ b/neutron_tempest_plugin/api/base.py
@@ -702,6 +702,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/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/scenario/base.py b/neutron_tempest_plugin/scenario/base.py
index 949a1a2..b2f9af3 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,7 +259,6 @@
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]
@@ -266,7 +272,7 @@
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()
@@ -296,10 +302,20 @@
"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))
+ 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):
+ local_ips = ip_utils.IPCommand(namespace=ns_name).list_addresses()
+ LOG.debug('Namespace %s; IP Addresses:\n%s',
+ ns_name, '\n'.join(str(r) for r in local_ips))
+ local_routes = ip_utils.IPCommand(namespace=ns_name).list_routes()
+ LOG.debug('Namespace %s; Local routes:\n%s',
+ ns_name, '\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))
+ 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,
@@ -381,12 +397,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,
@@ -454,7 +472,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['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:
@@ -462,7 +503,7 @@
if timeout:
kwargs['timeout'] = timeout
try:
- kwargs['port'] = (
+ kwargs['port'] = external_port or (
server['port_forwarding_tcp']['external_port'])
except KeyError:
pass
@@ -473,15 +514,17 @@
**kwargs)
self.assertIn(server['name'],
ssh_client.exec_command('hostname'))
- except lib_exc.SSHTimeout as ssh_e:
+ 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,
@@ -506,9 +549,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_floatingip.py b/neutron_tempest_plugin/scenario/test_floatingip.py
index d541642..8c8d163 100644
--- a/neutron_tempest_plugin/scenario/test_floatingip.py
+++ b/neutron_tempest_plugin/scenario/test_floatingip.py
@@ -392,7 +392,6 @@
same_network = None
- @test.unstable_test("bug 1897326")
@decorators.idempotent_id('1bdd849b-03dd-4b8f-994f-457cf8a36f93')
def test_floating_ip_update(self):
"""Test updating FIP with another port.
@@ -418,6 +417,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'],
@@ -435,8 +435,7 @@
# The FIP is now associated with the port of the second server.
try:
- common_utils.wait_until_true(_wait_for_fip_associated,
- timeout=15, sleep=3)
+ common_utils.wait_until_true(_wait_for_fip_associated, sleep=3)
except common_utils.WaitTimeout:
self._log_console_output(servers[-1:])
self.fail(
diff --git a/neutron_tempest_plugin/scenario/test_internal_dns.py b/neutron_tempest_plugin/scenario/test_internal_dns.py
index d19286c..c620233 100644
--- a/neutron_tempest_plugin/scenario/test_internal_dns.py
+++ b/neutron_tempest_plugin/scenario/test_internal_dns.py
@@ -52,6 +52,7 @@
{'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'],
diff --git a/neutron_tempest_plugin/scenario/test_ipv6.py b/neutron_tempest_plugin/scenario/test_ipv6.py
index 02e2846..732c96d 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
@@ -108,16 +109,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 +145,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..3897183 100644
--- a/neutron_tempest_plugin/scenario/test_metadata.py
+++ b/neutron_tempest_plugin/scenario/test_metadata.py
@@ -126,6 +126,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..fb6410c 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,23 +109,22 @@
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
@@ -128,25 +133,16 @@
@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 +151,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 +167,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 +187,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 938d2b0..6cd6b25 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 e4e6ca4..98fe6ae 100644
--- a/neutron_tempest_plugin/scenario/test_trunk.py
+++ b/neutron_tempest_plugin/scenario/test_trunk.py
@@ -161,6 +161,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 +200,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)
@@ -328,6 +330,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)
@@ -380,6 +383,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..0b2544b 100644
--- a/neutron_tempest_plugin/services/network/json/network_client.py
+++ b/neutron_tempest_plugin/services/network/json/network_client.py
@@ -952,8 +952,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/zuul.d/base.yaml b/zuul.d/base.yaml
index ddf7dc6..2bd6f5a 100644
--- a/zuul.d/base.yaml
+++ b/zuul.d/base.yaml
@@ -17,6 +17,8 @@
devstack_localrc:
USE_PYTHON3: true
NETWORK_API_EXTENSIONS: "{{ (network_api_extensions_common + network_api_extensions_tempest) | join(',') }}"
+ CIRROS_VERSION: 0.5.1
+ BUILD_TIMEOUT: 784
devstack_plugins:
neutron: https://opendev.org/openstack/neutron.git
neutron-tempest-plugin: https://opendev.org/openstack/neutron-tempest-plugin.git
@@ -36,6 +38,11 @@
neutron-tag-ports-during-bulk-creation: true
br-ex-tcpdump: true
br-int-flows: true
+ # 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:
@@ -100,6 +107,7 @@
tempest_test_regex: ^neutron_tempest_plugin\.scenario
devstack_localrc:
PHYSICAL_NETWORK: default
+ CIRROS_VERSION: 0.5.1
IMAGE_URLS: https://cloud-images.ubuntu.com/releases/bionic/release/ubuntu-18.04-server-cloudimg-amd64.img
ADVANCED_IMAGE_NAME: ubuntu-18.04-server-cloudimg-amd64
ADVANCED_INSTANCE_TYPE: ds512M
diff --git a/zuul.d/master_jobs.yaml b/zuul.d/master_jobs.yaml
index 5607274..728eed8 100644
--- a/zuul.d/master_jobs.yaml
+++ b/zuul.d/master_jobs.yaml
@@ -191,9 +191,14 @@
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
+ tempest_black_regex: "\
+ (?:neutron_tempest_plugin.scenario.test_ipv6.IPv6Test)|\
+ (^neutron_tempest_plugin.scenario.test_trunk.TrunkTest.test_trunk_subport_lifecycle)"
devstack_localrc:
Q_AGENT: ovn
NETWORK_API_EXTENSIONS: "{{ network_api_extensions | join(',') }}"
@@ -271,8 +276,9 @@
USE_PYTHON3: true
NETWORK_API_EXTENSIONS: "{{ (network_api_extensions_common + network_api_extensions_dvr) | join(',') }}"
PHYSICAL_NETWORK: default
- IMAGE_URLS: https://cloud-images.ubuntu.com/releases/xenial/release/ubuntu-16.04-server-cloudimg-amd64-disk1.img
- ADVANCED_IMAGE_NAME: ubuntu-16.04-server-cloudimg-amd64-disk1
+ CIRROS_VERSION: 0.5.1
+ IMAGE_URLS: https://cloud-images.ubuntu.com/releases/bionic/release/ubuntu-18.04-server-cloudimg-amd64.img
+ ADVANCED_IMAGE_NAME: ubuntu-18.04-server-cloudimg-amd64
ADVANCED_INSTANCE_TYPE: ds512M
ADVANCED_INSTANCE_USER: ubuntu
BUILD_TIMEOUT: 784
@@ -291,6 +297,11 @@
neutron-log: true
neutron-port-forwarding: true
cinder: true
+ # 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:
@@ -353,6 +364,11 @@
neutron-trunk: true
neutron-log: true
neutron-port-forwarding: true
+ # 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..0355f69 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,6 +176,7 @@
- neutron-tempest-plugin-sfc
- neutron-tempest-plugin-sfc-train
- neutron-tempest-plugin-sfc-ussuri
+ - neutron-tempest-plugin-sfc-victoria
- neutron-tempest-plugin-bgpvpn-bagpipe:
# TODO(slaweq): switch it to be voting when bug
# https://bugs.launchpad.net/networking-bagpipe/+bug/1897408
@@ -162,6 +188,11 @@
# https://bugs.launchpad.net/networking-bagpipe/+bug/1897408
# will be fixed
voting: false
+ - neutron-tempest-plugin-bgpvpn-bagpipe-victoria:
+ # 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-fwaas-train:
# TODO(slaweq): switch it to be voting when bug
# https://bugs.launchpad.net/neutron/+bug/1858645 will be fixed
@@ -172,8 +203,10 @@
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:
diff --git a/zuul.d/queens_jobs.yaml b/zuul.d/queens_jobs.yaml
index 2b52978..b0ee336 100644
--- a/zuul.d/queens_jobs.yaml
+++ b/zuul.d/queens_jobs.yaml
@@ -67,6 +67,7 @@
- dvr
devstack_localrc:
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
@@ -95,13 +96,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
@@ -118,15 +123,30 @@
(^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 +172,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 +197,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..6eb8c15 100644
--- a/zuul.d/rocky_jobs.yaml
+++ b/zuul.d/rocky_jobs.yaml
@@ -176,10 +176,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 +190,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 +223,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/victoria_jobs.yaml b/zuul.d/victoria_jobs.yaml
new file mode 100644
index 0000000..0bc1e13
--- /dev/null
+++ b/zuul.d/victoria_jobs.yaml
@@ -0,0 +1,188 @@
+- 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
+ devstack_localrc:
+ 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
+ devstack_localrc:
+ NETWORK_API_EXTENSIONS: "{{ network_api_extensions | join(',') }}"
+ devstack_local_conf:
+ test-config:
+ $TEMPEST_CONFIG:
+ 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
+ devstack_localrc:
+ NETWORK_API_EXTENSIONS: "{{ network_api_extensions | join(',') }}"
+ devstack_local_conf:
+ test-config:
+ $TEMPEST_CONFIG:
+ 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
+ devstack_localrc:
+ NETWORK_API_EXTENSIONS: "{{ network_api_extensions | join(',') }}"
+ devstack_local_conf:
+ test-config:
+ $TEMPEST_CONFIG:
+ 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(',') }}"
+
+- 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