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
This commit is contained in:
parent
6ad3311874
commit
010c6de34e
@ -1,3 +1,5 @@
|
|||||||
[pytest]
|
[pytest]
|
||||||
junit_family=legacy
|
junit_family=legacy
|
||||||
render_collapsed = True
|
render_collapsed = True
|
||||||
|
markers =
|
||||||
|
ovn_migration: Run test functions relevant for post OVN migration
|
||||||
|
@ -22,6 +22,8 @@ from tobiko.openstack.tests import _nova
|
|||||||
test_neutron_agents_are_alive = _neutron.test_neutron_agents_are_alive
|
test_neutron_agents_are_alive = _neutron.test_neutron_agents_are_alive
|
||||||
test_ovn_dbs_validations = _neutron.test_ovn_dbs_validations
|
test_ovn_dbs_validations = _neutron.test_ovn_dbs_validations
|
||||||
test_ovs_bridges_mac_table_size = _neutron.test_ovs_bridges_mac_table_size
|
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_evacuable_server_creation = _nova.test_evacuable_server_creation
|
||||||
test_server_creation = _nova.test_server_creation
|
test_server_creation = _nova.test_server_creation
|
||||||
|
@ -8,6 +8,7 @@ from oslo_log import log
|
|||||||
import tobiko
|
import tobiko
|
||||||
from tobiko.openstack import neutron
|
from tobiko.openstack import neutron
|
||||||
from tobiko.openstack import topology
|
from tobiko.openstack import topology
|
||||||
|
from tobiko.shell import ip
|
||||||
from tobiko.shell import sh
|
from tobiko.shell import sh
|
||||||
from tobiko.tripleo import containers
|
from tobiko.tripleo import containers
|
||||||
from tobiko.tripleo import pacemaker
|
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]
|
ssh_client=node.ssh_client, sudo=True).stdout.splitlines()[0]
|
||||||
test_case.assertEqual(mac_table_size.replace('"', ''),
|
test_case.assertEqual(mac_table_size.replace('"', ''),
|
||||||
expected_mac_table_size)
|
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,}")
|
||||||
|
@ -91,6 +91,17 @@ def list_network_namespaces(**execute_params):
|
|||||||
return namespaces
|
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'])
|
IP_COMMAND = sh.shell_command(['/sbin/ip'])
|
||||||
|
|
||||||
|
|
||||||
|
30
tobiko/tests/scenario/neutron/test_nodes.py
Normal file
30
tobiko/tests/scenario/neutron/test_nodes.py
Normal file
@ -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()
|
Loading…
Reference in New Issue
Block a user