From 89b600628d5aeaa81d3f7a7821c2b8939fd4d583 Mon Sep 17 00:00:00 2001 From: Joseph Crail Date: Sun, 22 May 2016 13:35:30 -0400 Subject: [PATCH 01/12] tests: move macros into separate module --- tests/common/macros.rs | 48 +++++++++++++++++++++++++++++++++++++++++ tests/common/mod.rs | 1 + tests/common/util.rs | 49 ------------------------------------------ 3 files changed, 49 insertions(+), 49 deletions(-) create mode 100755 tests/common/macros.rs diff --git a/tests/common/macros.rs b/tests/common/macros.rs new file mode 100755 index 000000000..c0005125b --- /dev/null +++ b/tests/common/macros.rs @@ -0,0 +1,48 @@ +#[macro_export] +macro_rules! assert_empty_stderr( + ($cond:expr) => ( + if $cond.stderr.len() > 0 { + panic!(format!("stderr: {}", $cond.stderr)) + } + ); +); + +#[macro_export] +macro_rules! assert_empty_stdout( + ($cond:expr) => ( + if $cond.stdout.len() > 0 { + panic!(format!("stdout: {}", $cond.stdout)) + } + ); +); + +#[macro_export] +macro_rules! assert_no_error( + ($cond:expr) => ( + assert!($cond.success); + if $cond.stderr.len() > 0 { + panic!(format!("stderr: {}", $cond.stderr)) + } + ); +); + +#[macro_export] +macro_rules! path_concat { + ($e:expr, ..$n:expr) => {{ + use std::path::PathBuf; + let n = $n; + let mut pb = PathBuf::new(); + for _ in 0..n { + pb.push($e); + } + pb.to_str().unwrap().to_owned() + }}; + ($($e:expr),*) => {{ + use std::path::PathBuf; + let mut pb = PathBuf::new(); + $( + pb.push($e); + )* + pb.to_str().unwrap().to_owned() + }}; +} diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 870edd9ff..3fcd90441 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -1,2 +1,3 @@ #[macro_use] +pub mod macros; pub mod util; diff --git a/tests/common/util.rs b/tests/common/util.rs index 1e3d42a14..5fc599b50 100755 --- a/tests/common/util.rs +++ b/tests/common/util.rs @@ -30,34 +30,6 @@ static ALREADY_RUN: &'static str = " you have already run this UCommand, if you testing();"; static MULTIPLE_STDIN_MEANINGLESS: &'static str = "Ucommand is designed around a typical use case of: provide args and input stream -> spawn process -> block until completion -> return output streams. For verifying that a particular section of the input stream is what causes a particular behavior, use the Command type directly."; -#[macro_export] -macro_rules! assert_empty_stderr( - ($cond:expr) => ( - if $cond.stderr.len() > 0 { - panic!(format!("stderr: {}", $cond.stderr)) - } - ); -); - -#[macro_export] -macro_rules! assert_empty_stdout( - ($cond:expr) => ( - if $cond.stdout.len() > 0 { - panic!(format!("stdout: {}", $cond.stdout)) - } - ); -); - -#[macro_export] -macro_rules! assert_no_error( - ($cond:expr) => ( - assert!($cond.success); - if $cond.stderr.len() > 0 { - panic!(format!("stderr: {}", $cond.stderr)) - } - ); -); - pub fn repeat_str(s: &str, n: u32) -> String { let mut repeated = String::new(); for _ in 0..n { @@ -66,27 +38,6 @@ pub fn repeat_str(s: &str, n: u32) -> String { repeated } -#[macro_export] -macro_rules! path_concat { - ($e:expr, ..$n:expr) => {{ - use std::path::PathBuf; - let n = $n; - let mut pb = PathBuf::new(); - for _ in 0..n { - pb.push($e); - } - pb.to_str().unwrap().to_owned() - }}; - ($($e:expr),*) => {{ - use std::path::PathBuf; - let mut pb = PathBuf::new(); - $( - pb.push($e); - )* - pb.to_str().unwrap().to_owned() - }}; -} - pub struct CmdResult { pub success: bool, pub stdout: String, From de7b6202a8956781f7586d57f40629d1f2cc0720 Mon Sep 17 00:00:00 2001 From: Joseph Crail Date: Sun, 22 May 2016 13:36:04 -0400 Subject: [PATCH 02/12] tests: move pathchk into new format --- tests/{pathchk.rs => test_pathchk.rs} | 3 --- tests/tests.rs | 1 + 2 files changed, 1 insertion(+), 3 deletions(-) rename tests/{pathchk.rs => test_pathchk.rs} (95%) diff --git a/tests/pathchk.rs b/tests/test_pathchk.rs similarity index 95% rename from tests/pathchk.rs rename to tests/test_pathchk.rs index 0c2857fd8..3af5a6d98 100644 --- a/tests/pathchk.rs +++ b/tests/test_pathchk.rs @@ -1,6 +1,3 @@ -#[macro_use] -mod common; - use common::util::*; static UTIL_NAME: &'static str = "pathchk"; diff --git a/tests/tests.rs b/tests/tests.rs index bae56caed..f2b1354d6 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -46,6 +46,7 @@ mod test_mktemp; mod test_nl; mod test_od; mod test_paste; +mod test_pathchk; mod test_printf; mod test_ptx; mod test_pwd; From 6652e6b57d7a3070b9c6f9524f998b529ae193e2 Mon Sep 17 00:00:00 2001 From: Joseph Crail Date: Sun, 22 May 2016 15:09:04 -0400 Subject: [PATCH 03/12] tests: un-hardcode executable artifact --- tests/common/util.rs | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/tests/common/util.rs b/tests/common/util.rs index 5fc599b50..3e79020f5 100755 --- a/tests/common/util.rs +++ b/tests/common/util.rs @@ -18,18 +18,19 @@ use std::time::Duration; use tempdir::TempDir; #[cfg(windows)] -static PROGNAME: &'static str = "target\\debug\\uutils.exe"; -#[cfg(windows)] -static FIXTURES_DIR: &'static str = "tests\\fixtures"; +static PROGNAME: &'static str = "uutils.exe"; #[cfg(not(windows))] -static PROGNAME: &'static str = "target/debug/uutils"; -#[cfg(not(windows))] -static FIXTURES_DIR: &'static str = "tests/fixtures"; +static PROGNAME: &'static str = "uutils"; + +static TESTS_DIR: &'static str = "tests"; +static FIXTURES_DIR: &'static str = "fixtures"; + static ALREADY_RUN: &'static str = " you have already run this UCommand, if you want to run \ another command in the same test, use TestSet::new instead of \ testing();"; static MULTIPLE_STDIN_MEANINGLESS: &'static str = "Ucommand is designed around a typical use case of: provide args and input stream -> spawn process -> block until completion -> return output streams. For verifying that a particular section of the input stream is what causes a particular behavior, use the Command type directly."; + pub fn repeat_str(s: &str, n: u32) -> String { let mut repeated = String::new(); for _ in 0..n { @@ -337,17 +338,20 @@ impl TestSet { let tmpd = Rc::new(TempDir::new("uutils").unwrap()); let ts = TestSet { bin_path: { - let mut bin_path_builder = env::current_dir().unwrap(); - bin_path_builder.push(PathBuf::from(PROGNAME)); - bin_path_builder + // Instead of hardcoding the path relative to the current + // directory, use Cargo's OUT_DIR to find path to executable. + // This allows tests to be run using profiles other than debug. + let target_dir = path_concat!(env::var("OUT_DIR").unwrap(), "..", "..", ".."); + Path::new(&target_dir).join(PROGNAME).canonicalize().unwrap() }, util_name: String::from(util_name), fixtures: AtPath::new(&tmpd.as_ref().path()), tmpd: tmpd, }; let mut fixture_path_builder = env::current_dir().unwrap(); - fixture_path_builder.push(PathBuf::from(FIXTURES_DIR)); - fixture_path_builder.push(PathBuf::from(util_name)); + fixture_path_builder.push(TESTS_DIR); + fixture_path_builder.push(FIXTURES_DIR); + fixture_path_builder.push(util_name); match fs::metadata(&fixture_path_builder) { Ok(m) => if m.is_dir() { recursive_copy(&fixture_path_builder, &ts.fixtures.subdir).unwrap(); From 8d42cecc5fb62f2a2a93c74e49ad9a76d9c894b0 Mon Sep 17 00:00:00 2001 From: Joseph Crail Date: Sun, 22 May 2016 15:15:57 -0400 Subject: [PATCH 04/12] tests: remove unused comment --- tests/common/util.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/common/util.rs b/tests/common/util.rs index 3e79020f5..7fe99dda3 100755 --- a/tests/common/util.rs +++ b/tests/common/util.rs @@ -178,7 +178,6 @@ impl AtPath { } fn minus(&self, name: &str) -> PathBuf { - // relative_from is currently unstable let prefixed = PathBuf::from(name); if prefixed.starts_with(&self.subdir) { let mut unprefixed = PathBuf::new(); From a7a10f357a771eb493c98adee21633fe609dfe89 Mon Sep 17 00:00:00 2001 From: Joseph Crail Date: Sun, 22 May 2016 15:29:23 -0400 Subject: [PATCH 05/12] tests: remove scoped files Scoped files were deprecated by scoped temporary directories used by the test harness. --- tests/common/util.rs | 39 --------------------------------------- tests/test_tail.rs | 12 ++++++------ 2 files changed, 6 insertions(+), 45 deletions(-) diff --git a/tests/common/util.rs b/tests/common/util.rs index 7fe99dda3..c0a28a0ea 100755 --- a/tests/common/util.rs +++ b/tests/common/util.rs @@ -3,7 +3,6 @@ use std::env; use std::fs::{self, File, OpenOptions}; use std::io::{Read, Write, Result}; -use std::ops::{Deref, DerefMut}; #[cfg(unix)] use std::os::unix::fs::symlink as symlink_file; #[cfg(windows)] @@ -120,40 +119,6 @@ pub fn get_root_path() -> &'static str { } } -/// A scoped, temporary file that is removed upon drop. -pub struct ScopedFile { - path: PathBuf, - file: File, -} - -impl ScopedFile { - fn new(path: PathBuf, file: File) -> ScopedFile { - ScopedFile { - path: path, - file: file - } - } -} - -impl Deref for ScopedFile { - type Target = File; - fn deref(&self) -> &File { - &self.file - } -} - -impl DerefMut for ScopedFile { - fn deref_mut(&mut self) -> &mut File { - &mut self.file - } -} - -impl Drop for ScopedFile { - fn drop(&mut self) { - fs::remove_file(&self.path).unwrap(); - } -} - pub struct AtPath { pub subdir: PathBuf, } @@ -234,10 +199,6 @@ impl AtPath { } } - pub fn make_scoped_file(&self, name: &str) -> ScopedFile { - ScopedFile::new(self.plus(name), self.make_file(name)) - } - pub fn touch(&self, file: &str) { log_info("touch", self.plus_as_string(file)); File::create(&self.plus(file)).unwrap(); diff --git a/tests/test_tail.rs b/tests/test_tail.rs index b3d211e2b..fbd527b39 100644 --- a/tests/test_tail.rs +++ b/tests/test_tail.rs @@ -65,13 +65,13 @@ fn test_single_big_args() { let (at, mut ucmd) = testing(UTIL_NAME); - let mut big_input = at.make_scoped_file(FILE); + let mut big_input = at.make_file(FILE); for i in 0..LINES { write!(&mut big_input, "Line {}\n", i).expect("Could not write to FILE"); } big_input.flush().expect("Could not flush FILE"); - let mut big_expected = at.make_scoped_file(EXPECTED_FILE); + let mut big_expected = at.make_file(EXPECTED_FILE); for i in (LINES - N_ARG)..LINES { write!(&mut big_expected, "Line {}\n", i).expect("Could not write to EXPECTED_FILE"); } @@ -104,14 +104,14 @@ fn test_bytes_big() { let (at, mut ucmd) = testing(UTIL_NAME); - let mut big_input = at.make_scoped_file(FILE); + let mut big_input = at.make_file(FILE); for i in 0..BYTES { let digit = from_digit((i % 10) as u32, 10).unwrap(); write!(&mut big_input, "{}", digit).expect("Could not write to FILE"); } big_input.flush().expect("Could not flush FILE"); - let mut big_expected = at.make_scoped_file(EXPECTED_FILE); + let mut big_expected = at.make_file(EXPECTED_FILE); for i in (BYTES - N_ARG)..BYTES { let digit = from_digit((i % 10) as u32, 10).unwrap(); write!(&mut big_expected, "{}", digit).expect("Could not write to EXPECTED_FILE"); @@ -171,13 +171,13 @@ fn test_lines_with_size_suffix() { let (at, mut ucmd) = testing(UTIL_NAME); - let mut big_input = at.make_scoped_file(FILE); + let mut big_input = at.make_file(FILE); for i in 0..LINES { writeln!(&mut big_input, "Line {}", i).expect("Could not write to FILE"); } big_input.flush().expect("Could not flush FILE"); - let mut big_expected = at.make_scoped_file(EXPECTED_FILE); + let mut big_expected = at.make_file(EXPECTED_FILE); for i in (LINES - N_ARG)..LINES { writeln!(&mut big_expected, "Line {}", i).expect("Could not write to EXPECTED_FILE"); } From b50fc88eadc39c0b84f951ef77e684d375bced56 Mon Sep 17 00:00:00 2001 From: Joseph Crail Date: Sun, 22 May 2016 16:04:09 -0400 Subject: [PATCH 06/12] mktemp: use tempfile crate from crates.io --- Cargo.lock | 20 +++++++++++++++++--- src/mktemp/Cargo.toml | 2 +- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d2464e9f8..2a0b1b345 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -515,7 +515,7 @@ dependencies = [ "getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tempfile 1.1.3 (git+https://github.com/Stebalien/tempfile.git)", + "tempfile 2.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "uucore 0.0.1", ] @@ -790,6 +790,19 @@ name = "rustc-serialize" version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "rustc_version" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "semver" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "seq" version = "0.0.1" @@ -914,12 +927,13 @@ dependencies = [ [[package]] name = "tempfile" -version = "1.1.3" -source = "git+https://github.com/Stebalien/tempfile.git#34e42b9fdd931ad694900b0afd7c7553a4ac8dd0" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/src/mktemp/Cargo.toml b/src/mktemp/Cargo.toml index 2545d17e9..d52718ce7 100644 --- a/src/mktemp/Cargo.toml +++ b/src/mktemp/Cargo.toml @@ -12,4 +12,4 @@ uucore = { path="../uucore" } getopts = "*" libc = "*" rand = "0.3" -tempfile = {git = "https://github.com/Stebalien/tempfile.git"} +tempfile = "*" From b132f65126995741013e2cfe6d22d23ecaba32f2 Mon Sep 17 00:00:00 2001 From: Joseph Crail Date: Sun, 22 May 2016 16:05:10 -0400 Subject: [PATCH 07/12] mktemp: build standalone executable --- src/mktemp/Cargo.toml | 4 ++++ src/mktemp/main.rs | 5 +++++ 2 files changed, 9 insertions(+) create mode 100644 src/mktemp/main.rs diff --git a/src/mktemp/Cargo.toml b/src/mktemp/Cargo.toml index d52718ce7..63f0f9580 100644 --- a/src/mktemp/Cargo.toml +++ b/src/mktemp/Cargo.toml @@ -13,3 +13,7 @@ getopts = "*" libc = "*" rand = "0.3" tempfile = "*" + +[[bin]] +name = "mktemp" +path = "main.rs" diff --git a/src/mktemp/main.rs b/src/mktemp/main.rs new file mode 100644 index 000000000..c736c6feb --- /dev/null +++ b/src/mktemp/main.rs @@ -0,0 +1,5 @@ +extern crate uu_mktemp; + +fn main() { + std::process::exit(uu_mktemp::uumain(std::env::args().collect())); +} From af6c88f676201ea4a6176a1c266f8d83c55b3179 Mon Sep 17 00:00:00 2001 From: Joseph Crail Date: Sun, 22 May 2016 16:08:22 -0400 Subject: [PATCH 08/12] mktemp: fix whitespace --- src/mktemp/mktemp.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/mktemp/mktemp.rs b/src/mktemp/mktemp.rs index ff7e0d22b..a4df5adf5 100644 --- a/src/mktemp/mktemp.rs +++ b/src/mktemp/mktemp.rs @@ -31,7 +31,6 @@ static VERSION: &'static str = env!("CARGO_PKG_VERSION"); static DEFAULT_TEMPLATE: &'static str = "tmp.XXXXXXXXXX"; - pub fn uumain(args: Vec) -> i32 { let mut opts = getopts::Options::new(); opts.optflag("d", "directory", "Make a directory instead of a file"); @@ -171,16 +170,12 @@ pub fn dry_exec(mut tmpdir: PathBuf, prefix: &str, rand: usize, suffix: &str) -> 0 } - - - fn exec(tmpdir: PathBuf, prefix: &str, rand: usize, suffix: &str, make_dir: bool) -> i32 { // TODO: respect make_dir option if make_dir { crash!(1, "Directory option is not supported yet. Sorry."); } - let tmpfile = NamedTempFileOptions::new() .prefix(prefix) .rand_bytes(rand) From 53c62db8d62be40b7ec54533554604072f3ff43a Mon Sep 17 00:00:00 2001 From: Joseph Crail Date: Sun, 22 May 2016 15:50:54 -0400 Subject: [PATCH 09/12] pathchk: make Unix only --- tests/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/tests.rs b/tests/tests.rs index f2b1354d6..044ba6ffa 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -17,6 +17,7 @@ mod sieve; #[cfg(unix)] mod test_chmod; #[cfg(unix)] mod test_mv; +#[cfg(unix)] mod test_pathchk; #[cfg(unix)] mod test_stdbuf; #[cfg(unix)] mod test_touch; #[cfg(unix)] mod test_unlink; @@ -46,7 +47,6 @@ mod test_mktemp; mod test_nl; mod test_od; mod test_paste; -mod test_pathchk; mod test_printf; mod test_ptx; mod test_pwd; From 678a05d90fb6ab56742919cb4d37f078242d8a41 Mon Sep 17 00:00:00 2001 From: Joseph Crail Date: Sun, 22 May 2016 18:48:12 -0400 Subject: [PATCH 10/12] mktemp: add build for all systems --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index a6a820e48..23e63faa8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,6 @@ unix = [ "logname", "mkfifo", "mknod", - "mktemp", "mv", "nice", "nohup", @@ -55,6 +54,7 @@ generic = [ "ln", "ls", "mkdir", + "mktemp", "nl", "nproc", "od", From efce1ac3f979035f1debabd985f1491759fd5cae Mon Sep 17 00:00:00 2001 From: Joseph Crail Date: Sun, 22 May 2016 19:38:37 -0400 Subject: [PATCH 11/12] appveyor: don't double build The integration tests build the multicall executable a second time, so we disable the original build and only run the tests. --- appveyor.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 5f3e0b527..ac9aa5828 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -11,12 +11,11 @@ install: - rustc -V - cargo -V -build_script: - - cargo build --release --features generic --no-default-features - artifacts: - - path: target\release\uutils.exe + - path: target\debug\uutils.exe name: uutils.exe +build: false + test_script: - cargo test --no-fail-fast --features generic --no-default-features From 56c9ccc347c46e929dbcd5f0454f964f30c37c4e Mon Sep 17 00:00:00 2001 From: Joseph Crail Date: Sun, 22 May 2016 22:43:00 -0400 Subject: [PATCH 12/12] tests/common: remove prefixed chars on Windows --- tests/common/util.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/common/util.rs b/tests/common/util.rs index c0a28a0ea..1af869ce1 100755 --- a/tests/common/util.rs +++ b/tests/common/util.rs @@ -301,8 +301,8 @@ impl TestSet { // Instead of hardcoding the path relative to the current // directory, use Cargo's OUT_DIR to find path to executable. // This allows tests to be run using profiles other than debug. - let target_dir = path_concat!(env::var("OUT_DIR").unwrap(), "..", "..", ".."); - Path::new(&target_dir).join(PROGNAME).canonicalize().unwrap() + let target_dir = path_concat!(env::var("OUT_DIR").unwrap(), "..", "..", "..", PROGNAME); + PathBuf::from(AtPath::new(&Path::new(&target_dir)).root_dir_resolved()) }, util_name: String::from(util_name), fixtures: AtPath::new(&tmpd.as_ref().path()),