]> git.lizzy.rs Git - rust.git/commitdiff
compiletest: Add caching of test results
authorAlex Crichton <alex@alexcrichton.com>
Wed, 1 Feb 2017 03:16:45 +0000 (19:16 -0800)
committerAlex Crichton <alex@alexcrichton.com>
Mon, 6 Feb 2017 16:44:27 +0000 (08:44 -0800)
Don't re-run tests in compiletest if all the inputs haven't changed, manage
stamp files in the output directory.

src/Cargo.lock
src/tools/compiletest/Cargo.toml
src/tools/compiletest/src/header.rs
src/tools/compiletest/src/main.rs
src/tools/compiletest/src/runtest.rs

index 06cf32ad0f6b5306ed22d5e11c65d63035393e9a..79e75dc70f9c1449241d8c46940b79da2bbd2367 100644 (file)
@@ -99,6 +99,7 @@ name = "compiletest"
 version = "0.0.0"
 dependencies = [
  "env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
index 3049875e86ea30cea6eee671de9187277e4e3b03..1fc98a78a7c473c73148174942d0e62f82bb9fda 100644 (file)
@@ -7,3 +7,4 @@ version = "0.0.0"
 log = "0.3"
 env_logger = { version = "0.3.5", default-features = false }
 rustc-serialize = "0.3"
+filetime = "0.1"
index 71d8d62c75b698adb47cf5c9f96989c3faf4fb2c..522cd222c269171efd09f2a2b76e5a527df53d34 100644 (file)
@@ -25,6 +25,7 @@
 pub struct EarlyProps {
     pub ignore: bool,
     pub should_fail: bool,
+    pub aux: Vec<String>,
 }
 
 impl EarlyProps {
@@ -32,6 +33,7 @@ pub fn from_file(config: &Config, testfile: &Path) -> Self {
         let mut props = EarlyProps {
             ignore: false,
             should_fail: false,
+            aux: Vec::new(),
         };
 
         iter_header(testfile,
@@ -50,6 +52,10 @@ pub fn from_file(config: &Config, testfile: &Path) -> Self {
                 ignore_lldb(config, ln) ||
                 ignore_llvm(config, ln);
 
+            if let Some(s) = parse_aux_build(ln) {
+                props.aux.push(s);
+            }
+
             props.should_fail = props.should_fail || parse_name_directive(ln, "should-fail");
         });
 
index c2997c8c160ef1c4b12dac9c796d0819ee371d90..6c63661d7fb345f65acdd296e79ef0cac9db2087 100644 (file)
@@ -25,6 +25,7 @@
 #[macro_use]
 extern crate log;
 extern crate env_logger;
+extern crate filetime;
 
 use std::env;
 use std::ffi::OsString;
@@ -32,6 +33,7 @@
 use std::io;
 use std::path::{Path, PathBuf};
 use std::process::Command;
+use filetime::FileTime;
 use getopts::{optopt, optflag, reqopt};
 use common::Config;
 use common::{Pretty, DebugInfoGdb, DebugInfoLldb, Mode};
@@ -457,7 +459,7 @@ pub fn make_test(config: &Config, testpaths: &TestPaths) -> test::TestDescAndFn
     };
 
     // Debugging emscripten code doesn't make sense today
-    let mut ignore = early_props.ignore;
+    let mut ignore = early_props.ignore || !up_to_date(config, testpaths, &early_props);
     if (config.mode == DebugInfoGdb || config.mode == DebugInfoLldb) &&
         config.target.contains("emscripten") {
         ignore = true;
@@ -473,6 +475,42 @@ pub fn make_test(config: &Config, testpaths: &TestPaths) -> test::TestDescAndFn
     }
 }
 
+fn stamp(config: &Config, testpaths: &TestPaths) -> PathBuf {
+    let stamp_name = format!("{}-H-{}-T-{}-S-{}.stamp",
+                             testpaths.file.file_name().unwrap()
+                                           .to_str().unwrap(),
+                             config.host,
+                             config.target,
+                             config.stage_id);
+    config.build_base.canonicalize()
+          .unwrap_or(config.build_base.clone())
+          .join(stamp_name)
+}
+
+fn up_to_date(config: &Config, testpaths: &TestPaths, props: &EarlyProps) -> bool {
+    let stamp = mtime(&stamp(config, testpaths));
+    let mut inputs = vec![
+        mtime(&testpaths.file),
+        mtime(&config.rustc_path),
+    ];
+    for aux in props.aux.iter() {
+        inputs.push(mtime(&testpaths.file.parent().unwrap()
+                                         .join("auxiliary")
+                                         .join(aux)));
+    }
+    for lib in config.run_lib_path.read_dir().unwrap() {
+        let lib = lib.unwrap();
+        inputs.push(mtime(&lib.path()));
+    }
+    inputs.iter().any(|input| *input > stamp)
+}
+
+fn mtime(path: &Path) -> FileTime {
+    fs::metadata(path).map(|f| {
+        FileTime::from_last_modification_time(&f)
+    }).unwrap_or(FileTime::zero())
+}
+
 pub fn make_test_name(config: &Config, testpaths: &TestPaths) -> test::TestName {
     // Convert a complete path to something like
     //
index a8c46722e163b97956fd27f3e173c3adfb315ba6..10d5f0d979f27a801b0648e9664934dd60132ff7 100644 (file)
@@ -80,6 +80,8 @@ pub fn run(config: Config, testpaths: &TestPaths) {
     }
 
     base_cx.complete_all();
+
+    File::create(::stamp(&config, &testpaths)).unwrap();
 }
 
 struct TestCx<'test> {