Ctrl K
ComunidadGuías…

hack/package-test-target-coverage.bats

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
#!/usr/bin/env bats
# -----------------------------------------------------------------------------
# Coverage invariant for the helm-unittest sweep: every package that ships a
# suite must answer the probe the sweep opens with.
#
# hack/helm-unit-tests.sh decides whether to enter a package directory by asking
# `make -C "$dir" -n test`, and a package that answers "No rule to make target"
# is skipped without a word. Every other guard in that script — the shadowed
# target check, the zero-suite check, the positive-evidence check — runs inside
# a directory the sweep already reached, so a package missing the target escapes
# all of them at once and the sweep still reports success. The suites under
# tests/ then read as coverage to anyone opening the directory while nothing
# executes them, which is worse than having no suite at all: a suite that has
# never run is where a stale assertion hides. packages/system/gpu-operator sat
# in exactly that state, with three passing test cases nothing ever ran.
#
# hack/helm-unit-tests.bats covers the script's own reactions against synthetic
# trees. This file makes the complementary claim, about the real tree: every
# package that ships a suite answers the probe the sweep opens with.
#
# That is narrower than "the sweep reaches every suite", and deliberately so.
# Reach also depends on the hardcoded root list the sweep loops over, so
# dropping packages/system from it would take every package under that root out
# of the run while each one keeps its target and this file stays green. That is
# the same shape as the packages/tests incident recorded in the sweep's own
# header, and it wants its own guard rather than a looser predicate here.
#
# The predicate is "holds at least one tests/*_test.yaml", not "has a tests/
# directory". That glob is helm-unittest's own default, so a package outside it
# has nothing of its own for a `test:` target to run and the sweep would reject
# it for reporting zero suites. packages/system/nfs-driver is the live case:
# its tests/ holds a PersistentVolumeClaim and a StorageClass to apply by hand,
# not a suite.
#
# "Of its own" is the load-bearing part. `--with-subchart` defaults to true, so
# a package carrying no suite of its own would still run any that came down
# with a vendored chart under charts/, and this predicate would not look for it.
# Only ingress-nginx and reloader vendor such suites today and both ship their
# own as well, so nothing is out of reach; a package that vendored suites and
# wrote none itself would need this predicate widened.
#
# Probed with `make -n` rather than by grepping the Makefile for `test:`, so the
# question asked here is the same one the sweep asks — a target reached through
# an include counts, and so would a rule this file cannot parse. The sweep's
# other precondition, that `$dir/Makefile` exists, is mirrored rather than left
# to make, which is looser about the name and about there being a makefile at
# all.
#
# The verdict comes from the sweep's command unchanged. Reading the diagnostic
# needs `LC_ALL=C` and `--no-print-directory`, and both are visible to a
# Makefile through `LC_ALL` and `MAKEFLAGS`, so a Makefile branching on either
# would answer this file and the sweep differently. That is why the failing
# package is probed a second time to explain rather than once to do both.
#
# Answering the probe is not the same as declaring a recipe: a path named `test`
# beside the Makefile, or an implicit rule that can build one, satisfies it too,
# and this file would report that package as covered. That is deliberate rather
# than overlooked. It is the sweep's own gate, so a package passing here is a
# package the sweep enters once it walks that package's root, which is the
# whole claim and no more than it: the root list is the caveat above. From
# inside, the sweep's positive-evidence check refuses whatever does not print
# the line a helm-unittest run emits. A pattern rule written to run
# helm-unittest would satisfy that check on its merits, which is the right
# outcome rather than a hole: the suites would be running.
#
# Not the "is up to date" check, which is the near miss worth naming. A path
# named `test` with no rule behind it makes make print "Nothing to be done for
# 'test'." and exit 0, which that grep does not match; measured on 3.81 and
# 4.4.1. "is up to date" is what make prints for the third case, a real recipe
# shadowed by a file of that name -- the one `.PHONY: test` prevents.
#
# Runs under hack/cozytest.sh, which is POSIX /bin/sh: no arrays, no bats `run`,
# no `$status`.
# -----------------------------------------------------------------------------

