Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add --run flag to compiletest #84500

Merged
merged 6 commits into from
May 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/bootstrap/builder/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,7 @@ mod dist {
compare_mode: None,
rustfix_coverage: false,
pass: None,
run: None,
};

let build = Build::new(config);
Expand Down Expand Up @@ -529,6 +530,7 @@ mod dist {
compare_mode: None,
rustfix_coverage: false,
pass: None,
run: None,
};

let build = Build::new(config);
Expand Down Expand Up @@ -584,6 +586,7 @@ mod dist {
compare_mode: None,
rustfix_coverage: false,
pass: None,
run: None,
};
// Make sure rustfmt binary not being found isn't an error.
config.channel = "beta".to_string();
Expand Down
14 changes: 12 additions & 2 deletions src/bootstrap/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ pub enum Subcommand {
bless: bool,
compare_mode: Option<String>,
pass: Option<String>,
run: Option<String>,
test_args: Vec<String>,
rustc_args: Vec<String>,
fail_fast: bool,
Expand Down Expand Up @@ -222,8 +223,8 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`",
VALUE overrides the skip-rebuild option in config.toml.",
"VALUE",
);
opts.optopt("", "rust-profile-generate", "rustc error format", "FORMAT");
opts.optopt("", "rust-profile-use", "rustc error format", "FORMAT");
opts.optopt("", "rust-profile-generate", "generate PGO profile with rustc build", "FORMAT");
opts.optopt("", "rust-profile-use", "use PGO profile for rustc build", "FORMAT");

// We can't use getopt to parse the options until we have completed specifying which
// options are valid, but under the current implementation, some options are conditional on
Expand Down Expand Up @@ -293,6 +294,7 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`",
"force {check,build,run}-pass tests to this mode.",
"check | build | run",
);
opts.optopt("", "run", "whether to execute run-* tests", "auto | always | never");
opts.optflag(
"",
"rustfix-coverage",
Expand Down Expand Up @@ -556,6 +558,7 @@ Arguments:
bless: matches.opt_present("bless"),
compare_mode: matches.opt_str("compare-mode"),
pass: matches.opt_str("pass"),
run: matches.opt_str("run"),
test_args: matches.opt_strs("test-args"),
rustc_args: matches.opt_strs("rustc-args"),
fail_fast: !matches.opt_present("no-fail-fast"),
Expand Down Expand Up @@ -742,6 +745,13 @@ impl Subcommand {
}
}

pub fn run(&self) -> Option<&str> {
match *self {
Subcommand::Test { ref run, .. } => run.as_ref().map(|s| &s[..]),
_ => None,
}
}

