]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_codegen_cranelift/build_system/tests.rs
bump version to 1.80.1+dfsg1-1~bpo12+pve1
[rustc.git] / compiler / rustc_codegen_cranelift / build_system / tests.rs
CommitLineData
f2b60f7d
FG
1use std::ffi::OsStr;
2use std::fs;
fe692bf9 3use std::path::PathBuf;
f2b60f7d
FG
4use std::process::Command;
5
add651ee
FG
6use crate::build_sysroot;
7use crate::config;
8use crate::path::{Dirs, RelPath};
9use crate::prepare::{apply_patches, GitRepo};
10use crate::rustc_info::get_default_sysroot;
11use crate::shared_utils::rustflags_from_env;
ed00b5ec 12use crate::utils::{spawn_and_wait, CargoProject, Compiler, LogGroup};
add651ee
FG
13use crate::{CodegenBackend, SysrootKind};
14
9c376795
FG
15static BUILD_EXAMPLE_OUT_DIR: RelPath = RelPath::BUILD.join("example");
16
f2b60f7d
FG
17struct TestCase {
18 config: &'static str,
9ffffee4
FG
19 cmd: TestCaseCmd,
20}
21
22enum TestCaseCmd {
fe692bf9 23 Custom { func: &'static dyn Fn(&TestRunner<'_>) },
9ffffee4 24 BuildLib { source: &'static str, crate_types: &'static str },
add651ee 25 BuildBin { source: &'static str },
9ffffee4
FG
26 BuildBinAndRun { source: &'static str, args: &'static [&'static str] },
27 JitBin { source: &'static str, args: &'static str },
f2b60f7d
FG
28}
29
30impl TestCase {
9ffffee4 31 // FIXME reduce usage of custom test case commands
fe692bf9 32 const fn custom(config: &'static str, func: &'static dyn Fn(&TestRunner<'_>)) -> Self {
9ffffee4
FG
33 Self { config, cmd: TestCaseCmd::Custom { func } }
34 }
35
36 const fn build_lib(
37 config: &'static str,
38 source: &'static str,
39 crate_types: &'static str,
40 ) -> Self {
41 Self { config, cmd: TestCaseCmd::BuildLib { source, crate_types } }
42 }
43
add651ee
FG
44 const fn build_bin(config: &'static str, source: &'static str) -> Self {
45 Self { config, cmd: TestCaseCmd::BuildBin { source } }
46 }
47
9ffffee4
FG
48 const fn build_bin_and_run(
49 config: &'static str,
50 source: &'static str,
51 args: &'static [&'static str],
52 ) -> Self {
53 Self { config, cmd: TestCaseCmd::BuildBinAndRun { source, args } }
54 }
55
56 const fn jit_bin(config: &'static str, source: &'static str, args: &'static str) -> Self {
57 Self { config, cmd: TestCaseCmd::JitBin { source, args } }
f2b60f7d
FG
58 }
59}
60
61const NO_SYSROOT_SUITE: &[TestCase] = &[
9ffffee4
FG
62 TestCase::build_lib("build.mini_core", "example/mini_core.rs", "lib,dylib"),
63 TestCase::build_lib("build.example", "example/example.rs", "lib"),
64 TestCase::jit_bin("jit.mini_core_hello_world", "example/mini_core_hello_world.rs", "abc bcd"),
65 TestCase::build_bin_and_run(
66 "aot.mini_core_hello_world",
67 "example/mini_core_hello_world.rs",
68 &["abc", "bcd"],
69 ),
f2b60f7d
FG
70];
71
72const BASE_SYSROOT_SUITE: &[TestCase] = &[
9ffffee4
FG
73 TestCase::build_bin_and_run(
74 "aot.arbitrary_self_types_pointers_and_wrappers",
75 "example/arbitrary_self_types_pointers_and_wrappers.rs",
76 &[],
77 ),
9ffffee4
FG
78 TestCase::build_lib("build.alloc_system", "example/alloc_system.rs", "lib"),
79 TestCase::build_bin_and_run("aot.alloc_example", "example/alloc_example.rs", &[]),
31ef2f64 80 TestCase::jit_bin("jit.std_example", "example/std_example.rs", "arg"),
9ffffee4
FG
81 TestCase::build_bin_and_run("aot.std_example", "example/std_example.rs", &["arg"]),
82 TestCase::build_bin_and_run("aot.dst_field_align", "example/dst-field-align.rs", &[]),
83 TestCase::build_bin_and_run(
84 "aot.subslice-patterns-const-eval",
85 "example/subslice-patterns-const-eval.rs",
86 &[],
87 ),
88 TestCase::build_bin_and_run(
89 "aot.track-caller-attribute",
90 "example/track-caller-attribute.rs",
91 &[],
92 ),
93 TestCase::build_bin_and_run("aot.float-minmax-pass", "example/float-minmax-pass.rs", &[]),
94 TestCase::build_bin_and_run("aot.mod_bench", "example/mod_bench.rs", &[]),
95 TestCase::build_bin_and_run("aot.issue-72793", "example/issue-72793.rs", &[]),
add651ee 96 TestCase::build_bin("aot.issue-59326", "example/issue-59326.rs"),
4b012472
FG
97 TestCase::custom("aot.polymorphize_coroutine", &|runner| {
98 runner.run_rustc(&["example/polymorphize_coroutine.rs", "-Zpolymorphize"]);
99 runner.run_out_command("polymorphize_coroutine", &[]);
100 }),
ed00b5ec 101 TestCase::build_bin_and_run("aot.neon", "example/neon.rs", &[]),
4b012472
FG
102 TestCase::custom("aot.gen_block_iterate", &|runner| {
103 runner.run_rustc([
104 "example/gen_block_iterate.rs",
105 "--edition",
106 "2024",
107 "-Zunstable-options",
108 ]);
109 runner.run_out_command("gen_block_iterate", &[]);
110 }),
f2b60f7d
FG
111];
112
fe692bf9
FG
113pub(crate) static RAND_REPO: GitRepo = GitRepo::github(
114 "rust-random",
115 "rand",
c0240ec0
FG
116 "1f4507a8e1cf8050e4ceef95eeda8f64645b6719",
117 "981f8bf489338978",
fe692bf9
FG
118 "rand",
119);
9c376795 120
fe692bf9 121pub(crate) static RAND: CargoProject = CargoProject::new(&RAND_REPO.source_dir(), "rand_target");
9c376795 122
fe692bf9
FG
123pub(crate) static REGEX_REPO: GitRepo = GitRepo::github(
124 "rust-lang",
125 "regex",
ed00b5ec
FG
126 "061ee815ef2c44101dba7b0b124600fcb03c1912",
127 "dc26aefbeeac03ca",
fe692bf9
FG
128 "regex",
129);
9c376795 130
fe692bf9 131pub(crate) static REGEX: CargoProject = CargoProject::new(&REGEX_REPO.source_dir(), "regex_target");
9c376795 132
e8be2606 133pub(crate) static PORTABLE_SIMD_SRC: RelPath = RelPath::BUILD.join("coretests");
9c376795 134
9ffffee4 135pub(crate) static PORTABLE_SIMD: CargoProject =
e8be2606 136 CargoProject::new(&PORTABLE_SIMD_SRC, "portable-simd_target");
9c376795 137
fe692bf9 138static LIBCORE_TESTS_SRC: RelPath = RelPath::BUILD.join("coretests");
353b0b11 139
fe692bf9 140static LIBCORE_TESTS: CargoProject = CargoProject::new(&LIBCORE_TESTS_SRC, "coretests_target");
9c376795 141
f2b60f7d 142const EXTENDED_SYSROOT_SUITE: &[TestCase] = &[
9ffffee4 143 TestCase::custom("test.rust-random/rand", &|runner| {
fe692bf9
FG
144 RAND_REPO.patch(&runner.dirs);
145
9ffffee4 146 RAND.clean(&runner.dirs);
9c376795
FG
147
148 if runner.is_native {
9c376795 149 let mut test_cmd = RAND.test(&runner.target_compiler, &runner.dirs);
353b0b11 150 test_cmd.arg("--workspace").arg("--").arg("-q");
9c376795
FG
151 spawn_and_wait(test_cmd);
152 } else {
353b0b11 153 eprintln!("Cross-Compiling: Not running tests");
9c376795
FG
154 let mut build_cmd = RAND.build(&runner.target_compiler, &runner.dirs);
155 build_cmd.arg("--workspace").arg("--tests");
156 spawn_and_wait(build_cmd);
157 }
f2b60f7d 158 }),
9ffffee4 159 TestCase::custom("test.libcore", &|runner| {
fe692bf9
FG
160 apply_patches(
161 &runner.dirs,
162 "coretests",
163 &runner.stdlib_source.join("library/core/tests"),
164 &LIBCORE_TESTS_SRC.to_path(&runner.dirs),
165 );
166
167 let source_lockfile = RelPath::PATCHES.to_path(&runner.dirs).join("coretests-lock.toml");
168 let target_lockfile = LIBCORE_TESTS_SRC.to_path(&runner.dirs).join("Cargo.lock");
169 fs::copy(source_lockfile, target_lockfile).unwrap();
170
9ffffee4 171 LIBCORE_TESTS.clean(&runner.dirs);
9c376795
FG
172
173 if runner.is_native {
353b0b11
FG
174 let mut test_cmd = LIBCORE_TESTS.test(&runner.target_compiler, &runner.dirs);
175 test_cmd.arg("--").arg("-q");
176 spawn_and_wait(test_cmd);
9c376795
FG
177 } else {
178 eprintln!("Cross-Compiling: Not running tests");
179 let mut build_cmd = LIBCORE_TESTS.build(&runner.target_compiler, &runner.dirs);
180 build_cmd.arg("--tests");
181 spawn_and_wait(build_cmd);
182 }
f2b60f7d 183 }),
9ffffee4 184 TestCase::custom("test.regex", &|runner| {
fe692bf9
FG
185 REGEX_REPO.patch(&runner.dirs);
186
9ffffee4 187 REGEX.clean(&runner.dirs);
9c376795 188
9c376795
FG
189 if runner.is_native {
190 let mut run_cmd = REGEX.test(&runner.target_compiler, &runner.dirs);
49aad941
FG
191 // regex-capi and regex-debug don't have any tests. Nor do they contain any code
192 // that is useful to test with cg_clif. Skip building them to reduce test time.
ed00b5ec
FG
193 run_cmd.args([
194 "-p",
195 "regex",
196 "-p",
197 "regex-syntax",
198 "--release",
199 "--all-targets",
200 "--",
201 "-q",
202 ]);
203 spawn_and_wait(run_cmd);
204
205 let mut run_cmd = REGEX.test(&runner.target_compiler, &runner.dirs);
206 // don't run integration tests for regex-autonata. they take like 2min each without
207 // much extra coverage of simd usage.
208 run_cmd.args(["-p", "regex-automata", "--release", "--lib", "--", "-q"]);
9c376795
FG
209 spawn_and_wait(run_cmd);
210 } else {
211 eprintln!("Cross-Compiling: Not running tests");
212 let mut build_cmd = REGEX.build(&runner.target_compiler, &runner.dirs);
213 build_cmd.arg("--tests");
9c376795
FG
214 spawn_and_wait(build_cmd);
215 }
f2b60f7d 216 }),
9ffffee4 217 TestCase::custom("test.portable-simd", &|runner| {
e8be2606
FG
218 apply_patches(
219 &runner.dirs,
220 "portable-simd",
221 &runner.stdlib_source.join("library/portable-simd"),
222 &PORTABLE_SIMD_SRC.to_path(&runner.dirs),
223 );
fe692bf9 224
9ffffee4 225 PORTABLE_SIMD.clean(&runner.dirs);
f2b60f7d 226
9c376795
FG
227 let mut build_cmd = PORTABLE_SIMD.build(&runner.target_compiler, &runner.dirs);
228 build_cmd.arg("--all-targets");
229 spawn_and_wait(build_cmd);
230
231 if runner.is_native {
232 let mut test_cmd = PORTABLE_SIMD.test(&runner.target_compiler, &runner.dirs);
233 test_cmd.arg("-q");
4b012472
FG
234 // FIXME remove after portable-simd update
235 test_cmd
236 .arg("--")
237 .arg("--skip")
238 .arg("core_simd::swizzle::simd_swizzle")
239 .arg("--skip")
240 .arg("core_simd::vector::Simd<T,N>::lanes");
9c376795
FG
241 spawn_and_wait(test_cmd);
242 }
f2b60f7d
FG
243 }),
244];
245
246pub(crate) fn run_tests(
9c376795 247 dirs: &Dirs,
f2b60f7d
FG
248 channel: &str,
249 sysroot_kind: SysrootKind,
fe692bf9
FG
250 use_unstable_features: bool,
251 skip_tests: &[&str],
252 cg_clif_dylib: &CodegenBackend,
9ffffee4 253 bootstrap_host_compiler: &Compiler,
fe692bf9 254 rustup_toolchain_name: Option<&str>,
9ffffee4 255 target_triple: String,
f2b60f7d 256) {
fe692bf9
FG
257 let stdlib_source =
258 get_default_sysroot(&bootstrap_host_compiler.rustc).join("lib/rustlib/src/rust");
259 assert!(stdlib_source.exists());
260
261 if config::get_bool("testsuite.no_sysroot") && !skip_tests.contains(&"testsuite.no_sysroot") {
9ffffee4 262 let target_compiler = build_sysroot::build_sysroot(
9c376795 263 dirs,
f2b60f7d
FG
264 channel,
265 SysrootKind::None,
2b03887a 266 cg_clif_dylib,
9ffffee4 267 bootstrap_host_compiler,
fe692bf9 268 rustup_toolchain_name,
9ffffee4 269 target_triple.clone(),
f2b60f7d
FG
270 );
271
49aad941
FG
272 let runner = TestRunner::new(
273 dirs.clone(),
274 target_compiler,
fe692bf9
FG
275 use_unstable_features,
276 skip_tests,
49aad941 277 bootstrap_host_compiler.triple == target_triple,
fe692bf9 278 stdlib_source.clone(),
49aad941 279 );
9ffffee4 280
9c376795 281 BUILD_EXAMPLE_OUT_DIR.ensure_fresh(dirs);
f2b60f7d
FG
282 runner.run_testsuite(NO_SYSROOT_SUITE);
283 } else {
284 eprintln!("[SKIP] no_sysroot tests");
285 }
286
fe692bf9
FG
287 let run_base_sysroot = config::get_bool("testsuite.base_sysroot")
288 && !skip_tests.contains(&"testsuite.base_sysroot");
289 let run_extended_sysroot = config::get_bool("testsuite.extended_sysroot")
290 && !skip_tests.contains(&"testsuite.extended_sysroot");
f2b60f7d
FG
291
292 if run_base_sysroot || run_extended_sysroot {
e8be2606 293 let target_compiler = build_sysroot::build_sysroot(
9c376795 294 dirs,
f2b60f7d
FG
295 channel,
296 sysroot_kind,
2b03887a 297 cg_clif_dylib,
9ffffee4 298 bootstrap_host_compiler,
fe692bf9 299 rustup_toolchain_name,
9ffffee4 300 target_triple.clone(),
f2b60f7d 301 );
f2b60f7d 302
e8be2606 303 let mut runner = TestRunner::new(
49aad941
FG
304 dirs.clone(),
305 target_compiler,
fe692bf9
FG
306 use_unstable_features,
307 skip_tests,
49aad941 308 bootstrap_host_compiler.triple == target_triple,
fe692bf9 309 stdlib_source,
49aad941 310 );
f2b60f7d 311
9ffffee4
FG
312 if run_base_sysroot {
313 runner.run_testsuite(BASE_SYSROOT_SUITE);
314 } else {
315 eprintln!("[SKIP] base_sysroot tests");
316 }
317
318 if run_extended_sysroot {
e8be2606
FG
319 // Rust's build system denies a couple of lints that trigger on several of the test
320 // projects. Changing the code to fix them is not worth it, so just silence all lints.
321 runner.target_compiler.rustflags.push("--cap-lints=allow".to_owned());
9ffffee4
FG
322 runner.run_testsuite(EXTENDED_SYSROOT_SUITE);
323 } else {
324 eprintln!("[SKIP] extended_sysroot tests");
325 }
f2b60f7d
FG
326 }
327}
328
fe692bf9 329struct TestRunner<'a> {
9c376795 330 is_native: bool,
f2b60f7d 331 jit_supported: bool,
fe692bf9
FG
332 use_unstable_features: bool,
333 skip_tests: &'a [&'a str],
9c376795 334 dirs: Dirs,
9c376795 335 target_compiler: Compiler,
fe692bf9 336 stdlib_source: PathBuf,
f2b60f7d
FG
337}
338
fe692bf9
FG
339impl<'a> TestRunner<'a> {
340 fn new(
341 dirs: Dirs,
342 mut target_compiler: Compiler,
343 use_unstable_features: bool,
344 skip_tests: &'a [&'a str],
345 is_native: bool,
346 stdlib_source: PathBuf,
347 ) -> Self {
add651ee
FG
348 target_compiler.rustflags.extend(rustflags_from_env("RUSTFLAGS"));
349 target_compiler.rustdocflags.extend(rustflags_from_env("RUSTDOCFLAGS"));
f2b60f7d
FG
350
351 // FIXME fix `#[linkage = "extern_weak"]` without this
9ffffee4 352 if target_compiler.triple.contains("darwin") {
add651ee
FG
353 target_compiler.rustflags.extend([
354 "-Clink-arg=-undefined".to_owned(),
355 "-Clink-arg=dynamic_lookup".to_owned(),
356 ]);
f2b60f7d
FG
357 }
358
fe692bf9
FG
359 let jit_supported = use_unstable_features
360 && is_native
9ffffee4
FG
361 && target_compiler.triple.contains("x86_64")
362 && !target_compiler.triple.contains("windows");
363
fe692bf9
FG
364 Self {
365 is_native,
366 jit_supported,
367 use_unstable_features,
368 skip_tests,
369 dirs,
370 target_compiler,
371 stdlib_source,
372 }
f2b60f7d
FG
373 }
374
49aad941 375 fn run_testsuite(&self, tests: &[TestCase]) {
9ffffee4 376 for TestCase { config, cmd } in tests {
f2b60f7d
FG
377 let (tag, testname) = config.split_once('.').unwrap();
378 let tag = tag.to_uppercase();
379 let is_jit_test = tag == "JIT";
380
add651ee 381 let _guard = if !config::get_bool(config)
fe692bf9
FG
382 || (is_jit_test && !self.jit_supported)
383 || self.skip_tests.contains(&config)
384 {
f2b60f7d
FG
385 eprintln!("[{tag}] {testname} (skipped)");
386 continue;
387 } else {
add651ee 388 let guard = LogGroup::guard(&format!("[{tag}] {testname}"));
f2b60f7d 389 eprintln!("[{tag}] {testname}");
add651ee
FG
390 guard
391 };
f2b60f7d 392
9ffffee4
FG
393 match *cmd {
394 TestCaseCmd::Custom { func } => func(self),
395 TestCaseCmd::BuildLib { source, crate_types } => {
fe692bf9
FG
396 if self.use_unstable_features {
397 self.run_rustc([source, "--crate-type", crate_types]);
398 } else {
399 self.run_rustc([
400 source,
401 "--crate-type",
402 crate_types,
403 "--cfg",
404 "no_unstable_features",
405 ]);
406 }
9ffffee4 407 }
add651ee
FG
408 TestCaseCmd::BuildBin { source } => {
409 if self.use_unstable_features {
410 self.run_rustc([source]);
411 } else {
412 self.run_rustc([source, "--cfg", "no_unstable_features"]);
413 }
414 }
9ffffee4 415 TestCaseCmd::BuildBinAndRun { source, args } => {
fe692bf9
FG
416 if self.use_unstable_features {
417 self.run_rustc([source]);
418 } else {
419 self.run_rustc([source, "--cfg", "no_unstable_features"]);
420 }
9ffffee4
FG
421 self.run_out_command(
422 source.split('/').last().unwrap().split('.').next().unwrap(),
423 args,
424 );
425 }
426 TestCaseCmd::JitBin { source, args } => {
427 let mut jit_cmd = self.rustc_command([
428 "-Zunstable-options",
429 "-Cllvm-args=mode=jit",
430 "-Cprefer-dynamic",
431 source,
432 "--cfg",
433 "jit",
434 ]);
435 if !args.is_empty() {
436 jit_cmd.env("CG_CLIF_JIT_ARGS", args);
437 }
438 spawn_and_wait(jit_cmd);
439
440 eprintln!("[JIT-lazy] {testname}");
441 let mut jit_cmd = self.rustc_command([
442 "-Zunstable-options",
443 "-Cllvm-args=mode=jit-lazy",
444 "-Cprefer-dynamic",
445 source,
446 "--cfg",
447 "jit",
448 ]);
449 if !args.is_empty() {
450 jit_cmd.env("CG_CLIF_JIT_ARGS", args);
451 }
452 spawn_and_wait(jit_cmd);
453 }
454 }
f2b60f7d
FG
455 }
456 }
457
9c376795 458 #[must_use]
f2b60f7d
FG
459 fn rustc_command<I, S>(&self, args: I) -> Command
460 where
461 I: IntoIterator<Item = S>,
462 S: AsRef<OsStr>,
463 {
9c376795 464 let mut cmd = Command::new(&self.target_compiler.rustc);
add651ee 465 cmd.args(&self.target_compiler.rustflags);
f2b60f7d 466 cmd.arg("-L");
9c376795 467 cmd.arg(format!("crate={}", BUILD_EXAMPLE_OUT_DIR.to_path(&self.dirs).display()));
f2b60f7d 468 cmd.arg("--out-dir");
9c376795 469 cmd.arg(format!("{}", BUILD_EXAMPLE_OUT_DIR.to_path(&self.dirs).display()));
f2b60f7d 470 cmd.arg("-Cdebuginfo=2");
9ffffee4
FG
471 cmd.arg("--target");
472 cmd.arg(&self.target_compiler.triple);
473 cmd.arg("-Cpanic=abort");
4b012472
FG
474 cmd.arg("-Zunstable-options");
475 cmd.arg("--check-cfg=cfg(no_unstable_features)");
476 cmd.arg("--check-cfg=cfg(jit)");
f2b60f7d
FG
477 cmd.args(args);
478 cmd
479 }
480
481 fn run_rustc<I, S>(&self, args: I)
482 where
483 I: IntoIterator<Item = S>,
484 S: AsRef<OsStr>,
485 {
486 spawn_and_wait(self.rustc_command(args));
487 }
488
49aad941 489 fn run_out_command(&self, name: &str, args: &[&str]) {
f2b60f7d
FG
490 let mut full_cmd = vec![];
491
492 // Prepend the RUN_WRAPPER's
9c376795
FG
493 if !self.target_compiler.runner.is_empty() {
494 full_cmd.extend(self.target_compiler.runner.iter().cloned());
f2b60f7d
FG
495 }
496
9c376795
FG
497 full_cmd.push(
498 BUILD_EXAMPLE_OUT_DIR.to_path(&self.dirs).join(name).to_str().unwrap().to_string(),
499 );
f2b60f7d 500
9ffffee4 501 for arg in args {
f2b60f7d
FG
502 full_cmd.push(arg.to_string());
503 }
504
505 let mut cmd_iter = full_cmd.into_iter();
506 let first = cmd_iter.next().unwrap();
507
508 let mut cmd = Command::new(first);
509 cmd.args(cmd_iter);
510
511 spawn_and_wait(cmd);
512 }
f2b60f7d 513}