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