use std::{sync::Arc, thread::spawn};
use aok::{OK, Void};
use compio::runtime::Runtime;
use log::info;
use waof::COMMIT_FRAME_TOTAL_LEN;
use super::support::{self, WalFixture, make_payload};
#[test]
fn test_commit_to_concurrent_waiters_consistency() -> Void {
let rt = Runtime::new()?;
rt.block_on(async {
let fixture = WalFixture::single_file("commit_concurrent.log", 64 * 1024)?;
let wal = fixture.wal;
for i in 0..16 {
wal.enqueue(&make_payload(64, i as u8))?;
}
wal.commit().await?;
let mut handles = Vec::new();
for worker in 0..8u32 {
let wal = Arc::clone(&wal);
handles.push(spawn(move || -> aok::Result<()> {
let worker_rt = Runtime::new()?;
worker_rt.block_on(async move {
for round in 0..20u32 {
for i in 0..4u32 {
let byte = (worker * 800 + round * 4 + i) as u8;
wal.enqueue(&make_payload(64, byte))?;
}
let target = wal.tail_address();
let committed = wal.commit_to(target).await?;
assert!(
committed >= target,
"唤醒位点 {committed} 不得小于等待目标 {target}"
);
}
aok::Result::<()>::Ok(())
})?;
Ok(())
}));
}
for handle in handles {
handle.join().expect("并发提交线程正常结束")?;
}
let tail = wal.tail_address();
assert_eq!(wal.committed_until_address(), tail, "提交水位须追平尾地址");
assert_eq!(wal.flushed_until_address(), tail, "刷盘水位须追平尾地址");
let data = support::collect_data(wal.scan(wal.begin_address(), tail)).await?;
assert_eq!(data.len(), 16 + 8 * 20 * 4);
info!("并发 commit_to 唤醒与位点一致性测试通过");
aok::Result::<()>::Ok(())
})?;
OK
}
#[test]
fn test_commit_to_same_target_merges_into_single_leader() -> Void {
let rt = Runtime::new()?;
rt.block_on(async {
let fixture = WalFixture::single_file("commit_merge.log", 64 * 1024)?;
let wal = fixture.wal;
for i in 0..32 {
wal.enqueue(&make_payload(64, i as u8))?;
}
let target = wal.tail_address();
let mut handles = Vec::new();
for _ in 0..8 {
let wal = Arc::clone(&wal);
handles.push(spawn(move || -> aok::Result<u64> {
let worker_rt = Runtime::new()?;
Ok(worker_rt.block_on(wal.commit_to(target))?)
}));
}
for handle in handles {
let committed = handle.join().expect("合并提交线程正常结束")?;
assert!(committed >= target, "合并唤醒位点须覆盖目标");
}
assert_eq!(
wal.committed_until_address(),
target + COMMIT_FRAME_TOTAL_LEN
);
info!("同位点并发提交单 Leader 合并测试通过");
aok::Result::<()>::Ok(())
})?;
OK
}