Skip to content

Commit 3bd2561

Browse files
committed
Break out {Cargo,RustAnalyzer,Rustfmt,Clippy} into their own devtool_tests module
1 parent 89cc96d commit 3bd2561

File tree

2 files changed

+272
-246
lines changed

2 files changed

+272
-246
lines changed
Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,260 @@
1+
//! Test suites of the various devtools (cargo, rustfmt, rust-analyzer, etc.). Note that rustdoc is
2+
//! not here because it has special logic that isn't required by other devtool tests.
3+
4+
use std::ffi::OsString;
5+
use std::{env, fs, iter};
6+
7+
use super::test_helpers::{prepare_cargo_test, run_cargo_test};
8+
use crate::core::build_steps::compile;
9+
use crate::core::build_steps::tool::{self, SourceType};
10+
use crate::core::builder::{Builder, Compiler, Kind, RunConfig, ShouldRun, Step};
11+
use crate::core::config::TargetSelection;
12+
use crate::utils::helpers;
13+
use crate::utils::render_tests::add_flags_and_try_run_tests;
14+
use crate::{Mode, t};
15+
16+
/// Runs `cargo test` for cargo itself.
17+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
18+
pub struct Cargo {
19+
stage: u32,
20+
host: TargetSelection,
21+
}
22+
23+
impl Cargo {
24+
const CRATE_PATH: &str = "src/tools/cargo";
25+
}
26+
27+
impl Step for Cargo {
28+
type Output = ();
29+
const ONLY_HOSTS: bool = true;
30+
31+
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
32+
run.path(Self::CRATE_PATH)
33+
}
34+
35+
fn make_run(run: RunConfig<'_>) {
36+
run.builder.ensure(Cargo { stage: run.builder.top_stage, host: run.target });
37+
}
38+
39+
/// Runs `cargo test` for `cargo` packaged with Rust.
40+
fn run(self, builder: &Builder<'_>) {
41+
let compiler = builder.compiler(self.stage, self.host);
42+
43+
builder.ensure(tool::Cargo { compiler, target: self.host });
44+
let cargo = tool::prepare_tool_cargo(
45+
builder,
46+
compiler,
47+
Mode::ToolRustc,
48+
self.host,
49+
Kind::Test,
50+
Self::CRATE_PATH,
51+
SourceType::Submodule,
52+
&[],
53+
);
54+
55+
// NOTE: can't use `run_cargo_test` because we need to overwrite `PATH`
56+
let mut cargo = prepare_cargo_test(cargo, &[], &[], "cargo", self.host, builder);
57+
58+
// Don't run cross-compile tests, we may not have cross-compiled libstd libs
59+
// available.
60+
cargo.env("CFG_DISABLE_CROSS_TESTS", "1");
61+
// Forcibly disable tests using nightly features since any changes to
62+
// those features won't be able to land.
63+
cargo.env("CARGO_TEST_DISABLE_NIGHTLY", "1");
64+
65+
fn path_for_cargo(builder: &Builder<'_>, compiler: Compiler) -> OsString {
66+
// Configure PATH to find the right rustc. NB. we have to use PATH
67+
// and not RUSTC because the Cargo test suite has tests that will
68+
// fail if rustc is not spelled `rustc`.
69+
let path = builder.sysroot(compiler).join("bin");
70+
let old_path = env::var_os("PATH").unwrap_or_default();
71+
env::join_paths(iter::once(path).chain(env::split_paths(&old_path))).expect("")
72+
}
73+
74+
cargo.env("PATH", path_for_cargo(builder, compiler));
75+
// Cargo's test suite uses `CARGO_RUSTC_CURRENT_DIR` to determine the path that `file!` is
76+
// relative to. Cargo no longer sets this env var, so we have to do that. This has to be the
77+
// same value as `-Zroot-dir`.
78+
cargo.env("CARGO_RUSTC_CURRENT_DIR", builder.src.display().to_string());
79+
80+
#[cfg(feature = "build-metrics")]
81+
builder.metrics.begin_test_suite(
82+
build_helper::metrics::TestSuiteMetadata::CargoPackage {
83+
crates: vec!["cargo".into()],
84+
target: self.host.triple.to_string(),
85+
host: self.host.triple.to_string(),
86+
stage: self.stage,
87+
},
88+
builder,
89+
);
90+
91+
let _time = helpers::timeit(builder);
92+
add_flags_and_try_run_tests(builder, &mut cargo);
93+
}
94+
}
95+
96+
/// Runs `cargo test` for rustfmt.
97+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
98+
pub struct Rustfmt {
99+
stage: u32,
100+
host: TargetSelection,
101+
}
102+
103+
impl Step for Rustfmt {
104+
type Output = ();
105+
const ONLY_HOSTS: bool = true;
106+
107+
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
108+
run.path("src/tools/rustfmt")
109+
}
110+
111+
fn make_run(run: RunConfig<'_>) {
112+
run.builder.ensure(Rustfmt { stage: run.builder.top_stage, host: run.target });
113+
}
114+
115+
/// Runs `cargo test` for rustfmt.
116+
fn run(self, builder: &Builder<'_>) {
117+
let stage = self.stage;
118+
let host = self.host;
119+
let compiler = builder.compiler(stage, host);
120+
121+
builder.ensure(tool::Rustfmt { compiler, target: self.host });
122+
123+
let mut cargo = tool::prepare_tool_cargo(
124+
builder,
125+
compiler,
126+
Mode::ToolRustc,
127+
host,
128+
Kind::Test,
129+
"src/tools/rustfmt",
130+
SourceType::InTree,
131+
&[],
132+
);
133+
134+
let dir = builder.test_out(compiler.host);
135+
t!(fs::create_dir_all(&dir));
136+
cargo.env("RUSTFMT_TEST_DIR", dir);
137+
138+
cargo.add_rustc_lib_path(builder);
139+
140+
run_cargo_test(cargo, &[], &[], "rustfmt", "rustfmt", host, builder);
141+
}
142+
}
143+
144+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
145+
pub struct RustAnalyzer {
146+
stage: u32,
147+
host: TargetSelection,
148+
}
149+
150+
impl Step for RustAnalyzer {
151+
type Output = ();
152+
const ONLY_HOSTS: bool = true;
153+
const DEFAULT: bool = true;
154+
155+
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
156+
run.path("src/tools/rust-analyzer")
157+
}
158+
159+
fn make_run(run: RunConfig<'_>) {
160+
run.builder.ensure(Self { stage: run.builder.top_stage, host: run.target });
161+
}
162+
163+
/// Runs `cargo test` for rust-analyzer
164+
fn run(self, builder: &Builder<'_>) {
165+
let stage = self.stage;
166+
let host = self.host;
167+
let compiler = builder.compiler(stage, host);
168+
169+
// We don't need to build the whole Rust Analyzer for the proc-macro-srv test suite,
170+
// but we do need the standard library to be present.
171+
builder.ensure(compile::Rustc::new(compiler, host));
172+
173+
let workspace_path = "src/tools/rust-analyzer";
174+
// until the whole RA test suite runs on `i686`, we only run
175+
// `proc-macro-srv` tests
176+
let crate_path = "src/tools/rust-analyzer/crates/proc-macro-srv";
177+
let mut cargo = tool::prepare_tool_cargo(
178+
builder,
179+
compiler,
180+
Mode::ToolRustc,
181+
host,
182+
Kind::Test,
183+
crate_path,
184+
SourceType::InTree,
185+
&["in-rust-tree".to_owned()],
186+
);
187+
cargo.allow_features(tool::RustAnalyzer::ALLOW_FEATURES);
188+
189+
let dir = builder.src.join(workspace_path);
190+
// needed by rust-analyzer to find its own text fixtures, cf.
191+
// https://github.com/rust-analyzer/expect-test/issues/33
192+
cargo.env("CARGO_WORKSPACE_DIR", &dir);
193+
194+
// RA's test suite tries to write to the source directory, that can't
195+
// work in Rust CI
196+
cargo.env("SKIP_SLOW_TESTS", "1");
197+
198+
cargo.add_rustc_lib_path(builder);
199+
run_cargo_test(cargo, &[], &[], "rust-analyzer", "rust-analyzer", host, builder);
200+
}
201+
}
202+
203+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
204+
pub struct Clippy {
205+
stage: u32,
206+
host: TargetSelection,
207+
}
208+
209+
impl Step for Clippy {
210+
type Output = ();
211+
const ONLY_HOSTS: bool = true;
212+
const DEFAULT: bool = false;
213+
214+
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
215+
run.path("src/tools/clippy")
216+
}
217+
218+
fn make_run(run: RunConfig<'_>) {
219+
run.builder.ensure(Clippy { stage: run.builder.top_stage, host: run.target });
220+
}
221+
222+
/// Runs `cargo test` for clippy.
223+
fn run(self, builder: &Builder<'_>) {
224+
let stage = self.stage;
225+
let host = self.host;
226+
let compiler = builder.compiler(stage, host);
227+
228+
builder.ensure(tool::Clippy { compiler, target: self.host });
229+
let mut cargo = tool::prepare_tool_cargo(
230+
builder,
231+
compiler,
232+
Mode::ToolRustc,
233+
host,
234+
Kind::Test,
235+
"src/tools/clippy",
236+
SourceType::InTree,
237+
&[],
238+
);
239+
240+
cargo.env("RUSTC_TEST_SUITE", builder.rustc(compiler));
241+
cargo.env("RUSTC_LIB_PATH", builder.rustc_libdir(compiler));
242+
let host_libs = builder.stage_out(compiler, Mode::ToolRustc).join(builder.cargo_dir());
243+
cargo.env("HOST_LIBS", host_libs);
244+
245+
cargo.add_rustc_lib_path(builder);
246+
let cargo = prepare_cargo_test(cargo, &[], &[], "clippy", host, builder);
247+
248+
let _guard = builder.msg_sysroot_tool(Kind::Test, compiler.stage, "clippy", host, host);
249+
250+
// Clippy reports errors if it blessed the outputs
251+
if cargo.allow_failure().run(builder) {
252+
// The tests succeeded; nothing to do.
253+
return;
254+
}
255+
256+
if !builder.config.cmd.bless() {
257+
crate::exit!(1);
258+
}
259+
}
260+
}

0 commit comments

Comments
 (0)