diff options
Diffstat (limited to 'tests/integration_tests')
-rw-r--r-- | tests/integration_tests/bugs/test_lp1835584.py | 8 | ||||
-rw-r--r-- | tests/integration_tests/conftest.py | 82 | ||||
-rw-r--r-- | tests/integration_tests/modules/test_ansible.py | 47 | ||||
-rw-r--r-- | tests/integration_tests/modules/test_lxd.py | 31 | ||||
-rw-r--r-- | tests/integration_tests/modules/test_wireguard.py | 16 | ||||
-rw-r--r-- | tests/integration_tests/util.py | 1 |
6 files changed, 74 insertions, 111 deletions
diff --git a/tests/integration_tests/bugs/test_lp1835584.py b/tests/integration_tests/bugs/test_lp1835584.py index 4d669ee2..4e732446 100644 --- a/tests/integration_tests/bugs/test_lp1835584.py +++ b/tests/integration_tests/bugs/test_lp1835584.py @@ -84,7 +84,13 @@ def test_azure_kernel_upgrade_case_insensitive_uuid( pytest.skip( "Provide CLOUD_INIT_SOURCE to install expected working cloud-init" ) - with session_cloud.launch() as instance: + with session_cloud.launch( + launch_kwargs={ + "image_id": session_cloud.cloud_instance.daily_image( + cfg_image_spec.image_id, image_type=ImageType.PRO_FIPS + ) + } + ) as instance: # We can't use setup_image fixture here because we want to avoid # taking a snapshot or cleaning the booted machine after cloud-init # upgrade. diff --git a/tests/integration_tests/conftest.py b/tests/integration_tests/conftest.py index 580fd6ad..6157bad8 100644 --- a/tests/integration_tests/conftest.py +++ b/tests/integration_tests/conftest.py @@ -7,7 +7,7 @@ import sys from contextlib import contextmanager from pathlib import Path from tarfile import TarFile -from typing import Dict, Iterator, Type +from typing import Dict, Generator, Iterator, Type import pytest from pycloudlib.lxd.instance import LXDInstance @@ -92,60 +92,20 @@ def disable_subp_usage(request): pass -@contextmanager -def _session_cloud( - request: pytest.FixtureRequest, -) -> Iterator[IntegrationCloud]: +@pytest.fixture(scope="session") +def session_cloud() -> Generator[IntegrationCloud, None, None]: if integration_settings.PLATFORM not in platforms.keys(): raise ValueError( - "{} is an invalid PLATFORM specified in settings. " - "Must be one of {}".format( - integration_settings.PLATFORM, list(platforms.keys()) - ) + f"{integration_settings.PLATFORM} is an invalid PLATFORM " + f"specified in settings. Must be one of {list(platforms.keys())}" ) - integration_cloud_marker = request.node.get_closest_marker( - "integration_cloud_args" - ) - cloud_args = [] - cloud_kwargs = {} - if integration_cloud_marker: - cloud_args = integration_cloud_marker.args - cloud_kwargs = integration_cloud_marker.kwargs - cloud = platforms[integration_settings.PLATFORM]( - *cloud_args, **cloud_kwargs - ) + cloud = platforms[integration_settings.PLATFORM]() cloud.emit_settings_to_log() - yield cloud - cloud.destroy() -@pytest.fixture -def session_cloud( - request: pytest.FixtureRequest, -) -> Iterator[IntegrationCloud]: - with _session_cloud(request) as cloud: - yield cloud - - -@pytest.fixture(scope="module") -def module_session_cloud( - request: pytest.FixtureRequest, -) -> Iterator[IntegrationCloud]: - with _session_cloud(request) as cloud: - yield cloud - - -@pytest.fixture(scope="class") -def class_session_cloud( - request: pytest.FixtureRequest, -) -> Iterator[IntegrationCloud]: - with _session_cloud(request) as cloud: - yield cloud - - def get_validated_source( session_cloud: IntegrationCloud, source=integration_settings.CLOUD_INIT_SOURCE, @@ -166,12 +126,11 @@ def get_validated_source( return CloudInitSource.DEB_PACKAGE elif source == "UPGRADE": return CloudInitSource.UPGRADE - raise ValueError( - "Invalid value for CLOUD_INIT_SOURCE setting: {}".format(source) - ) + raise ValueError(f"Invalid value for CLOUD_INIT_SOURCE setting: {source}") -def _setup_image(session_cloud: IntegrationCloud, request): +@pytest.fixture(scope="session") +def setup_image(session_cloud: IntegrationCloud, request): """Setup the target environment with the correct version of cloud-init. So we can launch instances / run tests with the correct image @@ -193,21 +152,6 @@ def _setup_image(session_cloud: IntegrationCloud, request): request.addfinalizer(session_cloud.delete_snapshot) -@pytest.fixture -def setup_image(session_cloud: IntegrationCloud, request): - _setup_image(session_cloud, request) - - -@pytest.fixture(scope="module") -def module_setup_image(module_session_cloud: IntegrationCloud, request): - _setup_image(module_session_cloud, request) - - -@pytest.fixture(scope="class") -def class_setup_image(class_session_cloud: IntegrationCloud, request): - _setup_image(class_session_cloud, request) - - def _collect_logs( instance: IntegrationInstance, node_id: str, test_failed: bool ): @@ -329,19 +273,19 @@ def client( @pytest.fixture(scope="module") def module_client( - request, fixture_utils, module_session_cloud, module_setup_image + request, fixture_utils, session_cloud, setup_image ) -> Iterator[IntegrationInstance]: """Provide a client that runs once per module.""" - with _client(request, fixture_utils, module_session_cloud) as client: + with _client(request, fixture_utils, session_cloud) as client: yield client @pytest.fixture(scope="class") def class_client( - request, fixture_utils, class_session_cloud, class_setup_image + request, fixture_utils, session_cloud, setup_image ) -> Iterator[IntegrationInstance]: """Provide a client that runs once per class.""" - with _client(request, fixture_utils, class_session_cloud) as client: + with _client(request, fixture_utils, session_cloud) as client: yield client diff --git a/tests/integration_tests/modules/test_ansible.py b/tests/integration_tests/modules/test_ansible.py index 0328781e..eebc7be9 100644 --- a/tests/integration_tests/modules/test_ansible.py +++ b/tests/integration_tests/modules/test_ansible.py @@ -22,14 +22,35 @@ write_files: content: | [Unit] Description=Serve a local git repo + Wants=repo_waiter.service + After=cloud-init-local.service + Before=cloud-config.service + Before=cloud-final.service + + [Install] + WantedBy=cloud-init-local.service [Service] - ExecStart=/usr/bin/env python3 -m http.server --directory \ -/root/playbooks/.git - Restart=on-failure + ExecStart=/usr/bin/env python3 -m http.server \ + --directory /root/playbooks/.git + + - path: /etc/systemd/system/repo_waiter.service + content: | + [Unit] + Description=Block boot until repo is available + After=repo_server.service + Before=cloud-final.service [Install] - WantedBy=cloud-final.service + WantedBy=cloud-init-local.service + + # clone into temp directory to test that server is running + # sdnotify would be an alternative way to verify that the server is + # running and continue once it is up, but this is simple and works + [Service] + Type=oneshot + ExecStart=sh -c "while \ + ! git clone http://0.0.0.0:8000/ $(mktemp -d); do sleep 0.1; done" - path: /root/playbooks/ubuntu.yml content: | @@ -57,8 +78,11 @@ write_files: - "{{ item }}" state: latest loop: "{{ packages }}" - +runcmd: + - [systemctl, enable, repo_server.service] + - [systemctl, enable, repo_waiter.service] """ + INSTALL_METHOD = """ ansible: install-method: {method} @@ -67,15 +91,13 @@ ansible: url: "http://0.0.0.0:8000/" playbook-name: ubuntu.yml full: true -runcmd: - - "systemctl enable repo_server.service" """ SETUP_REPO = f"cd {REPO_D} &&\ git init {REPO_D} &&\ git add {REPO_D}/roles/apt/tasks/main.yml {REPO_D}/ubuntu.yml &&\ git commit -m auto &&\ -git update-server-info" +(cd {REPO_D}/.git; git update-server-info)" def _test_ansible_pull_from_local_server(my_client): @@ -84,15 +106,6 @@ def _test_ansible_pull_from_local_server(my_client): my_client.execute("cloud-init clean --logs") my_client.restart() log = my_client.read_from_file("/var/log/cloud-init.log") - - # These ensure the repo used for ansible-pull works as expected - assert my_client.execute("wget http://0.0.0.0:8000").ok - assert my_client.execute("git clone http://0.0.0.0:8000/").ok - assert "(dead)" not in my_client.execute( - "systemctl status repo_server.service" - ) - - # Following assertions verify ansible behavior itself verify_clean_log(log) output_log = my_client.read_from_file("/var/log/cloud-init-output.log") assert "ok=3" in output_log diff --git a/tests/integration_tests/modules/test_lxd.py b/tests/integration_tests/modules/test_lxd.py index f4045425..3443b74a 100644 --- a/tests/integration_tests/modules/test_lxd.py +++ b/tests/integration_tests/modules/test_lxd.py @@ -3,7 +3,6 @@ (This is ported from ``tests/cloud_tests/testcases/modules/lxd_bridge.yaml``.) """ -import re import warnings import pytest @@ -30,10 +29,9 @@ lxd: STORAGE_USER_DATA = """\ #cloud-config -bootcmd: [ "apt-get --yes remove {0}", "! command -v {2}", "{3}" ] lxd: init: - storage_backend: {1} + storage_backend: {} """ @@ -51,7 +49,7 @@ class TestLxdBridge: verify_clean_log(cloud_init_log) # The bridge should exist - assert class_client.execute("ip addr show lxdbr0") + assert class_client.execute("ip addr show lxdbr0").ok raw_network_config = class_client.execute("lxc network show lxdbr0") network_config = yaml.safe_load(raw_network_config) @@ -60,42 +58,31 @@ class TestLxdBridge: def validate_storage(validate_client, pkg_name, command): log = validate_client.read_from_file("/var/log/cloud-init.log") - assert re.search(f"apt-get.*install.*{pkg_name}", log) is not None verify_clean_log(log, ignore_deprecations=False) return log @pytest.mark.no_container -@pytest.mark.user_data( - STORAGE_USER_DATA.format("btrfs-progs", "btrfs", "mkfs.btrfs", "true") -) +@pytest.mark.user_data(STORAGE_USER_DATA.format("btrfs")) def test_storage_btrfs(client): validate_storage(client, "btrfs-progs", "mkfs.btrfs") @pytest.mark.no_container -@pytest.mark.user_data( - STORAGE_USER_DATA.format( - "lvm2", - "lvm", - "lvcreate", - "apt-get install " - "thin-provisioning-tools && systemctl unmask lvm2-lvmpolld.socket", - ) -) +@pytest.mark.user_data(STORAGE_USER_DATA.format("lvm")) def test_storage_lvm(client): log = client.read_from_file("/var/log/cloud-init.log") # Note to self - if "doesn't use thinpool by default on Ubuntu due to LP" not in log: + if ( + "doesn't use thinpool by default on Ubuntu due to LP" not in log + and "-kvm" not in client.execute("uname -r") + ): warnings.warn("LP 1982780 has been fixed, update to allow thinpools") - validate_storage(client, "lvm2", "lvcreate") @pytest.mark.no_container -@pytest.mark.user_data( - STORAGE_USER_DATA.format("zfsutils-linux", "zfs", "zpool", "true") -) +@pytest.mark.user_data(STORAGE_USER_DATA.format("zfs")) def test_storage_zfs(client): validate_storage(client, "zfsutils-linux", "zpool") diff --git a/tests/integration_tests/modules/test_wireguard.py b/tests/integration_tests/modules/test_wireguard.py index 2e97c1fb..e658a9df 100644 --- a/tests/integration_tests/modules/test_wireguard.py +++ b/tests/integration_tests/modules/test_wireguard.py @@ -36,6 +36,12 @@ wireguard: readinessprobe: - ping -qc 5 192.168.254.1 2>&1 > /dev/null - echo $? > /tmp/ping + +# wg-quick configures the system interfaces and routes, but we need to ssh in +# stop the service at the end of cloud-init +runcmd: + - [systemctl, stop, wg-quick@wg0.service] + - [systemctl, stop, wg-quick@wg1.service] """ @@ -83,9 +89,15 @@ class TestWireguard: "269196eb9916617969dc5220c1a90d54", ), # check if systemd started wg0 - ("systemctl is-active wg-quick@wg0", "active"), + ( + "systemctl is-failed wg-quick@wg0; test $? -eq 1", + "inactive", + ), # check if systemd started wg1 - ("systemctl is-active wg-quick@wg1", "active"), + ( + "systemctl is-failed wg-quick@wg1; test $? -eq 1", + "inactive", + ), # check readiness probe (ping wg0) ("cat /tmp/ping", "0"), ), diff --git a/tests/integration_tests/util.py b/tests/integration_tests/util.py index 18ca1917..7eec3a4a 100644 --- a/tests/integration_tests/util.py +++ b/tests/integration_tests/util.py @@ -58,6 +58,7 @@ def verify_clean_log(log: str, ignore_deprecations: bool = True): "No lease found; using default endpoint", # Ubuntu lxd storage "thinpool by default on Ubuntu due to LP #1982780", + "WARNING]: Could not match supplied host pattern, ignoring:", ] traceback_texts = [] if "oracle" in log: |