test(ha-convergence-recovery): RED demotion-convergence + self-restart tests + seams (task 2.1)

This commit is contained in:
Rongsong Shen 2026-06-14 03:12:25 +00:00
parent b9ddfa60cb
commit c8e55947c2
7 changed files with 668 additions and 1 deletions

View file

@ -0,0 +1,70 @@
/*
* ha_convergence.c — demotion convergence + self-restart primitive
* (ha-convergence-recovery Requirement 1).
*
* ───────────────────────────────────────────────────────────────────────────
* RED SCAFFOLD (task 2.1) — task 2.2 REPLACES the bodies below with the real
* implementation (and moves controller_saved_argv's backing store into main.c).
*
* This file currently provides ONLY the link-time definitions the task-2.1 RED
* tests need to compile and link:
* - controller_saved_argv() — stub returning NULL (real argv capture is in
* main.c, task 2.2)
* - ha_self_restart() — RED stub: does NOT yet honor the ha_restart_hook
* / ha_fatal_hook contract, so the fatal-hook test
* FAILS until task 2.2 implements the real
* flush → execv → abort sequence (and the
* XCE_TESTING seam routing).
* - ha_restart_hook / ha_fatal_hook — the XCE_TESTING function-pointer seams,
* defined =NULL in exactly one TU (this one),
* mirroring the ha_*_hook seam pattern in ha.c.
*
* The DEMOTION-SEQUENCE behavior (hook disable on become-follower-from-PRIMARY,
* scheduled truncate-above-committed_lsn, restart) lives in raft_cb_become_
* follower (ha.c) and is NOT implemented here or there yet — that is task 2.2.
* Consequently every demotion-convergence test in test_demotion_convergence.c
* is RED against the current tree.
* ───────────────────────────────────────────────────────────────────────────
*/
#include <stddef.h>
#include "cluster.h"
#include "ha.h"
#include "xce/cluster_def.h"
#ifdef XCE_TESTING
/* XCE_TESTING seams (Req 1.6, 1.4) — defined here, declared in ha.h.
* Tests set these before exercising the restart/fatal contract. */
int (*ha_restart_hook)(cluster_t *c) = NULL;
void (*ha_fatal_hook)(const char *msg) = NULL;
#endif
/*
* controller_saved_argv — RED stub (task 2.2 moves the real, main()-populated
* accessor into main.c). Returns NULL: no argv has been captured in the
* scaffold, so a production execv would have nothing to exec.
*/
char **controller_saved_argv(void)
{
return NULL;
}
/*
* ha_self_restart — RED stub.
*
* Task 2.2 replaces this with the real primitive:
* - production: flush logs, execv(controller_saved_argv()); on exec return,
* ERROR + abort() (FATAL — Req 1.4); never returns.
* - XCE_TESTING: invoke ha_restart_hook(c) instead of execv (Req 1.6); if it
* reports failure (or is unset), invoke ha_fatal_hook in place of abort.
*
* Until then this stub deliberately does NOTHING (no hook routing), so the
* task-2.1 fatal-hook test — which asserts a failing restart hook drives
* ha_fatal_hook — FAILS (RED).
*/
int ha_self_restart(cluster_t *c)
{
(void)c;
return 0; /* RED scaffold — task 2.2 implements exec/abort + seam routing */
}