Commit fc20677fde

Alex Rønne Petersen <alex@alexrp.com>
2025-09-16 14:38:35
test: remove test-compare-output and test-asm-link tests
These were low value and unfocused tests. We already have coverage of the important aspects of these tests elsewhere. Additionally, there was really no need for these to have their own test harness.
1 parent 496313a
ci/riscv64-linux-debug.sh
@@ -49,7 +49,7 @@ unset CXX
 ninja install
 
 # No -fqemu and -fwasmtime here as they're covered by the x86_64-linux scripts.
-stage3-debug/bin/zig build test-cases test-modules test-unit test-c-abi test-stack-traces test-asm-link test-llvm-ir \
+stage3-debug/bin/zig build test-cases test-modules test-unit test-c-abi test-stack-traces test-llvm-ir \
   --maxrss 68719476736 \
   -Dstatic-llvm \
   -Dskip-non-native \
ci/riscv64-linux-release.sh
@@ -49,7 +49,7 @@ unset CXX
 ninja install
 
 # No -fqemu and -fwasmtime here as they're covered by the x86_64-linux scripts.
-stage3-release/bin/zig build test-cases test-modules test-unit test-c-abi test-stack-traces test-asm-link test-llvm-ir \
+stage3-release/bin/zig build test-cases test-modules test-unit test-c-abi test-stack-traces test-llvm-ir \
   --maxrss 68719476736 \
   -Dstatic-llvm \
   -Dskip-non-native \
test/src/Cases.zig
@@ -271,26 +271,6 @@ pub fn addC(ctx: *Cases, name: []const u8, target: std.Build.ResolvedTarget) *Ca
     return &ctx.cases.items[ctx.cases.items.len - 1];
 }
 
