Skip to content

Add --run flag to compiletest #84500

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

Merged
merged 6 commits into from
May 7, 2021
Merged
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
@@ -489,6 +489,7 @@ mod dist {
compare_mode: None,
rustfix_coverage: false,
pass: None,
run: None,
};

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

let build = Build::new(config);
@@ -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();
14 changes: 12 additions & 2 deletions src/bootstrap/flags.rs
Original file line number Diff line number Diff line change
@@ -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,
@@ -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
@@ -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",
@@ -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"),
@@ -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,
5 changes: 5 additions & 0 deletions src/bootstrap/test.rs
Original file line number Diff line number Diff line change
@@ -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);
}
1 change: 1 addition & 0 deletions src/test/debuginfo/should-fail.rs
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@

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

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

12 changes: 12 additions & 0 deletions src/tools/compiletest/src/common.rs
Original file line number Diff line number Diff line change
@@ -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>,

@@ -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
4 changes: 4 additions & 0 deletions src/tools/compiletest/src/header.rs
Original file line number Diff line number Diff line change
@@ -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")
{
7 changes: 7 additions & 0 deletions src/tools/compiletest/src/main.rs
Original file line number Diff line number Diff line change
@@ -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(
@@ -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"),
62 changes: 48 additions & 14 deletions src/tools/compiletest/src/runtest.rs
Original file line number Diff line number Diff line change
@@ -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) => {
@@ -317,6 +318,7 @@ enum TestOutput {
enum WillExecute {
Yes,
No,
Disabled,
}

/// Should `--emit metadata` be used?
@@ -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 {
@@ -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
@@ -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!(
@@ -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 };
@@ -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();

@@ -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();

@@ -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();

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