test(e2e): annotate genuine sleeps with TODO and rationale

Three poll/sleep sites in the install bats and the kubernetes runner are
NOT replaceable by `kubectl wait --for=condition=...` because the signal
they observe is not a Kubernetes API condition:

- e2e-install-cozystack.bats:55-56 - 5s pad lets late-arriving HRs join
  the awk-snapshot the parallel `kubectl wait` runs against. There is no
  k8s condition for "all expected platform HRs have been emitted" short
  of hard-coding the list.
- e2e-install-cozystack.bats:75 - LINSTOR node membership is reported by
  the linstor binary running inside the controller pod (kubectl exec),
  not a CRD status, so kubectl wait cannot subscribe to it.
- e2e-apps/run-kubernetes.sh:231-238 - validates the external HTTP path
  through MetalLB -> tenant ingress -> backend pod end-to-end. Not a
  single API condition.

Annotate each with TODO(e2e-replace-fixed-timeouts) and the rationale so
future readers do not "fix" them with a kubectl wait that does not work.

Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
This commit is contained in:
Myasnikov Daniil 2026-04-27 23:42:32 +05:00
parent f5a9686629
commit 461cdf961f
No known key found for this signature in database
GPG key ID: FA953A439C637F04
3 changed files with 13 additions and 0 deletions

View file

@ -227,6 +227,11 @@ EOF
exit 1
fi
# TODO(e2e-replace-fixed-timeouts): genuine retry loop. This validates an
# external HTTP path (MetalLB-advertised LB IP -> in-tenant ingress ->
# backend pod) which is not visible to the Kubernetes API as a single
# condition, so kubectl wait cannot replace it. The 20x3s = 60s budget is
# capped with `lb_ok=false` then asserted below.
lb_ok=false
for i in $(seq 1 20); do
echo "Attempt $i"

View file

@ -61,6 +61,11 @@ EOF
# Wait until HelmReleases appear & reconcile them
timeout 180 sh -ec 'until [ $(kubectl get hr -A --no-headers 2>/dev/null | wc -l) -gt 10 ]; do sleep 1; done'
# TODO(e2e-replace-fixed-timeouts): genuine sleep. The threshold of 10 is a
# heuristic for "enough HRs visible to start waiting"; the snapshot below
# uses whatever HRs have appeared by then. There is no objective k8s API
# signal for "all platform HRs have been emitted" without hard-coding the
# expected list, so the 5s pad lets a few late-arrivals join the snapshot.
sleep 5
kubectl get hr -A | awk 'NR>1 {print "kubectl wait --timeout=15m --for=condition=ready -n "$1" hr/"$2" &"} END {print "wait"}' | sh -ex

View file

@ -18,6 +18,9 @@ echo "[post-install-prep] waiting for linstor-controller to be Available"
kubectl wait deployment/linstor-controller -n cozy-linstor --timeout=5m --for=condition=available
echo "[post-install-prep] waiting for 3 LINSTOR nodes Online"
# TODO(e2e-replace-fixed-timeouts): genuine poll. LINSTOR node membership is
# reported by the linstor binary inside the controller pod, not via a
# Kubernetes API condition, so kubectl wait cannot subscribe to it.
timeout 60 sh -ec 'until [ $(kubectl exec -n cozy-linstor deploy/linstor-controller -- linstor node list | grep -c Online) -eq 3 ]; do sleep 1; done'
echo "[post-install-prep] creating LINSTOR storage pools (parallel across nodes)"