in testsuite/src/lib.rs [471:555]
fn driver_can_reproduce_mutations() {
use lain::rand::Rng;
use std::sync::{Arc, RwLock};
#[derive(Debug, Default, NewFuzzed, Mutatable, Clone, PartialEq, BinarySerialize)]
struct S {
value: u32,
}
#[derive(Default)]
struct LocalContext {}
#[derive(Default, Debug)]
struct GlobalContext {
mutated_data: Vec<S>,
iterations: usize,
}
fn fuzzer_routine<R: lain::rand::Rng>(
mutator: &mut Mutator<R>,
_ctx: &mut LocalContext,
global_ctx: Option<Arc<RwLock<GlobalContext>>>,
) -> Result<(), ()> {
let global_ctx = global_ctx.unwrap();
let mut global_ctx = global_ctx.write().unwrap();
let data = S::new_fuzzed(mutator, None);
global_ctx.mutated_data.push(data);
global_ctx.iterations += 1;
Ok(())
}
// Do the first run
let seed: u64 = lain::rand::thread_rng().gen();
let mut driver = lain::driver::FuzzerDriver::<GlobalContext>::new(1);
let global_context: Arc<RwLock<GlobalContext>> = Default::default();
driver.set_global_context(global_context.clone());
driver.set_seed(seed);
let driver = Arc::new(driver);
lain::driver::start_fuzzer(driver.clone(), fuzzer_routine);
let one_milli = std::time::Duration::from_millis(1);
loop {
if driver.num_iterations() >= 20 {
driver.signal_exit();
break;
}
std::thread::sleep(one_milli);
}
driver.join_threads();
// Recreate the driver for a reproduction run
let mutated_data = &global_context.read().unwrap().mutated_data[10..15];
let start_iteration: u64 = 10;
let end_iteration: u64 = 15;
let mut driver = lain::driver::FuzzerDriver::<GlobalContext>::new(1);
let global_context: Arc<RwLock<GlobalContext>> = Default::default();
driver.set_global_context(global_context.clone());
driver.set_to_reproduce_mode(start_iteration, end_iteration);
driver.set_seed(seed);
let driver = Arc::new(driver);
lain::driver::start_fuzzer(driver.clone(), fuzzer_routine);
driver.join_threads();
// Check for differences
let reproduced_data = &global_context.read().unwrap().mutated_data;
for i in 0..mutated_data.len() {
let i = i as usize;
assert_eq!(mutated_data[i], reproduced_data[i]);
}
//println!("{:?}", global_context.read().unwrap());
}