also looking at this
Implement the web UI server with Zig I/O
#26
8 files
+513
-114
| @@ -0,0 +1,74 @@ | ||
| 1 | //! Sequential test runner for test artifacts that exercise threaded network I/O. | |
| 2 | const builtin = ; | |
| 3 | const std = ; | |
| 4 | const testing = std.testing; | |
| 5 | ||
| 6 | pub const std_options: std.Options = .{ | |
| 7 | .logFn = log, | |
| 8 | }; | |
| 9 | ||
| 10 | var log_error_count: usize = 0; | |
| 11 | ||
| 12 | pub fn main(init: std.process.Init.Minimal) void { | |
| 13 | @disableInstrumentation(); | |
| 14 | ||
| 15 | var passed: usize = 0; | |
| 16 | var skipped: usize = 0; | |
| 17 | var failed: usize = 0; | |
| 18 | var leaked: usize = 0; | |
| 19 | ||
| 20 | for (builtin.test_functions, 0..) |test_fn, index| { | |
| 21 | testing.allocator_instance = .init(std.heap.page_allocator, .{ | |
| 22 | .canary = 0xc3a701ba, | |
| 23 | .check_write_after_free = true, | |
| 24 | }); | |
| 25 | testing.io_instance = .init(testing.allocator, .{ | |
| 26 | .argv0 = .init(init.args), | |
| 27 | .environ = init.environ, | |
| 28 | }); | |
| 29 | testing.log_level = .warn; | |
| 30 | testing.environ = init.environ; | |
| 31 | ||
| 32 | std.debug.print("{d}/{d} {s}...", .{ index + 1, builtin.test_functions.len, test_fn.name }); | |
| 33 | if (test_fn.func()) |_| { | |
| 34 | passed += 1; | |
| 35 | std.debug.print("OK\n", .{}); | |
| 36 | } else |err| switch (err) { | |
| 37 | error.SkipZigTest => { | |
| 38 | skipped += 1; | |
| 39 | std.debug.print("SKIP\n", .{}); | |
| 40 | }, | |
| 41 | else => { | |
| 42 | failed += 1; | |
| 43 | std.debug.print("FAIL ({t})\n", .{err}); | |
| 44 | if (@errorReturnTrace()) |trace| std.debug.dumpErrorReturnTrace(trace); | |
| 45 | }, | |
| 46 | } | |
| 47 | ||
| 48 | testing.io_instance.deinit(); | |
| 49 | leaked += @intFromBool(testing.allocator_instance.deinit() != 0); | |
| 50 | } | |
| 51 | ||
| 52 | std.debug.print("{d} passed; {d} skipped; {d} failed.\n", .{ passed, skipped, failed }); | |
| 53 | if (leaked != 0) std.debug.print("{d} tests leaked memory.\n", .{leaked}); | |
| 54 | if (log_error_count != 0) std.debug.print("{d} errors were logged.\n", .{log_error_count}); | |
| 55 | if (failed != 0 or leaked != 0 or log_error_count != 0) std.process.exit(1); | |
| 56 | } | |
| 57 | ||
| 58 | fn log( | |
| 59 | comptime message_level: std.log.Level, | |
| 60 | comptime scope: @EnumLiteral(), | |
| 61 | comptime format: []const u8, | |
| 62 | args: anytype, | |
| 63 | ) void { | |
| 64 | @disableInstrumentation(); | |
| 65 | if (@backingInt(message_level) <= @backingInt(std.log.Level.err)) { | |
| 66 | log_error_count +|= 1; | |
| 67 | } | |
| 68 | if (@backingInt(message_level) <= @backingInt(testing.log_level)) { | |
| 69 | std.debug.print( | |
| 70 | "[" ++ @tagName(scope) ++ "] (" ++ @tagName(message_level) ++ "): " ++ format ++ "\n", | |
| 71 | args, | |
| 72 | ); | |
| 73 | } | |
| 74 | } | |