From 010c6de34e5c9f2c78c85754a612531033de4b11 Mon Sep 17 00:00:00 2001 From: Roman Safronov Date: Sun, 25 Apr 2021 11:38:53 +0300 Subject: [PATCH] Add initial post OVN migration test The test validates that openstack nodes do not have any ML2/OVS specific namespaces and interfaces. Change-Id: Ia1722f049deab37283bb1e937da4b02515e89f05 --- pytest.ini | 2 ++ tobiko/openstack/tests/__init__.py | 2 ++ tobiko/openstack/tests/_neutron.py | 35 +++++++++++++++++++++ tobiko/shell/ip.py | 11 +++++++ tobiko/tests/scenario/neutron/test_nodes.py | 30 ++++++++++++++++++ 5 files changed, 80 insertions(+) create mode 100644 tobiko/tests/scenario/neutron/test_nodes.py diff --git a/pytest.ini b/pytest.ini index 89ee67574..a4ce0c428 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,3 +1,5 @@ [pytest] junit_family=legacy render_collapsed = True +markers = + ovn_migration: Run test functions relevant for post OVN migration diff --git a/tobiko/openstack/tests/__init__.py b/tobiko/openstack/tests/__init__.py index 8583619b3..e0decbbe7 100644 --- a/tobiko/openstack/tests/__init__.py +++ b/tobiko/openstack/tests/__init__.py @@ -22,6 +22,8 @@ from tobiko.openstack.tests import _nova test_neutron_agents_are_alive = _neutron.test_neutron_agents_are_alive test_ovn_dbs_validations = _neutron.test_ovn_dbs_validations test_ovs_bridges_mac_table_size = _neutron.test_ovs_bridges_mac_table_size +test_ovs_namespaces_are_absent = _neutron.test_ovs_namespaces_are_absent +test_ovs_interfaces_are_absent = _neutron.test_ovs_interfaces_are_absent test_evacuable_server_creation = _nova.test_evacuable_server_creation test_server_creation = _nova.test_server_creation diff --git a/tobiko/openstack/tests/_neutron.py b/tobiko/openstack/tests/_neutron.py index 92b1d88fb..779df0656 100644 --- a/tobiko/openstack/tests/_neutron.py +++ b/tobiko/openstack/tests/_neutron.py @@ -8,6 +8,7 @@ from oslo_log import log import tobiko from tobiko.openstack import neutron from tobiko.openstack import topology +from tobiko.shell import ip from tobiko.shell import sh from tobiko.tripleo import containers from tobiko.tripleo import pacemaker @@ -259,3 +260,37 @@ def test_ovs_bridges_mac_table_size(): ssh_client=node.ssh_client, sudo=True).stdout.splitlines()[0] test_case.assertEqual(mac_table_size.replace('"', ''), expected_mac_table_size) + + +def test_ovs_namespaces_are_absent(): + ovs_specific_namespaces = ['qrouter', 'qdhcp', 'snat', 'fip'] + for node in topology.list_openstack_nodes(): + if node.name.startswith('undercloud'): + continue + namespaces = ip.list_network_namespaces( + ssh_client=node.ssh_client, sudo=True) + namespaces = [namespace + for namespace in namespaces + if any(namespace.startswith(prefix) + for prefix in ovs_specific_namespaces)] + test_case = tobiko.get_test_case() + test_case.assertEqual( + [], namespaces, + f"Unexpected namespace found on {node.name}: {*namespaces,}") + + +def test_ovs_interfaces_are_absent(): + ovs_specific_interfaces = ['qvo', 'qvb', 'qbr'] + for node in topology.list_openstack_nodes(): + if node.name.startswith('undercloud'): + continue + interfaces = ip.list_network_interfaces( + ssh_client=node.ssh_client, sudo=True) + interfaces = [interface + for interface in interfaces + if any(interface.startswith(prefix) + for prefix in ovs_specific_interfaces)] + test_case = tobiko.get_test_case() + test_case.assertEqual( + [], interfaces, + f"Unexpected interface found on {node.name}: {*interfaces,}") diff --git a/tobiko/shell/ip.py b/tobiko/shell/ip.py index 2dd7df515..9fd83fff0 100644 --- a/tobiko/shell/ip.py +++ b/tobiko/shell/ip.py @@ -91,6 +91,17 @@ def list_network_namespaces(**execute_params): return namespaces +def list_network_interfaces(**execute_params): + interfaces = tobiko.Selection() + output = execute_ip(['--brief', 'address', 'list'], **execute_params) + if output: + for line in output.splitlines(): + fields = line.strip().split() + interface = fields[0] + interfaces.append(interface) + return interface + + IP_COMMAND = sh.shell_command(['/sbin/ip']) diff --git a/tobiko/tests/scenario/neutron/test_nodes.py b/tobiko/tests/scenario/neutron/test_nodes.py new file mode 100644 index 000000000..d5db46d11 --- /dev/null +++ b/tobiko/tests/scenario/neutron/test_nodes.py @@ -0,0 +1,30 @@ +# Copyright (c) 2021 Red Hat +# 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 __future__ import absolute_import + +import pytest +import testtools + +from tobiko.openstack import neutron +from tobiko.openstack import tests + + +class NodeTest(testtools.TestCase): + + @neutron.skip_unless_is_ovn() + @pytest.mark.ovn_migration + def test_ovs_objects_are_absent_on_node(self): + tests.test_ovs_namespaces_are_absent() + tests.test_ovs_interfaces_are_absent()