Skip to content

Commit

Permalink
compiletest: Add caching of test results
Browse files Browse the repository at this point in the history
Don't re-run tests in compiletest if all the inputs haven't changed, manage
stamp files in the output directory.
  • Loading branch information
alexcrichton committed Feb 6, 2017
1 parent 77578dc commit 41904a0
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 1 deletion.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
6 changes: 6 additions & 0 deletions src/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,15 @@ use extract_gdb_version;
pub struct EarlyProps {
pub ignore: bool,
pub should_fail: bool,
pub aux: Vec<String>,
}

impl EarlyProps {
pub fn from_file(config: &Config, testfile: &Path) -> Self {
let mut props = EarlyProps {
ignore: false,
should_fail: false,
aux: Vec::new(),
};

iter_header(testfile,
Expand All @@ -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");
});

Expand Down
40 changes: 39 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,15 @@ extern crate rustc_serialize;
#[macro_use]
extern crate log;
extern crate env_logger;
extern crate filetime;

use std::env;
use std::ffi::OsString;
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};
Expand Down Expand Up @@ -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;
Expand All @@ -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
//
Expand Down
2 changes: 2 additions & 0 deletions src/runtest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ pub fn run(config: Config, testpaths: &TestPaths) {
}

base_cx.complete_all();

File::create(::stamp(&config, &testpaths)).unwrap();
}

struct TestCx<'test> {
Expand Down

0 comments on commit 41904a0

Please sign in to comment.