fix bug-1060 bug-1067
This commit is contained in:
parent
6067ba6c94
commit
61e1391cd0
28 changed files with 7021 additions and 2926 deletions
|
|
@ -309,6 +309,75 @@ static void test_recovered_member_advertises_real_applied_lsn(void)
|
|||
printf("test_recovered_member_advertises_real_applied_lsn: PASS\n");
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* bug-1042: after recovery, the raft LIBRARY's log_len/commit_index */
|
||||
/* must be raised to the recovered position. ha_init_raft runs BEFORE */
|
||||
/* persist_recover on a standby-rejoin boot, leaving the library at */
|
||||
/* log_len=0; without ha_sync_raft_log_from_recovery the library then */
|
||||
/* rejects every AppendEntries (logOk fail for prevLogIndex>=1) and */
|
||||
/* the rejoined member never converges. */
|
||||
/* ------------------------------------------------------------------ */
|
||||
static void test_recovered_member_syncs_raft_log_len(void)
|
||||
{
|
||||
char tmp[256];
|
||||
strcpy(tmp, "/tmp/xce_rec1042_XXXXXX");
|
||||
TEST_ASSERT_NOT_NULL(mkdtemp(tmp));
|
||||
|
||||
/* Phase 1: write WAL entries, flush, stop. */
|
||||
{
|
||||
persist_t* p = make_fresh_persist(tmp);
|
||||
TEST_ASSERT_NOT_NULL(p);
|
||||
for (int i = 0; i < 5; i++)
|
||||
TEST_ASSERT_EQUAL_INT(0,
|
||||
persist_wal_async(p, WAL_JOB_UPDATE, "z", 1));
|
||||
TEST_ASSERT_EQUAL_INT(0, persist_flush(p));
|
||||
teardown_persist(p);
|
||||
}
|
||||
|
||||
/* Phase 2: restart — recover the WAL, then mimic the init-ordering hazard:
|
||||
* the raft library was init'd with log_len=0 BEFORE recovery ran. The sync
|
||||
* must raise the library's log_len to the recovered durable tip. */
|
||||
{
|
||||
persist_t* p2 = make_fresh_persist(tmp);
|
||||
TEST_ASSERT_NOT_NULL(p2);
|
||||
TEST_ASSERT_EQUAL_INT(0, persist_recover(p2));
|
||||
|
||||
uint64_t recovered_floor = persist_durable_floor(p2);
|
||||
TEST_ASSERT_TRUE(recovered_floor > 0);
|
||||
|
||||
ha_state_t ha;
|
||||
memset(&ha, 0, sizeof(ha));
|
||||
/* Library came up empty (ha_init_raft before recovery). */
|
||||
ha.raft.log_len = 0;
|
||||
ha.raft.commit_index = 0;
|
||||
ha.raft.term = 0;
|
||||
atomic_store_explicit(&ha.term, 4ULL, memory_order_release);
|
||||
/* The helper requires a non-NULL raft_c back-ref (production wiring). */
|
||||
ha.raft_c = (cluster_t*)0x1; /* non-NULL sentinel; helper never derefs it */
|
||||
|
||||
ha_sync_raft_log_from_recovery(&ha, p2);
|
||||
|
||||
/* The bug: log_len used to stay 0 → logOk rejects every AppendEntries. */
|
||||
TEST_ASSERT_EQUAL_UINT64(recovered_floor, ha.raft.log_len);
|
||||
/* commit_index advanced to the durable floor, clamped to log_len. */
|
||||
TEST_ASSERT_EQUAL_UINT64(recovered_floor, ha.raft.commit_index);
|
||||
TEST_ASSERT_TRUE(ha.raft.commit_index <= ha.raft.log_len);
|
||||
/* term aligned to the persisted/restored HA term. */
|
||||
TEST_ASSERT_EQUAL_UINT64(4ULL, ha.raft.term);
|
||||
|
||||
/* Monotonic: never lowers an already-higher library position. */
|
||||
ha.raft.log_len = recovered_floor + 100;
|
||||
ha.raft.commit_index = recovered_floor + 50;
|
||||
ha_sync_raft_log_from_recovery(&ha, p2);
|
||||
TEST_ASSERT_EQUAL_UINT64(recovered_floor + 100, ha.raft.log_len);
|
||||
TEST_ASSERT_EQUAL_UINT64(recovered_floor + 50, ha.raft.commit_index);
|
||||
|
||||
teardown_persist(p2);
|
||||
}
|
||||
|
||||
printf("test_recovered_member_syncs_raft_log_len: PASS\n");
|
||||
}
|
||||
|
||||
void test_persist_recovery(void)
|
||||
{
|
||||
RUN_TEST(test_recover_from_empty_state);
|
||||
|
|
@ -317,4 +386,5 @@ void test_persist_recovery(void)
|
|||
RUN_TEST(test_recover_rejects_corrupt_snapshot);
|
||||
RUN_TEST(test_recover_picks_latest_snapshot);
|
||||
RUN_TEST(test_recovered_member_advertises_real_applied_lsn);
|
||||
RUN_TEST(test_recovered_member_syncs_raft_log_len);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue