[tests] Add era test fixtures

This commit is contained in:
Ming-Hung Tsai 2021-10-01 15:49:23 +08:00
parent 321fce882f
commit 4cfe93570c
3 changed files with 193 additions and 0 deletions

34
tests/common/era.rs Normal file
View File

@ -0,0 +1,34 @@
use anyhow::Result;
use std::path::PathBuf;
use thinp::file_utils;
use crate::args;
use crate::common::era_xml_generator::{write_xml, CleanShutdownMeta};
use crate::common::process::*;
use crate::common::target::*;
use crate::common::test_dir::TestDir;
//-----------------------------------------------
pub fn mk_valid_xml(td: &mut TestDir) -> Result<PathBuf> {
let xml = td.mk_path("meta.xml");
let mut gen = CleanShutdownMeta::new(128, 256, 32, 4); // bs, nr_blocks, era, nr_wsets
write_xml(&xml, &mut gen)?;
Ok(xml)
}
pub fn mk_valid_md(td: &mut TestDir) -> Result<PathBuf> {
let xml = td.mk_path("meta.xml");
let md = td.mk_path("meta.bin");
let mut gen = CleanShutdownMeta::new(128, 256, 32, 4);
write_xml(&xml, &mut gen)?;
let _file = file_utils::create_sized_file(&md, 4096 * 4096);
run_ok(ERA_RESTORE, args!["-i", &xml, "-o", &md])?;
Ok(md)
}
//-----------------------------------------------

View File

@ -0,0 +1,157 @@
use anyhow::Result;
use rand::prelude::*;
use std::fs::OpenOptions;
use std::path::Path;
use thinp::era::ir::{self, MetadataVisitor};
use thinp::era::xml;
//------------------------------------------
pub trait XmlGen {
fn generate_xml(&mut self, v: &mut dyn MetadataVisitor) -> Result<()>;
}
pub fn write_xml(path: &Path, g: &mut dyn XmlGen) -> Result<()> {
let xml_out = OpenOptions::new()
.read(false)
.write(true)
.create(true)
.truncate(true)
.open(path)?;
let mut w = xml::XmlWriter::new(xml_out, false);
g.generate_xml(&mut w)
}
//------------------------------------------
// Ordered sequence generator where each element has an independent probability
// of being present.
struct IndependentSequence {
begin: u32,
end: u32,
prob: u32,
rng: ThreadRng,
}
impl IndependentSequence {
fn new(begin: u32, end: u32, prob: u32) -> IndependentSequence {
IndependentSequence {
begin,
end,
prob,
rng: rand::thread_rng(),
}
}
}
impl Iterator for IndependentSequence {
type Item = std::ops::Range<u32>;
// FIXME: reduce complexity
fn next(&mut self) -> Option<std::ops::Range<u32>> {
if self.begin >= self.end {
return None;
}
let mut b = self.begin;
while b < self.end && self.rng.gen_range(0..100) >= self.prob {
b += 1;
}
if b == self.end {
return None;
}
let mut e = b + 1;
while e < self.end && self.rng.gen_range(0..100) < self.prob {
e += 1;
}
self.begin = e + 1;
Some(std::ops::Range { start: b, end: e })
}
}
//------------------------------------------
fn create_superblock(block_size: u32, nr_blocks: u32, current_era: u32) -> ir::Superblock {
ir::Superblock {
uuid: "".to_string(),
block_size,
nr_blocks,
current_era,
}
}
pub struct CleanShutdownMeta {
block_size: u32,
nr_blocks: u32,
current_era: u32,
nr_writesets: u32,
}
impl CleanShutdownMeta {
pub fn new(block_size: u32, nr_blocks: u32, current_era: u32, nr_writesets: u32) -> Self {
CleanShutdownMeta {
block_size,
nr_blocks,
current_era,
nr_writesets,
}
}
fn generate_writeset(v: &mut dyn MetadataVisitor, ws: &ir::Writeset) -> Result<()> {
v.writeset_b(ws)?;
let gen = IndependentSequence::new(0, ws.nr_bits, 10);
for seq in gen {
v.writeset_blocks(&ir::MarkedBlocks {
begin: seq.start,
len: seq.end - seq.start,
})?;
}
v.writeset_e()?;
Ok(())
}
fn generate_era_array(v: &mut dyn MetadataVisitor, nr_blocks: u32, max_era: u32) -> Result<()> {
let mut rng = rand::thread_rng();
v.era_b()?;
for b in 0..nr_blocks {
let era = rng.gen_range(0..max_era);
v.era(&ir::Era { block: b, era })?;
}
v.era_e()?;
Ok(())
}
}
impl XmlGen for CleanShutdownMeta {
fn generate_xml(&mut self, v: &mut dyn MetadataVisitor) -> Result<()> {
v.superblock_b(&create_superblock(
self.block_size,
self.nr_blocks,
self.current_era,
))?;
let era_low = self.current_era - self.nr_writesets + 1;
for era in era_low..self.current_era + 1 {
Self::generate_writeset(
v,
&ir::Writeset {
era,
nr_bits: self.nr_blocks,
},
)?;
}
Self::generate_era_array(v, self.nr_blocks, era_low)?;
v.superblock_e()?;
Ok(())
}
}
//------------------------------------------

View File

@ -5,6 +5,8 @@
pub mod cache;
pub mod cache_xml_generator;
pub mod common_args;
pub mod era;
pub mod era_xml_generator;
pub mod fixture;
pub mod input_arg;
pub mod output_option;