1 use super::build_sysroot
;
3 use super::path
::{Dirs, RelPath}
;
4 use super::prepare
::GitRepo
;
5 use super::rustc_info
::get_host_triple
;
6 use super::utils
::{spawn_and_wait, spawn_and_wait_with_input, CargoProject, Compiler}
;
7 use super::SysrootKind
;
12 use std
::process
::Command
;
14 static BUILD_EXAMPLE_OUT_DIR
: RelPath
= RelPath
::BUILD
.join("example");
22 Custom { func: &'static dyn Fn(&TestRunner) }
,
23 BuildLib { source: &'static str, crate_types: &'static str }
,
24 BuildBinAndRun { source: &'static str, args: &'static [&'static str] }
,
25 JitBin { source: &'static str, args: &'static str }
,
29 // FIXME reduce usage of custom test case commands
30 const fn custom(config
: &'
static str, func
: &'
static dyn Fn(&TestRunner
)) -> Self {
31 Self { config, cmd: TestCaseCmd::Custom { func }
}
37 crate_types
: &'
static str,
39 Self { config, cmd: TestCaseCmd::BuildLib { source, crate_types }
}
42 const fn build_bin_and_run(
45 args
: &'
static [&'
static str],
47 Self { config, cmd: TestCaseCmd::BuildBinAndRun { source, args }
}
50 const fn jit_bin(config
: &'
static str, source
: &'
static str, args
: &'
static str) -> Self {
51 Self { config, cmd: TestCaseCmd::JitBin { source, args }
}
55 const NO_SYSROOT_SUITE
: &[TestCase
] = &[
56 TestCase
::build_lib("build.mini_core", "example/mini_core.rs", "lib,dylib"),
57 TestCase
::build_lib("build.example", "example/example.rs", "lib"),
58 TestCase
::jit_bin("jit.mini_core_hello_world", "example/mini_core_hello_world.rs", "abc bcd"),
59 TestCase
::build_bin_and_run(
60 "aot.mini_core_hello_world",
61 "example/mini_core_hello_world.rs",
66 const BASE_SYSROOT_SUITE
: &[TestCase
] = &[
67 TestCase
::build_bin_and_run(
68 "aot.arbitrary_self_types_pointers_and_wrappers",
69 "example/arbitrary_self_types_pointers_and_wrappers.rs",
72 TestCase
::build_bin_and_run(
73 "aot.issue_91827_extern_types",
74 "example/issue-91827-extern-types.rs",
77 TestCase
::build_lib("build.alloc_system", "example/alloc_system.rs", "lib"),
78 TestCase
::build_bin_and_run("aot.alloc_example", "example/alloc_example.rs", &[]),
79 TestCase
::jit_bin("jit.std_example", "example/std_example.rs", ""),
80 TestCase
::build_bin_and_run("aot.std_example", "example/std_example.rs", &["arg"]),
81 TestCase
::build_bin_and_run("aot.dst_field_align", "example/dst-field-align.rs", &[]),
82 TestCase
::build_bin_and_run(
83 "aot.subslice-patterns-const-eval",
84 "example/subslice-patterns-const-eval.rs",
87 TestCase
::build_bin_and_run(
88 "aot.track-caller-attribute",
89 "example/track-caller-attribute.rs",
92 TestCase
::build_bin_and_run("aot.float-minmax-pass", "example/float-minmax-pass.rs", &[]),
93 TestCase
::build_bin_and_run("aot.mod_bench", "example/mod_bench.rs", &[]),
94 TestCase
::build_bin_and_run("aot.issue-72793", "example/issue-72793.rs", &[]),
97 // FIXME(rust-random/rand#1293): Newer rand versions fail to test on Windows. Update once this is
99 pub(crate) static RAND_REPO
: GitRepo
=
100 GitRepo
::github("rust-random", "rand", "50b9a447410860af8d6db9a208c3576886955874", "rand");
102 pub(crate) static RAND
: CargoProject
= CargoProject
::new(&RAND_REPO
.source_dir(), "rand");
104 pub(crate) static REGEX_REPO
: GitRepo
=
105 GitRepo
::github("rust-lang", "regex", "a9b2e02352db92ce1f6e5b7ecd41b8bbffbe161a", "regex");
107 pub(crate) static REGEX
: CargoProject
= CargoProject
::new(®EX_REPO
.source_dir(), "regex");
109 pub(crate) static PORTABLE_SIMD_REPO
: GitRepo
= GitRepo
::github(
112 "9bd30e77b3a3c699af102ebb3df0f6110f8aa02e",
116 pub(crate) static PORTABLE_SIMD
: CargoProject
=
117 CargoProject
::new(&PORTABLE_SIMD_REPO
.source_dir(), "portable_simd");
119 pub(crate) static LIBCORE_TESTS_SRC
: RelPath
= RelPath
::DOWNLOAD
.join("coretests_src");
121 pub(crate) static LIBCORE_TESTS
: CargoProject
= CargoProject
::new(&LIBCORE_TESTS_SRC
, "core_tests");
123 const EXTENDED_SYSROOT_SUITE
: &[TestCase
] = &[
124 TestCase
::custom("test.rust-random/rand", &|runner
| {
125 RAND
.clean(&runner
.dirs
);
127 if runner
.is_native
{
128 let mut test_cmd
= RAND
.test(&runner
.target_compiler
, &runner
.dirs
);
129 test_cmd
.arg("--workspace").arg("--").arg("-q");
130 spawn_and_wait(test_cmd
);
132 eprintln
!("Cross-Compiling: Not running tests");
133 let mut build_cmd
= RAND
.build(&runner
.target_compiler
, &runner
.dirs
);
134 build_cmd
.arg("--workspace").arg("--tests");
135 spawn_and_wait(build_cmd
);
138 TestCase
::custom("test.libcore", &|runner
| {
139 LIBCORE_TESTS
.clean(&runner
.dirs
);
141 if runner
.is_native
{
142 let mut test_cmd
= LIBCORE_TESTS
.test(&runner
.target_compiler
, &runner
.dirs
);
143 test_cmd
.arg("--").arg("-q");
144 spawn_and_wait(test_cmd
);
146 eprintln
!("Cross-Compiling: Not running tests");
147 let mut build_cmd
= LIBCORE_TESTS
.build(&runner
.target_compiler
, &runner
.dirs
);
148 build_cmd
.arg("--tests");
149 spawn_and_wait(build_cmd
);
152 TestCase
::custom("test.regex-shootout-regex-dna", &|runner
| {
153 REGEX
.clean(&runner
.dirs
);
155 let mut build_cmd
= REGEX
.build(&runner
.target_compiler
, &runner
.dirs
);
156 build_cmd
.arg("--example").arg("shootout-regex-dna");
157 spawn_and_wait(build_cmd
);
159 if runner
.is_native
{
160 let mut run_cmd
= REGEX
.run(&runner
.target_compiler
, &runner
.dirs
);
161 run_cmd
.arg("--example").arg("shootout-regex-dna");
163 let input
= fs
::read_to_string(
164 REGEX
.source_dir(&runner
.dirs
).join("examples").join("regexdna-input.txt"),
167 let expected
= fs
::read_to_string(
168 REGEX
.source_dir(&runner
.dirs
).join("examples").join("regexdna-output.txt"),
172 let output
= spawn_and_wait_with_input(run_cmd
, input
);
174 let output_matches
= expected
.lines().eq(output
.lines());
176 println
!("Output files don't match!");
177 println
!("Expected Output:\n{}", expected
);
178 println
!("Actual Output:\n{}", output
);
180 std
::process
::exit(1);
184 TestCase
::custom("test.regex", &|runner
| {
185 REGEX
.clean(&runner
.dirs
);
187 if runner
.is_native
{
188 let mut run_cmd
= REGEX
.test(&runner
.target_compiler
, &runner
.dirs
);
189 run_cmd
.args(["--workspace", "--", "-q"]);
190 spawn_and_wait(run_cmd
);
192 eprintln
!("Cross-Compiling: Not running tests");
193 let mut build_cmd
= REGEX
.build(&runner
.target_compiler
, &runner
.dirs
);
194 build_cmd
.arg("--tests");
195 spawn_and_wait(build_cmd
);
198 TestCase
::custom("test.portable-simd", &|runner
| {
199 PORTABLE_SIMD
.clean(&runner
.dirs
);
201 let mut build_cmd
= PORTABLE_SIMD
.build(&runner
.target_compiler
, &runner
.dirs
);
202 build_cmd
.arg("--all-targets");
203 spawn_and_wait(build_cmd
);
205 if runner
.is_native
{
206 let mut test_cmd
= PORTABLE_SIMD
.test(&runner
.target_compiler
, &runner
.dirs
);
208 spawn_and_wait(test_cmd
);
213 pub(crate) fn run_tests(
216 sysroot_kind
: SysrootKind
,
217 cg_clif_dylib
: &Path
,
218 bootstrap_host_compiler
: &Compiler
,
219 target_triple
: String
,
221 if config
::get_bool("testsuite.no_sysroot") {
222 let target_compiler
= build_sysroot
::build_sysroot(
227 bootstrap_host_compiler
,
228 target_triple
.clone(),
232 TestRunner
::new(dirs
.clone(), target_compiler
, get_host_triple() == target_triple
);
234 BUILD_EXAMPLE_OUT_DIR
.ensure_fresh(dirs
);
235 runner
.run_testsuite(NO_SYSROOT_SUITE
);
237 eprintln
!("[SKIP] no_sysroot tests");
240 let run_base_sysroot
= config
::get_bool("testsuite.base_sysroot");
241 let run_extended_sysroot
= config
::get_bool("testsuite.extended_sysroot");
243 if run_base_sysroot
|| run_extended_sysroot
{
244 let target_compiler
= build_sysroot
::build_sysroot(
249 bootstrap_host_compiler
,
250 target_triple
.clone(),
254 TestRunner
::new(dirs
.clone(), target_compiler
, get_host_triple() == target_triple
);
256 if run_base_sysroot
{
257 runner
.run_testsuite(BASE_SYSROOT_SUITE
);
259 eprintln
!("[SKIP] base_sysroot tests");
262 if run_extended_sysroot
{
263 runner
.run_testsuite(EXTENDED_SYSROOT_SUITE
);
265 eprintln
!("[SKIP] extended_sysroot tests");
274 target_compiler
: Compiler
,
278 pub fn new(dirs
: Dirs
, mut target_compiler
: Compiler
, is_native
: bool
) -> Self {
279 if let Ok(rustflags
) = env
::var("RUSTFLAGS") {
280 target_compiler
.rustflags
.push(' '
);
281 target_compiler
.rustflags
.push_str(&rustflags
);
283 if let Ok(rustdocflags
) = env
::var("RUSTDOCFLAGS") {
284 target_compiler
.rustdocflags
.push(' '
);
285 target_compiler
.rustdocflags
.push_str(&rustdocflags
);
288 // FIXME fix `#[linkage = "extern_weak"]` without this
289 if target_compiler
.triple
.contains("darwin") {
290 target_compiler
.rustflags
.push_str(" -Clink-arg=-undefined -Clink-arg=dynamic_lookup");
293 let jit_supported
= is_native
294 && target_compiler
.triple
.contains("x86_64")
295 && !target_compiler
.triple
.contains("windows");
297 Self { is_native, jit_supported, dirs, target_compiler }
300 pub fn run_testsuite(&self, tests
: &[TestCase
]) {
301 for TestCase { config, cmd }
in tests
{
302 let (tag
, testname
) = config
.split_once('
.'
).unwrap();
303 let tag
= tag
.to_uppercase();
304 let is_jit_test
= tag
== "JIT";
306 if !config
::get_bool(config
) || (is_jit_test
&& !self.jit_supported
) {
307 eprintln
!("[{tag}] {testname} (skipped)");
310 eprintln
!("[{tag}] {testname}");
314 TestCaseCmd
::Custom { func }
=> func(self),
315 TestCaseCmd
::BuildLib { source, crate_types }
=> {
316 self.run_rustc([source
, "--crate-type", crate_types
]);
318 TestCaseCmd
::BuildBinAndRun { source, args }
=> {
319 self.run_rustc([source
]);
320 self.run_out_command(
321 source
.split('
/'
).last().unwrap().split('
.'
).next().unwrap(),
325 TestCaseCmd
::JitBin { source, args }
=> {
326 let mut jit_cmd
= self.rustc_command([
327 "-Zunstable-options",
328 "-Cllvm-args=mode=jit",
334 if !args
.is_empty() {
335 jit_cmd
.env("CG_CLIF_JIT_ARGS", args
);
337 spawn_and_wait(jit_cmd
);
339 eprintln
!("[JIT-lazy] {testname}");
340 let mut jit_cmd
= self.rustc_command([
341 "-Zunstable-options",
342 "-Cllvm-args=mode=jit-lazy",
348 if !args
.is_empty() {
349 jit_cmd
.env("CG_CLIF_JIT_ARGS", args
);
351 spawn_and_wait(jit_cmd
);
358 fn rustc_command
<I
, S
>(&self, args
: I
) -> Command
360 I
: IntoIterator
<Item
= S
>,
363 let mut cmd
= Command
::new(&self.target_compiler
.rustc
);
364 cmd
.args(self.target_compiler
.rustflags
.split_whitespace());
366 cmd
.arg(format
!("crate={}", BUILD_EXAMPLE_OUT_DIR
.to_path(&self.dirs
).display()));
367 cmd
.arg("--out-dir");
368 cmd
.arg(format
!("{}", BUILD_EXAMPLE_OUT_DIR
.to_path(&self.dirs
).display()));
369 cmd
.arg("-Cdebuginfo=2");
371 cmd
.arg(&self.target_compiler
.triple
);
372 cmd
.arg("-Cpanic=abort");
377 fn run_rustc
<I
, S
>(&self, args
: I
)
379 I
: IntoIterator
<Item
= S
>,
382 spawn_and_wait(self.rustc_command(args
));
385 fn run_out_command
<'a
>(&self, name
: &str, args
: &[&str]) {
386 let mut full_cmd
= vec
![];
388 // Prepend the RUN_WRAPPER's
389 if !self.target_compiler
.runner
.is_empty() {
390 full_cmd
.extend(self.target_compiler
.runner
.iter().cloned());
394 BUILD_EXAMPLE_OUT_DIR
.to_path(&self.dirs
).join(name
).to_str().unwrap().to_string(),
398 full_cmd
.push(arg
.to_string());
401 let mut cmd_iter
= full_cmd
.into_iter();
402 let first
= cmd_iter
.next().unwrap();
404 let mut cmd
= Command
::new(first
);