use std::{fs::File, path::Path};
use crate::database::wal::{WAL, errors::WALError};
mod default_wal;
pub fn test_wal_append(wal: &mut impl WAL) {
let mut prev = 0;
for i in 0..100 as i32 {
let offset = wal.append_log(&i.to_be_bytes()).unwrap();
assert!(prev == 0 || prev < offset);
prev = offset;
}
}
pub fn test_wal_read(wal: &mut impl WAL) {
for i in 0..100 as i32 {
wal.append_log(&i.to_be_bytes()).unwrap();
}
let wal_iterator = wal.read(0).unwrap();
let mut curr: i32 = 0;
for i in wal_iterator {
let (_, val) = i.unwrap();
assert_eq!(val, curr.to_be_bytes());
curr += 1;
}
assert_eq!(curr, 100);
}
pub fn test_wal_rotation(wal: &mut impl WAL, wal_file_size: u64) {
let wal_record_size = 40;
let iterations = ((wal_file_size * 5) / wal_record_size) - 1; for i in 0..iterations {
wal.append_log(&i.to_be_bytes()).unwrap();
}
let wal_iterator = wal.read(0).unwrap();
let mut curr: u64 = 0;
for i in wal_iterator {
let (_, val) = i.unwrap();
assert_eq!(val, curr.to_be_bytes());
curr += 1;
}
assert_eq!(curr, iterations);
}
pub fn test_wal_flush(wal: &mut impl WAL, wal_file_size: u64) {
let wal_record_size = 40;
let iterations = ((wal_file_size * 4) / wal_record_size) - 1; let mut wals_to_flush = 0;
for i in 0..iterations {
let offset = wal.append_log(&i.to_be_bytes()).unwrap();
if i == iterations / 2 {
wals_to_flush = offset;
}
}
wal.flush_wal(wals_to_flush).unwrap();
assert_eq!(Some(WALError::OffsetUnderflow), wal.read(0).err());
let wal_iterator = wal.read(wals_to_flush).unwrap();
let mut curr: u64 = iterations / 2 + 1; for i in wal_iterator {
let (_, val) = i.unwrap();
assert_eq!(val, curr.to_be_bytes());
curr += 1;
}
}
pub fn test_wal_corruption(wal: &mut impl WAL, wal_file_size: u64) {
let wal_record_size = 40;
let iterations = ((wal_file_size * 3) / wal_record_size) - 1; let mut wals_to_flush = 0;
for i in 0..iterations {
let offset = wal.append_log(&i.to_be_bytes()).unwrap();
if i == iterations / 2 {
wals_to_flush = offset;
}
}
let mut wal_iterator = wal.read(wals_to_flush + 3).unwrap();
assert!(wal_iterator.next().unwrap().is_err()); }
pub fn test_wal_invalid_file_name(wal: &mut impl WAL, root_dir: &Path) {
let invalid_file = root_dir.join("invalid_name.wal");
File::create(invalid_file).unwrap();
assert!(matches!(wal.read(0), Err(WALError::InvalidFileName(_))));
}
pub fn test_wal_max_palyload(wal: &mut impl WAL, wal_max_payload_len: u64) {
let payload = vec![0u8; (wal_max_payload_len + 3) as usize];
assert!(matches!(
wal.append_log(&payload),
Err(WALError::PayloadLengthOutOfBound(_))
));
}
pub fn test_wal_empty(wal: &mut impl WAL) {
assert!(matches!(wal.read(0).unwrap().next(), None));
}
pub fn test_wal_recovery_on_new(wal: &mut impl WAL) {
let offset = wal.append_log(b"test").unwrap();
assert!(offset > 0);
}