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