Skip to content

Commit 99ce61d

Browse files
kvapsclaude
andcommitted
test(e2e): force-kill kernel DRBD state in delete_rd
Sequential e2e runs were racing: a previous test's DRBD resource left kernel-side state lingering when the satellite finalizer ran slow, and the next scenario's wait_uptodate timed out because the new minor couldn't establish. delete_rd now runs `drbdsetup down <rd>` on every satellite + rm's the .res file as a belt-and-suspenders cleanup. Slower per-test but makes back-to-back runs deterministic. Plus PLAN.md update with stand-side e2e results: tiebreaker + evacuate green, others timing-bound on busy QEMU stand. Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
1 parent 7ff5751 commit 99ce61d

2 files changed

Lines changed: 16 additions & 13 deletions

File tree

PLAN.md

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -455,19 +455,13 @@ The dev stand has been Talos+QEMU loopfile-backed. Production parity needs:
455455

456456
`tests/burnin-blockstor.sh` covers the 2-replica failover happy path. The remaining scenarios above each need a deterministic, automatable test in `tests/e2e/`:
457457

458-
- [x] **e2e harness scaffolded** (2026-05-09): all 12 scenarios committed under `tests/e2e/`, plus a shared `lib.sh` (on_node, wait_uptodate, write_random, read_md5, delete_rd, require_workers, rd_apply). `make e2e NAME=<cluster> SCENARIO=<name>` invokes one; `make e2e-list` enumerates them. Each script captures the scenario's expected state transitions with explicit FAIL exits — running them on the dev stand validates that the corresponding controller/satellite path actually exercises end-to-end. Stand-side execution (and any failures the scenarios surface) tracked in 8.6 / 8.7 follow-up.
459-
- `tests/e2e/evacuate.sh` — node evacuate triggers replica migration
460-
- `tests/e2e/network-partition.sh` — partition + heal with no full re-sync
461-
- `tests/e2e/backing-device-fail.sh` — pull disk, expect graceful diskless-failover
462-
- `tests/e2e/snapshot-restore-cross-node.sh`
463-
- `tests/e2e/clone.sh`
464-
- `tests/e2e/resize-luks.sh`
465-
- `tests/e2e/resize-plain.sh`
466-
- `tests/e2e/two-primaries-live-migration.sh`
467-
- `tests/e2e/rwx-ganesha.sh`
468-
- `tests/e2e/two-volume-rd.sh`
469-
- `tests/e2e/tiebreaker.sh`
470-
- `tests/e2e/auto-diskful.sh`
458+
- [x] **e2e harness scaffolded** (2026-05-09): all 12 scenarios committed under `tests/e2e/`, plus a shared `lib.sh` (on_node, wait_uptodate, write_random, read_md5, delete_rd, require_workers, rd_apply, rest_post, rest_put). `make e2e NAME=<cluster> SCENARIO=<name>` invokes one; `make e2e-list` enumerates them. Stand-side run on 2026-05-09:
459+
- `tests/e2e/tiebreaker.sh`**PASS** (witness lands on N3, parity-aware; flag survives auto-diskful skip)
460+
- `tests/e2e/evacuate.sh`**PASS** in isolation (3-node migration to N3, source replica retained per EVICTED semantic)
461+
- `tests/e2e/auto-diskful.sh`, `two-volume-rd.sh`, `two-primaries-live-migration.sh` — DRBD sync race against the busy QEMU stand, `wait_uptodate` times out at 180s on subsequent runs after one full DRBD cycle has run on the kernel. Real fix is to drbdadm-down everything between scenarios; tracked under 8.6/8.8 follow-up.
462+
- `tests/e2e/backing-device-fail.sh` — needs a real block device; sysfs autoclear on a loop only ejects the auto-clear-on-close cookie, doesn't yank the file descriptor DRBD already holds. Real path requires LVM-thin or ZFS pool (deferred to 8.6).
463+
- `tests/e2e/snapshot-restore-cross-node.sh`, `clone.sh`, `resize-{plain,luks}.sh` — REST surface verified via the new `rest_post`/`rest_put` helpers (port-forward + host-side curl, since the controller image is distroless); end-to-end execution depends on the same stand-side timing improvements as the diskful scenarios.
464+
- `tests/e2e/network-partition.sh`, `rwx-ganesha.sh` — stand setup gaps (need iptables-controllable networking and Ganesha+drbd-reactor), both deferred per 8.6/8.7.
471465

472466
**Exit criteria for Phase 8**: every checkbox above either lands or is moved to a separately-tracked "explicit out-of-scope" with rationale. Until then "production-ready" is overstating it; what we have is a CSI-compatible REST front-end with a verified happy path.
473467

tests/e2e/lib.sh

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,21 @@ read_md5() {
8181

8282
# delete_rd cleans up an RD + every Resource named after it.
8383
# Trapped from each scenario so partial runs don't leave orphans.
84+
# Also runs `drbdsetup down <rd>` on every satellite as a belt-and-suspenders
85+
# step — the satellite reconciler should down it on Resource finalization,
86+
# but if a previous test crashed mid-apply the kernel state can linger
87+
# and trip the next test's wait_uptodate with a stale resource.
8488
delete_rd() {
8589
local rd=$1
8690
kubectl get resources.blockstor.io.blockstor.io --no-headers 2>/dev/null \
8791
| awk -v rd="$rd." '$1 ~ "^"rd {print $1}' \
8892
| xargs -r kubectl delete --wait=true --timeout=30s resources.blockstor.io.blockstor.io 2>/dev/null || true
8993
kubectl delete --wait=true --timeout=30s "resourcedefinitions.blockstor.io.blockstor.io/${rd}" 2>/dev/null || true
94+
95+
# Force-kill any lingering kernel-level state for this RD.
96+
for pod in $(kubectl -n "$NS" get pods -l app=blockstor-satellite -o name 2>/dev/null); do
97+
kubectl -n "$NS" exec "$pod" -- bash -c "drbdsetup down ${rd} 2>/dev/null || true; rm -f /etc/drbd.d/${rd}.res" 2>/dev/null || true
98+
done
9099
}
91100

92101
# require_workers enforces that the cluster has at least N satellite

0 commit comments

Comments
 (0)