aboutsummaryrefslogtreecommitdiff
path: root/scripts/testing/tests/conftest.py
blob: 00632b6a9d8f3b8fd87076c222536df96922b10f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# SPDX-License-Identifier: GPL-3.0-or-later
"""Pytest + Testinfra config for archsetup post-install validation.

These tests run on the *host* and connect to the freshly-installed VM over SSH
(Testinfra provides the `host` fixture, parametrized from --hosts). This file
adds two things the bespoke shell harness had that Testinfra does not:

  - Failure attribution. Each check is marked with the layer that owns a
    failure (archsetup | base_install | unknown), mirroring validation.sh's
    attribute_issue. Failures are bucketed and written to --attribution-file
    so run-test.sh can route base-install issues to the archzfs inbox as before.
  - Tiering markers (smoke | integration) so `pytest -m smoke` is a fast gate.

The `target_user` fixture supplies the account archsetup created; it reads
ARCHSETUP_TEST_USER (set by run-test.sh from the VM conf) and defaults to the
historical "cjennings".
"""

import os

import pytest


_ATTRIBUTION_BUCKETS = ("archsetup", "base_install", "unknown")
_failures = {bucket: [] for bucket in _ATTRIBUTION_BUCKETS}


def pytest_addoption(parser):
    parser.addoption(
        "--attribution-file",
        action="store",
        default=None,
        help="write the failure attribution report (archsetup/base_install/unknown) here",
    )


def pytest_configure(config):
    config.addinivalue_line(
        "markers",
        "attribution(bucket): layer that owns a failure — archsetup, base_install, or unknown",
    )
    config.addinivalue_line("markers", "smoke: fast subset (user, key packages, dotfiles present)")
    config.addinivalue_line("markers", "integration: full post-install checks")


@pytest.hookimpl(wrapper=True)
def pytest_runtest_makereport(item, call):
    report = yield
    if report.when == "call" and report.failed:
        marker = item.get_closest_marker("attribution")
        bucket = marker.args[0] if (marker and marker.args) else "archsetup"
        if bucket not in _failures:
            bucket = "unknown"
        _failures[bucket].append(item.nodeid)
    return report


def pytest_sessionfinish(session, exitstatus):
    path = session.config.getoption("--attribution-file")
    if not path:
        return
    with open(path, "w") as fh:
        for bucket in _ATTRIBUTION_BUCKETS:
            fh.write("[%s]\n" % bucket)
            for nodeid in _failures[bucket]:
                fh.write("  %s\n" % nodeid)


@pytest.fixture(scope="session")
def target_user():
    """The account archsetup created in the VM under test."""
    return os.environ.get("ARCHSETUP_TEST_USER", "cjennings")