Merge "Switch neutron-tempest-plugin-api job to zuul v3 format"
diff --git a/.gitignore b/.gitignore
index 963e589..a678dd2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -27,8 +27,8 @@
!.coveragerc
.tox
nosetests.xml
-.testrepository
.venv
+.stestr/
# Translations
*.mo
diff --git a/.stestr.conf b/.stestr.conf
new file mode 100644
index 0000000..7a46f32
--- /dev/null
+++ b/.stestr.conf
@@ -0,0 +1,3 @@
+[DEFAULT]
+test_path=${OS_TEST_PATH:-./neutron_tempest_plugin}
+top_dir=./
diff --git a/.testr.conf b/.testr.conf
deleted file mode 100644
index 6d83b3c..0000000
--- a/.testr.conf
+++ /dev/null
@@ -1,7 +0,0 @@
-[DEFAULT]
-test_command=OS_STDOUT_CAPTURE=${OS_STDOUT_CAPTURE:-1} \
- OS_STDERR_CAPTURE=${OS_STDERR_CAPTURE:-1} \
- OS_TEST_TIMEOUT=${OS_TEST_TIMEOUT:-60} \
- ${PYTHON:-python} -m subunit.run discover -t ./ . $LISTOPT $IDOPTION
-test_id_option=--load-list $IDFILE
-test_list_option=--list
diff --git a/.zuul.yaml b/.zuul.yaml
index 27780d0..247b100 100644
--- a/.zuul.yaml
+++ b/.zuul.yaml
@@ -212,7 +212,6 @@
- ^(test-|)requirements.txt$
- ^releasenotes/.*$
- ^setup.cfg$
- voting: false
- job:
name: neutron-tempest-plugin-designate-scenario-queens
diff --git a/neutron_tempest_plugin/api/admin/test_routers_dvr.py b/neutron_tempest_plugin/api/admin/test_routers_dvr.py
index 2313d1b..644bc38 100644
--- a/neutron_tempest_plugin/api/admin/test_routers_dvr.py
+++ b/neutron_tempest_plugin/api/admin/test_routers_dvr.py
@@ -19,7 +19,7 @@
from neutron_tempest_plugin.api import base_routers as base
-class RoutersTestDVR(base.BaseRouterTest):
+class RoutersTestDVRBase(base.BaseRouterTest):
required_extensions = ['router', 'dvr']
@@ -31,7 +31,7 @@
# admin credentials to create router with distributed=True attribute
# and checking for BadRequest exception and that the resulting router
# has a distributed attribute.
- super(RoutersTestDVR, cls).resource_setup()
+ super(RoutersTestDVRBase, cls).resource_setup()
name = data_utils.rand_name('pretest-check')
router = cls.admin_client.create_router(name)
if 'distributed' not in router['router']:
@@ -39,6 +39,9 @@
raise cls.skipException(msg)
cls.admin_client.delete_router(router['router']['id'])
+
+class RoutersTestDVR(RoutersTestDVRBase):
+
@decorators.idempotent_id('08a2a0a8-f1e4-4b34-8e30-e522e836c44e')
def test_distributed_router_creation(self):
"""
@@ -74,6 +77,11 @@
router['router']['id'])
self.assertFalse(router['router']['distributed'])
+
+class RouterTestCentralizedToDVR(RoutersTestDVRBase):
+
+ required_extensions = ['l3-ha']
+
@decorators.idempotent_id('acd43596-c1fb-439d-ada8-31ad48ae3c2e')
def test_centralized_router_update_to_dvr(self):
"""
diff --git a/neutron_tempest_plugin/api/test_routers.py b/neutron_tempest_plugin/api/test_routers.py
index d5d2e04..4637dd6 100644
--- a/neutron_tempest_plugin/api/test_routers.py
+++ b/neutron_tempest_plugin/api/test_routers.py
@@ -14,6 +14,7 @@
# under the License.
import netaddr
+
from tempest.common import utils as tutils
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
@@ -244,6 +245,11 @@
self.admin_client)
self.assertTrue(create_body['router']['distributed'])
+
+class DvrRoutersTestToCentralized(base_routers.BaseRouterTest):
+
+ required_extensions = ['dvr', 'l3-ha']
+
@decorators.idempotent_id('644d7a4a-01a1-4b68-bb8d-0c0042cb1729')
def test_convert_centralized_router(self):
router_args = {'tenant_id': self.client.tenant_id,
diff --git a/neutron_tempest_plugin/config.py b/neutron_tempest_plugin/config.py
index 65282cf..fc07e81 100644
--- a/neutron_tempest_plugin/config.py
+++ b/neutron_tempest_plugin/config.py
@@ -11,7 +11,6 @@
# under the License.
from oslo_config import cfg
-
from tempest import config
@@ -47,6 +46,17 @@
help='The agent mode for L3 agents in the deployment. '
'Configure this only when the single value is used by '
'all agents in the deployment.'),
+ cfg.StrOpt('test_mtu_networks',
+ default='[{"provider:network_type":"vxlan",'
+ '"mtu":1200, "cidr":"10.100.0.0/16"}'
+ ','
+ '{"provider:network_type":"vxlan",'
+ '"mtu":1300, "cidr":"10.200.0.0/16"}]',
+ help='Configuration for test networks. The format is JSON. '
+ '"provider:network_type":<TYPE> - string '
+ '"mtu":<MTU> - integer '
+ '"cidr"<SUBNET/MASK> - string '
+ '"provider:segmentation_id":<VLAN_ID> - integer')
]
# TODO(amuller): Redo configuration options registration as part of the planned
diff --git a/neutron_tempest_plugin/scenario/base.py b/neutron_tempest_plugin/scenario/base.py
index 2bb6344..b76a81a 100644
--- a/neutron_tempest_plugin/scenario/base.py
+++ b/neutron_tempest_plugin/scenario/base.py
@@ -218,9 +218,7 @@
key_name=self.keypair['name'],
networks=[{'uuid': self.network['id']}],
security_groups=[{'name': secgroup['security_group']['name']}])
- waiters.wait_for_server_status(self.os_primary.servers_client,
- self.server['server']['id'],
- constants.SERVER_STATUS_ACTIVE)
+ 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]
@@ -302,9 +300,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):
@@ -343,3 +350,25 @@
'result': 'expected' if result else 'unexpected'
})
return result
+
+ def wait_for_server_status(self, server, status, client=None, **kwargs):
+ """Waits for a server to reach a given status.
+
+ :param server: mapping having schema {'id': <server_id>}
+ :param status: string status to wait for (es: 'ACTIVE')
+ :param clien: servers client (self.os_primary.servers_client as
+ default value)
+ """
+
+ client = client or self.os_primary.servers_client
+ waiters.wait_for_server_status(client, server['id'], status, **kwargs)
+
+ def wait_for_server_active(self, server, client=None):
+ """Waits for a server to reach active status.
+
+ :param server: mapping having schema {'id': <server_id>}
+ :param clien: servers client (self.os_primary.servers_client as
+ default value)
+ """
+ self.wait_for_server_status(
+ server, constants.SERVER_STATUS_ACTIVE, client)
diff --git a/neutron_tempest_plugin/scenario/test_mtu.py b/neutron_tempest_plugin/scenario/test_mtu.py
index b38d770..0e3afe9 100644
--- a/neutron_tempest_plugin/scenario/test_mtu.py
+++ b/neutron_tempest_plugin/scenario/test_mtu.py
@@ -14,6 +14,7 @@
# under the License.
from neutron_lib.api.definitions import provider_net
+from oslo_serialization import jsonutils
from tempest.common import utils
from tempest.common import waiters
from tempest.lib.common.utils import data_utils
@@ -59,6 +60,9 @@
fip = self.create_and_associate_floatingip(port['id'])
return server, fip
+ def _get_network_params(self):
+ return jsonutils.loads(CONF.neutron_plugin_options.test_mtu_networks)
+
class NetworkMtuTest(NetworkMtuBaseTest):
credentials = ['primary', 'admin']
@@ -97,13 +101,13 @@
self.assertNotEqual(self.networks[0]['mtu'], self.networks[1]['mtu'])
self.networks.sort(key=lambda net: net['mtu'])
server1, fip1 = self.create_pingable_vm(self.networks[0],
- self.keypair, self.secgroup)
+ self.keypair, self.secgroup)
server_ssh_client1 = ssh.Client(
self.floating_ips[0]['floating_ip_address'],
CONF.validation.image_ssh_user,
pkey=self.keypair['private_key'])
server2, fip2 = self.create_pingable_vm(self.networks[1],
- self.keypair, self.secgroup)
+ self.keypair, self.secgroup)
server_ssh_client2 = ssh.Client(
self.floating_ips[0]['floating_ip_address'],
CONF.validation.image_ssh_user,
@@ -150,7 +154,7 @@
def skip_checks(cls):
super(NetworkWritableMtuTest, cls).skip_checks()
if ("vxlan" not in
- config.CONF.neutron_plugin_options.available_type_drivers):
+ config.CONF.neutron_plugin_options.available_type_drivers):
raise cls.skipException("VXLAN type_driver is not enabled")
@classmethod
@@ -160,24 +164,24 @@
def _create_setup(self):
self.admin_client = self.os_admin.network_client
- net_kwargs = {'tenant_id': self.client.tenant_id,
- 'provider:network_type': 'vxlan'}
- for _ in range(2):
- net_kwargs['name'] = data_utils.rand_name('net')
- network = self.admin_client.create_network(**net_kwargs)[
+ for test_net in self._get_network_params():
+ test_net['tenant_id'] = self.client.tenant_id
+ test_net['name'] = data_utils.rand_name('net')
+ cidr = None if 'cidr' not in test_net else test_net.pop('cidr')
+ network = self.admin_client.create_network(**test_net)[
'network']
self.networks.append(network)
self.addCleanup(self.admin_client.delete_network, network['id'])
- subnet = self.create_subnet(network)
+ subnet = self.create_subnet(network, cidr=cidr)
self.create_router_interface(self.router['id'], subnet['id'])
self.addCleanup(self.client.remove_router_interface_with_subnet_id,
self.router['id'], subnet['id'])
- # Update network mtu.
+ # update network mtu
net_mtu = self.admin_client.show_network(
self.networks[0]['id'])['network']['mtu']
self.admin_client.update_network(self.networks[0]['id'],
- mtu=(net_mtu - 1))
+ mtu=(net_mtu - 1))
self.networks[0]['mtu'] = (
self.admin_client.show_network(
self.networks[0]['id'])['network']['mtu'])
@@ -186,13 +190,13 @@
self.assertNotEqual(self.networks[0]['mtu'], self.networks[1]['mtu'])
self.networks.sort(key=lambda net: net['mtu'])
server1, fip1 = self.create_pingable_vm(self.networks[0],
- self.keypair, self.secgroup)
+ self.keypair, self.secgroup)
server_ssh_client1 = ssh.Client(
self.floating_ips[0]['floating_ip_address'],
CONF.validation.image_ssh_user,
pkey=self.keypair['private_key'])
server2, fip2 = self.create_pingable_vm(self.networks[1],
- self.keypair, self.secgroup)
+ self.keypair, self.secgroup)
server_ssh_client2 = ssh.Client(
self.floating_ips[0]['floating_ip_address'],
CONF.validation.image_ssh_user,
diff --git a/test-requirements.txt b/test-requirements.txt
index 84f3c18..c0546cf 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -9,7 +9,7 @@
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
-testrepository>=0.0.18 # Apache-2.0/BSD
+stestr>=1.0.0 # Apache-2.0
testtools>=2.2.0 # MIT
openstackdocstheme>=1.18.1 # Apache-2.0
# releasenotes
diff --git a/tox.ini b/tox.ini
index d966308..bba0a64 100644
--- a/tox.ini
+++ b/tox.ini
@@ -9,8 +9,11 @@
setenv =
VIRTUAL_ENV={envdir}
PYTHONWARNINGS=default::DeprecationWarning
+ OS_LOG_CAPTURE={env:OS_LOG_CAPTURE:true}
+ OS_STDOUT_CAPTURE={env:OS_STDOUT_CAPTURE:true}
+ OS_STDERR_CAPTURE={env:OS_STDERR_CAPTURE:true}
deps = -r{toxinidir}/test-requirements.txt
-commands = python setup.py test --slowest --testr-args='{posargs}'
+commands = stestr run --slowest {posargs}
[testenv:pep8]
commands =
@@ -23,7 +26,14 @@
commands = {posargs}
[testenv:cover]
-commands = python setup.py test --coverage --testr-args='{posargs}'
+setenv =
+ {[testenv]setenv}
+ PYTHON=coverage run --source neutron_tempest_plugin --parallel-mode
+commands =
+ stestr run --no-subunit-trace {posargs}
+ coverage combine
+ coverage html -d cover
+ coverage xml -o cover/coverage.xml
[testenv:docs]
commands = python setup.py build_sphinx