load test_helper

REPO_ROOT="$(cd "$(dirname "${BATS_TEST_FILENAME:-$0}")/.." && pwd)"

@test "every package shipping a helm-unittest suite answers the sweep probe" {
    # An empty violation list means "no violations" only if the scan reached
    # some packages. A renamed directory or a wrong root yields the same empty
    # string, and the test would pass having read nothing.
    scanned=0
    # cozytest.sh injects `set -u`, so every variable the loop reads is seeded
    # here rather than on first append.
    seen=""
    diagnostics=""

    for suite in "$REPO_ROOT"/packages/*/*/tests/*_test.yaml; do
        [ -f "$suite" ] || continue
        pkg=$(dirname "$(dirname "$suite")")
        # One package may ship several suites; count and probe it once.
        case " $seen " in
            *" $pkg "*) continue ;;
        esac
        seen="$seen $pkg"
        scanned=$((scanned + 1))

        # The sweep opens with `[ -f "$dir/Makefile" ]` and returns before it
        # probes anything, so mirror that first. make would not: it also accepts
        # GNUmakefile and makefile, and with no makefile at all it still answers
        # 0 for a target a path of that name satisfies. Either shape would pass
        # the probe below while the sweep skipped the package, which is the one
        # thing this file claims cannot happen.
        if [ ! -f "$pkg/Makefile" ]; then
            diagnostics="$diagnostics
  ${pkg#"$REPO_ROOT"/}: no Makefile, so the sweep returns before probing"
            continue
        fi

        # The verdict is taken from the sweep's own command, byte for byte, so
        # that no flag of this file's can separate the two answers. Deciding and
        # explaining are split for that reason: anything added here to make the
        # output readable is a variable a Makefile could branch on.
        if ! make -C "$pkg" -n test >/dev/null 2>&1; then
            # Only now, and only to explain. LC_ALL=C keeps make's wording in
            # the language the remedy text below is written against.
            #
            # --no-print-directory because on modern GNU make `-C` auto-enables
            # `-w`, and the fatal path prints the "Leaving directory" line after
            # the error, so `tail -n 1` would report the directory trace and
            # drop every diagnostic this block exists to surface: a missing rule
            # and a broken include collapse to the same trace line. Measured on
            # 4.4.1, where it happens, and on 3.81 -- still the /usr/bin/make on
            # macOS -- where `-C` prints no trace at all, so a local run cannot
            # see the difference. The version that draws the line was not
            # measured.
            #
            # `|| true` because this re-run is expected to fail and cozytest.sh
            # injects `set -e`; the verdict is already decided above.
            probe=$(LC_ALL=C make --no-print-directory -C "$pkg" -n test 2>&1 || true)

            # A missing rule is the expected cause, but an unparseable Makefile
            # and a broken include fail the same probe and have a different
            # remedy. Report what make said rather than asserting the cause.
            diagnostics="$diagnostics
  ${pkg#"$REPO_ROOT"/}: $(printf '%s' "$probe" | tail -n 1)"
        fi
    done

    if [ "$scanned" -eq 0 ]; then
        echo "no tests/*_test.yaml found under $REPO_ROOT/packages -- guard is blind." >&2
        return 1
    fi

    if [ -n "$diagnostics" ]; then
        echo "Packages shipping a helm-unittest suite the sweep cannot reach:" >&2
        # Each entry is appended with a leading newline, so the accumulator
        # opens with an empty one; drop it rather than the reader parsing a
        # blank first line under pressure.
        printf '%s\n' "$diagnostics" | sed '/^$/d' >&2
        echo "hack/helm-unit-tests.sh probes 'make -C <pkg> -n test' to decide whether" >&2
        echo "to enter a package, so these suites never run and the sweep stays green." >&2
        echo "Where the reason is a missing rule, add to that Makefile:" >&2
        echo "    .PHONY: test" >&2
        echo "    test:" >&2
        echo "    	helm unittest ." >&2
        return 1
    fi
}