feat(ha-repl-hardening): audit safe commit point and snapshot transfer tests (tasks 6.3, 6.4)
6.3: Fix single-node bug — ha_compute_safe_committed_lsn now returns self_lsn instead of 0 for n_peers=0 (prevents WAL truncation on single-node re-election). Add self_lsn/self_tag to ha_elect_ctx_t, populated unconditionally in ha_start_election_async. All 3 test scenarios pass under ASAN. 6.4: Add test_snapshot_recv_128kb_two_chunks (128KB snapshot in 2x64KB chunks, verifies size and applied_lsn); 4 other test cases already existed from tasks 3.5c/3.5d. All ASAN-clean.
This commit is contained in:
parent
d41cfc5813
commit
345d51dd61
5 changed files with 160 additions and 23 deletions
|
|
@ -466,7 +466,9 @@ static void test_safe_committed_lsn_two_peers_at_99_and_100(void)
|
|||
pthread_mutex_init(&ctx->lock, NULL);
|
||||
sem_init(&ctx->done, 0, 0);
|
||||
|
||||
/* Self data stored in votes[0].my_lsn / my_tag */
|
||||
/* Self data: self_lsn/self_tag (task 6.3) and votes[0].my_lsn/my_tag */
|
||||
ctx->self_lsn = 100;
|
||||
ctx->self_tag = 5;
|
||||
ctx->votes[0].my_lsn = 100;
|
||||
ctx->votes[0].my_tag = 5;
|
||||
ctx->votes[0].vote_granted = 1; /* peer0: granted, lsn=99 */
|
||||
|
|
@ -511,6 +513,8 @@ static void test_safe_committed_lsn_two_peers_at_50_and_51(void)
|
|||
pthread_mutex_init(&ctx->lock, NULL);
|
||||
sem_init(&ctx->done, 0, 0);
|
||||
|
||||
ctx->self_lsn = 100;
|
||||
ctx->self_tag = 5;
|
||||
ctx->votes[0].my_lsn = 100;
|
||||
ctx->votes[0].my_tag = 5;
|
||||
ctx->votes[0].vote_granted = 1; /* peer0: granted, lsn=50 */
|
||||
|
|
@ -537,30 +541,34 @@ static void test_safe_committed_lsn_two_peers_at_50_and_51(void)
|
|||
|
||||
/*
|
||||
* Test case C: single-node cluster (n_peers=0, no votes[] entries).
|
||||
* safe_committed_lsn must equal self's own LSN (self is the only majority).
|
||||
* safe_committed_lsn must equal self's own applied_lsn (self is the only majority).
|
||||
* Req 2.3 / task 6.3: returning 0 would truncate all WAL on re-election — wrong.
|
||||
* The fix (task 6.3): ha_elect_ctx_t gains self_lsn/self_tag fields populated
|
||||
* unconditionally by ha_start_election_async; ha_compute_safe_committed_lsn
|
||||
* returns ctx->self_lsn for the n_peers=0 case.
|
||||
*/
|
||||
static void test_safe_committed_lsn_single_node(void)
|
||||
{
|
||||
#ifdef XCE_TESTING
|
||||
/* n_other=0: no votes[] entries; but we still need my_lsn from... somewhere.
|
||||
* For the single-node case, ctx->n_peers=0 and votes[] is empty.
|
||||
* The function should use 0 as safe_lsn (no entries to check). */
|
||||
ha_elect_ctx_t *ctx = calloc(1, sizeof(*ctx));
|
||||
TEST_ASSERT_NOT_NULL(ctx);
|
||||
ctx->n_peers = 0;
|
||||
ctx->votes_granted = 1; /* self-vote only */
|
||||
ctx->n_replied = 0;
|
||||
/* Task 6.3: self_lsn/self_tag populated unconditionally */
|
||||
ctx->self_lsn = 77;
|
||||
ctx->self_tag = 3;
|
||||
pthread_mutex_init(&ctx->lock, NULL);
|
||||
sem_init(&ctx->done, 0, 0);
|
||||
|
||||
uint64_t safe_lsn = 0xDEAD, safe_tag = 0xDEAD;
|
||||
ha_compute_safe_committed_lsn(ctx, &safe_lsn, &safe_tag);
|
||||
|
||||
/* For single-node, safe_lsn should be 0 (no peer lsns to compare with) */
|
||||
TEST_ASSERT_EQUAL_UINT64_MESSAGE(0, safe_lsn,
|
||||
"single-node (n_peers=0): safe_committed_lsn must be 0 (no peer data)");
|
||||
TEST_ASSERT_EQUAL_UINT64_MESSAGE(0, safe_tag,
|
||||
"single-node (n_peers=0): safe_config_tag must be 0 (no peer data)");
|
||||
/* Single-node: safe_committed_lsn must equal self_lsn (not 0) */
|
||||
TEST_ASSERT_EQUAL_UINT64_MESSAGE(77, safe_lsn,
|
||||
"single-node (n_peers=0): safe_committed_lsn must equal self_lsn (77), not 0");
|
||||
TEST_ASSERT_EQUAL_UINT64_MESSAGE(3, safe_tag,
|
||||
"single-node (n_peers=0): safe_config_tag must equal self_tag (3), not 0");
|
||||
|
||||
free_ctx(ctx);
|
||||
printf("test_safe_committed_lsn_single_node: PASS (safe_lsn=%" PRIu64 ")\n", safe_lsn);
|
||||
|
|
@ -587,6 +595,8 @@ static void test_safe_committed_lsn_one_peer_denied(void)
|
|||
pthread_mutex_init(&ctx->lock, NULL);
|
||||
sem_init(&ctx->done, 0, 0);
|
||||
|
||||
ctx->self_lsn = 200;
|
||||
ctx->self_tag = 7;
|
||||
ctx->votes[0].my_lsn = 200;
|
||||
ctx->votes[0].my_tag = 7;
|
||||
ctx->votes[0].vote_granted = 0; /* peer denied vote */
|
||||
|
|
@ -669,6 +679,9 @@ static void test_become_leader_sets_committed_lsn_to_safe_lsn(void)
|
|||
pthread_mutex_init(&ctx->lock, NULL);
|
||||
sem_init(&ctx->done, 0, 0);
|
||||
|
||||
/* Self data in self_lsn/self_tag (task 6.3) and votes[0].my_lsn/my_tag */
|
||||
ctx->self_lsn = 200;
|
||||
ctx->self_tag = 5;
|
||||
/* votes[0]: self data (my_lsn=200) + peer0 granted at lsn=100 */
|
||||
ctx->votes[0].my_lsn = 200;
|
||||
ctx->votes[0].my_tag = 5;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue