Merge "Add retry decorator to SSH "execute" method"
diff --git a/.zuul.yaml b/.zuul.yaml
index 17c9e95..011bfe5 100644
--- a/.zuul.yaml
+++ b/.zuul.yaml
@@ -404,6 +404,129 @@
cinder: true
- job:
+ name: neutron-tempest-plugin-scenario-openvswitch
+ parent: neutron-tempest-plugin-scenario
+ timeout: 10000
+ vars:
+ network_api_extensions: *api_extensions_master
+ devstack_localrc:
+ Q_AGENT: openvswitch
+ NETWORK_API_EXTENSIONS: "{{ network_api_extensions | join(',') }}"
+ devstack_local_conf:
+ post-config:
+ $NEUTRON_CONF:
+ DEFAULT:
+ enable_dvr: false
+ # 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:
+ agent:
+ tunnel_types: vxlan,gre
+ ovs:
+ tunnel_bridge: br-tun
+ bridge_mappings: public:br-ex
+ test-config:
+ $TEMPEST_CONFIG:
+ neutron_plugin_options:
+ available_type_drivers: flat,vlan,local,vxlan
+
+- job:
+ name: neutron-tempest-plugin-scenario-openvswitch-queens
+ parent: neutron-tempest-plugin-scenario-openvswitch
+ nodeset: openstack-single-node-xenial
+ override-checkout: stable/queens
+ vars:
+ branch_override: stable/queens
+ network_api_extensions: *api_extensions_queens
+ # 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)"
+ devstack_localrc:
+ USE_PYTHON3: false
+ NETWORK_API_EXTENSIONS: "{{ network_api_extensions | join(',') }}"
+ TEMPEST_PLUGINS: /opt/stack/neutron-tempest-plugin
+
+- job:
+ name: neutron-tempest-plugin-scenario-openvswitch-rocky
+ parent: neutron-tempest-plugin-scenario-openvswitch
+ nodeset: openstack-single-node-xenial
+ override-checkout: stable/rocky
+ vars:
+ branch_override: stable/rocky
+ network_api_extensions: *api_extensions_rocky
+ devstack_localrc:
+ USE_PYTHON3: false
+ NETWORK_API_EXTENSIONS: "{{ network_api_extensions | join(',') }}"
+ TEMPEST_PLUGINS: /opt/stack/neutron-tempest-plugin
+
+- job:
+ name: neutron-tempest-plugin-scenario-openvswitch-stein
+ parent: neutron-tempest-plugin-scenario-openvswitch
+ override-checkout: stable/stein
+ vars:
+ branch_override: stable/stein
+ network_api_extensions: *api_extensions_stein
+ devstack_localrc:
+ NETWORK_API_EXTENSIONS: "{{ network_api_extensions | join(',') }}"
+
+- job:
+ name: neutron-tempest-plugin-scenario-openvswitch-iptables_hybrid
+ parent: neutron-tempest-plugin-scenario
+ timeout: 10000
+ vars:
+ network_api_extensions: *api_extensions_master
+ # 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)"
+ devstack_localrc:
+ Q_AGENT: openvswitch
+ NETWORK_API_EXTENSIONS: "{{ network_api_extensions | join(',') }}"
+ devstack_local_conf:
+ post-config:
+ $NEUTRON_CONF:
+ DEFAULT:
+ enable_dvr: false
+ # 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:
+ agent:
+ tunnel_types: vxlan,gre
+ ovs:
+ tunnel_bridge: br-tun
+ bridge_mappings: public:br-ex
+ securitygroup:
+ firewall_driver: iptables_hybrid
+ test-config:
+ $TEMPEST_CONFIG:
+ neutron_plugin_options:
+ available_type_drivers: flat,vlan,local,vxlan
+
+- job:
+ name: neutron-tempest-plugin-scenario-openvswitch-iptables_hybrid-rocky
+ parent: neutron-tempest-plugin-scenario-openvswitch-iptables_hybrid
+ nodeset: openstack-single-node-xenial
+ override-checkout: stable/rocky
+ vars:
+ branch_override: stable/rocky
+ network_api_extensions: *api_extensions_rocky
+ devstack_localrc:
+ USE_PYTHON3: false
+ NETWORK_API_EXTENSIONS: "{{ network_api_extensions | join(',') }}"
+ TEMPEST_PLUGINS: /opt/stack/neutron-tempest-plugin
+
+- job:
+ name: neutron-tempest-plugin-scenario-openvswitch-iptables_hybrid-stein
+ parent: neutron-tempest-plugin-scenario-openvswitch-iptables_hybrid
+ override-checkout: stable/stein
+ vars:
+ branch_override: stable/stein
+ network_api_extensions: *api_extensions_stein
+ devstack_localrc:
+ NETWORK_API_EXTENSIONS: "{{ network_api_extensions | join(',') }}"
+
+- job:
name: neutron-tempest-plugin-scenario-linuxbridge
parent: neutron-tempest-plugin-scenario
timeout: 10000
@@ -779,10 +902,14 @@
- neutron-tempest-plugin-designate-scenario
- neutron-tempest-plugin-dvr-multinode-scenario
- neutron-tempest-plugin-scenario-linuxbridge
+ - neutron-tempest-plugin-scenario-openvswitch
+ - neutron-tempest-plugin-scenario-openvswitch-iptables_hybrid
gate:
jobs:
- neutron-tempest-plugin-api
- neutron-tempest-plugin-scenario-linuxbridge
+ - neutron-tempest-plugin-scenario-openvswitch
+ - neutron-tempest-plugin-scenario-openvswitch-iptables_hybrid
- project-template:
name: neutron-tempest-plugin-jobs-queens
@@ -792,6 +919,7 @@
- neutron-tempest-plugin-designate-scenario-queens
- neutron-tempest-plugin-dvr-multinode-scenario-queens
- neutron-tempest-plugin-scenario-linuxbridge-queens
+ - neutron-tempest-plugin-scenario-openvswitch-queens
gate:
jobs:
- neutron-tempest-plugin-api-queens
@@ -804,6 +932,8 @@
- neutron-tempest-plugin-designate-scenario-rocky
- neutron-tempest-plugin-dvr-multinode-scenario-rocky
- neutron-tempest-plugin-scenario-linuxbridge-rocky
+ - neutron-tempest-plugin-scenario-openvswitch-rocky
+ - neutron-tempest-plugin-scenario-openvswitch-iptables_hybrid-rocky
gate:
jobs:
- neutron-tempest-plugin-api-rocky
@@ -816,6 +946,8 @@
- neutron-tempest-plugin-designate-scenario-stein
- neutron-tempest-plugin-dvr-multinode-scenario-stein
- neutron-tempest-plugin-scenario-linuxbridge-stein
+ - neutron-tempest-plugin-scenario-openvswitch-stein
+ - neutron-tempest-plugin-scenario-openvswitch-iptables_hybrid-stein
gate:
jobs:
- neutron-tempest-plugin-api-stein
diff --git a/neutron_tempest_plugin/api/admin/test_routers_dvr.py b/neutron_tempest_plugin/api/admin/test_routers_dvr.py
index 8d80ba6..ab25a3f 100644
--- a/neutron_tempest_plugin/api/admin/test_routers_dvr.py
+++ b/neutron_tempest_plugin/api/admin/test_routers_dvr.py
@@ -55,10 +55,8 @@
set to True
"""
name = data_utils.rand_name('router')
- router = self.admin_client.create_router(name, distributed=True)
- self.addCleanup(self.admin_client.delete_router,
- router['router']['id'])
- self.assertTrue(router['router']['distributed'])
+ router = self._create_admin_router(name, distributed=True)
+ self.assertTrue(router['distributed'])
@decorators.idempotent_id('8a0a72b4-7290-4677-afeb-b4ffe37bc352')
def test_centralized_router_creation(self):
@@ -74,10 +72,8 @@
as opposed to a "Distributed Virtual Router"
"""
name = data_utils.rand_name('router')
- router = self.admin_client.create_router(name, distributed=False)
- self.addCleanup(self.admin_client.delete_router,
- router['router']['id'])
- self.assertFalse(router['router']['distributed'])
+ router = self._create_admin_router(name, distributed=False)
+ self.assertFalse(router['distributed'])
class RouterTestCentralizedToDVR(RoutersTestDVRBase):
@@ -100,13 +96,10 @@
"""
name = data_utils.rand_name('router')
# router needs to be in admin state down in order to be upgraded to DVR
- router = self.admin_client.create_router(name, distributed=False,
- ha=False,
- admin_state_up=False)
- self.addCleanup(self.admin_client.delete_router,
- router['router']['id'])
- self.assertFalse(router['router']['distributed'])
- self.assertFalse(router['router']['ha'])
- router = self.admin_client.update_router(router['router']['id'],
+ router = self._create_admin_router(name, distributed=False,
+ ha=False, admin_state_up=False)
+ self.assertFalse(router['distributed'])
+ self.assertFalse(router['ha'])
+ router = self.admin_client.update_router(router['id'],
distributed=True)
self.assertTrue(router['router']['distributed'])
diff --git a/neutron_tempest_plugin/api/test_routers.py b/neutron_tempest_plugin/api/test_routers.py
index ab6b0f6..3b9867b 100644
--- a/neutron_tempest_plugin/api/test_routers.py
+++ b/neutron_tempest_plugin/api/test_routers.py
@@ -73,12 +73,11 @@
external_gateway_info = {
'network_id': CONF.network.public_network_id,
'enable_snat': enable_snat}
- create_body = self.admin_client.create_router(
- name, external_gateway_info=external_gateway_info)
- self.addCleanup(self.admin_client.delete_router,
- create_body['router']['id'])
+ router = self._create_admin_router(
+ name, external_network_id=CONF.network.public_network_id,
+ enable_snat=enable_snat)
# Verify snat attributes after router creation
- self._verify_router_gateway(create_body['router']['id'],
+ self._verify_router_gateway(router['id'],
exp_ext_gw_info=external_gateway_info)
def _verify_router_gateway(self, router_id, exp_ext_gw_info=None):
@@ -238,12 +237,8 @@
@decorators.idempotent_id('141297aa-3424-455d-aa8d-f2d95731e00a')
def test_create_distributed_router(self):
name = data_utils.rand_name('router')
- create_body = self.admin_client.create_router(
- name, distributed=True)
- self.addCleanup(self._delete_router,
- create_body['router']['id'],
- self.admin_client)
- self.assertTrue(create_body['router']['distributed'])
+ router = self._create_admin_router(name, distributed=True)
+ self.assertTrue(router['distributed'])
class DvrRoutersTestToCentralized(base_routers.BaseRouterTest):
@@ -255,11 +250,9 @@
# Convert a centralized router to distributed firstly
router_args = {'tenant_id': self.client.tenant_id,
'distributed': False, 'ha': False}
- router = self.admin_client.create_router(
+ router = self._create_admin_router(
data_utils.rand_name('router'), admin_state_up=False,
- **router_args)['router']
- self.addCleanup(self.admin_client.delete_router,
- router['id'])
+ **router_args)
self.assertFalse(router['distributed'])
self.assertFalse(router['ha'])
update_body = self.admin_client.update_router(router['id'],
@@ -289,11 +282,9 @@
def test_convert_centralized_router_to_distributed_extended(self):
router_args = {'tenant_id': self.client.tenant_id,
'distributed': False, 'ha': False}
- router = self.admin_client.create_router(
+ router = self._create_admin_router(
data_utils.rand_name('router'), admin_state_up=True,
- **router_args)['router']
- self.addCleanup(self.admin_client.delete_router,
- router['id'])
+ **router_args)
self.assertTrue(router['admin_state_up'])
self.assertFalse(router['distributed'])
# take router down to allow setting the router to distributed
@@ -314,11 +305,9 @@
def test_convert_distributed_router_to_centralized_extended(self):
router_args = {'tenant_id': self.client.tenant_id,
'distributed': True, 'ha': False}
- router = self.admin_client.create_router(
+ router = self._create_admin_router(
data_utils.rand_name('router'), admin_state_up=True,
- **router_args)['router']
- self.addCleanup(self.admin_client.delete_router,
- router['id'])
+ **router_args)
self.assertTrue(router['admin_state_up'])
self.assertTrue(router['distributed'])
# take router down to allow setting the router to centralized
diff --git a/neutron_tempest_plugin/api/test_routers_negative.py b/neutron_tempest_plugin/api/test_routers_negative.py
index f085fc9..5f24732 100644
--- a/neutron_tempest_plugin/api/test_routers_negative.py
+++ b/neutron_tempest_plugin/api/test_routers_negative.py
@@ -90,9 +90,9 @@
# create a centralized router
router_args = {'tenant_id': self.client.tenant_id,
'distributed': False}
- router = self.admin_client.create_router(
+ router = self._create_admin_router(
data_utils.rand_name('router'), admin_state_up=True,
- **router_args)['router']
+ **router_args)
self.assertTrue(router['admin_state_up'])
self.assertFalse(router['distributed'])
# attempt to set the router to distributed, catch BadRequest exception
@@ -107,9 +107,9 @@
# create a centralized router
router_args = {'tenant_id': self.client.tenant_id,
'distributed': False}
- router = self.admin_client.create_router(
+ router = self._create_admin_router(
data_utils.rand_name('router'), admin_state_up=True,
- **router_args)['router']
+ **router_args)
self.assertTrue(router['admin_state_up'])
self.assertFalse(router['distributed'])
# take the router down to modify distributed->True
diff --git a/neutron_tempest_plugin/fwaas/common/fwaas_v2_client.py b/neutron_tempest_plugin/fwaas/common/fwaas_v2_client.py
index 767afc0..44b0952 100644
--- a/neutron_tempest_plugin/fwaas/common/fwaas_v2_client.py
+++ b/neutron_tempest_plugin/fwaas/common/fwaas_v2_client.py
@@ -136,7 +136,7 @@
nl_constants.PENDING_UPDATE])
def _wait_firewall_group_while(self, firewall_group_id, statuses,
- not_found_ok=False):
+ not_found_ok=False):
start = int(time.time())
if not_found_ok:
expected_exceptions = (lib_exc.NotFound)
diff --git a/neutron_tempest_plugin/scenario/base.py b/neutron_tempest_plugin/scenario/base.py
index d87a365..4b2ddcd 100644
--- a/neutron_tempest_plugin/scenario/base.py
+++ b/neutron_tempest_plugin/scenario/base.py
@@ -170,8 +170,8 @@
client = client or cls.os_primary.interfaces_client
client.delete_interface(server_id, port_id=port_id)
- def setup_network_and_server(
- self, router=None, server_name=None, network=None, **kwargs):
+ def setup_network_and_server(self, router=None, server_name=None,
+ network=None, **kwargs):
"""Create network resources and a server.
Creating a network, subnet, router, keypair, security group
diff --git a/neutron_tempest_plugin/scenario/test_multicast.py b/neutron_tempest_plugin/scenario/test_multicast.py
index cfaa73f..9b79582 100644
--- a/neutron_tempest_plugin/scenario/test_multicast.py
+++ b/neutron_tempest_plugin/scenario/test_multicast.py
@@ -22,11 +22,13 @@
from neutron_tempest_plugin.common import ssh
from neutron_tempest_plugin.common import utils
from neutron_tempest_plugin import config
+from neutron_tempest_plugin import exceptions
from neutron_tempest_plugin.scenario import base
CONF = config.CONF
LOG = log.getLogger(__name__)
+PYTHON3_BIN = "python3"
def get_receiver_script(group, port, hello_message, ack_message, result_file):
@@ -192,20 +194,27 @@
port = self.client.list_ports(
network_id=self.network['id'], device_id=server['id'])['ports'][0]
server['fip'] = self.create_floatingip(port=port)
+ server['ssh_client'] = ssh.Client(server['fip']['floating_ip_address'],
+ self.username,
+ pkey=self.keypair['private_key'])
+ self._check_python_installed_on_server(server['ssh_client'],
+ server['id'])
return server
+ def _check_python_installed_on_server(self, ssh_client, server_id):
+ try:
+ ssh_client.execute_script('which %s' % PYTHON3_BIN)
+ except exceptions.SSHScriptFailed:
+ raise self.skipException(
+ "%s is not available on server %s" % (PYTHON3_BIN, server_id))
+
def _prepare_sender(self, server, mcast_address):
check_script = get_sender_script(
group=mcast_address, port=self.multicast_port,
message=self.multicast_message,
result_file=self.sender_output_file)
- ssh_client = ssh.Client(server['fip']['floating_ip_address'],
- self.username,
- pkey=self.keypair['private_key'])
-
- ssh_client.execute_script(
+ server['ssh_client'].execute_script(
'echo "%s" > ~/multicast_traffic_sender.py' % check_script)
- return ssh_client
def _prepare_receiver(self, server, mcast_address):
check_script = get_receiver_script(
@@ -216,9 +225,9 @@
server['fip']['floating_ip_address'],
self.username,
pkey=self.keypair['private_key'])
- ssh_client.execute_script(
+ self._check_python_installed_on_server(ssh_client, server['id'])
+ server['ssh_client'].execute_script(
'echo "%s" > ~/multicast_traffic_receiver.py' % check_script)
- return ssh_client
@decorators.idempotent_id('113486fc-24c9-4be4-8361-03b1c9892867')
def test_multicast_between_vms_on_same_network(self):
@@ -246,41 +255,39 @@
path=file_path))
return msg in result
- sender_ssh_client = self._prepare_sender(sender, mcast_address)
- receiver_ssh_clients = []
+ self._prepare_sender(sender, mcast_address)
receiver_ids = []
for receiver in receivers:
- receiver_ssh_client = self._prepare_receiver(
- receiver, mcast_address)
- receiver_ssh_client.execute_script(
- "python3 ~/multicast_traffic_receiver.py &", shell="bash")
+ self._prepare_receiver(receiver, mcast_address)
+ receiver['ssh_client'].execute_script(
+ "%s ~/multicast_traffic_receiver.py &" % PYTHON3_BIN,
+ shell="bash")
utils.wait_until_true(
lambda: _message_received(
- receiver_ssh_client, self.hello_message,
+ receiver['ssh_client'], self.hello_message,
self.receiver_output_file),
exception=RuntimeError(
"Receiver script didn't start properly on server "
"{!r}.".format(receiver['id'])))
- receiver_ssh_clients.append(receiver_ssh_client)
receiver_ids.append(receiver['id'])
# Now lets run scripts on sender
- sender_ssh_client.execute_script(
- "python3 ~/multicast_traffic_sender.py")
+ sender['ssh_client'].execute_script(
+ "%s ~/multicast_traffic_sender.py" % PYTHON3_BIN)
# And check if message was received
- for receiver_ssh_client in receiver_ssh_clients:
+ for receiver in receivers:
utils.wait_until_true(
lambda: _message_received(
- receiver_ssh_client, self.multicast_message,
+ receiver['ssh_client'], self.multicast_message,
self.receiver_output_file),
exception=RuntimeError(
"Receiver {!r} didn't get multicast message".format(
receiver['id'])))
# TODO(slaweq): add validation of answears on sended server
- replies_result = sender_ssh_client.execute_script(
+ replies_result = sender['ssh_client'].execute_script(
"cat {path} || echo '{path} not exists yet'".format(
path=self.sender_output_file))
for receiver_id in receiver_ids:
diff --git a/tox.ini b/tox.ini
index daf728a..bba37bb 100644
--- a/tox.ini
+++ b/tox.ini
@@ -55,12 +55,11 @@
commands = oslo_debug_helper -t neutron_tempest_plugin/ {posargs}
[flake8]
-# E125 continuation line does not distinguish itself from next logical line
# E126 continuation line over-indented for hanging indent
# E128 continuation line under-indented for visual indent
# E129 visually indented line with same indent as next logical line
# N530 direct neutron imports not allowed
-ignore = E125,E126,E128,E129,N530
+ignore = E126,E128,E129,N530
# H106: Don't put vim configuration in source files
# H203: Use assertIs(Not)None to check for None
# H204: Use assert(Not)Equal to check for equality