From d0b92a80224e1ed44434ed8546fa2ff497cc5312 Mon Sep 17 00:00:00 2001 From: mlugg Date: Sat, 13 Sep 2025 16:16:11 +0100 Subject: [PATCH] std.Build: do not expect server protocol for tests using immature backends For instance, when running a Zig test using the self-hosted aarch64 backend, this logic was previously expecting `std.zig.Server` to be used, but the default test runner intentionally does not do this because the backend is too immature to handle it. On 'master', this is causing sporadic failures; on this branch, they became consistent failures. --- lib/compiler/test_runner.zig | 8 +++++--- lib/std/Build.zig | 33 +++++++++++++++++++++++++++++++-- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/lib/compiler/test_runner.zig b/lib/compiler/test_runner.zig index adb3e9e90a..673ea2cb2d 100644 --- a/lib/compiler/test_runner.zig +++ b/lib/compiler/test_runner.zig @@ -17,7 +17,9 @@ var fba_buffer: [8192]u8 = undefined; var stdin_buffer: [4096]u8 = undefined; var stdout_buffer: [4096]u8 = undefined; -const crippled = switch (builtin.zig_backend) { +/// Keep in sync with logic in `std.Build.addRunArtifact` which decides whether +/// the test runner will communicate with the build runner via `std.zig.Server`. +const need_simple = switch (builtin.zig_backend) { .stage2_aarch64, .stage2_powerpc, .stage2_riscv64, @@ -33,7 +35,7 @@ pub fn main() void { return; } - if (crippled) { + if (need_simple) { return mainSimple() catch @panic("test failure\n"); } @@ -380,7 +382,7 @@ pub fn fuzz( // Some compiler backends are not capable of handling fuzz testing yet but // we still want CI test coverage enabled. - if (crippled) return; + if (need_simple) return; // Smoke test to ensure the test did not use conditional compilation to // contradict itself by making it not actually be a fuzz test when the test diff --git a/lib/std/Build.zig b/lib/std/Build.zig index c13b137ff6..9fd906e333 100644 --- a/lib/std/Build.zig +++ b/lib/std/Build.zig @@ -956,8 +956,37 @@ pub fn addRunArtifact(b: *Build, exe: *Step.Compile) *Step.Run { run_step.addArtifactArg(exe); } - const test_server_mode = if (exe.test_runner) |r| r.mode == .server else true; - if (test_server_mode) run_step.enableTestRunnerMode(); + const test_server_mode: bool = s: { + if (exe.test_runner) |r| break :s r.mode == .server; + if (exe.use_llvm == false) { + // The default test runner does not use the server protocol if the selected backend + // is too immature to support it. Keep this logic in sync with `need_simple` in the + // default test runner implementation. + switch (exe.rootModuleTarget().cpu.arch) { + // stage2_aarch64 + .aarch64, + .aarch64_be, + // stage2_powerpc + .powerpc, + .powerpcle, + .powerpc64, + .powerpc64le, + // stage2_riscv64 + .riscv64, + => break :s false, + + else => {}, + } + } + break :s true; + }; + if (test_server_mode) { + run_step.enableTestRunnerMode(); + } else if (exe.test_runner == null) { + // If a test runner does not use the `std.zig.Server` protocol, it can instead + // communicate failure via its exit code. + run_step.expectExitCode(0); + } } else { run_step.addArtifactArg(exe); }