summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Watkins <oddbloke@ubuntu.com>2020-12-09 18:11:18 -0500
committerGitHub <noreply@github.com>2020-12-09 18:11:18 -0500
commit05216aa37e1fad32433dbea102dc3ceae7d8565d (patch)
treecc705070832bbba8f0776bfa43041bb631d8a4da
parent17ca02e10623b12065532b26de9cefcccee0062c (diff)
downloadcloud-init-git-05216aa37e1fad32433dbea102dc3ceae7d8565d.tar.gz
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.txt2
-rw-r--r--tests/integration_tests/bugs/test_lp1898997.py71
-rw-r--r--tests/integration_tests/conftest.py23
-rw-r--r--tox.ini3
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:
diff --git a/tox.ini b/tox.ini
index 1841247b..2e242551 100644
--- a/tox.ini
+++ b/tox.ini
@@ -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