diff --git a/tests/testsuite/bench.rs b/tests/testsuite/bench.rs index b7009f6d18b..fff7083e3d8 100644 --- a/tests/testsuite/bench.rs +++ b/tests/testsuite/bench.rs @@ -1,5 +1,4 @@ use support::is_nightly; -use support::paths::CargoPathExt; use support::{basic_bin_manifest, basic_lib_manifest, basic_manifest, project}; #[test] @@ -13,22 +12,23 @@ fn cargo_bench_simple() { .file( "src/main.rs", r#" - #![feature(test)] - #[cfg(test)] - extern crate test; - - fn hello() -> &'static str { - "hello" - } - - pub fn main() { - println!("{}", hello()) - } - - #[bench] - fn bench_hello(_b: &mut test::Bencher) { - assert_eq!(hello(), "hello") - }"#, + #![feature(test)] + #[cfg(test)] + extern crate test; + + fn hello() -> &'static str { + "hello" + } + + pub fn main() { + println!("{}", hello()) + } + + #[bench] + fn bench_hello(_b: &mut test::Bencher) { + assert_eq!(hello(), "hello") + } + "#, ).build(); p.cargo("build").run(); @@ -42,7 +42,8 @@ fn cargo_bench_simple() { [COMPILING] foo v0.5.0 (CWD) [FINISHED] release [optimized] target(s) in [..] [RUNNING] target/release/deps/foo-[..][EXE]", - ).with_stdout_contains("test bench_hello ... bench: [..]") + ) + .with_stdout_contains("test bench_hello ... bench: [..]") .run(); } @@ -844,7 +845,7 @@ fn bench_dylib() { return; } - let p = project() + let mut p = project() .file( "Cargo.toml", r#" @@ -913,7 +914,7 @@ fn bench_dylib() { ).with_stdout_contains_n("test foo ... bench: [..]", 2) .run(); - p.root().move_into_the_past(); + p.write_file("foo", "bar"); p.cargo("bench -v") .with_stderr( "\ diff --git a/tests/testsuite/build.rs b/tests/testsuite/build.rs index 7c0d4245a5e..b9cad7f2270 100644 --- a/tests/testsuite/build.rs +++ b/tests/testsuite/build.rs @@ -1,13 +1,15 @@ use std::env; use std::fs::{self, File}; use std::io::prelude::*; +use std::thread; +use std::time::Duration; use cargo::util::paths::dylib_path_envvar; use support::paths::{root, CargoPathExt}; use support::registry::Package; use support::ProjectBuilder; use support::{ - basic_bin_manifest, basic_lib_manifest, basic_manifest, is_nightly, rustc_host, sleep_ms, + basic_bin_manifest, basic_lib_manifest, basic_manifest, is_nightly, rustc_host, }; use support::{main_file, project, Execs}; @@ -1986,7 +1988,7 @@ fn inferred_main_bin() { #[test] fn deletion_causes_failure() { - let p = project() + let mut p = project() .file( "Cargo.toml", r#" @@ -2004,7 +2006,7 @@ fn deletion_causes_failure() { .build(); p.cargo("build").run(); - p.change_file("Cargo.toml", &basic_manifest("foo", "0.0.1")); + p.write_file("Cargo.toml", &basic_manifest("foo", "0.0.1")); p.cargo("build").with_status(101).run(); } @@ -2123,7 +2125,7 @@ fn single_lib() { #[test] fn freshness_ignores_excluded() { - let foo = project() + let mut foo = project() .file( "Cargo.toml", r#" @@ -2137,7 +2139,6 @@ fn freshness_ignores_excluded() { ).file("build.rs", "fn main() {}") .file("src/lib.rs", "pub fn bar() -> i32 { 1 }") .build(); - foo.root().move_into_the_past(); foo.cargo("build") .with_stderr( @@ -2149,17 +2150,17 @@ fn freshness_ignores_excluded() { // Smoke test to make sure it doesn't compile again println!("first pass"); - foo.cargo("build").with_stdout("").run(); + foo.cargo("build").with_stderr("[FINISHED] [..]\n").run(); // Modify an ignored file and make sure we don't rebuild println!("second pass"); - File::create(&foo.root().join("src/bar.rs")).unwrap(); - foo.cargo("build").with_stdout("").run(); + foo.write_file("src/bar.rs", ""); + foo.cargo("build").with_stderr("[FINISHED] [..]\n").run(); } #[test] fn rebuild_preserves_out_dir() { - let foo = project() + let mut foo = project() .file( "Cargo.toml", r#" @@ -2187,7 +2188,6 @@ fn rebuild_preserves_out_dir() { "#, ).file("src/lib.rs", "pub fn bar() -> i32 { 1 }") .build(); - foo.root().move_into_the_past(); foo.cargo("build") .env("FIRST", "1") @@ -2198,7 +2198,7 @@ fn rebuild_preserves_out_dir() { ", ).run(); - File::create(&foo.root().join("src/bar.rs")).unwrap(); + foo.write_file("src/bar.rs", ""); foo.cargo("build") .with_stderr( "\ @@ -2247,8 +2247,7 @@ fn recompile_space_in_name() { ).file("src/my lib.rs", "") .build(); foo.cargo("build").run(); - foo.root().move_into_the_past(); - foo.cargo("build").with_stdout("").run(); + foo.cargo("build").with_stderr("[FINISHED] [..]\n").run(); } #[cfg(unix)] @@ -2524,7 +2523,7 @@ fn compile_then_delete() { assert!(p.bin("foo").is_file()); if cfg!(windows) { // On windows unlinking immediately after running often fails, so sleep - sleep_ms(100); + thread::sleep(Duration::from_millis(100)); } fs::remove_file(&p.bin("foo")).unwrap(); p.cargo("run -v").run(); diff --git a/tests/testsuite/build_script.rs b/tests/testsuite/build_script.rs index 6b4382437d5..fb247e3a718 100644 --- a/tests/testsuite/build_script.rs +++ b/tests/testsuite/build_script.rs @@ -9,7 +9,7 @@ use cargo::util::paths::remove_dir_all; use support::paths::CargoPathExt; use support::registry::Package; use support::{basic_manifest, cross_compile, project}; -use support::{rustc_host, sleep_ms}; +use support::rustc_host; #[test] fn custom_build_script_failed() { @@ -528,7 +528,7 @@ fn links_passes_env_vars() { #[test] fn only_rerun_build_script() { - let p = project() + let mut p = project() .file( "Cargo.toml", r#" @@ -543,10 +543,8 @@ fn only_rerun_build_script() { .build(); p.cargo("build -v").run(); - p.root().move_into_the_past(); - File::create(&p.root().join("some-new-file")).unwrap(); - p.root().move_into_the_past(); + p.write_file("some-new-file", ""); p.cargo("build -v") .with_stderr( @@ -585,9 +583,8 @@ fn rebuild_continues_to_pass_env_vars() { } "#, ).build(); - a.root().move_into_the_past(); - let p = project() + let mut p = project() .file( "Cargo.toml", &format!( @@ -616,17 +613,15 @@ fn rebuild_continues_to_pass_env_vars() { ).build(); p.cargo("build -v").run(); - p.root().move_into_the_past(); - File::create(&p.root().join("some-new-file")).unwrap(); - p.root().move_into_the_past(); + p.write_file("some-new-file", ""); p.cargo("build -v").run(); } #[test] fn testing_and_such() { - let p = project() + let mut p = project() .file( "Cargo.toml", r#" @@ -642,10 +637,8 @@ fn testing_and_such() { println!("build"); p.cargo("build -v").run(); - p.root().move_into_the_past(); - File::create(&p.root().join("src/lib.rs")).unwrap(); - p.root().move_into_the_past(); + p.write_file("src/lib.rs", ""); println!("test"); p.cargo("test -vj1") @@ -672,10 +665,7 @@ fn testing_and_such() { ", ).run(); - File::create(&p.root().join("src/main.rs")) - .unwrap() - .write_all(b"fn main() {}") - .unwrap(); + p.write_file("src/main.rs", "fn main() {}"); println!("run"); p.cargo("run") .with_stderr( @@ -979,7 +969,7 @@ fn build_cmd_with_a_build_cmd() { #[test] fn out_dir_is_preserved() { - let p = project() + let mut p = project() .file( "Cargo.toml", r#" @@ -1005,29 +995,27 @@ fn out_dir_is_preserved() { // Make the file p.cargo("build -v").run(); - p.root().move_into_the_past(); // Change to asserting that it's there - File::create(&p.root().join("build.rs")) - .unwrap() - .write_all( - br#" - use std::env; - use std::old_io::File; - fn main() { - let out = env::var("OUT_DIR").unwrap(); - File::open(&Path::new(&out).join("foo")).unwrap(); - } - "#, - ).unwrap(); - p.root().move_into_the_past(); + p.write_file( + "build.rs", + r#" + use std::env; + use std::fs::File; + use std::path::Path; + fn main() { + let out = env::var("OUT_DIR").unwrap(); + File::open(&Path::new(&out).join("foo")).unwrap(); + } + "#, + ); p.cargo("build -v").run(); // Run a fresh build where file should be preserved p.cargo("build -v").run(); // One last time to make sure it's still there. - File::create(&p.root().join("foo")).unwrap(); + p.write_file("foo", ""); p.cargo("build -v").run(); } @@ -1455,12 +1443,10 @@ fn build_script_with_dynamic_native_dependency() { build .cargo("build -v") - .env("RUST_LOG", "cargo::ops::cargo_rustc") .run(); foo.cargo("build -v") .env("SRC", build.root()) - .env("RUST_LOG", "cargo::ops::cargo_rustc") .run(); } @@ -2248,7 +2234,6 @@ fn fresh_builds_possible_with_link_libs() { ).run(); p.cargo("build -v") - .env("RUST_LOG", "cargo::ops::cargo_rustc::fingerprint=info") .with_stderr( "\ [FRESH] foo v0.5.0 ([..]) @@ -2299,7 +2284,6 @@ fn fresh_builds_possible_with_multiple_metadata_overrides() { ).run(); p.cargo("build -v") - .env("RUST_LOG", "cargo::ops::cargo_rustc::fingerprint=info") .with_stderr( "\ [FRESH] foo v0.5.0 ([..]) @@ -2310,7 +2294,12 @@ fn fresh_builds_possible_with_multiple_metadata_overrides() { #[test] fn rebuild_only_on_explicit_paths() { - let p = project() + let sleep = || { + use std::thread; + use std::time::Duration; + thread::sleep(Duration::new(1, 0)); + }; + let mut p = project() .file( "Cargo.toml", r#" @@ -2330,6 +2319,7 @@ fn rebuild_only_on_explicit_paths() { } "#, ).build(); + p.disable_mtime_management(); // TODO: should fix this test a different way... p.cargo("build -v").run(); @@ -2345,10 +2335,10 @@ fn rebuild_only_on_explicit_paths() { ", ).run(); - sleep_ms(1000); - File::create(p.root().join("foo")).unwrap(); - File::create(p.root().join("bar")).unwrap(); - sleep_ms(1000); // make sure the to-be-created outfile has a timestamp distinct from the infiles + sleep(); + p.write_file("foo", ""); + p.write_file("bar", ""); + sleep(); // now the exist, so run once, catch the mtime, then shouldn't run again println!("run with"); @@ -2371,11 +2361,11 @@ fn rebuild_only_on_explicit_paths() { ", ).run(); - sleep_ms(1000); + sleep(); // random other files do not affect freshness println!("run baz"); - File::create(p.root().join("baz")).unwrap(); + p.write_file("baz", ""); p.cargo("build -v") .with_stderr( "\ @@ -2386,7 +2376,7 @@ fn rebuild_only_on_explicit_paths() { // but changing dependent files does println!("run foo change"); - File::create(p.root().join("foo")).unwrap(); + p.write_file("foo", ""); p.cargo("build -v") .with_stderr( "\ @@ -3257,7 +3247,7 @@ fn rename_with_link_search_path() { } "#, ); - let p2 = p2.build(); + let mut p2 = p2.build(); // Move the output `libfoo.so` into the directory of `p2`, and then delete // the `p` project. On OSX the `libfoo.dylib` artifact references the @@ -3306,6 +3296,7 @@ fn rename_with_link_search_path() { println!("assuming {} is spurious, waiting to try again", error); thread::sleep(Duration::from_millis(100)); } + p2.set_root(&new); p2.cargo("run") .cwd(&new) diff --git a/tests/testsuite/build_script_env.rs b/tests/testsuite/build_script_env.rs index 2a7be1aa564..e1305ba4186 100644 --- a/tests/testsuite/build_script_env.rs +++ b/tests/testsuite/build_script_env.rs @@ -1,7 +1,4 @@ -use std::fs::File; - use support::project; -use support::sleep_ms; #[test] fn rerun_if_env_changes() { @@ -54,7 +51,7 @@ fn rerun_if_env_changes() { #[test] fn rerun_if_env_or_file_changes() { - let p = project() + let mut p = project() .file("src/main.rs", "fn main() {}") .file( "build.rs", @@ -86,8 +83,7 @@ fn rerun_if_env_or_file_changes() { .env("FOO", "bar") .with_stderr("[FINISHED] [..]") .run(); - sleep_ms(1000); - File::create(p.root().join("foo")).unwrap(); + p.write_file("foo", ""); p.cargo("build") .env("FOO", "bar") .with_stderr( diff --git a/tests/testsuite/features.rs b/tests/testsuite/features.rs index eaca5b1d94a..6c4d6ead5bc 100644 --- a/tests/testsuite/features.rs +++ b/tests/testsuite/features.rs @@ -1,7 +1,6 @@ use std::fs::File; use std::io::prelude::*; -use support::paths::CargoPathExt; use support::registry::Package; use support::{basic_manifest, project}; @@ -101,7 +100,7 @@ Consider adding `optional = true` to the dependency #[test] fn invalid4() { - let p = project() + let mut p = project() .file( "Cargo.toml", r#" @@ -133,7 +132,7 @@ the package `foo` depends on `bar`, with features: `bar` but `bar` does not have failed to select a version for `bar` which could resolve this conflict", ).run(); - p.change_file("Cargo.toml", &basic_manifest("foo", "0.0.1")); + p.write_file("Cargo.toml", &basic_manifest("foo", "0.0.1")); p.cargo("build --features test") .with_status(101) @@ -747,8 +746,8 @@ fn many_features_no_rebuilds() { [COMPILING] b v0.1.0 (CWD) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); - p.root().move_into_the_past(); + ) + .run(); p.cargo("build -v") .with_stderr( diff --git a/tests/testsuite/freshness.rs b/tests/testsuite/freshness.rs index f450cdb6c9d..db3e80de0a5 100644 --- a/tests/testsuite/freshness.rs +++ b/tests/testsuite/freshness.rs @@ -1,14 +1,14 @@ use std::fs::{self, File}; use std::io::prelude::*; -use support::paths::CargoPathExt; +use filetime::{self, FileTime}; + use support::registry::Package; -use support::sleep_ms; use support::{basic_manifest, project}; #[test] fn modifying_and_moving() { - let p = project() + let mut p = project() .file("src/main.rs", "mod a; fn main() {}") .file("src/a.rs", "") .build(); @@ -22,13 +22,8 @@ fn modifying_and_moving() { ).run(); p.cargo("build").with_stdout("").run(); - p.root().move_into_the_past(); - p.root().join("target").move_into_the_past(); - File::create(&p.root().join("src/a.rs")) - .unwrap() - .write_all(b"#[allow(unused)]fn main() {}") - .unwrap(); + p.write_file("src/a.rs", "#[allow(unused)] fn main() {}"); p.cargo("build") .with_stderr( "\ @@ -37,13 +32,14 @@ fn modifying_and_moving() { ", ).run(); - fs::rename(&p.root().join("src/a.rs"), &p.root().join("src/b.rs")).unwrap(); + p.write_file("src/b.rs", ""); + fs::remove_file(p.root().join("src/a.rs")).unwrap(); p.cargo("build").with_status(101).run(); } #[test] fn modify_only_some_files() { - let p = project() + let mut p = project() .file("src/lib.rs", "mod a;") .file("src/a.rs", "") .file("src/main.rs", "mod b; fn main() {}") @@ -59,22 +55,14 @@ fn modify_only_some_files() { ", ).run(); p.cargo("test").run(); - sleep_ms(1000); assert!(p.bin("foo").is_file()); - let lib = p.root().join("src/lib.rs"); - let bin = p.root().join("src/b.rs"); + // we shouldn't recompile the library + fs::write(p.root().join("src/lib.rs"), "invalid rust code").unwrap(); - File::create(&lib) - .unwrap() - .write_all(b"invalid rust code") - .unwrap(); - File::create(&bin) - .unwrap() - .write_all(b"#[allow(unused)]fn foo() {}") - .unwrap(); - lib.move_into_the_past(); + // but we should recompile the binary + p.write_file("src/b.rs", "#[allow(unused)] fn foo() {}"); // Make sure the binary is rebuilt, not the lib p.cargo("build") @@ -462,7 +450,7 @@ fn changing_bin_features_caches_targets() { #[test] fn rebuild_tests_if_lib_changes() { - let p = project() + let mut p = project() .file("src/lib.rs", "pub fn foo() {}") .file( "tests/foo.rs", @@ -476,8 +464,7 @@ fn rebuild_tests_if_lib_changes() { p.cargo("build").run(); p.cargo("test").run(); - sleep_ms(1000); - File::create(&p.root().join("src/lib.rs")).unwrap(); + p.write_file("src/lib.rs", ""); p.cargo("build -v").run(); p.cargo("test -v").with_status(101).run(); @@ -680,7 +667,11 @@ fn no_rebuild_if_build_artifacts_move_backwards_in_time() { p.cargo("build").run(); - p.root().move_into_the_past(); + filetime::set_file_times( + p.root().join("src/lib.rs"), + FileTime::from_unix_time(0, 0), + FileTime::from_unix_time(0, 0), + ).unwrap(); p.cargo("build") .with_stdout("") @@ -690,29 +681,29 @@ fn no_rebuild_if_build_artifacts_move_backwards_in_time() { #[test] fn rebuild_if_build_artifacts_move_forward_in_time() { - let p = project() + let mut p = project() .file( "Cargo.toml", r#" - [package] - name = "foo" - version = "0.0.1" - authors = [] + [package] + name = "foo" + version = "0.0.1" + authors = [] - [dependencies] - a = { path = "a" } - "#, - ).file("src/lib.rs", "") + [dependencies] + a = { path = "a" } + "#, + ) + .file("src/lib.rs", "") .file("a/Cargo.toml", &basic_manifest("a", "0.0.1")) .file("a/src/lib.rs", "") .build(); p.cargo("build").run(); - p.root().move_into_the_future(); + p.write_file("a/src/lib.rs", ""); p.cargo("build") - .env("RUST_LOG", "") .with_stdout("") .with_stderr( "\ @@ -779,7 +770,7 @@ fn rebuild_if_environment_changes() { #[test] fn no_rebuild_when_rename_dir() { - let p = project() + let mut p = project() .file( "Cargo.toml", r#" @@ -801,9 +792,9 @@ fn no_rebuild_when_rename_dir() { new.pop(); new.push("bar"); fs::rename(p.root(), &new).unwrap(); + p.set_root(&new); p.cargo("build") - .cwd(&new) .with_stderr("[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]") .run(); } diff --git a/tests/testsuite/git.rs b/tests/testsuite/git.rs index c99f5839e06..58e4c148495 100644 --- a/tests/testsuite/git.rs +++ b/tests/testsuite/git.rs @@ -1,6 +1,6 @@ use git2; use std::env; -use std::fs::{self, File}; +use std::fs::File; use std::io::prelude::*; use std::net::{TcpListener, TcpStream}; use std::path::Path; @@ -8,8 +8,7 @@ use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; use std::thread; -use support::paths::{self, CargoPathExt}; -use support::sleep_ms; +use support::paths; use support::{basic_lib_manifest, basic_manifest, git, main_file, path2url, project}; #[test] @@ -756,7 +755,6 @@ fn recompilation() { println!("compile after commit"); p.cargo("build").with_stdout("").run(); - p.root().move_into_the_past(); // Update the dependency and carry on! p.cargo("update") @@ -874,8 +872,6 @@ fn update_with_shared_deps() { git::add(&repo); git::commit(&repo); - sleep_ms(1000); - // By default, not transitive updates println!("dep1 update"); p.cargo("update -p dep1").with_stdout("").run(); @@ -1164,8 +1160,6 @@ fn stale_cached_version() { git::add(&repo); git::commit(&repo); - sleep_ms(1000); - let rev = repo.revparse_single("HEAD").unwrap().id(); File::create(&foo.root().join("Cargo.lock")) @@ -1286,7 +1280,6 @@ fn dep_with_changed_submodule() { git::add(&repo); git::commit(&repo); - sleep_ms(1000); // Update the dependency and carry on! println!("update"); p.cargo("update -v") @@ -1395,9 +1388,6 @@ fn git_build_cmd_freshness() { .file("src/lib.rs", "pub fn bar() -> i32 { 1 }") .file(".gitignore", "src/bar.rs") }).unwrap(); - foo.root().move_into_the_past(); - - sleep_ms(1000); foo.cargo("build") .with_stderr( @@ -1494,7 +1484,6 @@ fn git_repo_changing_no_rebuild() { ).file("src/main.rs", "fn main() {}") .file("build.rs", "fn main() {}") .build(); - p1.root().move_into_the_past(); p1.cargo("build") .with_stderr(&format!( "\ @@ -1551,7 +1540,7 @@ fn git_repo_changing_no_rebuild() { #[test] fn git_dep_build_cmd() { - let p = git::new("foo", |project| { + let mut p = git::new("foo", |project| { project .file( "Cargo.toml", @@ -1602,17 +1591,12 @@ fn git_dep_build_cmd() { ) }).unwrap(); - p.root().join("bar").move_into_the_past(); - p.cargo("build").run(); p.process(&p.bin("foo")).with_stdout("0\n").run(); // Touching bar.rs.in should cause the `build` command to run again. - fs::File::create(&p.root().join("bar/src/bar.rs.in")) - .unwrap() - .write_all(b"pub fn gimme() -> i32 { 1 }") - .unwrap(); + p.write_file("bar/src/bar.rs.in", "pub fn gimme() -> i32 { 1 }"); p.cargo("build").run(); @@ -2385,7 +2369,6 @@ fn include_overrides_gitignore() { ).run(); println!("build 3: touch `src/not_incl.rs`; expect build script *not* re-run"); - sleep_ms(1000); File::create(p.root().join("src").join("not_incl.rs")).unwrap(); p.cargo("build -v") @@ -2403,7 +2386,6 @@ fn include_overrides_gitignore() { // explicitly included file should cause a build-script re-run, // even if that same file is matched by `.gitignore`. println!("build 4: touch `src/incl.rs`; expect build script re-run"); - sleep_ms(1000); File::create(p.root().join("src").join("incl.rs")).unwrap(); p.cargo("build -v") diff --git a/tests/testsuite/out_dir.rs b/tests/testsuite/out_dir.rs index 2700e528d2c..e64074195dd 100644 --- a/tests/testsuite/out_dir.rs +++ b/tests/testsuite/out_dir.rs @@ -2,7 +2,6 @@ use std::env; use std::fs::{self, File}; use std::path::Path; -use support::sleep_ms; use support::{basic_manifest, project}; #[test] @@ -177,7 +176,7 @@ fn out_dir_is_a_file() { #[test] fn replaces_artifacts() { - let p = project() + let mut p = project() .file("src/main.rs", r#"fn main() { println!("foo") }"#) .build(); @@ -190,8 +189,7 @@ fn replaces_artifacts() { ).with_stdout("foo") .run(); - sleep_ms(1000); - p.change_file("src/main.rs", r#"fn main() { println!("bar") }"#); + p.write_file("src/main.rs", r#"fn main() { println!("bar") }"#); p.cargo("build -Z unstable-options --out-dir out") .masquerade_as_nightly_cargo() diff --git a/tests/testsuite/package.rs b/tests/testsuite/package.rs index 3a8503c7d06..f6e1551a6c9 100644 --- a/tests/testsuite/package.rs +++ b/tests/testsuite/package.rs @@ -7,7 +7,7 @@ use flate2::read::GzDecoder; use git2; use support::registry::Package; use support::{basic_manifest, git, is_nightly, path2url, paths, project, registry}; -use support::{cargo_process, sleep_ms}; +use support::cargo_process; use tar::Archive; #[test] @@ -691,7 +691,7 @@ Caused by: #[test] fn do_not_package_if_repository_is_dirty() { - let p = project().build(); + let mut p = project().build(); // Create a Git repository containing a minimal Rust project. let _ = git::repo(&paths::root().join("foo")) @@ -711,7 +711,7 @@ fn do_not_package_if_repository_is_dirty() { .build(); // Modify Cargo.toml without committing the change. - p.change_file( + p.write_file( "Cargo.toml", r#" [project] @@ -1257,7 +1257,7 @@ fn lock_file_and_workspace() { #[test] fn do_not_package_if_src_was_modified() { - let p = project() + let mut p = project() .file("src/main.rs", r#"fn main() { println!("hello"); }"#) .file( "build.rs", @@ -1270,14 +1270,13 @@ fn do_not_package_if_src_was_modified() { file.write_all(b"Hello, world of generated files.").expect("failed to write"); } "#, - ).build(); + ) + .build(); - if cfg!(target_os = "macos") { - // MacOS has 1s resolution filesystem. - // If src/main.rs is created within 1s of src/generated.txt, then it - // won't trigger the modification check. - sleep_ms(1000); - } + // MacOS has 1s resolution filesystem. + // If src/main.rs is created within 1s of src/generated.txt, then it + // won't trigger the modification check. + p.move_start_back_one_second(); p.cargo("package") .with_status(101) diff --git a/tests/testsuite/path.rs b/tests/testsuite/path.rs index 42f6e8ceb53..9de84caf671 100644 --- a/tests/testsuite/path.rs +++ b/tests/testsuite/path.rs @@ -1,9 +1,8 @@ use std::fs::{self, File}; use std::io::prelude::*; -use support::paths::{self, CargoPathExt}; +use support::paths; use support::registry::Package; -use support::sleep_ms; use support::{basic_lib_manifest, basic_manifest, main_file, project}; #[test] @@ -236,7 +235,7 @@ fn cargo_compile_with_transitive_dev_deps() { #[test] fn no_rebuild_dependency() { - let p = project() + let mut p = project() .file( "Cargo.toml", r#" @@ -253,6 +252,7 @@ fn no_rebuild_dependency() { .file("bar/Cargo.toml", &basic_lib_manifest("bar")) .file("bar/src/bar.rs", "pub fn bar() {}") .build(); + // First time around we should compile both foo and bar p.cargo("build") .with_stderr( @@ -262,14 +262,14 @@ fn no_rebuild_dependency() { in [..]\n", ).run(); - sleep_ms(1000); - p.change_file( + p.write_file( "src/main.rs", r#" - extern crate bar; - fn main() { bar::bar(); } - "#, + extern crate bar; + fn main() { bar::bar(); } + "#, ); + // Don't compile bar, but do recompile foo. p.cargo("build") .with_stderr( @@ -282,40 +282,49 @@ fn no_rebuild_dependency() { #[test] fn deep_dependencies_trigger_rebuild() { - let p = project() + let sleep = || { + use std::thread; + use std::time::Duration; + thread::sleep(Duration::new(1, 0)); + }; + let mut p = project() .file( "Cargo.toml", r#" - [project] + [project] - name = "foo" - version = "0.5.0" - authors = ["wycats@example.com"] + name = "foo" + version = "0.5.0" + authors = ["wycats@example.com"] - [dependencies.bar] - path = "bar" - "#, - ).file("src/main.rs", "extern crate bar; fn main() { bar::bar() }") + [dependencies.bar] + path = "bar" + "#, + ) + .file("src/main.rs", "extern crate bar; fn main() { bar::bar() }") .file( "bar/Cargo.toml", r#" - [project] + [project] - name = "bar" - version = "0.5.0" - authors = ["wycats@example.com"] + name = "bar" + version = "0.5.0" + authors = ["wycats@example.com"] - [lib] - name = "bar" - [dependencies.baz] - path = "../baz" - "#, - ).file( + [lib] + name = "bar" + [dependencies.baz] + path = "../baz" + "#, + ) + .file( "bar/src/bar.rs", "extern crate baz; pub fn bar() { baz::baz() }", - ).file("baz/Cargo.toml", &basic_lib_manifest("baz")) + ) + .file("baz/Cargo.toml", &basic_lib_manifest("baz")) .file("baz/src/baz.rs", "pub fn baz() {}") .build(); + p.disable_mtime_management(); p.cargo("build") .with_stderr( "[COMPILING] baz v0.5.0 (CWD/baz)\n\ @@ -327,14 +336,9 @@ fn deep_dependencies_trigger_rebuild() { p.cargo("build").with_stdout("").run(); // Make sure an update to baz triggers a rebuild of bar - // - // We base recompilation off mtime, so sleep for at least a second to ensure - // that this write will change the mtime. - File::create(&p.root().join("baz/src/baz.rs")) - .unwrap() - .write_all(br#"pub fn baz() { println!("hello!"); }"#) - .unwrap(); - sleep_ms(1000); + sleep(); + p.write_file("baz/src/baz.rs", "pub fn baz() {}"); + p.cargo("build") .with_stderr( "[COMPILING] baz v0.5.0 (CWD/baz)\n\ @@ -345,22 +349,22 @@ fn deep_dependencies_trigger_rebuild() { ).run(); // Make sure an update to bar doesn't trigger baz - File::create(&p.root().join("bar/src/bar.rs")) - .unwrap() - .write_all( - br#" - extern crate baz; - pub fn bar() { println!("hello!"); baz::baz(); } - "#, - ).unwrap(); - sleep_ms(1000); + sleep(); + p.write_file( + "bar/src/bar.rs", + r#" + extern crate baz; + pub fn bar() { println!("hello!"); baz::baz(); } + "#, + ); p.cargo("build") .with_stderr( "[COMPILING] bar v0.5.0 (CWD/bar)\n\ [COMPILING] foo v0.5.0 (CWD)\n\ [FINISHED] dev [unoptimized + debuginfo] target(s) \ in [..]\n", - ).run(); + ) + .run(); } #[test] @@ -414,7 +418,7 @@ fn no_rebuild_two_deps() { #[test] fn nested_deps_recompile() { - let p = project() + let mut p = project() .file( "Cargo.toml", r#" @@ -440,13 +444,10 @@ fn nested_deps_recompile() { [COMPILING] foo v0.5.0 (CWD)\n\ [FINISHED] dev [unoptimized + debuginfo] target(s) \ in [..]\n", - ).run(); - sleep_ms(1000); + ) + .run(); - File::create(&p.root().join("src/main.rs")) - .unwrap() - .write_all(br#"fn main() {}"#) - .unwrap(); + p.write_file("src/main.rs", "fn main() {}"); // This shouldn't recompile `bar` p.cargo("build") @@ -617,7 +618,7 @@ fn override_path_dep() { #[test] fn path_dep_build_cmd() { - let p = project() + let mut p = project() .file( "Cargo.toml", r#" @@ -657,7 +658,6 @@ fn path_dep_build_cmd() { "#, ).file("bar/src/bar.rs.in", "pub fn gimme() -> i32 { 0 }") .build(); - p.root().join("bar").move_into_the_past(); p.cargo("build") .with_stderr( @@ -672,12 +672,7 @@ fn path_dep_build_cmd() { p.process(&p.bin("foo")).with_stdout("0\n").run(); // Touching bar.rs.in should cause the `build` command to run again. - { - let file = fs::File::create(&p.root().join("bar/src/bar.rs.in")); - file.unwrap() - .write_all(br#"pub fn gimme() -> i32 { 1 }"#) - .unwrap(); - } + p.write_file("bar/src/bar.rs.in", "pub fn gimme() -> i32 { 1 } "); p.cargo("build") .with_stderr( @@ -775,11 +770,12 @@ fn custom_target_no_rebuild() { ", ).run(); + let mut cargo = p.cargo("build --manifest-path=b/Cargo.toml"); t!(fs::rename( p.root().join("target"), p.root().join("target_moved") )); - p.cargo("build --manifest-path=b/Cargo.toml") + cargo .env("CARGO_TARGET_DIR", "target_moved") .with_stderr( "\ diff --git a/tests/testsuite/publish.rs b/tests/testsuite/publish.rs index f0ebea8f788..82ca761d5c8 100644 --- a/tests/testsuite/publish.rs +++ b/tests/testsuite/publish.rs @@ -407,16 +407,16 @@ fn dont_publish_dirty() { .file( "Cargo.toml", r#" - [project] - name = "foo" - version = "0.0.1" - authors = [] - license = "MIT" - description = "foo" - documentation = "foo" - homepage = "foo" - repository = "foo" - "#, + [project] + name = "foo" + version = "0.0.1" + authors = [] + license = "MIT" + description = "foo" + documentation = "foo" + homepage = "foo" + repository = "foo" + "#, ).file("src/main.rs", "fn main() {}") .build(); diff --git a/tests/testsuite/registry.rs b/tests/testsuite/registry.rs index c449198e528..e1bc4d00ec9 100644 --- a/tests/testsuite/registry.rs +++ b/tests/testsuite/registry.rs @@ -405,10 +405,9 @@ fn lockfile_locks() { ", ).run(); - p.root().move_into_the_past(); Package::new("bar", "0.0.2").publish(); - p.cargo("build").with_stdout("").run(); + p.cargo("build").with_stderr("[FINISHED] [..]\n").run(); } #[test] @@ -444,11 +443,10 @@ fn lockfile_locks_transitively() { ", ).run(); - p.root().move_into_the_past(); Package::new("baz", "0.0.2").publish(); Package::new("bar", "0.0.2").dep("baz", "*").publish(); - p.cargo("build").with_stdout("").run(); + p.cargo("build").with_stderr("[FINISHED] [..]\n").run(); } #[test] @@ -548,7 +546,7 @@ fn yanks_in_lockfiles_are_ok() { Package::new("bar", "0.0.1").yanked(true).publish(); - p.cargo("build").with_stdout("").run(); + p.cargo("build").with_stderr("[FINISHED] [..]\n").run(); p.cargo("update") .with_status(101) @@ -580,7 +578,6 @@ fn update_with_lockfile_if_packages_missing() { Package::new("bar", "0.0.1").publish(); p.cargo("build").run(); - p.root().move_into_the_past(); paths::home().join(".cargo/registry").rm_rf(); p.cargo("build") @@ -886,7 +883,6 @@ fn git_and_registry_dep() { Package::new("a", "0.0.1").publish(); - p.root().move_into_the_past(); p.cargo("build") .with_stderr( "\ @@ -898,11 +894,11 @@ fn git_and_registry_dep() { [COMPILING] foo v0.0.1 (CWD) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s ", - ).run(); - p.root().move_into_the_past(); + ) + .run(); println!("second"); - p.cargo("build").with_stdout("").run(); + p.cargo("build").with_stderr("[FINISHED] [..]\n").run(); } #[test] diff --git a/tests/testsuite/rename_deps.rs b/tests/testsuite/rename_deps.rs index 2716b3b9189..7e2e86e08da 100644 --- a/tests/testsuite/rename_deps.rs +++ b/tests/testsuite/rename_deps.rs @@ -259,7 +259,7 @@ name, but the dependency on `foo v0.1.0` is listed as having different names fn rename_affects_fingerprint() { Package::new("foo", "0.1.0").publish(); - let p = project() + let mut p = project() .file( "Cargo.toml", r#" @@ -278,7 +278,7 @@ fn rename_affects_fingerprint() { p.cargo("build -v").masquerade_as_nightly_cargo().run(); - p.change_file( + p.write_file( "Cargo.toml", r#" cargo-features = ["rename-dependency"] diff --git a/tests/testsuite/rustc_info_cache.rs b/tests/testsuite/rustc_info_cache.rs index defd26dae48..29902db6e98 100644 --- a/tests/testsuite/rustc_info_cache.rs +++ b/tests/testsuite/rustc_info_cache.rs @@ -1,5 +1,5 @@ use std::env; -use support::paths::CargoPathExt; +use filetime::{self, FileTime}; use support::{basic_manifest, project}; #[test] @@ -79,7 +79,9 @@ fn rustc_info_cache() { .with_stderr_does_not_contain(update) .run(); - other_rustc.move_into_the_future(); + let mtime = FileTime::from_last_modification_time(&other_rustc.metadata().unwrap()); + let mtime = FileTime::from_unix_time(mtime.unix_seconds() + 1, mtime.nanoseconds()); + filetime::set_file_times(&other_rustc, mtime, mtime).unwrap(); p.cargo("build") .env("RUST_LOG", "cargo::util::rustc=info") diff --git a/tests/testsuite/support/mod.rs b/tests/testsuite/support/mod.rs index e898a96d3f6..7bd8e45e202 100644 --- a/tests/testsuite/support/mod.rs +++ b/tests/testsuite/support/mod.rs @@ -104,20 +104,22 @@ dependency. */ +use std::collections::HashMap; use std::env; use std::ffi::OsStr; use std::fmt; -use std::fs; +use std::fs::{self, File}; use std::io::prelude::*; use std::os; use std::path::{Path, PathBuf}; use std::process::{Command, Output}; use std::str; -use std::time::Duration; +use std::thread; use std::usize; -use cargo; use cargo::util::{CargoResult, ProcessBuilder, ProcessError, Rustc}; +use cargo; +use filetime::{self, FileTime}; use serde_json::{self, Value}; use url::Url; @@ -201,7 +203,21 @@ impl SymlinkBuilder { } pub struct Project { + /// Absolute path to the directory containing `Cargo.toml` for this project. root: PathBuf, + /// `mtime` of a file at the very start of the build, which is used to + /// ensure that all files are always set to this `mtime`. This is set on + /// `build`. + start: FileTime, + /// A map of files which have been updated since this project was created, + /// and the `FileTime` entry is the mtime to set the file to. + updates: HashMap, + /// Each time a file is created/updated we'll simulate time passing, and + /// this counter keeps track of how many times that's happened. + next_update: i64, + /// An escape hatch for a few existing tests to opt out of dealing with + /// `touch_everything_to_start`, shouldn't be used for new tests! + disable_mtime_management: bool, } #[must_use] @@ -225,7 +241,7 @@ impl ProjectBuilder { pub fn new(root: PathBuf) -> ProjectBuilder { ProjectBuilder { - root: Project { root }, + root: Project::at(root), files: vec![], symlinks: vec![], no_manifest: false, @@ -233,9 +249,7 @@ impl ProjectBuilder { } pub fn at>(mut self, path: P) -> Self { - self.root = Project { - root: paths::root().join(path), - }; + self.root = Project::at(paths::root().join(path)); self } @@ -285,8 +299,11 @@ impl ProjectBuilder { symlink.mk(); } - let ProjectBuilder { root, .. } = self; - root + let start = paths::home().join(".start"); + File::create(&start).unwrap(); + let ProjectBuilder { mut root, .. } = self; + root.start = FileTime::from_last_modification_time(&start.metadata().unwrap()); + return root } fn rm_root(&self) { @@ -295,11 +312,41 @@ impl ProjectBuilder { } impl Project { + fn at(root: PathBuf) -> Project { + Project { + root, + start: FileTime::zero(), + next_update: 1, + updates: HashMap::new(), + disable_mtime_management: false, + } + } + /// Root of the project, ex: `/path/to/cargo/target/cit/t0/foo` pub fn root(&self) -> PathBuf { self.root.clone() } + pub fn set_root(&mut self, root: &Path) { + self.root = root.to_path_buf(); + } + + pub fn disable_mtime_management(&mut self) { + self.disable_mtime_management = true; + } + + pub fn write_file(&mut self, path: &str, contents: &str) { + let path = self.root().join(path); + fs::write(&path, contents).unwrap(); + let seconds_offset = self.next_update; + self.next_update += 1; + let new_time = FileTime::from_unix_time( + self.start.unix_seconds() + seconds_offset * 100, + self.start.nanoseconds(), + ); + self.updates.insert(path, new_time); + } + /// Project's target dir, ex: `/path/to/cargo/target/cit/t0/foo/target` pub fn build_dir(&self) -> PathBuf { self.root().join("target") @@ -356,11 +403,6 @@ impl Project { )) } - /// Change the contents of an existing file. - pub fn change_file(&self, path: &str, body: &str) { - FileBuilder::new(self.root().join(path), body).mk() - } - /// Create a `ProcessBuilder` to run a program in the project /// and wrap it in an Execs to assert on the execution. /// Example: @@ -382,6 +424,7 @@ impl Project { if let Some(ref mut p) = execs.process_builder { split_and_add_args(p, cmd); } + self.touch_everything_to_start(&self.root); execs } @@ -449,6 +492,36 @@ impl Project { _ => unreachable!(), } } + + pub fn move_start_back_one_second(&mut self) { + self.start = FileTime::from_unix_time( + self.start.unix_seconds() - 1, + self.start.nanoseconds(), + ); + } + + fn touch_everything_to_start(&self, dir: &Path) { + if self.disable_mtime_management { + return + } + // ignore the target directory as it's got Cargo-specific files in there + if dir.file_name().unwrap() == "target" { + return + } + for entry in dir.read_dir().unwrap() { + let entry = entry.unwrap(); + let path = entry.path(); + let file_type = entry.file_type().unwrap(); + if file_type.is_dir() { + self.touch_everything_to_start(&path); + } else if file_type.is_file() { + let new_time = self.updates.get(&path).cloned().unwrap_or(self.start); + paths::do_op(&path, "set file times", |path| { + filetime::set_file_times(path, new_time, new_time) + }); + } + } + } } // Generates a project layout @@ -1131,7 +1204,7 @@ impl Execs { impl Drop for Execs { fn drop(&mut self) { - if !self.ran { + if !self.ran && !thread::panicking() { panic!("forgot to run this command"); } } @@ -1485,7 +1558,3 @@ pub fn git_process(s: &str) -> ProcessBuilder { split_and_add_args(&mut p, s); p } - -pub fn sleep_ms(ms: u64) { - ::std::thread::sleep(Duration::from_millis(ms)); -} diff --git a/tests/testsuite/support/paths.rs b/tests/testsuite/support/paths.rs index a5544ba0b77..4878d742363 100644 --- a/tests/testsuite/support/paths.rs +++ b/tests/testsuite/support/paths.rs @@ -6,8 +6,6 @@ use std::path::{Path, PathBuf}; use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT}; use std::sync::{Once, ONCE_INIT}; -use filetime::{self, FileTime}; - static CARGO_INTEGRATION_TEST_DIR: &'static str = "cit"; static NEXT_ID: AtomicUsize = ATOMIC_USIZE_INIT; @@ -58,18 +56,6 @@ pub fn home() -> PathBuf { pub trait CargoPathExt { fn rm_rf(&self); fn mkdir_p(&self); - - fn move_into_the_past(&self) { - self.move_in_time(|sec, nsec| (sec - 3600, nsec)) - } - - fn move_into_the_future(&self) { - self.move_in_time(|sec, nsec| (sec + 3600, nsec)) - } - - fn move_in_time(&self, travel_amount: F) - where - F: Fn(i64, u32) -> (i64, u32); } impl CargoPathExt for Path { @@ -99,52 +85,9 @@ impl CargoPathExt for Path { fs::create_dir_all(self) .unwrap_or_else(|e| panic!("failed to mkdir_p {}: {}", self.display(), e)) } - - fn move_in_time(&self, travel_amount: F) - where - F: Fn(i64, u32) -> ((i64, u32)), - { - if self.is_file() { - time_travel(self, &travel_amount); - } else { - recurse(self, &self.join("target"), &travel_amount); - } - - fn recurse(p: &Path, bad: &Path, travel_amount: &F) - where - F: Fn(i64, u32) -> ((i64, u32)), - { - if p.is_file() { - time_travel(p, travel_amount) - } else if !p.starts_with(bad) { - for f in t!(fs::read_dir(p)) { - let f = t!(f).path(); - recurse(&f, bad, travel_amount); - } - } - } - - fn time_travel(path: &Path, travel_amount: &F) - where - F: Fn(i64, u32) -> ((i64, u32)), - { - let stat = t!(path.metadata()); - - let mtime = FileTime::from_last_modification_time(&stat); - - let (sec, nsec) = travel_amount(mtime.unix_seconds(), mtime.nanoseconds()); - let newtime = FileTime::from_unix_time(sec, nsec); - - // Sadly change_file_times has a failure mode where a readonly file - // cannot have its times changed on windows. - do_op(path, "set file times", |path| { - filetime::set_file_times(path, newtime, newtime) - }); - } - } } -fn do_op(path: &Path, desc: &str, mut f: F) +pub fn do_op(path: &Path, desc: &str, mut f: F) where F: FnMut(&Path) -> io::Result<()>, { diff --git a/tests/testsuite/test.rs b/tests/testsuite/test.rs index 5a2fdf730b7..1da33df7126 100644 --- a/tests/testsuite/test.rs +++ b/tests/testsuite/test.rs @@ -1,11 +1,7 @@ -use std::fs::File; -use std::io::prelude::*; - use cargo; -use support::paths::CargoPathExt; use support::registry::Package; use support::{basic_bin_manifest, basic_lib_manifest, basic_manifest, cargo_exe, project}; -use support::{is_nightly, rustc_host, sleep_ms}; +use support::{is_nightly, rustc_host}; #[test] fn cargo_test_simple() { @@ -1042,7 +1038,6 @@ fn test_dylib() { ).with_stdout_contains_n("test foo ... ok", 2) .run(); - p.root().move_into_the_past(); p.cargo("test") .with_stderr( "\ @@ -1558,7 +1553,6 @@ fn build_then_selective_test() { .build(); p.cargo("build").run(); - p.root().move_into_the_past(); p.cargo("test -p b").run(); } @@ -2151,15 +2145,11 @@ fn bin_does_not_rebuild_tests() { .file("src/lib.rs", "") .file("src/main.rs", "fn main() {}") .file("tests/foo.rs", ""); - let p = p.build(); + let mut p = p.build(); p.cargo("test -v").run(); - sleep_ms(1000); - File::create(&p.root().join("src/main.rs")) - .unwrap() - .write_all(b"fn main() { 3; }") - .unwrap(); + p.write_file("src/main.rs", "fn main() { 3; }"); p.cargo("test -v --no-run") .with_stderr( diff --git a/tests/testsuite/workspaces.rs b/tests/testsuite/workspaces.rs index 17c28009ffd..b579aa12754 100644 --- a/tests/testsuite/workspaces.rs +++ b/tests/testsuite/workspaces.rs @@ -1,9 +1,8 @@ use std::env; use std::fs::{self, File}; -use std::io::{Read, Write}; +use std::io::Read; use support::registry::Package; -use support::sleep_ms; use support::{basic_lib_manifest, basic_manifest, git, project}; #[test] @@ -1004,14 +1003,11 @@ fn rebuild_please() { } "#, ); - let p = p.build(); + let mut p = p.build(); p.cargo("run").cwd(p.root().join("bin")).run(); - sleep_ms(1000); - - t!(t!(File::create(p.root().join("lib/src/lib.rs"))) - .write_all(br#"pub fn foo() -> u32 { 1 }"#)); + p.write_file("lib/src/lib.rs", "pub fn foo() -> u32 { 1 }"); p.cargo("build").cwd(p.root().join("lib")).run();