use lsmdb::StorageEngine;
use std::sync::Arc;
use std::thread;
use tempfile::TempDir;
#[test]
fn test_crash_and_manifest_recovery() {
let temp_dir = TempDir::new().unwrap();
let db_path = temp_dir.path().to_path_buf();
{
let engine = StorageEngine::open(&db_path).unwrap();
for i in 0..100 {
let key = format!("key_{:04}", i).into_bytes();
let val = format!("val_{:04}", i).into_bytes();
engine.put(&key, &val).unwrap();
}
let val = engine.get(b"key_0050").unwrap().unwrap();
assert_eq!(val, b"val_0050");
}
{
let engine = StorageEngine::open(&db_path).unwrap();
let val = engine.get(b"key_0050").unwrap().unwrap();
assert_eq!(val, b"val_0050");
let val_missing = engine.get(b"key_9999").unwrap();
assert!(val_missing.is_none());
}
}
#[test]
fn test_concurrent_write_chaos() {
let temp_dir = TempDir::new().unwrap();
let db_path = temp_dir.path().to_path_buf();
let engine = Arc::new(StorageEngine::open(db_path).unwrap());
let mut handles = vec![];
for thread_id in 0..50 {
let engine_clone = Arc::clone(&engine);
handles.push(thread::spawn(move || {
for i in 0..100 {
let key = format!("concurrent_key_{}_{}", thread_id, i).into_bytes();
let val = format!("concurrent_val_{}_{}", thread_id, i).into_bytes();
engine_clone.put(&key, &val).unwrap();
}
}));
}
for handle in handles {
handle.join().unwrap();
}
for thread_id in 0..50 {
let key = format!("concurrent_key_{}_{}", thread_id, 42).into_bytes();
let expected_val = format!("concurrent_val_{}_{}", thread_id, 42).into_bytes();
let val = engine.get(&key).unwrap().unwrap();
assert_eq!(val, expected_val);
}
}
#[test]
fn test_data_overwrites_and_tombstones() {
let temp_dir = TempDir::new().unwrap();
let engine = StorageEngine::open(temp_dir.path()).unwrap();
let key = b"hero";
engine.put(key, b"batman").unwrap();
assert_eq!(engine.get(key).unwrap().unwrap(), b"batman");
engine.update(key, b"superman").unwrap();
assert_eq!(engine.get(key).unwrap().unwrap(), b"superman");
engine.remove(key).unwrap();
assert!(engine.get(key).unwrap().is_none());
}
#[test]
fn test_huge_data_batch_flushing() {
let temp_dir = TempDir::new().unwrap();
let engine = StorageEngine::open(temp_dir.path()).unwrap();
let value_payload = vec![0xAF; 1024];
for i in 0..10000 {
let key = format!("heavy_key_{:06}", i).into_bytes();
engine.put(&key, &value_payload).unwrap();
}
assert_eq!(
engine.get(b"heavy_key_000000").unwrap().unwrap(),
value_payload
);
assert_eq!(
engine.get(b"heavy_key_005000").unwrap().unwrap(),
value_payload
);
assert_eq!(
engine.get(b"heavy_key_009999").unwrap().unwrap(),
value_payload
);
}