diff options
author | Daniel Watkins <oddbloke@ubuntu.com> | 2020-12-09 18:11:18 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-09 18:11:18 -0500 |
commit | 05216aa37e1fad32433dbea102dc3ceae7d8565d (patch) | |
tree | cc705070832bbba8f0776bfa43041bb631d8a4da | |
parent | 17ca02e10623b12065532b26de9cefcccee0062c (diff) | |
download | vyos-cloud-init-05216aa37e1fad32433dbea102dc3ceae7d8565d.tar.gz vyos-cloud-init-05216aa37e1fad32433dbea102dc3ceae7d8565d.zip |
integration_tests: add test for LP: #1898997 (#713)
integration_tests: add test for LP: #1898997
This introduces the `lxd_config_dict` mark, used to specify a
free-form configuration dict to LXD for tests which only run there; and
the `not_xenial` and `not_bionic` marks, used to skip tests on
xenial/bionic via a basic release skipping mechanism.
This also bumps the pycloudlib commit we depend upon, as
the latest commit includes the changes required for LXD network config
to work.
(The `lxd_config_dict` change further complicated `_client`, so a minor
refactoring is applied.)
-rw-r--r-- | integration-requirements.txt | 2 | ||||
-rw-r--r-- | tests/integration_tests/bugs/test_lp1898997.py | 71 | ||||
-rw-r--r-- | tests/integration_tests/conftest.py | 23 | ||||
-rw-r--r-- | tox.ini | 3 |
4 files changed, 93 insertions, 6 deletions
diff --git a/integration-requirements.txt b/integration-requirements.txt index 3648a0f1..b7e22ce7 100644 --- a/integration-requirements.txt +++ b/integration-requirements.txt @@ -1,5 +1,5 @@ # PyPI requirements for cloud-init integration testing # https://cloudinit.readthedocs.io/en/latest/topics/integration_tests.html # -pycloudlib @ git+https://github.com/canonical/pycloudlib.git@4b8d2cd5ac6316810ce16d081842da575625ca4f +pycloudlib @ git+https://github.com/canonical/pycloudlib.git@324763289c9a38fc9ac7ec524acb9eb11c7d6c13 pytest 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: @@ -173,8 +173,11 @@ markers = gce: test will only run on GCE platform azure: test will only run on Azure platform oci: test will only run on OCI platform + lxd_config_dict: set the config_dict passed on LXD instance creation lxd_container: test will only run in LXD container lxd_vm: test will only run in LXD VM + not_xenial: test cannot run on the xenial release + not_bionic: test cannot run on the bionic release no_container: test cannot run in a container user_data: the user data to be passed to the test instance instance_name: the name to be used for the test instance |