authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-08-25 14:59:10-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-08-25 15:36:25-07:00
log750998eef62a70dbea8c3ba1d44245f506370911
treefc9ba6494b79385aefa644a23f4523f8d8b03b98
parent4403008cabdb0d6cdff5cdadf4311e3d73b38a3f

Build: fail tests that log errors, like `zig test` does


4 files changed, 25 insertions(+), 10 deletions(-)

lib/std/Build/Step.zig+2-1
...@@ -45,10 +45,11 @@ pub const TestResults = struct {...@@ -45,10 +45,11 @@ pub const TestResults = struct {
45 fail_count: u32 = 0,45 fail_count: u32 = 0,
46 skip_count: u32 = 0,46 skip_count: u32 = 0,
47 leak_count: u32 = 0,47 leak_count: u32 = 0,
48 log_err_count: u32 = 0,
48 test_count: u32 = 0,49 test_count: u32 = 0,
4950
50 pub fn isSuccess(tr: TestResults) bool {51 pub fn isSuccess(tr: TestResults) bool {
51 return tr.fail_count == 0 and tr.leak_count == 0;52 return tr.fail_count == 0 and tr.leak_count == 0 and tr.log_err_count == 0;
52 }53 }
5354
54 pub fn passCount(tr: TestResults) u32 {55 pub fn passCount(tr: TestResults) u32 {
lib/std/Build/Step/Run.zig+15-5
...@@ -1048,6 +1048,7 @@ fn evalZigTest(...@@ -1048,6 +1048,7 @@ fn evalZigTest(
1048 var skip_count: u32 = 0;1048 var skip_count: u32 = 0;
1049 var leak_count: u32 = 0;1049 var leak_count: u32 = 0;
1050 var test_count: u32 = 0;1050 var test_count: u32 = 0;
1051 var log_err_count: u32 = 0;
10511052
1052 var metadata: ?TestMetadata = null;1053 var metadata: ?TestMetadata = null;
10531054
...@@ -1112,14 +1113,22 @@ fn evalZigTest(...@@ -1112,14 +1113,22 @@ fn evalZigTest(
11121113
1113 const TrHdr = std.zig.Server.Message.TestResults;1114 const TrHdr = std.zig.Server.Message.TestResults;
1114 const tr_hdr = @as(*align(1) const TrHdr, @ptrCast(body));1115 const tr_hdr = @as(*align(1) const TrHdr, @ptrCast(body));
1115 fail_count += @intFromBool(tr_hdr.flags.fail);1116 fail_count +|= @intFromBool(tr_hdr.flags.fail);
1116 skip_count += @intFromBool(tr_hdr.flags.skip);1117 skip_count +|= @intFromBool(tr_hdr.flags.skip);
1117 leak_count += @intFromBool(tr_hdr.flags.leak);1118 leak_count +|= @intFromBool(tr_hdr.flags.leak);
1119 log_err_count +|= tr_hdr.flags.log_err_count;
11181120
1119 if (tr_hdr.flags.fail or tr_hdr.flags.leak) {1121 if (tr_hdr.flags.fail or tr_hdr.flags.leak or tr_hdr.flags.log_err_count > 0) {
1120 const name = std.mem.sliceTo(md.string_bytes[md.names[tr_hdr.index]..], 0);1122 const name = std.mem.sliceTo(md.string_bytes[md.names[tr_hdr.index]..], 0);
1121 const msg = std.mem.trim(u8, stderr.readableSlice(0), "\n");1123 const msg = std.mem.trim(u8, stderr.readableSlice(0), "\n");
1122 const label = if (tr_hdr.flags.fail) "failed" else "leaked";1124 const label = if (tr_hdr.flags.fail)
1125 "failed"
1126 else if (tr_hdr.flags.leak)
1127 "leaked"
1128 else if (tr_hdr.flags.log_err_count > 0)
1129 "logged errors"
1130 else
1131 unreachable;
1123 if (msg.len > 0) {1132 if (msg.len > 0) {
1124 try self.step.addError("'{s}' {s}: {s}", .{ name, label, msg });1133 try self.step.addError("'{s}' {s}: {s}", .{ name, label, msg });
1125 } else {1134 } else {
...@@ -1153,6 +1162,7 @@ fn evalZigTest(...@@ -1153,6 +1162,7 @@ fn evalZigTest(
1153 .fail_count = fail_count,1162 .fail_count = fail_count,
1154 .skip_count = skip_count,1163 .skip_count = skip_count,
1155 .leak_count = leak_count,1164 .leak_count = leak_count,
1165 .log_err_count = log_err_count,
1156 },1166 },
1157 .test_metadata = metadata,1167 .test_metadata = metadata,
1158 };1168 };
lib/std/zig/Server.zig+2-3
...@@ -53,12 +53,11 @@ pub const Message = struct {...@@ -53,12 +53,11 @@ pub const Message = struct {
53 index: u32,53 index: u32,
54 flags: Flags,54 flags: Flags,
5555
56 pub const Flags = packed struct(u8) {56 pub const Flags = packed struct(u32) {
57 fail: bool,57 fail: bool,
58 skip: bool,58 skip: bool,
59 leak: bool,59 leak: bool,
6060 log_err_count: u29 = 0,
61 reserved: u5 = 0,
62 };61 };
63 };62 };
6463
lib/test_runner.zig+6-1
...@@ -90,6 +90,7 @@ fn mainServer() !void {...@@ -90,6 +90,7 @@ fn mainServer() !void {
9090
91 .run_test => {91 .run_test => {
92 std.testing.allocator_instance = .{};92 std.testing.allocator_instance = .{};
93 log_err_count = 0;
93 const index = try server.receiveBody_u32();94 const index = try server.receiveBody_u32();
94 const test_fn = builtin.test_functions[index];95 const test_fn = builtin.test_functions[index];
95 if (test_fn.async_frame_size != null)96 if (test_fn.async_frame_size != null)
...@@ -113,6 +114,10 @@ fn mainServer() !void {...@@ -113,6 +114,10 @@ fn mainServer() !void {
113 .fail = fail,114 .fail = fail,
114 .skip = skip,115 .skip = skip,
115 .leak = leak,116 .leak = leak,
117 .log_err_count = std.math.lossyCast(std.meta.FieldType(
118 std.zig.Server.Message.TestResults.Flags,
119 .log_err_count,
120 ), log_err_count),
116 },121 },
117 });122 });
118 },123 },
...@@ -218,7 +223,7 @@ pub fn log(...@@ -218,7 +223,7 @@ pub fn log(
218 args: anytype,223 args: anytype,
219) void {224) void {
220 if (@intFromEnum(message_level) <= @intFromEnum(std.log.Level.err)) {225 if (@intFromEnum(message_level) <= @intFromEnum(std.log.Level.err)) {
221 log_err_count += 1;226 log_err_count +|= 1;
222 }227 }
223 if (@intFromEnum(message_level) <= @intFromEnum(std.testing.log_level)) {228 if (@intFromEnum(message_level) <= @intFromEnum(std.testing.log_level)) {
224 std.debug.print(229 std.debug.print(