test(ha-wal-replication): registration lifecycle, broadcast, ACK tests (tasks 5.1-5.3)

Add test_repl_registration_lifecycle covering the complete 3-step standby
lifecycle: register (nstandbys==1, ep pointer verified), duplicate
(idempotent, same slot), deregister (ep==NULL, nstandbys==0 — the
previously-untested slot-zeroing invariant). Tasks 5.1/5.2 were already
covered by test_broadcast_one_standby_sends_entry, test_wal_wire
round-trip, and test_wal_ack_reply_updates_acked_lsn_and_signals.
18 repl unit tests pass under ASAN.
This commit is contained in:
Rongsong Shen 2026-06-10 11:41:43 +00:00
parent e2fba08f5d
commit ab270fab99

View file

@ -492,6 +492,46 @@ static void test_broadcast_send_failure_continues(void)
#endif
}
/* ============================================================
* Task 5.3: Registration lifecycle — Req 1.1, 1.2, 1.3
*
* Comprehensive test covering all three lifecycle steps in sequence:
* Step 1 (Req 1.1): Register ep → nstandbys==1, standbys[idx].ep==ep
* Step 2 (Req 1.3): Re-register same ep → idempotent, nstandbys==1, same idx
* Step 3 (Req 1.2): Deregister ep → nstandbys==0, standbys[idx].ep==NULL
* ============================================================ */
static void test_repl_registration_lifecycle(void) {
replicator_t r;
int dummy_ep = 0;
repl_init(&r);
/* Step 1: Register ep — Req 1.1 */
int idx = repl_add_standby(&r, (void *)&dummy_ep, "sb1", 7001);
TEST_ASSERT_TRUE_MESSAGE(idx >= 0, "repl_add_standby must return a valid slot index");
TEST_ASSERT_EQUAL_INT_MESSAGE(1, r.nstandbys,
"nstandbys must be 1 after first registration (Req 1.1)");
TEST_ASSERT_EQUAL_PTR_MESSAGE((void *)&dummy_ep, r.standbys[idx].ep,
"standbys[idx].ep must equal registered ep (Req 1.1)");
/* Step 2: Re-register same ep — idempotent, Req 1.3 */
int idx2 = repl_add_standby(&r, (void *)&dummy_ep, "sb1", 7001);
TEST_ASSERT_TRUE_MESSAGE(idx2 >= 0, "duplicate repl_add_standby must return valid index");
TEST_ASSERT_EQUAL_INT_MESSAGE(1, r.nstandbys,
"nstandbys must remain 1 after duplicate registration (Req 1.3)");
TEST_ASSERT_EQUAL_INT_MESSAGE(idx, idx2,
"duplicate registration must return the same slot index (Req 1.3)");
/* Step 3: Deregister ep — Req 1.2 */
repl_remove_standby(&r, (void *)&dummy_ep);
TEST_ASSERT_EQUAL_INT_MESSAGE(0, r.nstandbys,
"nstandbys must be 0 after deregistration (Req 1.2)");
TEST_ASSERT_NULL_MESSAGE(r.standbys[idx].ep,
"standbys[idx].ep must be NULL after deregistration (Req 1.2)");
repl_fini(&r);
printf("test_repl_registration_lifecycle: PASS\n");
}
void test_repl_unit(void) {
UNITY_BEGIN();
RUN_TEST(test_repl_init_zeroes_nstandbys);
@ -514,5 +554,7 @@ void test_repl_unit(void) {
/* Task 4.1: WAL ACK reply handler — Req 4.3 */
RUN_TEST(test_wal_ack_reply_updates_acked_lsn_and_signals);
RUN_TEST(test_wal_nack_does_not_update_acked_lsn);
/* Task 5.3: registration lifecycle — Req 1.1, 1.2, 1.3 */
RUN_TEST(test_repl_registration_lifecycle);
UNITY_END();
}