diff --git a/src/controller/testsuite/test_repl_unit.c b/src/controller/testsuite/test_repl_unit.c index 6562f48a..c69ca7c2 100644 --- a/src/controller/testsuite/test_repl_unit.c +++ b/src/controller/testsuite/test_repl_unit.c @@ -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(); }