compiletest: Add caching of test results

Don't re-run tests in compiletest if all the inputs haven't changed, manage
stamp files in the output directory.
This commit is contained in:
Alex Crichton 2017-01-31 19:16:45 -08:00
parent 9ad13c8d02
commit c8e0d04878
5 changed files with 49 additions and 1 deletions

1
src/Cargo.lock generated
View 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)",
]

View 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"

View File

@ -25,6 +25,7 @@ use extract_gdb_version;
pub struct EarlyProps {
pub ignore: bool,
pub should_fail: bool,
pub aux: Vec<String>,
}
impl EarlyProps {
@ -32,6 +33,7 @@ impl EarlyProps {
let mut props = EarlyProps {
ignore: false,
should_fail: false,
aux: Vec::new(),
};
iter_header(testfile,
@ -50,6 +52,10 @@ impl EarlyProps {
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");
});

View File

@ -25,6 +25,7 @@ extern crate rustc_serialize;
#[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::fs;
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
//

View 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> {