| ... | @@ -4,6 +4,11 @@ const Module = @import("Module.zig"); | ... | @@ -4,6 +4,11 @@ const Module = @import("Module.zig"); |
| 4 | const Allocator = std.mem.Allocator; | 4 | const Allocator = std.mem.Allocator; |
| 5 | const zir = @import("zir.zig"); | 5 | const zir = @import("zir.zig"); |
| 6 | const Package = @import("Package.zig"); | 6 | const Package = @import("Package.zig"); |
| | 7 | const build_options = @import("build_options"); |
| | 8 | const enable_qemu: bool = build_options.enable_qemu; |
| | 9 | const enable_wine: bool = build_options.enable_wine; |
| | 10 | const enable_wasmtime: bool = build_options.enable_wasmtime; |
| | 11 | const glibc_multi_install_dir: ?[]const u8 = build_options.glibc_multi_install_dir; |
| 7 | | 12 | |
| 8 | const cheader = @embedFile("cbe.h"); | 13 | const cheader = @embedFile("cbe.h"); |
| 9 | | 14 | |
| ... | @@ -401,8 +406,6 @@ pub const TestContext = struct { | ... | @@ -401,8 +406,6 @@ pub const TestContext = struct { |
| 401 | const root_node = try progress.start("tests", self.cases.items.len); | 406 | const root_node = try progress.start("tests", self.cases.items.len); |
| 402 | defer root_node.end(); | 407 | defer root_node.end(); |
| 403 | | 408 | |
| 404 | const native_info = try std.zig.system.NativeTargetInfo.detect(std.heap.page_allocator, .{}); | | |
| 405 | | | |
| 406 | for (self.cases.items) |case| { | 409 | for (self.cases.items) |case| { |
| 407 | std.testing.base_allocator_instance.reset(); | 410 | std.testing.base_allocator_instance.reset(); |
| 408 | | 411 | |
| ... | @@ -415,13 +418,19 @@ pub const TestContext = struct { | ... | @@ -415,13 +418,19 @@ pub const TestContext = struct { |
| 415 | progress.initial_delay_ns = 0; | 418 | progress.initial_delay_ns = 0; |
| 416 | progress.refresh_rate_ns = 0; | 419 | progress.refresh_rate_ns = 0; |
| 417 | | 420 | |
| 418 | const info = try std.zig.system.NativeTargetInfo.detect(std.testing.allocator, case.target); | 421 | try self.runOneCase(std.testing.allocator, &prg_node, case); |
| 419 | try self.runOneCase(std.testing.allocator, &prg_node, case, info.target); | | |
| 420 | try std.testing.allocator_instance.validate(); | 422 | try std.testing.allocator_instance.validate(); |
| 421 | } | 423 | } |
| 422 | } | 424 | } |
| 423 | | 425 | |
| 424 | fn runOneCase(self: *TestContext, allocator: *Allocator, root_node: *std.Progress.Node, case: Case, target: std.Target) !void { | 426 | fn runOneCase(self: *TestContext, allocator: *Allocator, root_node: *std.Progress.Node, case: Case) !void { |
| | 427 | const target_info = try std.zig.system.NativeTargetInfo.detect(std.testing.allocator, case.target); |
| | 428 | const target = target_info.target; |
| | 429 | |
| | 430 | var arena_allocator = std.heap.ArenaAllocator.init(allocator); |
| | 431 | defer arena_allocator.deinit(); |
| | 432 | const arena = &arena_allocator.allocator; |
| | 433 | |
| 425 | var tmp = std.testing.tmpDir(.{}); | 434 | var tmp = std.testing.tmpDir(.{}); |
| 426 | defer tmp.cleanup(); | 435 | defer tmp.cleanup(); |
| 427 | | 436 | |
| ... | @@ -429,8 +438,7 @@ pub const TestContext = struct { | ... | @@ -429,8 +438,7 @@ pub const TestContext = struct { |
| 429 | const root_pkg = try Package.create(allocator, tmp.dir, ".", tmp_src_path); | 438 | const root_pkg = try Package.create(allocator, tmp.dir, ".", tmp_src_path); |
| 430 | defer root_pkg.destroy(); | 439 | defer root_pkg.destroy(); |
| 431 | | 440 | |
| 432 | const bin_name = try std.zig.binNameAlloc(allocator, "test_case", target, case.output_mode, null); | 441 | const bin_name = try std.zig.binNameAlloc(arena, "test_case", target, case.output_mode, null); |
| 433 | defer allocator.free(bin_name); | | |
| 434 | | 442 | |
| 435 | var module = try Module.init(allocator, .{ | 443 | var module = try Module.init(allocator, .{ |
| 436 | .root_name = "test_case", | 444 | .root_name = "test_case", |
| ... | @@ -485,8 +493,7 @@ pub const TestContext = struct { | ... | @@ -485,8 +493,7 @@ pub const TestContext = struct { |
| 485 | // incremental updates | 493 | // incremental updates |
| 486 | var file = try tmp.dir.openFile(bin_name, .{ .read = true }); | 494 | var file = try tmp.dir.openFile(bin_name, .{ .read = true }); |
| 487 | defer file.close(); | 495 | defer file.close(); |
| 488 | var out = file.reader().readAllAlloc(allocator, 1024 * 1024) catch @panic("Unable to read C output!"); | 496 | var out = file.reader().readAllAlloc(arena, 1024 * 1024) catch @panic("Unable to read C output!"); |
| 489 | defer allocator.free(out); | | |
| 490 | | 497 | |
| 491 | if (expected_output.len != out.len) { | 498 | if (expected_output.len != out.len) { |
| 492 | std.debug.warn("\nTransformed C length differs:\n================\nExpected:\n================\n{}\n================\nFound:\n================\n{}\n================\nTest failed.\n", .{ expected_output, out }); | 499 | std.debug.warn("\nTransformed C length differs:\n================\nExpected:\n================\n{}\n================\nFound:\n================\n{}\n================\nTest failed.\n", .{ expected_output, out }); |
| ... | @@ -533,8 +540,7 @@ pub const TestContext = struct { | ... | @@ -533,8 +540,7 @@ pub const TestContext = struct { |
| 533 | var test_node = update_node.start("assert", null); | 540 | var test_node = update_node.start("assert", null); |
| 534 | test_node.activate(); | 541 | test_node.activate(); |
| 535 | defer test_node.end(); | 542 | defer test_node.end(); |
| 536 | var handled_errors = try allocator.alloc(bool, e.len); | 543 | var handled_errors = try arena.alloc(bool, e.len); |
| 537 | defer allocator.free(handled_errors); | | |
| 538 | for (handled_errors) |*h| { | 544 | for (handled_errors) |*h| { |
| 539 | h.* = false; | 545 | h.* = false; |
| 540 | } | 546 | } |
| ... | @@ -569,10 +575,56 @@ pub const TestContext = struct { | ... | @@ -569,10 +575,56 @@ pub const TestContext = struct { |
| 569 | exec_node.activate(); | 575 | exec_node.activate(); |
| 570 | defer exec_node.end(); | 576 | defer exec_node.end(); |
| 571 | | 577 | |
| 572 | try module.makeBinFileExecutable(); | 578 | var argv = std.ArrayList([]const u8).init(allocator); |
| | 579 | defer argv.deinit(); |
| | 580 | |
| | 581 | const exe_path = try std.fmt.allocPrint(arena, "." ++ std.fs.path.sep_str ++ "{}", .{bin_name}); |
| | 582 | |
| | 583 | switch (case.target.getExternalExecutor()) { |
| | 584 | .native => try argv.append(exe_path), |
| | 585 | .unavailable => return, // No executor available; pass test. |
| | 586 | |
| | 587 | .qemu => |qemu_bin_name| { |
| | 588 | if (enable_qemu) qemu: { |
| | 589 | // TODO Ability for test cases to specify whether to link libc. |
| | 590 | const need_cross_glibc = false; // target.isGnuLibC() and self.is_linking_libc; |
| | 591 | const glibc_dir_arg = if (need_cross_glibc) |
| | 592 | glibc_multi_install_dir orelse break :qemu |
| | 593 | else |
| | 594 | null; |
| | 595 | try argv.append(qemu_bin_name); |
| | 596 | if (glibc_dir_arg) |dir| { |
| | 597 | const linux_triple = try target.linuxTriple(arena); |
| | 598 | const full_dir = try std.fs.path.join(arena, &[_][]const u8{ |
| | 599 | dir, |
| | 600 | linux_triple, |
| | 601 | }); |
| | 602 | |
| | 603 | try argv.append("-L"); |
| | 604 | try argv.append(full_dir); |
| | 605 | } |
| | 606 | try argv.append(exe_path); |
| | 607 | } |
| | 608 | return; // QEMU not available; pass test. |
| | 609 | }, |
| | 610 | |
| | 611 | .wine => |wine_bin_name| if (enable_wine) { |
| | 612 | try argv.append(wine_bin_name); |
| | 613 | try argv.append(exe_path); |
| | 614 | } else { |
| | 615 | return; // Wine not available; pass test. |
| | 616 | }, |
| | 617 | |
| | 618 | .wasmtime => |wasmtime_bin_name| if (enable_wasmtime) { |
| | 619 | try argv.append(wasmtime_bin_name); |
| | 620 | try argv.append("--dir=."); |
| | 621 | try argv.append(exe_path); |
| | 622 | } else { |
| | 623 | return; // wasmtime not available; pass test. |
| | 624 | }, |
| | 625 | } |
| 573 | | 626 | |
| 574 | const exe_path = try std.fmt.allocPrint(allocator, "." ++ std.fs.path.sep_str ++ "{}", .{bin_name}); | 627 | try module.makeBinFileExecutable(); |
| 575 | defer allocator.free(exe_path); | | |
| 576 | | 628 | |
| 577 | break :x try std.ChildProcess.exec(.{ | 629 | break :x try std.ChildProcess.exec(.{ |
| 578 | .allocator = allocator, | 630 | .allocator = allocator, |