mod common;
use common::TestEnv;
use ironwal::WalOptions;
fn segment_filename(id: u64) -> String {
format!("{:020}.wal", id)
}
#[test]
fn test_basic_truncation() {
let mut opts = WalOptions::default();
opts.max_segment_size = u64::MAX;
opts.max_entries_per_segment = 10;
let env = TestEnv::new(opts);
let stream = "truncate_basic";
for _ in 0..30 {
env.wal.append(stream, &[0u8; 100]).unwrap();
}
let stream_dir = env.root.join(stream);
assert!(stream_dir.join(segment_filename(0)).exists());
assert!(stream_dir.join(segment_filename(10)).exists());
assert!(stream_dir.join(segment_filename(20)).exists());
let deleted = env.wal.truncate(stream, 15).unwrap();
assert_eq!(deleted, 1, "Should delete exactly 1 segment (Start ID 0)");
let seg0 = stream_dir.join(segment_filename(0));
assert!(!seg0.exists(), "Segment 0 should be deleted");
let seg10 = stream_dir.join(segment_filename(10));
assert!(seg10.exists(), "Segment 10 must exist");
let val = env.wal.get(stream, 10).unwrap();
assert!(val.is_some(), "Should be able to read preserved data");
let val_old = env.wal.get(stream, 0).unwrap();
assert!(val_old.is_none(), "Deleted data should be inaccessible");
}
#[test]
fn test_truncate_active_safety() {
let mut opts = WalOptions::default();
opts.max_segment_size = u64::MAX;
opts.max_entries_per_segment = 10;
let env = TestEnv::new(opts);
let stream = "truncate_safety";
for _ in 0..15 {
env.wal.append(stream, &[0u8; 100]).unwrap();
}
let deleted = env.wal.truncate(stream, 100).unwrap();
assert_eq!(deleted, 1, "Should delete old segment but preserve active one");
env.wal.append(stream, b"new_data").unwrap();
}
#[test]
fn test_index_rebuild_after_truncate() {
let mut opts = WalOptions::default();
opts.max_segment_size = u64::MAX;
opts.max_entries_per_segment = 10;
let env = TestEnv::new(opts);
let stream = "truncate_index";
for _ in 0..30 {
env.wal.append(stream, &[0u8; 100]).unwrap();
}
env.wal.truncate(stream, 15).unwrap();
let common::TestEnv {
wal: old_wal,
_dir,
root,
} = env;
drop(old_wal);
let wal = ironwal::Wal::new(ironwal::WalOptions::new(root)).unwrap();
let val = wal.get(stream, 20).unwrap();
assert!(val.is_some());
}