Files
cozystack/hack/check-hook-request-timeout.bats
Myasnikov Daniil cc942fed68 test(tests): run unit suites with Bats and retain POSIX coverage
The shell translator rewrites test bodies and loses Bats reporting.
The unit lane needs complete TAP results and JUnit reports without
changing how live-cluster suites run.

Sourced production helpers still need a dash pass, and unit test bodies
need nounset without exporting shell options into subprocesses.

Assisted-by: LLM
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
2026-10-07 11:04:00 +03:00

63 lines
2.7 KiB
Bash
Executable File

#!/usr/bin/env bats
# Repo-wide invariant: a kubectl call that relies on in-cluster credentials must
# not carry a non-zero --request-timeout.
#
# client-go loads in-cluster credentials only while the assembled config still
# equals the default. --request-timeout lands in that config, so any non-zero
# value diverts the call to kubectl's built-in default cluster, localhost:8080,
# where it is refused. Nothing about this is visible in a rendered manifest: the
# flag reads as ordinary defensive practice, the chart renders, and the failure
# appears only when the container runs against a real apiserver. It cost two
# packages before it was found (#4276, #4288), and in one of them the hook
# reported success while doing nothing.
#
# Scope and its limit. A file that names KUBECONFIG is skipped: it hands kubectl
# an explicit kubeconfig, so the in-cluster branch is not what serves it and the
# flag is harmless there. That is a per-file judgement, not per-command, which
# is the coarse part of this check and is why it is written down rather than
# inferred. Vendored charts under packages/*/*/charts are upstream and out of
# scope.
#
# Bounding the call is still available: --timeout bounds a watch, and
# activeDeadlineSeconds bounds the whole Job, which is what
# packages/apps/tenant/templates/cleanup-job.yaml uses and documents.
load test_helper
REPO_ROOT="$(cd "$(dirname "${BATS_TEST_FILENAME:-$0}")/.." && pwd)"
@test "no in-cluster kubectl call carries a non-zero --request-timeout" {
cd "$REPO_ROOT"
# Files in scope: non-vendored templates that invoke kubectl.
candidates="$(grep -rl 'kubectl' packages/*/*/templates/ 2>/dev/null || true)"
[ -n "$candidates" ] || { echo "FAIL: found no templates invoking kubectl; this check is broken, not clean"; false; }
# Guard against a vacuous pass: the tree ships many such templates, so a
# collapsed glob has to fail here rather than report success.
count="$(printf '%s\n' "$candidates" | grep -c . || true)"
[ "$count" -ge 10 ] || { echo "FAIL: only $count template(s) invoke kubectl; expected the tree's usual population"; false; }
offenders=""
for f in $candidates; do
# An explicit kubeconfig means the in-cluster branch is not in play here.
if grep -q 'KUBECONFIG' "$f"; then
continue
fi
hits="$(grep -nE -- '--request-timeout=[^0[:space:]]' "$f" || true)"
if [ -n "$hits" ]; then
offenders="${offenders}${f}
${hits}
"
fi
done
if [ -n "$offenders" ]; then
echo "FAIL: non-zero --request-timeout on a call that depends on in-cluster credentials."
echo "It diverts kubectl to localhost:8080 and the call never reaches the cluster."
echo "Bound the work with --timeout or activeDeadlineSeconds instead."
printf '%s\n' "$offenders"
false
fi
}