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 bless x.py subcommand for easy ui test replacement #50806

Merged
merged 5 commits into from
May 18, 2018
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
7 changes: 6 additions & 1 deletion src/bootstrap/bin/rustc.rs
Original file line number Diff line number Diff line change
@@ -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);
}
1 change: 1 addition & 0 deletions src/bootstrap/builder.rs
Original file line number Diff line number Diff line change
@@ -1461,6 +1461,7 @@ mod __test {
rustc_args: vec![],
fail_fast: true,
doc_tests: DocTests::No,
bless: false,
};

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

6 changes: 6 additions & 0 deletions src/tools/compiletest/src/main.rs
Original file line number Diff line number Diff line change
@@ -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"),
96 changes: 62 additions & 34 deletions src/tools/compiletest/src/runtest.rs
Original file line number Diff line number Diff line change
@@ -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,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!("");
}
}

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