2016-03-07 23:15:55 -08:00
|
|
|
// 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.
|
|
|
|
|
2016-11-16 12:31:19 -08:00
|
|
|
//! Implementation of the test-related targets of the build system.
|
2016-05-02 15:16:15 -07:00
|
|
|
//!
|
|
|
|
//! This file implements the various regression test suites that we execute on
|
|
|
|
//! our CI.
|
|
|
|
|
2016-10-21 13:18:09 -07:00
|
|
|
use std::collections::HashSet;
|
2016-04-29 14:23:15 -07:00
|
|
|
use std::env;
|
2017-07-01 06:58:54 +12:00
|
|
|
use std::ffi::OsString;
|
2017-06-26 10:23:50 -06:00
|
|
|
use std::iter;
|
2016-11-25 22:13:59 +01:00
|
|
|
use std::fmt;
|
2017-06-04 17:55:50 -06:00
|
|
|
use std::fs::{self, File};
|
2016-04-14 18:00:35 -07:00
|
|
|
use std::path::{PathBuf, Path};
|
|
|
|
use std::process::Command;
|
2017-06-04 17:55:50 -06:00
|
|
|
use std::io::Read;
|
2016-04-14 14:27:51 -07:00
|
|
|
|
2017-06-26 10:23:50 -06:00
|
|
|
use build_helper::{self, output};
|
2016-04-14 15:51:03 -07:00
|
|
|
|
2017-07-17 09:32:08 -07:00
|
|
|
use builder::{Kind, RunConfig, ShouldRun, Builder, Compiler, Step};
|
|
|
|
use cache::{INTERNER, Interned};
|
2017-07-04 19:41:43 -06:00
|
|
|
use compile;
|
2017-07-17 09:32:08 -07:00
|
|
|
use dist;
|
2017-07-04 19:41:43 -06:00
|
|
|
use native;
|
2017-07-12 10:12:47 -06:00
|
|
|
use tool::{self, Tool};
|
2017-07-17 09:32:08 -07:00
|
|
|
use util::{self, dylib_path, dylib_path_var};
|
|
|
|
use {Build, Mode};
|
2016-06-28 13:31:30 -07:00
|
|
|
|
2017-06-26 10:23:50 -06:00
|
|
|
const ADB_TEST_DIR: &str = "/data/tmp/work";
|
2016-03-07 23:15:55 -08:00
|
|
|
|
2016-11-25 22:13:59 +01:00
|
|
|
/// The two modes of the test runner; tests or benchmarks.
|
2017-07-13 18:48:44 -06:00
|
|
|
#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
|
2016-11-25 22:13:59 +01:00
|
|
|
pub enum TestKind {
|
|
|
|
/// Run `cargo test`
|
|
|
|
Test,
|
|
|
|
/// Run `cargo bench`
|
|
|
|
Bench,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl TestKind {
|
|
|
|
// Return the cargo subcommand for this test kind
|
|
|
|
fn subcommand(self) -> &'static str {
|
|
|
|
match self {
|
|
|
|
TestKind::Test => "test",
|
|
|
|
TestKind::Bench => "bench",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Display for TestKind {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
f.write_str(match *self {
|
|
|
|
TestKind::Test => "Testing",
|
|
|
|
TestKind::Bench => "Benchmarking",
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-02 09:27:44 -07:00
|
|
|
fn try_run(build: &Build, cmd: &mut Command) {
|
2017-06-27 13:37:24 -06:00
|
|
|
if !build.fail_fast {
|
2017-06-02 09:27:44 -07:00
|
|
|
if !build.try_run(cmd) {
|
|
|
|
let failures = build.delayed_failures.get();
|
|
|
|
build.delayed_failures.set(failures + 1);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
build.run(cmd);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn try_run_quiet(build: &Build, cmd: &mut Command) {
|
2017-06-27 13:37:24 -06:00
|
|
|
if !build.fail_fast {
|
2017-06-02 09:27:44 -07:00
|
|
|
if !build.try_run_quiet(cmd) {
|
|
|
|
let failures = build.delayed_failures.get();
|
|
|
|
build.delayed_failures.set(failures + 1);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
build.run_quiet(cmd);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-13 18:48:44 -06:00
|
|
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
|
|
|
pub struct Linkcheck {
|
|
|
|
host: Interned<String>,
|
2017-07-04 19:41:43 -06:00
|
|
|
}
|
|
|
|
|
2017-07-13 18:48:44 -06:00
|
|
|
impl Step for Linkcheck {
|
2017-07-04 19:41:43 -06:00
|
|
|
type Output = ();
|
2017-07-05 06:41:27 -06:00
|
|
|
const ONLY_HOSTS: bool = true;
|
|
|
|
const DEFAULT: bool = true;
|
2017-07-04 19:41:43 -06:00
|
|
|
|
|
|
|
/// Runs the `linkchecker` tool as compiled in `stage` by the `host` compiler.
|
|
|
|
///
|
|
|
|
/// This tool in `src/tools` will verify the validity of all our links in the
|
|
|
|
/// documentation to ensure we don't have a bunch of dead ones.
|
|
|
|
fn run(self, builder: &Builder) {
|
|
|
|
let build = builder.build;
|
|
|
|
let host = self.host;
|
|
|
|
|
|
|
|
println!("Linkcheck ({})", host);
|
2017-07-05 06:41:27 -06:00
|
|
|
|
|
|
|
builder.default_doc(None);
|
2017-07-04 19:41:43 -06:00
|
|
|
|
|
|
|
let _time = util::timeit();
|
2017-07-05 06:41:27 -06:00
|
|
|
try_run(build, builder.tool_cmd(Tool::Linkchecker)
|
2017-07-04 19:41:43 -06:00
|
|
|
.arg(build.out.join(host).join("doc")));
|
|
|
|
}
|
2017-07-05 06:41:27 -06:00
|
|
|
|
2017-07-18 18:03:38 -06:00
|
|
|
fn should_run(run: ShouldRun) -> ShouldRun {
|
2017-07-20 17:24:11 -06:00
|
|
|
let builder = run.builder;
|
|
|
|
run.path("src/tools/linkchecker").default_condition(builder.build.config.docs)
|
2017-07-05 06:41:27 -06:00
|
|
|
}
|
|
|
|
|
2017-07-20 17:51:07 -06:00
|
|
|
fn make_run(run: RunConfig) {
|
|
|
|
run.builder.ensure(Linkcheck { host: run.host });
|
2017-07-05 06:41:27 -06:00
|
|
|
}
|
2016-03-07 23:15:55 -08:00
|
|
|
}
|
2016-03-18 20:54:31 +00:00
|
|
|
|
2017-07-13 18:48:44 -06:00
|
|
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
|
|
|
pub struct Cargotest {
|
2017-07-04 19:41:43 -06:00
|
|
|
stage: u32,
|
2017-07-13 18:48:44 -06:00
|
|
|
host: Interned<String>,
|
2017-07-04 19:41:43 -06:00
|
|
|
}
|
2016-04-14 14:27:51 -07:00
|
|
|
|
2017-07-13 18:48:44 -06:00
|
|
|
impl Step for Cargotest {
|
2017-07-04 19:41:43 -06:00
|
|
|
type Output = ();
|
2017-07-05 06:41:27 -06:00
|
|
|
const ONLY_HOSTS: bool = true;
|
2017-07-04 19:41:43 -06:00
|
|
|
|
2017-07-18 18:03:38 -06:00
|
|
|
fn should_run(run: ShouldRun) -> ShouldRun {
|
|
|
|
run.path("src/tools/cargotest")
|
2017-07-12 10:12:47 -06:00
|
|
|
}
|
|
|
|
|
2017-07-20 17:51:07 -06:00
|
|
|
fn make_run(run: RunConfig) {
|
|
|
|
run.builder.ensure(Cargotest {
|
|
|
|
stage: run.builder.top_stage,
|
|
|
|
host: run.host,
|
2017-07-12 10:12:47 -06:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2017-07-04 19:41:43 -06:00
|
|
|
/// Runs the `cargotest` tool as compiled in `stage` by the `host` compiler.
|
|
|
|
///
|
|
|
|
/// This tool in `src/tools` will check out a few Rust projects and run `cargo
|
|
|
|
/// test` to ensure that we don't regress the test suites there.
|
|
|
|
fn run(self, builder: &Builder) {
|
|
|
|
let build = builder.build;
|
2017-07-05 10:46:41 -06:00
|
|
|
let compiler = builder.compiler(self.stage, self.host);
|
2017-07-05 06:41:27 -06:00
|
|
|
builder.ensure(compile::Rustc { compiler, target: compiler.host });
|
2017-07-04 19:41:43 -06:00
|
|
|
|
|
|
|
// Note that this is a short, cryptic, and not scoped directory name. This
|
|
|
|
// is currently to minimize the length of path on Windows where we otherwise
|
|
|
|
// quickly run into path name limit constraints.
|
|
|
|
let out_dir = build.out.join("ct");
|
|
|
|
t!(fs::create_dir_all(&out_dir));
|
|
|
|
|
|
|
|
let _time = util::timeit();
|
2017-07-05 06:41:27 -06:00
|
|
|
let mut cmd = builder.tool_cmd(Tool::CargoTest);
|
2017-07-04 19:41:43 -06:00
|
|
|
try_run(build, cmd.arg(&build.initial_cargo)
|
|
|
|
.arg(&out_dir)
|
2017-07-05 11:21:33 -06:00
|
|
|
.env("RUSTC", builder.rustc(compiler))
|
|
|
|
.env("RUSTDOC", builder.rustdoc(compiler)));
|
2017-07-04 19:41:43 -06:00
|
|
|
}
|
2017-04-17 17:24:05 -07:00
|
|
|
}
|
|
|
|
|
2017-07-13 18:48:44 -06:00
|
|
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
|
|
|
pub struct Cargo {
|
2017-07-04 19:41:43 -06:00
|
|
|
stage: u32,
|
2017-07-13 18:48:44 -06:00
|
|
|
host: Interned<String>,
|
2017-07-04 19:41:43 -06:00
|
|
|
}
|
|
|
|
|
2017-07-13 18:48:44 -06:00
|
|
|
impl Step for Cargo {
|
2017-07-04 19:41:43 -06:00
|
|
|
type Output = ();
|
2017-07-05 06:41:27 -06:00
|
|
|
const ONLY_HOSTS: bool = true;
|
|
|
|
|
2017-07-18 18:03:38 -06:00
|
|
|
fn should_run(run: ShouldRun) -> ShouldRun {
|
|
|
|
run.path("src/tools/cargo")
|
2017-07-05 06:41:27 -06:00
|
|
|
}
|
|
|
|
|
2017-07-20 17:51:07 -06:00
|
|
|
fn make_run(run: RunConfig) {
|
|
|
|
run.builder.ensure(Cargo {
|
|
|
|
stage: run.builder.top_stage,
|
|
|
|
host: run.target,
|
2017-07-05 06:41:27 -06:00
|
|
|
});
|
|
|
|
}
|
2017-07-04 19:41:43 -06:00
|
|
|
|
|
|
|
/// Runs `cargo test` for `cargo` packaged with Rust.
|
|
|
|
fn run(self, builder: &Builder) {
|
|
|
|
let build = builder.build;
|
2017-07-05 06:41:27 -06:00
|
|
|
let compiler = builder.compiler(self.stage, self.host);
|
2017-07-04 19:41:43 -06:00
|
|
|
|
2017-07-22 19:29:08 -06:00
|
|
|
builder.ensure(tool::Cargo { compiler, target: self.host });
|
2017-07-05 11:21:33 -06:00
|
|
|
let mut cargo = builder.cargo(compiler, Mode::Tool, self.host, "test");
|
2017-07-04 19:41:43 -06:00
|
|
|
cargo.arg("--manifest-path").arg(build.src.join("src/tools/cargo/Cargo.toml"));
|
|
|
|
if !build.fail_fast {
|
|
|
|
cargo.arg("--no-fail-fast");
|
|
|
|
}
|
2017-04-17 17:24:05 -07:00
|
|
|
|
2017-07-04 19:41:43 -06:00
|
|
|
// Don't build tests dynamically, just a pain to work with
|
|
|
|
cargo.env("RUSTC_NO_PREFER_DYNAMIC", "1");
|
|
|
|
|
|
|
|
// Don't run cross-compile tests, we may not have cross-compiled libstd libs
|
|
|
|
// available.
|
|
|
|
cargo.env("CFG_DISABLE_CROSS_TESTS", "1");
|
2017-04-17 17:24:05 -07:00
|
|
|
|
2017-07-17 09:52:05 -06:00
|
|
|
try_run(build, cargo.env("PATH", &path_for_cargo(builder, compiler)));
|
2017-07-04 19:41:43 -06:00
|
|
|
}
|
2017-07-01 06:58:54 +12:00
|
|
|
}
|
|
|
|
|
2017-07-17 09:52:05 -06:00
|
|
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
|
|
|
pub struct Rls {
|
2017-07-04 19:41:43 -06:00
|
|
|
stage: u32,
|
2017-07-17 09:52:05 -06:00
|
|
|
host: Interned<String>,
|
2017-07-04 19:41:43 -06:00
|
|
|
}
|
2017-07-01 06:58:54 +12:00
|
|
|
|
2017-07-17 09:52:05 -06:00
|
|
|
impl Step for Rls {
|
2017-07-04 19:41:43 -06:00
|
|
|
type Output = ();
|
2017-07-17 09:52:05 -06:00
|
|
|
const ONLY_HOSTS: bool = true;
|
|
|
|
|
2017-07-18 18:03:38 -06:00
|
|
|
fn should_run(run: ShouldRun) -> ShouldRun {
|
|
|
|
run.path("src/tools/rls")
|
2017-07-17 09:52:05 -06:00
|
|
|
}
|
|
|
|
|
2017-07-20 17:51:07 -06:00
|
|
|
fn make_run(run: RunConfig) {
|
|
|
|
run.builder.ensure(Rls {
|
|
|
|
stage: run.builder.top_stage,
|
|
|
|
host: run.target,
|
2017-07-17 09:52:05 -06:00
|
|
|
});
|
|
|
|
}
|
2017-07-01 06:58:54 +12:00
|
|
|
|
2017-07-04 19:41:43 -06:00
|
|
|
/// Runs `cargo test` for the rls.
|
|
|
|
fn run(self, builder: &Builder) {
|
|
|
|
let build = builder.build;
|
|
|
|
let stage = self.stage;
|
|
|
|
let host = self.host;
|
2017-07-17 09:52:05 -06:00
|
|
|
let compiler = builder.compiler(stage, host);
|
2017-07-01 06:58:54 +12:00
|
|
|
|
2017-07-22 19:29:08 -06:00
|
|
|
builder.ensure(tool::Rls { compiler, target: self.host });
|
2017-07-17 09:52:05 -06:00
|
|
|
let mut cargo = builder.cargo(compiler, Mode::Tool, host, "test");
|
2017-07-04 19:41:43 -06:00
|
|
|
cargo.arg("--manifest-path").arg(build.src.join("src/tools/rls/Cargo.toml"));
|
2017-07-01 06:58:54 +12:00
|
|
|
|
2017-07-04 19:41:43 -06:00
|
|
|
// Don't build tests dynamically, just a pain to work with
|
|
|
|
cargo.env("RUSTC_NO_PREFER_DYNAMIC", "1");
|
|
|
|
|
2017-07-17 09:52:05 -06:00
|
|
|
builder.add_rustc_lib_path(compiler, &mut cargo);
|
2017-07-04 19:41:43 -06:00
|
|
|
|
|
|
|
try_run(build, &mut cargo);
|
|
|
|
}
|
2017-07-01 06:58:54 +12:00
|
|
|
}
|
|
|
|
|
2017-07-17 09:52:05 -06:00
|
|
|
fn path_for_cargo(builder: &Builder, compiler: Compiler) -> OsString {
|
2017-07-01 06:58:54 +12:00
|
|
|
// Configure PATH to find the right rustc. NB. we have to use PATH
|
|
|
|
// and not RUSTC because the Cargo test suite has tests that will
|
|
|
|
// fail if rustc is not spelled `rustc`.
|
2017-07-17 09:52:05 -06:00
|
|
|
let path = builder.sysroot(compiler).join("bin");
|
2017-07-01 06:58:54 +12:00
|
|
|
let old_path = env::var_os("PATH").unwrap_or_default();
|
|
|
|
env::join_paths(iter::once(path).chain(env::split_paths(&old_path))).expect("")
|
2016-03-18 20:54:31 +00:00
|
|
|
}
|
2016-03-29 13:14:52 -07:00
|
|
|
|
2017-07-13 18:48:44 -06:00
|
|
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
|
|
|
pub struct Tidy {
|
|
|
|
host: Interned<String>,
|
2017-07-04 19:41:43 -06:00
|
|
|
}
|
|
|
|
|
2017-07-13 18:48:44 -06:00
|
|
|
impl Step for Tidy {
|
2017-07-04 19:41:43 -06:00
|
|
|
type Output = ();
|
2017-07-05 06:41:27 -06:00
|
|
|
const DEFAULT: bool = true;
|
|
|
|
const ONLY_HOSTS: bool = true;
|
|
|
|
const ONLY_BUILD: bool = true;
|
2017-07-04 19:41:43 -06:00
|
|
|
|
|
|
|
/// Runs the `tidy` tool as compiled in `stage` by the `host` compiler.
|
|
|
|
///
|
|
|
|
/// This tool in `src/tools` checks up on various bits and pieces of style and
|
|
|
|
/// otherwise just implements a few lint-like checks that are specific to the
|
|
|
|
/// compiler itself.
|
|
|
|
fn run(self, builder: &Builder) {
|
|
|
|
let build = builder.build;
|
|
|
|
let host = self.host;
|
|
|
|
|
|
|
|
let _folder = build.fold_output(|| "tidy");
|
|
|
|
println!("tidy check ({})", host);
|
2017-07-05 10:46:41 -06:00
|
|
|
let mut cmd = builder.tool_cmd(Tool::Tidy);
|
2017-07-04 19:41:43 -06:00
|
|
|
cmd.arg(build.src.join("src"));
|
|
|
|
if !build.config.vendor {
|
|
|
|
cmd.arg("--no-vendor");
|
|
|
|
}
|
|
|
|
if build.config.quiet_tests {
|
|
|
|
cmd.arg("--quiet");
|
|
|
|
}
|
|
|
|
try_run(build, &mut cmd);
|
2017-05-22 04:27:47 +08:00
|
|
|
}
|
2017-07-05 06:41:27 -06:00
|
|
|
|
2017-07-18 18:03:38 -06:00
|
|
|
fn should_run(run: ShouldRun) -> ShouldRun {
|
|
|
|
run.path("src/tools/tidy")
|
2017-07-05 06:41:27 -06:00
|
|
|
}
|
|
|
|
|
2017-07-20 17:51:07 -06:00
|
|
|
fn make_run(run: RunConfig) {
|
|
|
|
run.builder.ensure(Tidy {
|
|
|
|
host: run.builder.build.build,
|
2017-07-05 06:41:27 -06:00
|
|
|
});
|
|
|
|
}
|
2016-03-29 13:14:52 -07:00
|
|
|
}
|
2016-04-05 11:34:23 -07:00
|
|
|
|
2017-07-13 18:48:44 -06:00
|
|
|
fn testdir(build: &Build, host: Interned<String>) -> PathBuf {
|
2016-04-05 11:34:23 -07:00
|
|
|
build.out.join(host).join("test")
|
|
|
|
}
|
|
|
|
|
2017-07-13 18:48:44 -06:00
|
|
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
2017-07-07 11:51:57 -06:00
|
|
|
struct Test {
|
|
|
|
path: &'static str,
|
|
|
|
mode: &'static str,
|
|
|
|
suite: &'static str,
|
|
|
|
}
|
|
|
|
|
2017-07-07 12:31:29 -06:00
|
|
|
static DEFAULT_COMPILETESTS: &[Test] = &[
|
|
|
|
Test { path: "src/test/ui", mode: "ui", suite: "ui" },
|
|
|
|
Test { path: "src/test/run-pass", mode: "run-pass", suite: "run-pass" },
|
|
|
|
Test { path: "src/test/compile-fail", mode: "compile-fail", suite: "compile-fail" },
|
|
|
|
Test { path: "src/test/parse-fail", mode: "parse-fail", suite: "parse-fail" },
|
|
|
|
Test { path: "src/test/run-fail", mode: "run-fail", suite: "run-fail" },
|
2017-07-07 11:51:57 -06:00
|
|
|
Test {
|
|
|
|
path: "src/test/run-pass-valgrind",
|
|
|
|
mode: "run-pass-valgrind",
|
|
|
|
suite: "run-pass-valgrind"
|
|
|
|
},
|
2017-07-07 12:31:29 -06:00
|
|
|
Test { path: "src/test/mir-opt", mode: "mir-opt", suite: "mir-opt" },
|
|
|
|
Test { path: "src/test/codegen", mode: "codegen", suite: "codegen" },
|
|
|
|
Test { path: "src/test/codegen-units", mode: "codegen-units", suite: "codegen-units" },
|
|
|
|
Test { path: "src/test/incremental", mode: "incremental", suite: "incremental" },
|
2017-07-05 06:41:27 -06:00
|
|
|
|
2017-07-07 12:31:29 -06:00
|
|
|
// What this runs varies depending on the native platform being apple
|
|
|
|
Test { path: "src/test/debuginfo", mode: "debuginfo-XXX", suite: "debuginfo" },
|
|
|
|
];
|
2017-07-07 11:51:57 -06:00
|
|
|
|
2017-07-20 09:42:18 -06:00
|
|
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
|
|
|
pub struct DefaultCompiletest {
|
|
|
|
compiler: Compiler,
|
|
|
|
target: Interned<String>,
|
|
|
|
mode: &'static str,
|
|
|
|
suite: &'static str,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Step for DefaultCompiletest {
|
|
|
|
type Output = ();
|
|
|
|
const DEFAULT: bool = true;
|
|
|
|
|
|
|
|
fn should_run(mut run: ShouldRun) -> ShouldRun {
|
|
|
|
for test in DEFAULT_COMPILETESTS {
|
|
|
|
run = run.path(test.path);
|
|
|
|
}
|
|
|
|
run
|
|
|
|
}
|
|
|
|
|
2017-07-20 17:51:07 -06:00
|
|
|
fn make_run(run: RunConfig) {
|
|
|
|
let compiler = run.builder.compiler(run.builder.top_stage, run.host);
|
2017-07-20 09:42:18 -06:00
|
|
|
|
2017-07-20 17:51:07 -06:00
|
|
|
let test = run.path.map(|path| {
|
2017-07-20 09:42:18 -06:00
|
|
|
DEFAULT_COMPILETESTS.iter().find(|&&test| {
|
|
|
|
path.ends_with(test.path)
|
|
|
|
}).unwrap_or_else(|| {
|
|
|
|
panic!("make_run in compile test to receive test path, received {:?}", path);
|
|
|
|
})
|
|
|
|
});
|
|
|
|
|
|
|
|
if let Some(test) = test {
|
2017-07-20 17:51:07 -06:00
|
|
|
run.builder.ensure(DefaultCompiletest {
|
2017-07-20 09:42:18 -06:00
|
|
|
compiler,
|
2017-07-20 17:51:07 -06:00
|
|
|
target: run.target,
|
2017-07-20 09:42:18 -06:00
|
|
|
mode: test.mode,
|
|
|
|
suite: test.suite,
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
for test in DEFAULT_COMPILETESTS {
|
2017-07-20 17:51:07 -06:00
|
|
|
run.builder.ensure(DefaultCompiletest {
|
2017-07-20 09:42:18 -06:00
|
|
|
compiler,
|
2017-07-20 17:51:07 -06:00
|
|
|
target: run.target,
|
2017-07-20 09:42:18 -06:00
|
|
|
mode: test.mode,
|
|
|
|
suite: test.suite
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn run(self, builder: &Builder) {
|
|
|
|
builder.ensure(Compiletest {
|
|
|
|
compiler: self.compiler,
|
|
|
|
target: self.target,
|
|
|
|
mode: self.mode,
|
|
|
|
suite: self.suite,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-07 12:31:29 -06:00
|
|
|
// Also default, but host-only.
|
|
|
|
static HOST_COMPILETESTS: &[Test] = &[
|
|
|
|
Test { path: "src/test/ui-fulldeps", mode: "ui", suite: "ui-fulldeps" },
|
|
|
|
Test { path: "src/test/run-pass-fulldeps", mode: "run-pass", suite: "run-pass-fulldeps" },
|
|
|
|
Test { path: "src/test/run-fail-fulldeps", mode: "run-fail", suite: "run-fail-fulldeps" },
|
2017-07-07 11:51:57 -06:00
|
|
|
Test {
|
|
|
|
path: "src/test/compile-fail-fulldeps",
|
|
|
|
mode: "compile-fail",
|
|
|
|
suite: "compile-fail-fulldeps",
|
|
|
|
},
|
2017-07-07 12:31:29 -06:00
|
|
|
Test { path: "src/test/run-make", mode: "run-make", suite: "run-make" },
|
|
|
|
Test { path: "src/test/rustdoc", mode: "rustdoc", suite: "rustdoc" },
|
|
|
|
|
|
|
|
Test { path: "src/test/pretty", mode: "pretty", suite: "pretty" },
|
|
|
|
Test { path: "src/test/run-pass/pretty", mode: "pretty", suite: "run-pass" },
|
|
|
|
Test { path: "src/test/run-fail/pretty", mode: "pretty", suite: "run-fail" },
|
|
|
|
Test { path: "src/test/run-pass-valgrind/pretty", mode: "pretty", suite: "run-pass-valgrind" },
|
|
|
|
Test { path: "src/test/run-pass-fulldeps/pretty", mode: "pretty", suite: "run-pass-fulldeps" },
|
|
|
|
Test { path: "src/test/run-fail-fulldeps/pretty", mode: "pretty", suite: "run-fail-fulldeps" },
|
2017-07-05 06:41:27 -06:00
|
|
|
];
|
|
|
|
|
2017-07-20 09:42:18 -06:00
|
|
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
|
|
|
pub struct HostCompiletest {
|
|
|
|
compiler: Compiler,
|
|
|
|
target: Interned<String>,
|
|
|
|
mode: &'static str,
|
|
|
|
suite: &'static str,
|
|
|
|
}
|
2017-07-05 06:41:27 -06:00
|
|
|
|
2017-07-20 09:42:18 -06:00
|
|
|
impl Step for HostCompiletest {
|
2017-07-04 19:41:43 -06:00
|
|
|
type Output = ();
|
2017-07-05 06:41:27 -06:00
|
|
|
const DEFAULT: bool = true;
|
2017-07-20 09:42:18 -06:00
|
|
|
const ONLY_HOSTS: bool = true;
|
2017-07-05 06:41:27 -06:00
|
|
|
|
2017-07-18 18:03:38 -06:00
|
|
|
fn should_run(mut run: ShouldRun) -> ShouldRun {
|
2017-07-20 09:42:18 -06:00
|
|
|
for test in HOST_COMPILETESTS {
|
2017-07-18 18:03:38 -06:00
|
|
|
run = run.path(test.path);
|
|
|
|
}
|
|
|
|
run
|
2017-07-05 06:41:27 -06:00
|
|
|
}
|
|
|
|
|
2017-07-20 17:51:07 -06:00
|
|
|
fn make_run(run: RunConfig) {
|
|
|
|
let compiler = run.builder.compiler(run.builder.top_stage, run.host);
|
2017-07-05 06:41:27 -06:00
|
|
|
|
2017-07-20 17:51:07 -06:00
|
|
|
let test = run.path.map(|path| {
|
2017-07-20 09:42:18 -06:00
|
|
|
HOST_COMPILETESTS.iter().find(|&&test| {
|
2017-07-07 11:51:57 -06:00
|
|
|
path.ends_with(test.path)
|
2017-07-05 06:41:27 -06:00
|
|
|
}).unwrap_or_else(|| {
|
|
|
|
panic!("make_run in compile test to receive test path, received {:?}", path);
|
|
|
|
})
|
|
|
|
});
|
|
|
|
|
2017-07-20 09:42:18 -06:00
|
|
|
if let Some(test) = test {
|
2017-07-20 17:51:07 -06:00
|
|
|
run.builder.ensure(HostCompiletest {
|
2017-07-20 09:42:18 -06:00
|
|
|
compiler,
|
2017-07-20 17:51:07 -06:00
|
|
|
target: run.target,
|
2017-07-20 09:42:18 -06:00
|
|
|
mode: test.mode,
|
|
|
|
suite: test.suite,
|
2017-07-05 06:41:27 -06:00
|
|
|
});
|
2017-07-20 09:42:18 -06:00
|
|
|
} else {
|
|
|
|
for test in HOST_COMPILETESTS {
|
2017-07-23 07:22:12 -06:00
|
|
|
if test.mode == "pretty" {
|
|
|
|
continue;
|
|
|
|
}
|
2017-07-20 17:51:07 -06:00
|
|
|
run.builder.ensure(HostCompiletest {
|
2017-07-07 12:31:29 -06:00
|
|
|
compiler,
|
2017-07-20 17:51:07 -06:00
|
|
|
target: run.target,
|
2017-07-07 12:31:29 -06:00
|
|
|
mode: test.mode,
|
|
|
|
suite: test.suite
|
|
|
|
});
|
|
|
|
}
|
2017-07-05 06:41:27 -06:00
|
|
|
}
|
|
|
|
}
|
2017-07-04 19:41:43 -06:00
|
|
|
|
2017-07-20 09:42:18 -06:00
|
|
|
fn run(self, builder: &Builder) {
|
|
|
|
builder.ensure(Compiletest {
|
|
|
|
compiler: self.compiler,
|
|
|
|
target: self.target,
|
|
|
|
mode: self.mode,
|
|
|
|
suite: self.suite,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
|
|
|
struct Compiletest {
|
|
|
|
compiler: Compiler,
|
|
|
|
target: Interned<String>,
|
|
|
|
mode: &'static str,
|
|
|
|
suite: &'static str,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Step for Compiletest {
|
|
|
|
type Output = ();
|
|
|
|
|
|
|
|
fn should_run(run: ShouldRun) -> ShouldRun {
|
|
|
|
run.never()
|
|
|
|
}
|
|
|
|
|
2017-07-04 19:41:43 -06:00
|
|
|
/// Executes the `compiletest` tool to run a suite of tests.
|
|
|
|
///
|
|
|
|
/// Compiles all tests with `compiler` for `target` with the specified
|
|
|
|
/// compiletest `mode` and `suite` arguments. For example `mode` can be
|
|
|
|
/// "run-pass" or `suite` can be something like `debuginfo`.
|
|
|
|
fn run(self, builder: &Builder) {
|
|
|
|
let build = builder.build;
|
|
|
|
let compiler = self.compiler;
|
|
|
|
let target = self.target;
|
|
|
|
let mode = self.mode;
|
|
|
|
let suite = self.suite;
|
2017-07-05 06:41:27 -06:00
|
|
|
|
|
|
|
// Skip codegen tests if they aren't enabled in configuration.
|
|
|
|
if !build.config.codegen_tests && suite == "codegen" {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if suite == "debuginfo" {
|
2017-07-20 11:23:29 -06:00
|
|
|
// Skip debuginfo tests on MSVC
|
|
|
|
if build.build.contains("msvc") {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-07-05 06:41:27 -06:00
|
|
|
if mode == "debuginfo-XXX" {
|
|
|
|
return if build.build.contains("apple") {
|
|
|
|
builder.ensure(Compiletest {
|
|
|
|
mode: "debuginfo-lldb",
|
|
|
|
..self
|
2017-07-13 18:48:44 -06:00
|
|
|
});
|
2017-07-05 06:41:27 -06:00
|
|
|
} else {
|
|
|
|
builder.ensure(Compiletest {
|
|
|
|
mode: "debuginfo-gdb",
|
|
|
|
..self
|
2017-07-13 18:48:44 -06:00
|
|
|
});
|
2017-07-05 06:41:27 -06:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
builder.ensure(dist::DebuggerScripts {
|
2017-07-13 18:48:44 -06:00
|
|
|
sysroot: builder.sysroot(compiler),
|
2017-07-23 10:03:40 -06:00
|
|
|
host: target
|
2017-07-05 06:41:27 -06:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
if suite.ends_with("fulldeps") ||
|
|
|
|
// FIXME: Does pretty need librustc compiled? Note that there are
|
|
|
|
// fulldeps test suites with mode = pretty as well.
|
|
|
|
mode == "pretty" ||
|
|
|
|
mode == "rustdoc" ||
|
|
|
|
mode == "run-make" {
|
|
|
|
builder.ensure(compile::Rustc { compiler, target });
|
|
|
|
}
|
|
|
|
|
|
|
|
builder.ensure(compile::Test { compiler, target });
|
|
|
|
builder.ensure(native::TestHelpers { target });
|
2017-07-07 12:31:29 -06:00
|
|
|
builder.ensure(RemoteCopyLibs { compiler, target });
|
2017-07-05 06:41:27 -06:00
|
|
|
|
2017-07-04 19:41:43 -06:00
|
|
|
let _folder = build.fold_output(|| format!("test_{}", suite));
|
|
|
|
println!("Check compiletest suite={} mode={} ({} -> {})",
|
2017-07-13 18:48:44 -06:00
|
|
|
suite, mode, &compiler.host, target);
|
2017-07-05 06:41:27 -06:00
|
|
|
let mut cmd = builder.tool_cmd(Tool::Compiletest);
|
2017-07-04 19:41:43 -06:00
|
|
|
|
|
|
|
// compiletest currently has... a lot of arguments, so let's just pass all
|
|
|
|
// of them!
|
|
|
|
|
2017-07-05 11:21:33 -06:00
|
|
|
cmd.arg("--compile-lib-path").arg(builder.rustc_libdir(compiler));
|
2017-07-05 10:46:41 -06:00
|
|
|
cmd.arg("--run-lib-path").arg(builder.sysroot_libdir(compiler, target));
|
2017-07-05 11:21:33 -06:00
|
|
|
cmd.arg("--rustc-path").arg(builder.rustc(compiler));
|
2017-07-25 16:54:33 -06:00
|
|
|
|
|
|
|
// Avoid depending on rustdoc when we don't need it.
|
|
|
|
if mode == "rustdoc" || mode == "run-make" {
|
|
|
|
cmd.arg("--rustdoc-path").arg(builder.rustdoc(compiler));
|
|
|
|
}
|
|
|
|
|
2017-07-04 19:41:43 -06:00
|
|
|
cmd.arg("--src-base").arg(build.src.join("src/test").join(suite));
|
|
|
|
cmd.arg("--build-base").arg(testdir(build, compiler.host).join(suite));
|
|
|
|
cmd.arg("--stage-id").arg(format!("stage{}-{}", compiler.stage, target));
|
|
|
|
cmd.arg("--mode").arg(mode);
|
|
|
|
cmd.arg("--target").arg(target);
|
2017-07-13 18:48:44 -06:00
|
|
|
cmd.arg("--host").arg(&*compiler.host);
|
|
|
|
cmd.arg("--llvm-filecheck").arg(build.llvm_filecheck(build.build));
|
2017-07-04 19:41:43 -06:00
|
|
|
|
|
|
|
if let Some(ref nodejs) = build.config.nodejs {
|
|
|
|
cmd.arg("--nodejs").arg(nodejs);
|
|
|
|
}
|
2016-04-19 09:44:19 -07:00
|
|
|
|
2017-07-04 19:41:43 -06:00
|
|
|
let mut flags = vec!["-Crpath".to_string()];
|
|
|
|
if build.config.rust_optimize_tests {
|
|
|
|
flags.push("-O".to_string());
|
|
|
|
}
|
|
|
|
if build.config.rust_debuginfo_tests {
|
|
|
|
flags.push("-g".to_string());
|
|
|
|
}
|
2016-04-19 09:44:19 -07:00
|
|
|
|
2017-07-05 10:46:41 -06:00
|
|
|
let mut hostflags = build.rustc_flags(compiler.host);
|
2017-07-04 19:41:43 -06:00
|
|
|
hostflags.extend(flags.clone());
|
|
|
|
cmd.arg("--host-rustcflags").arg(hostflags.join(" "));
|
|
|
|
|
2017-07-13 18:48:44 -06:00
|
|
|
let mut targetflags = build.rustc_flags(target);
|
2017-07-04 19:41:43 -06:00
|
|
|
targetflags.extend(flags);
|
|
|
|
targetflags.push(format!("-Lnative={}",
|
|
|
|
build.test_helpers_out(target).display()));
|
|
|
|
cmd.arg("--target-rustcflags").arg(targetflags.join(" "));
|
|
|
|
|
|
|
|
cmd.arg("--docck-python").arg(build.python());
|
|
|
|
|
|
|
|
if build.build.ends_with("apple-darwin") {
|
|
|
|
// Force /usr/bin/python on macOS for LLDB tests because we're loading the
|
|
|
|
// LLDB plugin's compiled module which only works with the system python
|
|
|
|
// (namely not Homebrew-installed python)
|
|
|
|
cmd.arg("--lldb-python").arg("/usr/bin/python");
|
|
|
|
} else {
|
|
|
|
cmd.arg("--lldb-python").arg(build.python());
|
|
|
|
}
|
2016-04-05 11:34:23 -07:00
|
|
|
|
2017-07-04 19:41:43 -06:00
|
|
|
if let Some(ref gdb) = build.config.gdb {
|
|
|
|
cmd.arg("--gdb").arg(gdb);
|
|
|
|
}
|
|
|
|
if let Some(ref vers) = build.lldb_version {
|
|
|
|
cmd.arg("--lldb-version").arg(vers);
|
|
|
|
}
|
|
|
|
if let Some(ref dir) = build.lldb_python_dir {
|
|
|
|
cmd.arg("--lldb-python-dir").arg(dir);
|
|
|
|
}
|
|
|
|
let llvm_config = build.llvm_config(target);
|
|
|
|
let llvm_version = output(Command::new(&llvm_config).arg("--version"));
|
|
|
|
cmd.arg("--llvm-version").arg(llvm_version);
|
|
|
|
if !build.is_rust_llvm(target) {
|
|
|
|
cmd.arg("--system-llvm");
|
|
|
|
}
|
2016-04-05 11:34:23 -07:00
|
|
|
|
2017-07-04 19:41:43 -06:00
|
|
|
cmd.args(&build.flags.cmd.test_args());
|
2016-04-05 11:34:23 -07:00
|
|
|
|
2017-07-04 19:41:43 -06:00
|
|
|
if build.is_verbose() {
|
|
|
|
cmd.arg("--verbose");
|
|
|
|
}
|
2016-04-05 11:34:23 -07:00
|
|
|
|
2017-07-04 19:41:43 -06:00
|
|
|
if build.config.quiet_tests {
|
|
|
|
cmd.arg("--quiet");
|
|
|
|
}
|
2016-10-29 21:58:52 -04:00
|
|
|
|
2017-07-04 19:41:43 -06:00
|
|
|
// Only pass correct values for these flags for the `run-make` suite as it
|
|
|
|
// requires that a C++ compiler was configured which isn't always the case.
|
|
|
|
if suite == "run-make" {
|
|
|
|
let llvm_components = output(Command::new(&llvm_config).arg("--components"));
|
|
|
|
let llvm_cxxflags = output(Command::new(&llvm_config).arg("--cxxflags"));
|
|
|
|
cmd.arg("--cc").arg(build.cc(target))
|
|
|
|
.arg("--cxx").arg(build.cxx(target).unwrap())
|
|
|
|
.arg("--cflags").arg(build.cflags(target).join(" "))
|
|
|
|
.arg("--llvm-components").arg(llvm_components.trim())
|
|
|
|
.arg("--llvm-cxxflags").arg(llvm_cxxflags.trim());
|
|
|
|
} else {
|
|
|
|
cmd.arg("--cc").arg("")
|
|
|
|
.arg("--cxx").arg("")
|
|
|
|
.arg("--cflags").arg("")
|
|
|
|
.arg("--llvm-components").arg("")
|
|
|
|
.arg("--llvm-cxxflags").arg("");
|
|
|
|
}
|
2016-04-14 15:51:03 -07:00
|
|
|
|
2017-07-04 19:41:43 -06:00
|
|
|
if build.remote_tested(target) {
|
2017-07-05 06:41:27 -06:00
|
|
|
cmd.arg("--remote-test-client").arg(builder.tool_exe(Tool::RemoteTestClient));
|
2017-07-04 19:41:43 -06:00
|
|
|
}
|
2017-01-28 13:38:06 -08:00
|
|
|
|
2017-07-04 19:41:43 -06:00
|
|
|
// Running a C compiler on MSVC requires a few env vars to be set, to be
|
|
|
|
// sure to set them here.
|
|
|
|
//
|
|
|
|
// Note that if we encounter `PATH` we make sure to append to our own `PATH`
|
|
|
|
// rather than stomp over it.
|
|
|
|
if target.contains("msvc") {
|
2017-07-13 18:48:44 -06:00
|
|
|
for &(ref k, ref v) in build.cc[&target].0.env() {
|
2017-07-04 19:41:43 -06:00
|
|
|
if k != "PATH" {
|
|
|
|
cmd.env(k, v);
|
|
|
|
}
|
2016-04-14 15:51:03 -07:00
|
|
|
}
|
|
|
|
}
|
2017-07-04 19:41:43 -06:00
|
|
|
cmd.env("RUSTC_BOOTSTRAP", "1");
|
|
|
|
build.add_rust_test_threads(&mut cmd);
|
2016-04-14 15:51:03 -07:00
|
|
|
|
2017-07-04 19:41:43 -06:00
|
|
|
if build.config.sanitizers {
|
|
|
|
cmd.env("SANITIZER_SUPPORT", "1");
|
|
|
|
}
|
2017-02-03 18:58:47 -05:00
|
|
|
|
2017-07-04 19:41:43 -06:00
|
|
|
if build.config.profiler {
|
|
|
|
cmd.env("PROFILER_SUPPORT", "1");
|
|
|
|
}
|
2017-02-13 09:57:50 +00:00
|
|
|
|
2017-07-04 19:41:43 -06:00
|
|
|
cmd.arg("--adb-path").arg("adb");
|
|
|
|
cmd.arg("--adb-test-dir").arg(ADB_TEST_DIR);
|
|
|
|
if target.contains("android") {
|
|
|
|
// Assume that cc for this target comes from the android sysroot
|
|
|
|
cmd.arg("--android-cross-path")
|
|
|
|
.arg(build.cc(target).parent().unwrap().parent().unwrap());
|
|
|
|
} else {
|
|
|
|
cmd.arg("--android-cross-path").arg("");
|
|
|
|
}
|
2016-06-28 13:31:30 -07:00
|
|
|
|
2017-07-04 19:41:43 -06:00
|
|
|
build.ci_env.force_coloring_in_ci(&mut cmd);
|
2017-05-18 00:33:20 +08:00
|
|
|
|
2017-07-04 19:41:43 -06:00
|
|
|
let _time = util::timeit();
|
|
|
|
try_run(build, &mut cmd);
|
|
|
|
}
|
2016-04-05 11:34:23 -07:00
|
|
|
}
|
2016-04-14 18:00:35 -07:00
|
|
|
|
2017-07-13 18:48:44 -06:00
|
|
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
|
|
|
pub struct Docs {
|
|
|
|
compiler: Compiler,
|
2017-07-12 09:15:00 -06:00
|
|
|
}
|
|
|
|
|
2017-07-13 18:48:44 -06:00
|
|
|
impl Step for Docs {
|
2017-07-12 09:15:00 -06:00
|
|
|
type Output = ();
|
|
|
|
const DEFAULT: bool = true;
|
|
|
|
const ONLY_HOSTS: bool = true;
|
2016-04-14 18:00:35 -07:00
|
|
|
|
2017-07-18 18:03:38 -06:00
|
|
|
fn should_run(run: ShouldRun) -> ShouldRun {
|
|
|
|
run.path("src/doc")
|
2017-07-12 09:15:00 -06:00
|
|
|
}
|
2017-07-10 11:43:02 -06:00
|
|
|
|
2017-07-20 17:51:07 -06:00
|
|
|
fn make_run(run: RunConfig) {
|
|
|
|
run.builder.ensure(Docs {
|
|
|
|
compiler: run.builder.compiler(run.builder.top_stage, run.host),
|
2017-07-12 09:15:00 -06:00
|
|
|
});
|
|
|
|
}
|
2017-07-10 11:43:02 -06:00
|
|
|
|
2017-07-12 09:15:00 -06:00
|
|
|
/// Run `rustdoc --test` for all documentation in `src/doc`.
|
|
|
|
///
|
|
|
|
/// This will run all tests in our markdown documentation (e.g. the book)
|
|
|
|
/// located in `src/doc`. The `rustdoc` that's run is the one that sits next to
|
|
|
|
/// `compiler`.
|
|
|
|
fn run(self, builder: &Builder) {
|
|
|
|
let build = builder.build;
|
|
|
|
let compiler = self.compiler;
|
2017-07-12 10:12:47 -06:00
|
|
|
|
|
|
|
builder.ensure(compile::Test { compiler, target: compiler.host });
|
|
|
|
|
2017-07-12 09:15:00 -06:00
|
|
|
// Do a breadth-first traversal of the `src/doc` directory and just run
|
|
|
|
// tests for all files that end in `*.md`
|
|
|
|
let mut stack = vec![build.src.join("src/doc")];
|
|
|
|
let _time = util::timeit();
|
|
|
|
let _folder = build.fold_output(|| "test_docs");
|
|
|
|
|
|
|
|
while let Some(p) = stack.pop() {
|
|
|
|
if p.is_dir() {
|
|
|
|
stack.extend(t!(p.read_dir()).map(|p| t!(p).path()));
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
if p.extension().and_then(|s| s.to_str()) != Some("md") {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// The nostarch directory in the book is for no starch, and so isn't
|
|
|
|
// guaranteed to build. We don't care if it doesn't build, so skip it.
|
|
|
|
if p.to_str().map_or(false, |p| p.contains("nostarch")) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
markdown_test(builder, compiler, &p);
|
|
|
|
}
|
2016-04-14 18:00:35 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-13 18:48:44 -06:00
|
|
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
|
|
|
pub struct ErrorIndex {
|
|
|
|
compiler: Compiler,
|
2017-07-04 19:41:43 -06:00
|
|
|
}
|
2016-04-14 18:00:35 -07:00
|
|
|
|
2017-07-13 18:48:44 -06:00
|
|
|
impl Step for ErrorIndex {
|
2017-07-04 19:41:43 -06:00
|
|
|
type Output = ();
|
2017-07-05 06:41:27 -06:00
|
|
|
const DEFAULT: bool = true;
|
|
|
|
const ONLY_HOSTS: bool = true;
|
|
|
|
|
2017-07-18 18:03:38 -06:00
|
|
|
fn should_run(run: ShouldRun) -> ShouldRun {
|
|
|
|
run.path("src/tools/error_index_generator")
|
2017-07-05 06:41:27 -06:00
|
|
|
}
|
|
|
|
|
2017-07-20 17:51:07 -06:00
|
|
|
fn make_run(run: RunConfig) {
|
|
|
|
run.builder.ensure(ErrorIndex {
|
|
|
|
compiler: run.builder.compiler(run.builder.top_stage, run.host),
|
2017-07-05 06:41:27 -06:00
|
|
|
});
|
|
|
|
}
|
2017-07-04 19:41:43 -06:00
|
|
|
|
|
|
|
/// Run the error index generator tool to execute the tests located in the error
|
|
|
|
/// index.
|
|
|
|
///
|
|
|
|
/// The `error_index_generator` tool lives in `src/tools` and is used to
|
|
|
|
/// generate a markdown file from the error indexes of the code base which is
|
|
|
|
/// then passed to `rustdoc --test`.
|
|
|
|
fn run(self, builder: &Builder) {
|
|
|
|
let build = builder.build;
|
|
|
|
let compiler = self.compiler;
|
|
|
|
|
2017-07-05 06:41:27 -06:00
|
|
|
builder.ensure(compile::Std { compiler, target: compiler.host });
|
|
|
|
|
2017-07-04 19:41:43 -06:00
|
|
|
let _folder = build.fold_output(|| "test_error_index");
|
|
|
|
println!("Testing error-index stage{}", compiler.stage);
|
|
|
|
|
|
|
|
let dir = testdir(build, compiler.host);
|
|
|
|
t!(fs::create_dir_all(&dir));
|
|
|
|
let output = dir.join("error-index.md");
|
|
|
|
|
|
|
|
let _time = util::timeit();
|
2017-07-05 10:46:41 -06:00
|
|
|
build.run(builder.tool_cmd(Tool::ErrorIndex)
|
2017-07-04 19:41:43 -06:00
|
|
|
.arg("markdown")
|
|
|
|
.arg(&output)
|
|
|
|
.env("CFG_BUILD", &build.build));
|
|
|
|
|
2017-07-05 11:21:33 -06:00
|
|
|
markdown_test(builder, compiler, &output);
|
2017-07-04 19:41:43 -06:00
|
|
|
}
|
2016-04-14 18:00:35 -07:00
|
|
|
}
|
|
|
|
|
2017-07-05 11:21:33 -06:00
|
|
|
fn markdown_test(builder: &Builder, compiler: Compiler, markdown: &Path) {
|
|
|
|
let build = builder.build;
|
2017-06-04 17:55:50 -06:00
|
|
|
let mut file = t!(File::open(markdown));
|
|
|
|
let mut contents = String::new();
|
|
|
|
t!(file.read_to_string(&mut contents));
|
|
|
|
if !contents.contains("```") {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-06-06 12:00:22 -06:00
|
|
|
println!("doc tests for: {}", markdown.display());
|
2017-07-22 20:01:58 -06:00
|
|
|
let mut cmd = builder.rustdoc_cmd(compiler);
|
2016-11-16 12:31:19 -08:00
|
|
|
build.add_rust_test_threads(&mut cmd);
|
2016-04-14 18:00:35 -07:00
|
|
|
cmd.arg("--test");
|
|
|
|
cmd.arg(markdown);
|
2016-12-12 09:03:35 -08:00
|
|
|
cmd.env("RUSTC_BOOTSTRAP", "1");
|
2016-10-29 21:58:52 -04:00
|
|
|
|
2017-05-22 04:27:47 +08:00
|
|
|
let test_args = build.flags.cmd.test_args().join(" ");
|
2016-10-29 21:58:52 -04:00
|
|
|
cmd.arg("--test-args").arg(test_args);
|
|
|
|
|
2017-05-22 04:27:47 +08:00
|
|
|
if build.config.quiet_tests {
|
2017-06-02 09:27:44 -07:00
|
|
|
try_run_quiet(build, &mut cmd);
|
2017-05-22 04:27:47 +08:00
|
|
|
} else {
|
2017-06-02 09:27:44 -07:00
|
|
|
try_run(build, &mut cmd);
|
2017-05-22 04:27:47 +08:00
|
|
|
}
|
2016-04-14 18:00:35 -07:00
|
|
|
}
|
2016-04-29 14:23:15 -07:00
|
|
|
|
2017-07-13 18:48:44 -06:00
|
|
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
2017-07-18 15:28:53 -06:00
|
|
|
pub struct CrateLibrustc {
|
2017-07-13 18:48:44 -06:00
|
|
|
compiler: Compiler,
|
|
|
|
target: Interned<String>,
|
2017-07-05 06:41:27 -06:00
|
|
|
test_kind: TestKind,
|
2017-07-13 18:48:44 -06:00
|
|
|
krate: Option<Interned<String>>,
|
2017-07-05 06:41:27 -06:00
|
|
|
}
|
|
|
|
|
2017-07-18 15:28:53 -06:00
|
|
|
impl Step for CrateLibrustc {
|
2017-07-05 06:41:27 -06:00
|
|
|
type Output = ();
|
|
|
|
const DEFAULT: bool = true;
|
|
|
|
const ONLY_HOSTS: bool = true;
|
|
|
|
|
2017-07-18 18:03:38 -06:00
|
|
|
fn should_run(run: ShouldRun) -> ShouldRun {
|
|
|
|
run.krate("rustc-main")
|
2017-07-05 06:41:27 -06:00
|
|
|
}
|
|
|
|
|
2017-07-20 17:51:07 -06:00
|
|
|
fn make_run(run: RunConfig) {
|
|
|
|
let builder = run.builder;
|
|
|
|
let compiler = builder.compiler(builder.top_stage, run.host);
|
2017-07-05 06:41:27 -06:00
|
|
|
|
2017-07-20 17:51:07 -06:00
|
|
|
let make = |name: Option<Interned<String>>| {
|
2017-07-05 06:41:27 -06:00
|
|
|
let test_kind = if builder.kind == Kind::Test {
|
|
|
|
TestKind::Test
|
|
|
|
} else if builder.kind == Kind::Bench {
|
|
|
|
TestKind::Bench
|
|
|
|
} else {
|
2017-07-18 15:28:53 -06:00
|
|
|
panic!("unexpected builder.kind in crate: {:?}", builder.kind);
|
2017-07-05 06:41:27 -06:00
|
|
|
};
|
|
|
|
|
2017-07-18 15:28:53 -06:00
|
|
|
builder.ensure(CrateLibrustc {
|
2017-07-05 06:41:27 -06:00
|
|
|
compiler,
|
2017-07-20 17:51:07 -06:00
|
|
|
target: run.target,
|
2017-07-05 06:41:27 -06:00
|
|
|
test_kind: test_kind,
|
|
|
|
krate: name,
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2017-07-20 17:51:07 -06:00
|
|
|
if let Some(path) = run.path {
|
2017-07-05 06:41:27 -06:00
|
|
|
for (name, krate_path) in builder.crates("rustc-main") {
|
|
|
|
if path.ends_with(krate_path) {
|
2017-07-20 17:51:07 -06:00
|
|
|
make(Some(name));
|
2017-07-05 06:41:27 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2017-07-20 17:51:07 -06:00
|
|
|
make(None);
|
2017-07-05 06:41:27 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn run(self, builder: &Builder) {
|
2017-07-18 15:28:53 -06:00
|
|
|
builder.ensure(Crate {
|
2017-07-05 06:41:27 -06:00
|
|
|
compiler: self.compiler,
|
|
|
|
target: self.target,
|
|
|
|
mode: Mode::Librustc,
|
|
|
|
test_kind: self.test_kind,
|
|
|
|
krate: self.krate,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-07-13 18:48:44 -06:00
|
|
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
2017-07-18 15:28:53 -06:00
|
|
|
pub struct Crate {
|
2017-07-13 18:48:44 -06:00
|
|
|
compiler: Compiler,
|
|
|
|
target: Interned<String>,
|
2017-07-04 19:41:43 -06:00
|
|
|
mode: Mode,
|
|
|
|
test_kind: TestKind,
|
2017-07-13 18:48:44 -06:00
|
|
|
krate: Option<Interned<String>>,
|
2017-07-04 19:41:43 -06:00
|
|
|
}
|
2016-04-29 14:23:15 -07:00
|
|
|
|
2017-07-18 15:28:53 -06:00
|
|
|
impl Step for Crate {
|
2017-07-04 19:41:43 -06:00
|
|
|
type Output = ();
|
2017-07-05 06:41:27 -06:00
|
|
|
const DEFAULT: bool = true;
|
|
|
|
|
2017-07-18 18:03:38 -06:00
|
|
|
fn should_run(run: ShouldRun) -> ShouldRun {
|
|
|
|
run.krate("std").krate("test")
|
2017-07-05 06:41:27 -06:00
|
|
|
}
|
|
|
|
|
2017-07-20 17:51:07 -06:00
|
|
|
fn make_run(run: RunConfig) {
|
|
|
|
let builder = run.builder;
|
|
|
|
let compiler = builder.compiler(builder.top_stage, run.host);
|
2017-07-05 06:41:27 -06:00
|
|
|
|
2017-07-20 17:51:07 -06:00
|
|
|
let make = |mode: Mode, name: Option<Interned<String>>| {
|
2017-07-05 06:41:27 -06:00
|
|
|
let test_kind = if builder.kind == Kind::Test {
|
|
|
|
TestKind::Test
|
|
|
|
} else if builder.kind == Kind::Bench {
|
|
|
|
TestKind::Bench
|
|
|
|
} else {
|
2017-07-18 15:28:53 -06:00
|
|
|
panic!("unexpected builder.kind in crate: {:?}", builder.kind);
|
2017-07-05 06:41:27 -06:00
|
|
|
};
|
|
|
|
|
2017-07-18 15:28:53 -06:00
|
|
|
builder.ensure(Crate {
|
2017-07-20 17:51:07 -06:00
|
|
|
compiler,
|
|
|
|
target: run.target,
|
2017-07-05 06:41:27 -06:00
|
|
|
mode: mode,
|
|
|
|
test_kind: test_kind,
|
|
|
|
krate: name,
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2017-07-20 17:51:07 -06:00
|
|
|
if let Some(path) = run.path {
|
2017-07-05 06:41:27 -06:00
|
|
|
for (name, krate_path) in builder.crates("std") {
|
|
|
|
if path.ends_with(krate_path) {
|
2017-07-20 17:51:07 -06:00
|
|
|
make(Mode::Libstd, Some(name));
|
2017-07-05 06:41:27 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
for (name, krate_path) in builder.crates("test") {
|
|
|
|
if path.ends_with(krate_path) {
|
2017-07-20 17:51:07 -06:00
|
|
|
make(Mode::Libtest, Some(name));
|
2017-07-05 06:41:27 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2017-07-20 17:51:07 -06:00
|
|
|
make(Mode::Libstd, None);
|
|
|
|
make(Mode::Libtest, None);
|
2017-07-05 06:41:27 -06:00
|
|
|
}
|
|
|
|
}
|
2017-07-04 19:41:43 -06:00
|
|
|
|
|
|
|
/// Run all unit tests plus documentation tests for an entire crate DAG defined
|
|
|
|
/// by a `Cargo.toml`
|
|
|
|
///
|
|
|
|
/// This is what runs tests for crates like the standard library, compiler, etc.
|
|
|
|
/// It essentially is the driver for running `cargo test`.
|
|
|
|
///
|
|
|
|
/// Currently this runs all tests for a DAG by passing a bunch of `-p foo`
|
|
|
|
/// arguments, and those arguments are discovered from `cargo metadata`.
|
|
|
|
fn run(self, builder: &Builder) {
|
|
|
|
let build = builder.build;
|
|
|
|
let compiler = self.compiler;
|
|
|
|
let target = self.target;
|
|
|
|
let mode = self.mode;
|
|
|
|
let test_kind = self.test_kind;
|
|
|
|
let krate = self.krate;
|
|
|
|
|
2017-07-05 06:41:27 -06:00
|
|
|
builder.ensure(compile::Test { compiler, target });
|
|
|
|
builder.ensure(RemoteCopyLibs { compiler, target });
|
2017-07-17 09:32:08 -07:00
|
|
|
|
|
|
|
// If we're not doing a full bootstrap but we're testing a stage2 version of
|
|
|
|
// libstd, then what we're actually testing is the libstd produced in
|
|
|
|
// stage1. Reflect that here by updating the compiler that we're working
|
|
|
|
// with automatically.
|
|
|
|
let compiler = if build.force_use_stage1(compiler, target) {
|
|
|
|
builder.compiler(1, compiler.host)
|
|
|
|
} else {
|
|
|
|
compiler.clone()
|
|
|
|
};
|
|
|
|
|
|
|
|
let mut cargo = builder.cargo(compiler, mode, target, test_kind.subcommand());
|
|
|
|
let (name, root) = match mode {
|
2017-07-04 19:41:43 -06:00
|
|
|
Mode::Libstd => {
|
2017-07-17 09:32:08 -07:00
|
|
|
compile::std_cargo(build, &compiler, target, &mut cargo);
|
|
|
|
("libstd", "std")
|
2017-07-04 19:41:43 -06:00
|
|
|
}
|
|
|
|
Mode::Libtest => {
|
2017-07-17 09:32:08 -07:00
|
|
|
compile::test_cargo(build, &compiler, target, &mut cargo);
|
|
|
|
("libtest", "test")
|
2017-07-04 19:41:43 -06:00
|
|
|
}
|
|
|
|
Mode::Librustc => {
|
2017-07-12 10:12:47 -06:00
|
|
|
builder.ensure(compile::Rustc { compiler, target });
|
2017-07-17 09:32:08 -07:00
|
|
|
compile::rustc_cargo(build, &compiler, target, &mut cargo);
|
|
|
|
("librustc", "rustc-main")
|
2017-07-04 19:41:43 -06:00
|
|
|
}
|
|
|
|
_ => panic!("can only test libraries"),
|
|
|
|
};
|
2017-07-13 18:48:44 -06:00
|
|
|
let root = INTERNER.intern_string(String::from(root));
|
2017-07-04 19:41:43 -06:00
|
|
|
let _folder = build.fold_output(|| {
|
|
|
|
format!("{}_stage{}-{}", test_kind.subcommand(), compiler.stage, name)
|
|
|
|
});
|
|
|
|
println!("{} {} stage{} ({} -> {})", test_kind, name, compiler.stage,
|
2017-07-13 18:48:44 -06:00
|
|
|
&compiler.host, target);
|
2017-07-04 19:41:43 -06:00
|
|
|
|
|
|
|
// Build up the base `cargo test` command.
|
|
|
|
//
|
|
|
|
// Pass in some standard flags then iterate over the graph we've discovered
|
|
|
|
// in `cargo metadata` with the maps above and figure out what `-p`
|
|
|
|
// arguments need to get passed.
|
|
|
|
if test_kind.subcommand() == "test" && !build.fail_fast {
|
|
|
|
cargo.arg("--no-fail-fast");
|
|
|
|
}
|
|
|
|
|
|
|
|
match krate {
|
|
|
|
Some(krate) => {
|
|
|
|
cargo.arg("-p").arg(krate);
|
|
|
|
}
|
|
|
|
None => {
|
|
|
|
let mut visited = HashSet::new();
|
|
|
|
let mut next = vec![root];
|
|
|
|
while let Some(name) = next.pop() {
|
2017-07-17 09:32:08 -07:00
|
|
|
// Right now jemalloc and the sanitizer crates are
|
|
|
|
// target-specific crate in the sense that it's not present
|
|
|
|
// on all platforms. Custom skip it here for now, but if we
|
|
|
|
// add more this probably wants to get more generalized.
|
2017-07-04 19:41:43 -06:00
|
|
|
//
|
2017-07-17 09:32:08 -07:00
|
|
|
// Also skip `build_helper` as it's not compiled normally
|
|
|
|
// for target during the bootstrap and it's just meant to be
|
|
|
|
// a helper crate, not tested. If it leaks through then it
|
|
|
|
// ends up messing with various mtime calculations and such.
|
|
|
|
if !name.contains("jemalloc") &&
|
|
|
|
*name != *"build_helper" &&
|
|
|
|
!(name.starts_with("rustc_") && name.ends_with("san")) {
|
2017-07-04 19:41:43 -06:00
|
|
|
cargo.arg("-p").arg(&format!("{}:0.0.0", name));
|
|
|
|
}
|
2017-07-13 18:48:44 -06:00
|
|
|
for dep in build.crates[&name].deps.iter() {
|
2017-07-04 19:41:43 -06:00
|
|
|
if visited.insert(dep) {
|
2017-07-13 18:48:44 -06:00
|
|
|
next.push(*dep);
|
2017-07-04 19:41:43 -06:00
|
|
|
}
|
2016-10-21 13:18:09 -07:00
|
|
|
}
|
|
|
|
}
|
2016-10-06 23:30:38 -07:00
|
|
|
}
|
2016-04-29 14:23:15 -07:00
|
|
|
}
|
2016-11-16 12:31:19 -08:00
|
|
|
|
2017-07-04 19:41:43 -06:00
|
|
|
// The tests are going to run with the *target* libraries, so we need to
|
|
|
|
// ensure that those libraries show up in the LD_LIBRARY_PATH equivalent.
|
|
|
|
//
|
|
|
|
// Note that to run the compiler we need to run with the *host* libraries,
|
|
|
|
// but our wrapper scripts arrange for that to be the case anyway.
|
|
|
|
let mut dylib_path = dylib_path();
|
2017-07-13 18:48:44 -06:00
|
|
|
dylib_path.insert(0, PathBuf::from(&*builder.sysroot_libdir(compiler, target)));
|
2017-07-04 19:41:43 -06:00
|
|
|
cargo.env(dylib_path_var(), env::join_paths(&dylib_path).unwrap());
|
|
|
|
|
|
|
|
if target.contains("emscripten") || build.remote_tested(target) {
|
|
|
|
cargo.arg("--no-run");
|
|
|
|
}
|
2016-11-16 12:31:19 -08:00
|
|
|
|
2017-07-04 19:41:43 -06:00
|
|
|
cargo.arg("--");
|
2016-10-29 21:58:52 -04:00
|
|
|
|
2017-07-04 19:41:43 -06:00
|
|
|
if build.config.quiet_tests {
|
|
|
|
cargo.arg("--quiet");
|
|
|
|
}
|
2016-11-16 12:31:19 -08:00
|
|
|
|
2017-07-04 19:41:43 -06:00
|
|
|
let _time = util::timeit();
|
|
|
|
|
|
|
|
if target.contains("emscripten") {
|
|
|
|
build.run(&mut cargo);
|
2017-07-05 10:46:41 -06:00
|
|
|
krate_emscripten(build, compiler, target, mode);
|
2017-07-04 19:41:43 -06:00
|
|
|
} else if build.remote_tested(target) {
|
|
|
|
build.run(&mut cargo);
|
2017-07-05 10:46:41 -06:00
|
|
|
krate_remote(builder, compiler, target, mode);
|
2017-07-04 19:41:43 -06:00
|
|
|
} else {
|
|
|
|
cargo.args(&build.flags.cmd.test_args());
|
|
|
|
try_run(build, &mut cargo);
|
|
|
|
}
|
2016-06-28 13:31:30 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-06 00:41:50 +00:00
|
|
|
fn krate_emscripten(build: &Build,
|
2017-07-05 10:46:41 -06:00
|
|
|
compiler: Compiler,
|
2017-07-13 18:48:44 -06:00
|
|
|
target: Interned<String>,
|
2016-09-06 00:41:50 +00:00
|
|
|
mode: Mode) {
|
2017-01-28 13:38:06 -08:00
|
|
|
let out_dir = build.cargo_out(compiler, mode, target);
|
2017-06-26 10:23:50 -06:00
|
|
|
let tests = find_tests(&out_dir.join("deps"), target);
|
2017-01-28 13:38:06 -08:00
|
|
|
|
2017-06-26 10:23:50 -06:00
|
|
|
let nodejs = build.config.nodejs.as_ref().expect("nodejs not configured");
|
2017-01-28 13:38:06 -08:00
|
|
|
for test in tests {
|
2017-06-26 10:23:50 -06:00
|
|
|
println!("running {}", test.display());
|
2017-01-28 13:38:06 -08:00
|
|
|
let mut cmd = Command::new(nodejs);
|
2017-06-26 10:23:50 -06:00
|
|
|
cmd.arg(&test);
|
2017-01-28 13:38:06 -08:00
|
|
|
if build.config.quiet_tests {
|
|
|
|
cmd.arg("--quiet");
|
|
|
|
}
|
2017-06-02 09:27:44 -07:00
|
|
|
try_run(build, &mut cmd);
|
2017-01-28 13:38:06 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-05 10:46:41 -06:00
|
|
|
fn krate_remote(builder: &Builder,
|
|
|
|
compiler: Compiler,
|
2017-07-13 18:48:44 -06:00
|
|
|
target: Interned<String>,
|
travis: Parallelize tests on Android
Currently our slowest test suite on android, run-pass, takes over 5 times longer
than the x86_64 component (~400 -> ~2200s). Typically QEMU emulation does indeed
add overhead, but not 5x for this kind of workload. One of the slowest parts of
the Android process is that *compilation* happens serially. Tests themselves
need to run single-threaded on the emulator (due to how the test harness works)
and this forces the compiles themselves to be single threaded.
Now Travis gives us more than one core per machine, so it'd be much better if we
could take advantage of them! The emulator itself is still fundamentally
single-threaded, but we should see a nice speedup by sending binaries for it to
run much more quickly.
It turns out that we've already got all the tools to do this in-tree. The
qemu-test-{server,client} that are in use for the ARM Linux testing are a
perfect match for the Android emulator. This commit migrates the custom adb
management code in compiletest/rustbuild to the same qemu-test-{server,client}
implementation that ARM Linux uses.
This allows us to lift the parallelism restriction on the compiletest test
suites, namely run-pass. Consequently although we'll still basically run the
tests themselves in single threaded mode we'll be able to compile all of them in
parallel, keeping the pipeline much more full and using more cores for the work
at hand. Additionally the architecture here should be a bit speedier as it
should have less overhead than adb which is a whole new process on both the host
and the emulator!
Locally on an 8 core machine I've seen the run-pass test suite speed up from
taking nearly an hour to only taking 6 minutes. I don't think we'll see quite a
drastic speedup on Travis but I'm hoping this change can place the Android tests
well below 2 hours instead of just above 2 hours.
Because the client/server here are now repurposed for more than just QEMU,
they've been renamed to `remote-test-{server,client}`.
Note that this PR does not currently modify how debuginfo tests are executed on
Android. While parallelizable it wouldn't be quite as easy, so that's left to
another day. Thankfully that test suite is much smaller than the run-pass test
suite.
As a final fix I discovered that the ARM and Android test suites were actually
running all library unit tests (e.g. stdtest, coretest, etc) twice. I've
corrected that to only run tests once which should also give a nice boost in
overall cycle time here.
2017-04-26 08:52:19 -07:00
|
|
|
mode: Mode) {
|
2017-07-05 10:46:41 -06:00
|
|
|
let build = builder.build;
|
2017-01-28 13:38:06 -08:00
|
|
|
let out_dir = build.cargo_out(compiler, mode, target);
|
2017-06-26 10:23:50 -06:00
|
|
|
let tests = find_tests(&out_dir.join("deps"), target);
|
2017-01-28 13:38:06 -08:00
|
|
|
|
2017-07-05 06:41:27 -06:00
|
|
|
let tool = builder.tool_exe(Tool::RemoteTestClient);
|
2017-01-28 13:38:06 -08:00
|
|
|
for test in tests {
|
|
|
|
let mut cmd = Command::new(&tool);
|
|
|
|
cmd.arg("run")
|
|
|
|
.arg(&test);
|
|
|
|
if build.config.quiet_tests {
|
|
|
|
cmd.arg("--quiet");
|
|
|
|
}
|
|
|
|
cmd.args(&build.flags.cmd.test_args());
|
2017-06-02 09:27:44 -07:00
|
|
|
try_run(build, &mut cmd);
|
2017-01-28 13:38:06 -08:00
|
|
|
}
|
|
|
|
}
|
2016-09-05 19:56:48 -04:00
|
|
|
|
2017-07-13 18:48:44 -06:00
|
|
|
fn find_tests(dir: &Path, target: Interned<String>) -> Vec<PathBuf> {
|
2017-06-26 10:23:50 -06:00
|
|
|
let mut dst = Vec::new();
|
2016-06-28 13:31:30 -07:00
|
|
|
for e in t!(dir.read_dir()).map(|e| t!(e)) {
|
|
|
|
let file_type = t!(e.file_type());
|
|
|
|
if !file_type.is_file() {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
let filename = e.file_name().into_string().unwrap();
|
|
|
|
if (target.contains("windows") && filename.ends_with(".exe")) ||
|
2016-09-05 19:56:48 -04:00
|
|
|
(!target.contains("windows") && !filename.contains(".")) ||
|
2017-06-13 09:32:49 -03:00
|
|
|
(target.contains("emscripten") &&
|
|
|
|
filename.ends_with(".js") &&
|
|
|
|
!filename.ends_with(".asm.js")) {
|
2016-06-28 13:31:30 -07:00
|
|
|
dst.push(e.path());
|
|
|
|
}
|
|
|
|
}
|
2017-06-26 10:23:50 -06:00
|
|
|
dst
|
2016-06-28 13:31:30 -07:00
|
|
|
}
|
|
|
|
|
2017-07-12 10:12:47 -06:00
|
|
|
/// Some test suites are run inside emulators or on remote devices, and most
|
|
|
|
/// of our test binaries are linked dynamically which means we need to ship
|
|
|
|
/// the standard library and such to the emulator ahead of time. This step
|
|
|
|
/// represents this and is a dependency of all test suites.
|
|
|
|
///
|
|
|
|
/// Most of the time this is a noop. For some steps such as shipping data to
|
|
|
|
/// QEMU we have to build our own tools so we've got conditional dependencies
|
|
|
|
/// on those programs as well. Note that the remote test client is built for
|
|
|
|
/// the build target (us) and the server is built for the target.
|
2017-07-13 18:48:44 -06:00
|
|
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
|
|
|
pub struct RemoteCopyLibs {
|
|
|
|
compiler: Compiler,
|
|
|
|
target: Interned<String>,
|
2017-07-04 19:41:43 -06:00
|
|
|
}
|
2017-01-28 13:38:06 -08:00
|
|
|
|
2017-07-13 18:48:44 -06:00
|
|
|
impl Step for RemoteCopyLibs {
|
2017-07-04 19:41:43 -06:00
|
|
|
type Output = ();
|
2017-01-28 13:38:06 -08:00
|
|
|
|
2017-07-18 18:03:38 -06:00
|
|
|
fn should_run(run: ShouldRun) -> ShouldRun {
|
|
|
|
run.never()
|
2017-07-14 06:30:16 -06:00
|
|
|
}
|
|
|
|
|
2017-07-04 19:41:43 -06:00
|
|
|
fn run(self, builder: &Builder) {
|
|
|
|
let build = builder.build;
|
|
|
|
let compiler = self.compiler;
|
|
|
|
let target = self.target;
|
|
|
|
if !build.remote_tested(target) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2017-07-05 06:41:27 -06:00
|
|
|
builder.ensure(compile::Test { compiler, target });
|
|
|
|
|
2017-07-04 19:41:43 -06:00
|
|
|
println!("REMOTE copy libs to emulator ({})", target);
|
|
|
|
t!(fs::create_dir_all(build.out.join("tmp")));
|
2017-01-28 13:38:06 -08:00
|
|
|
|
2017-07-22 19:29:08 -06:00
|
|
|
let server = builder.ensure(tool::RemoteTestServer { compiler, target });
|
2017-07-04 19:41:43 -06:00
|
|
|
|
|
|
|
// Spawn the emulator and wait for it to come online
|
2017-07-05 06:41:27 -06:00
|
|
|
let tool = builder.tool_exe(Tool::RemoteTestClient);
|
2017-07-04 19:41:43 -06:00
|
|
|
let mut cmd = Command::new(&tool);
|
|
|
|
cmd.arg("spawn-emulator")
|
|
|
|
.arg(target)
|
|
|
|
.arg(&server)
|
|
|
|
.arg(build.out.join("tmp"));
|
|
|
|
if let Some(rootfs) = build.qemu_rootfs(target) {
|
|
|
|
cmd.arg(rootfs);
|
|
|
|
}
|
|
|
|
build.run(&mut cmd);
|
|
|
|
|
|
|
|
// Push all our dylibs to the emulator
|
2017-07-05 10:46:41 -06:00
|
|
|
for f in t!(builder.sysroot_libdir(compiler, target).read_dir()) {
|
2017-07-04 19:41:43 -06:00
|
|
|
let f = t!(f);
|
|
|
|
let name = f.file_name().into_string().unwrap();
|
|
|
|
if util::is_dylib(&name) {
|
|
|
|
build.run(Command::new(&tool)
|
|
|
|
.arg("push")
|
|
|
|
.arg(f.path()));
|
|
|
|
}
|
2017-01-28 13:38:06 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-13 18:48:44 -06:00
|
|
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
2017-07-04 19:41:43 -06:00
|
|
|
pub struct Distcheck;
|
2016-12-08 17:13:55 -08:00
|
|
|
|
2017-07-13 18:48:44 -06:00
|
|
|
impl Step for Distcheck {
|
2017-07-04 19:41:43 -06:00
|
|
|
type Output = ();
|
|
|
|
|
2017-07-18 18:03:38 -06:00
|
|
|
fn should_run(run: ShouldRun) -> ShouldRun {
|
|
|
|
run.path("distcheck")
|
2017-07-14 06:30:16 -06:00
|
|
|
}
|
|
|
|
|
2017-07-22 07:35:42 -06:00
|
|
|
fn make_run(run: RunConfig) {
|
|
|
|
run.builder.ensure(Distcheck);
|
|
|
|
}
|
|
|
|
|
2017-07-04 19:41:43 -06:00
|
|
|
/// Run "distcheck", a 'make check' from a tarball
|
|
|
|
fn run(self, builder: &Builder) {
|
|
|
|
let build = builder.build;
|
|
|
|
|
2017-07-13 18:48:44 -06:00
|
|
|
if *build.build != *"x86_64-unknown-linux-gnu" {
|
2017-07-04 19:41:43 -06:00
|
|
|
return
|
|
|
|
}
|
|
|
|
if !build.config.host.iter().any(|s| s == "x86_64-unknown-linux-gnu") {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if !build.config.target.iter().any(|s| s == "x86_64-unknown-linux-gnu") {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
println!("Distcheck");
|
|
|
|
let dir = build.out.join("tmp").join("distcheck");
|
|
|
|
let _ = fs::remove_dir_all(&dir);
|
|
|
|
t!(fs::create_dir_all(&dir));
|
|
|
|
|
2017-07-22 10:48:29 -06:00
|
|
|
// Guarantee that these are built before we begin running.
|
|
|
|
builder.ensure(dist::PlainSourceTarball);
|
|
|
|
builder.ensure(dist::Src);
|
|
|
|
|
2017-07-04 19:41:43 -06:00
|
|
|
let mut cmd = Command::new("tar");
|
|
|
|
cmd.arg("-xzf")
|
2017-07-12 18:52:31 -06:00
|
|
|
.arg(builder.ensure(dist::PlainSourceTarball))
|
2017-07-04 19:41:43 -06:00
|
|
|
.arg("--strip-components=1")
|
|
|
|
.current_dir(&dir);
|
|
|
|
build.run(&mut cmd);
|
|
|
|
build.run(Command::new("./configure")
|
|
|
|
.args(&build.config.configure_args)
|
|
|
|
.arg("--enable-vendor")
|
|
|
|
.current_dir(&dir));
|
|
|
|
build.run(Command::new(build_helper::make(&build.build))
|
|
|
|
.arg("check")
|
|
|
|
.current_dir(&dir));
|
|
|
|
|
|
|
|
// Now make sure that rust-src has all of libstd's dependencies
|
|
|
|
println!("Distcheck rust-src");
|
|
|
|
let dir = build.out.join("tmp").join("distcheck-src");
|
|
|
|
let _ = fs::remove_dir_all(&dir);
|
|
|
|
t!(fs::create_dir_all(&dir));
|
|
|
|
|
|
|
|
let mut cmd = Command::new("tar");
|
|
|
|
cmd.arg("-xzf")
|
2017-07-12 18:52:31 -06:00
|
|
|
.arg(builder.ensure(dist::Src))
|
2017-07-04 19:41:43 -06:00
|
|
|
.arg("--strip-components=1")
|
|
|
|
.current_dir(&dir);
|
|
|
|
build.run(&mut cmd);
|
|
|
|
|
|
|
|
let toml = dir.join("rust-src/lib/rustlib/src/rust/src/libstd/Cargo.toml");
|
|
|
|
build.run(Command::new(&build.initial_cargo)
|
|
|
|
.arg("generate-lockfile")
|
|
|
|
.arg("--manifest-path")
|
|
|
|
.arg(&toml)
|
|
|
|
.current_dir(&dir));
|
|
|
|
}
|
2016-12-08 17:13:55 -08:00
|
|
|
}
|
2016-12-30 19:50:57 -08:00
|
|
|
|
2017-07-13 18:48:44 -06:00
|
|
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
2017-07-04 19:41:43 -06:00
|
|
|
pub struct Bootstrap;
|
|
|
|
|
2017-07-13 18:48:44 -06:00
|
|
|
impl Step for Bootstrap {
|
2017-07-04 19:41:43 -06:00
|
|
|
type Output = ();
|
2017-07-05 06:41:27 -06:00
|
|
|
const DEFAULT: bool = true;
|
|
|
|
const ONLY_HOSTS: bool = true;
|
|
|
|
const ONLY_BUILD: bool = true;
|
2017-07-04 19:41:43 -06:00
|
|
|
|
|
|
|
/// Test the build system itself
|
|
|
|
fn run(self, builder: &Builder) {
|
|
|
|
let build = builder.build;
|
|
|
|
let mut cmd = Command::new(&build.initial_cargo);
|
|
|
|
cmd.arg("test")
|
|
|
|
.current_dir(build.src.join("src/bootstrap"))
|
|
|
|
.env("CARGO_TARGET_DIR", build.out.join("bootstrap"))
|
|
|
|
.env("RUSTC_BOOTSTRAP", "1")
|
|
|
|
.env("RUSTC", &build.initial_rustc);
|
|
|
|
if !build.fail_fast {
|
|
|
|
cmd.arg("--no-fail-fast");
|
|
|
|
}
|
|
|
|
cmd.arg("--").args(&build.flags.cmd.test_args());
|
|
|
|
try_run(build, &mut cmd);
|
2017-06-02 09:27:44 -07:00
|
|
|
}
|
2017-07-05 06:41:27 -06:00
|
|
|
|
2017-07-18 18:03:38 -06:00
|
|
|
fn should_run(run: ShouldRun) -> ShouldRun {
|
|
|
|
run.path("src/bootstrap")
|
2017-07-05 06:41:27 -06:00
|
|
|
}
|
|
|
|
|
2017-07-20 17:51:07 -06:00
|
|
|
fn make_run(run: RunConfig) {
|
|
|
|
run.builder.ensure(Bootstrap);
|
2017-07-05 06:41:27 -06:00
|
|
|
}
|
2016-12-30 19:50:57 -08:00
|
|
|
}
|