pub fn open(&self) -> bool {
match *self {
Subcommand::Doc { open, .. } => open,
Expand Down
5 changes: 5 additions & 0 deletions src/bootstrap/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1207,6 +1207,11 @@ note: if you're sure you want to do this, please open an issue as to why. In the
cmd.arg(pass);
}

if let Some(ref run) = builder.config.cmd.run() {
cmd.arg("--run");
cmd.arg(run);
}

if let Some(ref nodejs) = builder.config.nodejs {
cmd.arg("--nodejs").arg(nodejs);
}
Expand Down
1 change: 1 addition & 0 deletions src/test/debuginfo/should-fail.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

// == Test [gdb|lldb]-[command|check] are parsed correctly ===
// should-fail
// needs-run-enabled
// compile-flags:-g

// === GDB TESTS ===================================================================================
Expand Down
1 change: 1 addition & 0 deletions src/test/ui/meta/revision-bad.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
// run-fail
// revisions: foo bar
// should-fail
// needs-run-enabled
//[foo] error-pattern:bar
//[bar] error-pattern:foo

Expand Down
12 changes: 12 additions & 0 deletions src/tools/compiletest/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,9 @@ pub struct Config {
/// Force the pass mode of a check/build/run-pass test to this mode.
pub force_pass_mode: Option<PassMode>,

/// Explicitly enable or disable running.
pub run: Option<bool>,

/// Write out a parseable log of tests that were run
pub logfile: Option<PathBuf>,

Expand Down Expand Up @@ -348,6 +351,15 @@ pub struct Config {
pub npm: Option<String>,
}

impl Config {
pub fn run_enabled(&self) -> bool {
self.run.unwrap_or_else(|| {
// Auto-detect whether to run based on the platform.
!self.target.ends_with("-fuchsia")
})
}
}

#[derive(Debug, Clone)]
pub struct TestPaths {
pub file: PathBuf, // e.g., compile-test/foo/bar/baz.rs
Expand Down
4 changes: 4 additions & 0 deletions src/tools/compiletest/src/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ impl EarlyProps {
props.ignore = true;
}

if !config.run_enabled() && config.parse_name_directive(ln, "needs-run-enabled") {
props.ignore = true;
}

if !rustc_has_sanitizer_support
&& config.parse_name_directive(ln, "needs-sanitizer-support")
{
Expand Down
7 changes: 7 additions & 0 deletions src/tools/compiletest/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
"force {check,build,run}-pass tests to this mode.",
"check | build | run",
)
.optopt("", "run", "whether to execute run-* tests", "auto | always | never")
.optflag("", "ignored", "run tests marked as ignored")
.optflag("", "exact", "filters match exactly")
.optopt(
Expand Down Expand Up @@ -234,6 +235,12 @@ pub fn parse_config(args: Vec<String>) -> Config {
mode.parse::<PassMode>()
.unwrap_or_else(|_| panic!("unknown `--pass` option `{}` given", mode))
}),
run: matches.opt_str("run").and_then(|mode| match mode.as_str() {
"auto" => None,
"always" => Some(true),
"never" => Some(false),
_ => panic!("unknown `--run` option `{}` given", mode),
}),
logfile: matches.opt_str("logfile").map(|s| PathBuf::from(&s)),
runtool: matches.opt_str("runtool"),
host_rustcflags: matches.opt_str("host-rustcflags"),
Expand Down
62 changes: 48 additions & 14 deletions src/tools/compiletest/src/runtest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ pub fn run(config: Config, testpaths: &TestPaths, revision: Option<&str>) {
pub fn compute_stamp_hash(config: &Config) -> String {
let mut hash = DefaultHasher::new();
config.stage_id.hash(&mut hash);
config.run.hash(&mut hash);

match config.debugger {
Some(Debugger::Cdb) => {
Expand Down Expand Up @@ -317,6 +318,7 @@ enum TestOutput {
enum WillExecute {
Yes,
No,
Disabled,
}

/// Should `--emit metadata` be used?
Expand Down Expand Up @@ -357,14 +359,17 @@ impl<'test> TestCx<'test> {
}

fn should_run(&self, pm: Option<PassMode>) -> WillExecute {
match self.config.mode {
Ui if pm == Some(PassMode::Run) || self.props.fail_mode == Some(FailMode::Run) => {
WillExecute::Yes
}
MirOpt if pm == Some(PassMode::Run) => WillExecute::Yes,
Ui | MirOpt => WillExecute::No,
let test_should_run = match self.config.mode {
Ui if pm == Some(PassMode::Run) || self.props.fail_mode == Some(FailMode::Run) => true,
MirOpt if pm == Some(PassMode::Run) => true,
Ui | MirOpt => false,
mode => panic!("unimplemented for mode {:?}", mode),
}
};
if test_should_run { self.run_if_enabled() } else { WillExecute::No }
}

fn run_if_enabled(&self) -> WillExecute {
if self.config.run_enabled() { WillExecute::Yes } else { WillExecute::Disabled }
}

fn should_run_successfully(&self, pm: Option<PassMode>) -> bool {
Expand Down Expand Up @@ -439,12 +444,17 @@ impl<'test> TestCx<'test> {

fn run_rfail_test(&self) {
let pm = self.pass_mode();
let proc_res = self.compile_test(WillExecute::Yes, self.should_emit_metadata(pm));
let should_run = self.run_if_enabled();
let proc_res = self.compile_test(should_run, self.should_emit_metadata(pm));

if !proc_res.status.success() {
self.fatal_proc_rec("compilation failed!", &proc_res);
}

if let WillExecute::Disabled = should_run {
return;
}

let proc_res = self.exec_compiled_test();

// The value our Makefile configures valgrind to return on failure
Expand Down Expand Up @@ -483,12 +493,17 @@ impl<'test> TestCx<'test> {

fn run_rpass_test(&self) {
let emit_metadata = self.should_emit_metadata(self.pass_mode());
let proc_res = self.compile_test(WillExecute::Yes, emit_metadata);
let should_run = self.run_if_enabled();
let proc_res = self.compile_test(should_run, emit_metadata);

if !proc_res.status.success() {
self.fatal_proc_rec("compilation failed!", &proc_res);
}

if let WillExecute::Disabled = should_run {
return;
}

// FIXME(#41968): Move this check to tidy?
let expected_errors = errors::load_errors(&self.testpaths.file, self.revision);
assert!(
Expand All @@ -510,12 +525,17 @@ impl<'test> TestCx<'test> {
return self.run_rpass_test();
}

let mut proc_res = self.compile_test(WillExecute::Yes, EmitMetadata::No);
let should_run = self.run_if_enabled();
let mut proc_res = self.compile_test(should_run, EmitMetadata::No);

if !proc_res.status.success() {
self.fatal_proc_rec("compilation failed!", &proc_res);
}

if let WillExecute::Disabled = should_run {
return;
}

let mut new_config = self.config.clone();
new_config.runtool = new_config.valgrind_path.clone();
let new_cx = TestCx { config: &new_config, ..*self };
Expand Down Expand Up @@ -732,10 +752,14 @@ impl<'test> TestCx<'test> {

fn run_debuginfo_cdb_test_no_opt(&self) {
// compile test file (it should have 'compile-flags:-g' in the header)
let compile_result = self.compile_test(WillExecute::Yes, EmitMetadata::No);
let should_run = self.run_if_enabled();
let compile_result = self.compile_test(should_run, EmitMetadata::No);
if !compile_result.status.success() {
self.fatal_proc_rec("compilation failed!", &compile_result);
}
if let WillExecute::Disabled = should_run {
return;
}

let exe_file = self.make_exe_name();

Expand Down Expand Up @@ -826,10 +850,14 @@ impl<'test> TestCx<'test> {
let mut cmds = commands.join("\n");

// compile test file (it should have 'compile-flags:-g' in the header)
let compiler_run_result = self.compile_test(WillExecute::Yes, EmitMetadata::No);
let should_run = self.run_if_enabled();
let compiler_run_result = self.compile_test(should_run, EmitMetadata::No);
if !compiler_run_result.status.success() {
self.fatal_proc_rec("compilation failed!", &compiler_run_result);
}
if let WillExecute::Disabled = should_run {
return;
}

let exe_file = self.make_exe_name();

Expand Down Expand Up @@ -1044,10 +1072,14 @@ impl<'test> TestCx<'test> {

fn run_debuginfo_lldb_test_no_opt(&self) {
// compile test file (it should have 'compile-flags:-g' in the header)
let compile_result = self.compile_test(WillExecute::Yes, EmitMetadata::No);
let should_run = self.run_if_enabled();
let compile_result = self.compile_test(should_run, EmitMetadata::No);
if !compile_result.status.success() {
self.fatal_proc_rec("compilation failed!", &compile_result);
}
if let WillExecute::Disabled = should_run {
return;
}

let exe_file = self.make_exe_name();

Expand Down Expand Up @@ -1531,7 +1563,9 @@ impl<'test> TestCx<'test> {
// Only use `make_exe_name` when the test ends up being executed.
let output_file = match will_execute {
WillExecute::Yes => TargetLocation::ThisFile(self.make_exe_name()),
WillExecute::No => TargetLocation::ThisDirectory(self.output_base_dir()),
WillExecute::No | WillExecute::Disabled => {
TargetLocation::ThisDirectory(self.output_base_dir())
}
};

let allow_unused = match self.config.mode {
Expand Down