Rollup merge of #50806 - oli-obk:gesundheit, r=ehuss
Add `bless` x.py subcommand for easy ui test replacement fixes #49815 r? @nikomatsakis
This commit is contained in:
@@ -297,7 +297,12 @@ fn main() {
|
||||
}
|
||||
|
||||
if verbose > 1 {
|
||||
eprintln!("rustc command: {:?}", cmd);
|
||||
eprintln!(
|
||||
"rustc command: {:?}={:?} {:?}",
|
||||
bootstrap::util::dylib_path_var(),
|
||||
env::join_paths(&dylib_path).unwrap(),
|
||||
cmd,
|
||||
);
|
||||
eprintln!("sysroot: {:?}", sysroot);
|
||||
eprintln!("libdir: {:?}", libdir);
|
||||
}
|
||||
|
||||
@@ -1460,6 +1460,7 @@ mod __test {
|
||||
rustc_args: vec![],
|
||||
fail_fast: true,
|
||||
doc_tests: DocTests::No,
|
||||
bless: false,
|
||||
};
|
||||
|
||||
let build = Build::new(config);
|
||||
|
||||
@@ -59,6 +59,8 @@ pub enum Subcommand {
|
||||
},
|
||||
Test {
|
||||
paths: Vec<PathBuf>,
|
||||
/// Whether to automatically update stderr/stdout files
|
||||
bless: bool,
|
||||
test_args: Vec<String>,
|
||||
rustc_args: Vec<String>,
|
||||
fail_fast: bool,
|
||||
@@ -173,6 +175,7 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`");
|
||||
);
|
||||
opts.optflag("", "no-doc", "do not run doc tests");
|
||||
opts.optflag("", "doc", "only run doc tests");
|
||||
opts.optflag("", "bless", "update all stderr/stdout files of failing ui tests");
|
||||
},
|
||||
"bench" => { opts.optmulti("", "test-args", "extra arguments", "ARGS"); },
|
||||
"clean" => { opts.optflag("", "all", "clean all build artifacts"); },
|
||||
@@ -258,6 +261,7 @@ Arguments:
|
||||
./x.py test src/test/run-pass
|
||||
./x.py test src/libstd --test-args hash_map
|
||||
./x.py test src/libstd --stage 0
|
||||
./x.py test src/test/ui --bless
|
||||
|
||||
If no arguments are passed then the complete artifacts for that stage are
|
||||
compiled and tested.
|
||||
@@ -322,6 +326,7 @@ Arguments:
|
||||
"test" => {
|
||||
Subcommand::Test {
|
||||
paths,
|
||||
bless: matches.opt_present("bless"),
|
||||
test_args: matches.opt_strs("test-args"),
|
||||
rustc_args: matches.opt_strs("rustc-args"),
|
||||
fail_fast: !matches.opt_present("no-fail-fast"),
|
||||
@@ -424,6 +429,13 @@ impl Subcommand {
|
||||
_ => DocTests::Yes,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn bless(&self) -> bool {
|
||||
match *self {
|
||||
Subcommand::Test { bless, .. } => bless,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn split(s: Vec<String>) -> Vec<String> {
|
||||
|
||||
@@ -47,6 +47,16 @@ pub enum TestKind {
|
||||
Bench,
|
||||
}
|
||||
|
||||
impl From<Kind> for TestKind {
|
||||
fn from(kind: Kind) -> Self {
|
||||
match kind {
|
||||
Kind::Test => TestKind::Test,
|
||||
Kind::Bench => TestKind::Bench,
|
||||
_ => panic!("unexpected kind in crate: {:?}", kind)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TestKind {
|
||||
// Return the cargo subcommand for this test kind
|
||||
fn subcommand(self) -> &'static str {
|
||||
@@ -951,6 +961,10 @@ impl Step for Compiletest {
|
||||
cmd.arg("--host").arg(&*compiler.host);
|
||||
cmd.arg("--llvm-filecheck").arg(builder.llvm_filecheck(builder.config.build));
|
||||
|
||||
if builder.config.cmd.bless() {
|
||||
cmd.arg("--bless");
|
||||
}
|
||||
|
||||
if let Some(ref nodejs) = builder.config.nodejs {
|
||||
cmd.arg("--nodejs").arg(nodejs);
|
||||
}
|
||||
@@ -1342,13 +1356,7 @@ impl Step for CrateLibrustc {
|
||||
|
||||
for krate in builder.in_tree_crates("rustc-main") {
|
||||
if run.path.ends_with(&krate.path) {
|
||||
let test_kind = if builder.kind == Kind::Test {
|
||||
TestKind::Test
|
||||
} else if builder.kind == Kind::Bench {
|
||||
TestKind::Bench
|
||||
} else {
|
||||
panic!("unexpected builder.kind in crate: {:?}", builder.kind);
|
||||
};
|
||||
let test_kind = builder.kind.into();
|
||||
|
||||
builder.ensure(CrateLibrustc {
|
||||
compiler,
|
||||
@@ -1394,13 +1402,7 @@ impl Step for CrateNotDefault {
|
||||
let builder = run.builder;
|
||||
let compiler = builder.compiler(builder.top_stage, run.host);
|
||||
|
||||
let test_kind = if builder.kind == Kind::Test {
|
||||
TestKind::Test
|
||||
} else if builder.kind == Kind::Bench {
|
||||
TestKind::Bench
|
||||
} else {
|
||||
panic!("unexpected builder.kind in crate: {:?}", builder.kind);
|
||||
};
|
||||
let test_kind = builder.kind.into();
|
||||
|
||||
builder.ensure(CrateNotDefault {
|
||||
compiler,
|
||||
@@ -1461,13 +1463,7 @@ impl Step for Crate {
|
||||
let compiler = builder.compiler(builder.top_stage, run.host);
|
||||
|
||||
let make = |mode: Mode, krate: &CargoCrate| {
|
||||
let test_kind = if builder.kind == Kind::Test {
|
||||
TestKind::Test
|
||||
} else if builder.kind == Kind::Bench {
|
||||
TestKind::Bench
|
||||
} else {
|
||||
panic!("unexpected builder.kind in crate: {:?}", builder.kind);
|
||||
};
|
||||
let test_kind = builder.kind.into();
|
||||
|
||||
builder.ensure(Crate {
|
||||
compiler,
|
||||
@@ -1625,13 +1621,7 @@ impl Step for CrateRustdoc {
|
||||
fn make_run(run: RunConfig) {
|
||||
let builder = run.builder;
|
||||
|
||||
let test_kind = if builder.kind == Kind::Test {
|
||||
TestKind::Test
|
||||
} else if builder.kind == Kind::Bench {
|
||||
TestKind::Bench
|
||||
} else {
|
||||
panic!("unexpected builder.kind in crate: {:?}", builder.kind);
|
||||
};
|
||||
let test_kind = builder.kind.into();
|
||||
|
||||
builder.ensure(CrateRustdoc {
|
||||
host: run.host,
|
||||
|
||||
@@ -140,13 +140,9 @@ check that the test compiles successfully.
|
||||
### Editing and updating the reference files
|
||||
|
||||
If you have changed the compiler's output intentionally, or you are
|
||||
making a new test, you can use the script `ui/update-references.sh` to
|
||||
update the references. When you run the test framework, it will report
|
||||
various errors: in those errors is a command you can use to run the
|
||||
`ui/update-references.sh` script, which will then copy over the files
|
||||
from the build directory and use them as the new reference. You can
|
||||
also just run `ui/update-all-references.sh`. In both cases, you can run
|
||||
the script with `--help` to get a help message.
|
||||
making a new test, you can pass `--bless` to the command you used to
|
||||
run the tests. This will then copy over the files
|
||||
from the build directory and use them as the new reference.
|
||||
|
||||
### Normalization
|
||||
|
||||
|
||||
9
src/test/ui/E0508.ast.nll.stderr
Normal file
9
src/test/ui/E0508.ast.nll.stderr
Normal file
@@ -0,0 +1,9 @@
|
||||
error[E0508]: cannot move out of type `[NonCopy; 1]`, a non-copy array
|
||||
--> $DIR/E0508.rs:18:18
|
||||
|
|
||||
LL | let _value = array[0]; //[ast]~ ERROR [E0508]
|
||||
| ^^^^^^^^ cannot move out of here
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0508`.
|
||||
12
src/test/ui/E0508.ast.stderr
Normal file
12
src/test/ui/E0508.ast.stderr
Normal file
@@ -0,0 +1,12 @@
|
||||
error[E0508]: cannot move out of type `[NonCopy; 1]`, a non-copy array
|
||||
--> $DIR/E0508.rs:18:18
|
||||
|
|
||||
LL | let _value = array[0]; //[ast]~ ERROR [E0508]
|
||||
| ^^^^^^^^
|
||||
| |
|
||||
| cannot move out of here
|
||||
| help: consider using a reference instead: `&array[0]`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0508`.
|
||||
9
src/test/ui/E0508.mir.stderr
Normal file
9
src/test/ui/E0508.mir.stderr
Normal file
@@ -0,0 +1,9 @@
|
||||
error[E0508]: cannot move out of type `[NonCopy; 1]`, a non-copy array
|
||||
--> $DIR/E0508.rs:18:18
|
||||
|
|
||||
LL | let _value = array[0]; //[ast]~ ERROR [E0508]
|
||||
| ^^^^^^^^ cannot move out of here
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0508`.
|
||||
20
src/test/ui/E0508.rs
Normal file
20
src/test/ui/E0508.rs
Normal file
@@ -0,0 +1,20 @@
|
||||
// Copyright 2016 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: ast mir
|
||||
//[mir]compile-flags: -Z borrowck=mir
|
||||
|
||||
struct NonCopy;
|
||||
|
||||
fn main() {
|
||||
let array = [NonCopy; 1];
|
||||
let _value = array[0]; //[ast]~ ERROR [E0508]
|
||||
//[mir]~^ ERROR [E0508]
|
||||
}
|
||||
@@ -118,6 +118,9 @@ impl CompareMode {
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Config {
|
||||
/// Whether to overwrite stderr/stdout files instead of complaining about changes in output
|
||||
pub bless: bool,
|
||||
|
||||
/// The library paths required for running the compiler
|
||||
pub compile_lib_path: PathBuf,
|
||||
|
||||
|
||||
@@ -166,6 +166,11 @@ pub fn parse_config(args: Vec<String>) -> Config {
|
||||
"FLAGS",
|
||||
)
|
||||
.optflag("", "verbose", "run tests verbosely, showing all output")
|
||||
.optflag(
|
||||
"",
|
||||
"bless",
|
||||
"overwrite stderr/stdout files instead of complaining about a mismatch",
|
||||
)
|
||||
.optflag(
|
||||
"",
|
||||
"quiet",
|
||||
@@ -290,6 +295,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
|
||||
let src_base = opt_path(matches, "src-base");
|
||||
let run_ignored = matches.opt_present("ignored");
|
||||
Config {
|
||||
bless: matches.opt_present("bless"),
|
||||
compile_lib_path: make_absolute(opt_path(matches, "compile-lib-path")),
|
||||
run_lib_path: make_absolute(opt_path(matches, "run-lib-path")),
|
||||
rustc_path: opt_path(matches, "rustc-path"),
|
||||
|
||||
@@ -2596,15 +2596,13 @@ impl<'test> TestCx<'test> {
|
||||
}
|
||||
|
||||
if errors > 0 {
|
||||
println!("To update references, run this command from build directory:");
|
||||
println!("To update references, rerun the tests and pass the `--bless` flag");
|
||||
let relative_path_to_file = self.testpaths
|
||||
.relative_dir
|
||||
.join(self.testpaths.file.file_name().unwrap());
|
||||
println!(
|
||||
"{}/update-references.sh '{}' '{}'",
|
||||
self.config.src_base.display(),
|
||||
self.config.build_base.display(),
|
||||
relative_path_to_file.display()
|
||||
"To only update this specific test, also pass `--test-args {}`",
|
||||
relative_path_to_file.display(),
|
||||
);
|
||||
self.fatal_proc_rec(
|
||||
&format!("{} errors occurred comparing output.", errors),
|
||||
@@ -2926,6 +2924,7 @@ impl<'test> TestCx<'test> {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if !self.config.bless {
|
||||
if expected.is_empty() {
|
||||
println!("normalized {}:\n{}\n", kind, actual);
|
||||
} else {
|
||||
@@ -2951,6 +2950,7 @@ impl<'test> TestCx<'test> {
|
||||
println!("");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mode = self.config.compare_mode.as_ref().map_or("", |m| m.to_str());
|
||||
let output_file = self.output_base_name()
|
||||
@@ -2958,6 +2958,26 @@ impl<'test> TestCx<'test> {
|
||||
.with_extra_extension(mode)
|
||||
.with_extra_extension(kind);
|
||||
|
||||
let mut files = vec![output_file];
|
||||
if self.config.bless {
|
||||
files.push(expected_output_path(
|
||||
self.testpaths,
|
||||
self.revision,
|
||||
&self.config.compare_mode,
|
||||
kind,
|
||||
));
|
||||
}
|
||||
|
||||
for output_file in &files {
|
||||
if actual.is_empty() {
|
||||
if let Err(e) = ::std::fs::remove_file(output_file) {
|
||||
self.fatal(&format!(
|
||||
"failed to delete `{}`: {}",
|
||||
output_file.display(),
|
||||
e,
|
||||
));
|
||||
}
|
||||
} else {
|
||||
match File::create(&output_file).and_then(|mut f| f.write_all(actual.as_bytes())) {
|
||||
Ok(()) => {}
|
||||
Err(e) => self.fatal(&format!(
|
||||
@@ -2967,11 +2987,19 @@ impl<'test> TestCx<'test> {
|
||||
e
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
println!("\nThe actual {0} differed from the expected {0}.", kind);
|
||||
for output_file in files {
|
||||
println!("Actual {} saved to {}", kind, output_file.display());
|
||||
}
|
||||
if self.config.bless {
|
||||
0
|
||||
} else {
|
||||
1
|
||||
}
|
||||
}
|
||||
|
||||
fn create_stamp(&self) {
|
||||
let mut f = File::create(::stamp(&self.config, self.testpaths, self.revision)).unwrap();
|
||||
|
||||
Reference in New Issue
Block a user