Skip to content

Commit

Permalink
Rollup merge of rust-lang#50806 - oli-obk:gesundheit, r=ehuss
Browse files Browse the repository at this point in the history
Add `bless` x.py subcommand for easy ui test replacement

fixes rust-lang#49815

r? @nikomatsakis
  • Loading branch information
Mark-Simulacrum authored May 17, 2018
2 parents c95267e + 0ac2fd1 commit f83e4d7
Show file tree
Hide file tree
Showing 12 changed files with 161 additions and 70 deletions.
7 changes: 6 additions & 1 deletion src/bootstrap/bin/rustc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
1 change: 1 addition & 0 deletions src/bootstrap/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1460,6 +1460,7 @@ mod __test {
rustc_args: vec![],
fail_fast: true,
doc_tests: DocTests::No,
bless: false,
};

let build = Build::new(config);
Expand Down
12 changes: 12 additions & 0 deletions src/bootstrap/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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"); },
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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"),
Expand Down Expand Up @@ -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> {
Expand Down
46 changes: 18 additions & 28 deletions src/bootstrap/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
10 changes: 3 additions & 7 deletions src/test/COMPILER_TESTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
9 changes: 9 additions & 0 deletions src/test/ui/E0508.ast.nll.stderr
Original file line number Diff line number Diff line change
@@ -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 changes: 12 additions & 0 deletions src/test/ui/E0508.ast.stderr
Original file line number Diff line number Diff line change
@@ -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 changes: 9 additions & 0 deletions src/test/ui/E0508.mir.stderr
Original file line number Diff line number Diff line change
@@ -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 changes: 20 additions & 0 deletions src/test/ui/E0508.rs
Original file line number Diff line number Diff line change
@@ -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]
}
3 changes: 3 additions & 0 deletions src/tools/compiletest/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,

Expand Down
6 changes: 6 additions & 0 deletions src/tools/compiletest/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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"),
Expand Down
96 changes: 62 additions & 34 deletions src/tools/compiletest/src/runtest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -2926,29 +2924,31 @@ impl<'test> TestCx<'test> {
return 0;
}

if expected.is_empty() {
println!("normalized {}:\n{}\n", kind, actual);
} else {
println!("diff of {}:\n", kind);
let diff_results = make_diff(expected, actual, 3);
for result in diff_results {
let mut line_number = result.line_number;
for line in result.lines {
match line {
DiffLine::Expected(e) => {
println!("-\t{}", e);
line_number += 1;
}
DiffLine::Context(c) => {
println!("{}\t{}", line_number, c);
line_number += 1;
}
DiffLine::Resulting(r) => {
println!("+\t{}", r);
if !self.config.bless {
if expected.is_empty() {
println!("normalized {}:\n{}\n", kind, actual);
} else {
println!("diff of {}:\n", kind);
let diff_results = make_diff(expected, actual, 3);
for result in diff_results {
let mut line_number = result.line_number;
for line in result.lines {
match line {
DiffLine::Expected(e) => {
println!("-\t{}", e);
line_number += 1;
}
DiffLine::Context(c) => {
println!("{}\t{}", line_number, c);
line_number += 1;
}
DiffLine::Resulting(r) => {
println!("+\t{}", r);
}
}
}
println!("");
}
println!("");
}
}

Expand All @@ -2958,19 +2958,47 @@ impl<'test> TestCx<'test> {
.with_extra_extension(mode)
.with_extra_extension(kind);

match File::create(&output_file).and_then(|mut f| f.write_all(actual.as_bytes())) {
Ok(()) => {}
Err(e) => self.fatal(&format!(
"failed to write {} to `{}`: {}",
let mut files = vec![output_file];
if self.config.bless {
files.push(expected_output_path(
self.testpaths,
self.revision,
&self.config.compare_mode,
kind,
output_file.display(),
e
)),
));
}

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!(
"failed to write {} to `{}`: {}",
kind,
output_file.display(),
e
)),
}
}
}

println!("\nThe actual {0} differed from the expected {0}.", kind);
println!("Actual {} saved to {}", kind, output_file.display());
1
for output_file in files {
println!("Actual {} saved to {}", kind, output_file.display());
}
if self.config.bless {
0
} else {
1
}
}

fn create_stamp(&self) {
Expand Down

0 comments on commit f83e4d7

Please sign in to comment.