[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#1082134: cloud-init FTBFS with Python 3.13



Source: cloud-init
Version: 24.3.1-1
Severity: normal
User: debian-python@lists.debian.org
Usertags: python3.13

This package failed build from source when test-built against a version of
python3-defaults that includes 3.13 as a supported version.

To reproduce this issue, build against python3-defaults (python3-all-dev etc.)
from Debian experimental.

What's new in Python 3.13:
https://docs.python.org/3.13/whatsnew/3.13.html

Log snippet:

=================================== FAILURES ===================================
_ TestVersionedSchemas.test_versioned_cloud_config_schema_is_valid_json[schema2-is not one of ['v1']] _

self = <tests.unittests.config.test_schema.TestVersionedSchemas object at 0xffffb4421e00>
schema = {'version': 'v2'}, error_msg = "is not one of ['v1']"

    @pytest.mark.parametrize(
        "schema,error_msg",
        (
            ({}, None),
            ({"version": "v1"}, None),
            ({"version": "v2"}, "is not one of ['v1']"),
            (
                {"version": "v1", "final_message": -1},
                "is not of type 'string'",
            ),
            ({"version": "v1", "final_message": "some msg"}, None),
        ),
    )
    def test_versioned_cloud_config_schema_is_valid_json(
        self, schema, error_msg
    ):
        schema_dir = get_schema_dir()
        version_schemafile = os.path.join(
            schema_dir, VERSIONED_USERDATA_SCHEMA_FILE
        )
        # Point to local schema files avoid JSON resolver trying to pull the
        # reference from our upstream raw file in github.
        version_schema = json.loads(
            re.sub(
                r"https:\/\/raw.githubusercontent.com\/canonical\/"
                r"cloud-init\/main\/cloudinit\/config\/schemas\/",
                f"file://{schema_dir}/",
                load_text_file(version_schemafile),
            )
        )
        if error_msg:
>           with pytest.raises(SchemaValidationError) as context_mgr:
E           Failed: DID NOT RAISE <class 'cloudinit.config.schema.SchemaValidationError'>

tests/unittests/config/test_schema.py:148: Failed
------------------------------ Captured log call -------------------------------
2024-09-18 16:50:16 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/versions.schema.cloud-config.json (quiet=False)
2024-09-18 16:50:16 DEBUG     cloudinit.util:util.py:1622 Read 557 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/versions.schema.cloud-config.json
2024-09-18 16:50:16 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
_ TestVersionedSchemas.test_versioned_cloud_config_schema_is_valid_json[schema3-is not of type 'string'] _

self = <tests.unittests.config.test_schema.TestVersionedSchemas object at 0xffffb4422ea0>
schema = {'final_message': -1, 'version': 'v1'}
error_msg = "is not of type 'string'"

    @pytest.mark.parametrize(
        "schema,error_msg",
        (
            ({}, None),
            ({"version": "v1"}, None),
            ({"version": "v2"}, "is not one of ['v1']"),
            (
                {"version": "v1", "final_message": -1},
                "is not of type 'string'",
            ),
            ({"version": "v1", "final_message": "some msg"}, None),
        ),
    )
    def test_versioned_cloud_config_schema_is_valid_json(
        self, schema, error_msg
    ):
        schema_dir = get_schema_dir()
        version_schemafile = os.path.join(
            schema_dir, VERSIONED_USERDATA_SCHEMA_FILE
        )
        # Point to local schema files avoid JSON resolver trying to pull the
        # reference from our upstream raw file in github.
        version_schema = json.loads(
            re.sub(
                r"https:\/\/raw.githubusercontent.com\/canonical\/"
                r"cloud-init\/main\/cloudinit\/config\/schemas\/",
                f"file://{schema_dir}/",
                load_text_file(version_schemafile),
            )
        )
        if error_msg:
>           with pytest.raises(SchemaValidationError) as context_mgr:
E           Failed: DID NOT RAISE <class 'cloudinit.config.schema.SchemaValidationError'>

tests/unittests/config/test_schema.py:148: Failed
------------------------------ Captured log call -------------------------------
2024-09-18 16:50:16 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/versions.schema.cloud-config.json (quiet=False)
2024-09-18 16:50:16 DEBUG     cloudinit.util:util.py:1622 Read 557 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/versions.schema.cloud-config.json
2024-09-18 16:50:16 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
_ TestMain.test_main_validates_config_file[None-#cloud-config\nntp:-Valid schema] _

self = <tests.unittests.config.test_schema.TestMain object at 0xffffb3f91130>
_netplan_available = <MagicMock name='available' id='281473671392496'>
_read_cfg_paths = <MagicMock name='read_cfg_paths' id='281473671395184'>
schema_type = None, content = b'#cloud-config\nntp:', expected = 'Valid schema'
tmpdir = local('/tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_config_fil0')
capsys = <_pytest.capture.CaptureFixture object at 0xffffb19d6200>
caplog = <_pytest.logging.LogCaptureFixture object at 0xffffb19d7000>

    @pytest.mark.parametrize(
        "schema_type,content,expected",
        (
            (None, b"#cloud-config\nntp:";, "Valid schema"),
            ("cloud-config", b"#cloud-config\nntp:";, "Valid schema"),
            (
                "network-config",
                (
                    b"network: {'version': 2, 'ethernets':"
                    b" {'eth0': {'dhcp': true}}}"
                ),
                "Valid schema",
            ),
            (
                "network-config",
                (
                    b"network:\n version: 1\n config:\n  - type: physical\n"
                    b"    name: eth0\n    subnets:\n      - type: dhcp\n"
                ),
                "Valid schema",
            ),
        ),
    )
    @mock.patch("cloudinit.net.netplan.available", return_value=False)
    def test_main_validates_config_file(
        self,
        _netplan_available,
        _read_cfg_paths,
        schema_type,
        content,
        expected,
        tmpdir,
        capsys,
        caplog,
    ):
        """When --config-file parameter is provided, main validates schema."""
        myyaml = tmpdir.join("my.yaml")
        myargs = ["mycmd", "--config-file", myyaml.strpath]
        if schema_type:
            myargs += ["--schema-type", schema_type]
        myyaml.write(content)  # shortest ntp schema
        with mock.patch("sys.argv", myargs):
            # Always assert we have no netplan module which triggers
            # schema skip of network-config version: 2 until cloud-init
            # grows internal schema-network-config-v2.json.
            with mock.patch.dict("sys.modules", netplan=ImportError()):
                assert 0 == main(), "Expected 0 exit code"
        out, _err = capsys.readouterr()
>       assert expected in out
E       AssertionError: assert 'Valid schema' in 'Skipping cloud-config schema validation. Jsonschema dependency missing.\n'

tests/unittests/config/test_schema.py:2010: AssertionError
------------------------------ Captured log call -------------------------------
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 150110 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_config_fil0/my.yaml (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 18 bytes from /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_config_fil0/my.yaml
2024-09-18 16:50:17 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
_ TestMain.test_main_validates_config_file[cloud-config-#cloud-config\nntp:-Valid schema] _

self = <tests.unittests.config.test_schema.TestMain object at 0xffffb3f91220>
_netplan_available = <MagicMock name='available' id='281473671688080'>
_read_cfg_paths = <MagicMock name='read_cfg_paths' id='281473671689424'>
schema_type = 'cloud-config', content = b'#cloud-config\nntp:'
expected = 'Valid schema'
tmpdir = local('/tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_config_fil1')
capsys = <_pytest.capture.CaptureFixture object at 0xffffb19d7a10>
caplog = <_pytest.logging.LogCaptureFixture object at 0xffffb166d710>

    @pytest.mark.parametrize(
        "schema_type,content,expected",
        (
            (None, b"#cloud-config\nntp:";, "Valid schema"),
            ("cloud-config", b"#cloud-config\nntp:";, "Valid schema"),
            (
                "network-config",
                (
                    b"network: {'version': 2, 'ethernets':"
                    b" {'eth0': {'dhcp': true}}}"
                ),
                "Valid schema",
            ),
            (
                "network-config",
                (
                    b"network:\n version: 1\n config:\n  - type: physical\n"
                    b"    name: eth0\n    subnets:\n      - type: dhcp\n"
                ),
                "Valid schema",
            ),
        ),
    )
    @mock.patch("cloudinit.net.netplan.available", return_value=False)
    def test_main_validates_config_file(
        self,
        _netplan_available,
        _read_cfg_paths,
        schema_type,
        content,
        expected,
        tmpdir,
        capsys,
        caplog,
    ):
        """When --config-file parameter is provided, main validates schema."""
        myyaml = tmpdir.join("my.yaml")
        myargs = ["mycmd", "--config-file", myyaml.strpath]
        if schema_type:
            myargs += ["--schema-type", schema_type]
        myyaml.write(content)  # shortest ntp schema
        with mock.patch("sys.argv", myargs):
            # Always assert we have no netplan module which triggers
            # schema skip of network-config version: 2 until cloud-init
            # grows internal schema-network-config-v2.json.
            with mock.patch.dict("sys.modules", netplan=ImportError()):
                assert 0 == main(), "Expected 0 exit code"
        out, _err = capsys.readouterr()
>       assert expected in out
E       AssertionError: assert 'Valid schema' in 'Skipping cloud-config schema validation. Jsonschema dependency missing.\n'

tests/unittests/config/test_schema.py:2010: AssertionError
------------------------------ Captured log call -------------------------------
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 150110 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_config_fil1/my.yaml (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 18 bytes from /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_config_fil1/my.yaml
2024-09-18 16:50:17 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
_ TestMain.test_main_validates_config_file[network-config-network: {'version': 2, 'ethernets': {'eth0': {'dhcp': true}}}-Valid schema] _

self = <tests.unittests.config.test_schema.TestMain object at 0xffffb3fd1a90>
_netplan_available = <MagicMock name='available' id='281473671689088'>
_read_cfg_paths = <MagicMock name='read_cfg_paths' id='281473671682704'>
schema_type = 'network-config'
content = b"network: {'version': 2, 'ethernets': {'eth0': {'dhcp': true}}}"
expected = 'Valid schema'
tmpdir = local('/tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_config_fil2')
capsys = <_pytest.capture.CaptureFixture object at 0xffffb166edd0>
caplog = <_pytest.logging.LogCaptureFixture object at 0xffffb166d2b0>

    @pytest.mark.parametrize(
        "schema_type,content,expected",
        (
            (None, b"#cloud-config\nntp:";, "Valid schema"),
            ("cloud-config", b"#cloud-config\nntp:";, "Valid schema"),
            (
                "network-config",
                (
                    b"network: {'version': 2, 'ethernets':"
                    b" {'eth0': {'dhcp': true}}}"
                ),
                "Valid schema",
            ),
            (
                "network-config",
                (
                    b"network:\n version: 1\n config:\n  - type: physical\n"
                    b"    name: eth0\n    subnets:\n      - type: dhcp\n"
                ),
                "Valid schema",
            ),
        ),
    )
    @mock.patch("cloudinit.net.netplan.available", return_value=False)
    def test_main_validates_config_file(
        self,
        _netplan_available,
        _read_cfg_paths,
        schema_type,
        content,
        expected,
        tmpdir,
        capsys,
        caplog,
    ):
        """When --config-file parameter is provided, main validates schema."""
        myyaml = tmpdir.join("my.yaml")
        myargs = ["mycmd", "--config-file", myyaml.strpath]
        if schema_type:
            myargs += ["--schema-type", schema_type]
        myyaml.write(content)  # shortest ntp schema
        with mock.patch("sys.argv", myargs):
            # Always assert we have no netplan module which triggers
            # schema skip of network-config version: 2 until cloud-init
            # grows internal schema-network-config-v2.json.
            with mock.patch.dict("sys.modules", netplan=ImportError()):
                assert 0 == main(), "Expected 0 exit code"
        out, _err = capsys.readouterr()
>       assert expected in out
E       AssertionError: assert 'Valid schema' in 'Skipping network-config-v2 schema validation. Jsonschema dependency missing.\n'

tests/unittests/config/test_schema.py:2010: AssertionError
------------------------------ Captured log call -------------------------------
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 150110 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-network-config-v2.json (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 17775 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-network-config-v2.json
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_config_fil2/my.yaml (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 62 bytes from /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_config_fil2/my.yaml
2024-09-18 16:50:17 DEBUG     cloudinit.config.schema:schema.py:632 Skipping netplan schema validation. No netplan API available
2024-09-18 16:50:17 DEBUG     cloudinit.config.schema:schema.py:632 Skipping netplan schema validation. No netplan API available
2024-09-18 16:50:17 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
_ TestMain.test_main_validates_config_file[network-config-network:\n version: 1\n config:\n  - type: physical\n    name: eth0\n    subnets:\n      - type: dhcp\n-Valid schema] _

self = <tests.unittests.config.test_schema.TestMain object at 0xffffb3fd26d0>
_netplan_available = <MagicMock name='available' id='281473671684384'>
_read_cfg_paths = <MagicMock name='read_cfg_paths' id='281473671689760'>
schema_type = 'network-config'
content = b'network:\n version: 1\n config:\n  - type: physical\n    name: eth0\n    subnets:\n      - type: dhcp\n'
expected = 'Valid schema'
tmpdir = local('/tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_config_fil3')
capsys = <_pytest.capture.CaptureFixture object at 0xffffb166ef90>
caplog = <_pytest.logging.LogCaptureFixture object at 0xffffb166ef20>

    @pytest.mark.parametrize(
        "schema_type,content,expected",
        (
            (None, b"#cloud-config\nntp:";, "Valid schema"),
            ("cloud-config", b"#cloud-config\nntp:";, "Valid schema"),
            (
                "network-config",
                (
                    b"network: {'version': 2, 'ethernets':"
                    b" {'eth0': {'dhcp': true}}}"
                ),
                "Valid schema",
            ),
            (
                "network-config",
                (
                    b"network:\n version: 1\n config:\n  - type: physical\n"
                    b"    name: eth0\n    subnets:\n      - type: dhcp\n"
                ),
                "Valid schema",
            ),
        ),
    )
    @mock.patch("cloudinit.net.netplan.available", return_value=False)
    def test_main_validates_config_file(
        self,
        _netplan_available,
        _read_cfg_paths,
        schema_type,
        content,
        expected,
        tmpdir,
        capsys,
        caplog,
    ):
        """When --config-file parameter is provided, main validates schema."""
        myyaml = tmpdir.join("my.yaml")
        myargs = ["mycmd", "--config-file", myyaml.strpath]
        if schema_type:
            myargs += ["--schema-type", schema_type]
        myyaml.write(content)  # shortest ntp schema
        with mock.patch("sys.argv", myargs):
            # Always assert we have no netplan module which triggers
            # schema skip of network-config version: 2 until cloud-init
            # grows internal schema-network-config-v2.json.
            with mock.patch.dict("sys.modules", netplan=ImportError()):
                assert 0 == main(), "Expected 0 exit code"
        out, _err = capsys.readouterr()
>       assert expected in out
E       AssertionError: assert 'Valid schema' in 'Skipping network-config-v1 schema validation. Jsonschema dependency missing.\n'

tests/unittests/config/test_schema.py:2010: AssertionError
------------------------------ Captured log call -------------------------------
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 150110 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-network-config-v2.json (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 17775 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-network-config-v2.json
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_config_fil3/my.yaml (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 96 bytes from /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_config_fil3/my.yaml
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-network-config-v1.json (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 21068 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-network-config-v1.json
2024-09-18 16:50:17 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
_ TestMain.test_main_processed_data_preference_over_raw_data[prefer_processed_data_when_present_and_non_empty] _

self = <tests.unittests.config.test_schema.TestMain object at 0xffffb4438390>
_read_cfg_paths = <MagicMock name='getuid' id='281473690719904'>
_getuid = <MagicMock name='read_cfg_paths' id='281473690716880'>
read_cfg_paths = <MagicMock name='read_cfg_paths' id='281473690729648'>
update_path_content_by_key = {}
expected_keys = {'net_key': 'network_config', 'ud_key': 'cloud_config', 'vd2_key': 'vendor2_cloud_config', 'vd_key': 'vendor_cloud_config'}
paths = <cloudinit.helpers.Paths object at 0xffffb20a4370>
capsys = <_pytest.capture.CaptureFixture object at 0xffffb166fbd0>

    @pytest.mark.parametrize(
        "update_path_content_by_key, expected_keys",
        (
            pytest.param(
                {},
                {
                    "ud_key": "cloud_config",
                    "vd_key": "vendor_cloud_config",
                    "vd2_key": "vendor2_cloud_config",
                    "net_key": "network_config",
                },
                id="prefer_processed_data_when_present_and_non_empty",
            ),
            pytest.param(
                {
                    "cloud_config": "",
                    "vendor_cloud_config": "",
                    "vendor2_cloud_config": "",
                },
                {
                    "ud_key": "userdata_raw",
                    "vd_key": "vendordata_raw",
                    "vd2_key": "vendordata2_raw",
                    "net_key": "network_config",
                },
                id="prefer_raw_data_when_processed_is_empty",
            ),
            pytest.param(
                {"cloud_config": "", "userdata_raw": ""},
                {
                    "ud_key": "cloud_config",
                    "vd_key": "vendor_cloud_config",
                    "vd2_key": "vendor2_cloud_config",
                    "net_key": "network_config",
                },
                id="prefer_processed_vd_file_path_when_raw_and_processed_empty",
            ),
        ),
    )
    @mock.patch(M_PATH + "read_cfg_paths")
    @mock.patch(M_PATH + "os.getuid", return_value=0)
    def test_main_processed_data_preference_over_raw_data(
        self,
        _read_cfg_paths,
        _getuid,
        read_cfg_paths,
        update_path_content_by_key,
        expected_keys,
        paths,
        capsys,
    ):
        paths.get_ipath = paths.get_ipath_cur
        read_cfg_paths.return_value = paths
        path_content_by_key = {
            "cloud_config": "#cloud-config\n{}",
            "vendor_cloud_config": "#cloud-config\n{}",
            "vendor2_cloud_config": "#cloud-config\n{}",
            "vendordata_raw": "#cloud-config\n{}",
            "vendordata2_raw": "#cloud-config\n{}",
            "network_config": "{version: 1, config: []}",
            "userdata_raw": "#cloud-config\n{}",
        }
        expected_paths = dict(
            (key, paths.get_ipath_cur(expected_keys[key]))
            for key in expected_keys
        )
        path_content_by_key.update(update_path_content_by_key)
        for path_key, path_content in path_content_by_key.items():
            write_file(paths.get_ipath_cur(path_key), path_content)
        data_types = "user-data, vendor-data, vendor2-data, network-config"
        ud_msg = "  Valid schema user-data"
        if (
            not path_content_by_key["cloud_config"]
            and not path_content_by_key["userdata_raw"]
        ):
            ud_msg = (
                f"Empty 'cloud-config' found at {expected_paths['ud_key']}."
                " Nothing to validate."
            )
    
        expected = dedent(
            f"""\
        Found cloud-config data types: {data_types}
    
        1. user-data at {expected_paths["ud_key"]}:
        {ud_msg}
    
        2. vendor-data at {expected_paths['vd_key']}:
          Valid schema vendor-data
    
        3. vendor2-data at {expected_paths['vd2_key']}:
          Valid schema vendor2-data
    
        4. network-config at {expected_paths['net_key']}:
          Valid schema network-config
        """
        )
        myargs = ["mycmd", "--system"]
        with mock.patch("sys.argv", myargs):
            main()
        out, _err = capsys.readouterr()
>       assert expected == out
E       AssertionError: assert 'Found cloud-...work-config\n' == 'Found cloud-...cy missing.\n'
E         
E           Found cloud-config data types: user-data, vendor-data, vendor2-data, network-config
E           
E           1. user-data at /tmp/pytest-of-debusine-worker/pytest-0/test_main_processed_data_prefe0/cloud_dir/instance/cloud-config.txt:
E         - Skipping cloud-config schema validation. Jsonschema dependency missing.
E         +   Valid schema user-data
E           ...
E         
E         ...Full output truncated (11 lines hidden), use '-vv' to show

tests/unittests/config/test_schema.py:2113: AssertionError
------------------------------ Captured log call -------------------------------
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:2345 Writing to /tmp/pytest-of-debusine-worker/pytest-0/test_main_processed_data_prefe0/cloud_dir/instance/cloud-config.txt - wb: [644] 16 bytes
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:2345 Writing to /tmp/pytest-of-debusine-worker/pytest-0/test_main_processed_data_prefe0/cloud_dir/instance/vendor-cloud-config.txt - wb: [644] 16 bytes
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:2345 Writing to /tmp/pytest-of-debusine-worker/pytest-0/test_main_processed_data_prefe0/cloud_dir/instance/vendor2-cloud-config.txt - wb: [644] 16 bytes
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:2345 Writing to /tmp/pytest-of-debusine-worker/pytest-0/test_main_processed_data_prefe0/cloud_dir/instance/vendor-data.txt - wb: [644] 16 bytes
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:2345 Writing to /tmp/pytest-of-debusine-worker/pytest-0/test_main_processed_data_prefe0/cloud_dir/instance/vendor-data2.txt - wb: [644] 16 bytes
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:2345 Writing to /tmp/pytest-of-debusine-worker/pytest-0/test_main_processed_data_prefe0/cloud_dir/instance/network-config.json - wb: [644] 24 bytes
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:2345 Writing to /tmp/pytest-of-debusine-worker/pytest-0/test_main_processed_data_prefe0/cloud_dir/instance/user-data.txt - wb: [644] 16 bytes
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 150110 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /tmp/pytest-of-debusine-worker/pytest-0/test_main_processed_data_prefe0/cloud_dir/instance/cloud-config.txt (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 16 bytes from /tmp/pytest-of-debusine-worker/pytest-0/test_main_processed_data_prefe0/cloud_dir/instance/cloud-config.txt
2024-09-18 16:50:17 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /tmp/pytest-of-debusine-worker/pytest-0/test_main_processed_data_prefe0/cloud_dir/instance/vendor-cloud-config.txt (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 16 bytes from /tmp/pytest-of-debusine-worker/pytest-0/test_main_processed_data_prefe0/cloud_dir/instance/vendor-cloud-config.txt
2024-09-18 16:50:17 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /tmp/pytest-of-debusine-worker/pytest-0/test_main_processed_data_prefe0/cloud_dir/instance/vendor2-cloud-config.txt (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 16 bytes from /tmp/pytest-of-debusine-worker/pytest-0/test_main_processed_data_prefe0/cloud_dir/instance/vendor2-cloud-config.txt
2024-09-18 16:50:17 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-network-config-v2.json (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 17775 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-network-config-v2.json
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /tmp/pytest-of-debusine-worker/pytest-0/test_main_processed_data_prefe0/cloud_dir/instance/network-config.json (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 24 bytes from /tmp/pytest-of-debusine-worker/pytest-0/test_main_processed_data_prefe0/cloud_dir/instance/network-config.json
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-network-config-v1.json (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 21068 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-network-config-v1.json
2024-09-18 16:50:17 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
_ TestMain.test_main_processed_data_preference_over_raw_data[prefer_raw_data_when_processed_is_empty] _

self = <tests.unittests.config.test_schema.TestMain object at 0xffffb3fd8f50>
_read_cfg_paths = <MagicMock name='getuid' id='281473670634128'>
_getuid = <MagicMock name='read_cfg_paths' id='281473670633792'>
read_cfg_paths = <MagicMock name='read_cfg_paths' id='281473670627744'>
update_path_content_by_key = {'cloud_config': '', 'vendor2_cloud_config': '', 'vendor_cloud_config': ''}
expected_keys = {'net_key': 'network_config', 'ud_key': 'userdata_raw', 'vd2_key': 'vendordata2_raw', 'vd_key': 'vendordata_raw'}
paths = <cloudinit.helpers.Paths object at 0xffffb1c5b750>
capsys = <_pytest.capture.CaptureFixture object at 0xffffb166db00>

    @pytest.mark.parametrize(
        "update_path_content_by_key, expected_keys",
        (
            pytest.param(
                {},
                {
                    "ud_key": "cloud_config",
                    "vd_key": "vendor_cloud_config",
                    "vd2_key": "vendor2_cloud_config",
                    "net_key": "network_config",
                },
                id="prefer_processed_data_when_present_and_non_empty",
            ),
            pytest.param(
                {
                    "cloud_config": "",
                    "vendor_cloud_config": "",
                    "vendor2_cloud_config": "",
                },
                {
                    "ud_key": "userdata_raw",
                    "vd_key": "vendordata_raw",
                    "vd2_key": "vendordata2_raw",
                    "net_key": "network_config",
                },
                id="prefer_raw_data_when_processed_is_empty",
            ),
            pytest.param(
                {"cloud_config": "", "userdata_raw": ""},
                {
                    "ud_key": "cloud_config",
                    "vd_key": "vendor_cloud_config",
                    "vd2_key": "vendor2_cloud_config",
                    "net_key": "network_config",
                },
                id="prefer_processed_vd_file_path_when_raw_and_processed_empty",
            ),
        ),
    )
    @mock.patch(M_PATH + "read_cfg_paths")
    @mock.patch(M_PATH + "os.getuid", return_value=0)
    def test_main_processed_data_preference_over_raw_data(
        self,
        _read_cfg_paths,
        _getuid,
        read_cfg_paths,
        update_path_content_by_key,
        expected_keys,
        paths,
        capsys,
    ):
        paths.get_ipath = paths.get_ipath_cur
        read_cfg_paths.return_value = paths
        path_content_by_key = {
            "cloud_config": "#cloud-config\n{}",
            "vendor_cloud_config": "#cloud-config\n{}",
            "vendor2_cloud_config": "#cloud-config\n{}",
            "vendordata_raw": "#cloud-config\n{}",
            "vendordata2_raw": "#cloud-config\n{}",
            "network_config": "{version: 1, config: []}",
            "userdata_raw": "#cloud-config\n{}",
        }
        expected_paths = dict(
            (key, paths.get_ipath_cur(expected_keys[key]))
            for key in expected_keys
        )
        path_content_by_key.update(update_path_content_by_key)
        for path_key, path_content in path_content_by_key.items():
            write_file(paths.get_ipath_cur(path_key), path_content)
        data_types = "user-data, vendor-data, vendor2-data, network-config"
        ud_msg = "  Valid schema user-data"
        if (
            not path_content_by_key["cloud_config"]
            and not path_content_by_key["userdata_raw"]
        ):
            ud_msg = (
                f"Empty 'cloud-config' found at {expected_paths['ud_key']}."
                " Nothing to validate."
            )
    
        expected = dedent(
            f"""\
        Found cloud-config data types: {data_types}
    
        1. user-data at {expected_paths["ud_key"]}:
        {ud_msg}
    
        2. vendor-data at {expected_paths['vd_key']}:
          Valid schema vendor-data
    
        3. vendor2-data at {expected_paths['vd2_key']}:
          Valid schema vendor2-data
    
        4. network-config at {expected_paths['net_key']}:
          Valid schema network-config
        """
        )
        myargs = ["mycmd", "--system"]
        with mock.patch("sys.argv", myargs):
            main()
        out, _err = capsys.readouterr()
>       assert expected == out
E       AssertionError: assert 'Found cloud-...work-config\n' == 'Found cloud-...cy missing.\n'
E         
E           Found cloud-config data types: user-data, vendor-data, vendor2-data, network-config
E           
E           1. user-data at /tmp/pytest-of-debusine-worker/pytest-0/test_main_processed_data_prefe1/cloud_dir/instance/user-data.txt:
E         - Skipping cloud-config schema validation. Jsonschema dependency missing.
E         +   Valid schema user-data
E           ...
E         
E         ...Full output truncated (11 lines hidden), use '-vv' to show

tests/unittests/config/test_schema.py:2113: AssertionError
------------------------------ Captured log call -------------------------------
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:2345 Writing to /tmp/pytest-of-debusine-worker/pytest-0/test_main_processed_data_prefe1/cloud_dir/instance/cloud-config.txt - wb: [644] 0 bytes
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:2345 Writing to /tmp/pytest-of-debusine-worker/pytest-0/test_main_processed_data_prefe1/cloud_dir/instance/vendor-cloud-config.txt - wb: [644] 0 bytes
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:2345 Writing to /tmp/pytest-of-debusine-worker/pytest-0/test_main_processed_data_prefe1/cloud_dir/instance/vendor2-cloud-config.txt - wb: [644] 0 bytes
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:2345 Writing to /tmp/pytest-of-debusine-worker/pytest-0/test_main_processed_data_prefe1/cloud_dir/instance/vendor-data.txt - wb: [644] 16 bytes
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:2345 Writing to /tmp/pytest-of-debusine-worker/pytest-0/test_main_processed_data_prefe1/cloud_dir/instance/vendor-data2.txt - wb: [644] 16 bytes
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:2345 Writing to /tmp/pytest-of-debusine-worker/pytest-0/test_main_processed_data_prefe1/cloud_dir/instance/network-config.json - wb: [644] 24 bytes
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:2345 Writing to /tmp/pytest-of-debusine-worker/pytest-0/test_main_processed_data_prefe1/cloud_dir/instance/user-data.txt - wb: [644] 16 bytes
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 150110 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /tmp/pytest-of-debusine-worker/pytest-0/test_main_processed_data_prefe1/cloud_dir/instance/user-data.txt (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 16 bytes from /tmp/pytest-of-debusine-worker/pytest-0/test_main_processed_data_prefe1/cloud_dir/instance/user-data.txt
2024-09-18 16:50:17 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /tmp/pytest-of-debusine-worker/pytest-0/test_main_processed_data_prefe1/cloud_dir/instance/vendor-data.txt (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 16 bytes from /tmp/pytest-of-debusine-worker/pytest-0/test_main_processed_data_prefe1/cloud_dir/instance/vendor-data.txt
2024-09-18 16:50:17 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /tmp/pytest-of-debusine-worker/pytest-0/test_main_processed_data_prefe1/cloud_dir/instance/vendor-data2.txt (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 16 bytes from /tmp/pytest-of-debusine-worker/pytest-0/test_main_processed_data_prefe1/cloud_dir/instance/vendor-data2.txt
2024-09-18 16:50:17 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-network-config-v2.json (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 17775 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-network-config-v2.json
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /tmp/pytest-of-debusine-worker/pytest-0/test_main_processed_data_prefe1/cloud_dir/instance/network-config.json (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 24 bytes from /tmp/pytest-of-debusine-worker/pytest-0/test_main_processed_data_prefe1/cloud_dir/instance/network-config.json
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-network-config-v1.json (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 21068 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-network-config-v1.json
2024-09-18 16:50:17 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
_ TestMain.test_main_processed_data_preference_over_raw_data[prefer_processed_vd_file_path_when_raw_and_processed_empty] _

self = <tests.unittests.config.test_schema.TestMain object at 0xffffb3fd9010>
_read_cfg_paths = <MagicMock name='getuid' id='281473670631104'>
_getuid = <MagicMock name='read_cfg_paths' id='281473670637152'>
read_cfg_paths = <MagicMock name='read_cfg_paths' id='281473670642192'>
update_path_content_by_key = {'cloud_config': '', 'userdata_raw': ''}
expected_keys = {'net_key': 'network_config', 'ud_key': 'cloud_config', 'vd2_key': 'vendor2_cloud_config', 'vd_key': 'vendor_cloud_config'}
paths = <cloudinit.helpers.Paths object at 0xffffb1ca04b0>
capsys = <_pytest.capture.CaptureFixture object at 0xffffb166def0>

    @pytest.mark.parametrize(
        "update_path_content_by_key, expected_keys",
        (
            pytest.param(
                {},
                {
                    "ud_key": "cloud_config",
                    "vd_key": "vendor_cloud_config",
                    "vd2_key": "vendor2_cloud_config",
                    "net_key": "network_config",
                },
                id="prefer_processed_data_when_present_and_non_empty",
            ),
            pytest.param(
                {
                    "cloud_config": "",
                    "vendor_cloud_config": "",
                    "vendor2_cloud_config": "",
                },
                {
                    "ud_key": "userdata_raw",
                    "vd_key": "vendordata_raw",
                    "vd2_key": "vendordata2_raw",
                    "net_key": "network_config",
                },
                id="prefer_raw_data_when_processed_is_empty",
            ),
            pytest.param(
                {"cloud_config": "", "userdata_raw": ""},
                {
                    "ud_key": "cloud_config",
                    "vd_key": "vendor_cloud_config",
                    "vd2_key": "vendor2_cloud_config",
                    "net_key": "network_config",
                },
                id="prefer_processed_vd_file_path_when_raw_and_processed_empty",
            ),
        ),
    )
    @mock.patch(M_PATH + "read_cfg_paths")
    @mock.patch(M_PATH + "os.getuid", return_value=0)
    def test_main_processed_data_preference_over_raw_data(
        self,
        _read_cfg_paths,
        _getuid,
        read_cfg_paths,
        update_path_content_by_key,
        expected_keys,
        paths,
        capsys,
    ):
        paths.get_ipath = paths.get_ipath_cur
        read_cfg_paths.return_value = paths
        path_content_by_key = {
            "cloud_config": "#cloud-config\n{}",
            "vendor_cloud_config": "#cloud-config\n{}",
            "vendor2_cloud_config": "#cloud-config\n{}",
            "vendordata_raw": "#cloud-config\n{}",
            "vendordata2_raw": "#cloud-config\n{}",
            "network_config": "{version: 1, config: []}",
            "userdata_raw": "#cloud-config\n{}",
        }
        expected_paths = dict(
            (key, paths.get_ipath_cur(expected_keys[key]))
            for key in expected_keys
        )
        path_content_by_key.update(update_path_content_by_key)
        for path_key, path_content in path_content_by_key.items():
            write_file(paths.get_ipath_cur(path_key), path_content)
        data_types = "user-data, vendor-data, vendor2-data, network-config"
        ud_msg = "  Valid schema user-data"
        if (
            not path_content_by_key["cloud_config"]
            and not path_content_by_key["userdata_raw"]
        ):
            ud_msg = (
                f"Empty 'cloud-config' found at {expected_paths['ud_key']}."
                " Nothing to validate."
            )
    
        expected = dedent(
            f"""\
        Found cloud-config data types: {data_types}
    
        1. user-data at {expected_paths["ud_key"]}:
        {ud_msg}
    
        2. vendor-data at {expected_paths['vd_key']}:
          Valid schema vendor-data
    
        3. vendor2-data at {expected_paths['vd2_key']}:
          Valid schema vendor2-data
    
        4. network-config at {expected_paths['net_key']}:
          Valid schema network-config
        """
        )
        myargs = ["mycmd", "--system"]
        with mock.patch("sys.argv", myargs):
            main()
        out, _err = capsys.readouterr()
>       assert expected == out
E       AssertionError: assert 'Found cloud-...work-config\n' == 'Found cloud-...cy missing.\n'
E         
E           Found cloud-config data types: user-data, vendor-data, vendor2-data, network-config
E           
E           1. user-data at /tmp/pytest-of-debusine-worker/pytest-0/test_main_processed_data_prefe2/cloud_dir/instance/cloud-config.txt:
E           Empty 'cloud-config' found at /tmp/pytest-of-debusine-worker/pytest-0/test_main_processed_data_prefe2/cloud_dir/instance/cloud-config.txt. Nothing to validate.
E           
E           2. vendor-data at /tmp/pytest-of-debusine-worker/pytest-0/test_main_processed_data_prefe2/cloud_dir/instance/vendor-cloud-config.txt:...
E         
E         ...Full output truncated (10 lines hidden), use '-vv' to show

tests/unittests/config/test_schema.py:2113: AssertionError
------------------------------ Captured log call -------------------------------
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:2345 Writing to /tmp/pytest-of-debusine-worker/pytest-0/test_main_processed_data_prefe2/cloud_dir/instance/cloud-config.txt - wb: [644] 0 bytes
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:2345 Writing to /tmp/pytest-of-debusine-worker/pytest-0/test_main_processed_data_prefe2/cloud_dir/instance/vendor-cloud-config.txt - wb: [644] 16 bytes
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:2345 Writing to /tmp/pytest-of-debusine-worker/pytest-0/test_main_processed_data_prefe2/cloud_dir/instance/vendor2-cloud-config.txt - wb: [644] 16 bytes
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:2345 Writing to /tmp/pytest-of-debusine-worker/pytest-0/test_main_processed_data_prefe2/cloud_dir/instance/vendor-data.txt - wb: [644] 16 bytes
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:2345 Writing to /tmp/pytest-of-debusine-worker/pytest-0/test_main_processed_data_prefe2/cloud_dir/instance/vendor-data2.txt - wb: [644] 16 bytes
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:2345 Writing to /tmp/pytest-of-debusine-worker/pytest-0/test_main_processed_data_prefe2/cloud_dir/instance/network-config.json - wb: [644] 24 bytes
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:2345 Writing to /tmp/pytest-of-debusine-worker/pytest-0/test_main_processed_data_prefe2/cloud_dir/instance/user-data.txt - wb: [644] 0 bytes
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 150110 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /tmp/pytest-of-debusine-worker/pytest-0/test_main_processed_data_prefe2/cloud_dir/instance/cloud-config.txt (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 0 bytes from /tmp/pytest-of-debusine-worker/pytest-0/test_main_processed_data_prefe2/cloud_dir/instance/cloud-config.txt
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /tmp/pytest-of-debusine-worker/pytest-0/test_main_processed_data_prefe2/cloud_dir/instance/vendor-cloud-config.txt (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 16 bytes from /tmp/pytest-of-debusine-worker/pytest-0/test_main_processed_data_prefe2/cloud_dir/instance/vendor-cloud-config.txt
2024-09-18 16:50:17 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /tmp/pytest-of-debusine-worker/pytest-0/test_main_processed_data_prefe2/cloud_dir/instance/vendor2-cloud-config.txt (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 16 bytes from /tmp/pytest-of-debusine-worker/pytest-0/test_main_processed_data_prefe2/cloud_dir/instance/vendor2-cloud-config.txt
2024-09-18 16:50:17 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-network-config-v2.json (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 17775 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-network-config-v2.json
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /tmp/pytest-of-debusine-worker/pytest-0/test_main_processed_data_prefe2/cloud_dir/instance/network-config.json (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 24 bytes from /tmp/pytest-of-debusine-worker/pytest-0/test_main_processed_data_prefe2/cloud_dir/instance/network-config.json
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-network-config-v1.json (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 21068 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-network-config-v1.json
2024-09-18 16:50:17 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
_ TestMain.test_main_validates_system_userdata_vendordata_and_network_config[netv1_schema_validated] _

self = <tests.unittests.config.test_schema.TestMain object at 0xffffb3fd5e90>
_netplan_available = <MagicMock name='available' id='281473670639168'>
_getuid = <MagicMock name='getuid' id='281473670636480'>
_read_cfg_paths = <MagicMock name='read_cfg_paths' id='281473670636816'>
read_cfg_paths = <MagicMock name='read_cfg_paths' id='281473670641856'>
net_config = 'network:\n version: 1\n config:\n  - type: physical\n    name: eth0\n    subnets:\n      - type: dhcp\n'
net_output = '  Valid schema network-config'
error_raised = <contextlib._GeneratorContextManager object at 0xffffb4643b60>
capsys = <_pytest.capture.CaptureFixture object at 0xffffb166da90>
mocker = <pytest_mock.plugin.MockerFixture object at 0xffffb16de340>
paths = <cloudinit.helpers.Paths object at 0xffffb197d6d0>

    @pytest.mark.parametrize(
        "net_config,net_output,error_raised",
        (
            pytest.param(
                "network:\n version: 1\n config:\n  - type: physical\n"
                "    name: eth0\n    subnets:\n      - type: dhcp\n",
                "  Valid schema network-config",
                does_not_raise(),
                id="netv1_schema_validated",
            ),
            pytest.param(
                "network:\n version: 2\n ethernets:\n  eth0:\n"
                "   dhcp4: true\n",
                "  Valid schema network-config",
                does_not_raise(),
                id="netv2_schema_validated_non_netplan",
            ),
            pytest.param(
                "network: {}\n",
                "Skipping network-config schema validation on empty config.",
                does_not_raise(),
                id="empty_net_validation_is_skipped",
            ),
            pytest.param(
                "network:\n version: 1\n config:\n  - type: physical\n"
                "   name: eth0\n    subnets:\n      - type: dhcp\n",
                "  Invalid network-config {network_file}",
                pytest.raises(SystemExit),
                id="netv1_schema_errors_handled",
            ),
            pytest.param(
                "network:\n version: 1\n config:\n  - type: physical\n"
                "    name: eth01234567890123\n    subnets:\n"
                "      - type: dhcp\n",
                "  Invalid network-config {network_file}",
                pytest.raises(SystemExit),
                id="netv1_schema_error_on_nic_name_length",
            ),
        ),
    )
    @mock.patch(M_PATH + "read_cfg_paths")
    @mock.patch(M_PATH + "os.getuid", return_value=0)
    @mock.patch("cloudinit.net.netplan.available", return_value=False)
    def test_main_validates_system_userdata_vendordata_and_network_config(
        self,
        _netplan_available,
        _getuid,
        _read_cfg_paths,
        read_cfg_paths,
        net_config,
        net_output,
        error_raised,
        capsys,
        mocker,
        paths,
    ):
        """When --system is provided, main validates all config userdata."""
        paths.get_ipath = paths.get_ipath_cur
        read_cfg_paths.return_value = paths
        cloud_config_file = paths.get_ipath_cur("cloud_config")
        write_file(cloud_config_file, b"#cloud-config\nntp:";)
        vd_file = paths.get_ipath_cur("vendor_cloud_config")
        write_file(vd_file, b"#cloud-config\nssh_import_id: [me]")
        vd2_file = paths.get_ipath_cur("vendor2_cloud_config")
        write_file(vd2_file, b"#cloud-config\nssh_pwauth: true")
        network_file = paths.get_ipath_cur("network_config")
        write_file(network_file, net_config)
        myargs = ["mycmd", "--system"]
        with error_raised:
            # Always assert we have no netplan module which triggers
            # schema skip of network-config version: 2 until cloud-init
            # grows internal schema-network-config-v2.json.
            with mock.patch.dict("sys.modules", netplan=ImportError()):
                with mock.patch("sys.argv", myargs):
                    main()
        out, _err = capsys.readouterr()
    
        net_output = net_output.format(network_file=network_file)
        data_types = "user-data, vendor-data, vendor2-data, network-config"
        expected = dedent(
            f"""\
        Found cloud-config data types: {data_types}
    
        1. user-data at {cloud_config_file}:
          Valid schema user-data
    
        2. vendor-data at {vd_file}:
          Valid schema vendor-data
    
        3. vendor2-data at {vd2_file}:
          Valid schema vendor2-data
    
        4. network-config at {network_file}:
        {net_output}
        """
        )
>       assert expected == out
E       AssertionError: assert 'Found cloud-...work-config\n' == 'Found cloud-...cy missing.\n'
E         
E           Found cloud-config data types: user-data, vendor-data, vendor2-data, network-config
E           
E           1. user-data at /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use0/cloud_dir/instance/cloud-config.txt:
E         - Skipping cloud-config schema validation. Jsonschema dependency missing.
E         +   Valid schema user-data
E           ...
E         
E         ...Full output truncated (11 lines hidden), use '-vv' to show

tests/unittests/config/test_schema.py:2211: AssertionError
------------------------------ Captured log call -------------------------------
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:2345 Writing to /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use0/cloud_dir/instance/cloud-config.txt - wb: [644] 18 bytes
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:2345 Writing to /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use0/cloud_dir/instance/vendor-cloud-config.txt - wb: [644] 33 bytes
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:2345 Writing to /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use0/cloud_dir/instance/vendor2-cloud-config.txt - wb: [644] 30 bytes
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:2345 Writing to /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use0/cloud_dir/instance/network-config.json - wb: [644] 96 bytes
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 150110 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use0/cloud_dir/instance/cloud-config.txt (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 18 bytes from /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use0/cloud_dir/instance/cloud-config.txt
2024-09-18 16:50:17 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use0/cloud_dir/instance/vendor-cloud-config.txt (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 33 bytes from /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use0/cloud_dir/instance/vendor-cloud-config.txt
2024-09-18 16:50:17 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use0/cloud_dir/instance/vendor2-cloud-config.txt (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 30 bytes from /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use0/cloud_dir/instance/vendor2-cloud-config.txt
2024-09-18 16:50:17 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-network-config-v2.json (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 17775 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-network-config-v2.json
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use0/cloud_dir/instance/network-config.json (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 96 bytes from /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use0/cloud_dir/instance/network-config.json
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-network-config-v1.json (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 21068 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-network-config-v1.json
2024-09-18 16:50:17 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
_ TestMain.test_main_validates_system_userdata_vendordata_and_network_config[netv2_schema_validated_non_netplan] _

self = <tests.unittests.config.test_schema.TestMain object at 0xffffb3fd4310>
_netplan_available = <MagicMock name='available' id='281473670631440'>
_getuid = <MagicMock name='getuid' id='281473670636144'>
_read_cfg_paths = <MagicMock name='read_cfg_paths' id='281473670629088'>
read_cfg_paths = <MagicMock name='read_cfg_paths' id='281473670628416'>
net_config = 'network:\n version: 2\n ethernets:\n  eth0:\n   dhcp4: true\n'
net_output = '  Valid schema network-config'
error_raised = <contextlib._GeneratorContextManager object at 0xffffb46438c0>
capsys = <_pytest.capture.CaptureFixture object at 0xffffb19d74d0>
mocker = <pytest_mock.plugin.MockerFixture object at 0xffffb1629570>
paths = <cloudinit.helpers.Paths object at 0xffffb197d450>

    @pytest.mark.parametrize(
        "net_config,net_output,error_raised",
        (
            pytest.param(
                "network:\n version: 1\n config:\n  - type: physical\n"
                "    name: eth0\n    subnets:\n      - type: dhcp\n",
                "  Valid schema network-config",
                does_not_raise(),
                id="netv1_schema_validated",
            ),
            pytest.param(
                "network:\n version: 2\n ethernets:\n  eth0:\n"
                "   dhcp4: true\n",
                "  Valid schema network-config",
                does_not_raise(),
                id="netv2_schema_validated_non_netplan",
            ),
            pytest.param(
                "network: {}\n",
                "Skipping network-config schema validation on empty config.",
                does_not_raise(),
                id="empty_net_validation_is_skipped",
            ),
            pytest.param(
                "network:\n version: 1\n config:\n  - type: physical\n"
                "   name: eth0\n    subnets:\n      - type: dhcp\n",
                "  Invalid network-config {network_file}",
                pytest.raises(SystemExit),
                id="netv1_schema_errors_handled",
            ),
            pytest.param(
                "network:\n version: 1\n config:\n  - type: physical\n"
                "    name: eth01234567890123\n    subnets:\n"
                "      - type: dhcp\n",
                "  Invalid network-config {network_file}",
                pytest.raises(SystemExit),
                id="netv1_schema_error_on_nic_name_length",
            ),
        ),
    )
    @mock.patch(M_PATH + "read_cfg_paths")
    @mock.patch(M_PATH + "os.getuid", return_value=0)
    @mock.patch("cloudinit.net.netplan.available", return_value=False)
    def test_main_validates_system_userdata_vendordata_and_network_config(
        self,
        _netplan_available,
        _getuid,
        _read_cfg_paths,
        read_cfg_paths,
        net_config,
        net_output,
        error_raised,
        capsys,
        mocker,
        paths,
    ):
        """When --system is provided, main validates all config userdata."""
        paths.get_ipath = paths.get_ipath_cur
        read_cfg_paths.return_value = paths
        cloud_config_file = paths.get_ipath_cur("cloud_config")
        write_file(cloud_config_file, b"#cloud-config\nntp:";)
        vd_file = paths.get_ipath_cur("vendor_cloud_config")
        write_file(vd_file, b"#cloud-config\nssh_import_id: [me]")
        vd2_file = paths.get_ipath_cur("vendor2_cloud_config")
        write_file(vd2_file, b"#cloud-config\nssh_pwauth: true")
        network_file = paths.get_ipath_cur("network_config")
        write_file(network_file, net_config)
        myargs = ["mycmd", "--system"]
        with error_raised:
            # Always assert we have no netplan module which triggers
            # schema skip of network-config version: 2 until cloud-init
            # grows internal schema-network-config-v2.json.
            with mock.patch.dict("sys.modules", netplan=ImportError()):
                with mock.patch("sys.argv", myargs):
                    main()
        out, _err = capsys.readouterr()
    
        net_output = net_output.format(network_file=network_file)
        data_types = "user-data, vendor-data, vendor2-data, network-config"
        expected = dedent(
            f"""\
        Found cloud-config data types: {data_types}
    
        1. user-data at {cloud_config_file}:
          Valid schema user-data
    
        2. vendor-data at {vd_file}:
          Valid schema vendor-data
    
        3. vendor2-data at {vd2_file}:
          Valid schema vendor2-data
    
        4. network-config at {network_file}:
        {net_output}
        """
        )
>       assert expected == out
E       AssertionError: assert 'Found cloud-...work-config\n' == 'Found cloud-...cy missing.\n'
E         
E           Found cloud-config data types: user-data, vendor-data, vendor2-data, network-config
E           
E           1. user-data at /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use1/cloud_dir/instance/cloud-config.txt:
E         - Skipping cloud-config schema validation. Jsonschema dependency missing.
E         +   Valid schema user-data
E           ...
E         
E         ...Full output truncated (11 lines hidden), use '-vv' to show

tests/unittests/config/test_schema.py:2211: AssertionError
------------------------------ Captured log call -------------------------------
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:2345 Writing to /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use1/cloud_dir/instance/cloud-config.txt - wb: [644] 18 bytes
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:2345 Writing to /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use1/cloud_dir/instance/vendor-cloud-config.txt - wb: [644] 33 bytes
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:2345 Writing to /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use1/cloud_dir/instance/vendor2-cloud-config.txt - wb: [644] 30 bytes
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:2345 Writing to /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use1/cloud_dir/instance/network-config.json - wb: [644] 56 bytes
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 150110 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use1/cloud_dir/instance/cloud-config.txt (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 18 bytes from /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use1/cloud_dir/instance/cloud-config.txt
2024-09-18 16:50:17 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use1/cloud_dir/instance/vendor-cloud-config.txt (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 33 bytes from /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use1/cloud_dir/instance/vendor-cloud-config.txt
2024-09-18 16:50:17 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use1/cloud_dir/instance/vendor2-cloud-config.txt (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 30 bytes from /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use1/cloud_dir/instance/vendor2-cloud-config.txt
2024-09-18 16:50:17 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-network-config-v2.json (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 17775 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-network-config-v2.json
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use1/cloud_dir/instance/network-config.json (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 56 bytes from /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use1/cloud_dir/instance/network-config.json
2024-09-18 16:50:17 DEBUG     cloudinit.config.schema:schema.py:632 Skipping netplan schema validation. No netplan API available
2024-09-18 16:50:17 DEBUG     cloudinit.config.schema:schema.py:632 Skipping netplan schema validation. No netplan API available
2024-09-18 16:50:17 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
_ TestMain.test_main_validates_system_userdata_vendordata_and_network_config[empty_net_validation_is_skipped] _

self = <tests.unittests.config.test_schema.TestMain object at 0xffffb3fee0d0>
_netplan_available = <MagicMock name='available' id='281473670638832'>
_getuid = <MagicMock name='getuid' id='281473670630768'>
_read_cfg_paths = <MagicMock name='read_cfg_paths' id='281473670629424'>
read_cfg_paths = <MagicMock name='read_cfg_paths' id='281473670629760'>
net_config = 'network: {}\n'
net_output = 'Skipping network-config schema validation on empty config.'
error_raised = <contextlib._GeneratorContextManager object at 0xffffb4643a10>
capsys = <_pytest.capture.CaptureFixture object at 0xffffb18932a0>
mocker = <pytest_mock.plugin.MockerFixture object at 0xffffb1629090>
paths = <cloudinit.helpers.Paths object at 0xffffb206c5f0>

    @pytest.mark.parametrize(
        "net_config,net_output,error_raised",
        (
            pytest.param(
                "network:\n version: 1\n config:\n  - type: physical\n"
                "    name: eth0\n    subnets:\n      - type: dhcp\n",
                "  Valid schema network-config",
                does_not_raise(),
                id="netv1_schema_validated",
            ),
            pytest.param(
                "network:\n version: 2\n ethernets:\n  eth0:\n"
                "   dhcp4: true\n",
                "  Valid schema network-config",
                does_not_raise(),
                id="netv2_schema_validated_non_netplan",
            ),
            pytest.param(
                "network: {}\n",
                "Skipping network-config schema validation on empty config.",
                does_not_raise(),
                id="empty_net_validation_is_skipped",
            ),
            pytest.param(
                "network:\n version: 1\n config:\n  - type: physical\n"
                "   name: eth0\n    subnets:\n      - type: dhcp\n",
                "  Invalid network-config {network_file}",
                pytest.raises(SystemExit),
                id="netv1_schema_errors_handled",
            ),
            pytest.param(
                "network:\n version: 1\n config:\n  - type: physical\n"
                "    name: eth01234567890123\n    subnets:\n"
                "      - type: dhcp\n",
                "  Invalid network-config {network_file}",
                pytest.raises(SystemExit),
                id="netv1_schema_error_on_nic_name_length",
            ),
        ),
    )
    @mock.patch(M_PATH + "read_cfg_paths")
    @mock.patch(M_PATH + "os.getuid", return_value=0)
    @mock.patch("cloudinit.net.netplan.available", return_value=False)
    def test_main_validates_system_userdata_vendordata_and_network_config(
        self,
        _netplan_available,
        _getuid,
        _read_cfg_paths,
        read_cfg_paths,
        net_config,
        net_output,
        error_raised,
        capsys,
        mocker,
        paths,
    ):
        """When --system is provided, main validates all config userdata."""
        paths.get_ipath = paths.get_ipath_cur
        read_cfg_paths.return_value = paths
        cloud_config_file = paths.get_ipath_cur("cloud_config")
        write_file(cloud_config_file, b"#cloud-config\nntp:";)
        vd_file = paths.get_ipath_cur("vendor_cloud_config")
        write_file(vd_file, b"#cloud-config\nssh_import_id: [me]")
        vd2_file = paths.get_ipath_cur("vendor2_cloud_config")
        write_file(vd2_file, b"#cloud-config\nssh_pwauth: true")
        network_file = paths.get_ipath_cur("network_config")
        write_file(network_file, net_config)
        myargs = ["mycmd", "--system"]
        with error_raised:
            # Always assert we have no netplan module which triggers
            # schema skip of network-config version: 2 until cloud-init
            # grows internal schema-network-config-v2.json.
            with mock.patch.dict("sys.modules", netplan=ImportError()):
                with mock.patch("sys.argv", myargs):
                    main()
        out, _err = capsys.readouterr()
    
        net_output = net_output.format(network_file=network_file)
        data_types = "user-data, vendor-data, vendor2-data, network-config"
        expected = dedent(
            f"""\
        Found cloud-config data types: {data_types}
    
        1. user-data at {cloud_config_file}:
          Valid schema user-data
    
        2. vendor-data at {vd_file}:
          Valid schema vendor-data
    
        3. vendor2-data at {vd2_file}:
          Valid schema vendor2-data
    
        4. network-config at {network_file}:
        {net_output}
        """
        )
>       assert expected == out
E       AssertionError: assert 'Found cloud-...pty config.\n' == 'Found cloud-...pty config.\n'
E         
E           Found cloud-config data types: user-data, vendor-data, vendor2-data, network-config
E           
E           1. user-data at /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use2/cloud_dir/instance/cloud-config.txt:
E         - Skipping cloud-config schema validation. Jsonschema dependency missing.
E         +   Valid schema user-data
E           ...
E         
E         ...Full output truncated (10 lines hidden), use '-vv' to show

tests/unittests/config/test_schema.py:2211: AssertionError
------------------------------ Captured log call -------------------------------
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:2345 Writing to /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use2/cloud_dir/instance/cloud-config.txt - wb: [644] 18 bytes
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:2345 Writing to /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use2/cloud_dir/instance/vendor-cloud-config.txt - wb: [644] 33 bytes
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:2345 Writing to /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use2/cloud_dir/instance/vendor2-cloud-config.txt - wb: [644] 30 bytes
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:2345 Writing to /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use2/cloud_dir/instance/network-config.json - wb: [644] 12 bytes
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 150110 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use2/cloud_dir/instance/cloud-config.txt (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 18 bytes from /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use2/cloud_dir/instance/cloud-config.txt
2024-09-18 16:50:17 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use2/cloud_dir/instance/vendor-cloud-config.txt (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 33 bytes from /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use2/cloud_dir/instance/vendor-cloud-config.txt
2024-09-18 16:50:17 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use2/cloud_dir/instance/vendor2-cloud-config.txt (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 30 bytes from /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use2/cloud_dir/instance/vendor2-cloud-config.txt
2024-09-18 16:50:17 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-network-config-v2.json (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 17775 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-network-config-v2.json
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use2/cloud_dir/instance/network-config.json (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 12 bytes from /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use2/cloud_dir/instance/network-config.json
_ TestMain.test_main_validates_system_userdata_vendordata_and_network_config[netv1_schema_errors_handled] _

self = <tests.unittests.config.test_schema.TestMain object at 0xffffb3fee530>
_netplan_available = <MagicMock name='available' id='281473670638496'>
_getuid = <MagicMock name='getuid' id='281473670633456'>
_read_cfg_paths = <MagicMock name='read_cfg_paths' id='281473670631776'>
read_cfg_paths = <MagicMock name='read_cfg_paths' id='281473672413264'>
net_config = 'network:\n version: 1\n config:\n  - type: physical\n   name: eth0\n    subnets:\n      - type: dhcp\n'
net_output = '  Invalid network-config /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use3/cloud_dir/instance/network-config.json'
error_raised = <_pytest.python_api.RaisesContext object at 0xffffb4643bd0>
capsys = <_pytest.capture.CaptureFixture object at 0xffffb1890670>
mocker = <pytest_mock.plugin.MockerFixture object at 0xffffb18f8600>
paths = <cloudinit.helpers.Paths object at 0xffffb2481810>

    @pytest.mark.parametrize(
        "net_config,net_output,error_raised",
        (
            pytest.param(
                "network:\n version: 1\n config:\n  - type: physical\n"
                "    name: eth0\n    subnets:\n      - type: dhcp\n",
                "  Valid schema network-config",
                does_not_raise(),
                id="netv1_schema_validated",
            ),
            pytest.param(
                "network:\n version: 2\n ethernets:\n  eth0:\n"
                "   dhcp4: true\n",
                "  Valid schema network-config",
                does_not_raise(),
                id="netv2_schema_validated_non_netplan",
            ),
            pytest.param(
                "network: {}\n",
                "Skipping network-config schema validation on empty config.",
                does_not_raise(),
                id="empty_net_validation_is_skipped",
            ),
            pytest.param(
                "network:\n version: 1\n config:\n  - type: physical\n"
                "   name: eth0\n    subnets:\n      - type: dhcp\n",
                "  Invalid network-config {network_file}",
                pytest.raises(SystemExit),
                id="netv1_schema_errors_handled",
            ),
            pytest.param(
                "network:\n version: 1\n config:\n  - type: physical\n"
                "    name: eth01234567890123\n    subnets:\n"
                "      - type: dhcp\n",
                "  Invalid network-config {network_file}",
                pytest.raises(SystemExit),
                id="netv1_schema_error_on_nic_name_length",
            ),
        ),
    )
    @mock.patch(M_PATH + "read_cfg_paths")
    @mock.patch(M_PATH + "os.getuid", return_value=0)
    @mock.patch("cloudinit.net.netplan.available", return_value=False)
    def test_main_validates_system_userdata_vendordata_and_network_config(
        self,
        _netplan_available,
        _getuid,
        _read_cfg_paths,
        read_cfg_paths,
        net_config,
        net_output,
        error_raised,
        capsys,
        mocker,
        paths,
    ):
        """When --system is provided, main validates all config userdata."""
        paths.get_ipath = paths.get_ipath_cur
        read_cfg_paths.return_value = paths
        cloud_config_file = paths.get_ipath_cur("cloud_config")
        write_file(cloud_config_file, b"#cloud-config\nntp:";)
        vd_file = paths.get_ipath_cur("vendor_cloud_config")
        write_file(vd_file, b"#cloud-config\nssh_import_id: [me]")
        vd2_file = paths.get_ipath_cur("vendor2_cloud_config")
        write_file(vd2_file, b"#cloud-config\nssh_pwauth: true")
        network_file = paths.get_ipath_cur("network_config")
        write_file(network_file, net_config)
        myargs = ["mycmd", "--system"]
        with error_raised:
            # Always assert we have no netplan module which triggers
            # schema skip of network-config version: 2 until cloud-init
            # grows internal schema-network-config-v2.json.
            with mock.patch.dict("sys.modules", netplan=ImportError()):
                with mock.patch("sys.argv", myargs):
                    main()
        out, _err = capsys.readouterr()
    
        net_output = net_output.format(network_file=network_file)
        data_types = "user-data, vendor-data, vendor2-data, network-config"
        expected = dedent(
            f"""\
        Found cloud-config data types: {data_types}
    
        1. user-data at {cloud_config_file}:
          Valid schema user-data
    
        2. vendor-data at {vd_file}:
          Valid schema vendor-data
    
        3. vendor2-data at {vd2_file}:
          Valid schema vendor2-data
    
        4. network-config at {network_file}:
        {net_output}
        """
        )
>       assert expected == out
E       AssertionError: assert 'Found cloud-...config.json\n' == 'Found cloud-...config.json\n'
E         
E           Found cloud-config data types: user-data, vendor-data, vendor2-data, network-config
E           
E           1. user-data at /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use3/cloud_dir/instance/cloud-config.txt:
E         - Skipping cloud-config schema validation. Jsonschema dependency missing.
E         +   Valid schema user-data
E           ...
E         
E         ...Full output truncated (10 lines hidden), use '-vv' to show

tests/unittests/config/test_schema.py:2211: AssertionError
------------------------------ Captured log call -------------------------------
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:2345 Writing to /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use3/cloud_dir/instance/cloud-config.txt - wb: [644] 18 bytes
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:2345 Writing to /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use3/cloud_dir/instance/vendor-cloud-config.txt - wb: [644] 33 bytes
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:2345 Writing to /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use3/cloud_dir/instance/vendor2-cloud-config.txt - wb: [644] 30 bytes
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:2345 Writing to /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use3/cloud_dir/instance/network-config.json - wb: [644] 95 bytes
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 150110 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use3/cloud_dir/instance/cloud-config.txt (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 18 bytes from /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use3/cloud_dir/instance/cloud-config.txt
2024-09-18 16:50:17 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use3/cloud_dir/instance/vendor-cloud-config.txt (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 33 bytes from /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use3/cloud_dir/instance/vendor-cloud-config.txt
2024-09-18 16:50:17 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use3/cloud_dir/instance/vendor2-cloud-config.txt (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 30 bytes from /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use3/cloud_dir/instance/vendor2-cloud-config.txt
2024-09-18 16:50:17 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-network-config-v2.json (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 17775 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-network-config-v2.json
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use3/cloud_dir/instance/network-config.json (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 95 bytes from /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use3/cloud_dir/instance/network-config.json
_ TestMain.test_main_validates_system_userdata_vendordata_and_network_config[netv1_schema_error_on_nic_name_length] _

self = <tests.unittests.config.test_schema.TestMain object at 0xffffb44fe840>
_netplan_available = <MagicMock name='available' id='281473672425696'>
_getuid = <MagicMock name='getuid' id='281473672935616'>
_read_cfg_paths = <MagicMock name='read_cfg_paths' id='281473672933264'>
read_cfg_paths = <MagicMock name='read_cfg_paths' id='281473672925872'>
net_config = 'network:\n version: 1\n config:\n  - type: physical\n    name: eth01234567890123\n    subnets:\n      - type: dhcp\n'
net_output = '  Invalid network-config {network_file}'
error_raised = <_pytest.python_api.RaisesContext object at 0xffffb46ec050>
capsys = <_pytest.capture.CaptureFixture object at 0xffffb18906e0>
mocker = <pytest_mock.plugin.MockerFixture object at 0xffffb1629a50>
paths = <cloudinit.helpers.Paths object at 0xffffb24df930>

    @pytest.mark.parametrize(
        "net_config,net_output,error_raised",
        (
            pytest.param(
                "network:\n version: 1\n config:\n  - type: physical\n"
                "    name: eth0\n    subnets:\n      - type: dhcp\n",
                "  Valid schema network-config",
                does_not_raise(),
                id="netv1_schema_validated",
            ),
            pytest.param(
                "network:\n version: 2\n ethernets:\n  eth0:\n"
                "   dhcp4: true\n",
                "  Valid schema network-config",
                does_not_raise(),
                id="netv2_schema_validated_non_netplan",
            ),
            pytest.param(
                "network: {}\n",
                "Skipping network-config schema validation on empty config.",
                does_not_raise(),
                id="empty_net_validation_is_skipped",
            ),
            pytest.param(
                "network:\n version: 1\n config:\n  - type: physical\n"
                "   name: eth0\n    subnets:\n      - type: dhcp\n",
                "  Invalid network-config {network_file}",
                pytest.raises(SystemExit),
                id="netv1_schema_errors_handled",
            ),
            pytest.param(
                "network:\n version: 1\n config:\n  - type: physical\n"
                "    name: eth01234567890123\n    subnets:\n"
                "      - type: dhcp\n",
                "  Invalid network-config {network_file}",
                pytest.raises(SystemExit),
                id="netv1_schema_error_on_nic_name_length",
            ),
        ),
    )
    @mock.patch(M_PATH + "read_cfg_paths")
    @mock.patch(M_PATH + "os.getuid", return_value=0)
    @mock.patch("cloudinit.net.netplan.available", return_value=False)
    def test_main_validates_system_userdata_vendordata_and_network_config(
        self,
        _netplan_available,
        _getuid,
        _read_cfg_paths,
        read_cfg_paths,
        net_config,
        net_output,
        error_raised,
        capsys,
        mocker,
        paths,
    ):
        """When --system is provided, main validates all config userdata."""
        paths.get_ipath = paths.get_ipath_cur
        read_cfg_paths.return_value = paths
        cloud_config_file = paths.get_ipath_cur("cloud_config")
        write_file(cloud_config_file, b"#cloud-config\nntp:";)
        vd_file = paths.get_ipath_cur("vendor_cloud_config")
        write_file(vd_file, b"#cloud-config\nssh_import_id: [me]")
        vd2_file = paths.get_ipath_cur("vendor2_cloud_config")
        write_file(vd2_file, b"#cloud-config\nssh_pwauth: true")
        network_file = paths.get_ipath_cur("network_config")
        write_file(network_file, net_config)
        myargs = ["mycmd", "--system"]
>       with error_raised:
E       Failed: DID NOT RAISE <class 'SystemExit'>

tests/unittests/config/test_schema.py:2183: Failed
----------------------------- Captured stdout call -----------------------------
Found cloud-config data types: user-data, vendor-data, vendor2-data, network-config

1. user-data at /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use4/cloud_dir/instance/cloud-config.txt:
Skipping cloud-config schema validation. Jsonschema dependency missing.

2. vendor-data at /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use4/cloud_dir/instance/vendor-cloud-config.txt:
Skipping cloud-config schema validation. Jsonschema dependency missing.

3. vendor2-data at /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use4/cloud_dir/instance/vendor2-cloud-config.txt:
Skipping cloud-config schema validation. Jsonschema dependency missing.

4. network-config at /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use4/cloud_dir/instance/network-config.json:
Skipping network-config-v1 schema validation. Jsonschema dependency missing.
------------------------------ Captured log call -------------------------------
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:2345 Writing to /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use4/cloud_dir/instance/cloud-config.txt - wb: [644] 18 bytes
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:2345 Writing to /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use4/cloud_dir/instance/vendor-cloud-config.txt - wb: [644] 33 bytes
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:2345 Writing to /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use4/cloud_dir/instance/vendor2-cloud-config.txt - wb: [644] 30 bytes
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:2345 Writing to /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use4/cloud_dir/instance/network-config.json - wb: [644] 109 bytes
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 150110 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use4/cloud_dir/instance/cloud-config.txt (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 18 bytes from /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use4/cloud_dir/instance/cloud-config.txt
2024-09-18 16:50:17 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use4/cloud_dir/instance/vendor-cloud-config.txt (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 33 bytes from /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use4/cloud_dir/instance/vendor-cloud-config.txt
2024-09-18 16:50:17 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use4/cloud_dir/instance/vendor2-cloud-config.txt (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 30 bytes from /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use4/cloud_dir/instance/vendor2-cloud-config.txt
2024-09-18 16:50:17 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-network-config-v2.json (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 17775 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-network-config-v2.json
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use4/cloud_dir/instance/network-config.json (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 109 bytes from /tmp/pytest-of-debusine-worker/pytest-0/test_main_validates_system_use4/cloud_dir/instance/network-config.json
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-network-config-v1.json (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 21068 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-network-config-v1.json
2024-09-18 16:50:17 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
_________ TestNetworkSchema.test_network_schema[net_v2_invalid_config] _________

self = <tests.unittests.config.test_schema.TestNetworkSchema object at 0xffffb46e74d0>
_netplan_available = <MagicMock name='available' id='281473693803792'>
src_config = {'network': {'config': [], 'version': 2}}
schema_type_version = <SchemaType.NETWORK_CONFIG_V2: 'network-config-v2'>
expectation = <_pytest.python_api.RaisesContext object at 0xffffb46ee200>
log = '', caplog = <_pytest.logging.LogCaptureFixture object at 0xffffb2ab64a0>

    @pytest.mark.parametrize(
        "src_config, schema_type_version, expectation, log",
        (
            pytest.param(
                {"network": {"config": [], "version": 2}},
                SchemaType.NETWORK_CONFIG_V2,
                pytest.raises(
                    SchemaValidationError,
                    match=re.escape(
                        "Additional properties are not allowed ('config' was "
                        "unexpected)"
                    ),
                ),
                "",
                id="net_v2_invalid_config",
            ),
            pytest.param(
                {
                    "network": {
                        "version": 2,
                        "ethernets": {"eno1": {"dhcp4": True}},
                    }
                },
                SchemaType.NETWORK_CONFIG_V2,
                does_not_raise(),
                "",
                id="net_v2_simple_example",
            ),
            pytest.param(
                {
                    "version": 2,
                    "ethernets": {"eno1": {"dhcp4": True}},
                },
                SchemaType.NETWORK_CONFIG_V2,
                does_not_raise(),
                "",
                id="net_v2_no_top_level",
            ),
            pytest.param(
                {
                    "network": {
                        "version": 2,
                        "ethernets": {
                            "id0": {
                                "match": {
                                    "macaddress": "00:11:22:33:44:55",
                                },
                                "wakeonlan": True,
                                "dhcp4": True,
                                "addresses": [
                                    "192.168.14.2/24",
                                    "2001:1::1/64",
                                ],
                                "gateway4": "192.168.14.1",
                                "gateway6": "2001:1::2",
                                "nameservers": {
                                    "search": ["foo.local", "bar.local"],
                                    "addresses": ["8.8.8.8"],
                                },
                                "routes": [
                                    {
                                        "to": "192.0.2.0/24",
                                        "via": "11.0.0.1",
                                        "metric": 3,
                                    },
                                ],
                            },
                            "lom": {
                                "match": {"driver": "ixgbe"},
                                "set-name": "lom1",
                                "dhcp6": True,
                            },
                            "switchports": {
                                "match": {"name": "enp2*"},
                                "mtu": 1280,
                            },
                        },
                        "bonds": {
                            "bond0": {"interfaces": ["id0", "lom"]},
                        },
                        "bridges": {
                            "br0": {
                                "interfaces": ["wlp1s0", "switchports"],
                                "dhcp4": True,
                            },
                        },
                        "vlans": {
                            "en-intra": {
                                "id": 1,
                                "link": "id0",
                                "dhcp4": "yes",
                            },
                        },
                    }
                },
                SchemaType.NETWORK_CONFIG_V2,
                does_not_raise(),
                "",
                id="net_v2_complex_example",
            ),
            pytest.param(
                {"network": {"version": 1}},
                SchemaType.NETWORK_CONFIG_V1,
                pytest.raises(
                    SchemaValidationError,
                    match=re.escape("'config' is a required property"),
                ),
                "",
                id="config_key_required",
            ),
            pytest.param(
                {"network": {"version": 1, "config": []}},
                SchemaType.NETWORK_CONFIG_V1,
                does_not_raise(),
                "",
                id="config_key_required",
            ),
            pytest.param(
                {
                    "network": {
                        "version": 1,
                        "config": [{"name": "me", "type": "typo"}],
                    }
                },
                SchemaType.NETWORK_CONFIG_V1,
                pytest.raises(
                    SchemaValidationError,
                    match=(
                        r"network.config.0: {'name': 'me', 'type': 'typo'} is"
                        " not valid under any of the given schemas"
                    ),
                ),
                "",
                id="unknown_config_type_item",
            ),
            pytest.param(
                {"network": {"version": 1, "config": [{"type": "physical"}]}},
                SchemaType.NETWORK_CONFIG_V1,
                pytest.raises(
                    SchemaValidationError,
                    match=r"network.config.0: 'name' is a required property.*",
                ),
                "",
                id="physical_requires_name_property",
            ),
            pytest.param(
                {
                    "network": {
                        "version": 1,
                        "config": [{"type": "physical", "name": "a"}],
                    }
                },
                SchemaType.NETWORK_CONFIG_V1,
                does_not_raise(),
                "",
                id="physical_with_name_succeeds",
            ),
            pytest.param(
                {
                    "network": {
                        "version": 1,
                        "config": [
                            {"type": "physical", "name": "a", "asdf": 1}
                        ],
                    }
                },
                SchemaType.NETWORK_CONFIG_V1,
                pytest.raises(
                    SchemaValidationError,
                    match=r"Additional properties are not allowed.*",
                ),
                "",
                id="physical_no_additional_properties",
            ),
            pytest.param(
                {
                    "network": {
                        "version": 1,
                        "config": [VALID_PHYSICAL_CONFIG],
                    }
                },
                SchemaType.NETWORK_CONFIG_V1,
                does_not_raise(),
                "",
                id="physical_with_all_known_properties",
            ),
            pytest.param(
                {
                    "network": {
                        "version": 1,
                        "config": [VALID_BOND_CONFIG],
                    }
                },
                SchemaType.NETWORK_CONFIG_V1,
                does_not_raise(),
                "",
                id="bond_with_all_known_properties",
            ),
            pytest.param(
                {
                    "network": {
                        "version": 1,
                        "config": [
                            {"type": "physical", "name": "eth0", "mtu": None},
                            {"type": "nameserver", "address": "8.8.8.8"},
                        ],
                    }
                },
                SchemaType.NETWORK_CONFIG_V1,
                does_not_raise(),
                "",
                id="GH-4710_mtu_none_and_str_address",
            ),
        ),
    )
    @mock.patch("cloudinit.net.netplan.available", return_value=False)
    def test_network_schema(
        self,
        _netplan_available,
        src_config,
        schema_type_version,
        expectation,
        log,
        caplog,
    ):
        net_schema = get_schema(schema_type=schema_type_version)
>       with expectation:
E       Failed: DID NOT RAISE <class 'cloudinit.config.schema.SchemaValidationError'>

tests/unittests/config/test_schema.py:2564: Failed
------------------------------ Captured log call -------------------------------
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-network-config-v2.json (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 17775 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-network-config-v2.json
2024-09-18 16:50:17 DEBUG     cloudinit.config.schema:schema.py:632 Skipping netplan schema validation. No netplan API available
2024-09-18 16:50:17 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
_________ TestNetworkSchema.test_network_schema[config_key_required0] __________

self = <tests.unittests.config.test_schema.TestNetworkSchema object at 0xffffb453fe30>
_netplan_available = <MagicMock name='available' id='281473674745840'>
src_config = {'network': {'version': 1}}
schema_type_version = <SchemaType.NETWORK_CONFIG_V1: 'network-config-v1'>
expectation = <_pytest.python_api.RaisesContext object at 0xffffb46ee430>
log = '', caplog = <_pytest.logging.LogCaptureFixture object at 0xffffb2232820>

    @pytest.mark.parametrize(
        "src_config, schema_type_version, expectation, log",
        (
            pytest.param(
                {"network": {"config": [], "version": 2}},
                SchemaType.NETWORK_CONFIG_V2,
                pytest.raises(
                    SchemaValidationError,
                    match=re.escape(
                        "Additional properties are not allowed ('config' was "
                        "unexpected)"
                    ),
                ),
                "",
                id="net_v2_invalid_config",
            ),
            pytest.param(
                {
                    "network": {
                        "version": 2,
                        "ethernets": {"eno1": {"dhcp4": True}},
                    }
                },
                SchemaType.NETWORK_CONFIG_V2,
                does_not_raise(),
                "",
                id="net_v2_simple_example",
            ),
            pytest.param(
                {
                    "version": 2,
                    "ethernets": {"eno1": {"dhcp4": True}},
                },
                SchemaType.NETWORK_CONFIG_V2,
                does_not_raise(),
                "",
                id="net_v2_no_top_level",
            ),
            pytest.param(
                {
                    "network": {
                        "version": 2,
                        "ethernets": {
                            "id0": {
                                "match": {
                                    "macaddress": "00:11:22:33:44:55",
                                },
                                "wakeonlan": True,
                                "dhcp4": True,
                                "addresses": [
                                    "192.168.14.2/24",
                                    "2001:1::1/64",
                                ],
                                "gateway4": "192.168.14.1",
                                "gateway6": "2001:1::2",
                                "nameservers": {
                                    "search": ["foo.local", "bar.local"],
                                    "addresses": ["8.8.8.8"],
                                },
                                "routes": [
                                    {
                                        "to": "192.0.2.0/24",
                                        "via": "11.0.0.1",
                                        "metric": 3,
                                    },
                                ],
                            },
                            "lom": {
                                "match": {"driver": "ixgbe"},
                                "set-name": "lom1",
                                "dhcp6": True,
                            },
                            "switchports": {
                                "match": {"name": "enp2*"},
                                "mtu": 1280,
                            },
                        },
                        "bonds": {
                            "bond0": {"interfaces": ["id0", "lom"]},
                        },
                        "bridges": {
                            "br0": {
                                "interfaces": ["wlp1s0", "switchports"],
                                "dhcp4": True,
                            },
                        },
                        "vlans": {
                            "en-intra": {
                                "id": 1,
                                "link": "id0",
                                "dhcp4": "yes",
                            },
                        },
                    }
                },
                SchemaType.NETWORK_CONFIG_V2,
                does_not_raise(),
                "",
                id="net_v2_complex_example",
            ),
            pytest.param(
                {"network": {"version": 1}},
                SchemaType.NETWORK_CONFIG_V1,
                pytest.raises(
                    SchemaValidationError,
                    match=re.escape("'config' is a required property"),
                ),
                "",
                id="config_key_required",
            ),
            pytest.param(
                {"network": {"version": 1, "config": []}},
                SchemaType.NETWORK_CONFIG_V1,
                does_not_raise(),
                "",
                id="config_key_required",
            ),
            pytest.param(
                {
                    "network": {
                        "version": 1,
                        "config": [{"name": "me", "type": "typo"}],
                    }
                },
                SchemaType.NETWORK_CONFIG_V1,
                pytest.raises(
                    SchemaValidationError,
                    match=(
                        r"network.config.0: {'name': 'me', 'type': 'typo'} is"
                        " not valid under any of the given schemas"
                    ),
                ),
                "",
                id="unknown_config_type_item",
            ),
            pytest.param(
                {"network": {"version": 1, "config": [{"type": "physical"}]}},
                SchemaType.NETWORK_CONFIG_V1,
                pytest.raises(
                    SchemaValidationError,
                    match=r"network.config.0: 'name' is a required property.*",
                ),
                "",
                id="physical_requires_name_property",
            ),
            pytest.param(
                {
                    "network": {
                        "version": 1,
                        "config": [{"type": "physical", "name": "a"}],
                    }
                },
                SchemaType.NETWORK_CONFIG_V1,
                does_not_raise(),
                "",
                id="physical_with_name_succeeds",
            ),
            pytest.param(
                {
                    "network": {
                        "version": 1,
                        "config": [
                            {"type": "physical", "name": "a", "asdf": 1}
                        ],
                    }
                },
                SchemaType.NETWORK_CONFIG_V1,
                pytest.raises(
                    SchemaValidationError,
                    match=r"Additional properties are not allowed.*",
                ),
                "",
                id="physical_no_additional_properties",
            ),
            pytest.param(
                {
                    "network": {
                        "version": 1,
                        "config": [VALID_PHYSICAL_CONFIG],
                    }
                },
                SchemaType.NETWORK_CONFIG_V1,
                does_not_raise(),
                "",
                id="physical_with_all_known_properties",
            ),
            pytest.param(
                {
                    "network": {
                        "version": 1,
                        "config": [VALID_BOND_CONFIG],
                    }
                },
                SchemaType.NETWORK_CONFIG_V1,
                does_not_raise(),
                "",
                id="bond_with_all_known_properties",
            ),
            pytest.param(
                {
                    "network": {
                        "version": 1,
                        "config": [
                            {"type": "physical", "name": "eth0", "mtu": None},
                            {"type": "nameserver", "address": "8.8.8.8"},
                        ],
                    }
                },
                SchemaType.NETWORK_CONFIG_V1,
                does_not_raise(),
                "",
                id="GH-4710_mtu_none_and_str_address",
            ),
        ),
    )
    @mock.patch("cloudinit.net.netplan.available", return_value=False)
    def test_network_schema(
        self,
        _netplan_available,
        src_config,
        schema_type_version,
        expectation,
        log,
        caplog,
    ):
        net_schema = get_schema(schema_type=schema_type_version)
>       with expectation:
E       Failed: DID NOT RAISE <class 'cloudinit.config.schema.SchemaValidationError'>

tests/unittests/config/test_schema.py:2564: Failed
------------------------------ Captured log call -------------------------------
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-network-config-v1.json (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 21068 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-network-config-v1.json
2024-09-18 16:50:17 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
_______ TestNetworkSchema.test_network_schema[unknown_config_type_item] ________

self = <tests.unittests.config.test_schema.TestNetworkSchema object at 0xffffb3fa47c0>
_netplan_available = <MagicMock name='available' id='281473671385440'>
src_config = {'network': {'config': [{'name': 'me', 'type': 'typo'}], 'version': 1}}
schema_type_version = <SchemaType.NETWORK_CONFIG_V1: 'network-config-v1'>
expectation = <_pytest.python_api.RaisesContext object at 0xffffb46ee580>
log = '', caplog = <_pytest.logging.LogCaptureFixture object at 0xffffb18133f0>

    @pytest.mark.parametrize(
        "src_config, schema_type_version, expectation, log",
        (
            pytest.param(
                {"network": {"config": [], "version": 2}},
                SchemaType.NETWORK_CONFIG_V2,
                pytest.raises(
                    SchemaValidationError,
                    match=re.escape(
                        "Additional properties are not allowed ('config' was "
                        "unexpected)"
                    ),
                ),
                "",
                id="net_v2_invalid_config",
            ),
            pytest.param(
                {
                    "network": {
                        "version": 2,
                        "ethernets": {"eno1": {"dhcp4": True}},
                    }
                },
                SchemaType.NETWORK_CONFIG_V2,
                does_not_raise(),
                "",
                id="net_v2_simple_example",
            ),
            pytest.param(
                {
                    "version": 2,
                    "ethernets": {"eno1": {"dhcp4": True}},
                },
                SchemaType.NETWORK_CONFIG_V2,
                does_not_raise(),
                "",
                id="net_v2_no_top_level",
            ),
            pytest.param(
                {
                    "network": {
                        "version": 2,
                        "ethernets": {
                            "id0": {
                                "match": {
                                    "macaddress": "00:11:22:33:44:55",
                                },
                                "wakeonlan": True,
                                "dhcp4": True,
                                "addresses": [
                                    "192.168.14.2/24",
                                    "2001:1::1/64",
                                ],
                                "gateway4": "192.168.14.1",
                                "gateway6": "2001:1::2",
                                "nameservers": {
                                    "search": ["foo.local", "bar.local"],
                                    "addresses": ["8.8.8.8"],
                                },
                                "routes": [
                                    {
                                        "to": "192.0.2.0/24",
                                        "via": "11.0.0.1",
                                        "metric": 3,
                                    },
                                ],
                            },
                            "lom": {
                                "match": {"driver": "ixgbe"},
                                "set-name": "lom1",
                                "dhcp6": True,
                            },
                            "switchports": {
                                "match": {"name": "enp2*"},
                                "mtu": 1280,
                            },
                        },
                        "bonds": {
                            "bond0": {"interfaces": ["id0", "lom"]},
                        },
                        "bridges": {
                            "br0": {
                                "interfaces": ["wlp1s0", "switchports"],
                                "dhcp4": True,
                            },
                        },
                        "vlans": {
                            "en-intra": {
                                "id": 1,
                                "link": "id0",
                                "dhcp4": "yes",
                            },
                        },
                    }
                },
                SchemaType.NETWORK_CONFIG_V2,
                does_not_raise(),
                "",
                id="net_v2_complex_example",
            ),
            pytest.param(
                {"network": {"version": 1}},
                SchemaType.NETWORK_CONFIG_V1,
                pytest.raises(
                    SchemaValidationError,
                    match=re.escape("'config' is a required property"),
                ),
                "",
                id="config_key_required",
            ),
            pytest.param(
                {"network": {"version": 1, "config": []}},
                SchemaType.NETWORK_CONFIG_V1,
                does_not_raise(),
                "",
                id="config_key_required",
            ),
            pytest.param(
                {
                    "network": {
                        "version": 1,
                        "config": [{"name": "me", "type": "typo"}],
                    }
                },
                SchemaType.NETWORK_CONFIG_V1,
                pytest.raises(
                    SchemaValidationError,
                    match=(
                        r"network.config.0: {'name': 'me', 'type': 'typo'} is"
                        " not valid under any of the given schemas"
                    ),
                ),
                "",
                id="unknown_config_type_item",
            ),
            pytest.param(
                {"network": {"version": 1, "config": [{"type": "physical"}]}},
                SchemaType.NETWORK_CONFIG_V1,
                pytest.raises(
                    SchemaValidationError,
                    match=r"network.config.0: 'name' is a required property.*",
                ),
                "",
                id="physical_requires_name_property",
            ),
            pytest.param(
                {
                    "network": {
                        "version": 1,
                        "config": [{"type": "physical", "name": "a"}],
                    }
                },
                SchemaType.NETWORK_CONFIG_V1,
                does_not_raise(),
                "",
                id="physical_with_name_succeeds",
            ),
            pytest.param(
                {
                    "network": {
                        "version": 1,
                        "config": [
                            {"type": "physical", "name": "a", "asdf": 1}
                        ],
                    }
                },
                SchemaType.NETWORK_CONFIG_V1,
                pytest.raises(
                    SchemaValidationError,
                    match=r"Additional properties are not allowed.*",
                ),
                "",
                id="physical_no_additional_properties",
            ),
            pytest.param(
                {
                    "network": {
                        "version": 1,
                        "config": [VALID_PHYSICAL_CONFIG],
                    }
                },
                SchemaType.NETWORK_CONFIG_V1,
                does_not_raise(),
                "",
                id="physical_with_all_known_properties",
            ),
            pytest.param(
                {
                    "network": {
                        "version": 1,
                        "config": [VALID_BOND_CONFIG],
                    }
                },
                SchemaType.NETWORK_CONFIG_V1,
                does_not_raise(),
                "",
                id="bond_with_all_known_properties",
            ),
            pytest.param(
                {
                    "network": {
                        "version": 1,
                        "config": [
                            {"type": "physical", "name": "eth0", "mtu": None},
                            {"type": "nameserver", "address": "8.8.8.8"},
                        ],
                    }
                },
                SchemaType.NETWORK_CONFIG_V1,
                does_not_raise(),
                "",
                id="GH-4710_mtu_none_and_str_address",
            ),
        ),
    )
    @mock.patch("cloudinit.net.netplan.available", return_value=False)
    def test_network_schema(
        self,
        _netplan_available,
        src_config,
        schema_type_version,
        expectation,
        log,
        caplog,
    ):
        net_schema = get_schema(schema_type=schema_type_version)
>       with expectation:
E       Failed: DID NOT RAISE <class 'cloudinit.config.schema.SchemaValidationError'>

tests/unittests/config/test_schema.py:2564: Failed
------------------------------ Captured log call -------------------------------
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-network-config-v1.json (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 21068 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-network-config-v1.json
2024-09-18 16:50:17 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
____ TestNetworkSchema.test_network_schema[physical_requires_name_property] ____

self = <tests.unittests.config.test_schema.TestNetworkSchema object at 0xffffb46fef50>
_netplan_available = <MagicMock name='available' id='281473694073248'>
src_config = {'network': {'config': [{'type': 'physical'}], 'version': 1}}
schema_type_version = <SchemaType.NETWORK_CONFIG_V1: 'network-config-v1'>
expectation = <_pytest.python_api.RaisesContext object at 0xffffb46ee660>
log = '', caplog = <_pytest.logging.LogCaptureFixture object at 0xffffb18cb460>

    @pytest.mark.parametrize(
        "src_config, schema_type_version, expectation, log",
        (
            pytest.param(
                {"network": {"config": [], "version": 2}},
                SchemaType.NETWORK_CONFIG_V2,
                pytest.raises(
                    SchemaValidationError,
                    match=re.escape(
                        "Additional properties are not allowed ('config' was "
                        "unexpected)"
                    ),
                ),
                "",
                id="net_v2_invalid_config",
            ),
            pytest.param(
                {
                    "network": {
                        "version": 2,
                        "ethernets": {"eno1": {"dhcp4": True}},
                    }
                },
                SchemaType.NETWORK_CONFIG_V2,
                does_not_raise(),
                "",
                id="net_v2_simple_example",
            ),
            pytest.param(
                {
                    "version": 2,
                    "ethernets": {"eno1": {"dhcp4": True}},
                },
                SchemaType.NETWORK_CONFIG_V2,
                does_not_raise(),
                "",
                id="net_v2_no_top_level",
            ),
            pytest.param(
                {
                    "network": {
                        "version": 2,
                        "ethernets": {
                            "id0": {
                                "match": {
                                    "macaddress": "00:11:22:33:44:55",
                                },
                                "wakeonlan": True,
                                "dhcp4": True,
                                "addresses": [
                                    "192.168.14.2/24",
                                    "2001:1::1/64",
                                ],
                                "gateway4": "192.168.14.1",
                                "gateway6": "2001:1::2",
                                "nameservers": {
                                    "search": ["foo.local", "bar.local"],
                                    "addresses": ["8.8.8.8"],
                                },
                                "routes": [
                                    {
                                        "to": "192.0.2.0/24",
                                        "via": "11.0.0.1",
                                        "metric": 3,
                                    },
                                ],
                            },
                            "lom": {
                                "match": {"driver": "ixgbe"},
                                "set-name": "lom1",
                                "dhcp6": True,
                            },
                            "switchports": {
                                "match": {"name": "enp2*"},
                                "mtu": 1280,
                            },
                        },
                        "bonds": {
                            "bond0": {"interfaces": ["id0", "lom"]},
                        },
                        "bridges": {
                            "br0": {
                                "interfaces": ["wlp1s0", "switchports"],
                                "dhcp4": True,
                            },
                        },
                        "vlans": {
                            "en-intra": {
                                "id": 1,
                                "link": "id0",
                                "dhcp4": "yes",
                            },
                        },
                    }
                },
                SchemaType.NETWORK_CONFIG_V2,
                does_not_raise(),
                "",
                id="net_v2_complex_example",
            ),
            pytest.param(
                {"network": {"version": 1}},
                SchemaType.NETWORK_CONFIG_V1,
                pytest.raises(
                    SchemaValidationError,
                    match=re.escape("'config' is a required property"),
                ),
                "",
                id="config_key_required",
            ),
            pytest.param(
                {"network": {"version": 1, "config": []}},
                SchemaType.NETWORK_CONFIG_V1,
                does_not_raise(),
                "",
                id="config_key_required",
            ),
            pytest.param(
                {
                    "network": {
                        "version": 1,
                        "config": [{"name": "me", "type": "typo"}],
                    }
                },
                SchemaType.NETWORK_CONFIG_V1,
                pytest.raises(
                    SchemaValidationError,
                    match=(
                        r"network.config.0: {'name': 'me', 'type': 'typo'} is"
                        " not valid under any of the given schemas"
                    ),
                ),
                "",
                id="unknown_config_type_item",
            ),
            pytest.param(
                {"network": {"version": 1, "config": [{"type": "physical"}]}},
                SchemaType.NETWORK_CONFIG_V1,
                pytest.raises(
                    SchemaValidationError,
                    match=r"network.config.0: 'name' is a required property.*",
                ),
                "",
                id="physical_requires_name_property",
            ),
            pytest.param(
                {
                    "network": {
                        "version": 1,
                        "config": [{"type": "physical", "name": "a"}],
                    }
                },
                SchemaType.NETWORK_CONFIG_V1,
                does_not_raise(),
                "",
                id="physical_with_name_succeeds",
            ),
            pytest.param(
                {
                    "network": {
                        "version": 1,
                        "config": [
                            {"type": "physical", "name": "a", "asdf": 1}
                        ],
                    }
                },
                SchemaType.NETWORK_CONFIG_V1,
                pytest.raises(
                    SchemaValidationError,
                    match=r"Additional properties are not allowed.*",
                ),
                "",
                id="physical_no_additional_properties",
            ),
            pytest.param(
                {
                    "network": {
                        "version": 1,
                        "config": [VALID_PHYSICAL_CONFIG],
                    }
                },
                SchemaType.NETWORK_CONFIG_V1,
                does_not_raise(),
                "",
                id="physical_with_all_known_properties",
            ),
            pytest.param(
                {
                    "network": {
                        "version": 1,
                        "config": [VALID_BOND_CONFIG],
                    }
                },
                SchemaType.NETWORK_CONFIG_V1,
                does_not_raise(),
                "",
                id="bond_with_all_known_properties",
            ),
            pytest.param(
                {
                    "network": {
                        "version": 1,
                        "config": [
                            {"type": "physical", "name": "eth0", "mtu": None},
                            {"type": "nameserver", "address": "8.8.8.8"},
                        ],
                    }
                },
                SchemaType.NETWORK_CONFIG_V1,
                does_not_raise(),
                "",
                id="GH-4710_mtu_none_and_str_address",
            ),
        ),
    )
    @mock.patch("cloudinit.net.netplan.available", return_value=False)
    def test_network_schema(
        self,
        _netplan_available,
        src_config,
        schema_type_version,
        expectation,
        log,
        caplog,
    ):
        net_schema = get_schema(schema_type=schema_type_version)
>       with expectation:
E       Failed: DID NOT RAISE <class 'cloudinit.config.schema.SchemaValidationError'>

tests/unittests/config/test_schema.py:2564: Failed
------------------------------ Captured log call -------------------------------
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-network-config-v1.json (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 21068 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-network-config-v1.json
2024-09-18 16:50:17 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
___ TestNetworkSchema.test_network_schema[physical_no_additional_properties] ___

self = <tests.unittests.config.test_schema.TestNetworkSchema object at 0xffffb3f92c60>
_netplan_available = <MagicMock name='available' id='281473694076944'>
src_config = {'network': {'config': [{'asdf': 1, 'name': 'a', 'type': 'physical'}], 'version': 1}}
schema_type_version = <SchemaType.NETWORK_CONFIG_V1: 'network-config-v1'>
expectation = <_pytest.python_api.RaisesContext object at 0xffffb46ee7b0>
log = '', caplog = <_pytest.logging.LogCaptureFixture object at 0xffffb18ca3c0>

    @pytest.mark.parametrize(
        "src_config, schema_type_version, expectation, log",
        (
            pytest.param(
                {"network": {"config": [], "version": 2}},
                SchemaType.NETWORK_CONFIG_V2,
                pytest.raises(
                    SchemaValidationError,
                    match=re.escape(
                        "Additional properties are not allowed ('config' was "
                        "unexpected)"
                    ),
                ),
                "",
                id="net_v2_invalid_config",
            ),
            pytest.param(
                {
                    "network": {
                        "version": 2,
                        "ethernets": {"eno1": {"dhcp4": True}},
                    }
                },
                SchemaType.NETWORK_CONFIG_V2,
                does_not_raise(),
                "",
                id="net_v2_simple_example",
            ),
            pytest.param(
                {
                    "version": 2,
                    "ethernets": {"eno1": {"dhcp4": True}},
                },
                SchemaType.NETWORK_CONFIG_V2,
                does_not_raise(),
                "",
                id="net_v2_no_top_level",
            ),
            pytest.param(
                {
                    "network": {
                        "version": 2,
                        "ethernets": {
                            "id0": {
                                "match": {
                                    "macaddress": "00:11:22:33:44:55",
                                },
                                "wakeonlan": True,
                                "dhcp4": True,
                                "addresses": [
                                    "192.168.14.2/24",
                                    "2001:1::1/64",
                                ],
                                "gateway4": "192.168.14.1",
                                "gateway6": "2001:1::2",
                                "nameservers": {
                                    "search": ["foo.local", "bar.local"],
                                    "addresses": ["8.8.8.8"],
                                },
                                "routes": [
                                    {
                                        "to": "192.0.2.0/24",
                                        "via": "11.0.0.1",
                                        "metric": 3,
                                    },
                                ],
                            },
                            "lom": {
                                "match": {"driver": "ixgbe"},
                                "set-name": "lom1",
                                "dhcp6": True,
                            },
                            "switchports": {
                                "match": {"name": "enp2*"},
                                "mtu": 1280,
                            },
                        },
                        "bonds": {
                            "bond0": {"interfaces": ["id0", "lom"]},
                        },
                        "bridges": {
                            "br0": {
                                "interfaces": ["wlp1s0", "switchports"],
                                "dhcp4": True,
                            },
                        },
                        "vlans": {
                            "en-intra": {
                                "id": 1,
                                "link": "id0",
                                "dhcp4": "yes",
                            },
                        },
                    }
                },
                SchemaType.NETWORK_CONFIG_V2,
                does_not_raise(),
                "",
                id="net_v2_complex_example",
            ),
            pytest.param(
                {"network": {"version": 1}},
                SchemaType.NETWORK_CONFIG_V1,
                pytest.raises(
                    SchemaValidationError,
                    match=re.escape("'config' is a required property"),
                ),
                "",
                id="config_key_required",
            ),
            pytest.param(
                {"network": {"version": 1, "config": []}},
                SchemaType.NETWORK_CONFIG_V1,
                does_not_raise(),
                "",
                id="config_key_required",
            ),
            pytest.param(
                {
                    "network": {
                        "version": 1,
                        "config": [{"name": "me", "type": "typo"}],
                    }
                },
                SchemaType.NETWORK_CONFIG_V1,
                pytest.raises(
                    SchemaValidationError,
                    match=(
                        r"network.config.0: {'name': 'me', 'type': 'typo'} is"
                        " not valid under any of the given schemas"
                    ),
                ),
                "",
                id="unknown_config_type_item",
            ),
            pytest.param(
                {"network": {"version": 1, "config": [{"type": "physical"}]}},
                SchemaType.NETWORK_CONFIG_V1,
                pytest.raises(
                    SchemaValidationError,
                    match=r"network.config.0: 'name' is a required property.*",
                ),
                "",
                id="physical_requires_name_property",
            ),
            pytest.param(
                {
                    "network": {
                        "version": 1,
                        "config": [{"type": "physical", "name": "a"}],
                    }
                },
                SchemaType.NETWORK_CONFIG_V1,
                does_not_raise(),
                "",
                id="physical_with_name_succeeds",
            ),
            pytest.param(
                {
                    "network": {
                        "version": 1,
                        "config": [
                            {"type": "physical", "name": "a", "asdf": 1}
                        ],
                    }
                },
                SchemaType.NETWORK_CONFIG_V1,
                pytest.raises(
                    SchemaValidationError,
                    match=r"Additional properties are not allowed.*",
                ),
                "",
                id="physical_no_additional_properties",
            ),
            pytest.param(
                {
                    "network": {
                        "version": 1,
                        "config": [VALID_PHYSICAL_CONFIG],
                    }
                },
                SchemaType.NETWORK_CONFIG_V1,
                does_not_raise(),
                "",
                id="physical_with_all_known_properties",
            ),
            pytest.param(
                {
                    "network": {
                        "version": 1,
                        "config": [VALID_BOND_CONFIG],
                    }
                },
                SchemaType.NETWORK_CONFIG_V1,
                does_not_raise(),
                "",
                id="bond_with_all_known_properties",
            ),
            pytest.param(
                {
                    "network": {
                        "version": 1,
                        "config": [
                            {"type": "physical", "name": "eth0", "mtu": None},
                            {"type": "nameserver", "address": "8.8.8.8"},
                        ],
                    }
                },
                SchemaType.NETWORK_CONFIG_V1,
                does_not_raise(),
                "",
                id="GH-4710_mtu_none_and_str_address",
            ),
        ),
    )
    @mock.patch("cloudinit.net.netplan.available", return_value=False)
    def test_network_schema(
        self,
        _netplan_available,
        src_config,
        schema_type_version,
        expectation,
        log,
        caplog,
    ):
        net_schema = get_schema(schema_type=schema_type_version)
>       with expectation:
E       Failed: DID NOT RAISE <class 'cloudinit.config.schema.SchemaValidationError'>

tests/unittests/config/test_schema.py:2564: Failed
------------------------------ Captured log call -------------------------------
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-network-config-v1.json (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 21068 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-network-config-v1.json
2024-09-18 16:50:17 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
_ TestHandleSchemaArgs.test_handle_schema_unable_to_read_cfg_paths[failure0-expected_logs0] _

self = <tests.unittests.config.test_schema.TestHandleSchemaArgs object at 0xffffb46e7c50>
read_cfg_paths = <MagicMock name='read_cfg_paths' id='281473694082320'>
failure = OSError('No permissions on /var/lib/cloud/instance')
expected_logs = ['Using default instance-data/user-data paths for non-root']
paths = <cloudinit.helpers.Paths object at 0xffffb20a7bb0>
capsys = <_pytest.capture.CaptureFixture object at 0xffffb18c94e0>
caplog = <_pytest.logging.LogCaptureFixture object at 0xffffb1933d90>
tmpdir = local('/tmp/pytest-of-debusine-worker/pytest-0/test_handle_schema_unable_to_r0')

    @pytest.mark.parametrize(
        "failure, expected_logs",
        (
            (
                IOError("No permissions on /var/lib/cloud/instance"),
                ["Using default instance-data/user-data paths for non-root"],
            ),
            (
                DataSourceNotFoundException("No cached datasource found yet"),
                ["datasource not detected"],
            ),
        ),
    )
    @mock.patch(M_PATH + "read_cfg_paths")
    def test_handle_schema_unable_to_read_cfg_paths(
        self,
        read_cfg_paths,
        failure,
        expected_logs,
        paths,
        capsys,
        caplog,
        tmpdir,
    ):
        if isinstance(failure, IOError):
            failure.errno = EACCES
        read_cfg_paths.side_effect = [failure, paths]
        user_data_fn = tmpdir.join("user-data")
        with open(user_data_fn, "w") as f:
            f.write(
                dedent(
                    """\
                    #cloud-config
                    packages: [sl]
                    """
                )
            )
        args = self.Args(
            config_file=str(user_data_fn),
            schema_type="cloud-config",
            annotate=False,
            docs=None,
            system=None,
            instance_data=None,
        )
        handle_schema_args("unused", args)
>       assert "Valid schema" in capsys.readouterr().out
E       AssertionError: assert 'Valid schema' in 'Skipping cloud-config schema validation. Jsonschema dependency missing.\n'
E        +  where 'Skipping cloud-config schema validation. Jsonschema dependency missing.\n' = CaptureResult(out='Skipping cloud-config schema validation. Jsonschema dependency missing.\n', err='').out
E        +    where CaptureResult(out='Skipping cloud-config schema validation. Jsonschema dependency missing.\n', err='') = readouterr()
E        +      where readouterr = <_pytest.capture.CaptureFixture object at 0xffffb18c94e0>.readouterr

tests/unittests/config/test_schema.py:2734: AssertionError
------------------------------ Captured log call -------------------------------
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 150110 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json
2024-09-18 16:50:17 DEBUG     cloudinit.config.schema:schema.py:1782 Using default instance-data/user-data paths for non-root user
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1613 Reading from /tmp/pytest-of-debusine-worker/pytest-0/test_handle_schema_unable_to_r0/user-data (quiet=False)
2024-09-18 16:50:17 DEBUG     cloudinit.util:util.py:1622 Read 29 bytes from /tmp/pytest-of-debusine-worker/pytest-0/test_handle_schema_unable_to_r0/user-data
2024-09-18 16:50:17 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
_ TestHandleSchemaArgs.test_handle_schema_unable_to_read_cfg_paths[failure1-expected_logs1] _

self = <tests.unittests.config.test_schema.TestHandleSchemaArgs object at 0xffffb46e7d90>
read_cfg_paths = <MagicMock name='read_cfg_paths' id='281473671073136'>
failure = DataSourceNotFoundException('No cached datasource found yet')
expected_logs = ['datasource not detected']
paths = <cloudinit.helpers.Paths object at 0xffffb1b9eb70>
capsys = <_pytest.capture.CaptureFixture object at 0xffffb19aee40>
caplog = <_pytest.logging.LogCaptureFixture object at 0xffffb19ac210>
tmpdir = local('/tmp/pytest-of-debusine-worker/pytest-0/test_handle_schema_unable_to_r1')

    @pytest.mark.parametrize(
        "failure, expected_logs",
        (
            (
                IOError("No permissions on /var/lib/cloud/instance"),
                ["Using default instance-data/user-data paths for non-root"],
            ),
            (
                DataSourceNotFoundException("No cached datasource found yet"),
                ["datasource not detected"],
            ),
        ),
    )
    @mock.patch(M_PATH + "read_cfg_paths")
    def test_handle_schema_unable_to_read_cfg_paths(
        self,
        read_cfg_paths,
        failure,
        expected_logs,
        paths,
        capsys,
        caplog,
        tmpdir,
    ):
        if isinstance(failure, IOError):
            failure.errno = EACCES
        read_cfg_paths.side_effect = [failure, paths]
        user_data_fn = tmpdir.join("user-data")
        with open(user_data_fn, "w") as f:
            f.write(
                dedent(
                    """\
                    #cloud-config
                    packages: [sl]
                    """
                )
            )
        args = self.Args(
            config_file=str(user_data_fn),
            schema_type="cloud-config",
            annotate=False,
            docs=None,
            system=None,
            instance_data=None,
        )
        handle_schema_args("unused", args)
>       assert "Valid schema" in capsys.readouterr().out
E       AssertionError: assert 'Valid schema' in 'Skipping cloud-config schema validation. Jsonschema dependency missing.\n'
E        +  where 'Skipping cloud-config schema validation. Jsonschema dependency missing.\n' = CaptureResult(out='Skipping cloud-config schema validation. Jsonschema dependency missing.\n', err='').out
E        +    where CaptureResult(out='Skipping cloud-config schema validation. Jsonschema dependency missing.\n', err='') = readouterr()
E        +      where readouterr = <_pytest.capture.CaptureFixture object at 0xffffb19aee40>.readouterr

tests/unittests/config/test_schema.py:2734: AssertionError
------------------------------ Captured log call -------------------------------
2024-09-18 16:50:18 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json (quiet=False)
2024-09-18 16:50:18 DEBUG     cloudinit.util:util.py:1622 Read 150110 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json
2024-09-18 16:50:18 WARNING   cloudinit.config.schema:schema.py:1790 datasource not detected, using default instance-data/user-data paths.
2024-09-18 16:50:18 DEBUG     cloudinit.util:util.py:1613 Reading from /tmp/pytest-of-debusine-worker/pytest-0/test_handle_schema_unable_to_r1/user-data (quiet=False)
2024-09-18 16:50:18 DEBUG     cloudinit.util:util.py:1622 Read 29 bytes from /tmp/pytest-of-debusine-worker/pytest-0/test_handle_schema_unable_to_r1/user-data
2024-09-18 16:50:18 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
_ TestHandleSchemaArgs.test_handle_schema_args_annotate_deprecated_config[test_annotated_deprecation_info_boundary_devel_shows] _

self = <tests.unittests.config.test_schema.TestHandleSchemaArgs object at 0xffffb3ff4b00>
read_cfg_paths = <MagicMock name='read_cfg_paths' id='281473669246528'>
annotate = True, deprecation_info_boundary = 'devel'
expected_output = '#cloud-config\npackages:\n- htop\napt_update: true                # D1\napt_upgrade: true               # D2\napt_reb...* instead.\n# D3: Deprecated in version 22.2. Use **package_reboot_if_required** instead.\n\nValid schema {cfg_file}\n'
paths = <cloudinit.helpers.Paths object at 0xffffb1b79770>
caplog = <_pytest.logging.LogCaptureFixture object at 0xffffb19ad400>
capsys = <_pytest.capture.CaptureFixture object at 0xffffb19adfd0>
tmpdir = local('/tmp/pytest-of-debusine-worker/pytest-0/test_handle_schema_args_annota0')
mocker = <pytest_mock.plugin.MockerFixture object at 0xffffb1b765b0>

        @pytest.mark.parametrize(
            "annotate, deprecation_info_boundary, expected_output",
            [
                pytest.param(
                    True,
                    "devel",
                    dedent(
                        """\
                        #cloud-config
                        packages:
                        - htop
                        apt_update: true                # D1
                        apt_upgrade: true               # D2
                        apt_reboot_if_required: true            # D3
    
                        # Deprecations: -------------
                        # D1: Deprecated in version 22.2. Use **package_update** instead.
                        # D2: Deprecated in version 22.2. Use **package_upgrade** instead.
                        # D3: Deprecated in version 22.2. Use **package_reboot_if_required** instead.
    
                        Valid schema {cfg_file}
                        """  # noqa: E501
                    ),
                    id="test_annotated_deprecation_info_boundary_devel_shows",
                ),
                pytest.param(
                    True,
                    "22.1",
                    dedent(
                        """\
                        #cloud-config
                        packages:
                        - htop
                        apt_update: true                # D1
                        apt_upgrade: true               # D2
                        apt_reboot_if_required: true            # D3
    
                        # Deprecations: -------------
                        # D1: Deprecated in version 22.2. Use **package_update** instead.
                        # D2: Deprecated in version 22.2. Use **package_upgrade** instead.
                        # D3: Deprecated in version 22.2. Use **package_reboot_if_required** instead.
    
                        Valid schema {cfg_file}
                        """  # noqa: E501
                    ),
                    id="test_annotated_deprecation_info_boundary_below_unredacted",
                ),
                pytest.param(
                    False,
                    "18.2",
                    dedent(
                        """\
                        Cloud config schema deprecations: \
    apt_reboot_if_required: Deprecated in version 22.2. Use\
     **package_reboot_if_required** instead., apt_update: Deprecated in version\
     22.2. Use **package_update** instead., apt_upgrade: Deprecated in version\
     22.2. Use **package_upgrade** instead.\
                        Valid schema {cfg_file}
                        """  # noqa: E501
                    ),
                    id="test_deprecation_info_boundary_does_unannotated_unredacted",
                ),
            ],
        )
        @mock.patch(M_PATH + "read_cfg_paths")
        def test_handle_schema_args_annotate_deprecated_config(
            self,
            read_cfg_paths,
            annotate,
            deprecation_info_boundary,
            expected_output,
            paths,
            caplog,
            capsys,
            tmpdir,
            mocker,
        ):
            paths.get_ipath = paths.get_ipath_cur
            read_cfg_paths.return_value = paths
            user_data_fn = tmpdir.join("user-data")
            with open(user_data_fn, "w") as f:
                f.write(
                    dedent(
                        """\
                        #cloud-config
                        packages:
                        - htop
                        apt_update: true
                        apt_upgrade: true
                        apt_reboot_if_required: true
                        """
                    )
                )
            mocker.patch.object(
                features, "DEPRECATION_INFO_BOUNDARY", deprecation_info_boundary
            )
            args = self.Args(
                config_file=str(user_data_fn),
                schema_type="cloud-config",
                annotate=annotate,
                docs=None,
                system=None,
                instance_data=None,
            )
            handle_schema_args("unused", args)
            out, err = capsys.readouterr()
>           assert (
                expected_output.format(cfg_file=user_data_fn).split()
                == out.split()
            )
E           AssertionError: assert ['#cloud-conf..., 'true', ...] == ['Skipping', ...endency', ...]
E             
E             At index 0 diff: '#cloud-config' != 'Skipping'
E             Left contains 42 more items, first extra item: 'D1'
E             
E             Full diff:
E               [
E             -     'Skipping',...
E             
E             ...Full output truncated (56 lines hidden), use '-vv' to show

tests/unittests/config/test_schema.py:2844: AssertionError
------------------------------ Captured log call -------------------------------
2024-09-18 16:50:18 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json (quiet=False)
2024-09-18 16:50:18 DEBUG     cloudinit.util:util.py:1622 Read 150110 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json
2024-09-18 16:50:18 DEBUG     cloudinit.util:util.py:1613 Reading from /tmp/pytest-of-debusine-worker/pytest-0/test_handle_schema_args_annota0/user-data (quiet=False)
2024-09-18 16:50:18 DEBUG     cloudinit.util:util.py:1622 Read 95 bytes from /tmp/pytest-of-debusine-worker/pytest-0/test_handle_schema_args_annota0/user-data
2024-09-18 16:50:18 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
_ TestHandleSchemaArgs.test_handle_schema_args_annotate_deprecated_config[test_annotated_deprecation_info_boundary_below_unredacted] _

self = <tests.unittests.config.test_schema.TestHandleSchemaArgs object at 0xffffb3ff4c30>
read_cfg_paths = <MagicMock name='read_cfg_paths' id='281473672240768'>
annotate = True, deprecation_info_boundary = '22.1'
expected_output = '#cloud-config\npackages:\n- htop\napt_update: true                # D1\napt_upgrade: true               # D2\napt_reb...* instead.\n# D3: Deprecated in version 22.2. Use **package_reboot_if_required** instead.\n\nValid schema {cfg_file}\n'
paths = <cloudinit.helpers.Paths object at 0xffffb200dc70>
caplog = <_pytest.logging.LogCaptureFixture object at 0xffffb19aeac0>
capsys = <_pytest.capture.CaptureFixture object at 0xffffb19afa80>
tmpdir = local('/tmp/pytest-of-debusine-worker/pytest-0/test_handle_schema_args_annota1')
mocker = <pytest_mock.plugin.MockerFixture object at 0xffffb18461a0>

        @pytest.mark.parametrize(
            "annotate, deprecation_info_boundary, expected_output",
            [
                pytest.param(
                    True,
                    "devel",
                    dedent(
                        """\
                        #cloud-config
                        packages:
                        - htop
                        apt_update: true                # D1
                        apt_upgrade: true               # D2
                        apt_reboot_if_required: true            # D3
    
                        # Deprecations: -------------
                        # D1: Deprecated in version 22.2. Use **package_update** instead.
                        # D2: Deprecated in version 22.2. Use **package_upgrade** instead.
                        # D3: Deprecated in version 22.2. Use **package_reboot_if_required** instead.
    
                        Valid schema {cfg_file}
                        """  # noqa: E501
                    ),
                    id="test_annotated_deprecation_info_boundary_devel_shows",
                ),
                pytest.param(
                    True,
                    "22.1",
                    dedent(
                        """\
                        #cloud-config
                        packages:
                        - htop
                        apt_update: true                # D1
                        apt_upgrade: true               # D2
                        apt_reboot_if_required: true            # D3
    
                        # Deprecations: -------------
                        # D1: Deprecated in version 22.2. Use **package_update** instead.
                        # D2: Deprecated in version 22.2. Use **package_upgrade** instead.
                        # D3: Deprecated in version 22.2. Use **package_reboot_if_required** instead.
    
                        Valid schema {cfg_file}
                        """  # noqa: E501
                    ),
                    id="test_annotated_deprecation_info_boundary_below_unredacted",
                ),
                pytest.param(
                    False,
                    "18.2",
                    dedent(
                        """\
                        Cloud config schema deprecations: \
    apt_reboot_if_required: Deprecated in version 22.2. Use\
     **package_reboot_if_required** instead., apt_update: Deprecated in version\
     22.2. Use **package_update** instead., apt_upgrade: Deprecated in version\
     22.2. Use **package_upgrade** instead.\
                        Valid schema {cfg_file}
                        """  # noqa: E501
                    ),
                    id="test_deprecation_info_boundary_does_unannotated_unredacted",
                ),
            ],
        )
        @mock.patch(M_PATH + "read_cfg_paths")
        def test_handle_schema_args_annotate_deprecated_config(
            self,
            read_cfg_paths,
            annotate,
            deprecation_info_boundary,
            expected_output,
            paths,
            caplog,
            capsys,
            tmpdir,
            mocker,
        ):
            paths.get_ipath = paths.get_ipath_cur
            read_cfg_paths.return_value = paths
            user_data_fn = tmpdir.join("user-data")
            with open(user_data_fn, "w") as f:
                f.write(
                    dedent(
                        """\
                        #cloud-config
                        packages:
                        - htop
                        apt_update: true
                        apt_upgrade: true
                        apt_reboot_if_required: true
                        """
                    )
                )
            mocker.patch.object(
                features, "DEPRECATION_INFO_BOUNDARY", deprecation_info_boundary
            )
            args = self.Args(
                config_file=str(user_data_fn),
                schema_type="cloud-config",
                annotate=annotate,
                docs=None,
                system=None,
                instance_data=None,
            )
            handle_schema_args("unused", args)
            out, err = capsys.readouterr()
>           assert (
                expected_output.format(cfg_file=user_data_fn).split()
                == out.split()
            )
E           AssertionError: assert ['#cloud-conf..., 'true', ...] == ['Skipping', ...endency', ...]
E             
E             At index 0 diff: '#cloud-config' != 'Skipping'
E             Left contains 42 more items, first extra item: 'D1'
E             
E             Full diff:
E               [
E             -     'Skipping',...
E             
E             ...Full output truncated (56 lines hidden), use '-vv' to show

tests/unittests/config/test_schema.py:2844: AssertionError
------------------------------ Captured log call -------------------------------
2024-09-18 16:50:18 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json (quiet=False)
2024-09-18 16:50:18 DEBUG     cloudinit.util:util.py:1622 Read 150110 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json
2024-09-18 16:50:18 DEBUG     cloudinit.util:util.py:1613 Reading from /tmp/pytest-of-debusine-worker/pytest-0/test_handle_schema_args_annota1/user-data (quiet=False)
2024-09-18 16:50:18 DEBUG     cloudinit.util:util.py:1622 Read 95 bytes from /tmp/pytest-of-debusine-worker/pytest-0/test_handle_schema_args_annota1/user-data
2024-09-18 16:50:18 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
_ TestHandleSchemaArgs.test_handle_schema_args_annotate_deprecated_config[test_deprecation_info_boundary_does_unannotated_unredacted] _

self = <tests.unittests.config.test_schema.TestHandleSchemaArgs object at 0xffffb3ff9910>
read_cfg_paths = <MagicMock name='read_cfg_paths' id='281473693810176'>
annotate = False, deprecation_info_boundary = '18.2'
expected_output = 'Cloud config schema deprecations: apt_reboot_if_required: Deprecated in version 22.2. Use **package_reboot_if_require...apt_upgrade: Deprecated in version 22.2. Use **package_upgrade** instead.                    Valid schema {cfg_file}\n'
paths = <cloudinit.helpers.Paths object at 0xffffb2b2b890>
caplog = <_pytest.logging.LogCaptureFixture object at 0xffffb19ae0b0>
capsys = <_pytest.capture.CaptureFixture object at 0xffffb19ae350>
tmpdir = local('/tmp/pytest-of-debusine-worker/pytest-0/test_handle_schema_args_annota2')
mocker = <pytest_mock.plugin.MockerFixture object at 0xffffb1847d40>

        @pytest.mark.parametrize(
            "annotate, deprecation_info_boundary, expected_output",
            [
                pytest.param(
                    True,
                    "devel",
                    dedent(
                        """\
                        #cloud-config
                        packages:
                        - htop
                        apt_update: true                # D1
                        apt_upgrade: true               # D2
                        apt_reboot_if_required: true            # D3
    
                        # Deprecations: -------------
                        # D1: Deprecated in version 22.2. Use **package_update** instead.
                        # D2: Deprecated in version 22.2. Use **package_upgrade** instead.
                        # D3: Deprecated in version 22.2. Use **package_reboot_if_required** instead.
    
                        Valid schema {cfg_file}
                        """  # noqa: E501
                    ),
                    id="test_annotated_deprecation_info_boundary_devel_shows",
                ),
                pytest.param(
                    True,
                    "22.1",
                    dedent(
                        """\
                        #cloud-config
                        packages:
                        - htop
                        apt_update: true                # D1
                        apt_upgrade: true               # D2
                        apt_reboot_if_required: true            # D3
    
                        # Deprecations: -------------
                        # D1: Deprecated in version 22.2. Use **package_update** instead.
                        # D2: Deprecated in version 22.2. Use **package_upgrade** instead.
                        # D3: Deprecated in version 22.2. Use **package_reboot_if_required** instead.
    
                        Valid schema {cfg_file}
                        """  # noqa: E501
                    ),
                    id="test_annotated_deprecation_info_boundary_below_unredacted",
                ),
                pytest.param(
                    False,
                    "18.2",
                    dedent(
                        """\
                        Cloud config schema deprecations: \
    apt_reboot_if_required: Deprecated in version 22.2. Use\
     **package_reboot_if_required** instead., apt_update: Deprecated in version\
     22.2. Use **package_update** instead., apt_upgrade: Deprecated in version\
     22.2. Use **package_upgrade** instead.\
                        Valid schema {cfg_file}
                        """  # noqa: E501
                    ),
                    id="test_deprecation_info_boundary_does_unannotated_unredacted",
                ),
            ],
        )
        @mock.patch(M_PATH + "read_cfg_paths")
        def test_handle_schema_args_annotate_deprecated_config(
            self,
            read_cfg_paths,
            annotate,
            deprecation_info_boundary,
            expected_output,
            paths,
            caplog,
            capsys,
            tmpdir,
            mocker,
        ):
            paths.get_ipath = paths.get_ipath_cur
            read_cfg_paths.return_value = paths
            user_data_fn = tmpdir.join("user-data")
            with open(user_data_fn, "w") as f:
                f.write(
                    dedent(
                        """\
                        #cloud-config
                        packages:
                        - htop
                        apt_update: true
                        apt_upgrade: true
                        apt_reboot_if_required: true
                        """
                    )
                )
            mocker.patch.object(
                features, "DEPRECATION_INFO_BOUNDARY", deprecation_info_boundary
            )
            args = self.Args(
                config_file=str(user_data_fn),
                schema_type="cloud-config",
                annotate=annotate,
                docs=None,
                system=None,
                instance_data=None,
            )
            handle_schema_args("unused", args)
            out, err = capsys.readouterr()
>           assert (
                expected_output.format(cfg_file=user_data_fn).split()
                == out.split()
            )
E           AssertionError: assert ['Cloud', 'co...recated', ...] == ['Skipping', ...endency', ...]
E             
E             At index 0 diff: 'Cloud' != 'Skipping'
E             Left contains 24 more items, first extra item: 'version'
E             
E             Full diff:
E               [
E             -     'Skipping',...
E             
E             ...Full output truncated (39 lines hidden), use '-vv' to show

tests/unittests/config/test_schema.py:2844: AssertionError
------------------------------ Captured log call -------------------------------
2024-09-18 16:50:18 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json (quiet=False)
2024-09-18 16:50:18 DEBUG     cloudinit.util:util.py:1622 Read 150110 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json
2024-09-18 16:50:18 DEBUG     cloudinit.util:util.py:1613 Reading from /tmp/pytest-of-debusine-worker/pytest-0/test_handle_schema_args_annota2/user-data (quiet=False)
2024-09-18 16:50:18 DEBUG     cloudinit.util:util.py:1622 Read 95 bytes from /tmp/pytest-of-debusine-worker/pytest-0/test_handle_schema_args_annota2/user-data
2024-09-18 16:50:18 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
_ TestHandleSchemaArgs.test_handle_schema_args_jinja_with_errors[root_annotate_errors_with_exception] _

self = <tests.unittests.config.test_schema.TestHandleSchemaArgs object at 0xffffb3fa5bf0>
read_cfg_paths = <MagicMock name='read_cfg_paths' id='281473674749872'>
getuid = <MagicMock name='getuid' id='281473674754912'>, uid = 0
annotate = True
expected_out = "#cloud-config\nhostname: 123\t\t# E1\n\n# Errors: -------------\n# E1: 123 is not of type 'string'\n\n\n"
expected_err = 'Error: Invalid schema: user-data\n\n'
expectation = <_pytest.python_api.RaisesContext object at 0xffffb46eea50>
paths = <cloudinit.helpers.Paths object at 0xffffb2038870>
caplog = <_pytest.logging.LogCaptureFixture object at 0xffffb19ae3c0>
capsys = <_pytest.capture.CaptureFixture object at 0xffffb19ae5f0>
tmpdir = local('/tmp/pytest-of-debusine-worker/pytest-0/test_handle_schema_args_jinja_0')

    @pytest.mark.parametrize(
        "uid, annotate, expected_out, expected_err, expectation",
        [
            pytest.param(
                0,
                True,
                dedent(
                    """\
                    #cloud-config
                    hostname: 123		# E1
    
                    # Errors: -------------
                    # E1: 123 is not of type 'string'
    
    
                    """  # noqa: E501
                ),
                """Error: Invalid schema: user-data\n\n""",
                pytest.raises(SystemExit),
                id="root_annotate_errors_with_exception",
            ),
            pytest.param(
                0,
                False,
                dedent(
                    """\
                    Invalid user-data {cfg_file}
                    """  # noqa: E501
                ),
                dedent(
                    """\
                    Error: Cloud config schema errors: hostname: 123 is not of type 'string'
    
                    Error: Invalid schema: user-data
    
                    """  # noqa: E501
                ),
                pytest.raises(SystemExit),
                id="root_no_annotate_exception_with_unique_errors",
            ),
        ],
    )
    @mock.patch(M_PATH + "os.getuid")
    @mock.patch(M_PATH + "read_cfg_paths")
    def test_handle_schema_args_jinja_with_errors(
        self,
        read_cfg_paths,
        getuid,
        uid,
        annotate,
        expected_out,
        expected_err,
        expectation,
        paths,
        caplog,
        capsys,
        tmpdir,
    ):
        getuid.return_value = uid
        paths.get_ipath = paths.get_ipath_cur
        read_cfg_paths.return_value = paths
        user_data_fn = tmpdir.join("user-data")
        if uid == 0:
            id_path = paths.get_runpath("instance_data_sensitive")
        else:
            id_path = paths.get_runpath("instance_data")
        with open(id_path, "w") as f:
            f.write(json.dumps({"ds": {"asdf": 123}}))
        with open(user_data_fn, "w") as f:
            f.write(
                dedent(
                    """\
                    ## template: jinja
                    #cloud-config
                    hostname: {{ ds.asdf }}
                    """
                )
            )
        args = self.Args(
            config_file=str(user_data_fn),
            schema_type="cloud-config",
            annotate=annotate,
            docs=None,
            system=None,
            instance_data=None,
        )
>       with expectation:
E       Failed: DID NOT RAISE <class 'SystemExit'>

tests/unittests/config/test_schema.py:2937: Failed
----------------------------- Captured stdout call -----------------------------
Skipping cloud-config schema validation. Jsonschema dependency missing.
------------------------------ Captured log call -------------------------------
2024-09-18 16:50:18 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json (quiet=False)
2024-09-18 16:50:18 DEBUG     cloudinit.util:util.py:1622 Read 150110 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json
2024-09-18 16:50:18 DEBUG     cloudinit.util:util.py:1613 Reading from /tmp/pytest-of-debusine-worker/pytest-0/test_handle_schema_args_jinja_0/user-data (quiet=False)
2024-09-18 16:50:18 DEBUG     cloudinit.util:util.py:1622 Read 57 bytes from /tmp/pytest-of-debusine-worker/pytest-0/test_handle_schema_args_jinja_0/user-data
2024-09-18 16:50:18 DEBUG     cloudinit.util:util.py:1613 Reading from /tmp/pytest-of-debusine-worker/pytest-0/test_handle_schema_args_jinja_0/run_dir/instance-data-sensitive.json (quiet=False)
2024-09-18 16:50:18 DEBUG     cloudinit.util:util.py:1622 Read 21 bytes from /tmp/pytest-of-debusine-worker/pytest-0/test_handle_schema_args_jinja_0/run_dir/instance-data-sensitive.json
2024-09-18 16:50:18 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
_ TestHandleSchemaArgs.test_handle_schema_args_jinja_with_errors[root_no_annotate_exception_with_unique_errors] _

self = <tests.unittests.config.test_schema.TestHandleSchemaArgs object at 0xffffb3fa5d00>
read_cfg_paths = <MagicMock name='read_cfg_paths' id='281473674750544'>
getuid = <MagicMock name='getuid' id='281473674753232'>, uid = 0
annotate = False, expected_out = 'Invalid user-data {cfg_file}\n'
expected_err = "Error: Cloud config schema errors: hostname: 123 is not of type 'string'\n\nError: Invalid schema: user-data\n\n"
expectation = <_pytest.python_api.RaisesContext object at 0xffffb46efee0>
paths = <cloudinit.helpers.Paths object at 0xffffb2bb1ef0>
caplog = <_pytest.logging.LogCaptureFixture object at 0xffffb1bb9240>
capsys = <_pytest.capture.CaptureFixture object at 0xffffb1bb8e50>
tmpdir = local('/tmp/pytest-of-debusine-worker/pytest-0/test_handle_schema_args_jinja_1')

    @pytest.mark.parametrize(
        "uid, annotate, expected_out, expected_err, expectation",
        [
            pytest.param(
                0,
                True,
                dedent(
                    """\
                    #cloud-config
                    hostname: 123		# E1
    
                    # Errors: -------------
                    # E1: 123 is not of type 'string'
    
    
                    """  # noqa: E501
                ),
                """Error: Invalid schema: user-data\n\n""",
                pytest.raises(SystemExit),
                id="root_annotate_errors_with_exception",
            ),
            pytest.param(
                0,
                False,
                dedent(
                    """\
                    Invalid user-data {cfg_file}
                    """  # noqa: E501
                ),
                dedent(
                    """\
                    Error: Cloud config schema errors: hostname: 123 is not of type 'string'
    
                    Error: Invalid schema: user-data
    
                    """  # noqa: E501
                ),
                pytest.raises(SystemExit),
                id="root_no_annotate_exception_with_unique_errors",
            ),
        ],
    )
    @mock.patch(M_PATH + "os.getuid")
    @mock.patch(M_PATH + "read_cfg_paths")
    def test_handle_schema_args_jinja_with_errors(
        self,
        read_cfg_paths,
        getuid,
        uid,
        annotate,
        expected_out,
        expected_err,
        expectation,
        paths,
        caplog,
        capsys,
        tmpdir,
    ):
        getuid.return_value = uid
        paths.get_ipath = paths.get_ipath_cur
        read_cfg_paths.return_value = paths
        user_data_fn = tmpdir.join("user-data")
        if uid == 0:
            id_path = paths.get_runpath("instance_data_sensitive")
        else:
            id_path = paths.get_runpath("instance_data")
        with open(id_path, "w") as f:
            f.write(json.dumps({"ds": {"asdf": 123}}))
        with open(user_data_fn, "w") as f:
            f.write(
                dedent(
                    """\
                    ## template: jinja
                    #cloud-config
                    hostname: {{ ds.asdf }}
                    """
                )
            )
        args = self.Args(
            config_file=str(user_data_fn),
            schema_type="cloud-config",
            annotate=annotate,
            docs=None,
            system=None,
            instance_data=None,
        )
>       with expectation:
E       Failed: DID NOT RAISE <class 'SystemExit'>

tests/unittests/config/test_schema.py:2937: Failed
----------------------------- Captured stdout call -----------------------------
Skipping cloud-config schema validation. Jsonschema dependency missing.
------------------------------ Captured log call -------------------------------
2024-09-18 16:50:18 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json (quiet=False)
2024-09-18 16:50:18 DEBUG     cloudinit.util:util.py:1622 Read 150110 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json
2024-09-18 16:50:18 DEBUG     cloudinit.util:util.py:1613 Reading from /tmp/pytest-of-debusine-worker/pytest-0/test_handle_schema_args_jinja_1/user-data (quiet=False)
2024-09-18 16:50:18 DEBUG     cloudinit.util:util.py:1622 Read 57 bytes from /tmp/pytest-of-debusine-worker/pytest-0/test_handle_schema_args_jinja_1/user-data
2024-09-18 16:50:18 DEBUG     cloudinit.util:util.py:1613 Reading from /tmp/pytest-of-debusine-worker/pytest-0/test_handle_schema_args_jinja_1/run_dir/instance-data-sensitive.json (quiet=False)
2024-09-18 16:50:18 DEBUG     cloudinit.util:util.py:1622 Read 21 bytes from /tmp/pytest-of-debusine-worker/pytest-0/test_handle_schema_args_jinja_1/run_dir/instance-data-sensitive.json
2024-09-18 16:50:18 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
_ TestReportingSchema.test_schema_validation[config8-'a' is not of type 'object'] _

self = <test_reporting.TestReportingSchema object at 0xffffb3a2d250>
config = {'reporting': 'a'}, error_msg = "'a' is not of type 'object'"

    @pytest.mark.parametrize(
        "config, error_msg",
        [
            # GOOD: Minimum valid parameters
            ({"reporting": {"a": {"type": "print"}}}, None),
            ({"reporting": {"a": {"type": "log"}}}, None),
            (
                {
                    "reporting": {
                        "a": {"type": "webhook", "endpoint": "http://a"}
                    }
                },
                None,
            ),
            ({"reporting": {"a": {"type": "hyperv"}}}, None),
            # GOOD: All valid parameters
            ({"reporting": {"a": {"type": "log", "level": "WARN"}}}, None),
            (
                {
                    "reporting": {
                        "a": {
                            "type": "webhook",
                            "endpoint": "http://a";,
                            "timeout": 1,
                            "retries": 1,
                            "consumer_key": "somekey",
                            "token_key": "somekey",
                            "token_secret": "somesecret",
                            "consumer_secret": "somesecret",
                        }
                    }
                },
                None,
            ),
            (
                {
                    "reporting": {
                        "a": {
                            "type": "hyperv",
                            "kvp_file_path": "/some/path",
                            "event_types": ["a", "b"],
                        }
                    }
                },
                None,
            ),
            # GOOD: All combined together
            (
                {
                    "reporting": {
                        "a": {"type": "print"},
                        "b": {"type": "log", "level": "WARN"},
                        "c": {
                            "type": "webhook",
                            "endpoint": "http://a";,
                            "timeout": 1,
                            "retries": 1,
                            "consumer_key": "somekey",
                            "token_key": "somekey",
                            "token_secret": "somesecret",
                            "consumer_secret": "somesecret",
                        },
                        "d": {
                            "type": "hyperv",
                            "kvp_file_path": "/some/path",
                            "event_types": ["a", "b"],
                        },
                    }
                },
                None,
            ),
            # BAD: no top level objects
            ({"reporting": "a"}, "'a' is not of type 'object'"),
            ({"reporting": {"a": "b"}}, "'b' is not of type 'object'"),
            # BAD: invalid type
            (
                {"reporting": {"a": {"type": "b"}}},
                re.escape("'b' is not one of ['log']"),
            ),
            # BAD: invalid additional properties
            (
                {"reporting": {"a": {"type": "print", "a": "b"}}},
                "'a' was unexpected",
            ),
            (
                {"reporting": {"a": {"type": "log", "a": "b"}}},
                "'a' was unexpected",
            ),
            (
                {
                    "reporting": {
                        "a": {
                            "type": "webhook",
                            "endpoint": "http://a";,
                            "a": "b",
                        }
                    }
                },
                "'a' was unexpected",
            ),
            (
                {"reporting": {"a": {"type": "hyperv", "a": "b"}}},
                "'a' was unexpected",
            ),
            # BAD: missing required properties
            ({"reporting": {"a": {"level": "FATAL"}}}, "'type' is a required"),
            (
                {"reporting": {"a": {"endpoint": "http://a"}}},
                "'type' is a required",
            ),
            (
                {"reporting": {"a": {"kvp_file_path": "/a/b"}}},
                "'endpoint' is a required",
            ),
            (
                {"reporting": {"a": {"type": "webhook"}}},
                "'endpoint' is a required",
            ),
        ],
    )
    def test_schema_validation(self, config, error_msg):
        if error_msg is None:
            validate_cloudconfig_schema(config, get_schema(), strict=True)
        else:
>           with pytest.raises(SchemaValidationError, match=error_msg):
E           Failed: DID NOT RAISE <class 'cloudinit.config.schema.SchemaValidationError'>

tests/unittests/reporting/test_reporting.py:590: Failed
------------------------------ Captured log call -------------------------------
2024-09-18 16:50:33 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json (quiet=False)
2024-09-18 16:50:33 DEBUG     cloudinit.util:util.py:1622 Read 150110 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json
2024-09-18 16:50:33 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
_ TestReportingSchema.test_schema_validation[config9-'b' is not of type 'object'] _

self = <test_reporting.TestReportingSchema object at 0xffffb409b3e0>
config = {'reporting': {'a': 'b'}}, error_msg = "'b' is not of type 'object'"

    @pytest.mark.parametrize(
        "config, error_msg",
        [
            # GOOD: Minimum valid parameters
            ({"reporting": {"a": {"type": "print"}}}, None),
            ({"reporting": {"a": {"type": "log"}}}, None),
            (
                {
                    "reporting": {
                        "a": {"type": "webhook", "endpoint": "http://a"}
                    }
                },
                None,
            ),
            ({"reporting": {"a": {"type": "hyperv"}}}, None),
            # GOOD: All valid parameters
            ({"reporting": {"a": {"type": "log", "level": "WARN"}}}, None),
            (
                {
                    "reporting": {
                        "a": {
                            "type": "webhook",
                            "endpoint": "http://a";,
                            "timeout": 1,
                            "retries": 1,
                            "consumer_key": "somekey",
                            "token_key": "somekey",
                            "token_secret": "somesecret",
                            "consumer_secret": "somesecret",
                        }
                    }
                },
                None,
            ),
            (
                {
                    "reporting": {
                        "a": {
                            "type": "hyperv",
                            "kvp_file_path": "/some/path",
                            "event_types": ["a", "b"],
                        }
                    }
                },
                None,
            ),
            # GOOD: All combined together
            (
                {
                    "reporting": {
                        "a": {"type": "print"},
                        "b": {"type": "log", "level": "WARN"},
                        "c": {
                            "type": "webhook",
                            "endpoint": "http://a";,
                            "timeout": 1,
                            "retries": 1,
                            "consumer_key": "somekey",
                            "token_key": "somekey",
                            "token_secret": "somesecret",
                            "consumer_secret": "somesecret",
                        },
                        "d": {
                            "type": "hyperv",
                            "kvp_file_path": "/some/path",
                            "event_types": ["a", "b"],
                        },
                    }
                },
                None,
            ),
            # BAD: no top level objects
            ({"reporting": "a"}, "'a' is not of type 'object'"),
            ({"reporting": {"a": "b"}}, "'b' is not of type 'object'"),
            # BAD: invalid type
            (
                {"reporting": {"a": {"type": "b"}}},
                re.escape("'b' is not one of ['log']"),
            ),
            # BAD: invalid additional properties
            (
                {"reporting": {"a": {"type": "print", "a": "b"}}},
                "'a' was unexpected",
            ),
            (
                {"reporting": {"a": {"type": "log", "a": "b"}}},
                "'a' was unexpected",
            ),
            (
                {
                    "reporting": {
                        "a": {
                            "type": "webhook",
                            "endpoint": "http://a";,
                            "a": "b",
                        }
                    }
                },
                "'a' was unexpected",
            ),
            (
                {"reporting": {"a": {"type": "hyperv", "a": "b"}}},
                "'a' was unexpected",
            ),
            # BAD: missing required properties
            ({"reporting": {"a": {"level": "FATAL"}}}, "'type' is a required"),
            (
                {"reporting": {"a": {"endpoint": "http://a"}}},
                "'type' is a required",
            ),
            (
                {"reporting": {"a": {"kvp_file_path": "/a/b"}}},
                "'endpoint' is a required",
            ),
            (
                {"reporting": {"a": {"type": "webhook"}}},
                "'endpoint' is a required",
            ),
        ],
    )
    def test_schema_validation(self, config, error_msg):
        if error_msg is None:
            validate_cloudconfig_schema(config, get_schema(), strict=True)
        else:
>           with pytest.raises(SchemaValidationError, match=error_msg):
E           Failed: DID NOT RAISE <class 'cloudinit.config.schema.SchemaValidationError'>

tests/unittests/reporting/test_reporting.py:590: Failed
------------------------------ Captured log call -------------------------------
2024-09-18 16:50:33 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json (quiet=False)
2024-09-18 16:50:33 DEBUG     cloudinit.util:util.py:1622 Read 150110 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json
2024-09-18 16:50:33 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
_ TestReportingSchema.test_schema_validation[config10-'b'\\ is\\ not\\ one\\ of\\ \\['log'\\]] _

self = <test_reporting.TestReportingSchema object at 0xffffb409b4d0>
config = {'reporting': {'a': {'type': 'b'}}}
error_msg = "'b'\\ is\\ not\\ one\\ of\\ \\['log'\\]"

    @pytest.mark.parametrize(
        "config, error_msg",
        [
            # GOOD: Minimum valid parameters
            ({"reporting": {"a": {"type": "print"}}}, None),
            ({"reporting": {"a": {"type": "log"}}}, None),
            (
                {
                    "reporting": {
                        "a": {"type": "webhook", "endpoint": "http://a"}
                    }
                },
                None,
            ),
            ({"reporting": {"a": {"type": "hyperv"}}}, None),
            # GOOD: All valid parameters
            ({"reporting": {"a": {"type": "log", "level": "WARN"}}}, None),
            (
                {
                    "reporting": {
                        "a": {
                            "type": "webhook",
                            "endpoint": "http://a";,
                            "timeout": 1,
                            "retries": 1,
                            "consumer_key": "somekey",
                            "token_key": "somekey",
                            "token_secret": "somesecret",
                            "consumer_secret": "somesecret",
                        }
                    }
                },
                None,
            ),
            (
                {
                    "reporting": {
                        "a": {
                            "type": "hyperv",
                            "kvp_file_path": "/some/path",
                            "event_types": ["a", "b"],
                        }
                    }
                },
                None,
            ),
            # GOOD: All combined together
            (
                {
                    "reporting": {
                        "a": {"type": "print"},
                        "b": {"type": "log", "level": "WARN"},
                        "c": {
                            "type": "webhook",
                            "endpoint": "http://a";,
                            "timeout": 1,
                            "retries": 1,
                            "consumer_key": "somekey",
                            "token_key": "somekey",
                            "token_secret": "somesecret",
                            "consumer_secret": "somesecret",
                        },
                        "d": {
                            "type": "hyperv",
                            "kvp_file_path": "/some/path",
                            "event_types": ["a", "b"],
                        },
                    }
                },
                None,
            ),
            # BAD: no top level objects
            ({"reporting": "a"}, "'a' is not of type 'object'"),
            ({"reporting": {"a": "b"}}, "'b' is not of type 'object'"),
            # BAD: invalid type
            (
                {"reporting": {"a": {"type": "b"}}},
                re.escape("'b' is not one of ['log']"),
            ),
            # BAD: invalid additional properties
            (
                {"reporting": {"a": {"type": "print", "a": "b"}}},
                "'a' was unexpected",
            ),
            (
                {"reporting": {"a": {"type": "log", "a": "b"}}},
                "'a' was unexpected",
            ),
            (
                {
                    "reporting": {
                        "a": {
                            "type": "webhook",
                            "endpoint": "http://a";,
                            "a": "b",
                        }
                    }
                },
                "'a' was unexpected",
            ),
            (
                {"reporting": {"a": {"type": "hyperv", "a": "b"}}},
                "'a' was unexpected",
            ),
            # BAD: missing required properties
            ({"reporting": {"a": {"level": "FATAL"}}}, "'type' is a required"),
            (
                {"reporting": {"a": {"endpoint": "http://a"}}},
                "'type' is a required",
            ),
            (
                {"reporting": {"a": {"kvp_file_path": "/a/b"}}},
                "'endpoint' is a required",
            ),
            (
                {"reporting": {"a": {"type": "webhook"}}},
                "'endpoint' is a required",
            ),
        ],
    )
    def test_schema_validation(self, config, error_msg):
        if error_msg is None:
            validate_cloudconfig_schema(config, get_schema(), strict=True)
        else:
>           with pytest.raises(SchemaValidationError, match=error_msg):
E           Failed: DID NOT RAISE <class 'cloudinit.config.schema.SchemaValidationError'>

tests/unittests/reporting/test_reporting.py:590: Failed
------------------------------ Captured log call -------------------------------
2024-09-18 16:50:33 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json (quiet=False)
2024-09-18 16:50:33 DEBUG     cloudinit.util:util.py:1622 Read 150110 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json
2024-09-18 16:50:33 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
___ TestReportingSchema.test_schema_validation[config11-'a' was unexpected] ____

self = <test_reporting.TestReportingSchema object at 0xffffb3e5d0f0>
config = {'reporting': {'a': {'a': 'b', 'type': 'print'}}}
error_msg = "'a' was unexpected"

    @pytest.mark.parametrize(
        "config, error_msg",
        [
            # GOOD: Minimum valid parameters
            ({"reporting": {"a": {"type": "print"}}}, None),
            ({"reporting": {"a": {"type": "log"}}}, None),
            (
                {
                    "reporting": {
                        "a": {"type": "webhook", "endpoint": "http://a"}
                    }
                },
                None,
            ),
            ({"reporting": {"a": {"type": "hyperv"}}}, None),
            # GOOD: All valid parameters
            ({"reporting": {"a": {"type": "log", "level": "WARN"}}}, None),
            (
                {
                    "reporting": {
                        "a": {
                            "type": "webhook",
                            "endpoint": "http://a";,
                            "timeout": 1,
                            "retries": 1,
                            "consumer_key": "somekey",
                            "token_key": "somekey",
                            "token_secret": "somesecret",
                            "consumer_secret": "somesecret",
                        }
                    }
                },
                None,
            ),
            (
                {
                    "reporting": {
                        "a": {
                            "type": "hyperv",
                            "kvp_file_path": "/some/path",
                            "event_types": ["a", "b"],
                        }
                    }
                },
                None,
            ),
            # GOOD: All combined together
            (
                {
                    "reporting": {
                        "a": {"type": "print"},
                        "b": {"type": "log", "level": "WARN"},
                        "c": {
                            "type": "webhook",
                            "endpoint": "http://a";,
                            "timeout": 1,
                            "retries": 1,
                            "consumer_key": "somekey",
                            "token_key": "somekey",
                            "token_secret": "somesecret",
                            "consumer_secret": "somesecret",
                        },
                        "d": {
                            "type": "hyperv",
                            "kvp_file_path": "/some/path",
                            "event_types": ["a", "b"],
                        },
                    }
                },
                None,
            ),
            # BAD: no top level objects
            ({"reporting": "a"}, "'a' is not of type 'object'"),
            ({"reporting": {"a": "b"}}, "'b' is not of type 'object'"),
            # BAD: invalid type
            (
                {"reporting": {"a": {"type": "b"}}},
                re.escape("'b' is not one of ['log']"),
            ),
            # BAD: invalid additional properties
            (
                {"reporting": {"a": {"type": "print", "a": "b"}}},
                "'a' was unexpected",
            ),
            (
                {"reporting": {"a": {"type": "log", "a": "b"}}},
                "'a' was unexpected",
            ),
            (
                {
                    "reporting": {
                        "a": {
                            "type": "webhook",
                            "endpoint": "http://a";,
                            "a": "b",
                        }
                    }
                },
                "'a' was unexpected",
            ),
            (
                {"reporting": {"a": {"type": "hyperv", "a": "b"}}},
                "'a' was unexpected",
            ),
            # BAD: missing required properties
            ({"reporting": {"a": {"level": "FATAL"}}}, "'type' is a required"),
            (
                {"reporting": {"a": {"endpoint": "http://a"}}},
                "'type' is a required",
            ),
            (
                {"reporting": {"a": {"kvp_file_path": "/a/b"}}},
                "'endpoint' is a required",
            ),
            (
                {"reporting": {"a": {"type": "webhook"}}},
                "'endpoint' is a required",
            ),
        ],
    )
    def test_schema_validation(self, config, error_msg):
        if error_msg is None:
            validate_cloudconfig_schema(config, get_schema(), strict=True)
        else:
>           with pytest.raises(SchemaValidationError, match=error_msg):
E           Failed: DID NOT RAISE <class 'cloudinit.config.schema.SchemaValidationError'>

tests/unittests/reporting/test_reporting.py:590: Failed
------------------------------ Captured log call -------------------------------
2024-09-18 16:50:33 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json (quiet=False)
2024-09-18 16:50:33 DEBUG     cloudinit.util:util.py:1622 Read 150110 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json
2024-09-18 16:50:33 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
___ TestReportingSchema.test_schema_validation[config12-'a' was unexpected] ____

self = <test_reporting.TestReportingSchema object at 0xffffb3e5d2b0>
config = {'reporting': {'a': {'a': 'b', 'type': 'log'}}}
error_msg = "'a' was unexpected"

    @pytest.mark.parametrize(
        "config, error_msg",
        [
            # GOOD: Minimum valid parameters
            ({"reporting": {"a": {"type": "print"}}}, None),
            ({"reporting": {"a": {"type": "log"}}}, None),
            (
                {
                    "reporting": {
                        "a": {"type": "webhook", "endpoint": "http://a"}
                    }
                },
                None,
            ),
            ({"reporting": {"a": {"type": "hyperv"}}}, None),
            # GOOD: All valid parameters
            ({"reporting": {"a": {"type": "log", "level": "WARN"}}}, None),
            (
                {
                    "reporting": {
                        "a": {
                            "type": "webhook",
                            "endpoint": "http://a";,
                            "timeout": 1,
                            "retries": 1,
                            "consumer_key": "somekey",
                            "token_key": "somekey",
                            "token_secret": "somesecret",
                            "consumer_secret": "somesecret",
                        }
                    }
                },
                None,
            ),
            (
                {
                    "reporting": {
                        "a": {
                            "type": "hyperv",
                            "kvp_file_path": "/some/path",
                            "event_types": ["a", "b"],
                        }
                    }
                },
                None,
            ),
            # GOOD: All combined together
            (
                {
                    "reporting": {
                        "a": {"type": "print"},
                        "b": {"type": "log", "level": "WARN"},
                        "c": {
                            "type": "webhook",
                            "endpoint": "http://a";,
                            "timeout": 1,
                            "retries": 1,
                            "consumer_key": "somekey",
                            "token_key": "somekey",
                            "token_secret": "somesecret",
                            "consumer_secret": "somesecret",
                        },
                        "d": {
                            "type": "hyperv",
                            "kvp_file_path": "/some/path",
                            "event_types": ["a", "b"],
                        },
                    }
                },
                None,
            ),
            # BAD: no top level objects
            ({"reporting": "a"}, "'a' is not of type 'object'"),
            ({"reporting": {"a": "b"}}, "'b' is not of type 'object'"),
            # BAD: invalid type
            (
                {"reporting": {"a": {"type": "b"}}},
                re.escape("'b' is not one of ['log']"),
            ),
            # BAD: invalid additional properties
            (
                {"reporting": {"a": {"type": "print", "a": "b"}}},
                "'a' was unexpected",
            ),
            (
                {"reporting": {"a": {"type": "log", "a": "b"}}},
                "'a' was unexpected",
            ),
            (
                {
                    "reporting": {
                        "a": {
                            "type": "webhook",
                            "endpoint": "http://a";,
                            "a": "b",
                        }
                    }
                },
                "'a' was unexpected",
            ),
            (
                {"reporting": {"a": {"type": "hyperv", "a": "b"}}},
                "'a' was unexpected",
            ),
            # BAD: missing required properties
            ({"reporting": {"a": {"level": "FATAL"}}}, "'type' is a required"),
            (
                {"reporting": {"a": {"endpoint": "http://a"}}},
                "'type' is a required",
            ),
            (
                {"reporting": {"a": {"kvp_file_path": "/a/b"}}},
                "'endpoint' is a required",
            ),
            (
                {"reporting": {"a": {"type": "webhook"}}},
                "'endpoint' is a required",
            ),
        ],
    )
    def test_schema_validation(self, config, error_msg):
        if error_msg is None:
            validate_cloudconfig_schema(config, get_schema(), strict=True)
        else:
>           with pytest.raises(SchemaValidationError, match=error_msg):
E           Failed: DID NOT RAISE <class 'cloudinit.config.schema.SchemaValidationError'>

tests/unittests/reporting/test_reporting.py:590: Failed
------------------------------ Captured log call -------------------------------
2024-09-18 16:50:33 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json (quiet=False)
2024-09-18 16:50:33 DEBUG     cloudinit.util:util.py:1622 Read 150110 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json
2024-09-18 16:50:33 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
___ TestReportingSchema.test_schema_validation[config13-'a' was unexpected] ____

self = <test_reporting.TestReportingSchema object at 0xffffb3e89f30>
config = {'reporting': {'a': {'a': 'b', 'endpoint': 'http://a', 'type': 'webhook'}}}
error_msg = "'a' was unexpected"

    @pytest.mark.parametrize(
        "config, error_msg",
        [
            # GOOD: Minimum valid parameters
            ({"reporting": {"a": {"type": "print"}}}, None),
            ({"reporting": {"a": {"type": "log"}}}, None),
            (
                {
                    "reporting": {
                        "a": {"type": "webhook", "endpoint": "http://a"}
                    }
                },
                None,
            ),
            ({"reporting": {"a": {"type": "hyperv"}}}, None),
            # GOOD: All valid parameters
            ({"reporting": {"a": {"type": "log", "level": "WARN"}}}, None),
            (
                {
                    "reporting": {
                        "a": {
                            "type": "webhook",
                            "endpoint": "http://a";,
                            "timeout": 1,
                            "retries": 1,
                            "consumer_key": "somekey",
                            "token_key": "somekey",
                            "token_secret": "somesecret",
                            "consumer_secret": "somesecret",
                        }
                    }
                },
                None,
            ),
            (
                {
                    "reporting": {
                        "a": {
                            "type": "hyperv",
                            "kvp_file_path": "/some/path",
                            "event_types": ["a", "b"],
                        }
                    }
                },
                None,
            ),
            # GOOD: All combined together
            (
                {
                    "reporting": {
                        "a": {"type": "print"},
                        "b": {"type": "log", "level": "WARN"},
                        "c": {
                            "type": "webhook",
                            "endpoint": "http://a";,
                            "timeout": 1,
                            "retries": 1,
                            "consumer_key": "somekey",
                            "token_key": "somekey",
                            "token_secret": "somesecret",
                            "consumer_secret": "somesecret",
                        },
                        "d": {
                            "type": "hyperv",
                            "kvp_file_path": "/some/path",
                            "event_types": ["a", "b"],
                        },
                    }
                },
                None,
            ),
            # BAD: no top level objects
            ({"reporting": "a"}, "'a' is not of type 'object'"),
            ({"reporting": {"a": "b"}}, "'b' is not of type 'object'"),
            # BAD: invalid type
            (
                {"reporting": {"a": {"type": "b"}}},
                re.escape("'b' is not one of ['log']"),
            ),
            # BAD: invalid additional properties
            (
                {"reporting": {"a": {"type": "print", "a": "b"}}},
                "'a' was unexpected",
            ),
            (
                {"reporting": {"a": {"type": "log", "a": "b"}}},
                "'a' was unexpected",
            ),
            (
                {
                    "reporting": {
                        "a": {
                            "type": "webhook",
                            "endpoint": "http://a";,
                            "a": "b",
                        }
                    }
                },
                "'a' was unexpected",
            ),
            (
                {"reporting": {"a": {"type": "hyperv", "a": "b"}}},
                "'a' was unexpected",
            ),
            # BAD: missing required properties
            ({"reporting": {"a": {"level": "FATAL"}}}, "'type' is a required"),
            (
                {"reporting": {"a": {"endpoint": "http://a"}}},
                "'type' is a required",
            ),
            (
                {"reporting": {"a": {"kvp_file_path": "/a/b"}}},
                "'endpoint' is a required",
            ),
            (
                {"reporting": {"a": {"type": "webhook"}}},
                "'endpoint' is a required",
            ),
        ],
    )
    def test_schema_validation(self, config, error_msg):
        if error_msg is None:
            validate_cloudconfig_schema(config, get_schema(), strict=True)
        else:
>           with pytest.raises(SchemaValidationError, match=error_msg):
E           Failed: DID NOT RAISE <class 'cloudinit.config.schema.SchemaValidationError'>

tests/unittests/reporting/test_reporting.py:590: Failed
------------------------------ Captured log call -------------------------------
2024-09-18 16:50:33 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json (quiet=False)
2024-09-18 16:50:33 DEBUG     cloudinit.util:util.py:1622 Read 150110 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json
2024-09-18 16:50:33 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
___ TestReportingSchema.test_schema_validation[config14-'a' was unexpected] ____

self = <test_reporting.TestReportingSchema object at 0xffffb42a6e10>
config = {'reporting': {'a': {'a': 'b', 'type': 'hyperv'}}}
error_msg = "'a' was unexpected"

    @pytest.mark.parametrize(
        "config, error_msg",
        [
            # GOOD: Minimum valid parameters
            ({"reporting": {"a": {"type": "print"}}}, None),
            ({"reporting": {"a": {"type": "log"}}}, None),
            (
                {
                    "reporting": {
                        "a": {"type": "webhook", "endpoint": "http://a"}
                    }
                },
                None,
            ),
            ({"reporting": {"a": {"type": "hyperv"}}}, None),
            # GOOD: All valid parameters
            ({"reporting": {"a": {"type": "log", "level": "WARN"}}}, None),
            (
                {
                    "reporting": {
                        "a": {
                            "type": "webhook",
                            "endpoint": "http://a";,
                            "timeout": 1,
                            "retries": 1,
                            "consumer_key": "somekey",
                            "token_key": "somekey",
                            "token_secret": "somesecret",
                            "consumer_secret": "somesecret",
                        }
                    }
                },
                None,
            ),
            (
                {
                    "reporting": {
                        "a": {
                            "type": "hyperv",
                            "kvp_file_path": "/some/path",
                            "event_types": ["a", "b"],
                        }
                    }
                },
                None,
            ),
            # GOOD: All combined together
            (
                {
                    "reporting": {
                        "a": {"type": "print"},
                        "b": {"type": "log", "level": "WARN"},
                        "c": {
                            "type": "webhook",
                            "endpoint": "http://a";,
                            "timeout": 1,
                            "retries": 1,
                            "consumer_key": "somekey",
                            "token_key": "somekey",
                            "token_secret": "somesecret",
                            "consumer_secret": "somesecret",
                        },
                        "d": {
                            "type": "hyperv",
                            "kvp_file_path": "/some/path",
                            "event_types": ["a", "b"],
                        },
                    }
                },
                None,
            ),
            # BAD: no top level objects
            ({"reporting": "a"}, "'a' is not of type 'object'"),
            ({"reporting": {"a": "b"}}, "'b' is not of type 'object'"),
            # BAD: invalid type
            (
                {"reporting": {"a": {"type": "b"}}},
                re.escape("'b' is not one of ['log']"),
            ),
            # BAD: invalid additional properties
            (
                {"reporting": {"a": {"type": "print", "a": "b"}}},
                "'a' was unexpected",
            ),
            (
                {"reporting": {"a": {"type": "log", "a": "b"}}},
                "'a' was unexpected",
            ),
            (
                {
                    "reporting": {
                        "a": {
                            "type": "webhook",
                            "endpoint": "http://a";,
                            "a": "b",
                        }
                    }
                },
                "'a' was unexpected",
            ),
            (
                {"reporting": {"a": {"type": "hyperv", "a": "b"}}},
                "'a' was unexpected",
            ),
            # BAD: missing required properties
            ({"reporting": {"a": {"level": "FATAL"}}}, "'type' is a required"),
            (
                {"reporting": {"a": {"endpoint": "http://a"}}},
                "'type' is a required",
            ),
            (
                {"reporting": {"a": {"kvp_file_path": "/a/b"}}},
                "'endpoint' is a required",
            ),
            (
                {"reporting": {"a": {"type": "webhook"}}},
                "'endpoint' is a required",
            ),
        ],
    )
    def test_schema_validation(self, config, error_msg):
        if error_msg is None:
            validate_cloudconfig_schema(config, get_schema(), strict=True)
        else:
>           with pytest.raises(SchemaValidationError, match=error_msg):
E           Failed: DID NOT RAISE <class 'cloudinit.config.schema.SchemaValidationError'>

tests/unittests/reporting/test_reporting.py:590: Failed
------------------------------ Captured log call -------------------------------
2024-09-18 16:50:33 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json (quiet=False)
2024-09-18 16:50:33 DEBUG     cloudinit.util:util.py:1622 Read 150110 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json
2024-09-18 16:50:33 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
__ TestReportingSchema.test_schema_validation[config15-'type' is a required] ___

self = <test_reporting.TestReportingSchema object at 0xffffb42a7290>
config = {'reporting': {'a': {'level': 'FATAL'}}}
error_msg = "'type' is a required"

    @pytest.mark.parametrize(
        "config, error_msg",
        [
            # GOOD: Minimum valid parameters
            ({"reporting": {"a": {"type": "print"}}}, None),
            ({"reporting": {"a": {"type": "log"}}}, None),
            (
                {
                    "reporting": {
                        "a": {"type": "webhook", "endpoint": "http://a"}
                    }
                },
                None,
            ),
            ({"reporting": {"a": {"type": "hyperv"}}}, None),
            # GOOD: All valid parameters
            ({"reporting": {"a": {"type": "log", "level": "WARN"}}}, None),
            (
                {
                    "reporting": {
                        "a": {
                            "type": "webhook",
                            "endpoint": "http://a";,
                            "timeout": 1,
                            "retries": 1,
                            "consumer_key": "somekey",
                            "token_key": "somekey",
                            "token_secret": "somesecret",
                            "consumer_secret": "somesecret",
                        }
                    }
                },
                None,
            ),
            (
                {
                    "reporting": {
                        "a": {
                            "type": "hyperv",
                            "kvp_file_path": "/some/path",
                            "event_types": ["a", "b"],
                        }
                    }
                },
                None,
            ),
            # GOOD: All combined together
            (
                {
                    "reporting": {
                        "a": {"type": "print"},
                        "b": {"type": "log", "level": "WARN"},
                        "c": {
                            "type": "webhook",
                            "endpoint": "http://a";,
                            "timeout": 1,
                            "retries": 1,
                            "consumer_key": "somekey",
                            "token_key": "somekey",
                            "token_secret": "somesecret",
                            "consumer_secret": "somesecret",
                        },
                        "d": {
                            "type": "hyperv",
                            "kvp_file_path": "/some/path",
                            "event_types": ["a", "b"],
                        },
                    }
                },
                None,
            ),
            # BAD: no top level objects
            ({"reporting": "a"}, "'a' is not of type 'object'"),
            ({"reporting": {"a": "b"}}, "'b' is not of type 'object'"),
            # BAD: invalid type
            (
                {"reporting": {"a": {"type": "b"}}},
                re.escape("'b' is not one of ['log']"),
            ),
            # BAD: invalid additional properties
            (
                {"reporting": {"a": {"type": "print", "a": "b"}}},
                "'a' was unexpected",
            ),
            (
                {"reporting": {"a": {"type": "log", "a": "b"}}},
                "'a' was unexpected",
            ),
            (
                {
                    "reporting": {
                        "a": {
                            "type": "webhook",
                            "endpoint": "http://a";,
                            "a": "b",
                        }
                    }
                },
                "'a' was unexpected",
            ),
            (
                {"reporting": {"a": {"type": "hyperv", "a": "b"}}},
                "'a' was unexpected",
            ),
            # BAD: missing required properties
            ({"reporting": {"a": {"level": "FATAL"}}}, "'type' is a required"),
            (
                {"reporting": {"a": {"endpoint": "http://a"}}},
                "'type' is a required",
            ),
            (
                {"reporting": {"a": {"kvp_file_path": "/a/b"}}},
                "'endpoint' is a required",
            ),
            (
                {"reporting": {"a": {"type": "webhook"}}},
                "'endpoint' is a required",
            ),
        ],
    )
    def test_schema_validation(self, config, error_msg):
        if error_msg is None:
            validate_cloudconfig_schema(config, get_schema(), strict=True)
        else:
>           with pytest.raises(SchemaValidationError, match=error_msg):
E           Failed: DID NOT RAISE <class 'cloudinit.config.schema.SchemaValidationError'>

tests/unittests/reporting/test_reporting.py:590: Failed
------------------------------ Captured log call -------------------------------
2024-09-18 16:50:33 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json (quiet=False)
2024-09-18 16:50:33 DEBUG     cloudinit.util:util.py:1622 Read 150110 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json
2024-09-18 16:50:33 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
__ TestReportingSchema.test_schema_validation[config16-'type' is a required] ___

self = <test_reporting.TestReportingSchema object at 0xffffb3b5ad00>
config = {'reporting': {'a': {'endpoint': 'http://a'}}}
error_msg = "'type' is a required"

    @pytest.mark.parametrize(
        "config, error_msg",
        [
            # GOOD: Minimum valid parameters
            ({"reporting": {"a": {"type": "print"}}}, None),
            ({"reporting": {"a": {"type": "log"}}}, None),
            (
                {
                    "reporting": {
                        "a": {"type": "webhook", "endpoint": "http://a"}
                    }
                },
                None,
            ),
            ({"reporting": {"a": {"type": "hyperv"}}}, None),
            # GOOD: All valid parameters
            ({"reporting": {"a": {"type": "log", "level": "WARN"}}}, None),
            (
                {
                    "reporting": {
                        "a": {
                            "type": "webhook",
                            "endpoint": "http://a";,
                            "timeout": 1,
                            "retries": 1,
                            "consumer_key": "somekey",
                            "token_key": "somekey",
                            "token_secret": "somesecret",
                            "consumer_secret": "somesecret",
                        }
                    }
                },
                None,
            ),
            (
                {
                    "reporting": {
                        "a": {
                            "type": "hyperv",
                            "kvp_file_path": "/some/path",
                            "event_types": ["a", "b"],
                        }
                    }
                },
                None,
            ),
            # GOOD: All combined together
            (
                {
                    "reporting": {
                        "a": {"type": "print"},
                        "b": {"type": "log", "level": "WARN"},
                        "c": {
                            "type": "webhook",
                            "endpoint": "http://a";,
                            "timeout": 1,
                            "retries": 1,
                            "consumer_key": "somekey",
                            "token_key": "somekey",
                            "token_secret": "somesecret",
                            "consumer_secret": "somesecret",
                        },
                        "d": {
                            "type": "hyperv",
                            "kvp_file_path": "/some/path",
                            "event_types": ["a", "b"],
                        },
                    }
                },
                None,
            ),
            # BAD: no top level objects
            ({"reporting": "a"}, "'a' is not of type 'object'"),
            ({"reporting": {"a": "b"}}, "'b' is not of type 'object'"),
            # BAD: invalid type
            (
                {"reporting": {"a": {"type": "b"}}},
                re.escape("'b' is not one of ['log']"),
            ),
            # BAD: invalid additional properties
            (
                {"reporting": {"a": {"type": "print", "a": "b"}}},
                "'a' was unexpected",
            ),
            (
                {"reporting": {"a": {"type": "log", "a": "b"}}},
                "'a' was unexpected",
            ),
            (
                {
                    "reporting": {
                        "a": {
                            "type": "webhook",
                            "endpoint": "http://a";,
                            "a": "b",
                        }
                    }
                },
                "'a' was unexpected",
            ),
            (
                {"reporting": {"a": {"type": "hyperv", "a": "b"}}},
                "'a' was unexpected",
            ),
            # BAD: missing required properties
            ({"reporting": {"a": {"level": "FATAL"}}}, "'type' is a required"),
            (
                {"reporting": {"a": {"endpoint": "http://a"}}},
                "'type' is a required",
            ),
            (
                {"reporting": {"a": {"kvp_file_path": "/a/b"}}},
                "'endpoint' is a required",
            ),
            (
                {"reporting": {"a": {"type": "webhook"}}},
                "'endpoint' is a required",
            ),
        ],
    )
    def test_schema_validation(self, config, error_msg):
        if error_msg is None:
            validate_cloudconfig_schema(config, get_schema(), strict=True)
        else:
>           with pytest.raises(SchemaValidationError, match=error_msg):
E           Failed: DID NOT RAISE <class 'cloudinit.config.schema.SchemaValidationError'>

tests/unittests/reporting/test_reporting.py:590: Failed
------------------------------ Captured log call -------------------------------
2024-09-18 16:50:33 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json (quiet=False)
2024-09-18 16:50:33 DEBUG     cloudinit.util:util.py:1622 Read 150110 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json
2024-09-18 16:50:33 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
_ TestReportingSchema.test_schema_validation[config17-'endpoint' is a required] _

self = <test_reporting.TestReportingSchema object at 0xffffb3b5ae60>
config = {'reporting': {'a': {'kvp_file_path': '/a/b'}}}
error_msg = "'endpoint' is a required"

    @pytest.mark.parametrize(
        "config, error_msg",
        [
            # GOOD: Minimum valid parameters
            ({"reporting": {"a": {"type": "print"}}}, None),
            ({"reporting": {"a": {"type": "log"}}}, None),
            (
                {
                    "reporting": {
                        "a": {"type": "webhook", "endpoint": "http://a"}
                    }
                },
                None,
            ),
            ({"reporting": {"a": {"type": "hyperv"}}}, None),
            # GOOD: All valid parameters
            ({"reporting": {"a": {"type": "log", "level": "WARN"}}}, None),
            (
                {
                    "reporting": {
                        "a": {
                            "type": "webhook",
                            "endpoint": "http://a";,
                            "timeout": 1,
                            "retries": 1,
                            "consumer_key": "somekey",
                            "token_key": "somekey",
                            "token_secret": "somesecret",
                            "consumer_secret": "somesecret",
                        }
                    }
                },
                None,
            ),
            (
                {
                    "reporting": {
                        "a": {
                            "type": "hyperv",
                            "kvp_file_path": "/some/path",
                            "event_types": ["a", "b"],
                        }
                    }
                },
                None,
            ),
            # GOOD: All combined together
            (
                {
                    "reporting": {
                        "a": {"type": "print"},
                        "b": {"type": "log", "level": "WARN"},
                        "c": {
                            "type": "webhook",
                            "endpoint": "http://a";,
                            "timeout": 1,
                            "retries": 1,
                            "consumer_key": "somekey",
                            "token_key": "somekey",
                            "token_secret": "somesecret",
                            "consumer_secret": "somesecret",
                        },
                        "d": {
                            "type": "hyperv",
                            "kvp_file_path": "/some/path",
                            "event_types": ["a", "b"],
                        },
                    }
                },
                None,
            ),
            # BAD: no top level objects
            ({"reporting": "a"}, "'a' is not of type 'object'"),
            ({"reporting": {"a": "b"}}, "'b' is not of type 'object'"),
            # BAD: invalid type
            (
                {"reporting": {"a": {"type": "b"}}},
                re.escape("'b' is not one of ['log']"),
            ),
            # BAD: invalid additional properties
            (
                {"reporting": {"a": {"type": "print", "a": "b"}}},
                "'a' was unexpected",
            ),
            (
                {"reporting": {"a": {"type": "log", "a": "b"}}},
                "'a' was unexpected",
            ),
            (
                {
                    "reporting": {
                        "a": {
                            "type": "webhook",
                            "endpoint": "http://a";,
                            "a": "b",
                        }
                    }
                },
                "'a' was unexpected",
            ),
            (
                {"reporting": {"a": {"type": "hyperv", "a": "b"}}},
                "'a' was unexpected",
            ),
            # BAD: missing required properties
            ({"reporting": {"a": {"level": "FATAL"}}}, "'type' is a required"),
            (
                {"reporting": {"a": {"endpoint": "http://a"}}},
                "'type' is a required",
            ),
            (
                {"reporting": {"a": {"kvp_file_path": "/a/b"}}},
                "'endpoint' is a required",
            ),
            (
                {"reporting": {"a": {"type": "webhook"}}},
                "'endpoint' is a required",
            ),
        ],
    )
    def test_schema_validation(self, config, error_msg):
        if error_msg is None:
            validate_cloudconfig_schema(config, get_schema(), strict=True)
        else:
>           with pytest.raises(SchemaValidationError, match=error_msg):
E           Failed: DID NOT RAISE <class 'cloudinit.config.schema.SchemaValidationError'>

tests/unittests/reporting/test_reporting.py:590: Failed
------------------------------ Captured log call -------------------------------
2024-09-18 16:50:33 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json (quiet=False)
2024-09-18 16:50:33 DEBUG     cloudinit.util:util.py:1622 Read 150110 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json
2024-09-18 16:50:33 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
_ TestReportingSchema.test_schema_validation[config18-'endpoint' is a required] _

self = <test_reporting.TestReportingSchema object at 0xffffb3ec4c30>
config = {'reporting': {'a': {'type': 'webhook'}}}
error_msg = "'endpoint' is a required"

    @pytest.mark.parametrize(
        "config, error_msg",
        [
            # GOOD: Minimum valid parameters
            ({"reporting": {"a": {"type": "print"}}}, None),
            ({"reporting": {"a": {"type": "log"}}}, None),
            (
                {
                    "reporting": {
                        "a": {"type": "webhook", "endpoint": "http://a"}
                    }
                },
                None,
            ),
            ({"reporting": {"a": {"type": "hyperv"}}}, None),
            # GOOD: All valid parameters
            ({"reporting": {"a": {"type": "log", "level": "WARN"}}}, None),
            (
                {
                    "reporting": {
                        "a": {
                            "type": "webhook",
                            "endpoint": "http://a";,
                            "timeout": 1,
                            "retries": 1,
                            "consumer_key": "somekey",
                            "token_key": "somekey",
                            "token_secret": "somesecret",
                            "consumer_secret": "somesecret",
                        }
                    }
                },
                None,
            ),
            (
                {
                    "reporting": {
                        "a": {
                            "type": "hyperv",
                            "kvp_file_path": "/some/path",
                            "event_types": ["a", "b"],
                        }
                    }
                },
                None,
            ),
            # GOOD: All combined together
            (
                {
                    "reporting": {
                        "a": {"type": "print"},
                        "b": {"type": "log", "level": "WARN"},
                        "c": {
                            "type": "webhook",
                            "endpoint": "http://a";,
                            "timeout": 1,
                            "retries": 1,
                            "consumer_key": "somekey",
                            "token_key": "somekey",
                            "token_secret": "somesecret",
                            "consumer_secret": "somesecret",
                        },
                        "d": {
                            "type": "hyperv",
                            "kvp_file_path": "/some/path",
                            "event_types": ["a", "b"],
                        },
                    }
                },
                None,
            ),
            # BAD: no top level objects
            ({"reporting": "a"}, "'a' is not of type 'object'"),
            ({"reporting": {"a": "b"}}, "'b' is not of type 'object'"),
            # BAD: invalid type
            (
                {"reporting": {"a": {"type": "b"}}},
                re.escape("'b' is not one of ['log']"),
            ),
            # BAD: invalid additional properties
            (
                {"reporting": {"a": {"type": "print", "a": "b"}}},
                "'a' was unexpected",
            ),
            (
                {"reporting": {"a": {"type": "log", "a": "b"}}},
                "'a' was unexpected",
            ),
            (
                {
                    "reporting": {
                        "a": {
                            "type": "webhook",
                            "endpoint": "http://a";,
                            "a": "b",
                        }
                    }
                },
                "'a' was unexpected",
            ),
            (
                {"reporting": {"a": {"type": "hyperv", "a": "b"}}},
                "'a' was unexpected",
            ),
            # BAD: missing required properties
            ({"reporting": {"a": {"level": "FATAL"}}}, "'type' is a required"),
            (
                {"reporting": {"a": {"endpoint": "http://a"}}},
                "'type' is a required",
            ),
            (
                {"reporting": {"a": {"kvp_file_path": "/a/b"}}},
                "'endpoint' is a required",
            ),
            (
                {"reporting": {"a": {"type": "webhook"}}},
                "'endpoint' is a required",
            ),
        ],
    )
    def test_schema_validation(self, config, error_msg):
        if error_msg is None:
            validate_cloudconfig_schema(config, get_schema(), strict=True)
        else:
>           with pytest.raises(SchemaValidationError, match=error_msg):
E           Failed: DID NOT RAISE <class 'cloudinit.config.schema.SchemaValidationError'>

tests/unittests/reporting/test_reporting.py:590: Failed
------------------------------ Captured log call -------------------------------
2024-09-18 16:50:33 DEBUG     cloudinit.util:util.py:1613 Reading from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json (quiet=False)
2024-09-18 16:50:33 DEBUG     cloudinit.util:util.py:1622 Read 150110 bytes from /<<PKGBUILDDIR>>/cloudinit/config/schemas/schema-cloud-config-v1.json
2024-09-18 16:50:33 DEBUG     cloudinit.config.schema:schema.py:769 Ignoring schema validation. jsonschema is not present
=============================== warnings summary ===============================
tests/unittests/distros/package_management/test_apt.py:122
  /<<PKGBUILDDIR>>/tests/unittests/distros/package_management/test_apt.py:122: PytestCollectionWarning: cannot collect test class 'TestUpdatePackageSources' because it has a __init__ constructor (from: tests/unittests/distros/package_management/test_apt.py)
    @mock.patch.object(

tests/unittests/analyze/test_boot.py::TestAnalyzeBoot::test_boot_invalid_distro
tests/unittests/analyze/test_boot.py::TestAnalyzeBoot::test_container_no_ci_log_line
tests/unittests/analyze/test_boot.py::TestAnalyzeBoot::test_container_ci_log_line
  /<<PKGBUILDDIR>>/cloudinit/analyze/__init__.py:131: DeprecationWarning: datetime.datetime.utcfromtimestamp() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.fromtimestamp(timestamp, datetime.UTC).
    kernel_start_timestamp = datetime.utcfromtimestamp(kernel_start)

tests/unittests/analyze/test_boot.py::TestAnalyzeBoot::test_boot_invalid_distro
tests/unittests/analyze/test_boot.py::TestAnalyzeBoot::test_container_no_ci_log_line
tests/unittests/analyze/test_boot.py::TestAnalyzeBoot::test_container_ci_log_line
  /<<PKGBUILDDIR>>/cloudinit/analyze/__init__.py:132: DeprecationWarning: datetime.datetime.utcfromtimestamp() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.fromtimestamp(timestamp, datetime.UTC).
    kernel_end_timestamp = datetime.utcfromtimestamp(kernel_end)

tests/unittests/analyze/test_boot.py::TestAnalyzeBoot::test_boot_invalid_distro
tests/unittests/analyze/test_boot.py::TestAnalyzeBoot::test_container_no_ci_log_line
tests/unittests/analyze/test_boot.py::TestAnalyzeBoot::test_container_ci_log_line
  /<<PKGBUILDDIR>>/cloudinit/analyze/__init__.py:133: DeprecationWarning: datetime.datetime.utcfromtimestamp() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.fromtimestamp(timestamp, datetime.UTC).
    ci_sysd_start_timestamp = datetime.utcfromtimestamp(ci_sysd_start)

tests/unittests/analyze/test_boot.py::TestAnalyzeBoot::test_container_ci_log_line
  /<<PKGBUILDDIR>>/cloudinit/analyze/__init__.py:141: DeprecationWarning: datetime.datetime.utcfromtimestamp() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.fromtimestamp(timestamp, datetime.UTC).
    ci_start = datetime.utcfromtimestamp(last_init_local["timestamp"])

tests/unittests/analyze/test_dump.py::TestParseCILogLine::test_parse_logline_returns_event_for_amazon_linux_2_line
  /<<PKGBUILDDIR>>/tests/unittests/analyze/test_dump.py:201: DeprecationWarning: Parsing dates involving a day of month without a year specified is ambiguious
  and fails to parse leap day. The default behavior will change in Python 3.15
  to either always raise an exception or to use a different default year (TBD).
  To avoid trouble, add a specific year to the input & format.
  See https://github.com/python/cpython/issues/70647.
    datetime.strptime("Apr 30 19:39:11", "%b %d %H:%M:%S")

tests/unittests/cmd/devel/test_logs.py::TestCollectLogs::test_collect_logs_end_to_end
  /<<PKGBUILDDIR>>/tests/unittests/cmd/devel/test_logs.py:144: DeprecationWarning: Python 3.14 will, by default, filter extracted tar archives and reject files or modify their metadata. Use the filter argument to control this behavior.
    tar.extractall(extract_to)

tests/unittests/reporting/test_reporting_hyperv.py: 13 warnings
  /<<PKGBUILDDIR>>/cloudinit/reporting/handlers.py:376: DeprecationWarning: datetime.datetime.utcfromtimestamp() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.fromtimestamp(timestamp, datetime.UTC).
    datetime.utcfromtimestamp(event.timestamp).isoformat() + "Z"

tests/unittests/reporting/test_reporting_hyperv.py::TextKvpReporter::test_get_boot_telemetry
  /<<PKGBUILDDIR>>/cloudinit/sources/helpers/azure.py:125: DeprecationWarning: datetime.datetime.utcfromtimestamp() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.fromtimestamp(timestamp, datetime.UTC).
    datetime.utcfromtimestamp(kernel_start).isoformat() + "Z",

tests/unittests/reporting/test_reporting_hyperv.py::TextKvpReporter::test_get_boot_telemetry
  /<<PKGBUILDDIR>>/cloudinit/sources/helpers/azure.py:126: DeprecationWarning: datetime.datetime.utcfromtimestamp() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.fromtimestamp(timestamp, datetime.UTC).
    datetime.utcfromtimestamp(user_start).isoformat() + "Z",

tests/unittests/reporting/test_reporting_hyperv.py::TextKvpReporter::test_get_boot_telemetry
  /<<PKGBUILDDIR>>/cloudinit/sources/helpers/azure.py:127: DeprecationWarning: datetime.datetime.utcfromtimestamp() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.fromtimestamp(timestamp, datetime.UTC).
    datetime.utcfromtimestamp(cloudinit_activation).isoformat() + "Z",

tests/unittests/sources/azure/test_errors.py: 48 warnings
  /<<PKGBUILDDIR>>/tests/unittests/sources/azure/test_errors.py:23: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC).
    timestamp = datetime.datetime.utcnow()

tests/unittests/sources/azure/test_errors.py: 13 warnings
tests/unittests/sources/azure/test_kvp.py: 2 warnings
tests/unittests/sources/test_azure.py: 107 warnings
tests/unittests/sources/test_azure_helper.py: 11 warnings
  /<<PKGBUILDDIR>>/cloudinit/sources/azure/errors.py:55: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC).
    self.timestamp = datetime.utcnow()

tests/unittests/sources/azure/test_kvp.py::TestReportSuccessToHost::test_report_success_to_host
  /<<PKGBUILDDIR>>/tests/unittests/sources/azure/test_kvp.py:14: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC).
    timestamp = datetime.utcnow()

tests/unittests/sources/azure/test_kvp.py: 1 warning
tests/unittests/sources/test_azure.py: 49 warnings
  /<<PKGBUILDDIR>>/cloudinit/sources/azure/kvp.py:52: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC).
    f"timestamp={datetime.utcnow().isoformat()}",

tests/unittests/sources/test_azure.py: 72 warnings
tests/unittests/sources/test_azure_helper.py: 17 warnings
  /<<PKGBUILDDIR>>/cloudinit/sources/helpers/azure.py:1014: DeprecationWarning: Testing an element's truth value will always return True in future versions.  Use specific 'len(elem)' or 'elem is not None' test instead.
    if not root.find("./wa:ProvisioningSection", cls.NAMESPACES):

tests/unittests/sources/test_azure.py: 24 warnings
  /<<PKGBUILDDIR>>/tests/unittests/sources/test_azure.py:318: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC).
    timestamp = datetime.datetime.utcnow()

tests/unittests/sources/test_gce.py::TestDataSourceGCE::test_has_expired
tests/unittests/sources/test_gce.py::TestDataSourceGCE::test_has_expired
  /<<PKGBUILDDIR>>/cloudinit/sources/DataSourceGCE.py:236: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC).
    return datetime.datetime.utcnow() > expire_time

tests/unittests/test_cli.py: 16 warnings
  /<<PKGBUILDDIR>>/tests/unittests/test_cli.py:36: PytestMockWarning: Mocks returned by pytest-mock do not need to be used as context managers. The mocker fixture automatically undoes mocking at the end of a test. This warning can be ignored if it was triggered by mocking a context manager. https://pytest-mock.readthedocs.io/en/latest/remarks.html#usage-as-context-manager
    with mocker.patch(

tests/unittests/test_cli.py: 16 warnings
  /<<PKGBUILDDIR>>/tests/unittests/test_cli.py:39: PytestMockWarning: Mocks returned by pytest-mock do not need to be used as context managers. The mocker fixture automatically undoes mocking at the end of a test. This warning can be ignored if it was triggered by mocking a context manager. https://pytest-mock.readthedocs.io/en/latest/remarks.html#usage-as-context-manager
    ), mocker.patch(

tests/unittests/test_ds_identify.py::TestDsIdentify::test_ibmcloud_template_no_userdata_in_provisioning
  /usr/lib/python3.13/unittest/case.py:707: DeprecationWarning: It is deprecated to return a value that is not None from a test case (<bound method TestDsIdentify.test_ibmcloud_template_no_userdata_in_provisioning of <tests.unittests.test_ds_identify.TestDsIdentify testMethod=test_ibmcloud_template_no_userdata_in_provisioning>>)
    return self.run(*args, **kwds)

tests/unittests/test_ds_identify.py::TestDsIdentify::test_ibmcloud_template_userdata_in_provisioning
  /usr/lib/python3.13/unittest/case.py:707: DeprecationWarning: It is deprecated to return a value that is not None from a test case (<bound method TestDsIdentify.test_ibmcloud_template_userdata_in_provisioning of <tests.unittests.test_ds_identify.TestDsIdentify testMethod=test_ibmcloud_template_userdata_in_provisioning>>)
    return self.run(*args, **kwds)

tests/unittests/test_ds_identify.py::TestDsIdentify::test_vmware_on_vmware_open_vm_tools_64
  /usr/lib/python3.13/unittest/case.py:707: DeprecationWarning: It is deprecated to return a value that is not None from a test case (<bound method TestDsIdentify.test_vmware_on_vmware_open_vm_tools_64 of <tests.unittests.test_ds_identify.TestDsIdentify testMethod=test_vmware_on_vmware_open_vm_tools_64>>)
    return self.run(*args, **kwds)

tests/unittests/test_ds_identify.py::TestDsIdentify::test_vmware_on_vmware_open_vm_tools_aarch64_linux_gnu
  /usr/lib/python3.13/unittest/case.py:707: DeprecationWarning: It is deprecated to return a value that is not None from a test case (<bound method TestDsIdentify.test_vmware_on_vmware_open_vm_tools_aarch64_linux_gnu of <tests.unittests.test_ds_identify.TestDsIdentify testMethod=test_vmware_on_vmware_open_vm_tools_aarch64_linux_gnu>>)
    return self.run(*args, **kwds)

tests/unittests/test_ds_identify.py::TestDsIdentify::test_vmware_on_vmware_open_vm_tools_i386_linux_gnu
  /usr/lib/python3.13/unittest/case.py:707: DeprecationWarning: It is deprecated to return a value that is not None from a test case (<bound method TestDsIdentify.test_vmware_on_vmware_open_vm_tools_i386_linux_gnu of <tests.unittests.test_ds_identify.TestDsIdentify testMethod=test_vmware_on_vmware_open_vm_tools_i386_linux_gnu>>)
    return self.run(*args, **kwds)

tests/unittests/test_ds_identify.py::TestDsIdentify::test_vmware_on_vmware_open_vm_tools_x86_64_linux_gnu
  /usr/lib/python3.13/unittest/case.py:707: DeprecationWarning: It is deprecated to return a value that is not None from a test case (<bound method TestDsIdentify.test_vmware_on_vmware_open_vm_tools_x86_64_linux_gnu of <tests.unittests.test_ds_identify.TestDsIdentify testMethod=test_vmware_on_vmware_open_vm_tools_x86_64_linux_gnu>>)
    return self.run(*args, **kwds)

tests/unittests/test_ds_identify.py::TestWSL::test_empty_cloudinitdir
  /usr/lib/python3.13/unittest/case.py:707: DeprecationWarning: It is deprecated to return a value that is not None from a test case (<bound method TestWSL.test_empty_cloudinitdir of <tests.unittests.test_ds_identify.TestWSL testMethod=test_empty_cloudinitdir>>)
    return self.run(*args, **kwds)

tests/unittests/test_ds_identify.py::TestWSL::test_found_via_userdata
  /usr/lib/python3.13/unittest/case.py:707: DeprecationWarning: It is deprecated to return a value that is not None from a test case (<bound method TestWSL.test_found_via_userdata of <tests.unittests.test_ds_identify.TestWSL testMethod=test_found_via_userdata>>)
    return self.run(*args, **kwds)

tests/unittests/test_ds_identify.py::TestWSL::test_no_cloudinitdir_in_userprofile
  /usr/lib/python3.13/unittest/case.py:707: DeprecationWarning: It is deprecated to return a value that is not None from a test case (<bound method TestWSL.test_no_cloudinitdir_in_userprofile of <tests.unittests.test_ds_identify.TestWSL testMethod=test_no_cloudinitdir_in_userprofile>>)
    return self.run(*args, **kwds)

tests/unittests/test_ds_identify.py::TestWSL::test_no_userprofile
  /usr/lib/python3.13/unittest/case.py:707: DeprecationWarning: It is deprecated to return a value that is not None from a test case (<bound method TestWSL.test_no_userprofile of <tests.unittests.test_ds_identify.TestWSL testMethod=test_no_userprofile>>)
    return self.run(*args, **kwds)

tests/unittests/test_log.py::TestCloudInitLogger::test_logger_uses_gmtime
  /<<PKGBUILDDIR>>/tests/unittests/test_log.py:47: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC).
    utc_before = datetime.datetime.utcnow() - datetime.timedelta(0, 0.5)

tests/unittests/test_log.py::TestCloudInitLogger::test_logger_uses_gmtime
  /<<PKGBUILDDIR>>/tests/unittests/test_log.py:49: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC).
    utc_after = datetime.datetime.utcnow() + datetime.timedelta(0, 0.5)

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
=========================== short test summary info ============================
FAILED tests/unittests/config/test_schema.py::TestVersionedSchemas::test_versioned_cloud_config_schema_is_valid_json[schema2-is not one of ['v1']]
FAILED tests/unittests/config/test_schema.py::TestVersionedSchemas::test_versioned_cloud_config_schema_is_valid_json[schema3-is not of type 'string']
FAILED tests/unittests/config/test_schema.py::TestMain::test_main_validates_config_file[None-#cloud-config\nntp:-Valid schema]
FAILED tests/unittests/config/test_schema.py::TestMain::test_main_validates_config_file[cloud-config-#cloud-config\nntp:-Valid schema]
FAILED tests/unittests/config/test_schema.py::TestMain::test_main_validates_config_file[network-config-network: {'version': 2, 'ethernets': {'eth0': {'dhcp': true}}}-Valid schema]
FAILED tests/unittests/config/test_schema.py::TestMain::test_main_validates_config_file[network-config-network:\n version: 1\n config:\n  - type: physical\n    name: eth0\n    subnets:\n      - type: dhcp\n-Valid schema]
FAILED tests/unittests/config/test_schema.py::TestMain::test_main_processed_data_preference_over_raw_data[prefer_processed_data_when_present_and_non_empty]
FAILED tests/unittests/config/test_schema.py::TestMain::test_main_processed_data_preference_over_raw_data[prefer_raw_data_when_processed_is_empty]
FAILED tests/unittests/config/test_schema.py::TestMain::test_main_processed_data_preference_over_raw_data[prefer_processed_vd_file_path_when_raw_and_processed_empty]
FAILED tests/unittests/config/test_schema.py::TestMain::test_main_validates_system_userdata_vendordata_and_network_config[netv1_schema_validated]
FAILED tests/unittests/config/test_schema.py::TestMain::test_main_validates_system_userdata_vendordata_and_network_config[netv2_schema_validated_non_netplan]
FAILED tests/unittests/config/test_schema.py::TestMain::test_main_validates_system_userdata_vendordata_and_network_config[empty_net_validation_is_skipped]
FAILED tests/unittests/config/test_schema.py::TestMain::test_main_validates_system_userdata_vendordata_and_network_config[netv1_schema_errors_handled]
FAILED tests/unittests/config/test_schema.py::TestMain::test_main_validates_system_userdata_vendordata_and_network_config[netv1_schema_error_on_nic_name_length]
FAILED tests/unittests/config/test_schema.py::TestNetworkSchema::test_network_schema[net_v2_invalid_config]
FAILED tests/unittests/config/test_schema.py::TestNetworkSchema::test_network_schema[config_key_required0]
FAILED tests/unittests/config/test_schema.py::TestNetworkSchema::test_network_schema[unknown_config_type_item]
FAILED tests/unittests/config/test_schema.py::TestNetworkSchema::test_network_schema[physical_requires_name_property]
FAILED tests/unittests/config/test_schema.py::TestNetworkSchema::test_network_schema[physical_no_additional_properties]
FAILED tests/unittests/config/test_schema.py::TestHandleSchemaArgs::test_handle_schema_unable_to_read_cfg_paths[failure0-expected_logs0]
FAILED tests/unittests/config/test_schema.py::TestHandleSchemaArgs::test_handle_schema_unable_to_read_cfg_paths[failure1-expected_logs1]
FAILED tests/unittests/config/test_schema.py::TestHandleSchemaArgs::test_handle_schema_args_annotate_deprecated_config[test_annotated_deprecation_info_boundary_devel_shows]
FAILED tests/unittests/config/test_schema.py::TestHandleSchemaArgs::test_handle_schema_args_annotate_deprecated_config[test_annotated_deprecation_info_boundary_below_unredacted]
FAILED tests/unittests/config/test_schema.py::TestHandleSchemaArgs::test_handle_schema_args_annotate_deprecated_config[test_deprecation_info_boundary_does_unannotated_unredacted]
FAILED tests/unittests/config/test_schema.py::TestHandleSchemaArgs::test_handle_schema_args_jinja_with_errors[root_annotate_errors_with_exception]
FAILED tests/unittests/config/test_schema.py::TestHandleSchemaArgs::test_handle_schema_args_jinja_with_errors[root_no_annotate_exception_with_unique_errors]
FAILED tests/unittests/reporting/test_reporting.py::TestReportingSchema::test_schema_validation[config8-'a' is not of type 'object']
FAILED tests/unittests/reporting/test_reporting.py::TestReportingSchema::test_schema_validation[config9-'b' is not of type 'object']
FAILED tests/unittests/reporting/test_reporting.py::TestReportingSchema::test_schema_validation[config10-'b'\\ is\\ not\\ one\\ of\\ \\['log'\\]]
FAILED tests/unittests/reporting/test_reporting.py::TestReportingSchema::test_schema_validation[config11-'a' was unexpected]
FAILED tests/unittests/reporting/test_reporting.py::TestReportingSchema::test_schema_validation[config12-'a' was unexpected]
FAILED tests/unittests/reporting/test_reporting.py::TestReportingSchema::test_schema_validation[config13-'a' was unexpected]
FAILED tests/unittests/reporting/test_reporting.py::TestReportingSchema::test_schema_validation[config14-'a' was unexpected]
FAILED tests/unittests/reporting/test_reporting.py::TestReportingSchema::test_schema_validation[config15-'type' is a required]
FAILED tests/unittests/reporting/test_reporting.py::TestReportingSchema::test_schema_validation[config16-'type' is a required]
FAILED tests/unittests/reporting/test_reporting.py::TestReportingSchema::test_schema_validation[config17-'endpoint' is a required]
FAILED tests/unittests/reporting/test_reporting.py::TestReportingSchema::test_schema_validation[config18-'endpoint' is a required]
= 37 failed, 4596 passed, 489 skipped, 18 xfailed, 420 warnings in 83.49s (0:01:23) =
make[1]: *** [debian/rules:10: override_dh_auto_test] Error 1
make[1]: Leaving directory '/<<PKGBUILDDIR>>'
make: *** [debian/rules:7: build] Error 2
dpkg-buildpackage: error: debian/rules build subprocess returned exit status 2
--------------------------------------------------------------------------------
Build finished at 2024-09-18T16:51:29Z

If required, the full build log is available here (for the next 30 days):
https://debusine.debian.net/artifact/776771/

This bug has been filed at "normal" severity, as we haven't started the
transition to add 3.13 as a supported version, yet. This will be raised to RC
as soon as that happens, hopefully well before trixie.

Thanks,

Stefano


Reply to: