[tests] Add era test fixtures
This commit is contained in:
parent
321fce882f
commit
4cfe93570c
34
tests/common/era.rs
Normal file
34
tests/common/era.rs
Normal 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)
|
||||
}
|
||||
|
||||
//-----------------------------------------------
|
157
tests/common/era_xml_generator.rs
Normal file
157
tests/common/era_xml_generator.rs
Normal 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(())
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user