From 50056a5b3ad29695c795534cebbd031408633813 Mon Sep 17 00:00:00 2001 From: Matthew Lugg Date: Tue, 14 Oct 2025 23:01:13 +0100 Subject: [PATCH] compiler: rename `--test-timeout-ms` to `--test-timeout` The unit can now be specified in the argument. --- ci/aarch64-linux-debug.sh | 2 +- ci/aarch64-linux-release.sh | 2 +- ci/aarch64-macos-debug.sh | 2 +- ci/aarch64-macos-release.sh | 2 +- ci/aarch64-windows.ps1 | 2 +- ci/loongarch64-linux-debug.sh | 2 +- ci/loongarch64-linux-release.sh | 2 +- ci/riscv64-linux-debug.sh | 2 +- ci/riscv64-linux-release.sh | 2 +- ci/x86_64-freebsd-debug.sh | 2 +- ci/x86_64-freebsd-release.sh | 2 +- ci/x86_64-linux-debug-llvm.sh | 2 +- ci/x86_64-linux-debug.sh | 2 +- ci/x86_64-linux-release.sh | 2 +- ci/x86_64-windows-debug.ps1 | 2 +- ci/x86_64-windows-release.ps1 | 2 +- lib/compiler/build_runner.zig | 51 ++++++++++++++++++++++++--------- lib/std/Build/Step/Run.zig | 2 +- 18 files changed, 55 insertions(+), 30 deletions(-) diff --git a/ci/aarch64-linux-debug.sh b/ci/aarch64-linux-debug.sh index 00cf48f513..29c815e816 100755 --- a/ci/aarch64-linux-debug.sh +++ b/ci/aarch64-linux-debug.sh @@ -51,7 +51,7 @@ stage3-debug/bin/zig build test docs \ --search-prefix "$PREFIX" \ --zig-lib-dir "$PWD/../lib" \ -Denable-superhtml \ - --test-timeout-ms 60_000 + --test-timeout 60s stage3-debug/bin/zig build \ --prefix stage4-debug \ diff --git a/ci/aarch64-linux-release.sh b/ci/aarch64-linux-release.sh index f0a341d962..26547d8b41 100755 --- a/ci/aarch64-linux-release.sh +++ b/ci/aarch64-linux-release.sh @@ -51,7 +51,7 @@ stage3-release/bin/zig build test docs \ --search-prefix "$PREFIX" \ --zig-lib-dir "$PWD/../lib" \ -Denable-superhtml \ - --test-timeout-ms 60_000 + --test-timeout 60s # Ensure that stage3 and stage4 are byte-for-byte identical. stage3-release/bin/zig build \ diff --git a/ci/aarch64-macos-debug.sh b/ci/aarch64-macos-debug.sh index 787df10de4..4afff42269 100755 --- a/ci/aarch64-macos-debug.sh +++ b/ci/aarch64-macos-debug.sh @@ -47,4 +47,4 @@ stage3-debug/bin/zig build test docs \ -Dstatic-llvm \ -Dskip-non-native \ --search-prefix "$PREFIX" \ - --test-timeout-ms 60_000 + --test-timeout 60s diff --git a/ci/aarch64-macos-release.sh b/ci/aarch64-macos-release.sh index 872a2f4ee7..8ddbe9773d 100755 --- a/ci/aarch64-macos-release.sh +++ b/ci/aarch64-macos-release.sh @@ -47,7 +47,7 @@ stage3-release/bin/zig build test docs \ -Dstatic-llvm \ -Dskip-non-native \ --search-prefix "$PREFIX" \ - --test-timeout-ms 60_000 + --test-timeout 60s # Ensure that stage3 and stage4 are byte-for-byte identical. stage3-release/bin/zig build \ diff --git a/ci/aarch64-windows.ps1 b/ci/aarch64-windows.ps1 index 4f52bd3f81..8720c7004d 100644 --- a/ci/aarch64-windows.ps1 +++ b/ci/aarch64-windows.ps1 @@ -59,7 +59,7 @@ Write-Output "Main test suite..." -Dstatic-llvm ` -Dskip-non-native ` -Denable-symlinks-windows ` - --test-timeout-ms 60_000 + --test-timeout 60s CheckLastExitCode # Ensure that stage3 and stage4 are byte-for-byte identical. diff --git a/ci/loongarch64-linux-debug.sh b/ci/loongarch64-linux-debug.sh index 47312bbde2..a2f1126f4f 100755 --- a/ci/loongarch64-linux-debug.sh +++ b/ci/loongarch64-linux-debug.sh @@ -51,7 +51,7 @@ stage3-debug/bin/zig build test docs \ -Dtarget=native-native-musl \ --search-prefix "$PREFIX" \ --zig-lib-dir "$PWD/../lib" \ - --test-timeout-ms 120_000 + --test-timeout 2m stage3-debug/bin/zig build \ --prefix stage4-debug \ diff --git a/ci/loongarch64-linux-release.sh b/ci/loongarch64-linux-release.sh index 62a5350285..2cb6229d9b 100755 --- a/ci/loongarch64-linux-release.sh +++ b/ci/loongarch64-linux-release.sh @@ -51,7 +51,7 @@ stage3-release/bin/zig build test docs \ -Dtarget=native-native-musl \ --search-prefix "$PREFIX" \ --zig-lib-dir "$PWD/../lib" \ - --test-timeout-ms 120_000 + --test-timeout 2m # Ensure that stage3 and stage4 are byte-for-byte identical. stage3-release/bin/zig build \ diff --git a/ci/riscv64-linux-debug.sh b/ci/riscv64-linux-debug.sh index 98bc72a439..84a82be8dc 100755 --- a/ci/riscv64-linux-debug.sh +++ b/ci/riscv64-linux-debug.sh @@ -52,4 +52,4 @@ stage3-debug/bin/zig build test-cases test-modules test-unit test-c-abi test-sta -Dtarget=native-native-musl \ --search-prefix "$PREFIX" \ --zig-lib-dir "$PWD/../lib" \ - --test-timeout-ms 120_000 + --test-timeout 2m diff --git a/ci/riscv64-linux-release.sh b/ci/riscv64-linux-release.sh index 4622277699..1aa31a6f8a 100755 --- a/ci/riscv64-linux-release.sh +++ b/ci/riscv64-linux-release.sh @@ -52,4 +52,4 @@ stage3-release/bin/zig build test-cases test-modules test-unit test-c-abi test-s -Dtarget=native-native-musl \ --search-prefix "$PREFIX" \ --zig-lib-dir "$PWD/../lib" \ - --test-timeout-ms 120_000 + --test-timeout 2m diff --git a/ci/x86_64-freebsd-debug.sh b/ci/x86_64-freebsd-debug.sh index ffc6d55226..9440af5e02 100755 --- a/ci/x86_64-freebsd-debug.sh +++ b/ci/x86_64-freebsd-debug.sh @@ -52,7 +52,7 @@ stage3-debug/bin/zig build test docs \ -Dskip-macos \ --search-prefix "$PREFIX" \ --zig-lib-dir "$PWD/../lib" \ - --test-timeout-ms 60_000 + --test-timeout 60s stage3-debug/bin/zig build \ --prefix stage4-debug \ diff --git a/ci/x86_64-freebsd-release.sh b/ci/x86_64-freebsd-release.sh index 09048d1e22..7f67e757ba 100755 --- a/ci/x86_64-freebsd-release.sh +++ b/ci/x86_64-freebsd-release.sh @@ -52,7 +52,7 @@ stage3-release/bin/zig build test docs \ -Dskip-macos \ --search-prefix "$PREFIX" \ --zig-lib-dir "$PWD/../lib" \ - --test-timeout-ms 60_000 + --test-timeout 60s # Ensure that stage3 and stage4 are byte-for-byte identical. stage3-release/bin/zig build \ diff --git a/ci/x86_64-linux-debug-llvm.sh b/ci/x86_64-linux-debug-llvm.sh index 560ca74ead..7eae6a355f 100755 --- a/ci/x86_64-linux-debug-llvm.sh +++ b/ci/x86_64-linux-debug-llvm.sh @@ -62,4 +62,4 @@ stage3-debug/bin/zig build test docs \ --search-prefix "$PREFIX" \ --zig-lib-dir "$PWD/../lib" \ -Denable-superhtml \ - --test-timeout-ms 240_000 + --test-timeout 4m diff --git a/ci/x86_64-linux-debug.sh b/ci/x86_64-linux-debug.sh index 663c8f834a..c9693bc1a7 100755 --- a/ci/x86_64-linux-debug.sh +++ b/ci/x86_64-linux-debug.sh @@ -62,4 +62,4 @@ stage3-debug/bin/zig build test docs \ --search-prefix "$PREFIX" \ --zig-lib-dir "$PWD/../lib" \ -Denable-superhtml \ - --test-timeout-ms 240_000 + --test-timeout 4m diff --git a/ci/x86_64-linux-release.sh b/ci/x86_64-linux-release.sh index fb91d69330..725bae0510 100755 --- a/ci/x86_64-linux-release.sh +++ b/ci/x86_64-linux-release.sh @@ -64,7 +64,7 @@ stage3-release/bin/zig build test docs \ --search-prefix "$PREFIX" \ --zig-lib-dir "$PWD/../lib" \ -Denable-superhtml \ - --test-timeout-ms 240_000 + --test-timeout 4m # Ensure that stage3 and stage4 are byte-for-byte identical. stage3-release/bin/zig build \ diff --git a/ci/x86_64-windows-debug.ps1 b/ci/x86_64-windows-debug.ps1 index 516a8e3444..873d3d5ff1 100644 --- a/ci/x86_64-windows-debug.ps1 +++ b/ci/x86_64-windows-debug.ps1 @@ -60,7 +60,7 @@ Write-Output "Main test suite..." -Dskip-non-native ` -Dskip-release ` -Denable-symlinks-windows ` - --test-timeout-ms 240_000 + --test-timeout 4m CheckLastExitCode Write-Output "Build x86_64-windows-msvc behavior tests using the C backend..." diff --git a/ci/x86_64-windows-release.ps1 b/ci/x86_64-windows-release.ps1 index 80568eeb37..f925894138 100644 --- a/ci/x86_64-windows-release.ps1 +++ b/ci/x86_64-windows-release.ps1 @@ -59,7 +59,7 @@ Write-Output "Main test suite..." -Dstatic-llvm ` -Dskip-non-native ` -Denable-symlinks-windows ` - --test-timeout-ms 240_000 + --test-timeout 4m CheckLastExitCode # Ensure that stage3 and stage4 are byte-for-byte identical. diff --git a/lib/compiler/build_runner.zig b/lib/compiler/build_runner.zig index 90bc591469..374bfa6ed3 100644 --- a/lib/compiler/build_runner.zig +++ b/lib/compiler/build_runner.zig @@ -108,7 +108,7 @@ pub fn main() !void { var summary: ?Summary = null; var max_rss: u64 = 0; var skip_oom_steps = false; - var test_timeout_ms: ?u64 = null; + var test_timeout_ns: ?u64 = null; var color: Color = .auto; var help_menu = false; var steps_menu = false; @@ -189,14 +189,41 @@ pub fn main() !void { }; } else if (mem.eql(u8, arg, "--skip-oom-steps")) { skip_oom_steps = true; - } else if (mem.eql(u8, arg, "--test-timeout-ms")) { - const millis_str = nextArgOrFatal(args, &arg_idx); - test_timeout_ms = std.fmt.parseInt(u64, millis_str, 10) catch |err| { - std.debug.print("invalid millisecond count: '{s}': {s}\n", .{ - millis_str, @errorName(err), - }); - process.exit(1); + } else if (mem.eql(u8, arg, "--test-timeout")) { + const units: []const struct { []const u8, u64 } = &.{ + .{ "ns", 1 }, + .{ "nanosecond", 1 }, + .{ "us", std.time.ns_per_us }, + .{ "microsecond", std.time.ns_per_us }, + .{ "ms", std.time.ns_per_ms }, + .{ "millisecond", std.time.ns_per_ms }, + .{ "s", std.time.ns_per_s }, + .{ "second", std.time.ns_per_s }, + .{ "m", std.time.ns_per_min }, + .{ "minute", std.time.ns_per_min }, + .{ "h", std.time.ns_per_hour }, + .{ "hour", std.time.ns_per_hour }, }; + const timeout_str = nextArgOrFatal(args, &arg_idx); + const num_end_idx = std.mem.findLastNone(u8, timeout_str, "abcdefghijklmnopqrstuvwxyz") orelse fatal( + "invalid timeout '{s}': expected unit (ns, us, ms, s, m, h)", + .{timeout_str}, + ); + const num_str = timeout_str[0 .. num_end_idx + 1]; + const unit_str = timeout_str[num_end_idx + 1 ..]; + const unit_factor: f64 = for (units) |unit_and_factor| { + if (std.mem.eql(u8, unit_str, unit_and_factor[0])) { + break @floatFromInt(unit_and_factor[1]); + } + } else fatal( + "invalid timeout '{s}': invalid unit '{s}' (expected ns, us, ms, s, m, h)", + .{ timeout_str, unit_str }, + ); + const num_parsed = std.fmt.parseFloat(f64, num_str) catch |err| fatal( + "invalid timeout '{s}': invalid number '{s}' ({t})", + .{ timeout_str, num_str, err }, + ); + test_timeout_ns = std.math.lossyCast(u64, unit_factor * num_parsed); } else if (mem.eql(u8, arg, "--search-prefix")) { const search_prefix = nextArgOrFatal(args, &arg_idx); builder.addSearchPrefix(search_prefix); @@ -480,10 +507,7 @@ pub fn main() !void { .max_rss_is_default = false, .max_rss_mutex = .{}, .skip_oom_steps = skip_oom_steps, - .unit_test_timeout_ns = ns: { - const ms = test_timeout_ms orelse break :ns null; - break :ns std.math.mul(u64, ms, std.time.ns_per_ms) catch null; - }, + .unit_test_timeout_ns = test_timeout_ns, .watch = watch, .web_server = undefined, // set after `prepare` @@ -1584,7 +1608,8 @@ fn printUsage(b: *std.Build, w: *Writer) !void { \\ -j Limit concurrent jobs (default is to use all CPU cores) \\ --maxrss Limit memory usage (default is to use available memory) \\ --skip-oom-steps Instead of failing, skip steps that would exceed --maxrss - \\ --test-timeout-ms Limit execution time of unit tests, terminating if exceeded + \\ --test-timeout Limit execution time of unit tests, terminating if exceeded. + \\ The timeout must include a unit: ns, us, ms, s, m, h \\ --fetch[=mode] Fetch dependency tree (optionally choose laziness) and exit \\ needed (Default) Lazy dependencies are fetched as needed \\ all Lazy dependencies are always fetched diff --git a/lib/std/Build/Step/Run.zig b/lib/std/Build/Step/Run.zig index 9a3c1f7906..cd29262612 100644 --- a/lib/std/Build/Step/Run.zig +++ b/lib/std/Build/Step/Run.zig @@ -1814,7 +1814,7 @@ fn pollZigTest( // test. For instance, if the test runner leaves this much time between us requesting a test to // start and it acknowledging the test starting, we terminate the child and raise an error. This // *should* never happen, but could in theory be caused by some very unlucky IB in a test. - const response_timeout_ns = options.unit_test_timeout_ns orelse 60 * std.time.ns_per_s; + const response_timeout_ns = @max(options.unit_test_timeout_ns orelse 0, 60 * std.time.ns_per_s); const stdout = poller.reader(.stdout); const stderr = poller.reader(.stderr);