// except according to those terms.
#![crate_name = "compiletest"]
-
#![feature(test)]
#![feature(slice_rotate)]
-
#![deny(warnings)]
+extern crate diff;
+extern crate env_logger;
+extern crate filetime;
+extern crate getopts;
#[cfg(unix)]
extern crate libc;
-extern crate test;
-extern crate getopts;
-extern crate rustc_serialize;
#[macro_use]
extern crate log;
-extern crate env_logger;
-extern crate filetime;
-extern crate diff;
+extern crate rustc_serialize;
+extern crate test;
use std::env;
use std::ffi::OsString;
use filetime::FileTime;
use getopts::Options;
use common::Config;
-use common::{Pretty, DebugInfoGdb, DebugInfoLldb, Mode};
-use test::{TestPaths, ColorConfig};
+use common::{DebugInfoGdb, DebugInfoLldb, Mode, Pretty};
+use test::{ColorConfig, TestPaths};
use util::logv;
use self::header::EarlyProps;
run_tests(&config);
}
-pub fn parse_config(args: Vec<String> ) -> Config {
-
+pub fn parse_config(args: Vec<String>) -> Config {
let mut opts = Options::new();
- opts.reqopt("", "compile-lib-path", "path to host shared libraries", "PATH")
- .reqopt("", "run-lib-path", "path to target shared libraries", "PATH")
- .reqopt("", "rustc-path", "path to rustc to use for compiling", "PATH")
- .optopt("", "rustdoc-path", "path to rustdoc to use for compiling", "PATH")
- .reqopt("", "lldb-python", "path to python to use for doc tests", "PATH")
- .reqopt("", "docck-python", "path to python to use for doc tests", "PATH")
- .optopt("", "valgrind-path", "path to Valgrind executable for Valgrind tests", "PROGRAM")
- .optflag("", "force-valgrind", "fail if Valgrind tests cannot be run under Valgrind")
- .optopt("", "llvm-filecheck", "path to LLVM's FileCheck binary", "DIR")
+ opts.reqopt(
+ "",
+ "compile-lib-path",
+ "path to host shared libraries",
+ "PATH",
+ ).reqopt(
+ "",
+ "run-lib-path",
+ "path to target shared libraries",
+ "PATH",
+ )
+ .reqopt(
+ "",
+ "rustc-path",
+ "path to rustc to use for compiling",
+ "PATH",
+ )
+ .optopt(
+ "",
+ "rustdoc-path",
+ "path to rustdoc to use for compiling",
+ "PATH",
+ )
+ .reqopt(
+ "",
+ "lldb-python",
+ "path to python to use for doc tests",
+ "PATH",
+ )
+ .reqopt(
+ "",
+ "docck-python",
+ "path to python to use for doc tests",
+ "PATH",
+ )
+ .optopt(
+ "",
+ "valgrind-path",
+ "path to Valgrind executable for Valgrind tests",
+ "PROGRAM",
+ )
+ .optflag(
+ "",
+ "force-valgrind",
+ "fail if Valgrind tests cannot be run under Valgrind",
+ )
+ .optopt(
+ "",
+ "llvm-filecheck",
+ "path to LLVM's FileCheck binary",
+ "DIR",
+ )
.reqopt("", "src-base", "directory to scan for test files", "PATH")
- .reqopt("", "build-base", "directory to deposit test outputs", "PATH")
- .reqopt("", "stage-id", "the target-stage identifier", "stageN-TARGET")
- .reqopt("", "mode", "which sort of compile tests to run",
- "(compile-fail|parse-fail|run-fail|run-pass|\
- run-pass-valgrind|pretty|debug-info|incremental|mir-opt)")
+ .reqopt(
+ "",
+ "build-base",
+ "directory to deposit test outputs",
+ "PATH",
+ )
+ .reqopt(
+ "",
+ "stage-id",
+ "the target-stage identifier",
+ "stageN-TARGET",
+ )
+ .reqopt(
+ "",
+ "mode",
+ "which sort of compile tests to run",
+ "(compile-fail|parse-fail|run-fail|run-pass|\
+ run-pass-valgrind|pretty|debug-info|incremental|mir-opt)",
+ )
.optflag("", "ignored", "run tests marked as ignored")
.optflag("", "exact", "filters match exactly")
- .optopt("", "runtool", "supervisor program to run tests under \
- (eg. emulator, valgrind)", "PROGRAM")
- .optopt("", "host-rustcflags", "flags to pass to rustc for host", "FLAGS")
- .optopt("", "target-rustcflags", "flags to pass to rustc for target", "FLAGS")
+ .optopt(
+ "",
+ "runtool",
+ "supervisor program to run tests under \
+ (eg. emulator, valgrind)",
+ "PROGRAM",
+ )
+ .optopt(
+ "",
+ "host-rustcflags",
+ "flags to pass to rustc for host",
+ "FLAGS",
+ )
+ .optopt(
+ "",
+ "target-rustcflags",
+ "flags to pass to rustc for target",
+ "FLAGS",
+ )
.optflag("", "verbose", "run tests verbosely, showing all output")
- .optflag("", "quiet", "print one character per test instead of one line")
+ .optflag(
+ "",
+ "quiet",
+ "print one character per test instead of one line",
+ )
.optopt("", "color", "coloring: auto, always, never", "WHEN")
.optopt("", "logfile", "file to log test execution to", "FILE")
.optopt("", "target", "the target to build for", "TARGET")
.optopt("", "host", "the host to build for", "HOST")
- .optopt("", "gdb", "path to GDB to use for GDB debuginfo tests", "PATH")
- .optopt("", "lldb-version", "the version of LLDB used", "VERSION STRING")
- .optopt("", "llvm-version", "the version of LLVM used", "VERSION STRING")
+ .optopt(
+ "",
+ "gdb",
+ "path to GDB to use for GDB debuginfo tests",
+ "PATH",
+ )
+ .optopt(
+ "",
+ "lldb-version",
+ "the version of LLDB used",
+ "VERSION STRING",
+ )
+ .optopt(
+ "",
+ "llvm-version",
+ "the version of LLVM used",
+ "VERSION STRING",
+ )
.optflag("", "system-llvm", "is LLVM the system LLVM")
- .optopt("", "android-cross-path", "Android NDK standalone path", "PATH")
+ .optopt(
+ "",
+ "android-cross-path",
+ "Android NDK standalone path",
+ "PATH",
+ )
.optopt("", "adb-path", "path to the android debugger", "PATH")
- .optopt("", "adb-test-dir", "path to tests for the android debugger", "PATH")
- .optopt("", "lldb-python-dir", "directory containing LLDB's python module", "PATH")
+ .optopt(
+ "",
+ "adb-test-dir",
+ "path to tests for the android debugger",
+ "PATH",
+ )
+ .optopt(
+ "",
+ "lldb-python-dir",
+ "directory containing LLDB's python module",
+ "PATH",
+ )
.reqopt("", "cc", "path to a C compiler", "PATH")
.reqopt("", "cxx", "path to a C++ compiler", "PATH")
.reqopt("", "cflags", "flags for the C compiler", "FLAGS")
.optopt("", "ar", "path to an archiver", "PATH")
.optopt("", "linker", "path to a linker", "PATH")
- .reqopt("", "llvm-components", "list of LLVM components built in", "LIST")
+ .reqopt(
+ "",
+ "llvm-components",
+ "list of LLVM components built in",
+ "LIST",
+ )
.reqopt("", "llvm-cxxflags", "C++ flags for LLVM", "FLAGS")
.optopt("", "nodejs", "the name of nodejs", "PATH")
- .optopt("", "remote-test-client", "path to the remote test client", "PATH")
+ .optopt(
+ "",
+ "remote-test-client",
+ "path to the remote test client",
+ "PATH",
+ )
.optflag("h", "help", "show this message");
let (argv0, args_) = args.split_first().unwrap();
panic!()
}
- let matches =
- &match opts.parse(args_) {
- Ok(m) => m,
- Err(f) => panic!("{:?}", f)
- };
+ let matches = &match opts.parse(args_) {
+ Ok(m) => m,
+ Err(f) => panic!("{:?}", f),
+ };
if matches.opt_present("h") || matches.opt_present("help") {
let message = format!("Usage: {} [OPTIONS] [TESTNAME...]", argv0);
Some("auto") | None => ColorConfig::AutoColor,
Some("always") => ColorConfig::AlwaysColor,
Some("never") => ColorConfig::NeverColor,
- Some(x) => panic!("argument for --color must be auto, always, or never, but found `{}`", x),
+ Some(x) => panic!(
+ "argument for --color must be auto, always, or never, but found `{}`",
+ x
+ ),
};
Config {
src_base: opt_path(matches, "src-base"),
build_base: opt_path(matches, "build-base"),
stage_id: matches.opt_str("stage-id").unwrap(),
- mode: matches.opt_str("mode").unwrap().parse().expect("invalid mode"),
+ mode: matches
+ .opt_str("mode")
+ .unwrap()
+ .parse()
+ .expect("invalid mode"),
run_ignored: matches.opt_present("ignored"),
filter: matches.free.first().cloned(),
filter_exact: matches.opt_present("exact"),
android_cross_path: opt_path(matches, "android-cross-path"),
adb_path: opt_str2(matches.opt_str("adb-path")),
adb_test_dir: opt_str2(matches.opt_str("adb-test-dir")),
- adb_device_status:
- opt_str2(matches.opt_str("target")).contains("android") &&
- "(none)" != opt_str2(matches.opt_str("adb-test-dir")) &&
- !opt_str2(matches.opt_str("adb-test-dir")).is_empty(),
+ adb_device_status: opt_str2(matches.opt_str("target")).contains("android")
+ && "(none)" != opt_str2(matches.opt_str("adb-test-dir"))
+ && !opt_str2(matches.opt_str("adb-test-dir")).is_empty(),
lldb_python_dir: matches.opt_str("lldb-python-dir"),
verbose: matches.opt_present("verbose"),
quiet: matches.opt_present("quiet"),
pub fn log_config(config: &Config) {
let c = config;
logv(c, "configuration:".to_string());
- logv(c, format!("compile_lib_path: {:?}", config.compile_lib_path));
+ logv(
+ c,
+ format!("compile_lib_path: {:?}", config.compile_lib_path),
+ );
logv(c, format!("run_lib_path: {:?}", config.run_lib_path));
logv(c, format!("rustc_path: {:?}", config.rustc_path.display()));
logv(c, format!("rustdoc_path: {:?}", config.rustdoc_path));
logv(c, format!("stage_id: {}", config.stage_id));
logv(c, format!("mode: {}", config.mode));
logv(c, format!("run_ignored: {}", config.run_ignored));
- logv(c, format!("filter: {}",
- opt_str(&config.filter
- .as_ref()
- .map(|re| re.to_owned()))));
+ logv(
+ c,
+ format!(
+ "filter: {}",
+ opt_str(&config.filter.as_ref().map(|re| re.to_owned()))
+ ),
+ );
logv(c, format!("filter_exact: {}", config.filter_exact));
logv(c, format!("runtool: {}", opt_str(&config.runtool)));
- logv(c, format!("host-rustcflags: {}",
- opt_str(&config.host_rustcflags)));
- logv(c, format!("target-rustcflags: {}",
- opt_str(&config.target_rustcflags)));
+ logv(
+ c,
+ format!("host-rustcflags: {}", opt_str(&config.host_rustcflags)),
+ );
+ logv(
+ c,
+ format!("target-rustcflags: {}", opt_str(&config.target_rustcflags)),
+ );
logv(c, format!("target: {}", config.target));
logv(c, format!("host: {}", config.host));
- logv(c, format!("android-cross-path: {:?}",
- config.android_cross_path.display()));
+ logv(
+ c,
+ format!(
+ "android-cross-path: {:?}",
+ config.android_cross_path.display()
+ ),
+ );
logv(c, format!("adb_path: {:?}", config.adb_path));
logv(c, format!("adb_test_dir: {:?}", config.adb_test_dir));
- logv(c, format!("adb_device_status: {}",
- config.adb_device_status));
+ logv(
+ c,
+ format!("adb_device_status: {}", config.adb_device_status),
+ );
logv(c, format!("ar: {}", config.ar));
logv(c, format!("linker: {:?}", config.linker));
logv(c, format!("verbose: {}", config.verbose));
pub fn run_tests(config: &Config) {
if config.target.contains("android") {
if let DebugInfoGdb = config.mode {
- println!("{} debug-info test uses tcp 5039 port.\
- please reserve it", config.target);
+ println!(
+ "{} debug-info test uses tcp 5039 port.\
+ please reserve it",
+ config.target
+ );
// android debug-info test uses remote debugger so, we test 1 thread
// at once as they're all sharing the same TCP port to communicate
DebugInfoLldb => {
if let Some(lldb_version) = config.lldb_version.as_ref() {
if is_blacklisted_lldb_version(&lldb_version[..]) {
- println!("WARNING: The used version of LLDB ({}) has a \
- known issue that breaks debuginfo tests. See \
- issue #32520 for more information. Skipping all \
- LLDB-based tests!",
- lldb_version);
- return
+ println!(
+ "WARNING: The used version of LLDB ({}) has a \
+ known issue that breaks debuginfo tests. See \
+ issue #32520 for more information. Skipping all \
+ LLDB-based tests!",
+ lldb_version
+ );
+ return;
}
}
}
DebugInfoGdb => {
- if config.remote_test_client.is_some() &&
- !config.target.contains("android"){
- println!("WARNING: debuginfo tests are not available when \
- testing with remote");
- return
+ if config.remote_test_client.is_some() && !config.target.contains("android") {
+ println!(
+ "WARNING: debuginfo tests are not available when \
+ testing with remote"
+ );
+ return;
}
}
_ => { /* proceed */ }
// sadly osx needs some file descriptor limits raised for running tests in
// parallel (especially when we have lots and lots of child processes).
// For context, see #8904
- unsafe { raise_fd_limit::raise_fd_limit(); }
+ unsafe {
+ raise_fd_limit::raise_fd_limit();
+ }
// Prevent issue #21352 UAC blocking .exe containing 'patch' etc. on Windows
// If #11207 is resolved (adding manifest to .exe) this becomes unnecessary
env::set_var("__COMPAT_LAYER", "RunAsInvoker");
bench_benchmarks: true,
nocapture: match env::var("RUST_TEST_NOCAPTURE") {
Ok(val) => &val != "0",
- Err(_) => false
+ Err(_) => false,
},
color: config.color,
test_threads: None,
}
pub fn make_tests(config: &Config) -> Vec<test::TestDescAndFn> {
- debug!("making tests from {:?}",
- config.src_base.display());
+ debug!("making tests from {:?}", config.src_base.display());
let mut tests = Vec::new();
- collect_tests_from_dir(config,
- &config.src_base,
- &config.src_base,
- &PathBuf::new(),
- &mut tests)
- .unwrap();
+ collect_tests_from_dir(
+ config,
+ &config.src_base,
+ &config.src_base,
+ &PathBuf::new(),
+ &mut tests,
+ ).unwrap();
tests
}
-fn collect_tests_from_dir(config: &Config,
- base: &Path,
- dir: &Path,
- relative_dir_path: &Path,
- tests: &mut Vec<test::TestDescAndFn>)
- -> io::Result<()> {
+fn collect_tests_from_dir(
+ config: &Config,
+ base: &Path,
+ dir: &Path,
+ relative_dir_path: &Path,
+ tests: &mut Vec<test::TestDescAndFn>,
+) -> io::Result<()> {
// Ignore directories that contain a file
// `compiletest-ignore-dir`.
for file in fs::read_dir(dir)? {
relative_dir: relative_dir_path.parent().unwrap().to_path_buf(),
};
tests.push(make_test(config, &paths));
- return Ok(())
+ return Ok(());
}
}
fs::create_dir_all(&build_dir).unwrap();
} else {
debug!("found directory: {:?}", file_path.display());
- collect_tests_from_dir(config,
- base,
- &file_path,
- &relative_file_path,
- tests)?;
+ collect_tests_from_dir(config, base, &file_path, &relative_file_path, tests)?;
}
} else {
debug!("found other file/directory: {:?}", file_path.display());
test::ShouldPanic::Yes
} else {
test::ShouldPanic::No
- }
+ },
};
// Debugging emscripten code doesn't make sense today
- let ignore = early_props.ignore || !up_to_date(config, testpaths, &early_props) ||
- (config.mode == DebugInfoGdb || config.mode == DebugInfoLldb) &&
- config.target.contains("emscripten");
+ let ignore = early_props.ignore || !up_to_date(config, testpaths, &early_props)
+ || (config.mode == DebugInfoGdb || config.mode == DebugInfoLldb)
+ && config.target.contains("emscripten");
test::TestDescAndFn {
desc: test::TestDesc {
}
fn stamp(config: &Config, testpaths: &TestPaths) -> PathBuf {
- let stamp_name = format!("{}-{}.stamp",
- testpaths.file.file_name().unwrap()
- .to_str().unwrap(),
- config.stage_id);
- config.build_base.canonicalize()
- .unwrap_or_else(|_| config.build_base.clone())
- .join(&testpaths.relative_dir)
- .join(stamp_name)
+ let stamp_name = format!(
+ "{}-{}.stamp",
+ testpaths.file.file_name().unwrap().to_str().unwrap(),
+ config.stage_id
+ );
+ config
+ .build_base
+ .canonicalize()
+ .unwrap_or_else(|_| config.build_base.clone())
+ .join(&testpaths.relative_dir)
+ .join(stamp_name)
}
fn up_to_date(config: &Config, testpaths: &TestPaths, props: &EarlyProps) -> bool {
- let rust_src_dir = config.find_rust_src_root().expect(
- "Could not find Rust source root",
- );
+ let rust_src_dir = config
+ .find_rust_src_root()
+ .expect("Could not find Rust source root");
let stamp = mtime(&stamp(config, testpaths));
let mut inputs = vec![mtime(&testpaths.file), mtime(&config.rustc_path)];
for aux in props.aux.iter() {
- inputs.push(mtime(
- &testpaths.file.parent().unwrap().join("auxiliary").join(
- aux,
- ),
- ));
+ inputs.push(mtime(&testpaths
+ .file
+ .parent()
+ .unwrap()
+ .join("auxiliary")
+ .join(aux)));
}
// Relevant pretty printer files
let pretty_printer_files = [
}
fn mtime(path: &Path) -> FileTime {
- fs::metadata(path).map(|f| {
- FileTime::from_last_modification_time(&f)
- }).unwrap_or_else(|_| FileTime::zero())
+ fs::metadata(path)
+ .map(|f| FileTime::from_last_modification_time(&f))
+ .unwrap_or_else(|_| FileTime::zero())
}
pub fn make_test_name(config: &Config, testpaths: &TestPaths) -> test::TestName {
// Convert a complete path to something like
//
// run-pass/foo/bar/baz.rs
- let path =
- PathBuf::from(config.src_base.file_name().unwrap())
+ let path = PathBuf::from(config.src_base.file_name().unwrap())
.join(&testpaths.relative_dir)
.join(&testpaths.file.file_name().unwrap());
test::DynTestName(format!("[{}] {}", config.mode, path.display()))
pub fn make_test_closure(config: &Config, testpaths: &TestPaths) -> test::TestFn {
let config = config.clone();
let testpaths = testpaths.clone();
- test::DynTestFn(Box::new(move |()| {
- runtest::run(config, &testpaths)
- }))
+ test::DynTestFn(Box::new(move |()| runtest::run(config, &testpaths)))
}
/// Returns (Path to GDB, GDB Version, GDB has Rust Support)
Some(ref s) => s,
};
- let version_line = Command::new(gdb).arg("--version").output().map(|output| {
- String::from_utf8_lossy(&output.stdout).lines().next().unwrap().to_string()
- }).ok();
+ let version_line = Command::new(gdb)
+ .arg("--version")
+ .output()
+ .map(|output| {
+ String::from_utf8_lossy(&output.stdout)
+ .lines()
+ .next()
+ .unwrap()
+ .to_string()
+ })
+ .ok();
let version = match version_line {
Some(line) => extract_gdb_version(&line),
for (pos, c) in full_version_line.char_indices() {
if prev_was_digit || !c.is_digit(10) {
prev_was_digit = c.is_digit(10);
- continue
+ continue;
}
prev_was_digit = true;
Some(idx) => if line.as_bytes()[idx] == b'.' {
let patch = &line[idx + 1..];
- let patch_len = patch.find(|c: char| !c.is_digit(10))
- .unwrap_or_else(|| patch.len());
+ let patch_len = patch
+ .find(|c: char| !c.is_digit(10))
+ .unwrap_or_else(|| patch.len());
let patch = &patch[..patch_len];
- let patch = if patch_len > 3 || patch_len == 0 { None } else { Some(patch) };
+ let patch = if patch_len > 3 || patch_len == 0 {
+ None
+ } else {
+ Some(patch)
+ };
(&line[..idx], patch)
} else {
let full_version_line = full_version_line.trim();
for (pos, l) in full_version_line.char_indices() {
- if l != 'l' && l != 'L' { continue }
- if pos + 5 >= full_version_line.len() { continue }
+ if l != 'l' && l != 'L' {
+ continue;
+ }
+ if pos + 5 >= full_version_line.len() {
+ continue;
+ }
let l = full_version_line[pos + 1..].chars().next().unwrap();
- if l != 'l' && l != 'L' { continue }
+ if l != 'l' && l != 'L' {
+ continue;
+ }
let d = full_version_line[pos + 2..].chars().next().unwrap();
- if d != 'd' && d != 'D' { continue }
+ if d != 'd' && d != 'D' {
+ continue;
+ }
let b = full_version_line[pos + 3..].chars().next().unwrap();
- if b != 'b' && b != 'B' { continue }
+ if b != 'b' && b != 'B' {
+ continue;
+ }
let dash = full_version_line[pos + 4..].chars().next().unwrap();
- if dash != '-' { continue }
+ if dash != '-' {
+ continue;
+ }
- let vers = full_version_line[pos + 5..].chars().take_while(|c| {
- c.is_digit(10)
- }).collect::<String>();
- if !vers.is_empty() { return Some(vers) }
+ let vers = full_version_line[pos + 5..]
+ .chars()
+ .take_while(|c| c.is_digit(10))
+ .collect::<String>();
+ if !vers.is_empty() {
+ return Some(vers);
+ }
}
}
}
use common::Config;
use common::{CompileFail, ParseFail, Pretty, RunFail, RunPass, RunPassValgrind};
-use common::{Codegen, DebugInfoLldb, DebugInfoGdb, Rustdoc, CodegenUnits};
-use common::{Incremental, RunMake, Ui, MirOpt};
+use common::{Codegen, CodegenUnits, DebugInfoGdb, DebugInfoLldb, Rustdoc};
+use common::{Incremental, MirOpt, RunMake, Ui};
use diff;
-use errors::{self, ErrorKind, Error};
+use errors::{self, Error, ErrorKind};
use filetime::FileTime;
use json;
use header::TestProps;
use std::collections::HashSet;
use std::env;
use std::ffi::OsString;
-use std::fs::{self, File, create_dir_all};
+use std::fs::{self, create_dir_all, File};
use std::fmt;
use std::io::prelude::*;
use std::io::{self, BufReader};
use std::path::{Path, PathBuf};
-use std::process::{Command, Output, ExitStatus, Stdio, Child};
+use std::process::{Child, Command, ExitStatus, Output, Stdio};
use std::str;
use extract_gdb_version;
pub fn run(config: Config, testpaths: &TestPaths) {
match &*config.target {
-
"arm-linux-androideabi" | "armv7-linux-androideabi" | "aarch64-linux-android" => {
if !config.adb_device_status {
panic!("android device not available");
debug!("running {:?}", testpaths.file.display());
let base_props = TestProps::from_file(&testpaths.file, None, &config);
- let base_cx = TestCx { config: &config,
- props: &base_props,
- testpaths,
- revision: None };
+ let base_cx = TestCx {
+ config: &config,
+ props: &base_props,
+ testpaths,
+ revision: None,
+ };
base_cx.init_all();
if base_props.revisions.is_empty() {
base_cx.run_revision()
} else {
for revision in &base_props.revisions {
- let revision_props = TestProps::from_file(&testpaths.file,
- Some(revision),
- &config);
+ let revision_props = TestProps::from_file(&testpaths.file, Some(revision), &config);
let rev_cx = TestCx {
config: &config,
props: &revision_props,
testpaths,
- revision: Some(revision)
+ revision: Some(revision),
};
rev_cx.run_revision();
}
config: &'test Config,
props: &'test TestProps,
testpaths: &'test TestPaths,
- revision: Option<&'test str>
+ revision: Option<&'test str>,
}
struct DebuggerCommands {
/// revisions, exactly once, with revision == None).
fn run_revision(&self) {
match self.config.mode {
- CompileFail |
- ParseFail => self.run_cfail_test(),
+ CompileFail | ParseFail => self.run_cfail_test(),
RunFail => self.run_rfail_test(),
RunPass => self.run_rpass_test(),
RunPassValgrind => self.run_valgrind_test(),
if self.props.must_compile_successfully {
if !proc_res.status.success() {
- self.fatal_proc_rec(
- "test compilation failed although it shouldn't!",
- &proc_res);
+ self.fatal_proc_rec("test compilation failed although it shouldn't!", &proc_res);
}
} else {
if proc_res.status.success() {
self.fatal_proc_rec(
&format!("{} test compiled successfully!", self.config.mode)[..],
- &proc_res);
+ &proc_res,
+ );
}
self.check_correct_failure_status(&proc_res);
const RUST_ERR: i32 = 101;
if proc_res.status.code() != Some(RUST_ERR) {
self.fatal_proc_rec(
- &format!("failure produced the wrong error: {}",
- proc_res.status),
- proc_res);
+ &format!("failure produced the wrong error: {}", proc_res.status),
+ proc_res,
+ );
}
}
// FIXME(#41968): Move this check to tidy?
let expected_errors = errors::load_errors(&self.testpaths.file, self.revision);
- assert!(expected_errors.is_empty(),
- "run-pass tests with expected warnings should be moved to ui/");
+ assert!(
+ expected_errors.is_empty(),
+ "run-pass tests with expected warnings should be moved to ui/"
+ );
let proc_res = self.exec_compiled_test();
let mut new_config = self.config.clone();
new_config.runtool = new_config.valgrind_path.clone();
- let new_cx = TestCx { config: &new_config, ..*self };
+ let new_cx = TestCx {
+ config: &new_config,
+ ..*self
+ };
proc_res = new_cx.exec_compiled_test();
if !proc_res.status.success() {
if self.props.pp_exact.is_some() {
logv(self.config, "testing for exact pretty-printing".to_owned());
} else {
- logv(self.config, "testing for converging pretty-printing".to_owned());
+ logv(
+ self.config,
+ "testing for converging pretty-printing".to_owned(),
+ );
}
- let rounds = match self.props.pp_exact { Some(_) => 1, None => 2 };
+ let rounds = match self.props.pp_exact {
+ Some(_) => 1,
+ None => 2,
+ };
let mut src = String::new();
- File::open(&self.testpaths.file).unwrap().read_to_string(&mut src).unwrap();
+ File::open(&self.testpaths.file)
+ .unwrap()
+ .read_to_string(&mut src)
+ .unwrap();
let mut srcs = vec![src];
let mut round = 0;
while round < rounds {
- logv(self.config, format!("pretty-printing round {} revision {:?}",
- round, self.revision));
+ logv(
+ self.config,
+ format!(
+ "pretty-printing round {} revision {:?}",
+ round,
+ self.revision
+ ),
+ );
let proc_res = self.print_source(srcs[round].to_owned(), &self.props.pretty_mode);
if !proc_res.status.success() {
- self.fatal_proc_rec(&format!("pretty-printing failed in round {} revision {:?}",
- round, self.revision),
- &proc_res);
+ self.fatal_proc_rec(
+ &format!(
+ "pretty-printing failed in round {} revision {:?}",
+ round,
+ self.revision
+ ),
+ &proc_res,
+ );
}
- let ProcRes{ stdout, .. } = proc_res;
+ let ProcRes { stdout, .. } = proc_res;
srcs.push(stdout);
round += 1;
}
Some(ref file) => {
let filepath = self.testpaths.file.parent().unwrap().join(file);
let mut s = String::new();
- File::open(&filepath).unwrap().read_to_string(&mut s).unwrap();
+ File::open(&filepath)
+ .unwrap()
+ .read_to_string(&mut s)
+ .unwrap();
s
}
- None => { srcs[srcs.len() - 2].clone() }
+ None => srcs[srcs.len() - 2].clone(),
};
let mut actual = srcs[srcs.len() - 1].clone();
self.compare_source(&expected, &actual);
// If we're only making sure that the output matches then just stop here
- if self.props.pretty_compare_only { return; }
+ if self.props.pretty_compare_only {
+ return;
+ }
// Finally, let's make sure it actually appears to remain valid code
let proc_res = self.typecheck_source(actual);
self.fatal_proc_rec("pretty-printed source does not typecheck", &proc_res);
}
- if !self.props.pretty_expanded { return }
+ if !self.props.pretty_expanded {
+ return;
+ }
// additionally, run `--pretty expanded` and try to build it.
let proc_res = self.print_source(srcs[round].clone(), "expanded");
self.fatal_proc_rec("pretty-printing (expanded) failed", &proc_res);
}
- let ProcRes{ stdout: expanded_src, .. } = proc_res;
+ let ProcRes {
+ stdout: expanded_src,
+ ..
+ } = proc_res;
let proc_res = self.typecheck_source(expanded_src);
if !proc_res.status.success() {
self.fatal_proc_rec(
"pretty-printed source (expanded) does not typecheck",
- &proc_res);
+ &proc_res,
+ );
}
}
let aux_dir = self.aux_output_dir_name();
let mut rustc = Command::new(&self.config.rustc_path);
- rustc.arg("-")
+ rustc
+ .arg("-")
.arg("-Zunstable-options")
.args(&["--unpretty", &pretty_type])
.args(&["--target", &self.config.target])
- .arg("-L").arg(&aux_dir)
+ .arg("-L")
+ .arg(&aux_dir)
.args(self.split_maybe_args(&self.config.target_rustcflags))
.args(&self.props.compile_flags)
.envs(self.props.exec_env.clone());
- self.compose_and_run(rustc,
- self.config.compile_lib_path.to_str().unwrap(),
- Some(aux_dir.to_str().unwrap()),
- Some(src))
+ self.compose_and_run(
+ rustc,
+ self.config.compile_lib_path.to_str().unwrap(),
+ Some(aux_dir.to_str().unwrap()),
+ Some(src),
+ )
}
- fn compare_source(&self,
- expected: &str,
- actual: &str) {
+ fn compare_source(&self, expected: &str, actual: &str) {
if expected != actual {
self.error("pretty-printed source does not match expected source");
- println!("\n\
-expected:\n\
-------------------------------------------\n\
-{}\n\
-------------------------------------------\n\
-actual:\n\
-------------------------------------------\n\
-{}\n\
-------------------------------------------\n\
-\n",
- expected, actual);
+ println!(
+ "\n\
+ expected:\n\
+ ------------------------------------------\n\
+ {}\n\
+ ------------------------------------------\n\
+ actual:\n\
+ ------------------------------------------\n\
+ {}\n\
+ ------------------------------------------\n\
+ \n",
+ expected,
+ actual
+ );
panic!();
}
}
let aux_dir = self.aux_output_dir_name();
- rustc.arg("-")
+ rustc
+ .arg("-")
.arg("-Zno-trans")
- .arg("--out-dir").arg(&out_dir)
+ .arg("--out-dir")
+ .arg(&out_dir)
.arg(&format!("--target={}", target))
- .arg("-L").arg(&self.config.build_base)
- .arg("-L").arg(aux_dir);
+ .arg("-L")
+ .arg(&self.config.build_base)
+ .arg("-L")
+ .arg(aux_dir);
if let Some(revision) = self.revision {
rustc.args(&["--cfg", revision]);
let config = Config {
target_rustcflags: self.cleanup_debug_info_options(&self.config.target_rustcflags),
host_rustcflags: self.cleanup_debug_info_options(&self.config.host_rustcflags),
- .. self.config.clone()
+ ..self.config.clone()
};
let test_cx = TestCx {
let DebuggerCommands {
commands,
check_lines,
- breakpoint_lines
+ breakpoint_lines,
} = self.parse_debugger_commands(prefixes);
let mut cmds = commands.join("\n");
let debugger_run_result;
match &*self.config.target {
- "arm-linux-androideabi" |
- "armv7-linux-androideabi" |
- "aarch64-linux-android" => {
-
+ "arm-linux-androideabi" | "armv7-linux-androideabi" | "aarch64-linux-android" => {
cmds = cmds.replace("run", "continue");
let tool_path = match self.config.android_cross_path.to_str() {
Some(x) => x.to_owned(),
- None => self.fatal("cannot find android cross path")
+ None => self.fatal("cannot find android cross path"),
};
// write debugger script
script_str.push_str(&format!("set sysroot {}\n", tool_path));
script_str.push_str(&format!("file {}\n", exe_file.to_str().unwrap()));
script_str.push_str("target remote :5039\n");
- script_str.push_str(&format!("set solib-search-path \
- ./{}/stage2/lib/rustlib/{}/lib/\n",
- self.config.host, self.config.target));
+ script_str.push_str(&format!(
+ "set solib-search-path \
+ ./{}/stage2/lib/rustlib/{}/lib/\n",
+ self.config.host,
+ self.config.target
+ ));
for line in &breakpoint_lines {
- script_str.push_str(&format!("break {:?}:{}\n",
- self.testpaths.file.file_name()
- .unwrap()
- .to_string_lossy(),
- *line)[..]);
+ script_str.push_str(
+ &format!(
+ "break {:?}:{}\n",
+ self.testpaths.file.file_name().unwrap().to_string_lossy(),
+ *line
+ )[..],
+ );
}
script_str.push_str(&cmds);
script_str.push_str("\nquit\n");
.status()
.expect(&format!("failed to exec `{:?}`", adb_path));
- let adb_arg = format!("export LD_LIBRARY_PATH={}; \
- gdbserver{} :5039 {}/{}",
- self.config.adb_test_dir.clone(),
- if self.config.target.contains("aarch64")
- {"64"} else {""},
- self.config.adb_test_dir.clone(),
- exe_file.file_name().unwrap().to_str()
- .unwrap());
+ let adb_arg = format!(
+ "export LD_LIBRARY_PATH={}; \
+ gdbserver{} :5039 {}/{}",
+ self.config.adb_test_dir.clone(),
+ if self.config.target.contains("aarch64") {
+ "64"
+ } else {
+ ""
+ },
+ self.config.adb_test_dir.clone(),
+ exe_file.file_name().unwrap().to_str().unwrap()
+ );
debug!("adb arg: {}", adb_arg);
let mut adb = Command::new(adb_path)
line.truncate(0);
stdout.read_line(&mut line).unwrap();
if line.starts_with("Listening on port 5039") {
- break
+ break;
}
}
drop(stdout);
let debugger_script = self.make_out_name("debugger.script");
// FIXME (#9639): This needs to handle non-utf8 paths
- let debugger_opts =
- vec!["-quiet".to_owned(),
- "-batch".to_owned(),
- "-nx".to_owned(),
- format!("-command={}", debugger_script.to_str().unwrap())];
+ let debugger_opts = vec![
+ "-quiet".to_owned(),
+ "-batch".to_owned(),
+ "-nx".to_owned(),
+ format!("-command={}", debugger_script.to_str().unwrap()),
+ ];
let mut gdb_path = tool_path;
gdb_path.push_str("/bin/gdb");
let Output {
status,
stdout,
- stderr
+ stderr,
} = Command::new(&gdb_path)
.args(&debugger_opts)
.output()
}
_ => {
- let rust_src_root = self.config.find_rust_src_root().expect(
- "Could not find Rust source root",
- );
+ let rust_src_root = self.config
+ .find_rust_src_root()
+ .expect("Could not find Rust source root");
let rust_pp_module_rel_path = Path::new("./src/etc");
- let rust_pp_module_abs_path = rust_src_root.join(rust_pp_module_rel_path)
- .to_str()
- .unwrap()
- .to_owned();
+ let rust_pp_module_abs_path = rust_src_root
+ .join(rust_pp_module_rel_path)
+ .to_str()
+ .unwrap()
+ .to_owned();
// write debugger script
let mut script_str = String::with_capacity(2048);
script_str.push_str(&format!("set charset {}\n", Self::charset()));
match self.config.gdb_version {
Some(version) => {
- println!("NOTE: compiletest thinks it is using GDB version {}",
- version);
+ println!(
+ "NOTE: compiletest thinks it is using GDB version {}",
+ version
+ );
if version > extract_gdb_version("7.4").unwrap() {
// Add the directory containing the pretty printers to
// GDB's script auto loading safe path
- script_str.push_str(
- &format!("add-auto-load-safe-path {}\n",
- rust_pp_module_abs_path.replace(r"\", r"\\"))
- );
+ script_str.push_str(&format!(
+ "add-auto-load-safe-path {}\n",
+ rust_pp_module_abs_path.replace(r"\", r"\\")
+ ));
}
}
_ => {
- println!("NOTE: compiletest does not know which version of \
- GDB it is using");
+ println!(
+ "NOTE: compiletest does not know which version of \
+ GDB it is using"
+ );
}
}
script_str.push_str("set print pretty off\n");
// Add the pretty printer directory to GDB's source-file search path
- script_str.push_str(&format!("directory {}\n",
- rust_pp_module_abs_path));
+ script_str.push_str(&format!("directory {}\n", rust_pp_module_abs_path));
// Load the target executable
- script_str.push_str(&format!("file {}\n",
- exe_file.to_str().unwrap()
- .replace(r"\", r"\\")));
+ script_str.push_str(&format!(
+ "file {}\n",
+ exe_file.to_str().unwrap().replace(r"\", r"\\")
+ ));
// Force GDB to print values in the Rust format.
if self.config.gdb_native_rust {
// Add line breakpoints
for line in &breakpoint_lines {
- script_str.push_str(&format!("break '{}':{}\n",
- self.testpaths.file.file_name().unwrap()
- .to_string_lossy(),
- *line));
+ script_str.push_str(&format!(
+ "break '{}':{}\n",
+ self.testpaths.file.file_name().unwrap().to_string_lossy(),
+ *line
+ ));
}
script_str.push_str(&cmds);
let debugger_script = self.make_out_name("debugger.script");
// FIXME (#9639): This needs to handle non-utf8 paths
- let debugger_opts =
- vec!["-quiet".to_owned(),
- "-batch".to_owned(),
- "-nx".to_owned(),
- format!("-command={}", debugger_script.to_str().unwrap())];
+ let debugger_opts = vec![
+ "-quiet".to_owned(),
+ "-batch".to_owned(),
+ "-nx".to_owned(),
+ format!("-command={}", debugger_script.to_str().unwrap()),
+ ];
let mut gdb = Command::new(self.config.gdb.as_ref().unwrap());
gdb.args(&debugger_opts)
.env("PYTHONPATH", rust_pp_module_abs_path);
- debugger_run_result =
- self.compose_and_run(gdb,
- self.config.run_lib_path.to_str().unwrap(),
- None,
- None);
+ debugger_run_result = self.compose_and_run(
+ gdb,
+ self.config.run_lib_path.to_str().unwrap(),
+ None,
+ None,
+ );
}
}
let config = Config {
target_rustcflags: self.cleanup_debug_info_options(&self.config.target_rustcflags),
host_rustcflags: self.cleanup_debug_info_options(&self.config.host_rustcflags),
- .. self.config.clone()
+ ..self.config.clone()
};
match self.config.lldb_version {
Some(ref version) => {
- println!("NOTE: compiletest thinks it is using LLDB version {}",
- version);
+ println!(
+ "NOTE: compiletest thinks it is using LLDB version {}",
+ version
+ );
}
_ => {
- println!("NOTE: compiletest does not know which version of \
- LLDB it is using");
+ println!(
+ "NOTE: compiletest does not know which version of \
+ LLDB it is using"
+ );
}
}
script_str.push_str("version\n");
// Switch LLDB into "Rust mode"
- let rust_src_root = self.config.find_rust_src_root().expect(
- "Could not find Rust source root",
- );
+ let rust_src_root = self.config
+ .find_rust_src_root()
+ .expect("Could not find Rust source root");
let rust_pp_module_rel_path = Path::new("./src/etc/lldb_rust_formatters.py");
- let rust_pp_module_abs_path = rust_src_root.join(rust_pp_module_rel_path)
- .to_str()
- .unwrap()
- .to_owned();
-
- script_str.push_str(&format!("command script import {}\n",
- &rust_pp_module_abs_path[..])[..]);
+ let rust_pp_module_abs_path = rust_src_root
+ .join(rust_pp_module_rel_path)
+ .to_str()
+ .unwrap()
+ .to_owned();
+
+ script_str
+ .push_str(&format!("command script import {}\n", &rust_pp_module_abs_path[..])[..]);
script_str.push_str("type summary add --no-value ");
script_str.push_str("--python-function lldb_rust_formatters.print_val ");
script_str.push_str("-x \".*\" --category Rust\n");
// Set breakpoints on every line that contains the string "#break"
let source_file_name = self.testpaths.file.file_name().unwrap().to_string_lossy();
for line in &breakpoint_lines {
- script_str.push_str(&format!("breakpoint set --file '{}' --line {}\n",
- source_file_name,
- line));
+ script_str.push_str(&format!(
+ "breakpoint set --file '{}' --line {}\n",
+ source_file_name,
+ line
+ ));
}
// Append the other commands
let debugger_script = self.make_out_name("debugger.script");
// Let LLDB execute the script via lldb_batchmode.py
- let debugger_run_result = self.run_lldb(&exe_file,
- &debugger_script,
- &rust_src_root);
+ let debugger_run_result = self.run_lldb(&exe_file, &debugger_script, &rust_src_root);
if !debugger_run_result.status.success() {
self.fatal_proc_rec("Error while running LLDB", &debugger_run_result);
self.check_debugger_output(&debugger_run_result, &check_lines);
}
- fn run_lldb(&self,
- test_executable: &Path,
- debugger_script: &Path,
- rust_src_root: &Path)
- -> ProcRes {
+ fn run_lldb(
+ &self,
+ test_executable: &Path,
+ debugger_script: &Path,
+ rust_src_root: &Path,
+ ) -> ProcRes {
// Prepare the lldb_batchmode which executes the debugger script
let lldb_script_path = rust_src_root.join("src/etc/lldb_batchmode.py");
- self.cmd2procres(Command::new(&self.config.lldb_python)
- .arg(&lldb_script_path)
- .arg(test_executable)
- .arg(debugger_script)
- .env("PYTHONPATH",
- self.config.lldb_python_dir.as_ref().unwrap()))
+ self.cmd2procres(
+ Command::new(&self.config.lldb_python)
+ .arg(&lldb_script_path)
+ .arg(test_executable)
+ .arg(debugger_script)
+ .env("PYTHONPATH", self.config.lldb_python_dir.as_ref().unwrap()),
+ )
}
fn cmd2procres(&self, cmd: &mut Command) -> ProcRes {
let (status, out, err) = match cmd.output() {
- Ok(Output { status, stdout, stderr }) => {
- (status,
- String::from_utf8(stdout).unwrap(),
- String::from_utf8(stderr).unwrap())
- },
- Err(e) => {
- self.fatal(&format!("Failed to setup Python process for \
- LLDB script: {}", e))
- }
+ Ok(Output {
+ status,
+ stdout,
+ stderr,
+ }) => (
+ status,
+ String::from_utf8(stdout).unwrap(),
+ String::from_utf8(stderr).unwrap(),
+ ),
+ Err(e) => self.fatal(&format!(
+ "Failed to setup Python process for \
+ LLDB script: {}",
+ e
+ )),
};
self.dump_output(&out, &err);
status,
stdout: out,
stderr: err,
- cmdline: format!("{:?}", cmd)
+ cmdline: format!("{:?}", cmd),
}
}
fn parse_debugger_commands(&self, debugger_prefixes: &[&str]) -> DebuggerCommands {
- let directives = debugger_prefixes.iter().map(|prefix| (
- format!("{}-command", prefix),
- format!("{}-check", prefix),
- )).collect::<Vec<_>>();
+ let directives = debugger_prefixes
+ .iter()
+ .map(|prefix| {
+ (format!("{}-command", prefix), format!("{}-check", prefix))
+ })
+ .collect::<Vec<_>>();
let mut breakpoint_lines = vec![];
let mut commands = vec![];
}
for &(ref command_directive, ref check_directive) in &directives {
- self.config.parse_name_value_directive(
- &line,
- command_directive).map(|cmd| {
- commands.push(cmd)
- });
-
- self.config.parse_name_value_directive(
- &line,
- check_directive).map(|cmd| {
- check_lines.push(cmd)
- });
+ self.config
+ .parse_name_value_directive(&line, command_directive)
+ .map(|cmd| commands.push(cmd));
+
+ self.config
+ .parse_name_value_directive(&line, check_directive)
+ .map(|cmd| check_lines.push(cmd));
}
}
- Err(e) => {
- self.fatal(&format!("Error while parsing debugger commands: {}", e))
- }
+ Err(e) => self.fatal(&format!("Error while parsing debugger commands: {}", e)),
}
counter += 1;
}
}
// Remove options that are either unwanted (-O) or may lead to duplicates due to RUSTFLAGS.
- let options_to_remove = [
- "-O".to_owned(),
- "-g".to_owned(),
- "--debuginfo".to_owned()
- ];
- let new_options =
- self.split_maybe_args(options).into_iter()
- .filter(|x| !options_to_remove.contains(x))
- .collect::<Vec<String>>();
+ let options_to_remove = ["-O".to_owned(), "-g".to_owned(), "--debuginfo".to_owned()];
+ let new_options = self.split_maybe_args(options)
+ .into_iter()
+ .filter(|x| !options_to_remove.contains(x))
+ .collect::<Vec<String>>();
Some(new_options.join(" "))
}
}
}
if check_line_index != num_check_lines && num_check_lines > 0 {
- self.fatal_proc_rec(&format!("line not found in debugger output: {}",
- check_lines[check_line_index]),
- debugger_run_result);
+ self.fatal_proc_rec(
+ &format!(
+ "line not found in debugger output: {}",
+ check_lines[check_line_index]
+ ),
+ debugger_run_result,
+ );
}
fn check_single_line(line: &str, check_line: &str) -> bool {
let can_start_anywhere = check_line.starts_with("[...]");
let can_end_anywhere = check_line.ends_with("[...]");
- let check_fragments: Vec<&str> = check_line.split("[...]")
- .filter(|frag| !frag.is_empty())
- .collect();
+ let check_fragments: Vec<&str> = check_line
+ .split("[...]")
+ .filter(|frag| !frag.is_empty())
+ .collect();
if check_fragments.is_empty() {
return true;
}
let (mut rest, first_fragment) = if can_start_anywhere {
match line.find(check_fragments[0]) {
- Some(pos) => (&line[pos + check_fragments[0].len() ..], 1),
- None => return false
+ Some(pos) => (&line[pos + check_fragments[0].len()..], 1),
+ None => return false,
}
} else {
(line, 0)
for current_fragment in &check_fragments[first_fragment..] {
match rest.find(current_fragment) {
Some(pos) => {
- rest = &rest[pos + current_fragment.len() .. ];
+ rest = &rest[pos + current_fragment.len()..];
}
- None => return false
+ None => return false,
}
}
}
}
- fn check_error_patterns(&self,
- output_to_check: &str,
- proc_res: &ProcRes) {
+ fn check_error_patterns(&self, output_to_check: &str, proc_res: &ProcRes) {
if self.props.error_patterns.is_empty() {
if self.props.must_compile_successfully {
- return
+ return;
} else {
- self.fatal(&format!("no error pattern specified in {:?}",
- self.testpaths.file.display()));
+ self.fatal(&format!(
+ "no error pattern specified in {:?}",
+ self.testpaths.file.display()
+ ));
}
}
let mut next_err_idx = 0;
next_err_pat = self.props.error_patterns[next_err_idx].trim();
}
}
- if done { return; }
+ if done {
+ return;
+ }
let missing_patterns = &self.props.error_patterns[next_err_idx..];
if missing_patterns.len() == 1 {
self.fatal_proc_rec(
&format!("error pattern '{}' not found!", missing_patterns[0]),
- proc_res);
+ proc_res,
+ );
} else {
for pattern in missing_patterns {
self.error(&format!("error pattern '{}' not found!", *pattern));
}
}
- fn check_forbid_output(&self,
- output_to_check: &str,
- proc_res: &ProcRes) {
+ fn check_forbid_output(&self, output_to_check: &str, proc_res: &ProcRes) {
for pat in &self.props.forbid_output {
if output_to_check.contains(pat) {
self.fatal_proc_rec("forbidden pattern found in compiler output", proc_res);
}
}
- fn check_expected_errors(&self,
- expected_errors: Vec<errors::Error>,
- proc_res: &ProcRes) {
- if proc_res.status.success() &&
- expected_errors.iter().any(|x| x.kind == Some(ErrorKind::Error)) {
+ fn check_expected_errors(&self, expected_errors: Vec<errors::Error>, proc_res: &ProcRes) {
+ if proc_res.status.success()
+ && expected_errors
+ .iter()
+ .any(|x| x.kind == Some(ErrorKind::Error))
+ {
self.fatal_proc_rec("process did not return an error status", proc_res);
}
- let file_name =
- format!("{}", self.testpaths.file.display())
- .replace(r"\", "/"); // on windows, translate all '\' path separators to '/'
+ let file_name = format!("{}", self.testpaths.file.display()).replace(r"\", "/"); // on windows, translate all '\' path separators to '/'
// If the testcase being checked contains at least one expected "help"
// message, then we'll ensure that all "help" messages are expected.
// Otherwise, all "help" messages reported by the compiler will be ignored.
// This logic also applies to "note" messages.
- let expect_help = expected_errors.iter().any(|ee| ee.kind == Some(ErrorKind::Help));
- let expect_note = expected_errors.iter().any(|ee| ee.kind == Some(ErrorKind::Note));
+ let expect_help = expected_errors
+ .iter()
+ .any(|ee| ee.kind == Some(ErrorKind::Help));
+ let expect_note = expected_errors
+ .iter()
+ .any(|ee| ee.kind == Some(ErrorKind::Note));
// Parse the JSON output from the compiler and extract out the messages.
let actual_errors = json::parse_output(&file_name, &proc_res.stderr, proc_res);
let mut unexpected = Vec::new();
let mut found = vec![false; expected_errors.len()];
for actual_error in &actual_errors {
- let opt_index =
- expected_errors
- .iter()
- .enumerate()
- .position(|(index, expected_error)| {
- !found[index] &&
- actual_error.line_num == expected_error.line_num &&
- (expected_error.kind.is_none() ||
- actual_error.kind == expected_error.kind) &&
- actual_error.msg.contains(&expected_error.msg)
- });
+ let opt_index = expected_errors.iter().enumerate().position(
+ |(index, expected_error)| {
+ !found[index] && actual_error.line_num == expected_error.line_num
+ && (expected_error.kind.is_none()
+ || actual_error.kind == expected_error.kind)
+ && actual_error.msg.contains(&expected_error.msg)
+ },
+ );
match opt_index {
Some(index) => {
None => {
if self.is_unexpected_compiler_message(actual_error, expect_help, expect_note) {
- self.error(
- &format!("{}:{}: unexpected {}: '{}'",
- file_name,
- actual_error.line_num,
- actual_error.kind.as_ref()
- .map_or(String::from("message"),
- |k| k.to_string()),
- actual_error.msg));
+ self.error(&format!(
+ "{}:{}: unexpected {}: '{}'",
+ file_name,
+ actual_error.line_num,
+ actual_error
+ .kind
+ .as_ref()
+ .map_or(String::from("message"), |k| k.to_string()),
+ actual_error.msg
+ ));
unexpected.push(actual_error);
}
}
// anything not yet found is a problem
for (index, expected_error) in expected_errors.iter().enumerate() {
if !found[index] {
- self.error(
- &format!("{}:{}: expected {} not found: {}",
- file_name,
- expected_error.line_num,
- expected_error.kind.as_ref()
- .map_or("message".into(),
- |k| k.to_string()),
- expected_error.msg));
+ self.error(&format!(
+ "{}:{}: expected {} not found: {}",
+ file_name,
+ expected_error.line_num,
+ expected_error
+ .kind
+ .as_ref()
+ .map_or("message".into(), |k| k.to_string()),
+ expected_error.msg
+ ));
not_found.push(expected_error);
}
}
if !unexpected.is_empty() || !not_found.is_empty() {
- self.error(
- &format!("{} unexpected errors found, {} expected errors not found",
- unexpected.len(), not_found.len()));
- println!("status: {}\ncommand: {}",
- proc_res.status, proc_res.cmdline);
+ self.error(&format!(
+ "{} unexpected errors found, {} expected errors not found",
+ unexpected.len(),
+ not_found.len()
+ ));
+ println!("status: {}\ncommand: {}", proc_res.status, proc_res.cmdline);
if !unexpected.is_empty() {
println!("unexpected errors (from JSON output): {:#?}\n", unexpected);
}
/// which did not match any of the expected error. We always require
/// errors/warnings to be explicitly listed, but only require
/// helps/notes if there are explicit helps/notes given.
- fn is_unexpected_compiler_message(&self,
- actual_error: &Error,
- expect_help: bool,
- expect_note: bool)
- -> bool {
+ fn is_unexpected_compiler_message(
+ &self,
+ actual_error: &Error,
+ expect_help: bool,
+ expect_note: bool,
+ ) -> bool {
match actual_error.kind {
Some(ErrorKind::Help) => expect_help,
Some(ErrorKind::Note) => expect_note,
- Some(ErrorKind::Error) |
- Some(ErrorKind::Warning) => true,
- Some(ErrorKind::Suggestion) |
- None => false
+ Some(ErrorKind::Error) | Some(ErrorKind::Warning) => true,
+ Some(ErrorKind::Suggestion) | None => false,
}
}
fn compile_test(&self) -> ProcRes {
let mut rustc = self.make_compile_args(
- &self.testpaths.file, TargetLocation::ThisFile(self.make_exe_name()));
+ &self.testpaths.file,
+ TargetLocation::ThisFile(self.make_exe_name()),
+ );
rustc.arg("-L").arg(&self.aux_output_dir_name());
if self.props.build_aux_docs {
for rel_ab in &self.props.aux_builds {
let aux_testpaths = self.compute_aux_test_paths(rel_ab);
- let aux_props = self.props.from_aux_file(&aux_testpaths.file,
- self.revision,
- self.config);
+ let aux_props =
+ self.props
+ .from_aux_file(&aux_testpaths.file, self.revision, self.config);
let aux_cx = TestCx {
config: self.config,
props: &aux_props,
testpaths: &aux_testpaths,
- revision: self.revision
+ revision: self.revision,
};
let auxres = aux_cx.document(out_dir);
if !auxres.status.success() {
let aux_dir = self.aux_output_dir_name();
- let rustdoc_path = self.config.rustdoc_path.as_ref().expect("--rustdoc-path passed");
+ let rustdoc_path = self.config
+ .rustdoc_path
+ .as_ref()
+ .expect("--rustdoc-path passed");
let mut rustdoc = Command::new(rustdoc_path);
- rustdoc.arg("-L").arg(aux_dir)
- .arg("-o").arg(out_dir)
+ rustdoc
+ .arg("-L")
+ .arg(aux_dir)
+ .arg("-o")
+ .arg(out_dir)
.arg(&self.testpaths.file)
.args(&self.props.compile_flags);
if let Some(ref linker) = self.config.linker {
- rustdoc.arg("--linker").arg(linker).arg("-Z").arg("unstable-options");
+ rustdoc
+ .arg("--linker")
+ .arg(linker)
+ .arg("-Z")
+ .arg("unstable-options");
}
self.compose_and_run_compiler(rustdoc, None)
for entry in entries {
let entry = entry.unwrap();
if !entry.path().is_file() {
- continue
+ continue;
}
prog.push_str(":");
prog.push_str(entry.path().to_str().unwrap());
}
}
- let mut test_client = Command::new(
- self.config.remote_test_client.as_ref().unwrap());
+ let mut test_client =
+ Command::new(self.config.remote_test_client.as_ref().unwrap());
test_client
.args(&["run", &prog])
.args(args)
.envs(env.clone());
- self.compose_and_run(test_client,
- self.config.run_lib_path.to_str().unwrap(),
- Some(aux_dir.to_str().unwrap()),
- None)
+ self.compose_and_run(
+ test_client,
+ self.config.run_lib_path.to_str().unwrap(),
+ Some(aux_dir.to_str().unwrap()),
+ None,
+ )
}
_ => {
let aux_dir = self.aux_output_dir_name();
let ProcArgs { prog, args } = self.make_run_args();
let mut program = Command::new(&prog);
- program.args(args)
+ program
+ .args(args)
.current_dir(&self.output_base_name().parent().unwrap())
.envs(env.clone());
- self.compose_and_run(program,
- self.config.run_lib_path.to_str().unwrap(),
- Some(aux_dir.to_str().unwrap()),
- None)
+ self.compose_and_run(
+ program,
+ self.config.run_lib_path.to_str().unwrap(),
+ Some(aux_dir.to_str().unwrap()),
+ None,
+ )
}
}
}
/// For each `aux-build: foo/bar` annotation, we check to find the
/// file in a `aux` directory relative to the test itself.
fn compute_aux_test_paths(&self, rel_ab: &str) -> TestPaths {
- let test_ab = self.testpaths.file
- .parent()
- .expect("test file path has no parent")
- .join("auxiliary")
- .join(rel_ab);
+ let test_ab = self.testpaths
+ .file
+ .parent()
+ .expect("test file path has no parent")
+ .join("auxiliary")
+ .join(rel_ab);
if !test_ab.exists() {
- self.fatal(&format!("aux-build `{}` source not found", test_ab.display()))
+ self.fatal(&format!(
+ "aux-build `{}` source not found",
+ test_ab.display()
+ ))
}
TestPaths {
file: test_ab,
base: self.testpaths.base.clone(),
- relative_dir: self.testpaths.relative_dir
- .join("auxiliary")
- .join(rel_ab)
- .parent()
- .expect("aux-build path has no parent")
- .to_path_buf()
+ relative_dir: self.testpaths
+ .relative_dir
+ .join("auxiliary")
+ .join(rel_ab)
+ .parent()
+ .expect("aux-build path has no parent")
+ .to_path_buf(),
}
}
for rel_ab in &self.props.aux_builds {
let aux_testpaths = self.compute_aux_test_paths(rel_ab);
- let aux_props = self.props.from_aux_file(&aux_testpaths.file,
- self.revision,
- self.config);
+ let aux_props =
+ self.props
+ .from_aux_file(&aux_testpaths.file, self.revision, self.config);
let aux_output = {
let f = self.make_lib_name(&self.testpaths.file);
let parent = f.parent().unwrap();
config: self.config,
props: &aux_props,
testpaths: &aux_testpaths,
- revision: self.revision
+ revision: self.revision,
};
let mut aux_rustc = aux_cx.make_compile_args(&aux_testpaths.file, aux_output);
let crate_type = if aux_props.no_prefer_dynamic {
None
- } else if (self.config.target.contains("musl") && !aux_props.force_host) ||
- self.config.target.contains("wasm32") ||
- self.config.target.contains("emscripten") {
+ } else if (self.config.target.contains("musl") && !aux_props.force_host)
+ || self.config.target.contains("wasm32")
+ || self.config.target.contains("emscripten")
+ {
// We primarily compile all auxiliary libraries as dynamic libraries
// to avoid code size bloat and large binaries as much as possible
// for the test suite (otherwise including libstd statically in all
aux_rustc.arg("-L").arg(&aux_dir);
- let auxres = aux_cx.compose_and_run(aux_rustc,
- aux_cx.config.compile_lib_path.to_str().unwrap(),
- Some(aux_dir.to_str().unwrap()),
- None);
+ let auxres = aux_cx.compose_and_run(
+ aux_rustc,
+ aux_cx.config.compile_lib_path.to_str().unwrap(),
+ Some(aux_dir.to_str().unwrap()),
+ None,
+ );
if !auxres.status.success() {
self.fatal_proc_rec(
- &format!("auxiliary build of {:?} failed to compile: ",
- aux_testpaths.file.display()),
- &auxres);
+ &format!(
+ "auxiliary build of {:?} failed to compile: ",
+ aux_testpaths.file.display()
+ ),
+ &auxres,
+ );
}
}
rustc.envs(self.props.rustc_env.clone());
- self.compose_and_run(rustc,
- self.config.compile_lib_path.to_str().unwrap(),
- Some(aux_dir.to_str().unwrap()),
- input)
- }
-
- fn compose_and_run(&self,
- mut command: Command,
- lib_path: &str,
- aux_path: Option<&str>,
- input: Option<String>) -> ProcRes {
- let cmdline =
- {
+ self.compose_and_run(
+ rustc,
+ self.config.compile_lib_path.to_str().unwrap(),
+ Some(aux_dir.to_str().unwrap()),
+ input,
+ )
+ }
+
+ fn compose_and_run(
+ &self,
+ mut command: Command,
+ lib_path: &str,
+ aux_path: Option<&str>,
+ input: Option<String>,
+ ) -> ProcRes {
+ let cmdline = {
let cmdline = self.make_cmdline(&command, lib_path);
logv(self.config, format!("executing {}", cmdline));
cmdline
let newpath = env::join_paths(&path).unwrap();
command.env(dylib_env_var(), newpath);
- let mut child = command.spawn().expect(&format!("failed to exec `{:?}`", &command));
+ let mut child = command
+ .spawn()
+ .expect(&format!("failed to exec `{:?}`", &command));
if let Some(input) = input {
- child.stdin.as_mut().unwrap().write_all(input.as_bytes()).unwrap();
+ child
+ .stdin
+ .as_mut()
+ .unwrap()
+ .write_all(input.as_bytes())
+ .unwrap();
}
- let Output { status, stdout, stderr } = read2_abbreviated(child)
- .expect("failed to read output");
+ let Output {
+ status,
+ stdout,
+ stderr,
+ } = read2_abbreviated(child).expect("failed to read output");
let result = ProcRes {
status,
fn make_compile_args(&self, input_file: &Path, output_file: TargetLocation) -> Command {
let mut rustc = Command::new(&self.config.rustc_path);
- rustc.arg(input_file)
- .arg("-L").arg(&self.config.build_base);
+ rustc.arg(input_file).arg("-L").arg(&self.config.build_base);
// Optionally prevent default --target if specified in test compile-flags.
- let custom_target = self.props.compile_flags
+ let custom_target = self.props
+ .compile_flags
.iter()
.any(|x| x.starts_with("--target"));
}
if let Some(ref incremental_dir) = self.props.incremental_dir {
- rustc.args(&["-Z", &format!("incremental={}", incremental_dir.display())]);
+ rustc.args(&[
+ "-Z",
+ &format!("incremental={}", incremental_dir.display()),
+ ]);
rustc.args(&["-Z", "incremental-verify-ich"]);
rustc.args(&["-Z", "incremental-queries"]);
}
match self.config.mode {
- CompileFail |
- ParseFail |
- Incremental => {
+ CompileFail | ParseFail | Incremental => {
// If we are extracting and matching errors in the new
// fashion, then you want JSON mode. Old-skool error
// patterns still match the raw compiler output.
rustc.args(&["--error-format", "json"]);
}
}
- Ui => {
- if !self.props.compile_flags.iter().any(|s| s.starts_with("--error-format")) {
- rustc.args(&["--error-format", "json"]);
- }
- }
+ Ui => if !self.props
+ .compile_flags
+ .iter()
+ .any(|s| s.starts_with("--error-format"))
+ {
+ rustc.args(&["--error-format", "json"]);
+ },
MirOpt => {
rustc.args(&[
"-Zdump-mir=all",
"-Zmir-opt-level=3",
- "-Zdump-mir-exclude-pass-number"]);
+ "-Zdump-mir-exclude-pass-number",
+ ]);
let mir_dump_dir = self.get_mir_dump_dir();
let _ = fs::remove_dir_all(&mir_dump_dir);
args.extend(self.split_maybe_args(&self.props.run_flags));
let prog = args.remove(0);
- ProcArgs {
- prog,
- args,
- }
+ ProcArgs { prog, args }
}
fn split_maybe_args(&self, argstr: &Option<String>) -> Vec<String> {
match *argstr {
- Some(ref s) => {
- s
- .split(' ')
- .filter_map(|s| {
- if s.chars().all(|c| c.is_whitespace()) {
- None
- } else {
- Some(s.to_owned())
- }
- }).collect()
- }
- None => Vec::new()
+ Some(ref s) => s.split(' ')
+ .filter_map(|s| {
+ if s.chars().all(|c| c.is_whitespace()) {
+ None
+ } else {
+ Some(s.to_owned())
+ }
+ })
+ .collect(),
+ None => Vec::new(),
}
}
// Build the LD_LIBRARY_PATH variable as it would be seen on the command line
// for diagnostic purposes
fn lib_path_cmd_prefix(path: &str) -> String {
- format!("{}=\"{}\"", util::lib_path_env_var(), util::make_new_path(path))
+ format!(
+ "{}=\"{}\"",
+ util::lib_path_env_var(),
+ util::make_new_path(path)
+ )
}
format!("{} {:?}", lib_path_cmd_prefix(libpath), command)
self.maybe_dump_to_stdout(out, err);
}
- fn dump_output_file(&self,
- out: &str,
- extension: &str) {
+ fn dump_output_file(&self, out: &str, extension: &str) {
let outfile = self.make_out_name(extension);
- File::create(&outfile).unwrap().write_all(out.as_bytes()).unwrap();
+ File::create(&outfile)
+ .unwrap()
+ .write_all(out.as_bytes())
+ .unwrap();
}
fn make_out_name(&self, extension: &str) -> PathBuf {
let dir = self.config.build_base.join(&self.testpaths.relative_dir);
// Note: The directory `dir` is created during `collect_tests_from_dir`
- dir
- .join(&self.output_testname(&self.testpaths.file))
+ dir.join(&self.output_testname(&self.testpaths.file))
.with_extension(&self.config.stage_id)
}
fn error(&self, err: &str) {
match self.revision {
Some(rev) => println!("\nerror in revision `{}`: {}", rev, err),
- None => println!("\nerror: {}", err)
+ None => println!("\nerror: {}", err),
}
}
fn fatal(&self, err: &str) -> ! {
- self.error(err); panic!();
+ self.error(err);
+ panic!();
}
fn fatal_proc_rec(&self, err: &str, proc_res: &ProcRes) -> ! {
// errors here.
fn try_print_open_handles(&self) {
if !cfg!(windows) {
- return
+ return;
}
if self.config.mode != Incremental {
- return
+ return;
}
let filename = match self.testpaths.file.file_stem() {
fn compile_test_and_save_ir(&self) -> ProcRes {
let aux_dir = self.aux_output_dir_name();
- let output_file = TargetLocation::ThisDirectory(
- self.output_base_name().parent().unwrap().to_path_buf());
+ let output_file =
+ TargetLocation::ThisDirectory(self.output_base_name().parent().unwrap().to_path_buf());
let mut rustc = self.make_compile_args(&self.testpaths.file, output_file);
- rustc.arg("-L").arg(aux_dir)
- .arg("--emit=llvm-ir");
+ rustc.arg("-L").arg(aux_dir).arg("--emit=llvm-ir");
self.compose_and_run_compiler(rustc, None)
}
fn check_ir_with_filecheck(&self) -> ProcRes {
let irfile = self.output_base_name().with_extension("ll");
let mut filecheck = Command::new(self.config.llvm_filecheck.as_ref().unwrap());
- filecheck.arg("--input-file").arg(irfile)
+ filecheck
+ .arg("--input-file")
+ .arg(irfile)
.arg(&self.testpaths.file);
self.compose_and_run(filecheck, "", None, None)
}
}
}
- fn get_lines<P: AsRef<Path>>(&self, path: &P,
- mut other_files: Option<&mut Vec<String>>) -> Vec<usize> {
- let mut file = fs::File::open(path)
- .expect("markdown_test_output_check_entry File::open failed");
+ fn get_lines<P: AsRef<Path>>(
+ &self,
+ path: &P,
+ mut other_files: Option<&mut Vec<String>>,
+ ) -> Vec<usize> {
+ let mut file =
+ fs::File::open(path).expect("markdown_test_output_check_entry File::open failed");
let mut content = String::new();
file.read_to_string(&mut content)
.expect("markdown_test_output_check_entry read_to_string failed");
let mut ignore = false;
- content.lines()
- .enumerate()
- .filter_map(|(line_nb, line)| {
- if (line.trim_left().starts_with("pub mod ") ||
- line.trim_left().starts_with("mod ")) &&
- line.ends_with(';') {
- if let Some(ref mut other_files) = other_files {
- other_files.push(line.rsplit("mod ")
- .next()
- .unwrap()
- .replace(";", ""));
- }
- None
- } else {
- let sline = line.split("///").last().unwrap_or("");
- let line = sline.trim_left();
- if line.starts_with("```") {
- if ignore {
- ignore = false;
- None
- } else {
- ignore = true;
- Some(line_nb + 1)
- }
- } else {
- None
- }
- }
- })
- .collect()
+ content
+ .lines()
+ .enumerate()
+ .filter_map(|(line_nb, line)| {
+ if (line.trim_left().starts_with("pub mod ")
+ || line.trim_left().starts_with("mod "))
+ && line.ends_with(';')
+ {
+ if let Some(ref mut other_files) = other_files {
+ other_files.push(line.rsplit("mod ").next().unwrap().replace(";", ""));
+ }
+ None
+ } else {
+ let sline = line.split("///").last().unwrap_or("");
+ let line = sline.trim_left();
+ if line.starts_with("```") {
+ if ignore {
+ ignore = false;
+ None
+ } else {
+ ignore = true;
+ Some(line_nb + 1)
+ }
+ } else {
+ None
+ }
+ }
+ })
+ .collect()
}
fn check_rustdoc_test_option(&self, res: ProcRes) {
let mut other_files = Vec::new();
let mut files: HashMap<String, Vec<usize>> = HashMap::new();
let cwd = env::current_dir().unwrap();
- files.insert(self.testpaths.file.strip_prefix(&cwd)
- .unwrap_or(&self.testpaths.file)
- .to_str()
- .unwrap()
- .replace('\\', "/"),
- self.get_lines(&self.testpaths.file, Some(&mut other_files)));
+ files.insert(
+ self.testpaths
+ .file
+ .strip_prefix(&cwd)
+ .unwrap_or(&self.testpaths.file)
+ .to_str()
+ .unwrap()
+ .replace('\\', "/"),
+ self.get_lines(&self.testpaths.file, Some(&mut other_files)),
+ );
for other_file in other_files {
let mut path = self.testpaths.file.clone();
path.set_file_name(&format!("{}.rs", other_file));
- files.insert(path.strip_prefix(&cwd)
- .unwrap_or(&path)
- .to_str()
- .unwrap()
- .replace('\\', "/"),
- self.get_lines(&path, None));
+ files.insert(
+ path.strip_prefix(&cwd)
+ .unwrap_or(&path)
+ .to_str()
+ .unwrap()
+ .replace('\\', "/"),
+ self.get_lines(&path, None),
+ );
}
let mut tested = 0;
- for _ in res.stdout.split('\n')
- .filter(|s| s.starts_with("test "))
- .inspect(|s| {
- let tmp: Vec<&str> = s.split(" - ").collect();
- if tmp.len() == 2 {
- let path = tmp[0].rsplit("test ").next().unwrap();
- if let Some(ref mut v) = files.get_mut(
- &path.replace('\\', "/")) {
- tested += 1;
- let mut iter = tmp[1].split("(line ");
- iter.next();
- let line = iter.next()
- .unwrap_or(")")
- .split(')')
- .next()
- .unwrap_or("0")
- .parse()
- .unwrap_or(0);
- if let Ok(pos) = v.binary_search(&line) {
- v.remove(pos);
- } else {
- self.fatal_proc_rec(
- &format!("Not found doc test: \"{}\" in \"{}\":{:?}",
- s, path, v),
- &res);
- }
- }
- }
- }) {}
+ for _ in res.stdout
+ .split('\n')
+ .filter(|s| s.starts_with("test "))
+ .inspect(|s| {
+ let tmp: Vec<&str> = s.split(" - ").collect();
+ if tmp.len() == 2 {
+ let path = tmp[0].rsplit("test ").next().unwrap();
+ if let Some(ref mut v) = files.get_mut(&path.replace('\\', "/")) {
+ tested += 1;
+ let mut iter = tmp[1].split("(line ");
+ iter.next();
+ let line = iter.next()
+ .unwrap_or(")")
+ .split(')')
+ .next()
+ .unwrap_or("0")
+ .parse()
+ .unwrap_or(0);
+ if let Ok(pos) = v.binary_search(&line) {
+ v.remove(pos);
+ } else {
+ self.fatal_proc_rec(
+ &format!("Not found doc test: \"{}\" in \"{}\":{:?}", s, path, v),
+ &res,
+ );
+ }
+ }
+ }
+ }) {}
if tested == 0 {
self.fatal_proc_rec(&format!("No test has been found... {:?}", files), &res);
} else {
for (entry, v) in &files {
if !v.is_empty() {
- self.fatal_proc_rec(&format!("Not found test at line{} \"{}\":{:?}",
- if v.len() > 1 { "s" } else { "" }, entry, v),
- &res);
+ self.fatal_proc_rec(
+ &format!(
+ "Not found test at line{} \"{}\":{:?}",
+ if v.len() > 1 { "s" } else { "" },
+ entry,
+ v
+ ),
+ &res,
+ );
}
}
}
let mut wrong_cgus = Vec::new();
for expected_item in &expected {
- let actual_item_with_same_name = actual.iter()
- .find(|ti| ti.name == expected_item.name);
+ let actual_item_with_same_name = actual.iter().find(|ti| ti.name == expected_item.name);
if let Some(actual_item) = actual_item_with_same_name {
if !expected_item.codegen_units.is_empty() &&
// Also check for codegen units
- expected_item.codegen_units != actual_item.codegen_units {
+ expected_item.codegen_units != actual_item.codegen_units
+ {
wrong_cgus.push((expected_item.clone(), actual_item.clone()));
}
} else {
}
}
- let unexpected: Vec<_> =
- actual.iter()
- .filter(|acgu| !expected.iter().any(|ecgu| acgu.name == ecgu.name))
- .map(|acgu| acgu.string.clone())
- .collect();
+ let unexpected: Vec<_> = actual
+ .iter()
+ .filter(|acgu| !expected.iter().any(|ecgu| acgu.name == ecgu.name))
+ .map(|acgu| acgu.string.clone())
+ .collect();
if !missing.is_empty() {
missing.sort();
for &(ref expected_item, ref actual_item) in &wrong_cgus {
println!("{}", expected_item.name);
- println!(" expected: {}", codegen_units_to_str(&expected_item.codegen_units));
- println!(" actual: {}", codegen_units_to_str(&actual_item.codegen_units));
+ println!(
+ " expected: {}",
+ codegen_units_to_str(&expected_item.codegen_units)
+ );
+ println!(
+ " actual: {}",
+ codegen_units_to_str(&actual_item.codegen_units)
+ );
println!("");
}
}
- if !(missing.is_empty() && unexpected.is_empty() && wrong_cgus.is_empty())
- {
+ if !(missing.is_empty() && unexpected.is_empty() && wrong_cgus.is_empty()) {
panic!();
}
let full_string = format!("{}{}", PREFIX, s.trim().to_owned());
let parts: Vec<&str> = s.split(CGU_MARKER)
- .map(str::trim)
- .filter(|s| !s.is_empty())
- .collect();
+ .map(str::trim)
+ .filter(|s| !s.is_empty())
+ .collect();
let name = parts[0].trim();
let cgus = if parts.len() > 1 {
let cgus_str = parts[1];
- cgus_str.split(' ')
- .map(str::trim)
- .filter(|s| !s.is_empty())
- .map(str::to_owned)
- .collect()
- }
- else {
+ cgus_str
+ .split(' ')
+ .map(str::trim)
+ .filter(|s| !s.is_empty())
+ .map(str::to_owned)
+ .collect()
+ } else {
HashSet::new()
};
}
}
- fn codegen_units_to_str(cgus: &HashSet<String>) -> String
- {
+ fn codegen_units_to_str(cgus: &HashSet<String>) -> String {
let mut cgus: Vec<_> = cgus.iter().collect();
cgus.sort();
fs::create_dir_all(&incremental_dir).unwrap();
if self.config.verbose {
- print!("init_incremental_test: incremental_dir={}", incremental_dir.display());
+ print!(
+ "init_incremental_test: incremental_dir={}",
+ incremental_dir.display()
+ );
}
}
// FIXME -- use non-incremental mode as an oracle? That doesn't apply
// to #[rustc_dirty] and clean tests I guess
- let revision = self.revision.expect("incremental tests require a list of revisions");
+ let revision = self.revision
+ .expect("incremental tests require a list of revisions");
// Incremental workproduct directory should have already been created.
let incremental_dir = self.incremental_dir();
- assert!(incremental_dir.exists(), "init_incremental_test failed to create incremental dir");
+ assert!(
+ incremental_dir.exists(),
+ "init_incremental_test failed to create incremental dir"
+ );
// Add an extra flag pointing at the incremental directory.
let mut revision_props = self.props.clone();
};
if self.config.verbose {
- print!("revision={:?} revision_props={:#?}", revision, revision_props);
+ print!(
+ "revision={:?} revision_props={:#?}",
+ revision,
+ revision_props
+ );
}
if revision.starts_with("rpass") {
} else if revision.starts_with("cfail") {
revision_cx.run_cfail_test();
} else {
- revision_cx.fatal(
- "revision name must begin with rpass, rfail, or cfail");
+ revision_cx.fatal("revision name must begin with rpass, rfail, or cfail");
}
}
fn run_rmake_test(&self) {
// FIXME(#11094): we should fix these tests
if self.config.host != self.config.target {
- return
+ return;
}
let cwd = env::current_dir().unwrap();
- let src_root = self.config.src_base.parent().unwrap()
- .parent().unwrap()
- .parent().unwrap();
+ let src_root = self.config
+ .src_base
+ .parent()
+ .unwrap()
+ .parent()
+ .unwrap()
+ .parent()
+ .unwrap();
let src_root = cwd.join(&src_root);
let tmpdir = cwd.join(self.output_base_name());
create_dir_all(&tmpdir).unwrap();
let host = &self.config.host;
- let make = if host.contains("bitrig") || host.contains("dragonfly") ||
- host.contains("freebsd") || host.contains("netbsd") ||
- host.contains("openbsd") {
+ let make = if host.contains("bitrig") || host.contains("dragonfly")
+ || host.contains("freebsd") || host.contains("netbsd")
+ || host.contains("openbsd")
+ {
"gmake"
} else {
"make"
let mut cmd = Command::new(make);
cmd.current_dir(&self.testpaths.file)
- .stdout(Stdio::piped())
- .stderr(Stdio::piped())
- .env("TARGET", &self.config.target)
- .env("PYTHON", &self.config.docck_python)
- .env("S", src_root)
- .env("RUST_BUILD_STAGE", &self.config.stage_id)
- .env("RUSTC", cwd.join(&self.config.rustc_path))
- .env("RUSTDOC",
- cwd.join(&self.config.rustdoc_path.as_ref().expect("--rustdoc-path passed")))
- .env("TMPDIR", &tmpdir)
- .env("LD_LIB_PATH_ENVVAR", dylib_env_var())
- .env("HOST_RPATH_DIR", cwd.join(&self.config.compile_lib_path))
- .env("TARGET_RPATH_DIR", cwd.join(&self.config.run_lib_path))
- .env("LLVM_COMPONENTS", &self.config.llvm_components)
- .env("LLVM_CXXFLAGS", &self.config.llvm_cxxflags);
+ .stdout(Stdio::piped())
+ .stderr(Stdio::piped())
+ .env("TARGET", &self.config.target)
+ .env("PYTHON", &self.config.docck_python)
+ .env("S", src_root)
+ .env("RUST_BUILD_STAGE", &self.config.stage_id)
+ .env("RUSTC", cwd.join(&self.config.rustc_path))
+ .env(
+ "RUSTDOC",
+ cwd.join(&self.config
+ .rustdoc_path
+ .as_ref()
+ .expect("--rustdoc-path passed")),
+ )
+ .env("TMPDIR", &tmpdir)
+ .env("LD_LIB_PATH_ENVVAR", dylib_env_var())
+ .env("HOST_RPATH_DIR", cwd.join(&self.config.compile_lib_path))
+ .env("TARGET_RPATH_DIR", cwd.join(&self.config.run_lib_path))
+ .env("LLVM_COMPONENTS", &self.config.llvm_components)
+ .env("LLVM_CXXFLAGS", &self.config.llvm_cxxflags);
if let Some(ref linker) = self.config.linker {
cmd.env("RUSTC_LINKER", linker);
// MSYS doesn't like passing flags of the form `/foo` as it thinks it's
// a path and instead passes `C:\msys64\foo`, so convert all
// `/`-arguments to MSVC here to `-` arguments.
- let cflags = self.config.cflags.split(' ').map(|s| s.replace("/", "-"))
- .collect::<Vec<_>>().join(" ");
+ let cflags = self.config
+ .cflags
+ .split(' ')
+ .map(|s| s.replace("/", "-"))
+ .collect::<Vec<_>>()
+ .join(" ");
cmd.env("IS_MSVC", "1")
- .env("IS_WINDOWS", "1")
- .env("MSVC_LIB", format!("'{}' -nologo", lib.display()))
- .env("CC", format!("'{}' {}", self.config.cc, cflags))
- .env("CXX", &self.config.cxx);
+ .env("IS_WINDOWS", "1")
+ .env("MSVC_LIB", format!("'{}' -nologo", lib.display()))
+ .env("CC", format!("'{}' {}", self.config.cc, cflags))
+ .env("CXX", &self.config.cxx);
} else {
cmd.env("CC", format!("{} {}", self.config.cc, self.config.cflags))
- .env("CXX", format!("{} {}", self.config.cxx, self.config.cflags))
- .env("AR", &self.config.ar);
+ .env("CXX", format!("{} {}", self.config.cxx, self.config.cflags))
+ .env("AR", &self.config.ar);
if self.config.target.contains("windows") {
cmd.env("IS_WINDOWS", "1");
}
}
- let output = cmd.spawn().and_then(read2_abbreviated).expect("failed to spawn `make`");
+ let output = cmd.spawn()
+ .and_then(read2_abbreviated)
+ .expect("failed to spawn `make`");
if !output.status.success() {
let res = ProcRes {
status: output.status,
// if the user specified a format in the ui test
// print the output to the stderr file, otherwise extract
// the rendered error messages from json and print them
- let explicit = self.props.compile_flags.iter().any(|s| s.contains("--error-format"));
+ let explicit = self.props
+ .compile_flags
+ .iter()
+ .any(|s| s.contains("--error-format"));
let proc_res = self.compile_test();
json::extract_rendered(&proc_res.stderr, &proc_res)
};
- let normalized_stderr =
- self.normalize_output(&stderr, &self.props.normalize_stderr);
+ let normalized_stderr = self.normalize_output(&stderr, &self.props.normalize_stderr);
let mut errors = 0;
errors += self.compare_output("stdout", &normalized_stdout, &expected_stdout);
if errors > 0 {
println!("To update references, run this command from build directory:");
- 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());
- self.fatal_proc_rec(&format!("{} errors occurred comparing output.", errors),
- &proc_res);
+ 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()
+ );
+ self.fatal_proc_rec(
+ &format!("{} errors occurred comparing output.", errors),
+ &proc_res,
+ );
}
let expected_errors = errors::load_errors(&self.testpaths.file, self.revision);
fn check_mir_dump(&self) {
let mut test_file_contents = String::new();
- fs::File::open(self.testpaths.file.clone()).unwrap()
- .read_to_string(&mut test_file_contents)
- .unwrap();
- if let Some(idx) = test_file_contents.find("// END RUST SOURCE") {
+ fs::File::open(self.testpaths.file.clone())
+ .unwrap()
+ .read_to_string(&mut test_file_contents)
+ .unwrap();
+ if let Some(idx) = test_file_contents.find("// END RUST SOURCE") {
let (_, tests_text) = test_file_contents.split_at(idx + "// END_RUST SOURCE".len());
let tests_text_str = String::from(tests_text);
- let mut curr_test : Option<&str> = None;
+ let mut curr_test: Option<&str> = None;
let mut curr_test_contents = vec![ExpectedLine::Elision];
for l in tests_text_str.lines() {
debug!("line: {:?}", l);
let output_time = t(output_file);
let source_time = t(source_file);
if source_time > output_time {
- debug!("source file time: {:?} output file time: {:?}", source_time, output_time);
- panic!("test source file `{}` is newer than potentially stale output file `{}`.",
- source_file.display(), test_name);
+ debug!(
+ "source file time: {:?} output file time: {:?}",
+ source_time,
+ output_time
+ );
+ panic!(
+ "test source file `{}` is newer than potentially stale output file `{}`.",
+ source_file.display(),
+ test_name
+ );
}
}
debug!("comparing the contests of: {:?}", output_file);
debug!("with: {:?}", expected_content);
if !output_file.exists() {
- panic!("Output file `{}` from test does not exist",
- output_file.into_os_string().to_string_lossy());
+ panic!(
+ "Output file `{}` from test does not exist",
+ output_file.into_os_string().to_string_lossy()
+ );
}
self.check_mir_test_timestamp(test_name, &output_file);
let mut dumped_string = String::new();
dumped_file.read_to_string(&mut dumped_string).unwrap();
let mut dumped_lines = dumped_string.lines().filter(|l| !l.is_empty());
- let mut expected_lines = expected_content.iter().filter(|&l| {
- if let &ExpectedLine::Text(l) = l {
- !l.is_empty()
- } else {
- true
- }
- }).peekable();
+ let mut expected_lines = expected_content
+ .iter()
+ .filter(|&l| {
+ if let &ExpectedLine::Text(l) = l {
+ !l.is_empty()
+ } else {
+ true
+ }
+ })
+ .peekable();
let compare = |expected_line, dumped_line| {
let e_norm = normalize_mir_line(expected_line);
};
let error = |expected_line, extra_msg| {
- let normalize_all = dumped_string.lines()
- .map(nocomment_mir_line)
- .filter(|l| !l.is_empty())
- .collect::<Vec<_>>()
- .join("\n");
+ let normalize_all = dumped_string
+ .lines()
+ .map(nocomment_mir_line)
+ .filter(|l| !l.is_empty())
+ .collect::<Vec<_>>()
+ .join("\n");
let f = |l: &ExpectedLine<_>| match l {
&ExpectedLine::Elision => "... (elided)".into(),
- &ExpectedLine::Text(t) => t
+ &ExpectedLine::Text(t) => t,
};
- let expected_content = expected_content.iter()
- .map(|l| f(l))
- .collect::<Vec<_>>()
- .join("\n");
- panic!("Did not find expected line, error: {}\n\
- Actual Line: {:?}\n\
- Expected:\n{}\n\
- Actual:\n{}",
- extra_msg,
- expected_line,
- expected_content,
- normalize_all);
+ let expected_content = expected_content
+ .iter()
+ .map(|l| f(l))
+ .collect::<Vec<_>>()
+ .join("\n");
+ panic!(
+ "Did not find expected line, error: {}\n\
+ Actual Line: {:?}\n\
+ Expected:\n{}\n\
+ Actual:\n{}",
+ extra_msg,
+ expected_line,
+ expected_content,
+ normalize_all
+ );
};
// We expect each non-empty line to appear consecutively, non-consecutive lines
if !compare(expected_line, dumped_line) {
error!("{:?}", start_block_line);
- error(expected_line,
- format!("Mismatch in lines\nCurrnt block: {}\nExpected Line: {:?}",
- start_block_line.unwrap_or("None"), dumped_line));
+ error(
+ expected_line,
+ format!(
+ "Mismatch in lines\nCurrnt block: {}\nExpected Line: {:?}",
+ start_block_line.unwrap_or("None"),
+ dumped_line
+ ),
+ );
}
- },
+ }
Some(&ExpectedLine::Elision) => {
// skip any number of elisions in a row.
while let Some(&&ExpectedLine::Elision) = expected_lines.peek() {
error(expected_line, "ran out of mir dump to match against".into());
}
}
- },
- None => {},
+ }
+ None => {}
}
}
}
fn normalize_output(&self, output: &str, custom_rules: &[(String, String)]) -> String {
let parent_dir = self.testpaths.file.parent().unwrap();
let cflags = self.props.compile_flags.join(" ");
- let json = cflags.contains("--error-format json") ||
- cflags.contains("--error-format pretty-json") ||
- cflags.contains("--error-format=json") ||
- cflags.contains("--error-format=pretty-json");
+ let json = cflags.contains("--error-format json")
+ || cflags.contains("--error-format pretty-json")
+ || cflags.contains("--error-format=json")
+ || cflags.contains("--error-format=pretty-json");
let parent_dir_str = if json {
parent_dir.display().to_string().replace("\\", "\\\\")
} else {
let mut result = String::new();
match File::open(path).and_then(|mut f| f.read_to_string(&mut result)) {
Ok(_) => result,
- Err(e) => {
- self.fatal(&format!("failed to load expected output from `{}`: {}",
- path.display(), e))
- }
+ Err(e) => self.fatal(&format!(
+ "failed to load expected output from `{}`: {}",
+ path.display(),
+ e
+ )),
}
}
for diff in diff::lines(expected, actual) {
match diff {
- diff::Result::Left(l) => println!("-{}", l),
+ diff::Result::Left(l) => println!("-{}", l),
diff::Result::Both(l, _) => println!(" {}", l),
- diff::Result::Right(r) => println!("+{}", r),
+ diff::Result::Right(r) => println!("+{}", r),
}
}
let output_file = self.output_base_name().with_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 `{}`: {}",
- kind, output_file.display(), e))
- }
+ 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);
if let Some(e) = err {
println!("\nerror: {}", e);
}
- print!("\
- status: {}\n\
- command: {}\n\
- stdout:\n\
- ------------------------------------------\n\
- {}\n\
- ------------------------------------------\n\
- stderr:\n\
- ------------------------------------------\n\
- {}\n\
- ------------------------------------------\n\
- \n",
- self.status, self.cmdline, self.stdout,
- self.stderr);
+ print!(
+ "\
+ status: {}\n\
+ command: {}\n\
+ stdout:\n\
+ ------------------------------------------\n\
+ {}\n\
+ ------------------------------------------\n\
+ stderr:\n\
+ ------------------------------------------\n\
+ {}\n\
+ ------------------------------------------\n\
+ \n",
+ self.status,
+ self.cmdline,
+ self.stdout,
+ self.stderr
+ );
panic!();
}
}
#[derive(Clone, PartialEq, Eq)]
enum ExpectedLine<T: AsRef<str>> {
Elision,
- Text(T)
+ Text(T),
}
impl<T> fmt::Debug for ExpectedLine<T>
where
- T: AsRef<str> + fmt::Debug
+ T: AsRef<str> + fmt::Debug,
{
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
if let &ExpectedLine::Text(ref t) = self {
head: Vec<u8>,
skipped: usize,
tail: Box<[u8]>,
- }
+ },
}
impl ProcOutput {
let tail = bytes.split_off(new_len - TAIL_LEN).into_boxed_slice();
let head = replace(bytes, Vec::new());
let skipped = new_len - HEAD_LEN - TAIL_LEN;
- ProcOutput::Abbreviated { head, skipped, tail }
+ ProcOutput::Abbreviated {
+ head,
+ skipped,
+ tail,
+ }
}
- ProcOutput::Abbreviated { ref mut skipped, ref mut tail, .. } => {
+ ProcOutput::Abbreviated {
+ ref mut skipped,
+ ref mut tail,
+ ..
+ } => {
*skipped += data.len();
if data.len() <= TAIL_LEN {
tail[..data.len()].copy_from_slice(data);
fn into_bytes(self) -> Vec<u8> {
match self {
ProcOutput::Full(bytes) => bytes,
- ProcOutput::Abbreviated { mut head, skipped, tail } => {
+ ProcOutput::Abbreviated {
+ mut head,
+ skipped,
+ tail,
+ } => {
write!(&mut head, "\n\n<<<<<< SKIPPED {} BYTES >>>>>>\n\n", skipped).unwrap();
head.extend_from_slice(&tail);
head
let mut stderr = ProcOutput::Full(Vec::new());
drop(child.stdin.take());
- read2(child.stdout.take().unwrap(), child.stderr.take().unwrap(), &mut |is_stdout, data, _| {
- if is_stdout { &mut stdout } else { &mut stderr }.extend(data);
- data.clear();
- })?;
+ read2(
+ child.stdout.take().unwrap(),
+ child.stderr.take().unwrap(),
+ &mut |is_stdout, data, _| {
+ if is_stdout { &mut stdout } else { &mut stderr }.extend(data);
+ data.clear();
+ },
+ )?;
let status = child.wait()?;
Ok(Output {