Files
cozystack/hack/unit-test-parallelism.bats
Myasnikov Daniil 8456facc79 test(e2e): pin the stability-window reset and keep the fan-out test portable
The readiness gate resets its stability window when a list read fails,
and nothing held that: the existing "transient list error" case fails on
the first read, when there is no window to invalidate, so removing the
reset left the suite green. The new case breaks a read mid-window, where
a gate that kept counting through the gap would accept a release set it
never observed stable across it.

The parallel fan-out contract asked make for --output-sync, which arrived
in GNU Make 4.0 while macOS still ships 3.81 -- so on a contributor's
machine the suite died on an unknown option instead of reporting the
contract. Guarded by version, with the reason in place. CI runs 4.x, so
the contract is still enforced where it gates a merge.

Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
Assisted-By: LLM
2026-09-07 16:33:27 +05:00

42 lines
2.1 KiB
Bash

#!/usr/bin/env bats
# Contract for the bounded parallel unit-test fan-out used by PR CI.
@test "every non-E2E BATS file is an independent Make prerequisite" {
# --output-sync arrived in GNU Make 4.0, and macOS still ships 3.81, where
# this invocation dies on an unknown option rather than telling the reader
# why. CI is on 4.x, so the contract is still enforced where it gates a
# merge; skipping here keeps the suite runnable on a contributor's machine
# instead of failing for a reason that has nothing to do with the contract.
make_major=$(make --version 2>/dev/null | sed -n '1s/^GNU Make \([0-9][0-9]*\).*/\1/p')
if [ -z "$make_major" ] || [ "$make_major" -lt 4 ]; then
echo "skipped: this make has no --output-sync (needs GNU Make >= 4.0)" >&2
return 0
fi
expected=$(find hack -maxdepth 1 -type f -name '*.bats' ! -name 'e2e-*.bats' | wc -l)
output=$(make -n -j4 --output-sync=target bats-unit-tests)
# The COZYTEST_TRACE prefix is part of the pattern on purpose: the switch is
# per-target now that the serial loop is gone, and a target that loses it
# would go back to streaming full xtrace for every suite.
actual=$(printf '%s\n' "$output" | grep -c '^COZYTEST_TRACE=[^ ]* hack/cozytest.sh "hack/.*\.bats"$')
[ "$actual" -eq "$expected" ] || {
echo "make scheduled $actual BATS files independently, expected $expected" >&2
exit 1
}
if printf '%s\n' "$output" | grep -q 'for f in'; then
echo "bats-unit-tests still serializes the suite in a shell loop" >&2
exit 1
fi
}
@test "PR workflow shares four slots across unit and controller targets" {
grep -qF 'run: make unit-tests test-controllers -j4 --output-sync=target' \
.github/workflows/pull-requests.yaml || {
echo "PR checks do not use the bounded four-slot make invocation" >&2
exit 1
}
[ "$(grep -c 'run: make test-controllers' .github/workflows/pull-requests.yaml)" -eq 0 ] || {
echo "controller tests still run in a separate sequential workflow step" >&2
exit 1
}
}