diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/integration_tests/bugs/test_lp1898997.py | 71 | ||||
| -rw-r--r-- | tests/integration_tests/conftest.py | 23 | 
2 files changed, 89 insertions, 5 deletions
| diff --git a/tests/integration_tests/bugs/test_lp1898997.py b/tests/integration_tests/bugs/test_lp1898997.py new file mode 100644 index 00000000..54c88d82 --- /dev/null +++ b/tests/integration_tests/bugs/test_lp1898997.py @@ -0,0 +1,71 @@ +"""Integration test for LP: #1898997 + +cloud-init was incorrectly excluding Open vSwitch bridge members from its list +of interfaces.  This meant that instances which had only one interface which +was in an Open vSwitch bridge would not boot correctly: cloud-init would not +find the expected physical interfaces, so would not apply network config. + +This test checks that cloud-init believes it has successfully applied the +network configuration, and confirms that the bridge can be used to ping the +default gateway. +""" +import pytest + +MAC_ADDRESS = "de:ad:be:ef:12:34" + + +NETWORK_CONFIG = """\ +bridges: +        ovs-br: +            dhcp4: true +            interfaces: +            - enp5s0 +            macaddress: 52:54:00:d9:08:1c +            mtu: 1500 +            openvswitch: {{}} +ethernets: +    enp5s0: +      mtu: 1500 +      set-name: enp5s0 +      match: +          macaddress: {} +version: 2 +""".format(MAC_ADDRESS) + + +@pytest.mark.lxd_config_dict({ +    "user.network-config": NETWORK_CONFIG, +    "volatile.eth0.hwaddr": MAC_ADDRESS, +}) +@pytest.mark.lxd_vm +@pytest.mark.not_bionic +@pytest.mark.not_xenial +@pytest.mark.sru_2020_11 +@pytest.mark.ubuntu +class TestInterfaceListingWithOpenvSwitch: +    def test_ovs_member_interfaces_not_excluded(self, client): +        # We need to install openvswitch for our provided network configuration +        # to apply (on next boot), so DHCP on our default interface to fetch it +        client.execute("dhclient enp5s0") +        client.execute("apt update -qqy") +        client.execute("apt-get install -qqy openvswitch-switch") + +        # Now our networking config should successfully apply on a clean reboot +        client.execute("cloud-init clean --logs") +        client.restart() + +        cloudinit_output = client.read_from_file("/var/log/cloud-init.log") + +        # Confirm that the network configuration was applied successfully +        assert "WARN" not in cloudinit_output +        # Confirm that the applied network config created the OVS bridge +        assert "ovs-br" in client.execute("ip addr") + +        # Test that we can ping our gateway using our bridge +        gateway = client.execute( +            "ip -4 route show default | awk '{ print $3 }'" +        ) +        ping_result = client.execute( +            "ping -c 1 -W 1 -I ovs-br {}".format(gateway) +        ) +        assert ping_result.ok diff --git a/tests/integration_tests/conftest.py b/tests/integration_tests/conftest.py index 53ca5fb5..50b300c4 100644 --- a/tests/integration_tests/conftest.py +++ b/tests/integration_tests/conftest.py @@ -1,5 +1,6 @@  # This file is part of cloud-init. See LICENSE file for license information.  import datetime +import functools  import logging  import pytest  import os @@ -18,6 +19,7 @@ from tests.integration_tests.clouds import (      LxdContainerCloud,      LxdVmCloud,      OciCloud, +    _LxdIntegrationCloud,  )  from tests.integration_tests.instances import (      CloudInitSource, @@ -74,6 +76,10 @@ def pytest_runtest_setup(item):      if 'unstable' in test_marks and not integration_settings.RUN_UNSTABLE:          pytest.skip('Test marked unstable. Manually remove mark to run it') +    current_release = image.release +    if "not_{}".format(current_release) in test_marks: +        pytest.skip("Cannot run on release {}".format(current_release)) +  # disable_subp_usage is defined at a higher level, but we don't  # want it applied here @@ -184,14 +190,21 @@ def _client(request, fixture_utils, session_cloud: IntegrationCloud):      Launch the dynamic IntegrationClient instance using any provided      userdata, yield to the test, then cleanup      """ -    user_data = fixture_utils.closest_marker_first_arg_or( -        request, 'user_data', None) -    name = fixture_utils.closest_marker_first_arg_or( -        request, 'instance_name', None +    getter = functools.partial( +        fixture_utils.closest_marker_first_arg_or, request, default=None      ) +    user_data = getter('user_data') +    name = getter('instance_name') +    lxd_config_dict = getter('lxd_config_dict') +      launch_kwargs = {}      if name is not None: -        launch_kwargs = {"name": name} +        launch_kwargs["name"] = name +    if lxd_config_dict is not None: +        if not isinstance(session_cloud, _LxdIntegrationCloud): +            pytest.skip("lxd_config_dict requires LXD") +        launch_kwargs["config_dict"] = lxd_config_dict +      with session_cloud.launch(          user_data=user_data, launch_kwargs=launch_kwargs      ) as instance: | 
