From 014ad2e58b647d367621a4324503725eee60e71d Mon Sep 17 00:00:00 2001 From: Determinant Date: Thu, 11 Jun 2020 16:13:26 -0400 Subject: enhance the test --- tests/common/mod.rs | 96 ++++++++++++++++++++++++++--------------------------- tests/rand_fail.rs | 33 +++++++++++++++--- 2 files changed, 77 insertions(+), 52 deletions(-) diff --git a/tests/common/mod.rs b/tests/common/mod.rs index f230edb..ce49ec5 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -411,7 +411,7 @@ impl Canvas { return None; } let idx = rng.gen_range(0, self.queue.len()); - let (pos, _) = self.queue.get_index_mut(idx).unwrap(); + let (pos, _) = self.queue.get_index(idx).unwrap(); let pos = *pos; Some((self.paint(pos), pos)) } @@ -422,8 +422,8 @@ impl Canvas { } pub fn paint_all(&mut self) { - for (k, q) in self.queue.iter() { - self.canvas[*k as usize] = q.back().unwrap().0; + for (pos, q) in self.queue.iter() { + self.canvas[*pos as usize] = q.back().unwrap().0; } self.clear_queued() } @@ -442,6 +442,7 @@ impl Canvas { let cnt = self.waiting.get_mut(&rid).unwrap(); *cnt -= 1; if *cnt == 0 { + self.waiting.remove(&rid); Some(rid) } else { None @@ -511,7 +512,7 @@ pub struct PaintingSim { } impl PaintingSim { - fn run( + pub fn run( &self, state: &mut WALStoreEmulState, canvas: &mut Canvas, @@ -522,7 +523,8 @@ impl PaintingSim { ) -> Result<(), ()> { let mut rng = ::seed_from_u64(self.seed); - let mut wal = wal.recover(WALStoreEmul::new(state, fgen, |_, _| {}))?; + let mut wal = + wal.recover(WALStoreEmul::new(state, fgen.clone(), |_, _| {}))?; for _ in 0..self.n { let pss = (0..self.m) .map(|_| { @@ -539,11 +541,13 @@ impl PaintingSim { pss.iter().map(|e| e.to_bytes()).collect::>(); // write ahead let (rids, ok) = wal.grow(payloads); + assert_eq!(pss.len(), rids.len()); // keep track of the operations for (ps, rid) in pss.iter().zip(rids.iter()) { ops.push(ps.clone()); ringid_map.insert(*rid, ops.len() - 1); } + // grow could fail ok?; // finish appending to WAL /* @@ -556,7 +560,11 @@ impl PaintingSim { canvas.prepaint(&ps, &rid); } // run k ticks of the fine-grained scheduler - for _ in 0..self.k { + for _ in 0..rng.gen_range(1, self.k) { + // storage I/O could fail + if fgen.next_fail() { + return Err(()); + } if let Some((fin_rid, _)) = canvas.rand_paint(&mut rng) { if let Some(rid) = fin_rid { wal.peel(&[rid])? @@ -566,17 +574,11 @@ impl PaintingSim { } } } - // keep running until all operations are finished - while let Some((fin_rid, _)) = canvas.rand_paint(&mut rng) { - if let Some(rid) = fin_rid { - wal.peel(&[rid])? - } - } canvas.print(40); Ok(()) } - fn get_walloader(&self) -> WALLoader { + pub fn get_walloader(&self) -> WALLoader { WALLoader::new(self.file_nbit, self.block_nbit, self.file_cache) } @@ -598,7 +600,7 @@ impl PaintingSim { fgen.get_count() } - fn check( + pub fn check(&self, state: &mut WALStoreEmulState, canvas: &mut Canvas, wal: WALLoader, @@ -616,9 +618,6 @@ impl PaintingSim { |payload, ringid| { let s = PaintStrokes::from_bytes(&payload); canvas.prepaint(&s, &ringid); - if ringid_map.get(&ringid).is_none() { - println!("{:?}", ringid) - } last_idx = *ringid_map.get(&ringid).unwrap() + 1; }, )) @@ -626,41 +625,42 @@ impl PaintingSim { println!("last = {}/{}", last_idx, ops.len()); canvas.paint_all(); // recover complete - let canvas0 = canvas.new_reference(&ops[..last_idx]); - let res = canvas.is_same(&canvas0); - if !res { + let canvas0 = if last_idx > 0 { + let canvas0 = canvas.new_reference(&ops[..last_idx]); + if canvas.is_same(&canvas0) { + None + } else { + Some(canvas0) + } + } else { + let canvas0 = canvas.new_reference(&[]); + if canvas.is_same(&canvas0) { None } + else { + let i0 = ops.len() - self.m - 1; + let mut canvas0 = canvas0.new_reference(&ops[..i0]); + let mut res = None; + 'outer: loop { + for i in i0..ops.len() { + canvas0.prepaint(&ops[i], &WALRingId::empty_id()); + canvas0.paint_all(); + if canvas.is_same(&canvas0) { break 'outer } + } + res = Some(canvas0); + break + } + res + } + }; + if let Some(canvas0) = canvas0 { canvas.print(40); canvas0.print(40); + false + } else { + true } - res } - pub fn test(&self, fgen: G) -> bool { - let mut state = WALStoreEmulState::new(); - let mut canvas = Canvas::new(self.csize); - let mut ops: Vec = Vec::new(); - let mut ringid_map = HashMap::new(); - if self - .run( - &mut state, - &mut canvas, - self.get_walloader(), - &mut ops, - &mut ringid_map, - Rc::new(fgen), - ) - .is_err() - { - if !Self::check( - &mut state, - &mut canvas, - self.get_walloader(), - &ops, - &ringid_map, - ) { - return false; - } - } - true + pub fn new_canvas(&self) -> Canvas { + Canvas::new(self.csize) } } diff --git a/tests/rand_fail.rs b/tests/rand_fail.rs index 07edb39..e32ba23 100644 --- a/tests/rand_fail.rs +++ b/tests/rand_fail.rs @@ -1,12 +1,37 @@ -#[cfg(test)] -mod common; +#[cfg(test)] mod common; + +use std::collections::HashMap; +use std::rc::Rc; fn single_point_failure(sim: &common::PaintingSim) { let nticks = sim.get_nticks(); println!("nticks = {}", nticks); for i in 0..nticks { print!("fail pos = {}, ", i); - assert!(sim.test(common::SingleFailGen::new(i))); + let mut state = common::WALStoreEmulState::new(); + let mut canvas = sim.new_canvas(); + let mut ops: Vec = Vec::new(); + let mut ringid_map = HashMap::new(); + let fgen = common::SingleFailGen::new(i); + if sim + .run( + &mut state, + &mut canvas, + sim.get_walloader(), + &mut ops, + &mut ringid_map, + Rc::new(fgen), + ) + .is_err() + { + assert!(sim.check( + &mut state, + &mut canvas, + sim.get_walloader(), + &ops, + &ringid_map, + )) + } } } @@ -18,7 +43,7 @@ fn test_rand_fail() { file_cache: 1000, n: 100, m: 10, - k: 100, + k: 1000, csize: 1000, stroke_max_len: 10, stroke_max_col: 256, -- cgit v1.2.3