test(ha-commit-barrier-rollout): RED tests for config barrier (task 5.1)

6 RED carriers pinning the three configAck defects (previous-tag acks
count, n_active==0 success shortcut, no-self-count denominator) and the
push/upgrade failure path (logged-only result, unconditional success
ACK + restart). 2 sanctioned pins (single-member, success-unchanged).
Behavior-preserving signature change: push_config_to_standbys gains
acked_out (return still legacy push count; 7 call sites NULL'd,
body-diff verified). 29/6 in group; no collateral failures.
This commit is contained in:
Rongsong Shen 2026-06-12 16:31:42 +00:00
parent 732e836868
commit 9cdeba5816
9 changed files with 582 additions and 19 deletions

View file

@ -9,6 +9,10 @@
<!-- How the user likes things done. Code style, tools, patterns, communication. -->
## Key Learnings
- [2026-06-12] Census parsing caveat: controller_unit_test logs (tinylog) and Unity result lines BOTH go to stdout and can splice mid-line under the multi-threaded config-push tests — a distinct-Unity-line count silently drops spliced results. Robust census = union of Unity result names AND the `test_x: PASS` printf lines, cross-checked against the per-group `N Tests M Failures` summary blocks (which are splice-immune).
- [2026-06-12] Config-barrier test trick: when a test needs a covering config ACK for a tag only known AFTER conf_save_config hashes the re-encoded blob (upgradeConfig path), pre-ack with acked_config_lsn = UINT64_MAX — covers any push tag under both legacy (>0) and per-push (>= tag) counting.
- [2026-06-12] A zeroed stack cbuf_t DEADLOCKS on cbuf_put (ncap==0 → len==ncap → cond_wait forever); any fixture driving do_upgrade_config_with_bytes' restart path must cbuf_init(&c->wbuf, …) first.
- Census EXACT method (2026-06-12): count DISTINCT Unity `file:line:test:PASS` triples (`grep -aoE` + sort -u), not raw `2mPASS` occurrences — tinylog interleaving garbles ~9 verdict lines per run and duplicates others; distinct-triple count matched the 494-baseline arithmetic exactly (495 after task 4.3's +1).
- repl registry reconnect semantics: repl_remove_standby vacates the slot (ep=NULL, keeps last_disconnected_lsn guard); repl_add_standby reuses the first empty slot and memsets it (acked_lsn=0). With both standbys removed, majority_candidate_locked zero-fills to n_peers-1 → candidate 0 → committed_lsn frozen (RETAIN entries safely pending); after re-add, ONE covering ack = 2-of-3 majority.
- repl_wait_majority_ack walAck track is engine-only since barrier-rollout 2.2: entry_lsn==0 returns 0 immediately (documented once-per-lifetime LSN-0 first entry), everything else delegates to commit_submit unconditionally — ce==NULL surfaces as -EINVAL from commit_submit (unreachable in production; cluster_init_phase2 always wires the engine). The counting loop that remains in the function is configAck-ONLY (no self-count, n_active==0 shortcut is Req 8.5 config behavior). persist_wal_sync_append's residual non-engine branch can only store committed_lsn for the LSN-0 no-op case. (2026-06-12, task 2.2)

View file

@ -962,3 +962,18 @@
| 08:03 | Edited src/controller/testsuite/test_commit_barrier_reply.c | 2→5 lines | ~72 |
| 15:15 | Task 4.3 ha-commit-barrier-rollout: fact-retention-across-quorum-loss integration test (GREEN on landing) — quorum lost via repl_remove_standby x2, 4 worker facts via on_job_start/on_job_finish (cluster.c/do_notify not in test link), RETAIN pending + on-disk exactly-once scan, reconnect + covering ACK advances committed_lsn, no re-delivery, retained-depth=4 printed | src/controller/testsuite/test_commit_barrier_reply.c | census 495 distinct Unity PASS (494+1), ZERO FAIL | ~55k |
| 08:29 | Edited .kiro/specs/ha-commit-barrier-rollout/tasks.md | inline fix | ~30 |
| 08:43 | Edited src/controller/config_repl.h | modified acked_out() | ~244 |
| 08:43 | Edited src/controller/config_repl.c | added 1 condition(s) | ~219 |
| 08:43 | Edited src/controller/config_repl.c | added 1 condition(s) | ~57 |
| 08:43 | Edited src/controller/config_repl.c | 2→2 lines | ~40 |
| 08:44 | Edited src/controller/ha.c | 2→3 lines | ~59 |
| 08:44 | Edited src/controller/join.c | 2→2 lines | ~27 |
| 08:45 | Edited src/controller/testsuite/test_repl_majority.c | modified arithmetic() | ~158 |
| 08:45 | Edited src/controller/testsuite/test_repl_majority.c | modified entry_lsn() | ~121 |
| 08:45 | Edited src/controller/testsuite/test_repl_majority.c | 4→5 lines | ~90 |
| 08:49 | Edited src/controller/testsuite/test_commit_barrier_rollout.c | expanded (+6 lines) | ~339 |
| 08:50 | Edited src/controller/testsuite/test_commit_barrier_rollout.c | added 2 condition(s) | ~5302 |
| 08:51 | Edited src/controller/testsuite/test_commit_barrier_rollout.c | expanded (+10 lines) | ~210 |
| 08:51 | Edited src/controller/testsuite/test_commit_barrier_rollout.c | 3→8 lines | ~109 |
| 16:10 | Task 5.1 ha-commit-barrier-rollout: RED tests for configAck per-push arithmetic + upgrade failure path; behavior-preserving push_config_to_standbys signature change (+int *acked_out, return semantics unchanged) | src/controller/{config_repl.c,config_repl.h,ha.c,join.c}, testsuite/{test_commit_barrier_rollout.c,test_repl_majority.c} | 8 new cases (6 RED + 2 pins), isolated group 29 tests/6 fails, full suite: only those 6 fail (summary blocks), repl_majority green, prod controller builds | ~110k |
| 09:31 | Edited .kiro/specs/ha-commit-barrier-rollout/tasks.md | inline fix | ~22 |