authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-09-16 14:38:35+02:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-09-16 14:51:03+02:00
logfc20677fde9155c8dbd694eb157b63317623fbc6
treeeb3e626df7197386821854c8265093501a852003
parent496313a1bd4e8a4663ea99942d179a52b57e04e6
signaturebadge-check Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

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.

8 files changed, 2 insertions(+), 484 deletions(-)

build.zig-2
......@@ -568,7 +568,6 @@ pub fn build(b: *std.Build) !void {
568568 unit_tests.root_module.addOptions("build_options", exe_options);
569569 unit_tests_step.dependOn(&b.addRunArtifact(unit_tests).step);
570570
571 test_step.dependOn(tests.addCompareOutputTests(b, test_filters, optimization_modes));
572571 test_step.dependOn(tests.addStandaloneTests(
573572 b,
574573 optimization_modes,
......@@ -590,7 +589,6 @@ pub fn build(b: *std.Build) !void {
590589 test_step.dependOn(tests.addLinkTests(b, enable_macos_sdk, enable_ios_sdk, enable_symlinks_windows));
591590 test_step.dependOn(tests.addStackTraceTests(b, test_filters, optimization_modes));
592591 test_step.dependOn(tests.addCliTests(b));
593 test_step.dependOn(tests.addAssembleAndLinkTests(b, test_filters, optimization_modes));
594592 if (tests.addDebuggerTests(b, .{
595593 .test_filters = test_filters,
596594 .test_target_filters = test_target_filters,
ci/riscv64-linux-debug.sh+1-1
......@@ -49,7 +49,7 @@ unset CXX
4949ninja install
5050
5151# No -fqemu and -fwasmtime here as they're covered by the x86_64-linux scripts.
52stage3-debug/bin/zig build test-cases test-modules test-unit test-c-abi test-stack-traces test-asm-link test-llvm-ir \
52stage3-debug/bin/zig build test-cases test-modules test-unit test-c-abi test-stack-traces test-llvm-ir \
5353 --maxrss 68719476736 \
5454 -Dstatic-llvm \
5555 -Dskip-non-native \
ci/riscv64-linux-release.sh+1-1
......@@ -49,7 +49,7 @@ unset CXX
4949ninja install
5050
5151# No -fqemu and -fwasmtime here as they're covered by the x86_64-linux scripts.
52stage3-release/bin/zig build test-cases test-modules test-unit test-c-abi test-stack-traces test-asm-link test-llvm-ir \
52stage3-release/bin/zig build test-cases test-modules test-unit test-c-abi test-stack-traces test-llvm-ir \
5353 --maxrss 68719476736 \
5454 -Dstatic-llvm \
5555 -Dskip-non-native \
test/assemble_and_link.zig deleted-27
......@@ -1,27 +0,0 @@
1const std = @import("std");
2const builtin = @import("builtin");
3const tests = @import("tests.zig");
4
5pub fn addCases(cases: *tests.CompareOutputContext) void {
6 if (builtin.os.tag == .linux and builtin.cpu.arch == .x86_64) {
7 cases.addAsm("hello world linux x86_64",
8 \\.text
9 \\.globl _start
10 \\
11 \\_start:
12 \\ mov $1, %rax
13 \\ mov $1, %rdi
14 \\ mov $msg, %rsi
15 \\ mov $14, %rdx
16 \\ syscall
17 \\
18 \\ mov $60, %rax
19 \\ mov $0, %rdi
20 \\ syscall
21 \\
22 \\.data
23 \\msg:
24 \\ .ascii "Hello, world!\n"
25 , "Hello, world!\n");
26 }
27}
test/compare_output.zig deleted-221
......@@ -1,221 +0,0 @@
1const std = @import("std");
2const os = std.os;
3const tests = @import("tests.zig");
4
5pub fn addCases(cases: *tests.CompareOutputContext) void {
6 cases.addC("hello world with libc",
7 \\const c = @cImport({
8 \\ // See https://github.com/ziglang/zig/issues/515
9 \\ @cDefine("_NO_CRT_STDIO_INLINE", "1");
10 \\ @cInclude("stdio.h");
11 \\});
12 \\pub export fn main(argc: c_int, argv: [*][*]u8) c_int {
13 \\ _ = argc;
14 \\ _ = argv;
15 \\ _ = c.puts("Hello, world!");
16 \\ return 0;
17 \\}
18 , "Hello, world!" ++ if (@import("builtin").os.tag == .windows) "\r\n" else "\n");
19
20 cases.addC("number literals",
21 \\const std = @import("std");
22 \\const builtin = @import("builtin");
23 \\const is_windows = builtin.os.tag == .windows;
24 \\const c = @cImport({
25 \\ if (is_windows) {
26 \\ // See https://github.com/ziglang/zig/issues/515
27 \\ @cDefine("_NO_CRT_STDIO_INLINE", "1");
28 \\ @cInclude("io.h");
29 \\ @cInclude("fcntl.h");
30 \\ }
31 \\ @cInclude("stdio.h");
32 \\});
33 \\
34 \\pub export fn main(argc: c_int, argv: [*][*]u8) c_int {
35 \\ _ = argc;
36 \\ _ = argv;
37 \\ if (is_windows) {
38 \\ // we want actual \n, not \r\n
39 \\ _ = c._setmode(1, c._O_BINARY);
40 \\ }
41 \\ _ = c.printf("0: %llu\n",
42 \\ @as(u64, 0));
43 \\ _ = c.printf("320402575052271: %llu\n",
44 \\ @as(u64, 320402575052271));
45 \\ _ = c.printf("0x01236789abcdef: %llu\n",
46 \\ @as(u64, 0x01236789abcdef));
47 \\ _ = c.printf("0xffffffffffffffff: %llu\n",
48 \\ @as(u64, 0xffffffffffffffff));
49 \\ _ = c.printf("0x000000ffffffffffffffff: %llu\n",
50 \\ @as(u64, 0x000000ffffffffffffffff));
51 \\ _ = c.printf("0o1777777777777777777777: %llu\n",
52 \\ @as(u64, 0o1777777777777777777777));
53 \\ _ = c.printf("0o0000001777777777777777777777: %llu\n",
54 \\ @as(u64, 0o0000001777777777777777777777));
55 \\ _ = c.printf("0b1111111111111111111111111111111111111111111111111111111111111111: %llu\n",
56 \\ @as(u64, 0b1111111111111111111111111111111111111111111111111111111111111111));
57 \\ _ = c.printf("0b0000001111111111111111111111111111111111111111111111111111111111111111: %llu\n",
58 \\ @as(u64, 0b0000001111111111111111111111111111111111111111111111111111111111111111));
59 \\
60 \\ _ = c.printf("\n");
61 \\
62 \\ _ = c.printf("0.0: %.013a\n",
63 \\ @as(f64, 0.0));
64 \\ _ = c.printf("0e0: %.013a\n",
65 \\ @as(f64, 0e0));
66 \\ _ = c.printf("0.0e0: %.013a\n",
67 \\ @as(f64, 0.0e0));
68 \\ _ = c.printf("000000000000000000000000000000000000000000000000000000000.0e0: %.013a\n",
69 \\ @as(f64, 0.0e0));
70 \\ _ = c.printf("0.000000000000000000000000000000000000000000000000000000000e0: %.013a\n",
71 \\ @as(f64, 0.000000000000000000000000000000000000000000000000000000000e0));
72 \\ _ = c.printf("0.0e000000000000000000000000000000000000000000000000000000000: %.013a\n",
73 \\ @as(f64, 0.0e000000000000000000000000000000000000000000000000000000000));
74 \\ _ = c.printf("1.0: %.013a\n",
75 \\ @as(f64, 1.0));
76 \\ _ = c.printf("10.0: %.013a\n",
77 \\ @as(f64, 10.0));
78 \\ _ = c.printf("10.5: %.013a\n",
79 \\ @as(f64, 10.5));
80 \\ _ = c.printf("10.5e5: %.013a\n",
81 \\ @as(f64, 10.5e5));
82 \\ _ = c.printf("10.5e+5: %.013a\n",
83 \\ @as(f64, 10.5e+5));
84 \\ _ = c.printf("50.0e-2: %.013a\n",
85 \\ @as(f64, 50.0e-2));
86 \\ _ = c.printf("50e-2: %.013a\n",
87 \\ @as(f64, 50e-2));
88 \\
89 \\ _ = c.printf("\n");
90 \\
91 \\ _ = c.printf("0x1.0: %.013a\n",
92 \\ @as(f64, 0x1.0));
93 \\ _ = c.printf("0x10.0: %.013a\n",
94 \\ @as(f64, 0x10.0));
95 \\ _ = c.printf("0x100.0: %.013a\n",
96 \\ @as(f64, 0x100.0));
97 \\ _ = c.printf("0x103.0: %.013a\n",
98 \\ @as(f64, 0x103.0));
99 \\ _ = c.printf("0x103.7: %.013a\n",
100 \\ @as(f64, 0x103.7));
101 \\ _ = c.printf("0x103.70: %.013a\n",
102 \\ @as(f64, 0x103.70));
103 \\ _ = c.printf("0x103.70p4: %.013a\n",
104 \\ @as(f64, 0x103.70p4));
105 \\ _ = c.printf("0x103.70p5: %.013a\n",
106 \\ @as(f64, 0x103.70p5));
107 \\ _ = c.printf("0x103.70p+5: %.013a\n",
108 \\ @as(f64, 0x103.70p+5));
109 \\ _ = c.printf("0x103.70p-5: %.013a\n",
110 \\ @as(f64, 0x103.70p-5));
111 \\
112 \\ return 0;
113 \\}
114 ,
115 \\0: 0
116 \\320402575052271: 320402575052271
117 \\0x01236789abcdef: 320402575052271
118 \\0xffffffffffffffff: 18446744073709551615
119 \\0x000000ffffffffffffffff: 18446744073709551615
120 \\0o1777777777777777777777: 18446744073709551615
121 \\0o0000001777777777777777777777: 18446744073709551615
122 \\0b1111111111111111111111111111111111111111111111111111111111111111: 18446744073709551615
123 \\0b0000001111111111111111111111111111111111111111111111111111111111111111: 18446744073709551615
124 \\
125 \\0.0: 0x0.0000000000000p+0
126 \\0e0: 0x0.0000000000000p+0
127 \\0.0e0: 0x0.0000000000000p+0
128 \\000000000000000000000000000000000000000000000000000000000.0e0: 0x0.0000000000000p+0
129 \\0.000000000000000000000000000000000000000000000000000000000e0: 0x0.0000000000000p+0
130 \\0.0e000000000000000000000000000000000000000000000000000000000: 0x0.0000000000000p+0
131 \\1.0: 0x1.0000000000000p+0
132 \\10.0: 0x1.4000000000000p+3
133 \\10.5: 0x1.5000000000000p+3
134 \\10.5e5: 0x1.0059000000000p+20
135 \\10.5e+5: 0x1.0059000000000p+20
136 \\50.0e-2: 0x1.0000000000000p-1
137 \\50e-2: 0x1.0000000000000p-1
138 \\
139 \\0x1.0: 0x1.0000000000000p+0
140 \\0x10.0: 0x1.0000000000000p+4
141 \\0x100.0: 0x1.0000000000000p+8
142 \\0x103.0: 0x1.0300000000000p+8
143 \\0x103.7: 0x1.0370000000000p+8
144 \\0x103.70: 0x1.0370000000000p+8
145 \\0x103.70p4: 0x1.0370000000000p+12
146 \\0x103.70p5: 0x1.0370000000000p+13
147 \\0x103.70p+5: 0x1.0370000000000p+13
148 \\0x103.70p-5: 0x1.0370000000000p+3
149 \\
150 );
151
152 cases.addC("expose function pointer to C land",
153 \\const c = @cImport(@cInclude("stdlib.h"));
154 \\
155 \\export fn compare_fn(a: ?*const anyopaque, b: ?*const anyopaque) c_int {
156 \\ const a_int: *const i32 = @ptrCast(@alignCast(a));
157 \\ const b_int: *const i32 = @ptrCast(@alignCast(b));
158 \\ if (a_int.* < b_int.*) {
159 \\ return -1;
160 \\ } else if (a_int.* > b_int.*) {
161 \\ return 1;
162 \\ } else {
163 \\ return 0;
164 \\ }
165 \\}
166 \\
167 \\pub export fn main() c_int {
168 \\ var array = [_]u32{ 1, 7, 3, 2, 0, 9, 4, 8, 6, 5 };
169 \\
170 \\ c.qsort(@ptrCast(&array), @intCast(array.len), @sizeOf(i32), compare_fn);
171 \\
172 \\ for (array, 0..) |item, i| {
173 \\ if (item != i) {
174 \\ c.abort();
175 \\ }
176 \\ }
177 \\
178 \\ return 0;
179 \\}
180 , "");
181
182 cases.addC("casting between float and integer types",
183 \\const std = @import("std");
184 \\const builtin = @import("builtin");
185 \\const is_windows = builtin.os.tag == .windows;
186 \\const c = @cImport({
187 \\ if (is_windows) {
188 \\ // See https://github.com/ziglang/zig/issues/515
189 \\ @cDefine("_NO_CRT_STDIO_INLINE", "1");
190 \\ @cInclude("io.h");
191 \\ @cInclude("fcntl.h");
192 \\ }
193 \\ @cInclude("stdio.h");
194 \\});
195 \\
196 \\pub export fn main(argc: c_int, argv: [*][*]u8) c_int {
197 \\ _ = argc;
198 \\ _ = argv;
199 \\ if (is_windows) {
200 \\ // we want actual \n, not \r\n
201 \\ _ = c._setmode(1, c._O_BINARY);
202 \\ }
203 \\ const small: f32 = 3.25;
204 \\ const x: f64 = small;
205 \\ const y: i32 = @intFromFloat(x);
206 \\ const z: f64 = @floatFromInt(y);
207 \\ _ = c.printf("%.2f\n%d\n%.2f\n%.2f\n", x, y, z, @as(f64, -0.4));
208 \\ return 0;
209 \\}
210 , "3.25\n3\n3.00\n-0.40\n");
211
212 cases.add("valid carriage return example", "const std = @import(\"std\");\r\n" ++ // Testing CRLF line endings are valid
213 "\r\n" ++
214 "pub \r fn main() void {\r\n" ++ // Testing isolated carriage return as whitespace is valid
215 " var file_writer = std.fs.File.stdout().writerStreaming(&.{});\r\n" ++
216 " const stdout = &file_writer.interface;\r\n" ++
217 " stdout.print(\\\\A Multiline\r\n" ++ // testing CRLF at end of multiline string line is valid and normalises to \n in the output
218 " \\\\String\r\n" ++
219 " , .{}) catch unreachable;\r\n" ++
220 "}\r\n", "A Multiline\nString");
221}
test/src/Cases.zig-20
......@@ -271,26 +271,6 @@ pub fn addC(ctx: *Cases, name: []const u8, target: std.Build.ResolvedTarget) *Ca
271271 return &ctx.cases.items[ctx.cases.items.len - 1];
272272}
273273
274pub fn addCompareOutput(
275 ctx: *Cases,
276 name: []const u8,
277 src: [:0]const u8,
278 expected_stdout: []const u8,
279) void {
280 ctx.addExe(name, .{}).addCompareOutput(src, expected_stdout);
281}
282
283/// Adds a test case that compiles the Zig source given in `src`, executes
284/// it, runs it, and tests the output against `expected_stdout`
285pub fn compareOutput(
286 ctx: *Cases,
287 name: []const u8,
288 src: [:0]const u8,
289 expected_stdout: []const u8,
290) void {
291 return ctx.addCompareOutput(name, src, expected_stdout);
292}
293
294274pub fn addTransform(
295275 ctx: *Cases,
296276 name: []const u8,
test/src/CompareOutput.zig deleted-175
......@@ -1,175 +0,0 @@
1//! This is the implementation of the test harness.
2//! For the actual test cases, see test/compare_output.zig.
3
4b: *std.Build,
5step: *std.Build.Step,
6test_index: usize,
7test_filters: []const []const u8,
8optimize_modes: []const OptimizeMode,
9
10const Special = enum {
11 None,
12 Asm,
13 RuntimeSafety,
14};
15
16const TestCase = struct {
17 name: []const u8,
18 sources: std.array_list.Managed(SourceFile),
19 expected_output: []const u8,
20 link_libc: bool,
21 special: Special,
22 cli_args: []const []const u8,
23
24 const SourceFile = struct {
25 filename: []const u8,
26 source: []const u8,
27 };
28
29 pub fn addSourceFile(self: *TestCase, filename: []const u8, source: []const u8) void {
30 self.sources.append(SourceFile{
31 .filename = filename,
32 .source = source,
33 }) catch @panic("OOM");
34 }
35
36 pub fn setCommandLineArgs(self: *TestCase, args: []const []const u8) void {
37 self.cli_args = args;
38 }
39};
40
41pub fn createExtra(self: *CompareOutput, name: []const u8, source: []const u8, expected_output: []const u8, special: Special) TestCase {
42 var tc = TestCase{
43 .name = name,
44 .sources = std.array_list.Managed(TestCase.SourceFile).init(self.b.allocator),
45 .expected_output = expected_output,
46 .link_libc = false,
47 .special = special,
48 .cli_args = &[_][]const u8{},
49 };
50 const root_src_name = if (special == Special.Asm) "source.s" else "source.zig";
51 tc.addSourceFile(root_src_name, source);
52 return tc;
53}
54
55pub fn create(self: *CompareOutput, name: []const u8, source: []const u8, expected_output: []const u8) TestCase {
56 return createExtra(self, name, source, expected_output, Special.None);
57}
58
59pub fn addC(self: *CompareOutput, name: []const u8, source: []const u8, expected_output: []const u8) void {
60 var tc = self.create(name, source, expected_output);
61 tc.link_libc = true;
62 self.addCase(tc);
63}
64
65pub fn add(self: *CompareOutput, name: []const u8, source: []const u8, expected_output: []const u8) void {
66 const tc = self.create(name, source, expected_output);
67 self.addCase(tc);
68}
69
70pub fn addAsm(self: *CompareOutput, name: []const u8, source: []const u8, expected_output: []const u8) void {
71 const tc = self.createExtra(name, source, expected_output, Special.Asm);
72 self.addCase(tc);
73}
74
75pub fn addRuntimeSafety(self: *CompareOutput, name: []const u8, source: []const u8) void {
76 const tc = self.createExtra(name, source, undefined, Special.RuntimeSafety);
77 self.addCase(tc);
78}
79
80pub fn addCase(self: *CompareOutput, case: TestCase) void {
81 const b = self.b;
82
83 const write_src = b.addWriteFiles();
84 const first_src = case.sources.items[0];
85 const first_file = write_src.add(first_src.filename, first_src.source);
86 for (case.sources.items[1..]) |src_file| {
87 _ = write_src.add(src_file.filename, src_file.source);
88 }
89
90 switch (case.special) {
91 Special.Asm => {
92 const annotated_case_name = b.fmt("run assemble-and-link {s}", .{
93 case.name,
94 });
95 for (self.test_filters) |test_filter| {
96 if (mem.indexOf(u8, annotated_case_name, test_filter)) |_| break;
97 } else if (self.test_filters.len > 0) return;
98
99 const exe = b.addExecutable(.{
100 .name = "test",
101 .root_module = b.createModule(.{
102 .root_source_file = null,
103 .target = b.graph.host,
104 .optimize = .Debug,
105 }),
106 });
107 exe.root_module.addAssemblyFile(first_file);
108
109 const run = b.addRunArtifact(exe);
110 run.setName(annotated_case_name);
111 run.addArgs(case.cli_args);
112 run.expectStdOutEqual(case.expected_output);
113
114 self.step.dependOn(&run.step);
115 },
116 Special.None => {
117 for (self.optimize_modes) |optimize| {
118 const annotated_case_name = b.fmt("run compare-output {s} ({s})", .{
119 case.name, @tagName(optimize),
120 });
121 for (self.test_filters) |test_filter| {
122 if (mem.indexOf(u8, annotated_case_name, test_filter)) |_| break;
123 } else if (self.test_filters.len > 0) return;
124
125 const exe = b.addExecutable(.{
126 .name = "test",
127 .root_module = b.createModule(.{
128 .root_source_file = first_file,
129 .optimize = optimize,
130 .target = b.graph.host,
131 }),
132 });
133 if (case.link_libc) exe.root_module.link_libc = true;
134
135 const run = b.addRunArtifact(exe);
136 run.setName(annotated_case_name);
137 run.addArgs(case.cli_args);
138 run.expectStdOutEqual(case.expected_output);
139
140 self.step.dependOn(&run.step);
141 }
142 },
143 Special.RuntimeSafety => {
144 // TODO iterate over self.optimize_modes and test this in both
145 // debug and release safe mode
146 const annotated_case_name = b.fmt("run safety {s}", .{case.name});
147 for (self.test_filters) |test_filter| {
148 if (mem.indexOf(u8, annotated_case_name, test_filter)) |_| break;
149 } else if (self.test_filters.len > 0) return;
150
151 const exe = b.addExecutable(.{
152 .name = "test",
153 .root_module = b.createModule(.{
154 .root_source_file = first_file,
155 .target = b.graph.host,
156 .optimize = .Debug,
157 }),
158 });
159 if (case.link_libc) exe.root_module.link_libc = true;
160
161 const run = b.addRunArtifact(exe);
162 run.setName(annotated_case_name);
163 run.addArgs(case.cli_args);
164 run.expectExitCode(126);
165
166 self.step.dependOn(&run.step);
167 },
168 }
169}
170
171const CompareOutput = @This();
172const std = @import("std");
173const mem = std.mem;
174const fs = std.fs;
175const OptimizeMode = std.builtin.OptimizeMode;
test/tests.zig-37
......@@ -6,9 +6,7 @@ const OptimizeMode = std.builtin.OptimizeMode;
66const Step = std.Build.Step;
77
88// Cases
9const compare_output = @import("compare_output.zig");
109const stack_traces = @import("stack_traces.zig");
11const assemble_and_link = @import("assemble_and_link.zig");
1210const translate_c = @import("translate_c.zig");
1311const run_translated_c = @import("run_translated_c.zig");
1412const llvm_ir = @import("llvm_ir.zig");
......@@ -16,7 +14,6 @@ const llvm_ir = @import("llvm_ir.zig");
1614// Implementations
1715pub const TranslateCContext = @import("src/TranslateC.zig");
1816pub const RunTranslatedCContext = @import("src/RunTranslatedC.zig");
19pub const CompareOutputContext = @import("src/CompareOutput.zig");
2017pub const StackTracesContext = @import("src/StackTrace.zig");
2118pub const DebuggerContext = @import("src/Debugger.zig");
2219pub const LlvmIrContext = @import("src/LlvmIr.zig");
......@@ -1863,25 +1860,6 @@ const c_abi_targets = blk: {
18631860 };
18641861};
18651862
1866pub fn addCompareOutputTests(
1867 b: *std.Build,
1868 test_filters: []const []const u8,
1869 optimize_modes: []const OptimizeMode,
1870) *Step {
1871 const cases = b.allocator.create(CompareOutputContext) catch @panic("OOM");
1872 cases.* = CompareOutputContext{
1873 .b = b,
1874 .step = b.step("test-compare-output", "Run the compare output tests"),
1875 .test_index = 0,
1876 .test_filters = test_filters,
1877 .optimize_modes = optimize_modes,
1878 };
1879
1880 compare_output.addCases(cases);
1881
1882 return cases.step;
1883}
1884
18851863pub fn addStackTraceTests(
18861864 b: *std.Build,
18871865 test_filters: []const []const u8,
......@@ -2175,21 +2153,6 @@ pub fn addCliTests(b: *std.Build) *Step {
21752153 return step;
21762154}
21772155
2178pub fn addAssembleAndLinkTests(b: *std.Build, test_filters: []const []const u8, optimize_modes: []const OptimizeMode) *Step {
2179 const cases = b.allocator.create(CompareOutputContext) catch @panic("OOM");
2180 cases.* = CompareOutputContext{
2181 .b = b,
2182 .step = b.step("test-asm-link", "Run the assemble and link tests"),
2183 .test_index = 0,
2184 .test_filters = test_filters,
2185 .optimize_modes = optimize_modes,
2186 };
2187
2188 assemble_and_link.addCases(cases);
2189
2190 return cases.step;
2191}
2192
21932156pub fn addTranslateCTests(
21942157 b: *std.Build,
21952158 parent_step: *std.Build.Step,