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