forked from lei.chen/myxce
test(ha-wal-replication): seed current_lsn in 7 stale wal-catchup tests for bug-850 contiguity guard
The bug-850/851 forward-gap contiguity guard (persist.c:839, added in 20e59d0b)
correctly rejects a catch-up entry whose lsn is ahead of the WAL tail (-EAGAIN).
7 test_wal_catchup_* tests in test_config_repl.c predate the guard and applied
non-contiguous LSNs (42, 10-12, 1000+) to a fresh persist (current_lsn=1),
failing deterministically. Seed current_lsn to each test's first applied LSN so
the in-order stream is contiguous (mirroring the real catch-up streamer); the
apply->advance path and all asserted semantics are unchanged. Test-only; the
production contiguity guard is untouched. 179 controller tests, 0 failures (x3).
This commit is contained in:
parent
13c43c23a4
commit
46bd207b0f
1 changed files with 42 additions and 0 deletions
|
|
@ -1991,6 +1991,23 @@ static void destroy_test_persist_catchup(persist_t *p)
|
|||
free(p);
|
||||
}
|
||||
|
||||
/* bug-850/851 contiguity guard (persist.c:839): persist_wal_write_replicated
|
||||
* REFUSES a forward gap (entry.lsn > current_lsn → -EAGAIN) so a standby never
|
||||
* creates a WAL hole. A fresh persist has current_lsn == 1 (LSN 0 reserved,
|
||||
* persist.c:542). The catch-up tests below choose their own non-1 starting LSNs
|
||||
* (42, 10, 20, …); seed current_lsn to the first applied entry's LSN so the
|
||||
* first entry is contiguous (entry.lsn == current_lsn) and the guard accepts
|
||||
* the in-order stream — mirroring the real catch-up streamer, which streams
|
||||
* contiguously from current_lsn. current_lsn is a plain lock-protected field;
|
||||
* persist.c sets it directly under p->lock (e.g. persist.c:542,715), so do the
|
||||
* same here. */
|
||||
static void seed_persist_current_lsn(persist_t *p, uint64_t next_lsn)
|
||||
{
|
||||
pthread_mutex_lock(&p->lock);
|
||||
p->current_lsn = next_lsn;
|
||||
pthread_mutex_unlock(&p->lock);
|
||||
}
|
||||
|
||||
/* Test 2.1-A: successful single WAL entry advances applied_lsn */
|
||||
static void test_wal_catchup_entry_advances_applied_lsn(void)
|
||||
{
|
||||
|
|
@ -2008,6 +2025,9 @@ static void test_wal_catchup_entry_advances_applied_lsn(void)
|
|||
TEST_ASSERT_EQUAL_UINT64(0,
|
||||
(uint64_t)atomic_load_explicit(&ha.applied_lsn, memory_order_acquire));
|
||||
|
||||
/* Seed current_lsn so the entry at LSN 42 is contiguous (bug-850 guard). */
|
||||
seed_persist_current_lsn(p, 42);
|
||||
|
||||
/* Build a single-entry WAL catch-up with LSN=42, no payload */
|
||||
wal_catchup_entry_t entry;
|
||||
memset(&entry, 0, sizeof(entry));
|
||||
|
|
@ -2111,6 +2131,9 @@ static void test_wal_catchup_batch_advances_applied_lsn(void)
|
|||
TEST_ASSERT_EQUAL_UINT64(0,
|
||||
(uint64_t)atomic_load_explicit(&ha.applied_lsn, memory_order_acquire));
|
||||
|
||||
/* Seed current_lsn so the batch [10,11,12] is contiguous (bug-850 guard). */
|
||||
seed_persist_current_lsn(p, 10);
|
||||
|
||||
/* Build 3 sub-entries at LSNs 10, 11, 12 */
|
||||
wal_catchup_entry_t e0, e1, e2;
|
||||
memset(&e0, 0, sizeof(e0));
|
||||
|
|
@ -2163,6 +2186,9 @@ static void test_wal_catchup_partial_batch(void)
|
|||
/* Pre-set applied_lsn to 5 to verify monotonic advance */
|
||||
atomic_store_explicit(&ha.applied_lsn, 5, memory_order_release);
|
||||
|
||||
/* Seed current_lsn so the batch [20,21] is contiguous (bug-850 guard). */
|
||||
seed_persist_current_lsn(p, 20);
|
||||
|
||||
wal_catchup_entry_t e0, e1;
|
||||
memset(&e0, 0, sizeof(e0));
|
||||
memset(&e1, 0, sizeof(e1));
|
||||
|
|
@ -2209,6 +2235,11 @@ static void test_wal_catchup_batch_error_entry_skipped(void)
|
|||
cfg.election_timeout_ms = 1500;
|
||||
ha_init(&ha, &cfg, 0);
|
||||
|
||||
/* Seed current_lsn so the first good entry at LSN 30 is contiguous (bug-850
|
||||
* guard). The NULL sub-entry is skipped (no write, current_lsn stays at 31);
|
||||
* the test only requires applied_lsn >= 30 (the first good entry held). */
|
||||
seed_persist_current_lsn(p, 30);
|
||||
|
||||
/* Good entry at LSN 30, then a NULL pointer (simulates corrupt entry),
|
||||
* then good entry at LSN 32. */
|
||||
wal_catchup_entry_t e0, e2;
|
||||
|
|
@ -2260,6 +2291,10 @@ static void test_wal_catchup_batch_zero_entries_fallback(void)
|
|||
cfg.election_timeout_ms = 1500;
|
||||
ha_init(&ha, &cfg, 0);
|
||||
|
||||
/* Seed current_lsn so the fallback single entry at LSN 50 is contiguous
|
||||
* (bug-850 guard). */
|
||||
seed_persist_current_lsn(p, 50);
|
||||
|
||||
/* n_entries == 0 → single-entry path from task 2.1 */
|
||||
wal_catchup_entry_t entry;
|
||||
memset(&entry, 0, sizeof(entry));
|
||||
|
|
@ -2303,6 +2338,10 @@ static void test_wal_catchup_batch_256_entries(void)
|
|||
cfg.election_timeout_ms = 1500;
|
||||
ha_init(&ha, &cfg, 0);
|
||||
|
||||
/* Seed current_lsn so the consecutive batch starting at LSN 1000 is
|
||||
* contiguous (bug-850 guard). */
|
||||
seed_persist_current_lsn(p, 1000);
|
||||
|
||||
/* Allocate 256 sub-entries at consecutive LSNs starting at 1000 */
|
||||
const int N = 256;
|
||||
wal_catchup_entry_t entries[N];
|
||||
|
|
@ -2371,6 +2410,9 @@ static void test_wal_catchup_batch_applied_lsn_only_after_full_batch(void)
|
|||
* from full advance. */
|
||||
atomic_store_explicit(&ha.applied_lsn, 100, memory_order_release);
|
||||
|
||||
/* Seed current_lsn so the batch [200..203] is contiguous (bug-850 guard). */
|
||||
seed_persist_current_lsn(p, 200);
|
||||
|
||||
/* Build a batch of 4 entries at LSNs 200, 201, 202, 203 */
|
||||
wal_catchup_entry_t e0, e1, e2, e3;
|
||||
memset(&e0, 0, sizeof(e0));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue