Merge "Create security groups with the same name"
diff --git a/doc/requirements.txt b/doc/requirements.txt
new file mode 100644
index 0000000..6fe7c34
--- /dev/null
+++ b/doc/requirements.txt
@@ -0,0 +1,4 @@
+reno>=3.1.0 # Apache-2.0
+sphinx>=2.0.0,!=2.1.0 # BSD
+openstackdocstheme>=2.2.1 # Apache-2.0
+
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/base.py b/neutron_tempest_plugin/api/base.py
index d63dec8..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
diff --git a/neutron_tempest_plugin/api/test_network_ip_availability.py b/neutron_tempest_plugin/api/test_network_ip_availability.py
index e798680..22d2fc6 100644
--- a/neutron_tempest_plugin/api/test_network_ip_availability.py
+++ b/neutron_tempest_plugin/api/test_network_ip_availability.py
@@ -175,3 +175,22 @@
class NetworksIpAvailabilityIPv6Test(NetworksIpAvailabilityIPv4Test):
_ip_version = lib_constants.IP_VERSION_6
+
+ def setUp(self):
+ super(NetworksIpAvailabilityIPv6Test, self).setUp()
+ net_name = data_utils.rand_name('network')
+ self.network = self.create_network(network_name=net_name)
+
+ @decorators.idempotent_id('0d5a03f2-fdb7-4ec3-b746-734c51d74b69')
+ def test_list_ipv6_ip_availability_after_subnet_and_ports(self):
+ subnet = self.create_subnet(self.network, ip_version=self._ip_version,
+ enable_dhcp=False)
+ prefix = netaddr.IPNetwork(subnet['cidr']).prefixlen
+ body = self.admin_client.list_network_ip_availabilities()
+ used_ips_before_port_create = self._get_used_ips(self.network, body)
+ self.create_port(self.network)
+ net_availability = self.admin_client.list_network_ip_availabilities()
+ self._assert_total_and_used_ips(
+ used_ips_before_port_create + 1,
+ calc_total_ips(prefix, self._ip_version),
+ self.network, net_availability)
diff --git a/neutron_tempest_plugin/api/test_ports.py b/neutron_tempest_plugin/api/test_ports.py
index c59ee83..f1dfe5c 100644
--- a/neutron_tempest_plugin/api/test_ports.py
+++ b/neutron_tempest_plugin/api/test_ports.py
@@ -15,6 +15,7 @@
import copy
+from neutron_lib import constants as lib_constants
from tempest.common import utils
from tempest.lib import decorators
@@ -60,6 +61,20 @@
body = self.client.list_ports(id=body['port']['id'])['ports'][0]
self.assertEqual('d2', body['description'])
+ @decorators.idempotent_id('3ae162e8-ff00-490c-a423-6a88e48f1ed6')
+ def test_create_update_port_security(self):
+ body = self.create_port(self.network,
+ port_security_enabled=True)
+ self.assertTrue(body['port_security_enabled'])
+ body = self.client.list_ports(id=body['id'])['ports'][0]
+ self.assertTrue(body['port_security_enabled'])
+ body = self.client.update_port(body['id'],
+ port_security_enabled=False,
+ security_groups=[])
+ self.assertFalse(body['port']['port_security_enabled'])
+ body = self.client.list_ports(id=body['port']['id'])['ports'][0]
+ self.assertFalse(body['port_security_enabled'])
+
@decorators.idempotent_id('539fbefe-fb36-48aa-9a53-8c5fbd44e492')
@utils.requires_ext(extension="dns-integration",
service="network")
@@ -137,6 +152,28 @@
self.assertEqual(expected, subnets)
+class PortsIpv6TestJSON(base.BaseNetworkTest):
+
+ _ip_version = lib_constants.IP_VERSION_6
+
+ @classmethod
+ def resource_setup(cls):
+ super(PortsIpv6TestJSON, cls).resource_setup()
+ cls.network = cls.create_network()
+
+ @decorators.idempotent_id('b85879fb-4852-4b99-aa32-3f8a7a6a3f01')
+ def test_add_ipv6_ips_to_port(self):
+ s = self.create_subnet(self.network, ip_version=self._ip_version)
+ port = self.create_port(self.network)
+ # request another IP on the same subnet
+ port['fixed_ips'].append({'subnet_id': s['id']})
+ updated = self.client.update_port(port['id'],
+ fixed_ips=port['fixed_ips'])
+ subnets = [ip['subnet_id'] for ip in updated['port']['fixed_ips']]
+ expected = [s['id'], s['id']]
+ self.assertEqual(expected, subnets)
+
+
class PortsSearchCriteriaTest(base.BaseSearchCriteriaTest):
resource = 'port'
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/api/test_qos_negative.py b/neutron_tempest_plugin/api/test_qos_negative.py
index 8432c6a..f6c4afc 100644
--- a/neutron_tempest_plugin/api/test_qos_negative.py
+++ b/neutron_tempest_plugin/api/test_qos_negative.py
@@ -67,6 +67,28 @@
self.client.update_qos_policy, policy['id'],
description=LONG_DESCRIPTION_NG)
+ @decorators.attr(type='negative')
+ @decorators.idempotent_id('88b54ab0-804b-446c-bc19-8e54222d70ef')
+ def test_get_non_existent_qos_policy(self):
+ non_exist_id = data_utils.rand_name('qos_policy')
+ self.assertRaises(lib_exc.NotFound,
+ self.admin_client.show_qos_policy, non_exist_id)
+
+ @decorators.attr(type='negative')
+ @decorators.idempotent_id('21050859-1284-4bf5-b05a-13846f83988f')
+ def test_update_non_existent_qos_policy(self):
+ non_exist_id = data_utils.rand_name('qos_policy')
+ self.assertRaises(lib_exc.NotFound,
+ self.admin_client.update_qos_policy, non_exist_id,
+ shared=False)
+
+ @decorators.attr(type='negative')
+ @decorators.idempotent_id('09e435b7-44d3-4f9d-8aa8-c295d46b5866')
+ def test_delete_non_existent_qos_policy(self):
+ non_exist_id = data_utils.rand_name('qos_policy')
+ self.assertRaises(lib_exc.NotFound,
+ self.admin_client.delete_qos_policy, non_exist_id)
+
class QosBandwidthLimitRuleNegativeTestJSON(base.BaseAdminNetworkTest):
diff --git a/neutron_tempest_plugin/api/test_routers_negative.py b/neutron_tempest_plugin/api/test_routers_negative.py
index 8700761..86d58e2 100644
--- a/neutron_tempest_plugin/api/test_routers_negative.py
+++ b/neutron_tempest_plugin/api/test_routers_negative.py
@@ -19,6 +19,10 @@
import testtools
from neutron_tempest_plugin.api import base_routers as base
+from neutron_tempest_plugin import config
+
+
+CONF = config.CONF
class RoutersNegativeTestBase(base.BaseRouterTest):
@@ -88,6 +92,23 @@
self.client.add_router_interface_with_port_id,
self.router['id'], invalid_id)
+ @decorators.attr(type='negative')
+ @decorators.idempotent_id('dad7a8ba-2726-11eb-82dd-74e5f9e2a801')
+ def test_remove_associated_ports(self):
+ self.client.update_router(
+ self.router['id'],
+ external_gateway_info={
+ 'network_id': CONF.network.public_network_id})
+ network = self.create_network()
+ subnet = self.create_subnet(network)
+ self.create_router_interface(self.router['id'], subnet['id'])
+ port_ids = [
+ item['id'] for item in self.admin_client.list_ports(
+ device_id=self.router['id'])['ports']]
+ for port_id in port_ids:
+ with testtools.ExpectedException(lib_exc.Conflict):
+ self.admin_client.delete_port(port_id)
+
class DvrRoutersNegativeTest(RoutersNegativeTestBase):
diff --git a/neutron_tempest_plugin/common/ip.py b/neutron_tempest_plugin/common/ip.py
index d981770..7b172b0 100644
--- a/neutron_tempest_plugin/common/ip.py
+++ b/neutron_tempest_plugin/common/ip.py
@@ -57,6 +57,20 @@
return shell.execute(command_line, ssh_client=self.ssh_client,
timeout=self.timeout).stdout
+ def configure_vlan(self, addresses, port, vlan_tag, subport_ips):
+ port_device = get_port_device_name(addresses=addresses, port=port)
+ subport_device = '{!s}.{!s}'.format(port_device, vlan_tag)
+ LOG.debug('Configuring VLAN subport interface %r on top of interface '
+ '%r with IPs: %s', subport_device, port_device,
+ ', '.join(subport_ips))
+
+ self.add_link(link=port_device, name=subport_device, link_type='vlan',
+ segmentation_id=vlan_tag)
+ self.set_link(device=subport_device, state='up')
+ for subport_ip in subport_ips:
+ self.add_address(address=subport_ip, device=subport_device)
+ return subport_device
+
def configure_vlan_subport(self, port, subport, vlan_tag, subnets):
addresses = self.list_addresses()
try:
@@ -77,18 +91,19 @@
"Unable to get IP address and subnet prefix lengths for "
"subport")
- port_device = get_port_device_name(addresses=addresses, port=port)
- subport_device = '{!s}.{!s}'.format(port_device, vlan_tag)
- LOG.debug('Configuring VLAN subport interface %r on top of interface '
- '%r with IPs: %s', subport_device, port_device,
- ', '.join(subport_ips))
+ return self.configure_vlan(addresses, port, vlan_tag, subport_ips)
- self.add_link(link=port_device, name=subport_device, link_type='vlan',
- segmentation_id=vlan_tag)
- self.set_link(device=subport_device, state='up')
- for subport_ip in subport_ips:
- self.add_address(address=subport_ip, device=subport_device)
- return subport_device
+ def configure_vlan_transparent(self, port, vlan_tag, ip_addresses):
+ addresses = self.list_addresses()
+ try:
+ subport_device = get_vlan_device_name(addresses, ip_addresses)
+ except ValueError:
+ pass
+ else:
+ LOG.debug('Interface %r already configured.', subport_device)
+ return subport_device
+
+ return self.configure_vlan(addresses, port, vlan_tag, ip_addresses)
def list_namespaces(self):
namespaces_output = self.execute("netns")
@@ -128,6 +143,23 @@
# ip addr add 192.168.1.1/24 dev em1
return self.execute('address', 'add', address, 'dev', device)
+ def delete_address(self, address, device):
+ # ip addr del 192.168.1.1/24 dev em1
+ return self.execute('address', 'del', address, 'dev', device)
+
+ def add_route(self, address, device, gateway=None):
+ if gateway:
+ # ip route add 192.168.1.0/24 via 192.168.22.1 dev em1
+ return self.execute(
+ 'route', 'add', address, 'via', gateway, 'dev', device)
+ else:
+ # ip route add 192.168.1.0/24 dev em1
+ return self.execute('route', 'add', address, 'dev', device)
+
+ def delete_route(self, address, device):
+ # ip route del 192.168.1.0/24 dev em1
+ return self.execute('route', 'del', address, 'dev', device)
+
def list_routes(self, *args):
output = self.execute('route', 'show', *args)
return list(parse_routes(output))
@@ -312,6 +344,15 @@
raise ValueError(msg)
+def get_vlan_device_name(addresses, ip_addresses):
+ for address in list_ip_addresses(addresses=addresses,
+ ip_addresses=ip_addresses):
+ return address.device.name
+
+ msg = "Fixed IPs {0!r} not found on server.".format(' '.join(ip_addresses))
+ raise ValueError(msg)
+
+
def _get_ip_address_prefix_len_pairs(port, subnets):
subnets = {subnet['id']: subnet for subnet in subnets}
for fixed_ip in port['fixed_ips']:
diff --git a/neutron_tempest_plugin/common/ssh.py b/neutron_tempest_plugin/common/ssh.py
index c6204a4..8334521 100644
--- a/neutron_tempest_plugin/common/ssh.py
+++ b/neutron_tempest_plugin/common/ssh.py
@@ -286,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/scenario/base.py b/neutron_tempest_plugin/scenario/base.py
index c7c5459..127701c 100644
--- a/neutron_tempest_plugin/scenario/base.py
+++ b/neutron_tempest_plugin/scenario/base.py
@@ -205,7 +205,6 @@
else:
router = cls.create_admin_router(**kwargs)
LOG.debug("Created router %s", router['name'])
- cls.routers.append(router)
return router
@removals.remove(version='Stein',
@@ -307,13 +306,19 @@
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()
+ 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))
- 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('Namespace %s; Local ARP table:\n%s',
ns_name, '\n'.join(str(r) for r in arp_table))
@@ -513,7 +518,7 @@
pkey=self.keypair['private_key'],
**kwargs)
self.assertIn(server['name'],
- ssh_client.exec_command('hostname'))
+ ssh_client.get_hostname())
except (lib_exc.SSHTimeout, ssh_exc.AuthenticationException) as ssh_e:
LOG.debug(ssh_e)
if log_errors:
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_internal_dns.py b/neutron_tempest_plugin/scenario/test_internal_dns.py
index c620233..406af3d 100644
--- a/neutron_tempest_plugin/scenario/test_internal_dns.py
+++ b/neutron_tempest_plugin/scenario/test_internal_dns.py
@@ -59,7 +59,7 @@
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 732c96d..4237d4f 100644
--- a/neutron_tempest_plugin/scenario/test_ipv6.py
+++ b/neutron_tempest_plugin/scenario/test_ipv6.py
@@ -84,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
diff --git a/neutron_tempest_plugin/scenario/test_metadata.py b/neutron_tempest_plugin/scenario/test_metadata.py
index 3897183..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 = (
diff --git a/neutron_tempest_plugin/scenario/test_port_forwardings.py b/neutron_tempest_plugin/scenario/test_port_forwardings.py
index a4711ae..6a5d3c9 100644
--- a/neutron_tempest_plugin/scenario/test_port_forwardings.py
+++ b/neutron_tempest_plugin/scenario/test_port_forwardings.py
@@ -14,7 +14,6 @@
# under the License.
from neutron_lib import constants
-from neutron_lib.utils import test
from oslo_log import log
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
@@ -186,7 +185,6 @@
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
@@ -243,7 +241,6 @@
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,
diff --git a/neutron_tempest_plugin/scenario/test_ports.py b/neutron_tempest_plugin/scenario/test_ports.py
index 3b0408a..b3aeb87 100644
--- a/neutron_tempest_plugin/scenario/test_ports.py
+++ b/neutron_tempest_plugin/scenario/test_ports.py
@@ -12,6 +12,9 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
+import ipaddress
+
+from oslo_log import log as logging
from tempest.common import waiters
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
@@ -20,6 +23,7 @@
from neutron_tempest_plugin.scenario import base
from neutron_tempest_plugin.scenario import constants as const
+LOG = logging.getLogger(__name__)
CONF = config.CONF
@@ -78,3 +82,34 @@
self.os_primary.servers_client,
servers[0]['server']['id'])
self._try_delete_resource(self.delete_floatingip, fips[0])
+
+ @decorators.idempotent_id('62e32802-1d21-11eb-b322-74e5f9e2a801')
+ def test_port_with_fixed_ip(self):
+ """Test scenario:
+
+ 1) Get the last IP from the range of Subnet "Allocation pool"
+ 2) Create Port with fixed_ip resolved in #1
+ 3) Create a VM using updated Port in #2 and add Floating IP
+ 4) Check SSH access to VM
+ """
+ ip_range = [str(ip) for ip in ipaddress.IPv4Network(
+ self.subnet['cidr'])]
+ # Because of the tests executed in Parallel the IP may already
+ # be in use, so we'll try using IPs from Allocation pool
+ # (in reverse order) up until Port is successfully created.
+ for ip in reversed(ip_range):
+ try:
+ port = self.create_port(
+ self.network,
+ name=data_utils.rand_name("fixed_ip_port"),
+ security_groups=[self.secgroup['id']],
+ fixed_ips=[{'ip_address': ip}])
+ if port is not None:
+ break
+ except Exception as e:
+ LOG.warn('Failed to create Port, using Fixed_IP:{}, '
+ 'the Error was:{}'.format(ip, e))
+ fip, server = self._create_instance_with_port(port)
+ self.check_connectivity(fip[0]['floating_ip_address'],
+ CONF.validation.image_ssh_user,
+ self.keypair['private_key'])
diff --git a/neutron_tempest_plugin/scenario/test_qos.py b/neutron_tempest_plugin/scenario/test_qos.py
index 6cd6b25..77520a7 100644
--- a/neutron_tempest_plugin/scenario/test_qos.py
+++ b/neutron_tempest_plugin/scenario/test_qos.py
@@ -191,32 +191,26 @@
@decorators.idempotent_id('00682a0c-b72e-11e8-b81e-8c16450ea513')
def test_qos_basic_and_update(self):
- """This test covers both:
+ """This test covers following scenarios:
- 1) Basic QoS functionality
- This is a basic test that check that a QoS policy with
- a bandwidth limit rule is applied correctly by sending
- a file from the instance to the test node.
- Then calculating the bandwidth every ~1 sec by the number of bits
- received / elapsed time.
+ 1) Create a QoS policy associated with the network.
+ Expected result: BW is limited according the values set in
+ QoS policy rule.
- 2) Update QoS policy
- Administrator has the ability to update existing QoS policy,
- this test is planned to verify that:
- - actual BW is affected as expected after updating QoS policy.
- Test scenario:
- 1) Associating QoS Policy with "Original_bandwidth"
- to the test node
- 2) BW validation - by downloading file on test node.
- ("Original_bandwidth" is expected)
- 3) Updating existing QoS Policy to a new BW value
- "Updated_bandwidth"
- 4) BW validation - by downloading file on test node.
- ("Updated_bandwidth" is expected)
- Note:
- There are two options to associate QoS policy to VM:
- "Neutron Port" or "Network", in this test
- both options are covered.
+ 2) Update QoS policy associated with the network.
+ Expected result: BW is limited according the new values
+ set in QoS policy rule.
+
+ 3) Create a new QoS policy associated with the VM port.
+ Expected result: BW is limited according the values set in
+ new QoS policy rule.
+ Note: Neutron port is prioritized higher than Network, means
+ that: "Neutron Port Priority" is also covered.
+
+ 4) Update QoS policy associated with the VM port.
+ Expected result: BW is limited according the new values set
+ in QoS policy rule.
+
"""
# Setup resources
@@ -244,7 +238,10 @@
self.fip['floating_ip_address'],
port=self.NC_PORT),
timeout=self.CHECK_TIMEOUT,
- sleep=1)
+ sleep=1,
+ exception=RuntimeError(
+ 'Failed scenario: "Create a QoS policy associated with'
+ ' the network" Actual BW is not as expected!'))
# As admin user update QoS rule
self.os_admin.network_client.update_bandwidth_limit_rule(
@@ -261,7 +258,10 @@
port=self.NC_PORT,
expected_bw=QoSTest.LIMIT_BYTES_SEC * 2),
timeout=self.CHECK_TIMEOUT,
- sleep=1)
+ sleep=1,
+ exception=RuntimeError(
+ 'Failed scenario: "Update QoS policy associated with'
+ ' the network" Actual BW is not as expected!'))
# Create a new QoS policy
bw_limit_policy_id_new = self._create_qos_policy()
@@ -284,7 +284,10 @@
self.fip['floating_ip_address'],
port=self.NC_PORT),
timeout=self.CHECK_TIMEOUT,
- sleep=1)
+ sleep=1,
+ exception=RuntimeError(
+ 'Failed scenario: "Create a new QoS policy associated with'
+ ' the VM port" Actual BW is not as expected!'))
# As admin user update QoS rule
self.os_admin.network_client.update_bandwidth_limit_rule(
@@ -301,7 +304,10 @@
port=self.NC_PORT,
expected_bw=QoSTest.LIMIT_BYTES_SEC * 3),
timeout=self.CHECK_TIMEOUT,
- sleep=1)
+ sleep=1,
+ exception=RuntimeError(
+ 'Failed scenario: "Update QoS policy associated with'
+ ' the VM port" Actual BW is not as expected!'))
@decorators.idempotent_id('66e5673e-0522-11ea-8d71-362b9e155667')
def test_attach_previously_used_port_to_new_instance(self):
diff --git a/neutron_tempest_plugin/scenario/test_trunk.py b/neutron_tempest_plugin/scenario/test_trunk.py
index 98fe6ae..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
@@ -246,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),
diff --git a/neutron_tempest_plugin/scenario/test_vlan_transparency.py b/neutron_tempest_plugin/scenario/test_vlan_transparency.py
new file mode 100644
index 0000000..d9a529c
--- /dev/null
+++ b/neutron_tempest_plugin/scenario/test_vlan_transparency.py
@@ -0,0 +1,186 @@
+# Copyright (c) 2020 Red Hat, Inc.
+#
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from oslo_log import log as logging
+from tempest.lib.common.utils import data_utils
+from tempest.lib import decorators
+
+from neutron_tempest_plugin.common import ip
+from neutron_tempest_plugin.common import ssh
+from neutron_tempest_plugin import config
+from neutron_tempest_plugin.scenario import base
+
+
+LOG = logging.getLogger(__name__)
+CONF = config.CONF
+MIN_VLAN_ID = 1
+MAX_VLAN_ID = 4094
+
+
+class VlanTransparencyTest(base.BaseTempestTestCase):
+ credentials = ['primary', 'admin']
+ force_tenant_isolation = False
+
+ required_extensions = ['vlan-transparent', 'allowed-address-pairs']
+
+ @classmethod
+ def resource_setup(cls):
+ super(VlanTransparencyTest, cls).resource_setup()
+ # setup basic topology for servers we can log into
+ cls.rand_name = data_utils.rand_name(
+ cls.__name__.rsplit('.', 1)[-1])
+ cls.network = cls.create_network(name=cls.rand_name,
+ vlan_transparent=True)
+ 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.vm_ports = []
+ cls.security_group = cls.create_security_group(name=cls.rand_name)
+ cls.create_loginable_secgroup_rule(cls.security_group['id'])
+
+ if CONF.neutron_plugin_options.default_image_is_advanced:
+ cls.flavor_ref = CONF.compute.flavor_ref
+ cls.image_ref = CONF.compute.image_ref
+ else:
+ cls.flavor_ref = \
+ CONF.neutron_plugin_options.advanced_image_flavor_ref
+ cls.image_ref = CONF.neutron_plugin_options.advanced_image_ref
+
+ @classmethod
+ def skip_checks(cls):
+ super(VlanTransparencyTest, cls).skip_checks()
+ if not (CONF.neutron_plugin_options.advanced_image_ref or
+ CONF.neutron_plugin_options.default_image_is_advanced):
+ raise cls.skipException(
+ 'Advanced image is required to run these tests.')
+
+ def _create_port_and_server(self, index,
+ port_security=True,
+ allowed_address_pairs=None):
+ server_name = 'server-%s-%d' % (self.rand_name, index)
+ port_name = 'port-%s-%d' % (self.rand_name, index)
+ if port_security:
+ sec_groups = [self.security_group['id']]
+ else:
+ sec_groups = None
+ self.vm_ports.append(
+ self.create_port(network=self.network, name=port_name,
+ security_groups=sec_groups,
+ port_security_enabled=port_security,
+ allowed_address_pairs=allowed_address_pairs))
+ return self.create_server(flavor_ref=self.flavor_ref,
+ image_ref=self.image_ref,
+ key_name=self.keypair['name'],
+ networks=[{'port': self.vm_ports[-1]['id']}],
+ name=server_name)['server']
+
+ def _configure_vlan_transparent(self, port, ssh_client,
+ vlan_tag, vlan_ip):
+ ip_command = ip.IPCommand(ssh_client=ssh_client)
+ addresses = ip_command.list_addresses(port=port)
+ port_iface = ip.get_port_device_name(addresses, port)
+ subport_iface = ip_command.configure_vlan_transparent(
+ port=port, vlan_tag=vlan_tag, ip_addresses=[vlan_ip])
+
+ for address in ip_command.list_addresses(ip_addresses=vlan_ip):
+ self.assertEqual(subport_iface, address.device.name)
+ self.assertEqual(port_iface, address.device.parent)
+ break
+ else:
+ self.fail("Sub-port fixed IP not found on server.")
+
+ def _create_ssh_client(self, floating_ip):
+ if CONF.neutron_plugin_options.default_image_is_advanced:
+ username = CONF.validation.image_ssh_user
+ else:
+ username = CONF.neutron_plugin_options.advanced_image_ssh_user
+ return ssh.Client(host=floating_ip['floating_ip_address'],
+ username=username,
+ pkey=self.keypair['private_key'])
+
+ def _test_basic_vlan_transparency_connectivity(
+ self, port_security=True, use_allowed_address_pairs=False):
+ vlan_tag = data_utils.rand_int_id(start=MIN_VLAN_ID, end=MAX_VLAN_ID)
+ vlan_ipmask_template = '192.168.%d.{ip_last_byte}/24' % (vlan_tag %
+ 256)
+ vms = []
+ vlan_ipmasks = []
+ floating_ips = []
+ ssh_clients = []
+
+ for i in range(2):
+ vlan_ipmasks.append(vlan_ipmask_template.format(
+ ip_last_byte=(i + 1) * 10))
+ if use_allowed_address_pairs:
+ allowed_address_pairs = [{'ip_address': vlan_ipmasks[i]}]
+ else:
+ allowed_address_pairs = None
+ vms.append(self._create_port_and_server(
+ index=i,
+ port_security=port_security,
+ allowed_address_pairs=allowed_address_pairs))
+ floating_ips.append(self.create_floatingip(port=self.vm_ports[-1]))
+ ssh_clients.append(
+ self._create_ssh_client(floating_ip=floating_ips[i]))
+
+ self.check_connectivity(
+ host=floating_ips[i]['floating_ip_address'],
+ ssh_client=ssh_clients[i])
+ self._configure_vlan_transparent(port=self.vm_ports[-1],
+ ssh_client=ssh_clients[i],
+ vlan_tag=vlan_tag,
+ vlan_ip=vlan_ipmasks[i])
+
+ if port_security:
+ # Ping from vm0 to vm1 via VLAN interface should fail because
+ # we haven't allowed ICMP
+ self.check_remote_connectivity(
+ ssh_clients[0],
+ vlan_ipmasks[1].split('/')[0],
+ servers=vms,
+ should_succeed=False)
+
+ # allow intra-security-group traffic
+ sg_rule = self.create_pingable_secgroup_rule(
+ self.security_group['id'])
+ self.addCleanup(
+ self.os_primary.network_client.delete_security_group_rule,
+ sg_rule['id'])
+
+ # Ping from vm0 to vm1 via VLAN interface should pass because
+ # either port security is disabled or the ICMP sec group rule has been
+ # added
+ self.check_remote_connectivity(
+ ssh_clients[0],
+ vlan_ipmasks[1].split('/')[0],
+ servers=vms)
+ # Ping from vm1 to vm0 and check untagged packets are not dropped
+ self.check_remote_connectivity(
+ ssh_clients[1],
+ self.vm_ports[-2]['fixed_ips'][0]['ip_address'],
+ servers=vms)
+
+ @decorators.idempotent_id('a2694e3a-6d4d-4a23-9fcc-c3ed3ef37b16')
+ def test_vlan_transparent_port_sec_disabled(self):
+ self._test_basic_vlan_transparency_connectivity(
+ port_security=False, use_allowed_address_pairs=False)
+
+ @decorators.idempotent_id('2dd03b4f-9c20-4cda-8c6a-40fa453ec69a')
+ def test_vlan_transparent_allowed_address_pairs(self):
+ self._test_basic_vlan_transparency_connectivity(
+ port_security=True, use_allowed_address_pairs=True)
diff --git a/neutron_tempest_plugin/services/network/json/network_client.py b/neutron_tempest_plugin/services/network/json/network_client.py
index e733cd0..2678d73 100644
--- a/neutron_tempest_plugin/services/network/json/network_client.py
+++ b/neutron_tempest_plugin/services/network/json/network_client.py
@@ -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)
diff --git a/test-requirements.txt b/test-requirements.txt
index bf1c626..f5bac7c 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -7,10 +7,6 @@
coverage!=4.4,>=4.0 # Apache-2.0
flake8-import-order==0.12 # LGPLv3
python-subunit>=1.0.0 # Apache-2.0/BSD
-sphinx>=2.0.0,!=2.1.0 # BSD
oslotest>=3.2.0 # Apache-2.0
stestr>=1.0.0 # Apache-2.0
testtools>=2.2.0 # MIT
-openstackdocstheme>=2.2.1 # Apache-2.0
-# releasenotes
-reno>=3.1.0 # Apache-2.0
diff --git a/tox.ini b/tox.ini
index eecd16e..d3e722a 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}
@@ -39,9 +39,12 @@
coverage xml -o cover/coverage.xml
[testenv:docs]
+deps = -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master}
+ -r{toxinidir}/doc/requirements.txt
commands = sphinx-build -W -b html doc/source doc/build/html
[testenv:releasenotes]
+deps = {[testenv:docs]deps}
commands =
sphinx-build -a -E -W -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html
diff --git a/zuul.d/base.yaml b/zuul.d/base.yaml
index 28998cf..cc1479b 100644
--- a/zuul.d/base.yaml
+++ b/zuul.d/base.yaml
@@ -37,6 +37,12 @@
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
@@ -98,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
@@ -107,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 072c8b4..ee7c6e3 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,14 +173,21 @@
pre-run: playbooks/linuxbridge-scenario-pre-run.yaml
vars:
network_api_extensions: *api_extensions
+ network_api_extensions_linuxbridge:
+ - vlan-transparent
+ network_available_features: *available_features
+ # TODO(eolivare): remove VLAN Transparency tests from blacklist
+ # when bug https://bugs.launchpad.net/neutron/+bug/1907548 will be fixed
+ tempest_black_regex: "(^neutron_tempest_plugin.scenario.test_vlan_transparency.VlanTransparencyTest)"
devstack_localrc:
Q_AGENT: linuxbridge
- NETWORK_API_EXTENSIONS: "{{ network_api_extensions | join(',') }}"
+ NETWORK_API_EXTENSIONS: "{{ (network_api_extensions + network_api_extensions_linuxbridge) | join(',') }}"
devstack_local_conf:
post-config:
$NEUTRON_CONF:
DEFAULT:
enable_dvr: false
+ vlan_transparent: true
AGENT:
debug_iptables_rules: true
# NOTE(slaweq): We can get rid of this hardcoded absolute path when
@@ -179,8 +196,11 @@
/$NEUTRON_CORE_PLUGIN_CONF:
ml2:
type_drivers: flat,vlan,local,vxlan
+ mechanism_drivers: linuxbridge
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,6 +211,8 @@
timeout: 10000
vars:
network_api_extensions: *api_extensions
+ network_api_extensions_ovn:
+ - vlan-transparent
# TODO(haleyb): Remove IPv6Test from blacklist when
# https://bugs.launchpad.net/neutron/+bug/1881558 is fixed.
# TODO(slaweq): Remove test_trunk_subport_lifecycle test from the
@@ -204,7 +226,7 @@
(^neutron_tempest_plugin.scenario.test_mtu.NetworkWritableMtuTest)"
devstack_localrc:
Q_AGENT: ovn
- NETWORK_API_EXTENSIONS: "{{ network_api_extensions | join(',') }}"
+ NETWORK_API_EXTENSIONS: "{{ (network_api_extensions + network_api_extensions_ovn) | join(',') }}"
Q_ML2_PLUGIN_MECHANISM_DRIVERS: ovn,logger
Q_ML2_PLUGIN_TYPE_DRIVERS: local,flat,vlan,geneve
Q_ML2_TENANT_NETWORK_TYPE: geneve
@@ -215,6 +237,11 @@
OVN_DBS_LOG_LEVEL: dbg
ENABLE_TLS: True
OVN_IGMP_SNOOPING_ENABLE: True
+ # TODO(eolivare): Remove OVN_BUILD_FROM_SOURCE once vlan-transparency
+ # is included in an ovn released version
+ OVN_BUILD_FROM_SOURCE: True
+ OVN_BRANCH: "v20.12.0"
+ OVS_BRANCH: "branch-2.15"
devstack_services:
br-ex-tcpdump: true
br-int-flows: true
@@ -228,26 +255,34 @@
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:
DEFAULT:
enable_dvr: false
+ vlan_transparent: true
/$NEUTRON_CORE_PLUGIN_CONF:
ml2:
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:
@@ -299,7 +334,12 @@
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
@@ -350,6 +390,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
@@ -367,6 +409,9 @@
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
diff --git a/zuul.d/project.yaml b/zuul.d/project.yaml
index 0355f69..973ab9f 100644
--- a/zuul.d/project.yaml
+++ b/zuul.d/project.yaml
@@ -164,7 +164,6 @@
templates:
- build-openstack-docs-pti
- neutron-tempest-plugin-jobs
- - neutron-tempest-plugin-jobs-stein
- neutron-tempest-plugin-jobs-train
- neutron-tempest-plugin-jobs-ussuri
- neutron-tempest-plugin-jobs-victoria
@@ -177,30 +176,10 @@
- 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
- # will be fixed
- voting: false
+ - 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-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
- voting: false
- - neutron-tempest-plugin-fwaas-ussuri:
- # TODO(slaweq): switch it to be voting when bug
- # https://bugs.launchpad.net/neutron/+bug/1858645 will be fixed
- voting: false
+ - neutron-tempest-plugin-bgpvpn-bagpipe-ussuri
+ - neutron-tempest-plugin-bgpvpn-bagpipe-victoria
- neutron-tempest-plugin-dynamic-routing
- neutron-tempest-plugin-dynamic-routing-ussuri
- neutron-tempest-plugin-dynamic-routing-victoria
@@ -211,8 +190,16 @@
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
+
+ experimental:
+ jobs:
+ - neutron-tempest-plugin-fwaas-train:
+ # TODO(slaweq): switch it to be voting when bug
+ # https://bugs.launchpad.net/neutron/+bug/1858645 will be fixed
+ voting: false
+ - neutron-tempest-plugin-fwaas-ussuri:
+ # TODO(slaweq): switch it to be voting when bug
+ # https://bugs.launchpad.net/neutron/+bug/1858645 will be fixed
+ voting: false
diff --git a/zuul.d/queens_jobs.yaml b/zuul.d/queens_jobs.yaml
index b0ee336..e1ecc00 100644
--- a/zuul.d/queens_jobs.yaml
+++ b/zuul.d/queens_jobs.yaml
@@ -65,7 +65,10 @@
- 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(',') }}"
@@ -87,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
@@ -117,6 +121,7 @@
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: "\
diff --git a/zuul.d/rocky_jobs.yaml b/zuul.d/rocky_jobs.yaml
index 6eb8c15..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(',') }}"
diff --git a/zuul.d/stein_jobs.yaml b/zuul.d/stein_jobs.yaml
index ff6ed38..29dfa8a 100644
--- a/zuul.d/stein_jobs.yaml
+++ b/zuul.d/stein_jobs.yaml
@@ -3,6 +3,12 @@
parent: neutron-tempest-plugin-api
nodeset: openstack-single-node-bionic
override-checkout: stable/stein
+ required-projects: &required-projects-stein
+ - openstack/devstack-gate
+ - openstack/neutron
+ - name: openstack/neutron-tempest-plugin
+ override-checkout: 1.3.0
+ - openstack/tempest
vars:
branch_override: stable/stein
# TODO(slaweq): find a way to put this list of extensions in
@@ -73,7 +79,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:
@@ -81,14 +90,18 @@
parent: neutron-tempest-plugin-scenario-openvswitch
nodeset: openstack-single-node-bionic
override-checkout: stable/stein
+ required-projects: *required-projects-stein
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
@@ -97,14 +110,18 @@
parent: neutron-tempest-plugin-scenario-openvswitch-iptables_hybrid
nodeset: openstack-single-node-bionic
override-checkout: stable/stein
+ required-projects: *required-projects-stein
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
@@ -113,14 +130,18 @@
parent: neutron-tempest-plugin-scenario-linuxbridge
nodeset: openstack-single-node-bionic
override-checkout: stable/stein
+ required-projects: *required-projects-stein
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
@@ -129,6 +150,7 @@
parent: neutron-tempest-plugin-dvr-multinode-scenario
nodeset: openstack-two-node-bionic
override-checkout: stable/stein
+ required-projects: *required-projects-stein
vars:
network_api_extensions_common: *api_extensions
branch_override: stable/stein
@@ -141,7 +163,8 @@
required-projects:
- openstack/devstack-gate
- openstack/neutron
- - openstack/neutron-tempest-plugin
+ - name: openstack/neutron-tempest-plugin
+ override-checkout: 1.3.0
- name: openstack/designate-tempest-plugin
override-checkout: 0.7.0
- openstack/tempest
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..9cc0621 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
@@ -149,6 +163,7 @@
OVN_BUILD_MODULES: True
# TODO(skaplons): v2.13.1 is incompatible with kernel 4.15.0-118, sticking to commit hash until new v2.13 tag is created
OVS_BRANCH: 0047ca3a0290f1ef954f2c76b31477cf4b9755f5
+ OVN_BRANCH: "v20.03.0"
- job:
name: neutron-tempest-plugin-dvr-multinode-scenario-ussuri
diff --git a/zuul.d/victoria_jobs.yaml b/zuul.d/victoria_jobs.yaml
index 0bc1e13..5543ea7 100644
--- a/zuul.d/victoria_jobs.yaml
+++ b/zuul.d/victoria_jobs.yaml
@@ -81,7 +81,10 @@
- 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:
@@ -91,11 +94,14 @@
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
@@ -106,11 +112,14 @@
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
@@ -121,11 +130,14 @@
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
@@ -138,6 +150,11 @@
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