test(hack): pin HelmRelease v2 status shape used by remediation guard

run-kubernetes.sh extracts .status.installFailures and
.status.upgradeFailures via kubectl -o jsonpath. If a future flux
release renames the counters, kubectl returns empty, the guard reports
no cycle, and e2e silently misses real remediation loops.

Add a bats unit test that feeds a pinned HelmRelease v2 status snippet
through the same jsonpath and asserts the extraction still yields the
expected values. Also leave a pointer comment in run-kubernetes.sh so a
future flux bump surfaces the version coupling in review.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
This commit is contained in:
Aleksei Sviridkin 2026-04-16 21:13:06 +03:00
parent bc5473d4fc
commit 03426fbd71
No known key found for this signature in database
GPG key ID: 7988329FDF395282
2 changed files with 51 additions and 0 deletions

View file

@ -326,6 +326,13 @@ EOF
# A non-zero installFailures/upgradeFailures indicates the helm-wait budget expired while
# admin-kubeconfig was still being provisioned, which would trigger uninstall remediation
# and churn the Cluster CR.
# Flux helm-controller v2 status shape: .status.installFailures and
# .status.upgradeFailures are counters populated by the controller on
# every failed install/upgrade. If a future flux release renames them,
# kubectl returns the empty string and the guard silently passes. The
# shape is pinned by hack/remediation-guard.bats (see that file for
# details), and the vendored API types live under
# vendor/github.com/fluxcd/helm-controller/api/v2.
install_failures=$(kubectl get hr -n tenant-test "kubernetes-${test_name}" -ojsonpath='{.status.installFailures}')
upgrade_failures=$(kubectl get hr -n tenant-test "kubernetes-${test_name}" -ojsonpath='{.status.upgradeFailures}')
if helmrelease_has_remediation_cycle "${install_failures}" "${upgrade_failures}"; then

View file

@ -85,3 +85,47 @@
helmrelease_has_remediation_cycle "3" "5" || rc=$?
[ "$rc" -eq 0 ]
}
@test "installFailures and upgradeFailures extraction pins HR v2 status shape" {
# Pins the Flux HelmRelease v2 status shape that run-kubernetes.sh relies
# on. If a future Flux version renames .status.installFailures (or
# .status.upgradeFailures), kubectl get -o jsonpath returns an empty
# string, the guard quietly says "no cycle", and real remediation loops
# slip past the e2e assertion.
#
# This test uses yq to read the exact path used in the e2e script. yq
# evaluates the same json-ish jsonpath against a pinned HR snippet, so
# the test fails loudly if the field ever disappears or moves. Cross
# reference: vendor/github.com/fluxcd/helm-controller/api/v2/ status
# struct field tags.
tmp=$(mktemp -d)
trap 'rm -rf "$tmp"' EXIT
cat > "$tmp/hr.yaml" <<'YAML'
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: kubernetes-test
namespace: tenant-test
spec:
interval: 5m
status:
installFailures: 2
upgradeFailures: 0
conditions:
- type: Ready
status: "False"
reason: UninstallSucceeded
YAML
install_failures=$(yq '.status.installFailures' "$tmp/hr.yaml")
upgrade_failures=$(yq '.status.upgradeFailures' "$tmp/hr.yaml")
[ "$install_failures" = "2" ]
[ "$upgrade_failures" = "0" ]
. hack/e2e-apps/remediation-guard.sh
rc=0
helmrelease_has_remediation_cycle "$install_failures" "$upgrade_failures" || rc=$?
[ "$rc" -eq 0 ]
}