From 31c2a47971317f027ac3132ff951f1ff55361a36 Mon Sep 17 00:00:00 2001 From: Joao Marcos Mororo Costa Date: Mon, 13 Oct 2025 15:17:42 -0300 Subject: [PATCH 1/2] Communicate the error when a test fails --- lib/compiler/test_runner.zig | 9 ++++++++- lib/std/Build/Step/Run.zig | 28 ++++++++++++++++------------ lib/std/zig/Server.zig | 8 +++++--- 3 files changed, 29 insertions(+), 16 deletions(-) diff --git a/lib/compiler/test_runner.zig b/lib/compiler/test_runner.zig index 42c708cbfc7f..19ca7a4635e2 100644 --- a/lib/compiler/test_runner.zig +++ b/lib/compiler/test_runner.zig @@ -135,9 +135,11 @@ fn mainServer() !void { var fail = false; var skip = false; is_fuzz_test = false; + var err_name: ?[]const u8 = null; test_fn.func() catch |err| switch (err) { error.SkipZigTest => skip = true, else => { + err_name = @errorName(err); fail = true; if (@errorReturnTrace()) |trace| { std.debug.dumpStackTrace(trace); @@ -145,6 +147,7 @@ fn mainServer() !void { }, }; const leak = testing.allocator_instance.deinit() == .leak; + const err_name_slice = err_name orelse ""; try server.serveTestResults(.{ .index = index, .flags = .{ @@ -156,8 +159,12 @@ fn mainServer() !void { @FieldType(std.zig.Server.Message.TestResults.Flags, "log_err_count"), log_err_count, ), + .err_name_len = std.math.lossyCast( + @FieldType(std.zig.Server.Message.TestResults.Flags, "err_name_len"), + err_name_slice.len, + ), }, - }); + }, err_name_slice); }, .start_fuzzing => { // This ensures that this code won't be analyzed and hence reference fuzzer symbols diff --git a/lib/std/Build/Step/Run.zig b/lib/std/Build/Step/Run.zig index e6ee5ad2336f..84af7b76bac3 100644 --- a/lib/std/Build/Step/Run.zig +++ b/lib/std/Build/Step/Run.zig @@ -1768,18 +1768,22 @@ fn evalZigTest( const stderr_contents = stderr.buffered(); stderr.toss(stderr_contents.len); const msg = std.mem.trim(u8, stderr_contents, "\n"); - const label = if (tr_hdr.flags.fail) - "failed" - else if (tr_hdr.flags.leak) - "leaked" - else if (tr_hdr.flags.log_err_count > 0) - "logged errors" - else - unreachable; - if (msg.len > 0) { - try run.step.addError("'{s}' {s}: {s}", .{ name, label, msg }); - } else { - try run.step.addError("'{s}' {s}", .{ name, label }); + if (tr_hdr.flags.fail) { + const err_name = body[@sizeOf(TrHdr)..][0..tr_hdr.flags.err_name_len]; + try run.step.addError("'{s}' failed with error {s}: {s}", .{name, err_name, msg}); + } + else { + const label = if (tr_hdr.flags.leak) + "leaked" + else if (tr_hdr.flags.log_err_count > 0) + "logged errors" + else + unreachable; + if (msg.len > 0) { + try run.step.addError("'{s}' {s}: {s}", .{ name, label, msg }); + } else { + try run.step.addError("'{s}' {s}", .{ name, label }); + } } } diff --git a/lib/std/zig/Server.zig b/lib/std/zig/Server.zig index 06b9afae915e..adbee6b4b64b 100644 --- a/lib/std/zig/Server.zig +++ b/lib/std/zig/Server.zig @@ -97,7 +97,8 @@ pub const Message = struct { skip: bool, leak: bool, fuzz: bool, - log_err_count: u28 = 0, + log_err_count: u16 = 0, + err_name_len: u12 = 0, }; }; @@ -205,12 +206,13 @@ pub fn serveEmitDigest( try s.out.flush(); } -pub fn serveTestResults(s: *Server, msg: OutMessage.TestResults) !void { +pub fn serveTestResults(s: *Server, msg: OutMessage.TestResults, err_name: []const u8) !void { try s.serveMessageHeader(.{ .tag = .test_results, - .bytes_len = @intCast(@sizeOf(OutMessage.TestResults)), + .bytes_len = @intCast(@sizeOf(OutMessage.TestResults) + err_name.len), }); try s.out.writeStruct(msg, .little); + try s.out.writeAll(err_name); try s.out.flush(); } From a888a1a3f68d15849e57728e495c65ca8493c2af Mon Sep 17 00:00:00 2001 From: Joao Marcos Mororo Costa Date: Mon, 13 Oct 2025 15:31:04 -0300 Subject: [PATCH 2/2] Remove ':' when msg.len == 0 --- lib/std/Build/Step/Run.zig | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/std/Build/Step/Run.zig b/lib/std/Build/Step/Run.zig index 84af7b76bac3..7c94d7778cf1 100644 --- a/lib/std/Build/Step/Run.zig +++ b/lib/std/Build/Step/Run.zig @@ -1770,7 +1770,11 @@ fn evalZigTest( const msg = std.mem.trim(u8, stderr_contents, "\n"); if (tr_hdr.flags.fail) { const err_name = body[@sizeOf(TrHdr)..][0..tr_hdr.flags.err_name_len]; - try run.step.addError("'{s}' failed with error {s}: {s}", .{name, err_name, msg}); + if (msg.len > 0) { + try run.step.addError("'{s}' failed with error {s}: {s}", .{name, err_name, msg}); + } else { + try run.step.addError("'{s}' failed with error {s}", .{name, err_name}); + } } else { const label = if (tr_hdr.flags.leak)