[functional-tests] Move thin_dump tests to Rust.
cargo test
This commit is contained in:
parent
78db9a24fa
commit
baf1fe325f
@ -67,78 +67,6 @@
|
|||||||
;; to run.
|
;; to run.
|
||||||
(define (register-thin-tests) #t)
|
(define (register-thin-tests) #t)
|
||||||
|
|
||||||
;;;-----------------------------------------------------------
|
|
||||||
;;; thin_dump scenarios
|
|
||||||
;;;-----------------------------------------------------------
|
|
||||||
|
|
||||||
(define-scenario (thin-dump small-input-file)
|
|
||||||
"Fails with small input file"
|
|
||||||
(with-temp-file-sized ((md "thin.bin" 512))
|
|
||||||
(run-fail (thin-dump md))))
|
|
||||||
|
|
||||||
(define-scenario (thin-dump restore-is-noop)
|
|
||||||
"thin_dump followed by thin_restore is a noop."
|
|
||||||
(with-valid-metadata (md)
|
|
||||||
(run-ok-rcv (d1-stdout _) (thin-dump md)
|
|
||||||
(with-temp-file-containing ((xml "thin.xml" d1-stdout))
|
|
||||||
(run-ok (thin-restore "-i" xml "-o" md))
|
|
||||||
(run-ok-rcv (d2-stdout _) (thin-dump md)
|
|
||||||
(assert-equal d1-stdout d2-stdout))))))
|
|
||||||
|
|
||||||
(define-scenario (thin-dump no-stderr)
|
|
||||||
"thin_dump of clean data does not output error messages to stderr"
|
|
||||||
(with-valid-metadata (md)
|
|
||||||
(run-ok-rcv (stdout stderr) (thin-dump md)
|
|
||||||
(assert-eof stderr))))
|
|
||||||
|
|
||||||
(define-scenario (thin-dump override transaction-id)
|
|
||||||
"thin_dump obeys the --transaction-id override"
|
|
||||||
(with-valid-metadata (md)
|
|
||||||
(run-ok-rcv (stdout stderr) (thin-dump "--transaction-id 2345" md)
|
|
||||||
(assert-eof stderr)
|
|
||||||
(assert-matches ".*transaction=\"2345\"" stdout))))
|
|
||||||
|
|
||||||
(define-scenario (thin-dump override data-block-size)
|
|
||||||
"thin_dump obeys the --data-block-size override"
|
|
||||||
(with-valid-metadata (md)
|
|
||||||
(run-ok-rcv (stdout stderr) (thin-dump "--data-block-size 8192" md)
|
|
||||||
(assert-eof stderr)
|
|
||||||
(assert-matches ".*data_block_size=\"8192\"" stdout))))
|
|
||||||
|
|
||||||
(define-scenario (thin-dump override nr-data-blocks)
|
|
||||||
"thin_dump obeys the --nr-data-blocks override"
|
|
||||||
(with-valid-metadata (md)
|
|
||||||
(run-ok-rcv (stdout stderr) (thin-dump "--nr-data-blocks 234500" md)
|
|
||||||
(assert-eof stderr)
|
|
||||||
(assert-matches ".*nr_data_blocks=\"234500\"" stdout))))
|
|
||||||
|
|
||||||
(define-scenario (thin-dump repair-superblock succeeds)
|
|
||||||
"thin_dump can restore a missing superblock"
|
|
||||||
(with-valid-metadata (md)
|
|
||||||
(run-ok-rcv (expected-xml stderr) (thin-dump "--transaction-id=5" "--data-block-size=128" "--nr-data-blocks=4096000" md)
|
|
||||||
(damage-superblock md)
|
|
||||||
(run-ok-rcv (repaired-xml stderr) (thin-dump "--repair" "--transaction-id=5" "--data-block-size=128" "--nr-data-blocks=4096000" md)
|
|
||||||
(assert-eof stderr)
|
|
||||||
(assert-equal expected-xml repaired-xml)))))
|
|
||||||
|
|
||||||
(define-scenario (thin-dump repair-superblock missing-transaction-id)
|
|
||||||
"--transaction-id is mandatory if the superblock is damaged"
|
|
||||||
(with-damaged-superblock (md)
|
|
||||||
(run-fail-rcv (_ stderr) (thin-dump "--repair" "--data-block-size=128" "--nr-data-blocks=4096000" md)
|
|
||||||
(assert-matches ".*transaction id.*" stderr))))
|
|
||||||
|
|
||||||
(define-scenario (thin-dump repair-superblock missing-data-block-size)
|
|
||||||
"--data-block-size is mandatory if the superblock is damaged"
|
|
||||||
(with-damaged-superblock (md)
|
|
||||||
(run-fail-rcv (_ stderr) (thin-dump "--repair" "--transaction-id=5" "--nr-data-blocks=4096000" md)
|
|
||||||
(assert-matches ".*data block size.*" stderr))))
|
|
||||||
|
|
||||||
(define-scenario (thin-dump repair-superblock missing-nr-data-blocks)
|
|
||||||
"--nr-data-blocks is mandatory if the superblock is damaged"
|
|
||||||
(with-damaged-superblock (md)
|
|
||||||
(run-fail-rcv (_ stderr) (thin-dump "--repair" "--transaction-id=5" "--data-block-size=128" md)
|
|
||||||
(assert-matches ".*nr data blocks.*" stderr))))
|
|
||||||
|
|
||||||
;;;-----------------------------------------------------------
|
;;;-----------------------------------------------------------
|
||||||
;;; thin_rmap scenarios
|
;;; thin_rmap scenarios
|
||||||
;;;-----------------------------------------------------------
|
;;;-----------------------------------------------------------
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use duct::{cmd, Expression};
|
use duct::{cmd, Expression};
|
||||||
use std::fs::OpenOptions;
|
use std::fs::OpenOptions;
|
||||||
use std::path::{Path, PathBuf};
|
use std::io::{Read, Write};
|
||||||
|
use std::path::{Display, PathBuf};
|
||||||
use std::str::from_utf8;
|
use std::str::from_utf8;
|
||||||
use tempfile::{tempdir, TempDir};
|
use tempfile::{tempdir, TempDir};
|
||||||
use thinp::file_utils;
|
use thinp::file_utils;
|
||||||
use std::io::{Read};
|
|
||||||
|
|
||||||
pub mod xml_generator;
|
pub mod xml_generator;
|
||||||
use crate::common::xml_generator::{write_xml, FragmentedS, SingleThinS};
|
use crate::common::xml_generator::{write_xml, SingleThinS};
|
||||||
|
|
||||||
//------------------------------------------
|
//------------------------------------------
|
||||||
|
|
||||||
@ -56,7 +56,7 @@ pub struct TestDir {
|
|||||||
impl TestDir {
|
impl TestDir {
|
||||||
pub fn new() -> Result<TestDir> {
|
pub fn new() -> Result<TestDir> {
|
||||||
let dir = tempdir()?;
|
let dir = tempdir()?;
|
||||||
Ok(TestDir {dir, file_count: 0})
|
Ok(TestDir { dir, file_count: 0 })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mk_path(&mut self, file: &str) -> PathBuf {
|
pub fn mk_path(&mut self, file: &str) -> PathBuf {
|
||||||
@ -96,6 +96,7 @@ pub fn mk_valid_md(td: &mut TestDir) -> Result<PathBuf> {
|
|||||||
|
|
||||||
pub fn mk_zeroed_md(td: &mut TestDir) -> Result<PathBuf> {
|
pub fn mk_zeroed_md(td: &mut TestDir) -> Result<PathBuf> {
|
||||||
let md = td.mk_path("meta.bin");
|
let md = td.mk_path("meta.bin");
|
||||||
|
eprintln!("path = {:?}", md);
|
||||||
let _file = file_utils::create_sized_file(&md, 4096 * 4096);
|
let _file = file_utils::create_sized_file(&md, 4096 * 4096);
|
||||||
Ok(md)
|
Ok(md)
|
||||||
}
|
}
|
||||||
@ -120,4 +121,11 @@ pub fn superblock_all_zeroes(path: &PathBuf) -> Result<bool> {
|
|||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn damage_superblock(path: &PathBuf) -> Result<()> {
|
||||||
|
let mut output = OpenOptions::new().read(false).write(true).open(path)?;
|
||||||
|
let buf = [0u8; 512];
|
||||||
|
output.write_all(&buf)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
//------------------------------------------
|
//------------------------------------------
|
||||||
|
@ -1,8 +1,4 @@
|
|||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use duct::{cmd, Expression};
|
|
||||||
use std::path::{Path, PathBuf};
|
|
||||||
use std::str::from_utf8;
|
|
||||||
use tempfile::{tempdir, TempDir};
|
|
||||||
use thinp::file_utils;
|
use thinp::file_utils;
|
||||||
use thinp::version::TOOLS_VERSION;
|
use thinp::version::TOOLS_VERSION;
|
||||||
|
|
||||||
|
136
tests/thin_dump.rs
Normal file
136
tests/thin_dump.rs
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
use anyhow::Result;
|
||||||
|
use thinp::file_utils;
|
||||||
|
use std::fs::OpenOptions;
|
||||||
|
use std::io::{Write};
|
||||||
|
use std::str::from_utf8;
|
||||||
|
|
||||||
|
mod common;
|
||||||
|
|
||||||
|
use common::xml_generator::{write_xml, FragmentedS, SingleThinS};
|
||||||
|
use common::*;
|
||||||
|
|
||||||
|
//------------------------------------------
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn small_input_file() -> Result<()> {
|
||||||
|
let mut td = TestDir::new()?;
|
||||||
|
let md = td.mk_path("meta.bin");
|
||||||
|
file_utils::create_sized_file(&md, 512)?;
|
||||||
|
let _stderr = run_fail(thin_dump!(&md))?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn dump_restore_cycle() -> Result<()> {
|
||||||
|
let mut td = TestDir::new()?;
|
||||||
|
|
||||||
|
let md = mk_valid_md(&mut td)?;
|
||||||
|
let output = thin_dump!(&md).run()?;
|
||||||
|
|
||||||
|
let xml = td.mk_path("meta.xml");
|
||||||
|
let mut file = OpenOptions::new().read(false).write(true).create(true).open(&xml)?;
|
||||||
|
file.write_all(&output.stdout[0..])?;
|
||||||
|
drop(file);
|
||||||
|
|
||||||
|
let md2 = mk_zeroed_md(&mut td)?;
|
||||||
|
thin_restore!("-i", &xml, "-o", &md2).run()?;
|
||||||
|
|
||||||
|
let output2 = thin_dump!(&md2).run()?;
|
||||||
|
assert_eq!(output.stdout, output2.stdout);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn no_stderr() -> Result<()> {
|
||||||
|
let mut td = TestDir::new()?;
|
||||||
|
|
||||||
|
let md = mk_valid_md(&mut td)?;
|
||||||
|
let output = thin_dump!(&md).run()?;
|
||||||
|
|
||||||
|
assert_eq!(output.stderr.len(), 0);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn override_something(flag: &str, value: &str, pattern: &str) -> Result<()> {
|
||||||
|
let mut td = TestDir::new()?;
|
||||||
|
let md = mk_valid_md(&mut td)?;
|
||||||
|
let output = thin_dump!(&md, flag, value).run()?;
|
||||||
|
|
||||||
|
assert_eq!(output.stderr.len(), 0);
|
||||||
|
assert!(from_utf8(&output.stdout[0..])?.contains(pattern));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn override_transaction_id() -> Result<()> {
|
||||||
|
override_something("--transaction-id", "2345", "transaction=\"2345\"")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn override_data_block_size() -> Result<()> {
|
||||||
|
override_something("--data-block-size", "8192", "data_block_size=\"8192\"")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn override_nr_data_blocks() -> Result<()> {
|
||||||
|
override_something("--nr-data-blocks", "234500", "nr_data_blocks=\"234500\"")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn repair_superblock() -> Result<()> {
|
||||||
|
let mut td = TestDir::new()?;
|
||||||
|
let md = mk_valid_md(&mut td)?;
|
||||||
|
let before = thin_dump!("--transaction-id=5", "--data-block-size=128", "--nr-data-blocks=4096000", &md).run()?;
|
||||||
|
damage_superblock(&md)?;
|
||||||
|
|
||||||
|
let after = thin_dump!("--repair", "--transaction-id=5", "--data-block-size=128", "--nr-data-blocks=4096000", &md).run()?;
|
||||||
|
assert_eq!(after.stderr.len(), 0);
|
||||||
|
assert_eq!(before.stdout, after.stdout);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn missing_transaction_id() -> Result<()> {
|
||||||
|
let mut td = TestDir::new()?;
|
||||||
|
let md = mk_valid_md(&mut td)?;
|
||||||
|
damage_superblock(&md)?;
|
||||||
|
let stderr = run_fail(thin_dump!("--repair", "--data-block-size=128", "--nr-data-blocks=4096000", &md))?;
|
||||||
|
assert!(stderr.contains("transaction id"));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn missing_data_block_size() -> Result<()> {
|
||||||
|
let mut td = TestDir::new()?;
|
||||||
|
let md = mk_valid_md(&mut td)?;
|
||||||
|
damage_superblock(&md)?;
|
||||||
|
let stderr = run_fail(thin_dump!("--repair", "--transaction-id=5", "--nr-data-blocks=4096000", &md))?;
|
||||||
|
assert!(stderr.contains("data block size"));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn missing_nr_data_blocks() -> Result<()> {
|
||||||
|
let mut td = TestDir::new()?;
|
||||||
|
let md = mk_valid_md(&mut td)?;
|
||||||
|
damage_superblock(&md)?;
|
||||||
|
let stderr = run_fail(thin_dump!("--repair", "--transaction-id=5", "--data-block-size=128", &md))?;
|
||||||
|
assert!(stderr.contains("nr data blocks"));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// (define-scenario (thin-dump repair-superblock missing-data-block-size)
|
||||||
|
// "--data-block-size is mandatory if the superblock is damaged"
|
||||||
|
// (with-damaged-superblock (md)
|
||||||
|
// (run-fail-rcv (_ stderr) (thin-dump "--repair" "--transaction-id=5" "--nr-data-blocks=4096000" md)
|
||||||
|
// (assert-matches ".*data block size.*" stderr))))
|
||||||
|
//
|
||||||
|
// (define-scenario (thin-dump repair-superblock missing-nr-data-blocks)
|
||||||
|
// "--nr-data-blocks is mandatory if the superblock is damaged"
|
||||||
|
// (with-damaged-superblock (md)
|
||||||
|
// (run-fail-rcv (_ stderr) (thin-dump "--repair" "--transaction-id=5" "--data-block-size=128" md)
|
||||||
|
// (assert-matches ".*nr data blocks.*" stderr))))
|
||||||
|
//
|
@ -1,8 +1,5 @@
|
|||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use duct::{cmd, Expression};
|
|
||||||
use std::path::{Path, PathBuf};
|
|
||||||
use std::str::from_utf8;
|
use std::str::from_utf8;
|
||||||
use tempfile::{tempdir, TempDir};
|
|
||||||
use thinp::file_utils;
|
use thinp::file_utils;
|
||||||
use thinp::version::TOOLS_VERSION;
|
use thinp::version::TOOLS_VERSION;
|
||||||
|
|
||||||
|
@ -3,8 +3,7 @@ use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
|||||||
use rand::prelude::*;
|
use rand::prelude::*;
|
||||||
use std::fs::OpenOptions;
|
use std::fs::OpenOptions;
|
||||||
use std::io::{Cursor, Read, Seek, SeekFrom, Write};
|
use std::io::{Cursor, Read, Seek, SeekFrom, Write};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path};
|
||||||
use tempfile::tempdir;
|
|
||||||
|
|
||||||
use thinp::file_utils;
|
use thinp::file_utils;
|
||||||
use thinp::thin::xml::{self, Visit};
|
use thinp::thin::xml::{self, Visit};
|
||||||
|
Loading…
Reference in New Issue
Block a user