1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
|
# This file is part of cloud-init. See LICENSE file for license information.
"""Integration test for the package update upgrade install module.
This test module asserts that packages are upgraded/updated during boot
with the ``package_update_upgrade_install`` module. We are also testing
if we can install new packages during boot too.
"""
import re
import pytest
from tests.integration_tests.clouds import IntegrationCloud
from tests.integration_tests.releases import CURRENT_RELEASE, IS_UBUNTU
from tests.integration_tests.util import verify_clean_boot, verify_clean_log
USER_DATA = """\
#cloud-config
packages:
- sl
- apt:
- tree
- snap:
- curl
- postman
package_update: true
package_upgrade: true
"""
@pytest.mark.skipif(not IS_UBUNTU, reason="Uses Apt")
@pytest.mark.user_data(USER_DATA)
class TestPackageUpdateUpgradeInstall:
def assert_apt_package_installed(self, pkg_out, name, version=None):
"""Check dpkg-query --show output for matching package name.
@param name: package base name
@param version: string representing a package version or part of a
version.
"""
pkg_match = re.search(
"^%s\t(?P<version>.*)$" % name, pkg_out, re.MULTILINE
)
if pkg_match:
installed_version = pkg_match.group("version")
if not version:
return # Success
if installed_version.startswith(version):
return # Success
raise AssertionError(
"Expected package version %s-%s not found. Found %s" % name,
version,
installed_version,
)
raise AssertionError(f"Package not installed: {name}")
def test_apt_packages_are_installed(self, class_client):
pkg_out = class_client.execute("dpkg-query --show")
self.assert_apt_package_installed(pkg_out, "sl")
self.assert_apt_package_installed(pkg_out, "tree")
def test_apt_packages_were_updated(self, class_client):
out = class_client.execute(
"grep ^Commandline: /var/log/apt/history.log"
)
assert re.search(
"Commandline: (/usr/bin/)?apt-get --option=Dpkg::Options"
"::=--force-confold --option=Dpkg::options::=--force-unsafe-io "
r"--assume-yes --quiet install (sl|tree) (tree|sl)",
out,
)
def test_apt_packages_were_upgraded(self, class_client):
"""Test cloud-init-output for install & upgrade stuff."""
out = class_client.read_from_file("/var/log/cloud-init-output.log")
assert "Setting up tree (" in out
assert "Setting up sl (" in out
assert "Reading package lists..." in out
assert "Building dependency tree..." in out
assert "Reading state information..." in out
assert "Calculating upgrade..." in out
def test_snap_packages_are_installed(self, class_client):
output = class_client.execute("snap list")
assert "curl" in output
assert "postman" in output
def test_snap_refresh_not_called_when_refresh_hold_forever(
self, class_client
):
"""Assert snap refresh is not called when snap refresh --hold is set.
Certain network-limited or secure environments may opt to avoid
contacting snap API endpoints. In those scenarios, it is expected
that automated snap refresh is held for all snaps. Typically, this is
done with snap refresh --hold in those environments.
Assert cloud-init does not attempt to call snap refresh when
refresh.hold is forever.
"""
assert class_client.execute(
[
"grep",
r"Running command \['snap', 'refresh'",
"/var/log/cloud-init.log",
]
).ok
assert class_client.execute("snap refresh --hold").ok
class_client.instance.clean()
class_client.restart()
assert class_client.execute(
[
"grep",
r"Running command \['snap', 'refresh']",
"/var/log/cloud-init.log",
]
).failed
assert class_client.execute(
"grep 'Skipping snap refresh' /var/log/cloud-init.log"
).ok
HELLO_VERSIONS_BY_RELEASE = {
"questing": "2.10-5",
"plucky": "2.10-3build2",
"oracular": "2.10-3build2",
"noble": "2.10-3build1",
"mantic": "2.10-3",
"lunar": "2.10-3",
"jammy": "2.10-2ubuntu4",
"focal": "2.10-2ubuntu2",
}
VERSIONED_USER_DATA = """\
#cloud-config
packages:
- [hello, {pkg_version}]
"""
@pytest.mark.skipif(not IS_UBUNTU, reason="Uses Apt")
def test_versioned_packages_are_installed(session_cloud: IntegrationCloud):
pkg_version = HELLO_VERSIONS_BY_RELEASE.get(
CURRENT_RELEASE.series, "2.10-5"
)
with session_cloud.launch(
user_data=VERSIONED_USER_DATA.format(pkg_version=pkg_version)
) as client:
verify_clean_log(client.read_from_file("/var/log/cloud-init.log"))
verify_clean_boot(client)
assert f"hello {pkg_version}" == client.execute(
"dpkg-query -W hello"
), (
"If this is failing for a new release, add it to "
"HELLO_VERSIONS_BY_RELEASE"
)
|