]> git.proxmox.com Git - rustc.git/blob - src/bootstrap/builder/tests.rs
New upstream version 1.63.0+dfsg1
[rustc.git] / src / bootstrap / builder / tests.rs
1 use super::*;
2 use crate::config::{Config, TargetSelection};
3 use std::thread;
4
5 fn configure(cmd: &str, host: &[&str], target: &[&str]) -> Config {
6 configure_with_args(&[cmd.to_owned()], host, target)
7 }
8
9 fn configure_with_args(cmd: &[String], host: &[&str], target: &[&str]) -> Config {
10 let mut config = Config::parse(cmd);
11 // don't save toolstates
12 config.save_toolstates = None;
13 config.dry_run = true;
14
15 // Ignore most submodules, since we don't need them for a dry run.
16 // But make sure to check out the `doc` and `rust-analyzer` submodules, since some steps need them
17 // just to know which commands to run.
18 let submodule_build = Build::new(Config {
19 // don't include LLVM, so CI doesn't require ninja/cmake to be installed
20 rust_codegen_backends: vec![],
21 ..Config::parse(&["check".to_owned()])
22 });
23 submodule_build.update_submodule(Path::new("src/doc/book"));
24 submodule_build.update_submodule(Path::new("src/tools/rust-analyzer"));
25 config.submodules = Some(false);
26
27 config.ninja_in_file = false;
28 // try to avoid spurious failures in dist where we create/delete each others file
29 // HACK: rather than pull in `tempdir`, use the one that cargo has conveniently created for us
30 let dir = Path::new(env!("OUT_DIR"))
31 .join("tmp-rustbuild-tests")
32 .join(&thread::current().name().unwrap_or("unknown").replace(":", "-"));
33 t!(fs::create_dir_all(&dir));
34 config.out = dir;
35 config.build = TargetSelection::from_user("A");
36 config.hosts = host.iter().map(|s| TargetSelection::from_user(s)).collect();
37 config.targets = target.iter().map(|s| TargetSelection::from_user(s)).collect();
38 config
39 }
40
41 fn first<A, B>(v: Vec<(A, B)>) -> Vec<A> {
42 v.into_iter().map(|(a, _)| a).collect::<Vec<_>>()
43 }
44
45 fn run_build(paths: &[PathBuf], config: Config) -> Cache {
46 let kind = config.cmd.kind();
47 let build = Build::new(config);
48 let builder = Builder::new(&build);
49 builder.run_step_descriptions(&Builder::get_step_descriptions(kind), paths);
50 builder.cache
51 }
52
53 fn check_cli<const N: usize>(paths: [&str; N]) {
54 run_build(
55 &paths.map(PathBuf::from),
56 configure_with_args(&paths.map(String::from), &["A"], &["A"]),
57 );
58 }
59
60 #[test]
61 fn test_valid() {
62 // make sure multi suite paths are accepted
63 check_cli(["test", "src/test/ui/attr-start.rs", "src/test/ui/attr-shebang.rs"]);
64 }
65
66 #[test]
67 #[should_panic]
68 fn test_invalid() {
69 // make sure that invalid paths are caught, even when combined with valid paths
70 check_cli(["test", "library/std", "x"]);
71 }
72
73 #[test]
74 fn test_intersection() {
75 let set = PathSet::Set(
76 ["library/core", "library/alloc", "library/std"].into_iter().map(TaskPath::parse).collect(),
77 );
78 let mut command_paths =
79 vec![Path::new("library/core"), Path::new("library/alloc"), Path::new("library/stdarch")];
80 let subset = set.intersection_removing_matches(&mut command_paths, None);
81 assert_eq!(
82 subset,
83 PathSet::Set(["library/core", "library/alloc"].into_iter().map(TaskPath::parse).collect())
84 );
85 assert_eq!(command_paths, vec![Path::new("library/stdarch")]);
86 }
87
88 #[test]
89 fn test_exclude() {
90 let mut config = configure("test", &["A"], &["A"]);
91 config.exclude = vec![TaskPath::parse("src/tools/tidy")];
92 let cache = run_build(&[], config);
93
94 // Ensure we have really excluded tidy
95 assert!(!cache.contains::<test::Tidy>());
96
97 // Ensure other tests are not affected.
98 assert!(cache.contains::<test::RustdocUi>());
99 }
100
101 #[test]
102 fn test_exclude_kind() {
103 let path = PathBuf::from("src/tools/cargotest");
104 let exclude = TaskPath::parse("test::src/tools/cargotest");
105 assert_eq!(exclude, TaskPath { kind: Some(Kind::Test), path: path.clone() });
106
107 let mut config = configure("test", &["A"], &["A"]);
108 // Ensure our test is valid, and `test::Cargotest` would be run without the exclude.
109 assert!(run_build(&[path.clone()], config.clone()).contains::<test::Cargotest>());
110 // Ensure tests for cargotest are skipped.
111 config.exclude = vec![exclude.clone()];
112 assert!(!run_build(&[path.clone()], config).contains::<test::Cargotest>());
113
114 // Ensure builds for cargotest are not skipped.
115 let mut config = configure("build", &["A"], &["A"]);
116 config.exclude = vec![exclude];
117 assert!(run_build(&[path], config).contains::<tool::CargoTest>());
118 }
119
120 mod defaults {
121 use super::{configure, first, run_build};
122 use crate::builder::*;
123 use crate::Config;
124 use pretty_assertions::assert_eq;
125
126 #[test]
127 fn build_default() {
128 let mut cache = run_build(&[], configure("build", &["A"], &["A"]));
129
130 let a = TargetSelection::from_user("A");
131 assert_eq!(
132 first(cache.all::<compile::Std>()),
133 &[
134 compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a },
135 compile::Std { compiler: Compiler { host: a, stage: 1 }, target: a },
136 ]
137 );
138 assert!(!cache.all::<compile::Assemble>().is_empty());
139 // Make sure rustdoc is only built once.
140 assert_eq!(
141 first(cache.all::<tool::Rustdoc>()),
142 // Recall that rustdoc stages are off-by-one
143 // - this is the compiler it's _linked_ to, not built with.
144 &[tool::Rustdoc { compiler: Compiler { host: a, stage: 1 } }],
145 );
146 assert_eq!(
147 first(cache.all::<compile::Rustc>()),
148 &[compile::Rustc { compiler: Compiler { host: a, stage: 0 }, target: a },]
149 );
150 }
151
152 #[test]
153 fn build_stage_0() {
154 let config = Config { stage: 0, ..configure("build", &["A"], &["A"]) };
155 let mut cache = run_build(&[], config);
156
157 let a = TargetSelection::from_user("A");
158 assert_eq!(
159 first(cache.all::<compile::Std>()),
160 &[compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a },]
161 );
162 assert!(!cache.all::<compile::Assemble>().is_empty());
163 assert_eq!(
164 first(cache.all::<tool::Rustdoc>()),
165 // This is the beta rustdoc.
166 // Add an assert here to make sure this is the only rustdoc built.
167 &[tool::Rustdoc { compiler: Compiler { host: a, stage: 0 } }],
168 );
169 assert!(cache.all::<compile::Rustc>().is_empty());
170 }
171
172 #[test]
173 fn build_cross_compile() {
174 let config = Config { stage: 1, ..configure("build", &["A", "B"], &["A", "B"]) };
175 let mut cache = run_build(&[], config);
176
177 let a = TargetSelection::from_user("A");
178 let b = TargetSelection::from_user("B");
179
180 // Ideally, this build wouldn't actually have `target: a`
181 // rustdoc/rustcc/std here (the user only requested a host=B build, so
182 // there's not really a need for us to build for target A in this case
183 // (since we're producing stage 1 libraries/binaries). But currently
184 // rustbuild is just a bit buggy here; this should be fixed though.
185 assert_eq!(
186 first(cache.all::<compile::Std>()),
187 &[
188 compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a },
189 compile::Std { compiler: Compiler { host: a, stage: 1 }, target: a },
190 compile::Std { compiler: Compiler { host: a, stage: 0 }, target: b },
191 compile::Std { compiler: Compiler { host: a, stage: 1 }, target: b },
192 ]
193 );
194 assert_eq!(
195 first(cache.all::<compile::Assemble>()),
196 &[
197 compile::Assemble { target_compiler: Compiler { host: a, stage: 0 } },
198 compile::Assemble { target_compiler: Compiler { host: a, stage: 1 } },
199 compile::Assemble { target_compiler: Compiler { host: b, stage: 1 } },
200 ]
201 );
202 assert_eq!(
203 first(cache.all::<tool::Rustdoc>()),
204 &[
205 tool::Rustdoc { compiler: Compiler { host: a, stage: 1 } },
206 tool::Rustdoc { compiler: Compiler { host: b, stage: 1 } },
207 ],
208 );
209 assert_eq!(
210 first(cache.all::<compile::Rustc>()),
211 &[
212 compile::Rustc { compiler: Compiler { host: a, stage: 0 }, target: a },
213 compile::Rustc { compiler: Compiler { host: a, stage: 0 }, target: b },
214 ]
215 );
216 }
217
218 #[test]
219 fn doc_default() {
220 let mut config = configure("doc", &["A"], &["A"]);
221 config.compiler_docs = true;
222 config.cmd = Subcommand::Doc { paths: Vec::new(), open: false };
223 let mut cache = run_build(&[], config);
224 let a = TargetSelection::from_user("A");
225
226 // error_index_generator uses stage 0 to share rustdoc artifacts with the
227 // rustdoc tool.
228 assert_eq!(first(cache.all::<doc::ErrorIndex>()), &[doc::ErrorIndex { target: a },]);
229 assert_eq!(
230 first(cache.all::<tool::ErrorIndex>()),
231 &[tool::ErrorIndex { compiler: Compiler { host: a, stage: 0 } }]
232 );
233 // docs should be built with the beta compiler, not with the stage0 artifacts.
234 // recall that rustdoc is off-by-one: `stage` is the compiler rustdoc is _linked_ to,
235 // not the one it was built by.
236 assert_eq!(
237 first(cache.all::<tool::Rustdoc>()),
238 &[tool::Rustdoc { compiler: Compiler { host: a, stage: 0 } },]
239 );
240 }
241 }
242
243 mod dist {
244 use super::{first, run_build, Config};
245 use crate::builder::*;
246 use pretty_assertions::assert_eq;
247
248 fn configure(host: &[&str], target: &[&str]) -> Config {
249 Config { stage: 2, ..super::configure("dist", host, target) }
250 }
251
252 #[test]
253 fn dist_baseline() {
254 let mut cache = run_build(&[], configure(&["A"], &["A"]));
255
256 let a = TargetSelection::from_user("A");
257
258 assert_eq!(first(cache.all::<dist::Docs>()), &[dist::Docs { host: a },]);
259 assert_eq!(first(cache.all::<dist::Mingw>()), &[dist::Mingw { host: a },]);
260 assert_eq!(
261 first(cache.all::<dist::Rustc>()),
262 &[dist::Rustc { compiler: Compiler { host: a, stage: 2 } },]
263 );
264 assert_eq!(
265 first(cache.all::<dist::Std>()),
266 &[dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a },]
267 );
268 assert_eq!(first(cache.all::<dist::Src>()), &[dist::Src]);
269 // Make sure rustdoc is only built once.
270 assert_eq!(
271 first(cache.all::<tool::Rustdoc>()),
272 &[tool::Rustdoc { compiler: Compiler { host: a, stage: 2 } },]
273 );
274 }
275
276 #[test]
277 fn dist_with_targets() {
278 let mut cache = run_build(&[], configure(&["A"], &["A", "B"]));
279
280 let a = TargetSelection::from_user("A");
281 let b = TargetSelection::from_user("B");
282
283 assert_eq!(
284 first(cache.all::<dist::Docs>()),
285 &[dist::Docs { host: a }, dist::Docs { host: b },]
286 );
287 assert_eq!(
288 first(cache.all::<dist::Mingw>()),
289 &[dist::Mingw { host: a }, dist::Mingw { host: b },]
290 );
291 assert_eq!(
292 first(cache.all::<dist::Rustc>()),
293 &[dist::Rustc { compiler: Compiler { host: a, stage: 2 } },]
294 );
295 assert_eq!(
296 first(cache.all::<dist::Std>()),
297 &[
298 dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a },
299 dist::Std { compiler: Compiler { host: a, stage: 2 }, target: b },
300 ]
301 );
302 assert_eq!(first(cache.all::<dist::Src>()), &[dist::Src]);
303 }
304
305 #[test]
306 fn dist_with_hosts() {
307 let mut cache = run_build(&[], configure(&["A", "B"], &["A", "B"]));
308
309 let a = TargetSelection::from_user("A");
310 let b = TargetSelection::from_user("B");
311
312 assert_eq!(
313 first(cache.all::<dist::Docs>()),
314 &[dist::Docs { host: a }, dist::Docs { host: b },]
315 );
316 assert_eq!(
317 first(cache.all::<dist::Mingw>()),
318 &[dist::Mingw { host: a }, dist::Mingw { host: b },]
319 );
320 assert_eq!(
321 first(cache.all::<dist::Rustc>()),
322 &[
323 dist::Rustc { compiler: Compiler { host: a, stage: 2 } },
324 dist::Rustc { compiler: Compiler { host: b, stage: 2 } },
325 ]
326 );
327 assert_eq!(
328 first(cache.all::<dist::Std>()),
329 &[
330 dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a },
331 dist::Std { compiler: Compiler { host: a, stage: 1 }, target: b },
332 ]
333 );
334 assert_eq!(
335 first(cache.all::<compile::Std>()),
336 &[
337 compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a },
338 compile::Std { compiler: Compiler { host: a, stage: 1 }, target: a },
339 compile::Std { compiler: Compiler { host: a, stage: 2 }, target: a },
340 compile::Std { compiler: Compiler { host: a, stage: 1 }, target: b },
341 compile::Std { compiler: Compiler { host: a, stage: 2 }, target: b },
342 ],
343 );
344 assert_eq!(first(cache.all::<dist::Src>()), &[dist::Src]);
345 }
346
347 #[test]
348 fn dist_only_cross_host() {
349 let a = TargetSelection::from_user("A");
350 let b = TargetSelection::from_user("B");
351 let mut config = configure(&["A", "B"], &["A", "B"]);
352 config.docs = false;
353 config.extended = true;
354 config.hosts = vec![b];
355 let mut cache = run_build(&[], config);
356
357 assert_eq!(
358 first(cache.all::<dist::Rustc>()),
359 &[dist::Rustc { compiler: Compiler { host: b, stage: 2 } },]
360 );
361 assert_eq!(
362 first(cache.all::<compile::Rustc>()),
363 &[
364 compile::Rustc { compiler: Compiler { host: a, stage: 0 }, target: a },
365 compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: b },
366 ]
367 );
368 }
369
370 #[test]
371 fn dist_with_targets_and_hosts() {
372 let mut cache = run_build(&[], configure(&["A", "B"], &["A", "B", "C"]));
373
374 let a = TargetSelection::from_user("A");
375 let b = TargetSelection::from_user("B");
376 let c = TargetSelection::from_user("C");
377
378 assert_eq!(
379 first(cache.all::<dist::Docs>()),
380 &[dist::Docs { host: a }, dist::Docs { host: b }, dist::Docs { host: c },]
381 );
382 assert_eq!(
383 first(cache.all::<dist::Mingw>()),
384 &[dist::Mingw { host: a }, dist::Mingw { host: b }, dist::Mingw { host: c },]
385 );
386 assert_eq!(
387 first(cache.all::<dist::Rustc>()),
388 &[
389 dist::Rustc { compiler: Compiler { host: a, stage: 2 } },
390 dist::Rustc { compiler: Compiler { host: b, stage: 2 } },
391 ]
392 );
393 assert_eq!(
394 first(cache.all::<dist::Std>()),
395 &[
396 dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a },
397 dist::Std { compiler: Compiler { host: a, stage: 1 }, target: b },
398 dist::Std { compiler: Compiler { host: a, stage: 2 }, target: c },
399 ]
400 );
401 assert_eq!(first(cache.all::<dist::Src>()), &[dist::Src]);
402 }
403
404 #[test]
405 fn dist_with_empty_host() {
406 let config = configure(&[], &["C"]);
407 let mut cache = run_build(&[], config);
408
409 let a = TargetSelection::from_user("A");
410 let c = TargetSelection::from_user("C");
411
412 assert_eq!(first(cache.all::<dist::Docs>()), &[dist::Docs { host: c },]);
413 assert_eq!(first(cache.all::<dist::Mingw>()), &[dist::Mingw { host: c },]);
414 assert_eq!(
415 first(cache.all::<dist::Std>()),
416 &[dist::Std { compiler: Compiler { host: a, stage: 2 }, target: c },]
417 );
418 }
419
420 #[test]
421 fn dist_with_same_targets_and_hosts() {
422 let mut cache = run_build(&[], configure(&["A", "B"], &["A", "B"]));
423
424 let a = TargetSelection::from_user("A");
425 let b = TargetSelection::from_user("B");
426
427 assert_eq!(
428 first(cache.all::<dist::Docs>()),
429 &[dist::Docs { host: a }, dist::Docs { host: b },]
430 );
431 assert_eq!(
432 first(cache.all::<dist::Mingw>()),
433 &[dist::Mingw { host: a }, dist::Mingw { host: b },]
434 );
435 assert_eq!(
436 first(cache.all::<dist::Rustc>()),
437 &[
438 dist::Rustc { compiler: Compiler { host: a, stage: 2 } },
439 dist::Rustc { compiler: Compiler { host: b, stage: 2 } },
440 ]
441 );
442 assert_eq!(
443 first(cache.all::<dist::Std>()),
444 &[
445 dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a },
446 dist::Std { compiler: Compiler { host: a, stage: 1 }, target: b },
447 ]
448 );
449 assert_eq!(first(cache.all::<dist::Src>()), &[dist::Src]);
450 assert_eq!(
451 first(cache.all::<compile::Std>()),
452 &[
453 compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a },
454 compile::Std { compiler: Compiler { host: a, stage: 1 }, target: a },
455 compile::Std { compiler: Compiler { host: a, stage: 2 }, target: a },
456 compile::Std { compiler: Compiler { host: a, stage: 1 }, target: b },
457 compile::Std { compiler: Compiler { host: a, stage: 2 }, target: b },
458 ]
459 );
460 assert_eq!(
461 first(cache.all::<compile::Assemble>()),
462 &[
463 compile::Assemble { target_compiler: Compiler { host: a, stage: 0 } },
464 compile::Assemble { target_compiler: Compiler { host: a, stage: 1 } },
465 compile::Assemble { target_compiler: Compiler { host: a, stage: 2 } },
466 compile::Assemble { target_compiler: Compiler { host: b, stage: 2 } },
467 ]
468 );
469 }
470
471 #[test]
472 fn build_all() {
473 let build = Build::new(configure(&["A", "B"], &["A", "B", "C"]));
474 let mut builder = Builder::new(&build);
475 builder.run_step_descriptions(
476 &Builder::get_step_descriptions(Kind::Build),
477 &["compiler/rustc".into(), "library/std".into()],
478 );
479
480 let a = TargetSelection::from_user("A");
481 let b = TargetSelection::from_user("B");
482 let c = TargetSelection::from_user("C");
483
484 assert_eq!(
485 first(builder.cache.all::<compile::Std>()),
486 &[
487 compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a },
488 compile::Std { compiler: Compiler { host: a, stage: 1 }, target: a },
489 compile::Std { compiler: Compiler { host: a, stage: 2 }, target: a },
490 compile::Std { compiler: Compiler { host: a, stage: 1 }, target: b },
491 compile::Std { compiler: Compiler { host: a, stage: 2 }, target: b },
492 compile::Std { compiler: Compiler { host: a, stage: 2 }, target: c },
493 ]
494 );
495 assert!(!builder.cache.all::<compile::Assemble>().is_empty());
496 assert_eq!(
497 first(builder.cache.all::<compile::Rustc>()),
498 &[
499 compile::Rustc { compiler: Compiler { host: a, stage: 0 }, target: a },
500 compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: a },
501 compile::Rustc { compiler: Compiler { host: a, stage: 2 }, target: a },
502 compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: b },
503 compile::Rustc { compiler: Compiler { host: a, stage: 2 }, target: b },
504 ]
505 );
506 }
507
508 #[test]
509 fn build_with_empty_host() {
510 let config = configure(&[], &["C"]);
511 let build = Build::new(config);
512 let mut builder = Builder::new(&build);
513 builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Build), &[]);
514
515 let a = TargetSelection::from_user("A");
516 let c = TargetSelection::from_user("C");
517
518 assert_eq!(
519 first(builder.cache.all::<compile::Std>()),
520 &[
521 compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a },
522 compile::Std { compiler: Compiler { host: a, stage: 1 }, target: a },
523 compile::Std { compiler: Compiler { host: a, stage: 2 }, target: c },
524 ]
525 );
526 assert_eq!(
527 first(builder.cache.all::<compile::Assemble>()),
528 &[
529 compile::Assemble { target_compiler: Compiler { host: a, stage: 0 } },
530 compile::Assemble { target_compiler: Compiler { host: a, stage: 1 } },
531 compile::Assemble { target_compiler: Compiler { host: a, stage: 2 } },
532 ]
533 );
534 assert_eq!(
535 first(builder.cache.all::<compile::Rustc>()),
536 &[
537 compile::Rustc { compiler: Compiler { host: a, stage: 0 }, target: a },
538 compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: a },
539 ]
540 );
541 }
542
543 #[test]
544 fn test_with_no_doc_stage0() {
545 let mut config = configure(&["A"], &["A"]);
546 config.stage = 0;
547 config.cmd = Subcommand::Test {
548 paths: vec!["library/std".into()],
549 skip: vec![],
550 test_args: vec![],
551 rustc_args: vec![],
552 fail_fast: true,
553 doc_tests: DocTests::No,
554 bless: false,
555 force_rerun: false,
556 compare_mode: None,
557 rustfix_coverage: false,
558 pass: None,
559 run: None,
560 };
561
562 let build = Build::new(config);
563 let mut builder = Builder::new(&build);
564
565 let host = TargetSelection::from_user("A");
566
567 builder.run_step_descriptions(
568 &[StepDescription::from::<test::Crate>(Kind::Test)],
569 &["library/std".into()],
570 );
571
572 // Ensure we don't build any compiler artifacts.
573 assert!(!builder.cache.contains::<compile::Rustc>());
574 assert_eq!(
575 first(builder.cache.all::<test::Crate>()),
576 &[test::Crate {
577 compiler: Compiler { host, stage: 0 },
578 target: host,
579 mode: Mode::Std,
580 test_kind: test::TestKind::Test,
581 crates: vec![INTERNER.intern_str("std")],
582 },]
583 );
584 }
585
586 #[test]
587 fn doc_ci() {
588 let mut config = configure(&["A"], &["A"]);
589 config.compiler_docs = true;
590 config.cmd = Subcommand::Doc { paths: Vec::new(), open: false };
591 let build = Build::new(config);
592 let mut builder = Builder::new(&build);
593 builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Doc), &[]);
594 let a = TargetSelection::from_user("A");
595
596 // error_index_generator uses stage 1 to share rustdoc artifacts with the
597 // rustdoc tool.
598 assert_eq!(
599 first(builder.cache.all::<doc::ErrorIndex>()),
600 &[doc::ErrorIndex { target: a },]
601 );
602 assert_eq!(
603 first(builder.cache.all::<tool::ErrorIndex>()),
604 &[tool::ErrorIndex { compiler: Compiler { host: a, stage: 1 } }]
605 );
606 // This is actually stage 1, but Rustdoc::run swaps out the compiler with
607 // stage minus 1 if --stage is not 0. Very confusing!
608 assert_eq!(
609 first(builder.cache.all::<tool::Rustdoc>()),
610 &[tool::Rustdoc { compiler: Compiler { host: a, stage: 2 } },]
611 );
612 }
613
614 #[test]
615 fn test_docs() {
616 // Behavior of `x.py test` doing various documentation tests.
617 let mut config = configure(&["A"], &["A"]);
618 config.cmd = Subcommand::Test {
619 paths: vec![],
620 skip: vec![],
621 test_args: vec![],
622 rustc_args: vec![],
623 fail_fast: true,
624 doc_tests: DocTests::Yes,
625 bless: false,
626 force_rerun: false,
627 compare_mode: None,
628 rustfix_coverage: false,
629 pass: None,
630 run: None,
631 };
632 // Make sure rustfmt binary not being found isn't an error.
633 config.channel = "beta".to_string();
634 let build = Build::new(config);
635 let mut builder = Builder::new(&build);
636
637 builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Test), &[]);
638 let a = TargetSelection::from_user("A");
639
640 // error_index_generator uses stage 1 to share rustdoc artifacts with the
641 // rustdoc tool.
642 assert_eq!(
643 first(builder.cache.all::<doc::ErrorIndex>()),
644 &[doc::ErrorIndex { target: a },]
645 );
646 assert_eq!(
647 first(builder.cache.all::<tool::ErrorIndex>()),
648 &[tool::ErrorIndex { compiler: Compiler { host: a, stage: 1 } }]
649 );
650 // Unfortunately rustdoc is built twice. Once from stage1 for compiletest
651 // (and other things), and once from stage0 for std crates. Ideally it
652 // would only be built once. If someone wants to fix this, it might be
653 // worth investigating if it would be possible to test std from stage1.
654 // Note that the stages here are +1 than what they actually are because
655 // Rustdoc::run swaps out the compiler with stage minus 1 if --stage is
656 // not 0.
657 //
658 // The stage 0 copy is the one downloaded for bootstrapping. It is
659 // (currently) needed to run "cargo test" on the linkchecker, and
660 // should be relatively "free".
661 assert_eq!(
662 first(builder.cache.all::<tool::Rustdoc>()),
663 &[
664 tool::Rustdoc { compiler: Compiler { host: a, stage: 0 } },
665 tool::Rustdoc { compiler: Compiler { host: a, stage: 1 } },
666 tool::Rustdoc { compiler: Compiler { host: a, stage: 2 } },
667 ]
668 );
669 }
670 }