test(ha-single-leader-role): sweep all COMMITTING fixtures to direct-PRIMARY contract (task 5.1)
This commit is contained in:
parent
71ce41f486
commit
7f974e766b
11 changed files with 138 additions and 169 deletions
|
|
@ -1,17 +1,18 @@
|
|||
/*
|
||||
* test_ha_repl_push.c — Unity tests for Task 4.2:
|
||||
* Config and WAL replication push to standbys in the COMMITTING path.
|
||||
* Config and WAL replication push to standbys on election win (the node
|
||||
* becomes CTRL_PRIMARY directly — single leader role, ha-single-leader-role).
|
||||
*
|
||||
* Tests verify:
|
||||
* Req 7.1: When entering CTRL_PRIMARY_COMMITTING, push_config_to_standbys
|
||||
* Req 7.1: When the node becomes CTRL_PRIMARY, push_config_to_standbys
|
||||
* is called (via ha_push_config_hook seam).
|
||||
* Req 7.2: When entering CTRL_PRIMARY_COMMITTING, ha_send_ctrlhello_to_all_standbys
|
||||
* Req 7.2: When the node becomes CTRL_PRIMARY, ha_send_ctrlhello_to_all_standbys
|
||||
* is called to trigger catch-up replication (via ha_send_ctrlhello_hook seam).
|
||||
* Req 7.3: The push is triggered at the point of COMMITTING entry, not before.
|
||||
* Req 7.3: The push is triggered at the point of promotion, not before.
|
||||
* When election is lost (CTRL_STANDBY), no push occurs.
|
||||
*
|
||||
* Design ref: design.md "ha_send_ctrlhello_to_all_standbys" section
|
||||
* Boundary: ha.c (election evaluation + COMMITTING path)
|
||||
* Boundary: ha.c (election evaluation + direct-PRIMARY promotion path)
|
||||
* Requirements: 7.1, 7.2, 7.3
|
||||
*/
|
||||
#define _GNU_SOURCE
|
||||
|
|
@ -31,7 +32,7 @@
|
|||
/* ── Test-only seam: ha_send_ctrlhello_to_all_standbys call hook ─────────────
|
||||
*
|
||||
* In production, ha_elect_evaluate_and_signal calls
|
||||
* ha_send_ctrlhello_to_all_standbys(c) in the COMMITTING path.
|
||||
* ha_send_ctrlhello_to_all_standbys(c) on the promotion path.
|
||||
* For unit tests, the real function is not linked (cluster.c not in test binary).
|
||||
* The XCE_TESTING seam in ha.c checks ha_send_ctrlhello_hook; if non-NULL, it
|
||||
* calls the hook instead of the real ha_send_ctrlhello_to_all_standbys.
|
||||
|
|
@ -41,7 +42,7 @@ extern int (*ha_send_ctrlhello_hook)(void *c);
|
|||
/* ── Test-only seam: push_config_to_standbys call hook ──────────────────────
|
||||
*
|
||||
* In production, ha_elect_evaluate_and_signal calls push_config_to_standbys(c,...)
|
||||
* in the COMMITTING path. For unit tests, the seam in ha.c checks
|
||||
* on the promotion path. For unit tests, the seam in ha.c checks
|
||||
* ha_push_config_hook; if non-NULL, it calls the hook instead.
|
||||
*/
|
||||
extern int (*ha_push_config_hook)(void *c);
|
||||
|
|
@ -83,7 +84,6 @@ static ha_config_t g_cfg = {
|
|||
.max_promotion_retries = 5,
|
||||
.election_jitter_max_ms = 0,
|
||||
.election_priority_step_ms = 500,
|
||||
.committing_timeout_ms = 10000,
|
||||
};
|
||||
|
||||
/* ── Helper: build a minimal ha_elect_ctx_t ─────────────────────────────── */
|
||||
|
|
@ -136,12 +136,12 @@ static void clear_hooks(void)
|
|||
ha_phase2_hook = NULL;
|
||||
}
|
||||
|
||||
/* ── Test 1: Req 7.2 — COMMITTING path calls ha_send_ctrlhello_to_all_standbys ── */
|
||||
/* ── Test 1: Req 7.2 — promotion calls ha_send_ctrlhello_to_all_standbys ───── */
|
||||
|
||||
static void test_committing_calls_ctrlhello_push(void)
|
||||
static void test_promotion_calls_ctrlhello_push(void)
|
||||
{
|
||||
/* When election is won (CTRL_PRIMARY → COMMITTING), ha_send_ctrlhello_to_all_standbys
|
||||
* must be called exactly once.
|
||||
/* When election is won (node becomes CTRL_PRIMARY directly),
|
||||
* ha_send_ctrlhello_to_all_standbys must be called exactly once.
|
||||
* Single-node wins: n_other=0, votes_granted=1. */
|
||||
reset_counters();
|
||||
|
||||
|
|
@ -156,18 +156,18 @@ static void test_committing_calls_ctrlhello_push(void)
|
|||
ha_elect_evaluate_and_signal(&ha, ctx);
|
||||
|
||||
TEST_ASSERT_EQUAL_INT_MESSAGE(1, g_ctrlhello_call_count,
|
||||
"ha_send_ctrlhello_to_all_standbys must be called once on COMMITTING entry (Req 7.2)");
|
||||
"ha_send_ctrlhello_to_all_standbys must be called once on promotion (Req 7.2)");
|
||||
|
||||
free_ctx(ctx);
|
||||
ha_fini(&ha);
|
||||
clear_hooks();
|
||||
printf("test_committing_calls_ctrlhello_push: PASS (ctrlhello_calls=%d)\n",
|
||||
printf("test_promotion_calls_ctrlhello_push: PASS (ctrlhello_calls=%d)\n",
|
||||
g_ctrlhello_call_count);
|
||||
}
|
||||
|
||||
/* ── Test 2: Req 7.1 — COMMITTING path calls push_config_to_standbys ──────── */
|
||||
/* ── Test 2: Req 7.1 — promotion calls push_config_to_standbys ────────────── */
|
||||
|
||||
static void test_committing_calls_push_config(void)
|
||||
static void test_promotion_calls_push_config(void)
|
||||
{
|
||||
/* When election is won, push_config_to_standbys must be called once. */
|
||||
reset_counters();
|
||||
|
|
@ -183,12 +183,12 @@ static void test_committing_calls_push_config(void)
|
|||
ha_elect_evaluate_and_signal(&ha, ctx);
|
||||
|
||||
TEST_ASSERT_EQUAL_INT_MESSAGE(1, g_push_config_call_count,
|
||||
"push_config_to_standbys must be called once on COMMITTING entry (Req 7.1)");
|
||||
"push_config_to_standbys must be called once on promotion (Req 7.1)");
|
||||
|
||||
free_ctx(ctx);
|
||||
ha_fini(&ha);
|
||||
clear_hooks();
|
||||
printf("test_committing_calls_push_config: PASS (push_config_calls=%d)\n",
|
||||
printf("test_promotion_calls_push_config: PASS (push_config_calls=%d)\n",
|
||||
g_push_config_call_count);
|
||||
}
|
||||
|
||||
|
|
@ -251,8 +251,8 @@ static void test_3node_win_calls_both_pushes(void)
|
|||
|
||||
ctrl_role_t actual_role =
|
||||
(ctrl_role_t)atomic_load_explicit(&ha.role, memory_order_acquire);
|
||||
TEST_ASSERT_EQUAL_INT_MESSAGE((int)CTRL_PRIMARY_COMMITTING, (int)actual_role,
|
||||
"ha->role must be CTRL_PRIMARY_COMMITTING after winning");
|
||||
TEST_ASSERT_EQUAL_INT_MESSAGE((int)CTRL_PRIMARY, (int)actual_role,
|
||||
"ha->role must be CTRL_PRIMARY directly after winning (single leader role, Req 1.1)");
|
||||
|
||||
TEST_ASSERT_EQUAL_INT_MESSAGE(1, g_ctrlhello_call_count,
|
||||
"ha_send_ctrlhello_to_all_standbys must be called once (3-node win)");
|
||||
|
|
@ -303,8 +303,8 @@ static void test_done_posted_prevents_double_push(void)
|
|||
|
||||
void test_ha_repl_push(void)
|
||||
{
|
||||
RUN_TEST(test_committing_calls_ctrlhello_push);
|
||||
RUN_TEST(test_committing_calls_push_config);
|
||||
RUN_TEST(test_promotion_calls_ctrlhello_push);
|
||||
RUN_TEST(test_promotion_calls_push_config);
|
||||
RUN_TEST(test_standby_result_does_not_push);
|
||||
RUN_TEST(test_3node_win_calls_both_pushes);
|
||||
RUN_TEST(test_done_posted_prevents_double_push);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue