blob: 23cc22c5cb3ae6b609e3fea4db79fbf4bb718af9 [file] [log] [blame]
Alex Crichtondefd1b32016-03-08 07:15:551// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2// file at the top-level directory of this distribution and at
3// http://rust-lang.org/COPYRIGHT.
4//
5// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8// option. This file may not be copied, modified, or distributed
9// except according to those terms.
10
Alex Crichton0e272de2016-11-16 20:31:1911//! Implementation of the test-related targets of the build system.
Alex Crichtonf72bfe62016-05-02 22:16:1512//!
13//! This file implements the various regression test suites that we execute on
14//! our CI.
15
Sébastien Mariea7d90252016-12-17 19:09:2316extern crate build_helper;
17
Alex Crichtona270b802016-10-21 20:18:0918use std::collections::HashSet;
Alex Crichtonbb9062a2016-04-29 21:23:1519use std::env;
Ulrik Sverdrupb1566ba2016-11-25 21:13:5920use std::fmt;
Mark Simulacrumdd1d75e2017-06-04 23:55:5021use std::fs::{self, File};
Alex Crichtonede89442016-04-15 01:00:3522use std::path::{PathBuf, Path};
23use std::process::Command;
Mark Simulacrumdd1d75e2017-06-04 23:55:5024use std::io::Read;
Alex Crichton73c2d2a2016-04-14 21:27:5125
Alex Crichton126e09e2016-04-14 22:51:0326use build_helper::output;
27
Alex Crichton48a07bf2016-07-06 04:58:2028use {Build, Compiler, Mode};
Alex Crichtond38db822016-12-09 01:13:5529use dist;
Alex Crichton1747ce22017-01-28 21:38:0630use util::{self, dylib_path, dylib_path_var, exe};
Alex Crichton39a5d3f2016-06-28 20:31:3031
Alex Crichton7bc2cbf2017-04-26 15:52:1932const ADB_TEST_DIR: &'static str = "/data/tmp/work";
Alex Crichtondefd1b32016-03-08 07:15:5533
Ulrik Sverdrupb1566ba2016-11-25 21:13:5934/// The two modes of the test runner; tests or benchmarks.
35#[derive(Copy, Clone)]
36pub enum TestKind {
37 /// Run `cargo test`
38 Test,
39 /// Run `cargo bench`
40 Bench,
41}
42
43impl TestKind {
44 // Return the cargo subcommand for this test kind
45 fn subcommand(self) -> &'static str {
46 match self {
47 TestKind::Test => "test",
48 TestKind::Bench => "bench",
49 }
50 }
51}
52
53impl fmt::Display for TestKind {
54 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
55 f.write_str(match *self {
56 TestKind::Test => "Testing",
57 TestKind::Bench => "Benchmarking",
58 })
59 }
60}
61
Josh Stone617aea42017-06-02 16:27:4462fn try_run(build: &Build, cmd: &mut Command) {
63 if build.flags.cmd.no_fail_fast() {
64 if !build.try_run(cmd) {
65 let failures = build.delayed_failures.get();
66 build.delayed_failures.set(failures + 1);
67 }
68 } else {
69 build.run(cmd);
70 }
71}
72
73fn try_run_quiet(build: &Build, cmd: &mut Command) {
74 if build.flags.cmd.no_fail_fast() {
75 if !build.try_run_quiet(cmd) {
76 let failures = build.delayed_failures.get();
77 build.delayed_failures.set(failures + 1);
78 }
79 } else {
80 build.run_quiet(cmd);
81 }
82}
83
Alex Crichtonf72bfe62016-05-02 22:16:1584/// Runs the `linkchecker` tool as compiled in `stage` by the `host` compiler.
85///
86/// This tool in `src/tools` will verify the validity of all our links in the
87/// documentation to ensure we don't have a bunch of dead ones.
Alex Crichton254876e2016-12-28 23:01:2188pub fn linkcheck(build: &Build, host: &str) {
89 println!("Linkcheck ({})", host);
90 let compiler = Compiler::new(0, host);
Alex Crichton0e272de2016-11-16 20:31:1991
92 let _time = util::timeit();
Josh Stone617aea42017-06-02 16:27:4493 try_run(build, build.tool_cmd(&compiler, "linkchecker")
94 .arg(build.out.join(host).join("doc")));
Alex Crichtondefd1b32016-03-08 07:15:5595}
Brian Anderson3a790ac2016-03-18 20:54:3196
Alex Crichtonf72bfe62016-05-02 22:16:1597/// Runs the `cargotest` tool as compiled in `stage` by the `host` compiler.
98///
99/// This tool in `src/tools` will check out a few Rust projects and run `cargo
100/// test` to ensure that we don't regress the test suites there.
Brian Anderson3a790ac2016-03-18 20:54:31101pub fn cargotest(build: &Build, stage: u32, host: &str) {
102 let ref compiler = Compiler::new(stage, host);
Brian Anderson80199222016-04-06 18:03:42103
Alex Crichton73c2d2a2016-04-14 21:27:51104 // Note that this is a short, cryptic, and not scoped directory name. This
105 // is currently to minimize the length of path on Windows where we otherwise
106 // quickly run into path name limit constraints.
107 let out_dir = build.out.join("ct");
108 t!(fs::create_dir_all(&out_dir));
109
Alex Crichton0e272de2016-11-16 20:31:19110 let _time = util::timeit();
Alex Crichton254876e2016-12-28 23:01:21111 let mut cmd = Command::new(build.tool(&Compiler::new(0, host), "cargotest"));
112 build.prepare_tool_cmd(compiler, &mut cmd);
Josh Stone617aea42017-06-02 16:27:44113 try_run(build, cmd.arg(&build.cargo)
114 .arg(&out_dir)
115 .env("RUSTC", build.compiler_path(compiler))
116 .env("RUSTDOC", build.rustdoc(compiler)));
Alex Crichton009f45f2017-04-18 00:24:05117}
118
119/// Runs `cargo test` for `cargo` packaged with Rust.
120pub fn cargo(build: &Build, stage: u32, host: &str) {
121 let ref compiler = Compiler::new(stage, host);
122
123 // Configure PATH to find the right rustc. NB. we have to use PATH
124 // and not RUSTC because the Cargo test suite has tests that will
125 // fail if rustc is not spelled `rustc`.
126 let path = build.sysroot(compiler).join("bin");
127 let old_path = ::std::env::var("PATH").expect("");
128 let sep = if cfg!(windows) { ";" } else {":" };
129 let ref newpath = format!("{}{}{}", path.display(), sep, old_path);
130
131 let mut cargo = build.cargo(compiler, Mode::Tool, host, "test");
Alex Crichton5daf5572017-04-20 21:32:54132 cargo.arg("--manifest-path").arg(build.src.join("src/tools/cargo/Cargo.toml"));
Josh Stone617aea42017-06-02 16:27:44133 if build.flags.cmd.no_fail_fast() {
134 cargo.arg("--no-fail-fast");
135 }
Alex Crichton009f45f2017-04-18 00:24:05136
137 // Don't build tests dynamically, just a pain to work with
138 cargo.env("RUSTC_NO_PREFER_DYNAMIC", "1");
139
140 // Don't run cross-compile tests, we may not have cross-compiled libstd libs
141 // available.
142 cargo.env("CFG_DISABLE_CROSS_TESTS", "1");
143
Josh Stone617aea42017-06-02 16:27:44144 try_run(build, cargo.env("PATH", newpath));
Brian Anderson3a790ac2016-03-18 20:54:31145}
Alex Crichton9dd3c542016-03-29 20:14:52146
Alex Crichtonf72bfe62016-05-02 22:16:15147/// Runs the `tidy` tool as compiled in `stage` by the `host` compiler.
148///
149/// This tool in `src/tools` checks up on various bits and pieces of style and
150/// otherwise just implements a few lint-like checks that are specific to the
151/// compiler itself.
Alex Crichton254876e2016-12-28 23:01:21152pub fn tidy(build: &Build, host: &str) {
kennytme6e5dc02017-05-17 16:33:20153 let _folder = build.fold_output(|| "tidy");
Alex Crichton254876e2016-12-28 23:01:21154 println!("tidy check ({})", host);
155 let compiler = Compiler::new(0, host);
Eduard-Mihai Burtescud29f0bc2017-02-10 20:59:40156 let mut cmd = build.tool_cmd(&compiler, "tidy");
157 cmd.arg(build.src.join("src"));
158 if !build.config.vendor {
159 cmd.arg("--no-vendor");
160 }
kennytm6ac07872017-05-21 20:27:47161 if build.config.quiet_tests {
162 cmd.arg("--quiet");
163 }
Josh Stone617aea42017-06-02 16:27:44164 try_run(build, &mut cmd);
Alex Crichton9dd3c542016-03-29 20:14:52165}
Alex Crichtonb325baf2016-04-05 18:34:23166
167fn testdir(build: &Build, host: &str) -> PathBuf {
168 build.out.join(host).join("test")
169}
170
Alex Crichtonf72bfe62016-05-02 22:16:15171/// Executes the `compiletest` tool to run a suite of tests.
172///
173/// Compiles all tests with `compiler` for `target` with the specified
174/// compiletest `mode` and `suite` arguments. For example `mode` can be
175/// "run-pass" or `suite` can be something like `debuginfo`.
Alex Crichtonb325baf2016-04-05 18:34:23176pub fn compiletest(build: &Build,
177 compiler: &Compiler,
178 target: &str,
179 mode: &str,
180 suite: &str) {
kennytme6e5dc02017-05-17 16:33:20181 let _folder = build.fold_output(|| format!("test_{}", suite));
Alex Crichton0e272de2016-11-16 20:31:19182 println!("Check compiletest suite={} mode={} ({} -> {})",
183 suite, mode, compiler.host, target);
Alex Crichton254876e2016-12-28 23:01:21184 let mut cmd = Command::new(build.tool(&Compiler::new(0, compiler.host),
185 "compiletest"));
186 build.prepare_tool_cmd(compiler, &mut cmd);
Alex Crichtonb325baf2016-04-05 18:34:23187
Alex Crichtonf72bfe62016-05-02 22:16:15188 // compiletest currently has... a lot of arguments, so let's just pass all
189 // of them!
190
Alex Crichtonb325baf2016-04-05 18:34:23191 cmd.arg("--compile-lib-path").arg(build.rustc_libdir(compiler));
192 cmd.arg("--run-lib-path").arg(build.sysroot_libdir(compiler, target));
193 cmd.arg("--rustc-path").arg(build.compiler_path(compiler));
194 cmd.arg("--rustdoc-path").arg(build.rustdoc(compiler));
195 cmd.arg("--src-base").arg(build.src.join("src/test").join(suite));
Alex Crichtonb325baf2016-04-05 18:34:23196 cmd.arg("--build-base").arg(testdir(build, compiler.host).join(suite));
197 cmd.arg("--stage-id").arg(format!("stage{}-{}", compiler.stage, target));
198 cmd.arg("--mode").arg(mode);
199 cmd.arg("--target").arg(target);
200 cmd.arg("--host").arg(compiler.host);
201 cmd.arg("--llvm-filecheck").arg(build.llvm_filecheck(&build.config.build));
202
Brian Anderson8401e372016-09-15 19:42:26203 if let Some(nodejs) = build.config.nodejs.as_ref() {
204 cmd.arg("--nodejs").arg(nodejs);
205 }
206
Alex Crichton39a5d3f2016-06-28 20:31:30207 let mut flags = vec!["-Crpath".to_string()];
Alex Crichtonf4e4ec72016-05-13 22:26:41208 if build.config.rust_optimize_tests {
Alex Crichton39a5d3f2016-06-28 20:31:30209 flags.push("-O".to_string());
Alex Crichtonf4e4ec72016-05-13 22:26:41210 }
211 if build.config.rust_debuginfo_tests {
Alex Crichton39a5d3f2016-06-28 20:31:30212 flags.push("-g".to_string());
Alex Crichtonf4e4ec72016-05-13 22:26:41213 }
214
Alex Crichton39a5d3f2016-06-28 20:31:30215 let mut hostflags = build.rustc_flags(&compiler.host);
216 hostflags.extend(flags.clone());
217 cmd.arg("--host-rustcflags").arg(hostflags.join(" "));
Alex Crichtonf4e4ec72016-05-13 22:26:41218
Alex Crichton39a5d3f2016-06-28 20:31:30219 let mut targetflags = build.rustc_flags(&target);
220 targetflags.extend(flags);
221 targetflags.push(format!("-Lnative={}",
222 build.test_helpers_out(target).display()));
223 cmd.arg("--target-rustcflags").arg(targetflags.join(" "));
Alex Crichtoncbe62922016-04-19 16:44:19224
Alex Crichton5f6261382016-11-14 16:04:39225 cmd.arg("--docck-python").arg(build.python());
Alex Crichtoncbe62922016-04-19 16:44:19226
227 if build.config.build.ends_with("apple-darwin") {
Corey Farwell97a1b6a2017-03-12 18:13:35228 // Force /usr/bin/python on macOS for LLDB tests because we're loading the
Alex Crichtoncbe62922016-04-19 16:44:19229 // LLDB plugin's compiled module which only works with the system python
230 // (namely not Homebrew-installed python)
231 cmd.arg("--lldb-python").arg("/usr/bin/python");
232 } else {
Alex Crichton5f6261382016-11-14 16:04:39233 cmd.arg("--lldb-python").arg(build.python());
Alex Crichtoncbe62922016-04-19 16:44:19234 }
Alex Crichtonb325baf2016-04-05 18:34:23235
Tim Neumanndce46002016-10-29 18:11:53236 if let Some(ref gdb) = build.config.gdb {
237 cmd.arg("--gdb").arg(gdb);
Alex Crichtonb325baf2016-04-05 18:34:23238 }
239 if let Some(ref vers) = build.lldb_version {
240 cmd.arg("--lldb-version").arg(vers);
241 }
242 if let Some(ref dir) = build.lldb_python_dir {
243 cmd.arg("--lldb-python-dir").arg(dir);
244 }
Alex Crichton96283fc2016-09-01 17:52:44245 let llvm_config = build.llvm_config(target);
246 let llvm_version = output(Command::new(&llvm_config).arg("--version"));
247 cmd.arg("--llvm-version").arg(llvm_version);
Alex Crichtonb325baf2016-04-05 18:34:23248
Alex Crichtona270b802016-10-21 20:18:09249 cmd.args(&build.flags.cmd.test_args());
Alex Crichtonb325baf2016-04-05 18:34:23250
Niko Matsakis83453bc2016-11-16 23:02:56251 if build.config.verbose() || build.flags.verbose() {
Alex Crichtonb325baf2016-04-05 18:34:23252 cmd.arg("--verbose");
253 }
254
Corey Farwellc8c6d2c2016-10-30 01:58:52255 if build.config.quiet_tests {
256 cmd.arg("--quiet");
257 }
258
Alex Crichtonf72bfe62016-05-02 22:16:15259 // Only pass correct values for these flags for the `run-make` suite as it
260 // requires that a C++ compiler was configured which isn't always the case.
Alex Crichton126e09e2016-04-14 22:51:03261 if suite == "run-make" {
Alex Crichton126e09e2016-04-14 22:51:03262 let llvm_components = output(Command::new(&llvm_config).arg("--components"));
263 let llvm_cxxflags = output(Command::new(&llvm_config).arg("--cxxflags"));
264 cmd.arg("--cc").arg(build.cc(target))
265 .arg("--cxx").arg(build.cxx(target))
266 .arg("--cflags").arg(build.cflags(target).join(" "))
267 .arg("--llvm-components").arg(llvm_components.trim())
268 .arg("--llvm-cxxflags").arg(llvm_cxxflags.trim());
269 } else {
270 cmd.arg("--cc").arg("")
271 .arg("--cxx").arg("")
272 .arg("--cflags").arg("")
273 .arg("--llvm-components").arg("")
274 .arg("--llvm-cxxflags").arg("");
275 }
276
Alex Crichton7bc2cbf2017-04-26 15:52:19277 if build.remote_tested(target) {
278 cmd.arg("--remote-test-client")
Alex Crichton1747ce22017-01-28 21:38:06279 .arg(build.tool(&Compiler::new(0, &build.config.build),
Alex Crichton7bc2cbf2017-04-26 15:52:19280 "remote-test-client"));
Alex Crichton1747ce22017-01-28 21:38:06281 }
282
Alex Crichton126e09e2016-04-14 22:51:03283 // Running a C compiler on MSVC requires a few env vars to be set, to be
284 // sure to set them here.
Alex Crichton0e272de2016-11-16 20:31:19285 //
286 // Note that if we encounter `PATH` we make sure to append to our own `PATH`
287 // rather than stomp over it.
Alex Crichton126e09e2016-04-14 22:51:03288 if target.contains("msvc") {
289 for &(ref k, ref v) in build.cc[target].0.env() {
290 if k != "PATH" {
291 cmd.env(k, v);
292 }
293 }
294 }
Alex Crichton21866602016-11-16 17:19:02295 cmd.env("RUSTC_BOOTSTRAP", "1");
Alex Crichton0e272de2016-11-16 20:31:19296 build.add_rust_test_threads(&mut cmd);
Alex Crichton126e09e2016-04-14 22:51:03297
Jorge Aparicio775a9362017-02-03 23:58:47298 if build.config.sanitizers {
299 cmd.env("SANITIZER_SUPPORT", "1");
300 }
301
Alex Crichton39a5d3f2016-06-28 20:31:30302 cmd.arg("--adb-path").arg("adb");
303 cmd.arg("--adb-test-dir").arg(ADB_TEST_DIR);
304 if target.contains("android") {
305 // Assume that cc for this target comes from the android sysroot
306 cmd.arg("--android-cross-path")
307 .arg(build.cc(target).parent().unwrap().parent().unwrap());
308 } else {
309 cmd.arg("--android-cross-path").arg("");
310 }
311
kennytme6e5dc02017-05-17 16:33:20312 build.ci_env.force_coloring_in_ci(&mut cmd);
313
Alex Crichton0e272de2016-11-16 20:31:19314 let _time = util::timeit();
Josh Stone617aea42017-06-02 16:27:44315 try_run(build, &mut cmd);
Alex Crichtonb325baf2016-04-05 18:34:23316}
Alex Crichtonede89442016-04-15 01:00:35317
Alex Crichtonf72bfe62016-05-02 22:16:15318/// Run `rustdoc --test` for all documentation in `src/doc`.
319///
320/// This will run all tests in our markdown documentation (e.g. the book)
321/// located in `src/doc`. The `rustdoc` that's run is the one that sits next to
322/// `compiler`.
Alex Crichtonede89442016-04-15 01:00:35323pub fn docs(build: &Build, compiler: &Compiler) {
Alex Crichtonf72bfe62016-05-02 22:16:15324 // Do a breadth-first traversal of the `src/doc` directory and just run
325 // tests for all files that end in `*.md`
Alex Crichtonede89442016-04-15 01:00:35326 let mut stack = vec![build.src.join("src/doc")];
Alex Crichton0e272de2016-11-16 20:31:19327 let _time = util::timeit();
kennytme6e5dc02017-05-17 16:33:20328 let _folder = build.fold_output(|| "test_docs");
Alex Crichtonede89442016-04-15 01:00:35329
330 while let Some(p) = stack.pop() {
331 if p.is_dir() {
Mark Simulacrumdd1d75e2017-06-04 23:55:50332 stack.extend(t!(p.read_dir()).map(|p| t!(p).path()).filter(|p| {
333 p.extension().and_then(|s| s.to_str()) == Some("md") &&
334 // The nostarch directory in the book is for no starch, and so isn't guaranteed to
335 // build. We don't care if it doesn't build, so skip it.
336 p.to_str().map_or(true, |p| !p.contains("nostarch"))
337 }));
Alex Crichtonede89442016-04-15 01:00:35338 continue
339 }
340
Alex Crichtonede89442016-04-15 01:00:35341 println!("doc tests for: {}", p.display());
342 markdown_test(build, compiler, &p);
343 }
344}
345
Alex Crichtonf72bfe62016-05-02 22:16:15346/// Run the error index generator tool to execute the tests located in the error
347/// index.
348///
349/// The `error_index_generator` tool lives in `src/tools` and is used to
350/// generate a markdown file from the error indexes of the code base which is
351/// then passed to `rustdoc --test`.
Alex Crichtonede89442016-04-15 01:00:35352pub fn error_index(build: &Build, compiler: &Compiler) {
kennytme6e5dc02017-05-17 16:33:20353 let _folder = build.fold_output(|| "test_error_index");
Alex Crichtonede89442016-04-15 01:00:35354 println!("Testing error-index stage{}", compiler.stage);
355
Alex Crichton860c6ab2016-11-08 17:59:46356 let dir = testdir(build, compiler.host);
357 t!(fs::create_dir_all(&dir));
358 let output = dir.join("error-index.md");
Alex Crichton0e272de2016-11-16 20:31:19359
360 let _time = util::timeit();
Alex Crichton254876e2016-12-28 23:01:21361 build.run(build.tool_cmd(&Compiler::new(0, compiler.host),
362 "error_index_generator")
Alex Crichtonede89442016-04-15 01:00:35363 .arg("markdown")
364 .arg(&output)
365 .env("CFG_BUILD", &build.config.build));
366
367 markdown_test(build, compiler, &output);
368}
369
370fn markdown_test(build: &Build, compiler: &Compiler, markdown: &Path) {
Mark Simulacrumdd1d75e2017-06-04 23:55:50371 let mut file = t!(File::open(markdown));
372 let mut contents = String::new();
373 t!(file.read_to_string(&mut contents));
374 if !contents.contains("```") {
375 return;
376 }
377
Alex Crichtonede89442016-04-15 01:00:35378 let mut cmd = Command::new(build.rustdoc(compiler));
379 build.add_rustc_lib_path(compiler, &mut cmd);
Alex Crichton0e272de2016-11-16 20:31:19380 build.add_rust_test_threads(&mut cmd);
Alex Crichtonede89442016-04-15 01:00:35381 cmd.arg("--test");
382 cmd.arg(markdown);
Alex Crichton6f62fae2016-12-12 17:03:35383 cmd.env("RUSTC_BOOTSTRAP", "1");
Corey Farwellc8c6d2c2016-10-30 01:58:52384
kennytm6ac07872017-05-21 20:27:47385 let test_args = build.flags.cmd.test_args().join(" ");
Corey Farwellc8c6d2c2016-10-30 01:58:52386 cmd.arg("--test-args").arg(test_args);
387
kennytm6ac07872017-05-21 20:27:47388 if build.config.quiet_tests {
Josh Stone617aea42017-06-02 16:27:44389 try_run_quiet(build, &mut cmd);
kennytm6ac07872017-05-21 20:27:47390 } else {
Josh Stone617aea42017-06-02 16:27:44391 try_run(build, &mut cmd);
kennytm6ac07872017-05-21 20:27:47392 }
Alex Crichtonede89442016-04-15 01:00:35393}
Alex Crichtonbb9062a2016-04-29 21:23:15394
395/// Run all unit tests plus documentation tests for an entire crate DAG defined
396/// by a `Cargo.toml`
397///
398/// This is what runs tests for crates like the standard library, compiler, etc.
399/// It essentially is the driver for running `cargo test`.
400///
401/// Currently this runs all tests for a DAG by passing a bunch of `-p foo`
Alex Crichton147e2da2016-10-07 06:30:38402/// arguments, and those arguments are discovered from `cargo metadata`.
Alex Crichtonbb9062a2016-04-29 21:23:15403pub fn krate(build: &Build,
404 compiler: &Compiler,
405 target: &str,
Alex Crichtona270b802016-10-21 20:18:09406 mode: Mode,
Ulrik Sverdrupb1566ba2016-11-25 21:13:59407 test_kind: TestKind,
Alex Crichtona270b802016-10-21 20:18:09408 krate: Option<&str>) {
Alex Crichton147e2da2016-10-07 06:30:38409 let (name, path, features, root) = match mode {
Ahmed Charles9ca382f2016-09-02 08:55:29410 Mode::Libstd => {
Alex Crichton40aaa652017-02-15 16:53:18411 ("libstd", "src/libstd", build.std_features(), "std")
Ahmed Charles9ca382f2016-09-02 08:55:29412 }
413 Mode::Libtest => {
Alex Crichton40aaa652017-02-15 16:53:18414 ("libtest", "src/libtest", String::new(), "test")
Ahmed Charles9ca382f2016-09-02 08:55:29415 }
416 Mode::Librustc => {
Alex Crichton147e2da2016-10-07 06:30:38417 ("librustc", "src/rustc", build.rustc_features(), "rustc-main")
Ahmed Charles9ca382f2016-09-02 08:55:29418 }
Alex Crichtonbb9062a2016-04-29 21:23:15419 _ => panic!("can only test libraries"),
420 };
kennytme6e5dc02017-05-17 16:33:20421 let _folder = build.fold_output(|| {
422 format!("{}_stage{}-{}", test_kind.subcommand(), compiler.stage, name)
423 });
Ulrik Sverdrupb1566ba2016-11-25 21:13:59424 println!("{} {} stage{} ({} -> {})", test_kind, name, compiler.stage,
Alex Crichtonbb9062a2016-04-29 21:23:15425 compiler.host, target);
426
Alex Crichton7046fea2016-12-25 23:20:33427 // If we're not doing a full bootstrap but we're testing a stage2 version of
428 // libstd, then what we're actually testing is the libstd produced in
429 // stage1. Reflect that here by updating the compiler that we're working
430 // with automatically.
431 let compiler = if build.force_use_stage1(compiler, target) {
432 Compiler::new(1, compiler.host)
433 } else {
434 compiler.clone()
435 };
436
Alex Crichtonbb9062a2016-04-29 21:23:15437 // Build up the base `cargo test` command.
Alex Crichton147e2da2016-10-07 06:30:38438 //
439 // Pass in some standard flags then iterate over the graph we've discovered
440 // in `cargo metadata` with the maps above and figure out what `-p`
441 // arguments need to get passed.
Alex Crichton7046fea2016-12-25 23:20:33442 let mut cargo = build.cargo(&compiler, mode, target, test_kind.subcommand());
Alex Crichtonbb9062a2016-04-29 21:23:15443 cargo.arg("--manifest-path")
444 .arg(build.src.join(path).join("Cargo.toml"))
445 .arg("--features").arg(features);
Josh Stone617aea42017-06-02 16:27:44446 if test_kind.subcommand() == "test" && build.flags.cmd.no_fail_fast() {
447 cargo.arg("--no-fail-fast");
448 }
Alex Crichtonbb9062a2016-04-29 21:23:15449
Alex Crichtona270b802016-10-21 20:18:09450 match krate {
451 Some(krate) => {
452 cargo.arg("-p").arg(krate);
Alex Crichtonbb9062a2016-04-29 21:23:15453 }
Alex Crichtona270b802016-10-21 20:18:09454 None => {
455 let mut visited = HashSet::new();
456 let mut next = vec![root];
457 while let Some(name) = next.pop() {
Alex Crichton36a926a2017-01-13 23:11:34458 // Right now jemalloc is our only target-specific crate in the
459 // sense that it's not present on all platforms. Custom skip it
460 // here for now, but if we add more this probably wants to get
461 // more generalized.
462 //
463 // Also skip `build_helper` as it's not compiled normally for
464 // target during the bootstrap and it's just meant to be a
465 // helper crate, not tested. If it leaks through then it ends up
466 // messing with various mtime calculations and such.
467 if !name.contains("jemalloc") && name != "build_helper" {
Vadim Petrochenkovb4abb722017-02-02 20:55:42468 cargo.arg("-p").arg(&format!("{}:0.0.0", name));
Alex Crichtona270b802016-10-21 20:18:09469 }
470 for dep in build.crates[name].deps.iter() {
471 if visited.insert(dep) {
472 next.push(dep);
473 }
474 }
Alex Crichtonbb9062a2016-04-29 21:23:15475 }
476 }
Alex Crichtonbb9062a2016-04-29 21:23:15477 }
478
479 // The tests are going to run with the *target* libraries, so we need to
480 // ensure that those libraries show up in the LD_LIBRARY_PATH equivalent.
481 //
482 // Note that to run the compiler we need to run with the *host* libraries,
483 // but our wrapper scripts arrange for that to be the case anyway.
484 let mut dylib_path = dylib_path();
Alex Crichton7046fea2016-12-25 23:20:33485 dylib_path.insert(0, build.sysroot_libdir(&compiler, target));
Alex Crichtonbb9062a2016-04-29 21:23:15486 cargo.env(dylib_path_var(), env::join_paths(&dylib_path).unwrap());
Alex Crichtonbb9062a2016-04-29 21:23:15487
Alex Crichton7bc2cbf2017-04-26 15:52:19488 if target.contains("emscripten") || build.remote_tested(target) {
Alex Crichton0e272de2016-11-16 20:31:19489 cargo.arg("--no-run");
490 }
491
492 cargo.arg("--");
493
Corey Farwellc8c6d2c2016-10-30 01:58:52494 if build.config.quiet_tests {
Corey Farwellc8c6d2c2016-10-30 01:58:52495 cargo.arg("--quiet");
496 }
497
Alex Crichton0e272de2016-11-16 20:31:19498 let _time = util::timeit();
499
Alex Crichton7bc2cbf2017-04-26 15:52:19500 if target.contains("emscripten") {
Alex Crichton0e272de2016-11-16 20:31:19501 build.run(&mut cargo);
Alex Crichton7046fea2016-12-25 23:20:33502 krate_emscripten(build, &compiler, target, mode);
Alex Crichton7bc2cbf2017-04-26 15:52:19503 } else if build.remote_tested(target) {
Alex Crichton1747ce22017-01-28 21:38:06504 build.run(&mut cargo);
Alex Crichton7bc2cbf2017-04-26 15:52:19505 krate_remote(build, &compiler, target, mode);
Alex Crichton39a5d3f2016-06-28 20:31:30506 } else {
Alex Crichtona270b802016-10-21 20:18:09507 cargo.args(&build.flags.cmd.test_args());
Josh Stone617aea42017-06-02 16:27:44508 try_run(build, &mut cargo);
Alex Crichton39a5d3f2016-06-28 20:31:30509 }
510}
511
Brian Andersonb8b50f02016-09-06 00:41:50512fn krate_emscripten(build: &Build,
513 compiler: &Compiler,
514 target: &str,
515 mode: Mode) {
Alex Crichton1747ce22017-01-28 21:38:06516 let mut tests = Vec::new();
517 let out_dir = build.cargo_out(compiler, mode, target);
Alex Crichton1747ce22017-01-28 21:38:06518 find_tests(&out_dir.join("deps"), target, &mut tests);
Ross Schulmanad9184c2016-09-05 23:56:48519
Alex Crichton1747ce22017-01-28 21:38:06520 for test in tests {
521 let test_file_name = test.to_string_lossy().into_owned();
522 println!("running {}", test_file_name);
523 let nodejs = build.config.nodejs.as_ref().expect("nodejs not configured");
524 let mut cmd = Command::new(nodejs);
525 cmd.arg(&test_file_name);
526 if build.config.quiet_tests {
527 cmd.arg("--quiet");
528 }
Josh Stone617aea42017-06-02 16:27:44529 try_run(build, &mut cmd);
Alex Crichton1747ce22017-01-28 21:38:06530 }
531}
532
Alex Crichton7bc2cbf2017-04-26 15:52:19533fn krate_remote(build: &Build,
534 compiler: &Compiler,
535 target: &str,
536 mode: Mode) {
Alex Crichton1747ce22017-01-28 21:38:06537 let mut tests = Vec::new();
538 let out_dir = build.cargo_out(compiler, mode, target);
Alex Crichton1747ce22017-01-28 21:38:06539 find_tests(&out_dir.join("deps"), target, &mut tests);
540
541 let tool = build.tool(&Compiler::new(0, &build.config.build),
Alex Crichton7bc2cbf2017-04-26 15:52:19542 "remote-test-client");
Alex Crichton1747ce22017-01-28 21:38:06543 for test in tests {
544 let mut cmd = Command::new(&tool);
545 cmd.arg("run")
546 .arg(&test);
547 if build.config.quiet_tests {
548 cmd.arg("--quiet");
549 }
550 cmd.args(&build.flags.cmd.test_args());
Josh Stone617aea42017-06-02 16:27:44551 try_run(build, &mut cmd);
Alex Crichton1747ce22017-01-28 21:38:06552 }
553}
Ross Schulmanad9184c2016-09-05 23:56:48554
Alex Crichton39a5d3f2016-06-28 20:31:30555fn find_tests(dir: &Path,
556 target: &str,
557 dst: &mut Vec<PathBuf>) {
558 for e in t!(dir.read_dir()).map(|e| t!(e)) {
559 let file_type = t!(e.file_type());
560 if !file_type.is_file() {
561 continue
562 }
563 let filename = e.file_name().into_string().unwrap();
564 if (target.contains("windows") && filename.ends_with(".exe")) ||
Ross Schulmanad9184c2016-09-05 23:56:48565 (!target.contains("windows") && !filename.contains(".")) ||
Tim Neumann4eeede32017-03-04 13:59:49566 (target.contains("emscripten") && filename.ends_with(".js")) {
Alex Crichton39a5d3f2016-06-28 20:31:30567 dst.push(e.path());
568 }
569 }
570}
571
Mátyás Mustohab194def2017-04-11 10:10:05572pub fn remote_copy_libs(build: &Build, compiler: &Compiler, target: &str) {
Alex Crichton7bc2cbf2017-04-26 15:52:19573 if !build.remote_tested(target) {
574 return
Alex Crichtoncf8fde12016-12-31 02:54:05575 }
576
Alex Crichton7bc2cbf2017-04-26 15:52:19577 println!("REMOTE copy libs to emulator ({})", target);
Alex Crichton1747ce22017-01-28 21:38:06578 t!(fs::create_dir_all(build.out.join("tmp")));
579
Alex Crichton1747ce22017-01-28 21:38:06580 let server = build.cargo_out(compiler, Mode::Tool, target)
Alex Crichton7bc2cbf2017-04-26 15:52:19581 .join(exe("remote-test-server", target));
Alex Crichton1747ce22017-01-28 21:38:06582
583 // Spawn the emulator and wait for it to come online
584 let tool = build.tool(&Compiler::new(0, &build.config.build),
Alex Crichton7bc2cbf2017-04-26 15:52:19585 "remote-test-client");
586 let mut cmd = Command::new(&tool);
587 cmd.arg("spawn-emulator")
588 .arg(target)
589 .arg(&server)
590 .arg(build.out.join("tmp"));
591 if let Some(rootfs) = build.qemu_rootfs(target) {
592 cmd.arg(rootfs);
593 }
594 build.run(&mut cmd);
Alex Crichton1747ce22017-01-28 21:38:06595
596 // Push all our dylibs to the emulator
597 for f in t!(build.sysroot_libdir(compiler, target).read_dir()) {
598 let f = t!(f);
599 let name = f.file_name().into_string().unwrap();
600 if util::is_dylib(&name) {
601 build.run(Command::new(&tool)
602 .arg("push")
603 .arg(f.path()));
604 }
605 }
606}
607
Alex Crichtond38db822016-12-09 01:13:55608/// Run "distcheck", a 'make check' from a tarball
609pub fn distcheck(build: &Build) {
610 if build.config.build != "x86_64-unknown-linux-gnu" {
611 return
612 }
613 if !build.config.host.iter().any(|s| s == "x86_64-unknown-linux-gnu") {
614 return
615 }
616 if !build.config.target.iter().any(|s| s == "x86_64-unknown-linux-gnu") {
617 return
618 }
619
Josh Stonec5cd4cb2017-04-26 19:37:12620 println!("Distcheck");
Alex Crichtond38db822016-12-09 01:13:55621 let dir = build.out.join("tmp").join("distcheck");
622 let _ = fs::remove_dir_all(&dir);
623 t!(fs::create_dir_all(&dir));
624
625 let mut cmd = Command::new("tar");
626 cmd.arg("-xzf")
627 .arg(dist::rust_src_location(build))
628 .arg("--strip-components=1")
629 .current_dir(&dir);
630 build.run(&mut cmd);
631 build.run(Command::new("./configure")
Alex Crichton4781eb32016-12-30 17:26:25632 .args(&build.config.configure_args)
Eduard-Mihai Burtescud29f0bc2017-02-10 20:59:40633 .arg("--enable-vendor")
Alex Crichtond38db822016-12-09 01:13:55634 .current_dir(&dir));
Sébastien Mariea7d90252016-12-17 19:09:23635 build.run(Command::new(build_helper::make(&build.config.build))
Alex Crichtond38db822016-12-09 01:13:55636 .arg("check")
637 .current_dir(&dir));
Josh Stonec5cd4cb2017-04-26 19:37:12638
639 // Now make sure that rust-src has all of libstd's dependencies
640 println!("Distcheck rust-src");
641 let dir = build.out.join("tmp").join("distcheck-src");
642 let _ = fs::remove_dir_all(&dir);
643 t!(fs::create_dir_all(&dir));
644
645 let mut cmd = Command::new("tar");
646 cmd.arg("-xzf")
647 .arg(dist::rust_src_installer(build))
648 .arg("--strip-components=1")
649 .current_dir(&dir);
650 build.run(&mut cmd);
651
652 let toml = dir.join("rust-src/lib/rustlib/src/rust/src/libstd/Cargo.toml");
653 build.run(Command::new(&build.cargo)
654 .arg("generate-lockfile")
655 .arg("--manifest-path")
656 .arg(&toml)
657 .current_dir(&dir));
Alex Crichtond38db822016-12-09 01:13:55658}
Alex Crichton1a040b32016-12-31 03:50:57659
660/// Test the build system itself
661pub fn bootstrap(build: &Build) {
662 let mut cmd = Command::new(&build.cargo);
663 cmd.arg("test")
664 .current_dir(build.src.join("src/bootstrap"))
665 .env("CARGO_TARGET_DIR", build.out.join("bootstrap"))
666 .env("RUSTC", &build.rustc);
Josh Stone617aea42017-06-02 16:27:44667 if build.flags.cmd.no_fail_fast() {
668 cmd.arg("--no-fail-fast");
669 }
Alex Crichton1a040b32016-12-31 03:50:57670 cmd.arg("--").args(&build.flags.cmd.test_args());
Josh Stone617aea42017-06-02 16:27:44671 try_run(build, &mut cmd);
Alex Crichton1a040b32016-12-31 03:50:57672}