add incremental test runner and some tests
This commit is contained in:
parent
3fb40c1d95
commit
068142a2e6
12
mk/tests.mk
12
mk/tests.mk
@ -305,6 +305,7 @@ check-stage$(1)-T-$(2)-H-$(3)-exec: \
|
||||
check-stage$(1)-T-$(2)-H-$(3)-doc-crates-exec \
|
||||
check-stage$(1)-T-$(2)-H-$(3)-debuginfo-gdb-exec \
|
||||
check-stage$(1)-T-$(2)-H-$(3)-debuginfo-lldb-exec \
|
||||
check-stage$(1)-T-$(2)-H-$(3)-incremental-exec \
|
||||
check-stage$(1)-T-$(2)-H-$(3)-doc-exec \
|
||||
check-stage$(1)-T-$(2)-H-$(3)-pretty-exec
|
||||
|
||||
@ -481,6 +482,7 @@ DEBUGINFO_LLDB_RS := $(call rwildcard,$(S)src/test/debuginfo/,*.rs)
|
||||
CODEGEN_RS := $(call rwildcard,$(S)src/test/codegen/,*.rs)
|
||||
CODEGEN_CC := $(call rwildcard,$(S)src/test/codegen/,*.cc)
|
||||
CODEGEN_UNITS_RS := $(call rwildcard,$(S)src/test/codegen-units/,*.rs)
|
||||
INCREMENTAL_RS := $(call rwildcard,$(S)src/test/incremental/,*.rs)
|
||||
RUSTDOCCK_RS := $(call rwildcard,$(S)src/test/rustdoc/,*.rs)
|
||||
|
||||
RPASS_TESTS := $(RPASS_RS)
|
||||
@ -496,6 +498,7 @@ DEBUGINFO_GDB_TESTS := $(DEBUGINFO_GDB_RS)
|
||||
DEBUGINFO_LLDB_TESTS := $(DEBUGINFO_LLDB_RS)
|
||||
CODEGEN_TESTS := $(CODEGEN_RS) $(CODEGEN_CC)
|
||||
CODEGEN_UNITS_TESTS := $(CODEGEN_UNITS_RS)
|
||||
INCREMENTAL_TESTS := $(INCREMENTAL_RS)
|
||||
RUSTDOCCK_TESTS := $(RUSTDOCCK_RS)
|
||||
|
||||
CTEST_SRC_BASE_rpass = run-pass
|
||||
@ -558,6 +561,11 @@ CTEST_BUILD_BASE_codegen-units = codegen-units
|
||||
CTEST_MODE_codegen-units = codegen-units
|
||||
CTEST_RUNTOOL_codegen-units = $(CTEST_RUNTOOL)
|
||||
|
||||
CTEST_SRC_BASE_incremental = incremental
|
||||
CTEST_BUILD_BASE_incremental = incremental
|
||||
CTEST_MODE_incremental = incremental
|
||||
CTEST_RUNTOOL_incremental = $(CTEST_RUNTOOL)
|
||||
|
||||
CTEST_SRC_BASE_rustdocck = rustdoc
|
||||
CTEST_BUILD_BASE_rustdocck = rustdoc
|
||||
CTEST_MODE_rustdocck = rustdoc
|
||||
@ -681,6 +689,7 @@ CTEST_DEPS_debuginfo-lldb_$(1)-T-$(2)-H-$(3) = $$(DEBUGINFO_LLDB_TESTS) \
|
||||
$(S)src/etc/lldb_rust_formatters.py
|
||||
CTEST_DEPS_codegen_$(1)-T-$(2)-H-$(3) = $$(CODEGEN_TESTS)
|
||||
CTEST_DEPS_codegen-units_$(1)-T-$(2)-H-$(3) = $$(CODEGEN_UNITS_TESTS)
|
||||
CTEST_DEPS_incremental_$(1)-T-$(2)-H-$(3) = $$(INCREMENTAL_TESTS)
|
||||
CTEST_DEPS_rustdocck_$(1)-T-$(2)-H-$(3) = $$(RUSTDOCCK_TESTS) \
|
||||
$$(HBIN$(1)_H_$(3))/rustdoc$$(X_$(3)) \
|
||||
$(S)src/etc/htmldocck.py
|
||||
@ -747,7 +756,7 @@ endif
|
||||
endef
|
||||
|
||||
CTEST_NAMES = rpass rpass-valgrind rpass-full rfail-full cfail-full rfail cfail pfail \
|
||||
debuginfo-gdb debuginfo-lldb codegen codegen-units rustdocck
|
||||
debuginfo-gdb debuginfo-lldb codegen codegen-units rustdocck incremental
|
||||
|
||||
$(foreach host,$(CFG_HOST), \
|
||||
$(eval $(foreach target,$(CFG_TARGET), \
|
||||
@ -945,6 +954,7 @@ TEST_GROUPS = \
|
||||
debuginfo-lldb \
|
||||
codegen \
|
||||
codegen-units \
|
||||
incremental \
|
||||
doc \
|
||||
$(foreach docname,$(DOC_NAMES),doc-$(docname)) \
|
||||
pretty \
|
||||
|
@ -25,7 +25,8 @@ pub enum Mode {
|
||||
DebugInfoLldb,
|
||||
Codegen,
|
||||
Rustdoc,
|
||||
CodegenUnits
|
||||
CodegenUnits,
|
||||
Incremental,
|
||||
}
|
||||
|
||||
impl FromStr for Mode {
|
||||
@ -43,6 +44,7 @@ impl FromStr for Mode {
|
||||
"codegen" => Ok(Codegen),
|
||||
"rustdoc" => Ok(Rustdoc),
|
||||
"codegen-units" => Ok(CodegenUnits),
|
||||
"incremental" => Ok(Incremental),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
@ -62,6 +64,7 @@ impl fmt::Display for Mode {
|
||||
Codegen => "codegen",
|
||||
Rustdoc => "rustdoc",
|
||||
CodegenUnits => "codegen-units",
|
||||
Incremental => "incremental",
|
||||
}, f)
|
||||
}
|
||||
}
|
||||
|
@ -71,7 +71,8 @@ pub fn parse_config(args: Vec<String> ) -> Config {
|
||||
reqopt("", "aux-base", "directory to find auxiliary test files", "PATH"),
|
||||
reqopt("", "stage-id", "the target-stage identifier", "stageN-TARGET"),
|
||||
reqopt("", "mode", "which sort of compile tests to run",
|
||||
"(compile-fail|parse-fail|run-fail|run-pass|run-pass-valgrind|pretty|debug-info)"),
|
||||
"(compile-fail|parse-fail|run-fail|run-pass|\
|
||||
run-pass-valgrind|pretty|debug-info|incremental)"),
|
||||
optflag("", "ignored", "run tests marked as ignored"),
|
||||
optopt("", "runtool", "supervisor program to run tests under \
|
||||
(eg. emulator, valgrind)", "PROGRAM"),
|
||||
|
@ -11,6 +11,7 @@
|
||||
use common::Config;
|
||||
use common::{CompileFail, ParseFail, Pretty, RunFail, RunPass, RunPassValgrind};
|
||||
use common::{Codegen, DebugInfoLldb, DebugInfoGdb, Rustdoc, CodegenUnits};
|
||||
use common::{Incremental};
|
||||
use errors::{self, ErrorKind};
|
||||
use header::TestProps;
|
||||
use header;
|
||||
@ -59,6 +60,7 @@ pub fn run(config: Config, testpaths: &TestPaths) {
|
||||
Codegen => run_codegen_test(&config, &props, &testpaths),
|
||||
Rustdoc => run_rustdoc_test(&config, &props, &testpaths),
|
||||
CodegenUnits => run_codegen_units_test(&config, &props, &testpaths),
|
||||
Incremental => run_incremental_test(&config, &props, &testpaths),
|
||||
}
|
||||
}
|
||||
|
||||
@ -1966,3 +1968,66 @@ fn run_codegen_units_test(config: &Config, props: &TestProps, testpaths: &TestPa
|
||||
panic!();
|
||||
}
|
||||
}
|
||||
|
||||
fn run_incremental_test(config: &Config, props: &TestProps, testpaths: &TestPaths) {
|
||||
// Basic plan for a test incremental/foo/bar.rs:
|
||||
// - load list of revisions pass1, fail2, pass3
|
||||
// - each should begin with `pass` or `fail`
|
||||
// - if `pass`, expect compile to succeed
|
||||
// - if `fail`, expect errors from file
|
||||
// - create a directory build/foo/bar.incremental
|
||||
// - compile foo/bar.rs with -Z incremental=.../foo/bar.incremental and -C pass1
|
||||
// - because name of revision starts with "pass", expect success
|
||||
// - compile foo/bar.rs with -Z incremental=.../foo/bar.incremental and -C fail2
|
||||
// - because name of revision starts with "fail", expect an error
|
||||
// - load expected errors as usual, but filter for those that end in `[fail2]`
|
||||
// - compile foo/bar.rs with -Z incremental=.../foo/bar.incremental and -C pass3
|
||||
// - because name of revision starts with "pass", expect success
|
||||
// - execute build/foo/bar.exe and save output
|
||||
//
|
||||
// FIXME -- use non-incremental mode as an oracle? That doesn't apply
|
||||
// to #[rustc_dirty] and clean tests I guess
|
||||
|
||||
assert!(!props.revisions.is_empty(), "incremental tests require a list of revisions");
|
||||
|
||||
let output_base_name = output_base_name(config, testpaths);
|
||||
|
||||
// Create the incremental workproduct directory.
|
||||
let incremental_dir = output_base_name.with_extension("incremental");
|
||||
if incremental_dir.exists() {
|
||||
fs::remove_dir_all(&incremental_dir).unwrap();
|
||||
}
|
||||
fs::create_dir_all(&incremental_dir).unwrap();
|
||||
|
||||
if config.verbose {
|
||||
print!("incremental_dir={}", incremental_dir.display());
|
||||
}
|
||||
|
||||
for revision in &props.revisions {
|
||||
let mut revision_props = props.clone();
|
||||
header::load_props_into(&mut revision_props, &testpaths.file, Some(&revision));
|
||||
|
||||
revision_props.compile_flags.extend(vec![
|
||||
format!("-Z"),
|
||||
format!("incremental={}", incremental_dir.display()),
|
||||
format!("--cfg"),
|
||||
format!("{}", revision),
|
||||
]);
|
||||
|
||||
if config.verbose {
|
||||
print!("revision={:?} revision_props={:#?}", revision, revision_props);
|
||||
}
|
||||
|
||||
if revision.starts_with("rpass") {
|
||||
run_rpass_test_revision(config, &revision_props, testpaths, Some(&revision));
|
||||
} else if revision.starts_with("rfail") {
|
||||
run_rfail_test_revision(config, &revision_props, testpaths, Some(&revision));
|
||||
} else if revision.starts_with("cfail") {
|
||||
run_cfail_test_revision(config, &revision_props, testpaths, Some(&revision));
|
||||
} else {
|
||||
fatal(
|
||||
Some(revision),
|
||||
"revision name must begin with rpass, rfail, or cfail");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
54
src/test/incremental/dirty_clean.rs
Normal file
54
src/test/incremental/dirty_clean.rs
Normal file
@ -0,0 +1,54 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// revisions: rpass1 cfail2
|
||||
|
||||
#![allow(warnings)]
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
// Sanity check for the dirty-clean system. Give the opposite
|
||||
// annotations that we expect to see, so that we check that errors are
|
||||
// reported.
|
||||
|
||||
fn main() { }
|
||||
|
||||
mod x {
|
||||
#[cfg(rpass1)]
|
||||
pub fn x() -> usize {
|
||||
22
|
||||
}
|
||||
|
||||
#[cfg(cfail2)]
|
||||
pub fn x() -> u32 {
|
||||
22
|
||||
}
|
||||
}
|
||||
|
||||
mod y {
|
||||
use x;
|
||||
|
||||
#[rustc_clean(label="TypeckItemBody", cfg="cfail2")]
|
||||
#[rustc_clean(label="TransCrateItem", cfg="cfail2")]
|
||||
pub fn y() {
|
||||
//[cfail2]~^ ERROR `TypeckItemBody("y::y")` not found in dep graph, but should be clean
|
||||
//[cfail2]~| ERROR `TransCrateItem("y::y")` not found in dep graph, but should be clean
|
||||
x::x();
|
||||
}
|
||||
}
|
||||
|
||||
mod z {
|
||||
#[rustc_dirty(label="TypeckItemBody", cfg="cfail2")]
|
||||
#[rustc_dirty(label="TransCrateItem", cfg="cfail2")]
|
||||
pub fn z() {
|
||||
//[cfail2]~^ ERROR `TypeckItemBody("z::z")` found in dep graph, but should be dirty
|
||||
// FIXME(#32014) -- TransCrateItem ought to be clean, but it is in fact
|
||||
// dirty, hence we don't see an error here.
|
||||
}
|
||||
}
|
46
src/test/incremental/hello_world.rs
Normal file
46
src/test/incremental/hello_world.rs
Normal file
@ -0,0 +1,46 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// revisions: rpass1 rpass2
|
||||
|
||||
#![allow(warnings)]
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
fn main() { }
|
||||
|
||||
mod x {
|
||||
#[cfg(rpass1)]
|
||||
pub fn x() -> i32 {
|
||||
1
|
||||
}
|
||||
|
||||
#[cfg(rpass2)]
|
||||
pub fn x() -> i32 {
|
||||
2
|
||||
}
|
||||
}
|
||||
|
||||
mod y {
|
||||
use x;
|
||||
|
||||
#[rustc_dirty(label="TypeckItemBody", cfg="rpass2")]
|
||||
pub fn y() {
|
||||
x::x();
|
||||
}
|
||||
}
|
||||
|
||||
mod z {
|
||||
use y;
|
||||
|
||||
#[rustc_clean(label="TypeckItemBody", cfg="rpass2")]
|
||||
pub fn z() {
|
||||
y::y();
|
||||
}
|
||||
}
|
58
src/test/incremental/string_constant.rs
Normal file
58
src/test/incremental/string_constant.rs
Normal file
@ -0,0 +1,58 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// revisions: rpass1 rpass2
|
||||
|
||||
#![allow(warnings)]
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
// Here the only thing which changes is the string constant in `x`.
|
||||
// Therefore, the compiler deduces (correctly) that typeck is not
|
||||
// needed even for callers of `x`.
|
||||
//
|
||||
// It is not entirely clear why `TransCrateItem` invalidates `y` and
|
||||
// `z`, actually, I think it's because of the structure of
|
||||
// trans. -nmatsakis
|
||||
|
||||
fn main() { }
|
||||
|
||||
mod x {
|
||||
#[cfg(rpass1)]
|
||||
pub fn x() {
|
||||
println!("1");
|
||||
}
|
||||
|
||||
#[cfg(rpass2)]
|
||||
#[rustc_dirty(label="TypeckItemBody", cfg="rpass2")]
|
||||
#[rustc_dirty(label="TransCrateItem", cfg="rpass2")]
|
||||
pub fn x() {
|
||||
println!("2");
|
||||
}
|
||||
}
|
||||
|
||||
mod y {
|
||||
use x;
|
||||
|
||||
#[rustc_clean(label="TypeckItemBody", cfg="rpass2")]
|
||||
#[rustc_dirty(label="TransCrateItem", cfg="rpass2")]
|
||||
pub fn y() {
|
||||
x::x();
|
||||
}
|
||||
}
|
||||
|
||||
mod z {
|
||||
use y;
|
||||
|
||||
#[rustc_clean(label="TypeckItemBody", cfg="rpass2")]
|
||||
#[rustc_dirty(label="TransCrateItem", cfg="rpass2")]
|
||||
pub fn z() {
|
||||
y::y();
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user