summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Falcon <james.falcon@canonical.com>2022-01-10 16:56:29 -0600
committerGitHub <noreply@github.com>2022-01-10 15:56:29 -0700
commitdc1aabfca851e520693c05322f724bd102c76364 (patch)
tree05c7a0d293b9ddece5671fcdf6a38c59ce776ac8
parent57ccd89b6af7d3551915df56f548b7617dfcebf9 (diff)
downloadcloud-init-git-dc1aabfca851e520693c05322f724bd102c76364.tar.gz
Remove 3.5 and xenial support (SC-711) (#1167)
Includes: - Update tox.ini and .travis.yml accordingly - Cleanup tox.ini with new tox syntax and cloud-init dependencies - Update documentation accordingly - Replace/remove xenial references where additional testing isn't required - Remove xenial checks in integration tests - Replace yield_fixture with fixture in pytest tests Sections of code commented with lines like "Remove when Xenial is no longer supported" still exist as they're require additional testing.
-rw-r--r--.travis.yml41
-rw-r--r--cloudinit/config/cc_apt_configure.py2
-rw-r--r--cloudinit/distros/debian.py2
-rw-r--r--conftest.py4
-rw-r--r--doc/examples/cloud-config-apt.txt6
-rw-r--r--doc/examples/cloud-config-chef.txt5
-rw-r--r--doc/rtd/topics/debugging.rst6
-rw-r--r--doc/rtd/topics/testing.rst38
-rw-r--r--tests/integration_tests/bugs/test_gh626.py7
-rw-r--r--tests/integration_tests/bugs/test_lp1898997.py2
-rw-r--r--tests/integration_tests/conftest.py29
-rw-r--r--tests/integration_tests/datasources/test_lxd_discovery.py8
-rw-r--r--tests/integration_tests/modules/test_disk_setup.py5
-rw-r--r--tests/integration_tests/modules/test_lxd_bridge.py2
-rw-r--r--tests/integration_tests/modules/test_users_groups.py1
-rw-r--r--tests/unittests/cmd/devel/test_hotplug_hook.py2
-rw-r--r--tests/unittests/config/test_cc_install_hotplug.py2
-rw-r--r--tests/unittests/distros/test_networking.py4
-rw-r--r--tests/unittests/sources/test_lxd.py2
-rw-r--r--tests/unittests/sources/test_oracle.py4
-rw-r--r--tests/unittests/sources/test_vmware.py2
-rw-r--r--tests/unittests/test_features.py2
-rw-r--r--tests/unittests/test_net_activators.py4
-rw-r--r--tests/unittests/test_stages.py2
-rw-r--r--tests/unittests/test_util.py2
-rw-r--r--tox.ini190
26 files changed, 137 insertions, 237 deletions
diff --git a/.travis.yml b/.travis.yml
index 2351246b..208bed23 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -75,17 +75,17 @@ matrix:
- cp /usr/share/doc/sbuild/examples/example.sbuildrc /home/$USER/.sbuildrc
script:
# Ubuntu LTS: Build
- - ./packages/bddeb -S -d --release xenial
+ - ./packages/bddeb -S -d --release bionic
- |
needs_caching=false
- if [ -e "$TRAVIS_BUILD_DIR/chroots/xenial-amd64.tar" ]; then
+ if [ -e "$TRAVIS_BUILD_DIR/chroots/bionic-amd64.tar" ]; then
# If we have a cached chroot, move it into place
- sudo mkdir -p /var/lib/schroot/chroots/xenial-amd64
- sudo tar --sparse --xattrs --preserve-permissions --numeric-owner -xf "$TRAVIS_BUILD_DIR/chroots/xenial-amd64.tar" -C /var/lib/schroot/chroots/xenial-amd64
+ sudo mkdir -p /var/lib/schroot/chroots/bionic-amd64
+ sudo tar --sparse --xattrs --preserve-permissions --numeric-owner -xf "$TRAVIS_BUILD_DIR/chroots/bionic-amd64.tar" -C /var/lib/schroot/chroots/bionic-amd64
# Write its configuration
- cat > sbuild-xenial-amd64 << EOM
- [xenial-amd64]
- description=xenial-amd64
+ cat > sbuild-bionic-amd64 << EOM
+ [bionic-amd64]
+ description=bionic-amd64
groups=sbuild,root,admin
root-groups=sbuild,root,admin
# Uncomment these lines to allow members of these groups to access
@@ -95,20 +95,20 @@ matrix:
type=directory
profile=sbuild
union-type=overlay
- directory=/var/lib/schroot/chroots/xenial-amd64
+ directory=/var/lib/schroot/chroots/bionic-amd64
EOM
- sudo mv sbuild-xenial-amd64 /etc/schroot/chroot.d/
- sudo chown root /etc/schroot/chroot.d/sbuild-xenial-amd64
+ sudo mv sbuild-bionic-amd64 /etc/schroot/chroot.d/
+ sudo chown root /etc/schroot/chroot.d/sbuild-bionic-amd64
# And ensure it's up-to-date.
- before_pkgs="$(sudo schroot -c source:xenial-amd64 -d / dpkg -l | sha256sum)"
- sudo schroot -c source:xenial-amd64 -d / -- sh -c "apt-get update && apt-get -qqy upgrade"
- after_pkgs=$(sudo schroot -c source:xenial-amd64 -d / dpkg -l | sha256sum)
+ before_pkgs="$(sudo schroot -c source:bionic-amd64 -d / dpkg -l | sha256sum)"
+ sudo schroot -c source:bionic-amd64 -d / -- sh -c "apt-get update && apt-get -qqy upgrade"
+ after_pkgs=$(sudo schroot -c source:bionic-amd64 -d / dpkg -l | sha256sum)
if [ "$before_pkgs" != "$after_pkgs" ]; then
needs_caching=true
fi
else
# Otherwise, create the chroot
- sudo -E su $USER -c 'mk-sbuild xenial'
+ sudo -E su $USER -c 'mk-sbuild bionic'
needs_caching=true
fi
# If there are changes to the schroot (or it's entirely new),
@@ -116,19 +116,19 @@ matrix:
# move it into the cached dir; no need to compress it because
# Travis will do that anyway
if [ "$needs_caching" = "true" ]; then
- sudo tar --sparse --xattrs --xattrs-include=* -cf "$TRAVIS_BUILD_DIR/chroots/xenial-amd64.tar" -C /var/lib/schroot/chroots/xenial-amd64 .
+ sudo tar --sparse --xattrs --xattrs-include=* -cf "$TRAVIS_BUILD_DIR/chroots/bionic-amd64.tar" -C /var/lib/schroot/chroots/bionic-amd64 .
fi
# Use sudo to get a new shell where we're in the sbuild group
# Don't run integration tests when build fails
- |
- sudo -E su $USER -c 'DEB_BUILD_OPTIONS=nocheck sbuild --nolog --no-run-lintian --no-run-autopkgtest --verbose --dist=xenial cloud-init_*.dsc' &&
+ sudo -E su $USER -c 'DEB_BUILD_OPTIONS=nocheck sbuild --nolog --no-run-lintian --no-run-autopkgtest --verbose --dist=bionic cloud-init_*.dsc' &&
ssh-keygen -P "" -q -f ~/.ssh/id_rsa &&
sg lxd -c 'CLOUD_INIT_CLOUD_INIT_SOURCE="$(ls *.deb)" tox -e integration-tests-ci'
- - python: 3.5
+ - python: 3.6
env:
- TOXENV=xenial
- PYTEST_ADDOPTS=-v # List all tests run by pytest
- dist: xenial
+ TOXENV=lowest-supported
+ PYTEST_ADDOPTS=-v # List all tests run by pytest
+ dist: bionic
- python: 3.6
env: TOXENV=flake8
- python: 3.6
@@ -145,4 +145,3 @@ matrix:
- python: 3.9
- python: 3.8
- python: 3.7
- - python: 3.5
diff --git a/cloudinit/config/cc_apt_configure.py b/cloudinit/config/cc_apt_configure.py
index b0728517..37077a9f 100644
--- a/cloudinit/config/cc_apt_configure.py
+++ b/cloudinit/config/cc_apt_configure.py
@@ -133,7 +133,7 @@ meta = {
source1:
keyid: 'keyid'
keyserver: 'keyserverurl'
- source: 'deb [signed-by=$KEY_FILE] http://<url>/ xenial main'
+ source: 'deb [signed-by=$KEY_FILE] http://<url>/ bionic main'
source2:
source: 'ppa:<ppa-name>'
source3:
diff --git a/cloudinit/distros/debian.py b/cloudinit/distros/debian.py
index 0105a383..9effa0a0 100644
--- a/cloudinit/distros/debian.py
+++ b/cloudinit/distros/debian.py
@@ -257,7 +257,7 @@ class Distro(distros.Distro):
pkgs = []
e = os.environ.copy()
- # See: http://manpages.ubuntu.com/manpages/xenial/man7/debconf.7.html
+ # See: http://manpages.ubuntu.com/manpages/bionic/man7/debconf.7.html
e["DEBIAN_FRONTEND"] = "noninteractive"
wcfg = self.get_option("apt_get_wrapper", APT_GET_WRAPPER)
diff --git a/conftest.py b/conftest.py
index ffcb3233..3979eb0a 100644
--- a/conftest.py
+++ b/conftest.py
@@ -65,7 +65,7 @@ class _FixtureUtils:
return result[0]
-@pytest.yield_fixture(autouse=True)
+@pytest.fixture(autouse=True)
def disable_subp_usage(request, fixture_utils):
"""
Across all (pytest) tests, ensure that subp.subp is not invoked.
@@ -166,7 +166,7 @@ def fixture_utils():
return _FixtureUtils
-@pytest.yield_fixture
+@pytest.fixture
def httpretty():
"""
Enable HTTPretty for duration of the testcase, resetting before and after.
diff --git a/doc/examples/cloud-config-apt.txt b/doc/examples/cloud-config-apt.txt
index 778187b5..39f546e1 100644
--- a/doc/examples/cloud-config-apt.txt
+++ b/doc/examples/cloud-config-apt.txt
@@ -254,7 +254,7 @@ apt:
#
# Creates a file in /etc/apt/sources.list.d/ for the sources list entry
# based on the key: "/etc/apt/sources.list.d/curtin-dev-ppa.list"
- source: "deb http://ppa.launchpad.net/curtin-dev/test-archive/ubuntu xenial main"
+ source: "deb http://ppa.launchpad.net/curtin-dev/test-archive/ubuntu bionic main"
# 2.2 keyid
#
@@ -282,13 +282,13 @@ apt:
# They will be replaced with the default or specified mirrors and the
# running release.
# The entry below would be possibly turned into:
- # source: deb http://archive.ubuntu.com/ubuntu xenial multiverse
+ # source: deb http://archive.ubuntu.com/ubuntu bionic multiverse
source: deb [signed-by=$KEY_FILE] $MIRROR $RELEASE multiverse
keyid: F430BBA5
my-repo3.list:
# this would have the same end effect as 'ppa:curtin-dev/test-archive'
- source: "deb http://ppa.launchpad.net/curtin-dev/test-archive/ubuntu xenial main"
+ source: "deb http://ppa.launchpad.net/curtin-dev/test-archive/ubuntu bionic main"
keyid: F430BBA5 # GPG key ID published on the key server
filename: curtin-dev-ppa.list
diff --git a/doc/examples/cloud-config-chef.txt b/doc/examples/cloud-config-chef.txt
index 414111a1..9bb3c150 100644
--- a/doc/examples/cloud-config-chef.txt
+++ b/doc/examples/cloud-config-chef.txt
@@ -4,9 +4,6 @@
# list of recipes when the instance boots for the first time.
# Make sure that this file is valid yaml before starting instances.
# It should be passed as user-data when starting the instance.
-#
-# This example assumes the instance is 16.04 (xenial)
-
# The default is to install from packages.
@@ -55,7 +52,7 @@ chef:
# Valid values are 'accept' and 'accept-no-persist'
chef_license: "accept"
-
+
# Valid values are 'gems' and 'packages' and 'omnibus'
install_type: "packages"
diff --git a/doc/rtd/topics/debugging.rst b/doc/rtd/topics/debugging.rst
index b897a318..a4a2779f 100644
--- a/doc/rtd/topics/debugging.rst
+++ b/doc/rtd/topics/debugging.rst
@@ -88,7 +88,7 @@ To quickly obtain a cloud-init log try using lxc on any ubuntu system:
.. code-block:: shell-session
- $ lxc init ubuntu-daily:xenial x1
+ $ lxc init ubuntu-daily:focal x1
$ lxc start x1
$ # Take lxc's cloud-init.log and pipe it to the analyzer
$ lxc file pull x1/var/log/cloud-init.log - | cloud-init analyze dump -i -
@@ -104,13 +104,13 @@ To quickly analyze a KVM a cloud-init log:
.. code-block:: shell-session
- $ wget https://cloud-images.ubuntu.com/daily/server/xenial/current/xenial-server-cloudimg-amd64.img
+ $ wget https://cloud-images.ubuntu.com/daily/server/focal/current/focal-server-cloudimg-amd64.img
2. Create a snapshot image to preserve the original cloud-image
.. code-block:: shell-session
- $ qemu-img create -b xenial-server-cloudimg-amd64.img -f qcow2 \
+ $ qemu-img create -b focal-server-cloudimg-amd64.img -f qcow2 \
test-cloudinit.qcow2
3. Create a seed image with metadata using `cloud-localds`
diff --git a/doc/rtd/topics/testing.rst b/doc/rtd/topics/testing.rst
index 7a1e3eec..5543c6f5 100644
--- a/doc/rtd/topics/testing.rst
+++ b/doc/rtd/topics/testing.rst
@@ -54,28 +54,22 @@ Test Layout
* pytest tests should use bare ``assert`` statements, to take advantage
of pytest's `assertion introspection`_
- * For ``==`` and other commutative assertions, the expected value
- should be placed before the value under test:
- ``assert expected_value == function_under_test()``
-
-
``pytest`` Version Gotchas
--------------------------
-As we still support Ubuntu 16.04 (Xenial Xerus), we can only use pytest
-features that are available in v2.8.7. This is an inexhaustive list of
+As we still support Ubuntu 18.04 (Bionic Beaver), we can only use pytest
+features that are available in v3.3.2. This is an inexhaustive list of
ways in which this may catch you out:
-* Support for using ``yield`` in ``pytest.fixture`` functions was only
- introduced in `pytest 3.0`_. Such functions must instead use the
- ``pytest.yield_fixture`` decorator.
-
* Only the following built-in fixtures are available [#fixture-list]_:
* ``cache``
* ``capfd``
- * ``caplog`` (provided by ``python3-pytest-catchlog`` on xenial)
+ * ``capfdbinary``
+ * ``caplog``
* ``capsys``
+ * ``capsysbinary``
+ * ``doctest_namespace``
* ``monkeypatch``
* ``pytestconfig``
* ``record_xml_property``
@@ -83,22 +77,6 @@ ways in which this may catch you out:
* ``tmpdir_factory``
* ``tmpdir``
-* On xenial, the objects returned by the ``tmpdir`` fixture cannot be
- used where paths are required; they are rejected as invalid paths.
- You must instead use their ``.strpath`` attribute.
-
- * For example, instead of ``util.write_file(tmpdir.join("some_file"),
- ...)``, you should write
- ``util.write_file(tmpdir.join("some_file").strpath, ...)``.
-
-* The `pytest.param`_ function cannot be used. It was introduced in
- pytest 3.1, which means it is not available on xenial. The more
- limited mechanism it replaced was removed in pytest 4.0, so is not
- available in focal or later. The only available alternatives are to
- write mark-requiring test instances as completely separate tests,
- without utilising parameterisation, or to apply the mark to the
- entire parameterized test (and therefore every test instance).
-
Mocking and Assertions
----------------------
@@ -168,9 +146,9 @@ Test Argument Ordering
.. [#fixture-list] This list of fixtures (with markup) can be
reproduced by running::
- py.test-3 --fixtures -q | grep "^[^ -]" | grep -v '\(no\|capturelog\)' | sort | sed 's/.*/* ``\0``/'
+ python3 -m pytest --fixtures -q | grep "^[^ -]" | grep -v 'no tests ran in' | sort | sed 's/ \[session scope\]//g;s/.*/* ``\0``/g'
- in a xenial lxd container with python3-pytest-catchlog installed.
+ in an ubuntu lxd container with python3-pytest installed.
.. _pytest: https://docs.pytest.org/
.. _pytest fixtures: https://docs.pytest.org/en/latest/fixture.html
diff --git a/tests/integration_tests/bugs/test_gh626.py b/tests/integration_tests/bugs/test_gh626.py
index 7c720143..b80b677a 100644
--- a/tests/integration_tests/bugs/test_gh626.py
+++ b/tests/integration_tests/bugs/test_gh626.py
@@ -8,7 +8,6 @@ import pytest
import yaml
from tests.integration_tests import random_mac_address
-from tests.integration_tests.clouds import ImageSpecification
from tests.integration_tests.instances import IntegrationInstance
MAC_ADDRESS = random_mac_address()
@@ -29,7 +28,6 @@ iface eth0 inet dhcp
ethernet-wol g"""
-@pytest.mark.sru_2020_11
@pytest.mark.lxd_container
@pytest.mark.lxd_vm
@pytest.mark.lxd_config_dict(
@@ -39,11 +37,6 @@ iface eth0 inet dhcp
}
)
def test_wakeonlan(client: IntegrationInstance):
- if ImageSpecification.from_os_image().release == "xenial":
- eni = client.execute("cat /etc/network/interfaces.d/50-cloud-init.cfg")
- assert eni.endswith(EXPECTED_ENI_END)
- return
-
netplan_cfg = client.execute("cat /etc/netplan/50-cloud-init.yaml")
netplan_yaml = yaml.safe_load(netplan_cfg)
assert "wakeonlan" in netplan_yaml["network"]["ethernets"]["eth0"]
diff --git a/tests/integration_tests/bugs/test_lp1898997.py b/tests/integration_tests/bugs/test_lp1898997.py
index 115bd34f..d8ea54c3 100644
--- a/tests/integration_tests/bugs/test_lp1898997.py
+++ b/tests/integration_tests/bugs/test_lp1898997.py
@@ -47,8 +47,6 @@ version: 2
@pytest.mark.lxd_vm
@pytest.mark.lxd_use_exec
@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):
diff --git a/tests/integration_tests/conftest.py b/tests/integration_tests/conftest.py
index b14b6ad0..2e44ef29 100644
--- a/tests/integration_tests/conftest.py
+++ b/tests/integration_tests/conftest.py
@@ -45,17 +45,6 @@ os_list = ["ubuntu"]
session_start_time = datetime.datetime.now().strftime("%y%m%d%H%M%S")
-XENIAL_LXD_VM_EXEC_MSG = """\
-The default xenial images do not support `exec` for LXD VMs.
-
-Specify an image known to work using:
-
- OS_IMAGE=<image id>::ubuntu::xenial
-
-You can re-run specifically tests that require this by passing `-m
-lxd_use_exec` to pytest.
-"""
-
def pytest_runtest_setup(item):
"""Skip tests on unsupported clouds.
@@ -101,7 +90,7 @@ def disable_subp_usage(request):
pass
-@pytest.yield_fixture(scope="session")
+@pytest.fixture(scope="session")
def session_cloud():
if integration_settings.PLATFORM not in platforms.keys():
raise ValueError(
@@ -246,16 +235,6 @@ def _client(request, fixture_utils, session_cloud: IntegrationCloud):
if lxd_use_exec is not None:
if not isinstance(session_cloud, _LxdIntegrationCloud):
pytest.skip("lxd_use_exec requires LXD")
- if isinstance(session_cloud, LxdVmCloud):
- image_spec = ImageSpecification.from_os_image()
- if image_spec.release == image_spec.image_id == "xenial":
- # Why fail instead of skip? We expect that skipped tests will
- # be run in a different one of our usual battery of test runs
- # (e.g. LXD-only tests are skipped on EC2 but will run in our
- # normal LXD test runs). This is not true of this test: it
- # can't run in our usual xenial LXD VM test run, and it may not
- # run anywhere else. A failure flags up this discrepancy.
- pytest.fail(XENIAL_LXD_VM_EXEC_MSG)
launch_kwargs["execute_via_ssh"] = False
local_launch_kwargs = {}
if lxd_setup is not None:
@@ -276,21 +255,21 @@ def _client(request, fixture_utils, session_cloud: IntegrationCloud):
_collect_logs(instance, request.node.nodeid, test_failed)
-@pytest.yield_fixture
+@pytest.fixture
def client(request, fixture_utils, session_cloud, setup_image):
"""Provide a client that runs for every test."""
with _client(request, fixture_utils, session_cloud) as client:
yield client
-@pytest.yield_fixture(scope="module")
+@pytest.fixture(scope="module")
def module_client(request, fixture_utils, session_cloud, setup_image):
"""Provide a client that runs once per module."""
with _client(request, fixture_utils, session_cloud) as client:
yield client
-@pytest.yield_fixture(scope="class")
+@pytest.fixture(scope="class")
def class_client(request, fixture_utils, session_cloud, setup_image):
"""Provide a client that runs once per class."""
with _client(request, fixture_utils, session_cloud) as client:
diff --git a/tests/integration_tests/datasources/test_lxd_discovery.py b/tests/integration_tests/datasources/test_lxd_discovery.py
index da010813..eb2a4cf2 100644
--- a/tests/integration_tests/datasources/test_lxd_discovery.py
+++ b/tests/integration_tests/datasources/test_lxd_discovery.py
@@ -59,13 +59,9 @@ def test_lxd_datasource_discovery(client: IntegrationInstance):
)
if (
client.settings.PLATFORM == "lxd_vm"
- and ImageSpecification.from_os_image().release
- in (
- "xenial",
- "bionic",
- )
+ and ImageSpecification.from_os_image().release == "bionic"
):
- # pycloudlib injects user.vendor_data for lxd_vm on bionic and xenial
+ # pycloudlib injects user.vendor_data for lxd_vm on bionic
# to start the lxd-agent.
# https://github.com/canonical/pycloudlib/blob/main/pycloudlib/\
# lxd/defaults.py#L13-L27
diff --git a/tests/integration_tests/modules/test_disk_setup.py b/tests/integration_tests/modules/test_disk_setup.py
index 22277331..8f9d5f40 100644
--- a/tests/integration_tests/modules/test_disk_setup.py
+++ b/tests/integration_tests/modules/test_disk_setup.py
@@ -20,7 +20,7 @@ def setup_and_mount_lxd_disk(instance: LXDInstance):
)
-@pytest.yield_fixture
+@pytest.fixture
def create_disk():
# 640k should be enough for anybody
subp("dd if=/dev/zero of={} bs=1k count=640".format(DISK_PATH).split())
@@ -133,10 +133,9 @@ class TestPartProbeAvailability:
assert sdb["children"][1]["name"] == "sdb2"
assert sdb["children"][1]["mountpoint"] == "/mnt2"
- # Not bionic or xenial because the LXD agent gets in the way of us
+ # Not bionic because the LXD agent gets in the way of us
# changing the userdata
@pytest.mark.not_bionic
- @pytest.mark.not_xenial
def test_disk_setup_when_mounted(
self, create_disk, client: IntegrationInstance
):
diff --git a/tests/integration_tests/modules/test_lxd_bridge.py b/tests/integration_tests/modules/test_lxd_bridge.py
index 2cb3f4f3..3292a833 100644
--- a/tests/integration_tests/modules/test_lxd_bridge.py
+++ b/tests/integration_tests/modules/test_lxd_bridge.py
@@ -33,8 +33,6 @@ class TestLxdBridge:
"""Check that the expected LXD binaries are installed"""
assert class_client.execute(["which", binary_name]).ok
- @pytest.mark.not_xenial
- @pytest.mark.sru_2020_11
def test_bridge(self, class_client):
"""Check that the given bridge is configured"""
cloud_init_log = class_client.read_from_file("/var/log/cloud-init.log")
diff --git a/tests/integration_tests/modules/test_users_groups.py b/tests/integration_tests/modules/test_users_groups.py
index 3d1358ce..fddff681 100644
--- a/tests/integration_tests/modules/test_users_groups.py
+++ b/tests/integration_tests/modules/test_users_groups.py
@@ -106,7 +106,6 @@ def test_sudoers_includedir(client: IntegrationInstance):
https://github.com/canonical/cloud-init/pull/783
"""
if ImageSpecification.from_os_image().release in [
- "xenial",
"bionic",
"focal",
]:
diff --git a/tests/unittests/cmd/devel/test_hotplug_hook.py b/tests/unittests/cmd/devel/test_hotplug_hook.py
index 842e8dfd..5ecb5969 100644
--- a/tests/unittests/cmd/devel/test_hotplug_hook.py
+++ b/tests/unittests/cmd/devel/test_hotplug_hook.py
@@ -16,7 +16,7 @@ hotplug_args = namedtuple("hotplug_args", "udevaction, subsystem, devpath")
FAKE_MAC = "11:22:33:44:55:66"
-@pytest.yield_fixture
+@pytest.fixture
def mocks():
m_init = mock.MagicMock(spec=Init)
m_distro = mock.MagicMock(spec=Distro)
diff --git a/tests/unittests/config/test_cc_install_hotplug.py b/tests/unittests/config/test_cc_install_hotplug.py
index 3bd44aba..e67fce60 100644
--- a/tests/unittests/config/test_cc_install_hotplug.py
+++ b/tests/unittests/config/test_cc_install_hotplug.py
@@ -12,7 +12,7 @@ from cloudinit.config.cc_install_hotplug import (
from cloudinit.event import EventScope, EventType
-@pytest.yield_fixture()
+@pytest.fixture()
def mocks():
m_update_enabled = mock.patch("cloudinit.stages.update_event_enabled")
m_write = mock.patch("cloudinit.util.write_file", autospec=True)
diff --git a/tests/unittests/distros/test_networking.py b/tests/unittests/distros/test_networking.py
index 635f6901..274647cb 100644
--- a/tests/unittests/distros/test_networking.py
+++ b/tests/unittests/distros/test_networking.py
@@ -13,7 +13,7 @@ from cloudinit.distros.networking import (
)
-@pytest.yield_fixture
+@pytest.fixture
def generic_networking_cls():
"""Returns a direct Networking subclass which errors on /sys usage.
@@ -40,7 +40,7 @@ def generic_networking_cls():
yield TestNetworking
-@pytest.yield_fixture
+@pytest.fixture
def sys_class_net(tmpdir):
sys_class_net_path = tmpdir.join("sys/class/net")
sys_class_net_path.ensure_dir()
diff --git a/tests/unittests/sources/test_lxd.py b/tests/unittests/sources/test_lxd.py
index ad1508a0..e11c3746 100644
--- a/tests/unittests/sources/test_lxd.py
+++ b/tests/unittests/sources/test_lxd.py
@@ -57,7 +57,7 @@ def lxd_metadata():
return LXD_V1_METADATA
-@pytest.yield_fixture
+@pytest.fixture
def lxd_ds(request, paths, lxd_metadata):
"""
Return an instantiated DataSourceLXD.
diff --git a/tests/unittests/sources/test_oracle.py b/tests/unittests/sources/test_oracle.py
index e0e79c8c..356b3738 100644
--- a/tests/unittests/sources/test_oracle.py
+++ b/tests/unittests/sources/test_oracle.py
@@ -93,7 +93,7 @@ def metadata_version():
return 2
-@pytest.yield_fixture
+@pytest.fixture
def oracle_ds(request, fixture_utils, paths, metadata_version):
"""
Return an instantiated DataSourceOracle.
@@ -649,7 +649,7 @@ class TestCommon_GetDataBehaviour:
separate class for that case.)
"""
- @pytest.yield_fixture(params=[True, False])
+ @pytest.fixture(params=[True, False])
def parameterized_oracle_ds(self, request, oracle_ds):
"""oracle_ds parameterized for iSCSI and non-iSCSI root respectively"""
is_iscsi_root = request.param
diff --git a/tests/unittests/sources/test_vmware.py b/tests/unittests/sources/test_vmware.py
index dcdbda89..dd331349 100644
--- a/tests/unittests/sources/test_vmware.py
+++ b/tests/unittests/sources/test_vmware.py
@@ -57,7 +57,7 @@ runcmd:
"""
-@pytest.yield_fixture(autouse=True)
+@pytest.fixture(autouse=True)
def common_patches():
with mock.patch("cloudinit.util.platform.platform", return_value="Linux"):
with mock.patch.multiple(
diff --git a/tests/unittests/test_features.py b/tests/unittests/test_features.py
index 141de55b..794a9654 100644
--- a/tests/unittests/test_features.py
+++ b/tests/unittests/test_features.py
@@ -12,7 +12,7 @@ import pytest
import cloudinit
-@pytest.yield_fixture()
+@pytest.fixture()
def create_override(request):
"""
Create a feature overrides file and do some module wizardry to make
diff --git a/tests/unittests/test_net_activators.py b/tests/unittests/test_net_activators.py
index 0e3ab43f..3c29e2f7 100644
--- a/tests/unittests/test_net_activators.py
+++ b/tests/unittests/test_net_activators.py
@@ -39,7 +39,7 @@ NETPLAN_CALL_LIST = [
]
-@pytest.yield_fixture
+@pytest.fixture
def available_mocks():
mocks = namedtuple("Mocks", "m_which, m_file")
with patch("cloudinit.subp.which", return_value=True) as m_which:
@@ -47,7 +47,7 @@ def available_mocks():
yield mocks(m_which, m_file)
-@pytest.yield_fixture
+@pytest.fixture
def unavailable_mocks():
mocks = namedtuple("Mocks", "m_which, m_file")
with patch("cloudinit.subp.which", return_value=False) as m_which:
diff --git a/tests/unittests/test_stages.py b/tests/unittests/test_stages.py
index be1a0787..3214410b 100644
--- a/tests/unittests/test_stages.py
+++ b/tests/unittests/test_stages.py
@@ -512,7 +512,7 @@ class TestInit_InitializeFilesystem:
TODO: Expand these tests to cover all of _initialize_filesystem's behavior.
"""
- @pytest.yield_fixture
+ @pytest.fixture
def init(self, paths):
"""A fixture which yields a stages.Init instance with paths and cfg set
diff --git a/tests/unittests/test_util.py b/tests/unittests/test_util.py
index e2bfe9d2..3765511b 100644
--- a/tests/unittests/test_util.py
+++ b/tests/unittests/test_util.py
@@ -1127,7 +1127,7 @@ class TestMountCb:
TODO: Test the if/else branch that actually performs the mounting operation
"""
- @pytest.yield_fixture
+ @pytest.fixture
def already_mounted_device_and_mountdict(self):
"""Mock an already-mounted device, and yield (device, mount dict)"""
device = "/dev/fake0"
diff --git a/tox.ini b/tox.ini
index 034ee9a4..57d18cdb 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,58 +1,52 @@
[tox]
-envlist = py3, xenial-dev, flake8, pylint, black, isort
+envlist = py3, lowest-supported-dev, flake8, pylint, black, isort
recreate = True
[testenv]
-commands = {envpython} -m pytest {posargs:tests/unittests}
+basepython = python3
setenv =
LC_ALL = en_US.utf-8
passenv=
PYTEST_ADDOPTS
-[testenv:flake8]
-basepython = python3
+[flake_env]
+envdir = {toxworkdir}/.flake_env
deps =
flake8==3.9.2
-commands = {envpython} -m flake8 {posargs:cloudinit/ tests/ tools/ setup.py}
-
-# https://github.com/gabrielfalcao/HTTPretty/issues/223
-setenv =
- LC_ALL = en_US.utf-8
-
-[testenv:pylint]
-basepython = python3
-deps =
- # requirements
pylint==2.11.1
- # test-requirements because unit tests are now present in cloudinit tree
+ black==21.12b0
+ isort==5.10.1
-r{toxinidir}/test-requirements.txt
-r{toxinidir}/integration-requirements.txt
+
+[testenv:flake8]
+envdir = {[flake_env]envdir}
+deps = {[flake_env]deps}
+commands = {envpython} -m flake8 {posargs:cloudinit/ tests/ tools/ setup.py}
+
+[testenv:pylint]
+envdir = {[flake_env]envdir}
+deps = {[flake_env]deps}
commands = {envpython} -m pylint {posargs:cloudinit tests tools}
[testenv:black]
-basepython = python3
-deps =
- # requirements
- black==21.12b0
+envdir = {[flake_env]envdir}
+deps = {[flake_env]deps}
commands = {envpython} -m black . --check
[testenv:isort]
-basepython = python3
-deps =
- isort==5.10.1
+envdir = {[flake_env]envdir}
+deps = {[flake_env]deps}
commands = {envpython} -m isort . --check-only
[testenv:format]
-basepython = python3
-deps =
- black==21.12b0
- isort==5.10.1
+envdir = {[flake_env]envdir}
+deps = {[flake_env]deps}
commands =
{envpython} -m isort .
{envpython} -m black .
[testenv:py3]
-basepython = python3
deps =
-r{toxinidir}/test-requirements.txt
commands = {envpython} -m pytest \
@@ -60,84 +54,56 @@ commands = {envpython} -m pytest \
{posargs:--cov=cloudinit --cov-branch \
tests/unittests}
-[testenv:py27]
-basepython = python2.7
-deps = -r{toxinidir}/test-requirements.txt
+[lowest-supported-deps]
+# Tox is going to install requirements from pip. This is fine for
+# testing python version compatibility, but when we build cloud-init, we are
+# building against the dependencies in the OS repo, not pip. The OS
+# dependencies will generally be older than what is found in pip.
-[flake8]
-# E203: whitespace before ':', doesn't adhere to pep8 or black formatting
-# W503: line break before binary operator
-ignore=E203,W503
-exclude = .venv,.tox,dist,doc,*egg,.git,build,tools
-per-file-ignores =
- cloudinit/cmd/main.py:E402
+# To obtain these versions, check the versions of these libraries
+# in the oldest support Ubuntu distro.
-[testenv:doc]
-basepython = python3
-deps =
- -r{toxinidir}/doc-requirements.txt
-commands =
- {envpython} -m sphinx {posargs:doc/rtd doc/rtd_html}
- doc8 doc/rtd
-
-[xenial-shared-deps]
-# The version of pytest in xenial doesn't work with Python 3.8, so we define
-# two xenial environments: [testenv:xenial] runs the tests with exactly the
-# version of pytest present in xenial, and is used in CI. [testenv:xenial-dev]
-# runs the tests with the lowest version of pytest that works with Python 3.8,
-# 3.0.7, but keeps the other dependencies at xenial's level.
-#
-# (This section is not a testenv, it is used to maintain a single definition of
-# the dependencies shared between the two xenial testenvs.)
+# httpretty isn't included here because python2.7 requires a higher version
+# than whats run on bionic, so we need two different definitions.
deps =
- # requirements
- jinja2==2.8
- pyyaml==3.11
- oauthlib==1.0.3
- pyserial==3.0.1
+ jinja2==2.10
+ oauthlib==2.0.6
+ pyserial==3.4
configobj==5.0.6
- requests==2.9.1
- jsonschema
+ pyyaml==3.12
+ requests==2.18.4
+ jsonpatch==1.16
+ jsonschema==2.6.0
+ netifaces==0.10.4
# test-requirements
- pytest-catchlog==1.2.1
-
-[testenv:xenial]
-# When updating this commands definition, also update the definition in
-# [testenv:xenial-dev]. See the comment there for details.
-commands =
- python ./tools/pipremove jsonschema
- python -m pytest {posargs:tests/unittests}
-basepython = python3
+ pytest==3.3.2
+ pytest-cov==2.5.1
+ # Needed by pytest and default causes failures
+ attrs==17.4.0
+
+[testenv:lowest-supported]
+# This definition will run on bionic with the version of httpretty
+# that runs there
deps =
- # Refer to the comment in [xenial-shared-deps] for details
- {[xenial-shared-deps]deps}
- httpretty==0.8.6
- jsonpatch==1.10
- pytest==2.8.7
-
-[testenv:xenial-dev]
-# This should be:
-# commands = {[testenv:xenial]commands}
-# but the version of pytest in xenial has a bug
-# (https://github.com/tox-dev/tox/issues/208) which means that the {posargs}
-# substitution variable is misparsed and causes a traceback. Ensure that any
-# changes here are reflected in [testenv:xenial].
-commands =
- python ./tools/pipremove jsonschema
- python -m pytest {posargs:tests/unittests}
-basepython = {[testenv:xenial]basepython}
+ {[lowest-supported-deps]deps}
+ httpretty==0.8.14
+commands = {[testenv:py3]commands}
+
+[testenv:lowest-supported-dev]
+# The oldest httpretty version to work with Python 3.7+ is 0.9.5,
+# because it is the first to include this commit:
+# https://github.com/gabrielfalcao/HTTPretty/commit/5776d97da3992b9071db5e21faf175f6e8729060
deps =
- # Refer to the comment in [xenial-shared-deps] for details
- {[xenial-shared-deps]deps}
- # httpretty in xenial is 0.8.6, not 0.9.5. The oldest version to work with
- # Python 3.7+ is 0.9.5, because it is the first to include this commit:
- # https://github.com/gabrielfalcao/HTTPretty/commit/5776d97da3992b9071db5e21faf175f6e8729060
+ {[lowest-supported-deps]deps}
httpretty==0.9.5
- # jsonpatch in xenial is 1.10, not 1.19 (#839779). The oldest version
- # to work with python3.6 is 1.16 as found in Artful. To keep default
- # invocation of 'tox' happy, accept the difference in version here.
- jsonpatch==1.16
- pytest==3.0.7
+commands = {[testenv:py3]commands}
+
+[testenv:doc]
+deps =
+ -r{toxinidir}/doc-requirements.txt
+commands =
+ {envpython} -m sphinx {posargs:doc/rtd doc/rtd_html}
+ doc8 doc/rtd
[testenv:tip-flake8]
commands = {envpython} -m flake8 {posargs:cloudinit/ tests/ tools/ setup.py}
@@ -152,37 +118,36 @@ deps =
-r{toxinidir}/test-requirements.txt
-r{toxinidir}/integration-requirements.txt
-# Until Xenial tox support is dropped or bumps to tox:2.3.2, reflect changes to
-# deps into testenv:integration-tests-ci: commands, passenv and deps.
-# This is due to (https://github.com/tox-dev/tox/issues/208) which means that
-# the {posargs} handling and substitutions won't do what we want until tox 2.3.2
-# Once Xenial is dropped, integration-tests-ci can use proper substitution
-# commands = {[testenv:integration-tests]commands}
[testenv:integration-tests]
-basepython = python3
commands = {envpython} -m pytest --log-cli-level=INFO {posargs:tests/integration_tests}
-passenv = CLOUD_INIT_* SSH_AUTH_SOCK OS_*
deps =
-r{toxinidir}/integration-requirements.txt
+passenv = CLOUD_INIT_* SSH_AUTH_SOCK OS_*
[testenv:integration-tests-ci]
-commands = {envpython} -m pytest --log-cli-level=INFO {posargs:tests/integration_tests}
+commands = {[testenv:integration-tests]commands}
+deps = {[testenv:integration-tests]deps}
passenv = CLOUD_INIT_* SSH_AUTH_SOCK OS_* TRAVIS
-deps =
- -r{toxinidir}/integration-requirements.txt
setenv =
PYTEST_ADDOPTS="-m ci and not adhoc"
[testenv:integration-tests-jenkins]
-commands = {envpython} -m pytest --log-cli-level=INFO {posargs:tests/integration_tests}
+commands = {[testenv:integration-tests]commands}
+deps = {[testenv:integration-tests]deps}
passenv = *_proxy CLOUD_INIT_* SSH_AUTH_SOCK OS_* GOOGLE_* GCP_*
-deps =
- -r{toxinidir}/integration-requirements.txt
setenv =
PYTEST_ADDOPTS="-m not adhoc"
+[flake8]
+# E203: whitespace before ':', doesn't adhere to pep8 or black formatting
+# W503: line break before binary operator
+ignore=E203,W503
+exclude = .venv,.tox,dist,doc,*egg,.git,build,tools
+per-file-ignores =
+ cloudinit/cmd/main.py:E402
+
[pytest]
-# TODO: s/--strict/--strict-markers/ once xenial support is dropped
+# TODO: s/--strict/--strict-markers/ once pytest version is high enough
testpaths = tests/unittests
addopts = --strict
log_format = %(asctime)s %(levelname)-9s %(name)s:%(filename)s:%(lineno)d %(message)s
@@ -202,7 +167,6 @@ markers =
lxd_setup: specify callable to be called between init and start
lxd_use_exec: `execute` will use `lxc exec` instead of SSH
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