[functional-tests (rust)] port thin_repair tests to rust.
cargo test
This commit is contained in:
parent
f56ea2d031
commit
4ac428128a
@ -111,97 +111,6 @@
|
||||
(run-fail-rcv (_ stderr) (thin-delta "--snap1 45 --snap2 46")
|
||||
(assert-starts-with "No input device provided." stderr)))
|
||||
|
||||
;;;-----------------------------------------------------------
|
||||
;;; thin_repair scenarios
|
||||
;;;-----------------------------------------------------------
|
||||
(define-scenario (thin-repair dont-repair-xml)
|
||||
"Fails gracefully if run on XML rather than metadata"
|
||||
(with-thin-xml (xml)
|
||||
(with-empty-metadata (md)
|
||||
(run-fail-rcv (_ stderr) (thin-repair "-i" xml "-o" md)
|
||||
#t))))
|
||||
|
||||
(define-scenario (thin-repair missing-input-file)
|
||||
"the input file can't be found"
|
||||
(with-empty-metadata (md)
|
||||
(run-fail-rcv (_ stderr) (thin-repair "-i no-such-file -o" md)
|
||||
(assert-superblock-all-zeroes md)
|
||||
(assert-starts-with "Couldn't stat file" stderr))))
|
||||
|
||||
(define-scenario (thin-repair garbage-input-file)
|
||||
"the input file is just zeroes"
|
||||
(with-empty-metadata (md1)
|
||||
(with-corrupt-metadata (md2)
|
||||
(run-fail-rcv (_ stderr) (thin-repair "-i " md1 "-o" md2)
|
||||
(assert-superblock-all-zeroes md2)))))
|
||||
|
||||
(define-scenario (thin-repair missing-output-file)
|
||||
"the output file can't be found"
|
||||
(with-thin-xml (xml)
|
||||
(run-fail-rcv (_ stderr) (thin-repair "-i " xml)
|
||||
(assert-starts-with "No output file provided." stderr))))
|
||||
|
||||
(define-scenario (thin-repair override transaction-id)
|
||||
"thin_repair obeys the --transaction-id override"
|
||||
(with-valid-metadata (md1)
|
||||
(with-empty-metadata (md2)
|
||||
(run-ok-rcv (stdout stderr) (thin-repair "--transaction-id 2345" "-i" md1 "-o" md2)
|
||||
(assert-eof stderr))
|
||||
(run-ok-rcv (stdout stderr) (thin-dump md2)
|
||||
(assert-matches ".*transaction=\"2345\"" stdout)))))
|
||||
|
||||
(define-scenario (thin-repair override data-block-size)
|
||||
"thin_repair obeys the --data-block-size override"
|
||||
(with-valid-metadata (md1)
|
||||
(with-empty-metadata (md2)
|
||||
(run-ok-rcv (stdout stderr) (thin-repair "--data-block-size 8192" "-i" md1 "-o" md2)
|
||||
(assert-eof stderr))
|
||||
(run-ok-rcv (stdout stderr) (thin-dump md2)
|
||||
(assert-matches ".*data_block_size=\"8192\"" stdout)))))
|
||||
|
||||
(define-scenario (thin-repair override nr-data-blocks)
|
||||
"thin_repair obeys the --nr-data-blocks override"
|
||||
(with-valid-metadata (md1)
|
||||
(with-empty-metadata (md2)
|
||||
(run-ok-rcv (stdout stderr) (thin-repair "--nr-data-blocks 234500" "-i" md1 "-o" md2)
|
||||
(assert-eof stderr))
|
||||
(run-ok-rcv (stdout stderr) (thin-dump md2)
|
||||
(assert-matches ".*nr_data_blocks=\"234500\"" stdout)))))
|
||||
|
||||
(define-scenario (thin-repair superblock succeeds)
|
||||
"thin_repair can restore a missing superblock"
|
||||
(with-valid-metadata (md1)
|
||||
(run-ok-rcv (expected-xml stderr) (thin-dump "--transaction-id=5" "--data-block-size=128" "--nr-data-blocks=4096000" md1)
|
||||
(damage-superblock md1)
|
||||
(with-empty-metadata (md2)
|
||||
(run-ok-rcv (_ stderr) (thin-repair "--transaction-id=5" "--data-block-size=128" "--nr-data-blocks=4096000" "-i" md1 "-o" md2)
|
||||
(assert-eof stderr))
|
||||
(run-ok-rcv (repaired-xml stderr) (thin-dump md2)
|
||||
(assert-eof stderr)
|
||||
(assert-equal expected-xml repaired-xml))))))
|
||||
|
||||
(define-scenario (thin-repair superblock missing-transaction-id)
|
||||
"--transaction-id is mandatory if the superblock is damaged"
|
||||
(with-damaged-superblock (md1)
|
||||
(with-empty-metadata (md2)
|
||||
(run-fail-rcv (_ stderr) (thin-repair "--data-block-size=128" "--nr-data-blocks=4096000" "-i" md1 "-o" md2)
|
||||
(assert-matches ".*transaction id.*" stderr)))))
|
||||
|
||||
(define-scenario (thin-repair superblock missing-data-block-size)
|
||||
"--data-block-size is mandatory if the superblock is damaged"
|
||||
(with-damaged-superblock (md1)
|
||||
(with-empty-metadata (md2)
|
||||
(run-fail-rcv (_ stderr) (thin-repair "--transaction-id=5" "--nr-data-blocks=4096000" "-i" md1 "-o" md2)
|
||||
(assert-matches ".*data block size.*" stderr)))))
|
||||
|
||||
(define-scenario (thin-repair superblock missing-nr-data-blocks)
|
||||
"--nr-data-blocks is mandatory if the superblock is damaged"
|
||||
(with-damaged-superblock (md1)
|
||||
(with-empty-metadata (md2)
|
||||
(run-fail-rcv (_ stderr) (thin-repair "--transaction-id=5" "--data-block-size=128" "-i" md1 "-o" md2)
|
||||
(assert-matches ".*nr data blocks.*" stderr)))))
|
||||
|
||||
|
||||
;;;-----------------------------------------------------------
|
||||
;;; thin_metadata_pack scenarios
|
||||
;;;-----------------------------------------------------------
|
||||
|
@ -59,6 +59,17 @@ macro_rules! thin_rmap {
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! thin_repair {
|
||||
( $( $arg: expr ),* ) => {
|
||||
{
|
||||
use std::ffi::OsString;
|
||||
let args: &[OsString] = &[$( Into::<OsString>::into($arg) ),*];
|
||||
duct::cmd("bin/thin_repair", args).stdout_capture().stderr_capture()
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
//------------------------------------------
|
||||
|
||||
pub struct TestDir {
|
||||
|
158
tests/thin_repair.rs
Normal file
158
tests/thin_repair.rs
Normal file
@ -0,0 +1,158 @@
|
||||
use anyhow::Result;
|
||||
use std::str::from_utf8;
|
||||
use thinp::version::TOOLS_VERSION;
|
||||
|
||||
mod common;
|
||||
use common::*;
|
||||
|
||||
//------------------------------------------
|
||||
|
||||
#[test]
|
||||
fn accepts_v() -> Result<()> {
|
||||
let stdout = thin_repair!("-V").read()?;
|
||||
assert_eq!(stdout, TOOLS_VERSION);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn accepts_version() -> Result<()> {
|
||||
let stdout = thin_repair!("--version").read()?;
|
||||
assert_eq!(stdout, TOOLS_VERSION);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
const USAGE: &str = "Usage: thin_repair [options] {device|file}\nOptions:\n {-h|--help}\n {-i|--input} <input metadata (binary format)>\n {-o|--output} <output metadata (binary format)>\n {--transaction-id} <natural>\n {--data-block-size} <natural>\n {--nr-data-blocks} <natural>\n {-V|--version}";
|
||||
|
||||
#[test]
|
||||
fn accepts_h() -> Result<()> {
|
||||
let stdout = thin_repair!("-h").read()?;
|
||||
assert_eq!(stdout, USAGE);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn accepts_help() -> Result<()> {
|
||||
let stdout = thin_repair!("--help").read()?;
|
||||
assert_eq!(stdout, USAGE);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dont_repair_xml() -> Result<()> {
|
||||
let mut td = TestDir::new()?;
|
||||
let md = mk_zeroed_md(&mut td)?;
|
||||
let xml = mk_valid_xml(&mut td)?;
|
||||
run_fail(thin_repair!("-i", &xml, "-o", &md))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn missing_input_file() -> Result<()> {
|
||||
let mut td = TestDir::new()?;
|
||||
let md = mk_zeroed_md(&mut td)?;
|
||||
let stderr = run_fail(thin_repair!("-i", "no-such-file", "-o", &md))?;
|
||||
assert!(superblock_all_zeroes(&md)?);
|
||||
assert!(stderr.contains("Couldn't stat file"));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn garbage_input_file() -> Result<()> {
|
||||
let mut td = TestDir::new()?;
|
||||
let md = mk_zeroed_md(&mut td)?;
|
||||
let md2 = mk_zeroed_md(&mut td)?;
|
||||
run_fail(thin_repair!("-i", &md, "-o", &md2))?;
|
||||
assert!(superblock_all_zeroes(&md2)?);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn missing_output_file() -> Result<()> {
|
||||
let mut td = TestDir::new()?;
|
||||
let md = mk_valid_md(&mut td)?;
|
||||
let stderr = run_fail(thin_repair!("-i", &md))?;
|
||||
assert!(stderr.contains("No output file provided."));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn override_thing(flag: &str, val: &str, pattern: &str) -> Result<()> {
|
||||
let mut td = TestDir::new()?;
|
||||
let md1 = mk_valid_md(&mut td)?;
|
||||
let md2 = mk_zeroed_md(&mut td)?;
|
||||
let output = thin_repair!(flag, val, "-i", &md1, "-o", &md2).run()?;
|
||||
assert_eq!(output.stderr.len(), 0);
|
||||
let output = thin_dump!(&md2).run()?;
|
||||
assert!(from_utf8(&output.stdout[0..])?.contains(pattern));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn override_transaction_id() -> Result<()> {
|
||||
override_thing("--transaction-id", "2345", "transaction=\"2345\"")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn override_data_block_size() -> Result<()> {
|
||||
override_thing("--data-block-size", "8192", "data_block_size=\"8192\"")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn override_nr_data_blocks() -> Result<()> {
|
||||
override_thing("--nr-data-blocks", "234500", "nr_data_blocks=\"234500\"")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn superblock_succeeds() -> Result<()> {
|
||||
let mut td = TestDir::new()?;
|
||||
let md1 = mk_valid_md(&mut td)?;
|
||||
let original = thin_dump!(
|
||||
"--transaction-id=5",
|
||||
"--data-block-size=128",
|
||||
"--nr-data-blocks=4096000",
|
||||
&md1
|
||||
)
|
||||
.run()?;
|
||||
assert_eq!(original.stderr.len(), 0);
|
||||
damage_superblock(&md1)?;
|
||||
let md2 = mk_zeroed_md(&mut td)?;
|
||||
thin_repair!(
|
||||
"--transaction-id=5",
|
||||
"--data-block-size=128",
|
||||
"--nr-data-blocks=4096000",
|
||||
"-i",
|
||||
&md1,
|
||||
"-o",
|
||||
&md2
|
||||
)
|
||||
.run()?;
|
||||
let repaired = thin_dump!(&md2).run()?;
|
||||
assert_eq!(repaired.stderr.len(), 0);
|
||||
assert_eq!(original.stdout, repaired.stdout);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn missing_thing(flag1: &str, flag2: &str, pattern: &str) -> Result<()>
|
||||
{
|
||||
let mut td = TestDir::new()?;
|
||||
let md1 = mk_valid_md(&mut td)?;
|
||||
damage_superblock(&md1)?;
|
||||
let md2 = mk_zeroed_md(&mut td)?;
|
||||
let stderr = run_fail(thin_repair!(flag1, flag2, "-i", &md1, "-o", &md2))?;
|
||||
assert!(stderr.contains(pattern));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn missing_transaction_id() -> Result<()> {
|
||||
missing_thing("--data-block-size=128", "--nr-data-blocks=4096000", "transaction id")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn missing_data_block_size() -> Result<()> {
|
||||
missing_thing("--transaction-id=5", "--nr-data-blocks=4096000", "data block size")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn missing_nr_data_blocks() -> Result<()> {
|
||||
missing_thing("--transaction-id=5", "--data-block-size=128", "nr data blocks")
|
||||
}
|
@ -47,10 +47,7 @@ fn rejects_bad_option() -> Result<()> {
|
||||
fn valid_region_format_should_pass() -> Result<()> {
|
||||
let mut td = TestDir::new()?;
|
||||
let md = mk_valid_md(&mut td)?;
|
||||
let output = thin_rmap!("--region", "23..7890", &md).unchecked().run()?;
|
||||
eprintln!("stdout: {:?}", output.stdout);
|
||||
eprintln!("stderr: {:?}", output.stderr);
|
||||
assert!(output.status.success());
|
||||
thin_rmap!("--region", "23..7890", &md).run()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user