-pub fn addCompareOutput(
-    ctx: *Cases,
-    name: []const u8,
-    src: [:0]const u8,
-    expected_stdout: []const u8,
-) void {
-    ctx.addExe(name, .{}).addCompareOutput(src, expected_stdout);
-}
-
-/// Adds a test case that compiles the Zig source given in `src`, executes
-/// it, runs it, and tests the output against `expected_stdout`
-pub fn compareOutput(
-    ctx: *Cases,
-    name: []const u8,
-    src: [:0]const u8,
-    expected_stdout: []const u8,
-) void {
-    return ctx.addCompareOutput(name, src, expected_stdout);
-}
-
 pub fn addTransform(
     ctx: *Cases,
     name: []const u8,
test/src/CompareOutput.zig
@@ -1,175 +0,0 @@
-//! This is the implementation of the test harness.
-//! For the actual test cases, see test/compare_output.zig.
-
-b: *std.Build,
-step: *std.Build.Step,
-test_index: usize,
-test_filters: []const []const u8,
-optimize_modes: []const OptimizeMode,
-
-const Special = enum {
-    None,
-    Asm,
-    RuntimeSafety,
-};
-
-const TestCase = struct {
-    name: []const u8,
-    sources: std.array_list.Managed(SourceFile),
-    expected_output: []const u8,
-    link_libc: bool,
-    special: Special,
-    cli_args: []const []const u8,
-
-    const SourceFile = struct {
-        filename: []const u8,
-        source: []const u8,
-    };
-
-    pub fn addSourceFile(self: *TestCase, filename: []const u8, source: []const u8) void {
-        self.sources.append(SourceFile{
-            .filename = filename,
-            .source = source,
-        }) catch @panic("OOM");
-    }
-
-    pub fn setCommandLineArgs(self: *TestCase, args: []const []const u8) void {
-        self.cli_args = args;
-    }
-};
-
-pub fn createExtra(self: *CompareOutput, name: []const u8, source: []const u8, expected_output: []const u8, special: Special) TestCase {
-    var tc = TestCase{
-        .name = name,
-        .sources = std.array_list.Managed(TestCase.SourceFile).init(self.b.allocator),
-        .expected_output = expected_output,
-        .link_libc = false,
-        .special = special,
-        .cli_args = &[_][]const u8{},
-    };
-    const root_src_name = if (special == Special.Asm) "source.s" else "source.zig";
-    tc.addSourceFile(root_src_name, source);
-    return tc;
-}
-
-pub fn create(self: *CompareOutput, name: []const u8, source: []const u8, expected_output: []const u8) TestCase {
-    return createExtra(self, name, source, expected_output, Special.None);
-}
-
-pub fn addC(self: *CompareOutput, name: []const u8, source: []const u8, expected_output: []const u8) void {
-    var tc = self.create(name, source, expected_output);
-    tc.link_libc = true;
-    self.addCase(tc);
-}
-
-pub fn add(self: *CompareOutput, name: []const u8, source: []const u8, expected_output: []const u8) void {
-    const tc = self.create(name, source, expected_output);
-    self.addCase(tc);
-}
-
-pub fn addAsm(self: *CompareOutput, name: []const u8, source: []const u8, expected_output: []const u8) void {
-    const tc = self.createExtra(name, source, expected_output, Special.Asm);
-    self.addCase(tc);
-}
-
-pub fn addRuntimeSafety(self: *CompareOutput, name: []const u8, source: []const u8) void {
-    const tc = self.createExtra(name, source, undefined, Special.RuntimeSafety);
-    self.addCase(tc);
-}
-
-pub fn addCase(self: *CompareOutput, case: TestCase) void {
-    const b = self.b;
-
-    const write_src = b.addWriteFiles();
-    const first_src = case.sources.items[0];
-    const first_file = write_src.add(first_src.filename, first_src.source);
-    for (case.sources.items[1..]) |src_file| {
-        _ = write_src.add(src_file.filename, src_file.source);
-    }
-
-    switch (case.special) {
-        Special.Asm => {
-            const annotated_case_name = b.fmt("run assemble-and-link {s}", .{
-                case.name,
-            });
-            for (self.test_filters) |test_filter| {
-                if (mem.indexOf(u8, annotated_case_name, test_filter)) |_| break;
-            } else if (self.test_filters.len > 0) return;
-
-            const exe = b.addExecutable(.{
-                .name = "test",
-                .root_module = b.createModule(.{
-                    .root_source_file = null,
-                    .target = b.graph.host,
-                    .optimize = .Debug,
-                }),
-            });
-            exe.root_module.addAssemblyFile(first_file);
-
-            const run = b.addRunArtifact(exe);
-            run.setName(annotated_case_name);
-            run.addArgs(case.cli_args);
-            run.expectStdOutEqual(case.expected_output);
-
-            self.step.dependOn(&run.step);
-        },
-        Special.None => {
-            for (self.optimize_modes) |optimize| {
-                const annotated_case_name = b.fmt("run compare-output {s} ({s})", .{
-                    case.name, @tagName(optimize),
-                });
-                for (self.test_filters) |test_filter| {
-                    if (mem.indexOf(u8, annotated_case_name, test_filter)) |_| break;
-                } else if (self.test_filters.len > 0) return;
-
-                const exe = b.addExecutable(.{
-                    .name = "test",
-                    .root_module = b.createModule(.{
-                        .root_source_file = first_file,
-                        .optimize = optimize,
-                        .target = b.graph.host,
-                    }),
-                });
-                if (case.link_libc) exe.root_module.link_libc = true;
-
-                const run = b.addRunArtifact(exe);
-                run.setName(annotated_case_name);
-                run.addArgs(case.cli_args);
-                run.expectStdOutEqual(case.expected_output);
-
-                self.step.dependOn(&run.step);
-            }
-        },
-        Special.RuntimeSafety => {
-            // TODO iterate over self.optimize_modes and test this in both
-            // debug and release safe mode
-            const annotated_case_name = b.fmt("run safety {s}", .{case.name});
-            for (self.test_filters) |test_filter| {
-                if (mem.indexOf(u8, annotated_case_name, test_filter)) |_| break;
-            } else if (self.test_filters.len > 0) return;
-
-            const exe = b.addExecutable(.{
-                .name = "test",
-                .root_module = b.createModule(.{
-                    .root_source_file = first_file,
-                    .target = b.graph.host,
-                    .optimize = .Debug,
-                }),
-            });
-            if (case.link_libc) exe.root_module.link_libc = true;
-
-            const run = b.addRunArtifact(exe);
-            run.setName(annotated_case_name);
-            run.addArgs(case.cli_args);
-            run.expectExitCode(126);
-
-            self.step.dependOn(&run.step);
-        },
-    }
-}
-
-const CompareOutput = @This();
-const std = @import("std");
-const mem = std.mem;
-const fs = std.fs;
-const OptimizeMode = std.builtin.OptimizeMode;
test/assemble_and_link.zig
@@ -1,27 +0,0 @@
-const std = @import("std");
-const builtin = @import("builtin");
-const tests = @import("tests.zig");
-
-pub fn addCases(cases: *tests.CompareOutputContext) void {
-    if (builtin.os.tag == .linux and builtin.cpu.arch == .x86_64) {
-        cases.addAsm("hello world linux x86_64",
-            \\.text
-            \\.globl _start
-            \\
-            \\_start:
-            \\    mov $1, %rax
-            \\    mov $1, %rdi
-            \\    mov $msg, %rsi
-            \\    mov $14, %rdx
-            \\    syscall
-            \\
-            \\    mov $60, %rax
-            \\    mov $0, %rdi
-            \\    syscall
-            \\
-            \\.data
-            \\msg:
-            \\    .ascii "Hello, world!\n"
-        , "Hello, world!\n");
-    }
-}
test/compare_output.zig
@@ -1,221 +0,0 @@
-const std = @import("std");
-const os = std.os;
-const tests = @import("tests.zig");
-
-pub fn addCases(cases: *tests.CompareOutputContext) void {
-    cases.addC("hello world with libc",
-        \\const c = @cImport({
-        \\    // See https://github.com/ziglang/zig/issues/515
-        \\    @cDefine("_NO_CRT_STDIO_INLINE", "1");
-        \\    @cInclude("stdio.h");
-        \\});
-        \\pub export fn main(argc: c_int, argv: [*][*]u8) c_int {
-        \\    _ = argc;
-        \\    _ = argv;
-        \\    _ = c.puts("Hello, world!");
-        \\    return 0;
-        \\}
-    , "Hello, world!" ++ if (@import("builtin").os.tag == .windows) "\r\n" else "\n");
-
-    cases.addC("number literals",
-        \\const std = @import("std");
-        \\const builtin = @import("builtin");
-        \\const is_windows = builtin.os.tag == .windows;
-        \\const c = @cImport({
-        \\    if (is_windows) {
-        \\        // See https://github.com/ziglang/zig/issues/515
-        \\        @cDefine("_NO_CRT_STDIO_INLINE", "1");
-        \\        @cInclude("io.h");
-        \\        @cInclude("fcntl.h");
-        \\    }
-        \\    @cInclude("stdio.h");
-        \\});
-        \\
-        \\pub export fn main(argc: c_int, argv: [*][*]u8) c_int {
-        \\    _ = argc;
-        \\    _ = argv;
-        \\    if (is_windows) {
-        \\        // we want actual \n, not \r\n
-        \\        _ = c._setmode(1, c._O_BINARY);
-        \\    }
-        \\    _ = c.printf("0: %llu\n",
-        \\             @as(u64, 0));
-        \\    _ = c.printf("320402575052271: %llu\n",
-        \\         @as(u64, 320402575052271));
-        \\    _ = c.printf("0x01236789abcdef: %llu\n",
-        \\         @as(u64, 0x01236789abcdef));
-        \\    _ = c.printf("0xffffffffffffffff: %llu\n",
-        \\         @as(u64, 0xffffffffffffffff));
-        \\    _ = c.printf("0x000000ffffffffffffffff: %llu\n",
-        \\         @as(u64, 0x000000ffffffffffffffff));
-        \\    _ = c.printf("0o1777777777777777777777: %llu\n",
-        \\         @as(u64, 0o1777777777777777777777));
-        \\    _ = c.printf("0o0000001777777777777777777777: %llu\n",
-        \\         @as(u64, 0o0000001777777777777777777777));
-        \\    _ = c.printf("0b1111111111111111111111111111111111111111111111111111111111111111: %llu\n",
-        \\         @as(u64, 0b1111111111111111111111111111111111111111111111111111111111111111));
-        \\    _ = c.printf("0b0000001111111111111111111111111111111111111111111111111111111111111111: %llu\n",
-        \\         @as(u64, 0b0000001111111111111111111111111111111111111111111111111111111111111111));
-        \\
-        \\    _ = c.printf("\n");
-        \\
-        \\    _ = c.printf("0.0: %.013a\n",
-        \\         @as(f64, 0.0));
-        \\    _ = c.printf("0e0: %.013a\n",
-        \\         @as(f64, 0e0));
-        \\    _ = c.printf("0.0e0: %.013a\n",
-        \\         @as(f64, 0.0e0));
-        \\    _ = c.printf("000000000000000000000000000000000000000000000000000000000.0e0: %.013a\n",
-        \\         @as(f64, 0.0e0));
-        \\    _ = c.printf("0.000000000000000000000000000000000000000000000000000000000e0: %.013a\n",
-        \\         @as(f64, 0.000000000000000000000000000000000000000000000000000000000e0));
-        \\    _ = c.printf("0.0e000000000000000000000000000000000000000000000000000000000: %.013a\n",
-        \\         @as(f64, 0.0e000000000000000000000000000000000000000000000000000000000));
-        \\    _ = c.printf("1.0: %.013a\n",
-        \\         @as(f64, 1.0));
-        \\    _ = c.printf("10.0: %.013a\n",
-        \\         @as(f64, 10.0));
-        \\    _ = c.printf("10.5: %.013a\n",
-        \\         @as(f64, 10.5));
-        \\    _ = c.printf("10.5e5: %.013a\n",
-        \\         @as(f64, 10.5e5));
-        \\    _ = c.printf("10.5e+5: %.013a\n",
-        \\         @as(f64, 10.5e+5));
-        \\    _ = c.printf("50.0e-2: %.013a\n",
-        \\         @as(f64, 50.0e-2));
-        \\    _ = c.printf("50e-2: %.013a\n",
-        \\         @as(f64, 50e-2));
-        \\
-        \\    _ = c.printf("\n");
-        \\
-        \\    _ = c.printf("0x1.0: %.013a\n",
-        \\         @as(f64, 0x1.0));
-        \\    _ = c.printf("0x10.0: %.013a\n",
-        \\         @as(f64, 0x10.0));
-        \\    _ = c.printf("0x100.0: %.013a\n",
-        \\         @as(f64, 0x100.0));
-        \\    _ = c.printf("0x103.0: %.013a\n",
-        \\         @as(f64, 0x103.0));
-        \\    _ = c.printf("0x103.7: %.013a\n",
-        \\         @as(f64, 0x103.7));
-        \\    _ = c.printf("0x103.70: %.013a\n",
-        \\         @as(f64, 0x103.70));
-        \\    _ = c.printf("0x103.70p4: %.013a\n",
-        \\         @as(f64, 0x103.70p4));
-        \\    _ = c.printf("0x103.70p5: %.013a\n",
-        \\         @as(f64, 0x103.70p5));
-        \\    _ = c.printf("0x103.70p+5: %.013a\n",
-        \\         @as(f64, 0x103.70p+5));
-        \\    _ = c.printf("0x103.70p-5: %.013a\n",
-        \\         @as(f64, 0x103.70p-5));
-        \\
-        \\    return 0;
-        \\}
-    ,
-        \\0: 0
-        \\320402575052271: 320402575052271
-        \\0x01236789abcdef: 320402575052271
-        \\0xffffffffffffffff: 18446744073709551615
-        \\0x000000ffffffffffffffff: 18446744073709551615
-        \\0o1777777777777777777777: 18446744073709551615
-        \\0o0000001777777777777777777777: 18446744073709551615
-        \\0b1111111111111111111111111111111111111111111111111111111111111111: 18446744073709551615
-        \\0b0000001111111111111111111111111111111111111111111111111111111111111111: 18446744073709551615
-        \\
-        \\0.0: 0x0.0000000000000p+0
-        \\0e0: 0x0.0000000000000p+0
-        \\0.0e0: 0x0.0000000000000p+0
-        \\000000000000000000000000000000000000000000000000000000000.0e0: 0x0.0000000000000p+0
-        \\0.000000000000000000000000000000000000000000000000000000000e0: 0x0.0000000000000p+0
-        \\0.0e000000000000000000000000000000000000000000000000000000000: 0x0.0000000000000p+0
-        \\1.0: 0x1.0000000000000p+0
-        \\10.0: 0x1.4000000000000p+3
-        \\10.5: 0x1.5000000000000p+3
-        \\10.5e5: 0x1.0059000000000p+20
-        \\10.5e+5: 0x1.0059000000000p+20
-        \\50.0e-2: 0x1.0000000000000p-1
-        \\50e-2: 0x1.0000000000000p-1
-        \\
-        \\0x1.0: 0x1.0000000000000p+0
-        \\0x10.0: 0x1.0000000000000p+4
-        \\0x100.0: 0x1.0000000000000p+8
-        \\0x103.0: 0x1.0300000000000p+8
-        \\0x103.7: 0x1.0370000000000p+8
-        \\0x103.70: 0x1.0370000000000p+8
-        \\0x103.70p4: 0x1.0370000000000p+12
-        \\0x103.70p5: 0x1.0370000000000p+13
-        \\0x103.70p+5: 0x1.0370000000000p+13
-        \\0x103.70p-5: 0x1.0370000000000p+3
-        \\
-    );
-
-    cases.addC("expose function pointer to C land",
-        \\const c = @cImport(@cInclude("stdlib.h"));
-        \\
-        \\export fn compare_fn(a: ?*const anyopaque, b: ?*const anyopaque) c_int {
-        \\    const a_int: *const i32 = @ptrCast(@alignCast(a));
-        \\    const b_int: *const i32 = @ptrCast(@alignCast(b));
-        \\    if (a_int.* < b_int.*) {
-        \\        return -1;
-        \\    } else if (a_int.* > b_int.*) {
-        \\        return 1;
-        \\    } else {
-        \\        return 0;
-        \\    }
-        \\}
-        \\
-        \\pub export fn main() c_int {
-        \\    var array = [_]u32{ 1, 7, 3, 2, 0, 9, 4, 8, 6, 5 };
-        \\
-        \\    c.qsort(@ptrCast(&array), @intCast(array.len), @sizeOf(i32), compare_fn);
-        \\
-        \\    for (array, 0..) |item, i| {
-        \\        if (item != i) {
-        \\            c.abort();
-        \\        }
-        \\    }
-        \\
-        \\    return 0;
-        \\}
-    , "");
-
-    cases.addC("casting between float and integer types",
-        \\const std = @import("std");
-        \\const builtin = @import("builtin");
-        \\const is_windows = builtin.os.tag == .windows;
-        \\const c = @cImport({
-        \\    if (is_windows) {
-        \\        // See https://github.com/ziglang/zig/issues/515
-        \\        @cDefine("_NO_CRT_STDIO_INLINE", "1");
-        \\        @cInclude("io.h");
-        \\        @cInclude("fcntl.h");
-        \\    }
-        \\    @cInclude("stdio.h");
-        \\});
-        \\
-        \\pub export fn main(argc: c_int, argv: [*][*]u8) c_int {
-        \\    _ = argc;
-        \\    _ = argv;
-        \\    if (is_windows) {
-        \\        // we want actual \n, not \r\n
-        \\        _ = c._setmode(1, c._O_BINARY);
-        \\    }
-        \\    const small: f32 = 3.25;
-        \\    const x: f64 = small;
-        \\    const y: i32 = @intFromFloat(x);
-        \\    const z: f64 = @floatFromInt(y);
-        \\    _ = c.printf("%.2f\n%d\n%.2f\n%.2f\n", x, y, z, @as(f64, -0.4));
-        \\    return 0;
-        \\}
-    , "3.25\n3\n3.00\n-0.40\n");
-
-    cases.add("valid carriage return example", "const std = @import(\"std\");\r\n" ++ // Testing CRLF line endings are valid
-        "\r\n" ++
-        "pub \r fn main() void {\r\n" ++ // Testing isolated carriage return as whitespace is valid
-        "    var file_writer = std.fs.File.stdout().writerStreaming(&.{});\r\n" ++
-        "    const stdout = &file_writer.interface;\r\n" ++
-        "    stdout.print(\\\\A Multiline\r\n" ++ // testing CRLF at end of multiline string line is valid and normalises to \n in the output
-        "                 \\\\String\r\n" ++
-        "                 , .{}) catch unreachable;\r\n" ++
-        "}\r\n", "A Multiline\nString");
-}
test/tests.zig
@@ -6,9 +6,7 @@ const OptimizeMode = std.builtin.OptimizeMode;
 const Step = std.Build.Step;
 
 // Cases
-const compare_output = @import("compare_output.zig");
 const stack_traces = @import("stack_traces.zig");
-const assemble_and_link = @import("assemble_and_link.zig");
 const translate_c = @import("translate_c.zig");
 const run_translated_c = @import("run_translated_c.zig");
 const llvm_ir = @import("llvm_ir.zig");
@@ -16,7 +14,6 @@ const llvm_ir = @import("llvm_ir.zig");
 // Implementations
 pub const TranslateCContext = @import("src/TranslateC.zig");
 pub const RunTranslatedCContext = @import("src/RunTranslatedC.zig");
-pub const CompareOutputContext = @import("src/CompareOutput.zig");
 pub const StackTracesContext = @import("src/StackTrace.zig");
 pub const DebuggerContext = @import("src/Debugger.zig");
 pub const LlvmIrContext = @import("src/LlvmIr.zig");
@@ -1863,25 +1860,6 @@ const c_abi_targets = blk: {
     };
 };
 
