[functional-tests] port some of the cache_check tests to Rust

This commit is contained in:
Joe Thornber
2020-08-07 14:30:00 +01:00
parent 4a0582bb5d
commit fa4ea3e2d9
21 changed files with 464 additions and 128 deletions

View File

@@ -0,0 +1,94 @@
use anyhow::{Result};
use rand::prelude::*;
use std::collections::HashSet;
use std::fs::OpenOptions;
use std::path::Path;
use thinp::cache::xml;
//------------------------------------------
pub trait XmlGen {
fn generate_xml(&mut self, v: &mut dyn xml::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);
g.generate_xml(&mut w)
}
pub struct CacheGen {
block_size: u64,
nr_cache_blocks: u64,
nr_origin_blocks: u64,
percent_resident: u8,
percent_dirty: u8,
}
impl CacheGen {
pub fn new(
block_size: u64,
nr_cache_blocks: u64,
nr_origin_blocks: u64,
percent_resident: u8,
percent_dirty: u8,
) -> Self {
CacheGen {
block_size,
nr_cache_blocks,
nr_origin_blocks,
percent_resident,
percent_dirty,
}
}
}
impl XmlGen for CacheGen {
fn generate_xml(&mut self, v: &mut dyn xml::MetadataVisitor) -> Result<()> {
v.superblock_b(&xml::Superblock {
uuid: "".to_string(),
block_size: self.block_size,
nr_cache_blocks: self.nr_cache_blocks,
policy: "smq".to_string(),
hint_width: 4,
})?;
let mut cblocks = Vec::new();
for n in 0..self.nr_cache_blocks {
cblocks.push(n);
}
cblocks.shuffle(&mut rand::thread_rng());
v.mappings_b()?;
{
let nr_resident = (self.nr_cache_blocks * 100 as u64) / (self.percent_resident as u64);
let mut used = HashSet::new();
for n in 0..nr_resident {
let mut oblock = 0u64;
while used.contains(&oblock) {
oblock = rand::thread_rng().gen();
}
used.insert(oblock);
// FIXME: dirty should vary
v.mapping(&xml::Map {
cblock: cblocks[n as usize],
oblock,
dirty: false,
})?;
}
}
v.mappings_e()?;
v.superblock_e()?;
Ok(())
}
}
//------------------------------------------

View File

@@ -6,11 +6,14 @@ use std::fs::OpenOptions;
use std::io::{Read, Write};
use std::path::{PathBuf};
use std::str::from_utf8;
use tempfile::{tempdir, TempDir};
use thinp::file_utils;
pub mod xml_generator;
use crate::common::xml_generator::{write_xml, SingleThinS};
pub mod thin_xml_generator;
pub mod cache_xml_generator;
pub mod test_dir;
use crate::common::thin_xml_generator::{write_xml, SingleThinS};
use test_dir::TestDir;
//------------------------------------------
@@ -103,28 +106,19 @@ macro_rules! thin_metadata_unpack {
};
}
#[macro_export]
macro_rules! cache_check {
( $( $arg: expr ),* ) => {
{
use std::ffi::OsString;
let args: &[OsString] = &[$( Into::<OsString>::into($arg) ),*];
duct::cmd("bin/cache_check", args).stdout_capture().stderr_capture()
}
};
}
//------------------------------------------
pub struct TestDir {
dir: TempDir,
file_count: usize,
}
impl TestDir {
pub fn new() -> Result<TestDir> {
let dir = tempdir()?;
Ok(TestDir { dir, file_count: 0 })
}
pub fn mk_path(&mut self, file: &str) -> PathBuf {
let mut p = PathBuf::new();
p.push(&self.dir);
p.push(PathBuf::from(format!("{:02}_{}", self.file_count, file)));
self.file_count += 1;
p
}
}
// Returns stderr, a non zero status must be returned
pub fn run_fail(command: Expression) -> Result<String> {
let output = command.stderr_capture().unchecked().run()?;

27
tests/common/test_dir.rs Normal file
View File

@@ -0,0 +1,27 @@
use anyhow::Result;
use std::path::{PathBuf};
use tempfile::{tempdir, TempDir};
//---------------------------------------
pub struct TestDir {
dir: TempDir,
file_count: usize,
}
impl TestDir {
pub fn new() -> Result<TestDir> {
let dir = tempdir()?;
Ok(TestDir { dir, file_count: 0 })
}
pub fn mk_path(&mut self, file: &str) -> PathBuf {
let mut p = PathBuf::new();
p.push(&self.dir);
p.push(PathBuf::from(format!("{:02}_{}", self.file_count, file)));
self.file_count += 1;
p
}
}
//---------------------------------------