Merge "Tempest: Add l3-ha extension requirement for HA tests"
diff --git a/.zuul.yaml b/.zuul.yaml
index 636327e..adcb433 100644
--- a/.zuul.yaml
+++ b/.zuul.yaml
@@ -187,7 +187,6 @@
- ^(test-|)requirements.txt$
- ^releasenotes/.*$
- ^setup.cfg$
- voting: false
- job:
name: neutron-tempest-plugin-designate-scenario-queens
@@ -208,6 +207,7 @@
gate:
jobs:
- neutron-tempest-plugin-api
+ - neutron-tempest-plugin-scenario-linuxbridge
- build-openstack-sphinx-docs
- project-template:
diff --git a/neutron_tempest_plugin/api/admin/test_quotas.py b/neutron_tempest_plugin/api/admin/test_quotas.py
index 1acfc18..ae773c8 100644
--- a/neutron_tempest_plugin/api/admin/test_quotas.py
+++ b/neutron_tempest_plugin/api/admin/test_quotas.py
@@ -121,17 +121,26 @@
new_quotas = {'network': {'used': 1, 'limit': 2, 'reserved': 0},
'port': {'used': 1, 'limit': 2, 'reserved': 0}}
- # update quota limit for tenant
- new_quota = {'network': new_quotas['network']['limit'], 'port':
- new_quotas['port']['limit']}
- quota_set = self._setup_quotas(tenant_id, **new_quota)
-
# create test resources
network = self._create_network(tenant_id)
post_body = {"network_id": network['id'],
"tenant_id": tenant_id}
+
+ # NOTE(lucasagomes): Some backends such as OVN will create a port
+ # to be used by the metadata agent upon creating a network. In
+ # order to make this test more generic we need to calculate the
+ # number of expected used ports after the network is created and
+ # prior for the port being created
+ ports = self.admin_client.list_ports(tenant_id=tenant_id)
+ new_quotas['port']['used'] += len(ports['ports'])
+
self._create_port(**post_body)
+ # update quota limit for tenant
+ new_quota = {'network': new_quotas['network']['limit'], 'port':
+ new_quotas['port']['limit']}
+ quota_set = self._setup_quotas(tenant_id, **new_quota)
+
# confirm from extended API quotas were changed
# as requested for tenant
quota_set = self.admin_client.show_details_quota(tenant_id)
diff --git a/neutron_tempest_plugin/api/base.py b/neutron_tempest_plugin/api/base.py
index fdd8ba9..6246eb7 100644
--- a/neutron_tempest_plugin/api/base.py
+++ b/neutron_tempest_plugin/api/base.py
@@ -284,8 +284,9 @@
return network
@classmethod
- def create_subnet(cls, network, gateway=None, cidr=None, mask_bits=None,
- ip_version=None, client=None, **kwargs):
+ def create_subnet(cls, network, gateway='', cidr=None, mask_bits=None,
+ ip_version=None, client=None, reserve_cidr=True,
+ **kwargs):
"""Wrapper utility that returns a test subnet.
Convenient wrapper for client.create_subnet method. It reserves and
@@ -298,6 +299,7 @@
It can be a str or a netaddr.IPAddress
If gateway is not given, then it will use default address for
given subnet CIDR, like "192.168.0.1" for "192.168.0.0/24" CIDR
+ if gateway is given as None then no gateway will be assigned
:param cidr: CIDR of the subnet to create
It can be either None, a str or a netaddr.IPNetwork instance
@@ -318,6 +320,10 @@
:param client: client to be used to connect to network service
+ :param reserve_cidr: if True then it reserves assigned CIDR to avoid
+ using the same CIDR for further subnets in the scope of the same
+ test case class
+
:param **kwargs: optional parameters to be forwarded to wrapped method
[1] http://netaddr.readthedocs.io/en/latest/tutorial_01.html#supernets-and-subnets # noqa
@@ -335,22 +341,23 @@
"Gateway IP version doesn't match IP version")
else:
ip_version = gateway_ip.version
+ else:
+ ip_version = ip_version or cls._ip_version
for subnet_cidr in cls.get_subnet_cidrs(
ip_version=ip_version, cidr=cidr, mask_bits=mask_bits):
- if cls.try_reserve_subnet_cidr(subnet_cidr):
- gateway_ip = gateway or str(subnet_cidr.ip + 1)
- try:
- body = client.create_subnet(
- network_id=network['id'],
- cidr=str(subnet_cidr),
- ip_version=subnet_cidr.version,
- gateway_ip=str(gateway_ip),
- **kwargs)
- break
- except lib_exc.BadRequest as e:
- if 'overlaps with another subnet' not in str(e):
- raise
+ if gateway is not None:
+ kwargs['gateway_ip'] = str(gateway or (subnet_cidr.ip + 1))
+ try:
+ body = client.create_subnet(
+ network_id=network['id'],
+ cidr=str(subnet_cidr),
+ ip_version=subnet_cidr.version,
+ **kwargs)
+ break
+ except lib_exc.BadRequest as e:
+ if 'overlaps with another subnet' not in str(e):
+ raise
else:
message = 'Available CIDR for subnet creation could not be found'
raise ValueError(message)
@@ -359,6 +366,8 @@
cls.subnets.append(subnet)
else:
cls.admin_subnets.append(subnet)
+ if reserve_cidr:
+ cls.reserve_subnet_cidr(subnet_cidr)
return subnet
@classmethod
diff --git a/neutron_tempest_plugin/api/test_dhcp_ipv6.py b/neutron_tempest_plugin/api/test_dhcp_ipv6.py
index 69b4ea0..0fab75c 100644
--- a/neutron_tempest_plugin/api/test_dhcp_ipv6.py
+++ b/neutron_tempest_plugin/api/test_dhcp_ipv6.py
@@ -58,8 +58,8 @@
ports = body['ports']
for port in ports:
if (port['device_owner'].startswith(
- constants.DEVICE_OWNER_ROUTER_INTF)
- and port['device_id'] in [r['id'] for r in self.routers]):
+ constants.DEVICE_OWNER_ROUTER_INTF) and
+ port['device_id'] in [r['id'] for r in self.routers]):
self.client.remove_router_interface_with_port_id(
port['device_id'], port['id']
)
diff --git a/neutron_tempest_plugin/api/test_network_ip_availability.py b/neutron_tempest_plugin/api/test_network_ip_availability.py
index ed56363..10aee2e 100644
--- a/neutron_tempest_plugin/api/test_network_ip_availability.py
+++ b/neutron_tempest_plugin/api/test_network_ip_availability.py
@@ -79,11 +79,11 @@
def calc_total_ips(prefix, ip_version):
# will calculate total ips after removing reserved.
if ip_version == lib_constants.IP_VERSION_4:
- total_ips = 2 ** (lib_constants.IPv4_BITS
- - prefix) - DEFAULT_IP4_RESERVED
+ total_ips = 2 ** (lib_constants.IPv4_BITS -
+ prefix) - DEFAULT_IP4_RESERVED
elif ip_version == lib_constants.IP_VERSION_6:
- total_ips = 2 ** (lib_constants.IPv6_BITS
- - prefix) - DEFAULT_IP6_RESERVED
+ total_ips = 2 ** (lib_constants.IPv6_BITS -
+ prefix) - DEFAULT_IP6_RESERVED
return total_ips
diff --git a/neutron_tempest_plugin/api/test_routers.py b/neutron_tempest_plugin/api/test_routers.py
index e1b2eb1..4637dd6 100644
--- a/neutron_tempest_plugin/api/test_routers.py
+++ b/neutron_tempest_plugin/api/test_routers.py
@@ -160,9 +160,12 @@
# Add router interface with subnet id
router = self._create_router(data_utils.rand_name('router'), True)
intf = self.create_router_interface(router['id'], subnet['id'])
- status_active = lambda: self.client.show_port(
- intf['port_id'])['port']['status'] == 'ACTIVE'
- utils.wait_until_true(status_active, exception=AssertionError)
+
+ def _status_active():
+ return self.client.show_port(
+ intf['port_id'])['port']['status'] == 'ACTIVE'
+
+ utils.wait_until_true(_status_active, exception=AssertionError)
@decorators.idempotent_id('c86ac3a8-50bd-4b00-a6b8-62af84a0765c')
@tutils.requires_ext(extension='extraroute', service='network')
diff --git a/neutron_tempest_plugin/common/utils.py b/neutron_tempest_plugin/common/utils.py
index d6d0aee..c42d984 100644
--- a/neutron_tempest_plugin/common/utils.py
+++ b/neutron_tempest_plugin/common/utils.py
@@ -18,11 +18,12 @@
"""Utilities and helper functions."""
-import eventlet
import functools
import threading
import time
+import eventlet
+
class classproperty(object):
def __init__(self, f):
diff --git a/neutron_tempest_plugin/scenario/base.py b/neutron_tempest_plugin/scenario/base.py
index 2bb6344..0a2fa14 100644
--- a/neutron_tempest_plugin/scenario/base.py
+++ b/neutron_tempest_plugin/scenario/base.py
@@ -302,9 +302,18 @@
1)
def check_remote_connectivity(self, source, dest, should_succeed=True,
- nic=None, mtu=None, fragmentation=True):
- self.assertTrue(self._check_remote_connectivity(
- source, dest, should_succeed, nic, mtu, fragmentation))
+ nic=None, mtu=None, fragmentation=True,
+ servers=None):
+ try:
+ self.assertTrue(self._check_remote_connectivity(
+ source, dest, should_succeed, nic, mtu, fragmentation))
+ except lib_exc.SSHTimeout as ssh_e:
+ LOG.debug(ssh_e)
+ self._log_console_output(servers)
+ raise
+ except AssertionError:
+ self._log_console_output(servers)
+ raise
def ping_ip_address(self, ip_address, should_succeed=True,
ping_timeout=None, mtu=None):
diff --git a/neutron_tempest_plugin/scenario/test_floatingip.py b/neutron_tempest_plugin/scenario/test_floatingip.py
index 251f21c..bc40176 100644
--- a/neutron_tempest_plugin/scenario/test_floatingip.py
+++ b/neutron_tempest_plugin/scenario/test_floatingip.py
@@ -68,8 +68,8 @@
network_id=CONF.network.public_network_id)
for subnet in subnets['subnets']:
- if (subnet['gateway_ip']
- and subnet['ip_version'] == lib_constants.IP_VERSION_4):
+ if (subnet['gateway_ip'] and
+ subnet['ip_version'] == lib_constants.IP_VERSION_4):
return subnet['gateway_ip']
@classmethod
@@ -212,15 +212,6 @@
def resource_setup(cls):
super(FloatingIPQosTest, cls).resource_setup()
- @classmethod
- def skip_checks(cls):
- super(FloatingIPQosTest, cls).skip_checks()
- if utils.is_extension_enabled("dvr", "network"):
- raise cls.skipException(
- "Skip until bug "
- "https://bugs.launchpad.net/neutron/+bug/1758316 "
- "will be fixed.")
-
@decorators.idempotent_id('5eb48aea-eaba-4c20-8a6f-7740070a0aa3')
def test_qos(self):
"""Test floating IP is binding to a QoS policy with
diff --git a/neutron_tempest_plugin/scenario/test_mtu.py b/neutron_tempest_plugin/scenario/test_mtu.py
index 8f1c9ed..b38d770 100644
--- a/neutron_tempest_plugin/scenario/test_mtu.py
+++ b/neutron_tempest_plugin/scenario/test_mtu.py
@@ -69,8 +69,8 @@
def skip_checks(cls):
super(NetworkMtuTest, cls).skip_checks()
if ("vxlan" not in
- config.CONF.neutron_plugin_options.available_type_drivers
- or "gre" not in
+ config.CONF.neutron_plugin_options.available_type_drivers or
+ "gre" not in
config.CONF.neutron_plugin_options.available_type_drivers):
raise cls.skipException("GRE or VXLAN type_driver is not enabled")
diff --git a/neutron_tempest_plugin/scenario/test_qos.py b/neutron_tempest_plugin/scenario/test_qos.py
index 58accb0..0611160 100644
--- a/neutron_tempest_plugin/scenario/test_qos.py
+++ b/neutron_tempest_plugin/scenario/test_qos.py
@@ -75,8 +75,8 @@
BS = 512
COUNT = BUFFER_SIZE / BS
FILE_SIZE = BS * COUNT
- LIMIT_BYTES_SEC = (constants.LIMIT_KILO_BITS_PER_SECOND * 1024
- * TOLERANCE_FACTOR / 8.0)
+ LIMIT_BYTES_SEC = (constants.LIMIT_KILO_BITS_PER_SECOND * 1024 *
+ TOLERANCE_FACTOR / 8.0)
FILE_PATH = "/tmp/img"
NC_PORT = 1234
diff --git a/neutron_tempest_plugin/scenario/test_trunk.py b/neutron_tempest_plugin/scenario/test_trunk.py
index 6fdcd5b..2ff7e5d 100644
--- a/neutron_tempest_plugin/scenario/test_trunk.py
+++ b/neutron_tempest_plugin/scenario/test_trunk.py
@@ -34,7 +34,8 @@
'sudo su -c '
'"ip l a link $IFACE name $IFACE.%(tag)d type vlan id %(tag)d &&'
'ip l s up dev $IFACE.%(tag)d && '
- 'dhclient $IFACE.%(tag)d"')
+ '{ ps -ef | grep -q "dhclient .*$IFACE.%(tag)d" || '
+ 'dhclient $IFACE.%(tag)d"; }')
class TrunkTest(base.BaseTempestTestCase):
@@ -230,7 +231,7 @@
vlan_tag = 10
vlan_network = self.create_network()
- self.create_subnet(vlan_network)
+ self.create_subnet(vlan_network, gateway=None)
servers = [
self._create_server_with_port_and_subport(vlan_network, vlan_tag)
diff --git a/test-requirements.txt b/test-requirements.txt
index b8835e3..84f3c18 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -5,6 +5,7 @@
hacking<0.13,>=0.12.0 # Apache-2.0
coverage!=4.4,>=4.0 # Apache-2.0
+flake8-import-order==0.12 # LGPLv3
python-subunit>=1.0.0 # Apache-2.0/BSD
sphinx!=1.6.6,!=1.6.7,>=1.6.2 # BSD
oslotest>=3.2.0 # Apache-2.0
diff --git a/tox.ini b/tox.ini
index 06eda94..d966308 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,6 +1,6 @@
[tox]
minversion = 2.0
-envlist = py34,py27,pypy,pep8
+envlist = pep8
skipsdist = True
[testenv]
@@ -15,7 +15,7 @@
[testenv:pep8]
commands =
sh ./tools/misc-sanity-checks.sh
- flake8 {posargs}
+ flake8
whitelist_externals =
sh