-pub fn addCompareOutputTests(
-    b: *std.Build,
-    test_filters: []const []const u8,
-    optimize_modes: []const OptimizeMode,
-) *Step {
-    const cases = b.allocator.create(CompareOutputContext) catch @panic("OOM");
-    cases.* = CompareOutputContext{
-        .b = b,
-        .step = b.step("test-compare-output", "Run the compare output tests"),
-        .test_index = 0,
-        .test_filters = test_filters,
-        .optimize_modes = optimize_modes,
-    };
-
-    compare_output.addCases(cases);
-
-    return cases.step;
-}
-
 pub fn addStackTraceTests(
     b: *std.Build,
     test_filters: []const []const u8,
@@ -2175,21 +2153,6 @@ pub fn addCliTests(b: *std.Build) *Step {
     return step;
 }
 
-pub fn addAssembleAndLinkTests(b: *std.Build, test_filters: []const []const u8, optimize_modes: []const OptimizeMode) *Step {
-    const cases = b.allocator.create(CompareOutputContext) catch @panic("OOM");
-    cases.* = CompareOutputContext{
-        .b = b,
-        .step = b.step("test-asm-link", "Run the assemble and link tests"),
-        .test_index = 0,
-        .test_filters = test_filters,
-        .optimize_modes = optimize_modes,
-    };
-
-    assemble_and_link.addCases(cases);
-
-    return cases.step;
-}
-
 pub fn addTranslateCTests(
     b: *std.Build,
     parent_step: *std.Build.Step,
build.zig
@@ -568,7 +568,6 @@ pub fn build(b: *std.Build) !void {
     unit_tests.root_module.addOptions("build_options", exe_options);
     unit_tests_step.dependOn(&b.addRunArtifact(unit_tests).step);
 
-    test_step.dependOn(tests.addCompareOutputTests(b, test_filters, optimization_modes));
     test_step.dependOn(tests.addStandaloneTests(
         b,
         optimization_modes,
@@ -590,7 +589,6 @@ pub fn build(b: *std.Build) !void {
     test_step.dependOn(tests.addLinkTests(b, enable_macos_sdk, enable_ios_sdk, enable_symlinks_windows));
     test_step.dependOn(tests.addStackTraceTests(b, test_filters, optimization_modes));
     test_step.dependOn(tests.addCliTests(b));
-    test_step.dependOn(tests.addAssembleAndLinkTests(b, test_filters, optimization_modes));
     if (tests.addDebuggerTests(b, .{
         .test_filters = test_filters,
         .test_target_filters = test_target_filters,