Files
qdrant/lib/wal/tests/process_crash.rs
Tim Visée 74e51f7339 Claude: simplify codebase (#8627)
* [ai] Replace manual into mappings with Into::into

* Reformat

* [ai] Use implicit .iter

* Don't iterate over keys too

* [ai] Replace unwrap_or

* Reformat

* [ai] Use as_deref and then_some

* [ai] Use more to_string

* [ai] Use explicitly typed into conversions

* Reformat

* [ai] More explicit into conversions

* Reformat
2026-04-09 10:02:45 +02:00

70 lines
2.2 KiB
Rust

//! Simulates a process crash while writing to a write ahead log segment.
//!
//! Steps:
//!
//! 1. The test process creates a seed and a temporary directory
//! 2. The test process creates a subprocess with the seed and directory as
//! arguments.
//! 3. The subprocess creates a segment in the directory, and appends entries to
//! the segment based on the seed.
//! 4. The subprocess aborts without closing resources or cleaning up state.
//! 5. The test process reads the entries from the segment, ensuring that no
//! corruption or data loss has occurred.
use std::collections::HashMap;
use std::{env, process};
use rand::Rng;
use tempfile::Builder;
use wal::test_utils::EntryGenerator;
const SEGMENT_CAPACITY: usize = 32 * 1024 * 1024;
const EXIT_CODE: i32 = 42;
#[test]
fn process_crash() {
let vars: HashMap<String, String> = env::vars().collect();
if vars.contains_key("SEED") && vars.contains_key("SEGMENT_PATH") {
let seed: usize = vars["SEED"].parse().unwrap();
let path = vars["SEGMENT_PATH"].clone();
subprocess(path, seed);
} else {
test()
}
}
fn test() {
let tempdir = Builder::new().prefix("segment").tempdir().unwrap();
let seed: usize = rand::rng().next_u32() as usize;
let path = tempdir.path().join("segment");
println!("Spawning subprocess; path: {path:?}; seed: {seed}");
let exit_code = process::Command::new(env::current_exe().unwrap())
.env("SEED", seed.to_string())
.env("SEGMENT_PATH", format!("{}", path.display()))
.status()
.unwrap()
.code()
.unwrap();
assert_eq!(EXIT_CODE, exit_code);
let segment = wal::Segment::open(path).unwrap();
let entries = EntryGenerator::with_seed_and_segment_capacity(seed, SEGMENT_CAPACITY);
for (i, entry) in entries.into_iter().enumerate() {
assert_eq!(&entry[..], &*segment.entry(i).unwrap());
}
}
fn subprocess(path: String, seed: usize) {
let mut segment = wal::Segment::create(path, SEGMENT_CAPACITY).unwrap();
for entry in EntryGenerator::with_seed_and_segment_capacity(seed, SEGMENT_CAPACITY) {
segment.append(&entry).expect("segment capacity exhausted");
}
process::exit(EXIT_CODE);
}