From b4725823ce8a834fb4bc2f924d181f4efd12cd48 Mon Sep 17 00:00:00 2001 From: Omer Ben-Amram Date: Mon, 3 Jun 2019 16:06:28 +0300 Subject: overhauled CLI --- tests/fixtures.rs | 27 ++++++++++++++ tests/skeptic.rs | 1 + tests/test_cli.rs | 62 ++++++++++++++++++++++++++++++++ tests/test_cli_interactive.rs | 82 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 172 insertions(+) create mode 100644 tests/fixtures.rs create mode 100644 tests/skeptic.rs create mode 100644 tests/test_cli.rs create mode 100644 tests/test_cli_interactive.rs (limited to 'tests') diff --git a/tests/fixtures.rs b/tests/fixtures.rs new file mode 100644 index 0000000..17dfed6 --- /dev/null +++ b/tests/fixtures.rs @@ -0,0 +1,27 @@ +#![allow(dead_code)] +use std::path::PathBuf; + +use std::sync::{Once, ONCE_INIT}; + +static LOGGER_INIT: Once = ONCE_INIT; + +// Rust runs the tests concurrently, so unless we synchronize logging access +// it will crash when attempting to run `cargo test` with some logging facilities. +pub fn ensure_env_logger_initialized() { + LOGGER_INIT.call_once(env_logger::init); +} + +pub fn samples_dir() -> PathBuf { + PathBuf::from(file!()) + .parent() + .unwrap() + .parent() + .unwrap() + .join("samples") + .canonicalize() + .unwrap() +} + +pub fn mft_sample() -> PathBuf { + samples_dir().join("MFT") +} diff --git a/tests/skeptic.rs b/tests/skeptic.rs new file mode 100644 index 0000000..ff46c9c --- /dev/null +++ b/tests/skeptic.rs @@ -0,0 +1 @@ +include!(concat!(env!("OUT_DIR"), "/skeptic-tests.rs")); diff --git a/tests/test_cli.rs b/tests/test_cli.rs new file mode 100644 index 0000000..890b055 --- /dev/null +++ b/tests/test_cli.rs @@ -0,0 +1,62 @@ +mod fixtures; + +use fixtures::*; + +use assert_cmd::prelude::*; +use std::fs; +use std::fs::File; +use std::io::{Read, Write}; +use std::process::Command; +use tempfile::tempdir; + +#[test] +fn it_respects_directory_output() { + let d = tempdir().unwrap(); + let f = d.as_ref().join("test.out"); + + let sample = mft_sample(); + + let mut cmd = Command::cargo_bin("mft_dump").expect("failed to find binary"); + cmd.args(&["-f", &f.to_string_lossy(), sample.to_str().unwrap()]); + + assert!( + cmd.output().unwrap().stdout.is_empty(), + "Expected output to be printed to file, but was printed to stdout" + ); + + let mut expected = vec![]; + + File::open(&f).unwrap().read_to_end(&mut expected).unwrap(); + assert!( + !expected.is_empty(), + "Expected output to be printed to file" + ) +} + +#[test] +fn test_it_refuses_to_overwrite_directory() { + let d = tempdir().unwrap(); + + let sample = mft_sample(); + let mut cmd = Command::cargo_bin("mft_dump").expect("failed to find binary"); + cmd.args(&["-f", &d.path().to_string_lossy(), sample.to_str().unwrap()]); + + cmd.assert().failure().code(1); +} + +#[test] +fn test_it_exports_resident_streams() { + let d = tempdir().unwrap(); + + let sample = mft_sample(); + let mut cmd = Command::cargo_bin("mft_dump").expect("failed to find binary"); + cmd.args(&[ + "-e", + &d.path().to_string_lossy().to_string(), + &sample.to_string_lossy().to_string(), + ]); + + cmd.assert().success(); + + assert_eq!(fs::read_dir(d.path()).unwrap().count(), 1108) +} diff --git a/tests/test_cli_interactive.rs b/tests/test_cli_interactive.rs new file mode 100644 index 0000000..5f7111f --- /dev/null +++ b/tests/test_cli_interactive.rs @@ -0,0 +1,82 @@ +// The interactive tests are in a separate file, +// since they use `rexpect`, which internally uses quirky fork semantics to open a pty. +// They will fail if tried to be executed concurrently any other CLI test. + +mod fixtures; + +use fixtures::*; + +use std::fs::File; +use std::io::{Read, Write}; +use tempfile::tempdir; + +use assert_cmd::cargo::cargo_bin; +#[cfg(not(target_os = "windows"))] +use rexpect::spawn; + +// It should behave the same on windows, but interactive testing relies on unix pty internals. +#[test] +#[cfg(not(target_os = "windows"))] +fn test_it_confirms_before_overwriting_a_file() { + let d = tempdir().unwrap(); + let f = d.as_ref().join("test.out"); + + let mut file = File::create(&f).unwrap(); + file.write_all(b"I'm a file!").unwrap(); + + let sample = mft_sample(); + + let cmd_string = format!( + "{bin} -f {output_file} {sample}", + bin = cargo_bin("mft_dump").display(), + output_file = f.to_string_lossy(), + sample = sample.to_str().unwrap() + ); + + let mut p = spawn(&cmd_string, Some(10000)).unwrap(); + p.exp_regex(r#"Are you sure you want to override.*"#) + .unwrap(); + p.send_line("y").unwrap(); + p.exp_eof().unwrap(); + + let mut expected = vec![]; + + File::open(&f).unwrap().read_to_end(&mut expected).unwrap(); + assert!( + !expected.len() > 100, + "Expected output to be printed to file" + ) +} + +#[test] +#[cfg(not(target_os = "windows"))] +fn test_it_confirms_before_overwriting_a_file_and_quits() { + let d = tempdir().unwrap(); + let f = d.as_ref().join("test.out"); + + let mut file = File::create(&f).unwrap(); + file.write_all(b"I'm a file!").unwrap(); + + let sample = mft_sample(); + + let cmd_string = format!( + "{bin} -f {output_file} {sample}", + bin = cargo_bin("mft_dump").display(), + output_file = f.to_string_lossy(), + sample = sample.to_str().unwrap() + ); + + let mut p = spawn(&cmd_string, Some(10000)).unwrap(); + p.exp_regex(r#"Are you sure you want to override.*"#) + .unwrap(); + p.send_line("n").unwrap(); + p.exp_eof().unwrap(); + + let mut expected = vec![]; + + File::open(&f).unwrap().read_to_end(&mut expected).unwrap(); + assert!( + !expected.len() > 100, + "Expected output to be printed to file" + ) +} -- cgit v1.2.3