diff --git a/tests/common.rs b/tests/common.rs index 280c279..ae597d3 100644 --- a/tests/common.rs +++ b/tests/common.rs @@ -1,45 +1,103 @@ use std::fs::File; use std::io::Write; -use rand::Rng; + +use ntest::assert_false; use rand::distributions::Alphanumeric; +use rand::Rng; pub const PLAIN_FILE_CONTENT: &str = "some sensitive data"; -const TEST_DIR: &str = "target/test"; +pub const TEST_DIR: &str = "target/test"; -pub fn setup() -> EnvironmentDetails { +pub fn setup(data_type: TestDataType) -> EnvironmentDetails { std::fs::create_dir_all(TEST_DIR).unwrap(); - let filename: String = rand::thread_rng() - .sample_iter(&Alphanumeric) - .take(7) - .map(char::from) - .collect(); - let tmp_file_path = format!("{}/{}", TEST_DIR, filename); - let mut tmp_file = File::create(&tmp_file_path).unwrap(); + return match data_type { + TestDataType::RandomSingleFile => { + let filename: String = rand::thread_rng() + .sample_iter(&Alphanumeric) + .take(7) + .map(char::from) + .collect(); + let tmp_file_path = format!("{}/{}", TEST_DIR, filename); + + prepare_file(&tmp_file_path); + + EnvironmentDetails::single(tmp_file_path) + } + TestDataType::SingleFile(filename) => { + let tmp_file_path = format!("{}/{}", TEST_DIR, filename); + + prepare_file(&tmp_file_path); + + EnvironmentDetails::single(tmp_file_path) + } + TestDataType::MultipleFiles(files) => { + let files = files.iter().map(|file| format!("{}/{}", TEST_DIR, file)).collect::>(); + for file in files.iter() { + let path = std::path::Path::new(&file); + let directory = path.parent().unwrap(); + std::fs::create_dir_all(directory).unwrap(); + + prepare_file(&file); + } + + EnvironmentDetails::multiple(files) + } + }; +} + +fn prepare_file(filepath: &str) { + let mut tmp_file = File::create(&filepath).unwrap(); tmp_file.write(PLAIN_FILE_CONTENT.as_bytes()).unwrap(); tmp_file.sync_all().unwrap(); +} - println!("{}", filename); +pub fn check_file_content(file: &String) { + // file's content will become an invalid UTF-8 string + assert_false!(std::fs::read_to_string(file).is_ok()); +} - EnvironmentDetails::new(&tmp_file_path) +pub fn check_file_length(file: &String) { + let shredded_file_length = std::fs::metadata(file).unwrap().len(); + // file's size hasn't changed + assert_eq!(PLAIN_FILE_CONTENT.len() as u64, shredded_file_length); } pub fn cleanup(env_details: EnvironmentDetails) { - if std::path::Path::new(&env_details.test_file_path).exists() { - std::fs::remove_file(&env_details.test_file_path).unwrap(); + match env_details { + EnvironmentDetails::Single(filename) => { + if std::path::Path::new(&filename).exists() { + std::fs::remove_file(&filename).unwrap(); + } + } + EnvironmentDetails::Multiple(files) => { + files.iter().for_each(|file| { + if std::path::Path::new(file).exists() { + std::fs::remove_file(file).unwrap(); + } + }) + } } } -pub struct EnvironmentDetails { - pub test_file_path: String, +pub enum EnvironmentDetails { + Single(String), + Multiple(Vec), } impl EnvironmentDetails { - pub fn new(filepath: &str) -> EnvironmentDetails { - EnvironmentDetails { - test_file_path: filepath.to_string(), - } + pub fn single(file: String) -> EnvironmentDetails { + EnvironmentDetails::Single(file) } + pub fn multiple(files: Vec) -> EnvironmentDetails { + EnvironmentDetails::Multiple(files) + } +} + +pub enum TestDataType { + RandomSingleFile, + SingleFile(String), + MultipleFiles(Vec), } \ No newline at end of file diff --git a/tests/integration_test.rs b/tests/integration_test.rs index 2dd4f86..6519379 100644 --- a/tests/integration_test.rs +++ b/tests/integration_test.rs @@ -1,49 +1,97 @@ extern crate rshred; -use ntest::timeout; use ntest::assert_false; +use ntest::timeout; mod common; #[test] -#[timeout(1000)] +#[timeout(10000)] fn shredding_without_file_deletion() { - let env_details = common::setup(); + let env_details = common::setup(common::TestDataType::RandomSingleFile); + match &env_details { + common::EnvironmentDetails::Single(filename) => { + let options = rshred::ShredOptions::new(filename.to_owned()) + .set_verbosity(rshred::Verbosity::None) + .set_is_interactive(false) + .set_keep_files(true) + .build(); + rshred::Shredder::with_options(options).run(); - let initial_file_length = std::fs::metadata(&env_details.test_file_path).unwrap().len(); - - let options = rshred::ShredOptions::new(env_details.test_file_path.to_string()) - .set_verbosity(rshred::Verbosity::None) - .set_is_interactive(false) - .set_keep_files(true) - .build(); - rshred::Shredder::with_options(options).run(); - - let shredded_file_length = std::fs::metadata(&env_details.test_file_path).unwrap().len(); - // file's size hasn't changed - assert_eq!(initial_file_length, shredded_file_length); - - // file's content will become an invalid UTF-8 string - assert_false!(std::fs::read_to_string(&env_details.test_file_path).is_ok()); + common::check_file_content(filename); + common::check_file_length(filename); + } + common::EnvironmentDetails::Multiple(_) => { + unreachable!() + } + } common::cleanup(env_details); } #[test] -#[timeout(1000)] +#[timeout(10000)] fn shredding_with_file_deletion() { - let env_details = common::setup(); + let env_details = common::setup(common::TestDataType::RandomSingleFile); + match &env_details { + common::EnvironmentDetails::Single(filename) => { + let options = rshred::ShredOptions::new(filename.to_owned()) + .set_verbosity(rshred::Verbosity::None) + .set_is_interactive(false) + .set_keep_files(false) + .build(); + rshred::Shredder::with_options(options).run(); - let options = rshred::ShredOptions::new(env_details.test_file_path.to_string()) - .set_verbosity(rshred::Verbosity::None) - .set_is_interactive(false) - .set_keep_files(false) - .build(); - rshred::Shredder::with_options(options).run(); + let shredded_file_exists = std::path::Path::new(filename).exists(); - let shredded_file_exists = std::path::Path::new(&env_details.test_file_path).exists(); - - assert_false!(shredded_file_exists); + assert_false!(shredded_file_exists); + } + common::EnvironmentDetails::Multiple(_) => { + unreachable!() + } + } common::cleanup(env_details); -} \ No newline at end of file +} + +#[test] +#[timeout(10000)] +fn shredding_directory_recursively() { + let env_details = common::setup(common::TestDataType::MultipleFiles( + vec![ + String::from("test3/subdir1/1.txt"), + String::from("test3/subdir1/2.txt"), + String::from("test3/subdir1/3.txt"), + String::from("test3/subdir1/subdir11/1.txt"), + String::from("test3/subdir1/subdir11/2.txt"), + String::from("test3/subdir2/subdir1/111.txt"), + String::from("test3/subdir3/1231.txt"), + String::from("test3/subdir3/1222.txt"), + String::from("test3/subdir3/1286.txt"), + String::from("test3/subdir3/1286/anotherdir/abs.txt"), + String::from("test3/subdir3/1286/anotherdir/abc.txt"), + ] + )); + + match &env_details { + common::EnvironmentDetails::Single(_) => { + unreachable!() + } + common::EnvironmentDetails::Multiple(files) => { + let options = rshred::ShredOptions::new(format!("{}/{}", common::TEST_DIR, "test3")) + .set_verbosity(rshred::Verbosity::None) + .set_is_interactive(false) + .set_is_recursive(true) + .set_keep_files(true) + .build(); + rshred::Shredder::with_options(options).run(); + + for file in files { + common::check_file_content(file); + common::check_file_length(file); + } + } + } + + common::cleanup(env_details); +}