Added tests for recursive shredding.

This commit is contained in:
Alexey Zinchenko 2021-02-14 01:45:49 +03:00
parent b2f0031455
commit 8ddca513ae
2 changed files with 156 additions and 50 deletions

View File

@ -1,45 +1,103 @@
use std::fs::File; use std::fs::File;
use std::io::Write; use std::io::Write;
use rand::Rng;
use ntest::assert_false;
use rand::distributions::Alphanumeric; use rand::distributions::Alphanumeric;
use rand::Rng;
pub const PLAIN_FILE_CONTENT: &str = "some sensitive data"; 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(); std::fs::create_dir_all(TEST_DIR).unwrap();
let filename: String = rand::thread_rng() return match data_type {
.sample_iter(&Alphanumeric) TestDataType::RandomSingleFile => {
.take(7) let filename: String = rand::thread_rng()
.map(char::from) .sample_iter(&Alphanumeric)
.collect(); .take(7)
let tmp_file_path = format!("{}/{}", TEST_DIR, filename); .map(char::from)
let mut tmp_file = File::create(&tmp_file_path).unwrap(); .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::<Vec<String>>();
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.write(PLAIN_FILE_CONTENT.as_bytes()).unwrap();
tmp_file.sync_all().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) { pub fn cleanup(env_details: EnvironmentDetails) {
if std::path::Path::new(&env_details.test_file_path).exists() { match env_details {
std::fs::remove_file(&env_details.test_file_path).unwrap(); 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 enum EnvironmentDetails {
pub test_file_path: String, Single(String),
Multiple(Vec<String>),
} }
impl EnvironmentDetails { impl EnvironmentDetails {
pub fn new(filepath: &str) -> EnvironmentDetails { pub fn single(file: String) -> EnvironmentDetails {
EnvironmentDetails { EnvironmentDetails::Single(file)
test_file_path: filepath.to_string(),
}
} }
pub fn multiple(files: Vec<String>) -> EnvironmentDetails {
EnvironmentDetails::Multiple(files)
}
}
pub enum TestDataType {
RandomSingleFile,
SingleFile(String),
MultipleFiles(Vec<String>),
} }

View File

@ -1,49 +1,97 @@
extern crate rshred; extern crate rshred;
use ntest::timeout;
use ntest::assert_false; use ntest::assert_false;
use ntest::timeout;
mod common; mod common;
#[test] #[test]
#[timeout(1000)] #[timeout(10000)]
fn shredding_without_file_deletion() { 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(); common::check_file_content(filename);
common::check_file_length(filename);
let options = rshred::ShredOptions::new(env_details.test_file_path.to_string()) }
.set_verbosity(rshred::Verbosity::None) common::EnvironmentDetails::Multiple(_) => {
.set_is_interactive(false) unreachable!()
.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::cleanup(env_details); common::cleanup(env_details);
} }
#[test] #[test]
#[timeout(1000)] #[timeout(10000)]
fn shredding_with_file_deletion() { 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()) let shredded_file_exists = std::path::Path::new(filename).exists();
.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(&env_details.test_file_path).exists(); assert_false!(shredded_file_exists);
}
assert_false!(shredded_file_exists); common::EnvironmentDetails::Multiple(_) => {
unreachable!()
}
}
common::cleanup(env_details); common::cleanup(env_details);
} }
#[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);
}