authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-07-26 20:09:48-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-07-26 20:09:48-07:00
log4e53249d769346683d45d4a4cb4a437388f9e186
treed3b2fa77951f91e3936cbfd473d0638da2df5f59
parentea3db3274d890b7d00c907c037ffe203f41adbd3

test-cases harness: improve stage2 compatibility

* proper skip_stage1 mechanism that doesn't get side-stepped with manually added test cases. * avoid runtime-known function pointers. * check for type equality more simply without checking the type name.

1 files changed, 17 insertions(+), 30 deletions(-)

src/test.zig+17-30
...@@ -20,7 +20,7 @@ const enable_wasmtime: bool = build_options.enable_wasmtime;...@@ -20,7 +20,7 @@ const enable_wasmtime: bool = build_options.enable_wasmtime;
20const enable_darling: bool = build_options.enable_darling;20const enable_darling: bool = build_options.enable_darling;
21const enable_rosetta: bool = build_options.enable_rosetta;21const enable_rosetta: bool = build_options.enable_rosetta;
22const glibc_runtimes_dir: ?[]const u8 = build_options.glibc_runtimes_dir;22const glibc_runtimes_dir: ?[]const u8 = build_options.glibc_runtimes_dir;
23const skip_stage1 = build_options.skip_stage1;23const skip_stage1 = builtin.zig_backend != .stage1 or build_options.skip_stage1;
2424
25const hr = "=" ** 80;25const hr = "=" ** 80;
2626
...@@ -233,11 +233,11 @@ const TestManifest = struct {...@@ -233,11 +233,11 @@ const TestManifest = struct {
233 fn ConfigValueIterator(comptime T: type) type {233 fn ConfigValueIterator(comptime T: type) type {
234 return struct {234 return struct {
235 inner: std.mem.SplitIterator(u8),235 inner: std.mem.SplitIterator(u8),
236 parse_fn: ParseFn(T),
237236
238 fn next(self: *@This()) !?T {237 fn next(self: *@This()) !?T {
239 const next_raw = self.inner.next() orelse return null;238 const next_raw = self.inner.next() orelse return null;
240 return try self.parse_fn(next_raw);239 const parseFn = getDefaultParser(T);
240 return try parseFn(next_raw);
241 }241 }
242 };242 };
243 }243 }
...@@ -313,27 +313,17 @@ const TestManifest = struct {...@@ -313,27 +313,17 @@ const TestManifest = struct {
313 return manifest;313 return manifest;
314 }314 }
315315
316 fn getConfigForKeyCustomParser(316 fn getConfigForKey(
317 self: TestManifest,317 self: TestManifest,
318 key: []const u8,318 key: []const u8,
319 comptime T: type,319 comptime T: type,
320 parse_fn: ParseFn(T),
321 ) ConfigValueIterator(T) {320 ) ConfigValueIterator(T) {
322 const bytes = self.config_map.get(key) orelse TestManifestConfigDefaults.get(self.@"type", key);321 const bytes = self.config_map.get(key) orelse TestManifestConfigDefaults.get(self.@"type", key);
323 return ConfigValueIterator(T){322 return ConfigValueIterator(T){
324 .inner = std.mem.split(u8, bytes, ","),323 .inner = std.mem.split(u8, bytes, ","),
325 .parse_fn = parse_fn,
326 };324 };
327 }325 }
328326
329 fn getConfigForKey(
330 self: TestManifest,
331 key: []const u8,
332 comptime T: type,
333 ) ConfigValueIterator(T) {
334 return self.getConfigForKeyCustomParser(key, T, getDefaultParser(T));
335 }
336
337 fn getConfigForKeyAlloc(327 fn getConfigForKeyAlloc(
338 self: TestManifest,328 self: TestManifest,
339 allocator: Allocator,329 allocator: Allocator,
...@@ -377,6 +367,15 @@ const TestManifest = struct {...@@ -377,6 +367,15 @@ const TestManifest = struct {
377 }367 }
378368
379 fn getDefaultParser(comptime T: type) ParseFn(T) {369 fn getDefaultParser(comptime T: type) ParseFn(T) {
370 if (T == CrossTarget) return struct {
371 fn parse(str: []const u8) anyerror!T {
372 var opts = CrossTarget.ParseOptions{
373 .arch_os_abi = str,
374 };
375 return try CrossTarget.parse(opts);
376 }
377 }.parse;
378
380 switch (@typeInfo(T)) {379 switch (@typeInfo(T)) {
381 .Int => return struct {380 .Int => return struct {
382 fn parse(str: []const u8) anyerror!T {381 fn parse(str: []const u8) anyerror!T {
...@@ -397,14 +396,7 @@ const TestManifest = struct {...@@ -397,14 +396,7 @@ const TestManifest = struct {
397 };396 };
398 }397 }
399 }.parse,398 }.parse,
400 .Struct => if (comptime std.mem.eql(u8, @typeName(T), "CrossTarget")) return struct {399 .Struct => @compileError("no default parser for " ++ @typeName(T)),
401 fn parse(str: []const u8) anyerror!T {
402 var opts = CrossTarget.ParseOptions{
403 .arch_os_abi = str,
404 };
405 return try CrossTarget.parse(opts);
406 }
407 }.parse else @compileError("no default parser for " ++ @typeName(T)),
408 else => @compileError("no default parser for " ++ @typeName(T)),400 else => @compileError("no default parser for " ++ @typeName(T)),
409 }401 }
410 }402 }
...@@ -884,8 +876,6 @@ pub const TestContext = struct {...@@ -884,8 +876,6 @@ pub const TestContext = struct {
884 src: [:0]const u8,876 src: [:0]const u8,
885 expected_errors: []const []const u8,877 expected_errors: []const []const u8,
886 ) void {878 ) void {
887 if (skip_stage1) return;
888
889 const case = ctx.addObj(name, .{});879 const case = ctx.addObj(name, .{});
890 case.backend = .stage1;880 case.backend = .stage1;
891 case.addError(src, expected_errors);881 case.addError(src, expected_errors);
...@@ -897,8 +887,6 @@ pub const TestContext = struct {...@@ -897,8 +887,6 @@ pub const TestContext = struct {
897 src: [:0]const u8,887 src: [:0]const u8,
898 expected_errors: []const []const u8,888 expected_errors: []const []const u8,
899 ) void {889 ) void {
900 if (skip_stage1) return;
901
902 const case = ctx.addTest(name, .{});890 const case = ctx.addTest(name, .{});
903 case.backend = .stage1;891 case.backend = .stage1;
904 case.addError(src, expected_errors);892 case.addError(src, expected_errors);
...@@ -910,8 +898,6 @@ pub const TestContext = struct {...@@ -910,8 +898,6 @@ pub const TestContext = struct {
910 src: [:0]const u8,898 src: [:0]const u8,
911 expected_errors: []const []const u8,899 expected_errors: []const []const u8,
912 ) void {900 ) void {
913 if (skip_stage1) return;
914
915 const case = ctx.addExe(name, .{});901 const case = ctx.addExe(name, .{});
916 case.backend = .stage1;902 case.backend = .stage1;
917 case.addError(src, expected_errors);903 case.addError(src, expected_errors);
...@@ -1143,8 +1129,6 @@ pub const TestContext = struct {...@@ -1143,8 +1129,6 @@ pub const TestContext = struct {
11431129
1144 // Cross-product to get all possible test combinations1130 // Cross-product to get all possible test combinations
1145 for (backends) |backend| {1131 for (backends) |backend| {
1146 if (backend == .stage1 and skip_stage1) continue;
1147
1148 for (targets) |target| {1132 for (targets) |target| {
1149 const name = try std.fmt.allocPrint(ctx.arena, "{s} ({s}, {s})", .{1133 const name = try std.fmt.allocPrint(ctx.arena, "{s} ({s}, {s})", .{
1150 name_prefix,1134 name_prefix,
...@@ -1276,6 +1260,9 @@ pub const TestContext = struct {...@@ -1276,6 +1260,9 @@ pub const TestContext = struct {
1276 if (!build_options.have_llvm and case.backend == .llvm)1260 if (!build_options.have_llvm and case.backend == .llvm)
1277 continue;1261 continue;
12781262
1263 if (skip_stage1 and case.backend == .stage1)
1264 continue;
1265
1279 if (build_options.test_filter) |test_filter| {1266 if (build_options.test_filter) |test_filter| {
1280 if (std.mem.indexOf(u8, case.name, test_filter) == null) continue;1267 if (std.mem.indexOf(u8, case.name, test_filter) == null) continue;
1281 }1268 }