authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-08-13 03:05:41+01:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-08-17 18:50:10-04:00
log936a79f428241f25468f5e54bd24bb6e9a78adbd
treecb509558299e8f38a4ec7c2e35431a8e65119608
parentaa6c1c40ec29d581844ebb5db09a33453c76d4ba

tools,test: improve incr-check and add new incremental tests


3 files changed, 133 insertions(+), 4 deletions(-)

test/incremental/add_decl_namespaced created+59
...@@ -0,0 +1,59 @@
1#target=x86_64-linux
2#update=initial version
3#file=main.zig
4const std = @import("std");
5pub fn main() !void {
6 try std.io.getStdOut().writeAll(@This().foo);
7}
8const foo = "good morning\n";
9#expect_stdout="good morning\n"
10
11#update=add new declaration
12#file=main.zig
13const std = @import("std");
14pub fn main() !void {
15 try std.io.getStdOut().writeAll(@This().foo);
16}
17const foo = "good morning\n";
18const bar = "good evening\n";
19#expect_stdout="good morning\n"
20
21#update=reference new declaration
22#file=main.zig
23const std = @import("std");
24pub fn main() !void {
25 try std.io.getStdOut().writeAll(@This().bar);
26}
27const foo = "good morning\n";
28const bar = "good evening\n";
29#expect_stdout="good evening\n"
30
31#update=reference missing declaration
32#file=main.zig
33const std = @import("std");
34pub fn main() !void {
35 try std.io.getStdOut().writeAll(@This().qux);
36}
37const foo = "good morning\n";
38const bar = "good evening\n";
39#expect_error=ignored
40
41#update=add missing declaration
42#file=main.zig
43const std = @import("std");
44pub fn main() !void {
45 try std.io.getStdOut().writeAll(@This().qux);
46}
47const foo = "good morning\n";
48const bar = "good evening\n";
49const qux = "good night\n";
50#expect_stdout="good night\n"
51
52#update=remove unused declarations
53#file=main.zig
54const std = @import("std");
55pub fn main() !void {
56 try std.io.getStdOut().writeAll(@This().qux);
57}
58const qux = "good night\n";
59#expect_stdout="good night\n"
test/incremental/unreferenced_error created+38
...@@ -0,0 +1,38 @@
1#target=x86_64-linux
2#update=initial version
3#file=main.zig
4const std = @import("std");
5pub fn main() !void {
6 try std.io.getStdOut().writeAll(a);
7}
8const a = "Hello, World!\n";
9#expect_stdout="Hello, World!\n"
10
11#update=introduce compile error
12#file=main.zig
13const std = @import("std");
14pub fn main() !void {
15 try std.io.getStdOut().writeAll(a);
16}
17const a = @compileError("bad a");
18#expect_error=ignored
19
20#update=remove error reference
21#file=main.zig
22const std = @import("std");
23pub fn main() !void {
24 try std.io.getStdOut().writeAll(b);
25}
26const a = @compileError("bad a");
27const b = "Hi there!\n";
28#expect_stdout="Hi there!\n"
29
30#update=introduce and remove reference to error
31#file=main.zig
32const std = @import("std");
33pub fn main() !void {
34 try std.io.getStdOut().writeAll(a);
35}
36const a = "Back to a\n";
37const b = @compileError("bad b");
38#expect_stdout="Back to a\n"
tools/incr-check.zig+36-4
...@@ -2,7 +2,7 @@ const std = @import("std");...@@ -2,7 +2,7 @@ const std = @import("std");
2const fatal = std.process.fatal;2const fatal = std.process.fatal;
3const Allocator = std.mem.Allocator;3const Allocator = std.mem.Allocator;
44
5const usage = "usage: incr-check <zig binary path> <input file> [-fno-emit-bin] [--zig-lib-dir lib]";5const usage = "usage: incr-check <zig binary path> <input file> [-fno-emit-bin] [--zig-lib-dir lib] [--debug-zcu]";
66
7pub fn main() !void {7pub fn main() !void {
8 var arena_instance = std.heap.ArenaAllocator.init(std.heap.page_allocator);8 var arena_instance = std.heap.ArenaAllocator.init(std.heap.page_allocator);
...@@ -13,6 +13,7 @@ pub fn main() !void {...@@ -13,6 +13,7 @@ pub fn main() !void {
13 var opt_input_file_name: ?[]const u8 = null;13 var opt_input_file_name: ?[]const u8 = null;
14 var opt_lib_dir: ?[]const u8 = null;14 var opt_lib_dir: ?[]const u8 = null;
15 var no_bin = false;15 var no_bin = false;
16 var debug_zcu = false;
1617
17 var arg_it = try std.process.argsWithAllocator(arena);18 var arg_it = try std.process.argsWithAllocator(arena);
18 _ = arg_it.skip();19 _ = arg_it.skip();
...@@ -20,6 +21,8 @@ pub fn main() !void {...@@ -20,6 +21,8 @@ pub fn main() !void {
20 if (arg.len > 0 and arg[0] == '-') {21 if (arg.len > 0 and arg[0] == '-') {
21 if (std.mem.eql(u8, arg, "-fno-emit-bin")) {22 if (std.mem.eql(u8, arg, "-fno-emit-bin")) {
22 no_bin = true;23 no_bin = true;
24 } else if (std.mem.eql(u8, arg, "--debug-zcu")) {
25 debug_zcu = true;
23 } else if (std.mem.eql(u8, arg, "--zig-lib-dir")) {26 } else if (std.mem.eql(u8, arg, "--zig-lib-dir")) {
24 opt_lib_dir = arg_it.next() orelse fatal("expected arg after '--zig-lib-dir'\n{s}", .{usage});27 opt_lib_dir = arg_it.next() orelse fatal("expected arg after '--zig-lib-dir'\n{s}", .{usage});
25 } else {28 } else {
...@@ -48,6 +51,13 @@ pub fn main() !void {...@@ -48,6 +51,13 @@ pub fn main() !void {
48 const tmp_dir_path = "tmp_" ++ std.fmt.hex(rand_int);51 const tmp_dir_path = "tmp_" ++ std.fmt.hex(rand_int);
49 const tmp_dir = try std.fs.cwd().makeOpenPath(tmp_dir_path, .{});52 const tmp_dir = try std.fs.cwd().makeOpenPath(tmp_dir_path, .{});
5053
54 if (opt_lib_dir) |lib_dir| {
55 if (!std.fs.path.isAbsolute(lib_dir)) {
56 // The cwd of the subprocess is within the tmp dir, so prepend `..` to the path.
57 opt_lib_dir = try std.fs.path.join(arena, &.{ "..", lib_dir });
58 }
59 }
60
51 const child_prog_node = prog_node.start("zig build-exe", 0);61 const child_prog_node = prog_node.start("zig build-exe", 0);
52 defer child_prog_node.end();62 defer child_prog_node.end();
5363
...@@ -74,6 +84,9 @@ pub fn main() !void {...@@ -74,6 +84,9 @@ pub fn main() !void {
74 } else {84 } else {
75 try child_args.appendSlice(arena, &.{ "-fno-llvm", "-fno-lld" });85 try child_args.appendSlice(arena, &.{ "-fno-llvm", "-fno-lld" });
76 }86 }
87 if (debug_zcu) {
88 try child_args.appendSlice(arena, &.{ "--debug-log", "zcu" });
89 }
7790
78 var child = std.process.Child.init(child_args.items, arena);91 var child = std.process.Child.init(child_args.items, arena);
79 child.stdin_behavior = .Pipe;92 child.stdin_behavior = .Pipe;
...@@ -89,6 +102,7 @@ pub fn main() !void {...@@ -89,6 +102,7 @@ pub fn main() !void {
89 .tmp_dir = tmp_dir,102 .tmp_dir = tmp_dir,
90 .tmp_dir_path = tmp_dir_path,103 .tmp_dir_path = tmp_dir_path,
91 .child = &child,104 .child = &child,
105 .allow_stderr = debug_zcu,
92 };106 };
93107
94 try child.spawn();108 try child.spawn();
...@@ -102,6 +116,11 @@ pub fn main() !void {...@@ -102,6 +116,11 @@ pub fn main() !void {
102 for (case.updates) |update| {116 for (case.updates) |update| {
103 var update_node = prog_node.start(update.name, 0);117 var update_node = prog_node.start(update.name, 0);
104 defer update_node.end();118 defer update_node.end();
119
120 if (debug_zcu) {
121 std.log.info("=== START UPDATE '{s}' ===", .{update.name});
122 }
123
105 eval.write(update);124 eval.write(update);
106 try eval.requestUpdate();125 try eval.requestUpdate();
107 try eval.check(&poller, update);126 try eval.check(&poller, update);
...@@ -118,6 +137,7 @@ const Eval = struct {...@@ -118,6 +137,7 @@ const Eval = struct {
118 tmp_dir: std.fs.Dir,137 tmp_dir: std.fs.Dir,
119 tmp_dir_path: []const u8,138 tmp_dir_path: []const u8,
120 child: *std.process.Child,139 child: *std.process.Child,
140 allow_stderr: bool,
121141
122 const StreamEnum = enum { stdout, stderr };142 const StreamEnum = enum { stdout, stderr };
123 const Poller = std.io.Poller(StreamEnum);143 const Poller = std.io.Poller(StreamEnum);
...@@ -173,7 +193,11 @@ const Eval = struct {...@@ -173,7 +193,11 @@ const Eval = struct {
173 };193 };
174 if (stderr.readableLength() > 0) {194 if (stderr.readableLength() > 0) {
175 const stderr_data = try stderr.toOwnedSlice();195 const stderr_data = try stderr.toOwnedSlice();
176 fatal("error_bundle included unexpected stderr:\n{s}", .{stderr_data});196 if (eval.allow_stderr) {
197 std.log.info("error_bundle included stderr:\n{s}", .{stderr_data});
198 } else {
199 fatal("error_bundle included unexpected stderr:\n{s}", .{stderr_data});
200 }
177 }201 }
178 if (result_error_bundle.errorMessageCount() == 0) {202 if (result_error_bundle.errorMessageCount() == 0) {
179 // Empty bundle indicates successful update in a `-fno-emit-bin` build.203 // Empty bundle indicates successful update in a `-fno-emit-bin` build.
...@@ -197,7 +221,11 @@ const Eval = struct {...@@ -197,7 +221,11 @@ const Eval = struct {
197 const result_binary = try arena.dupe(u8, body[@sizeOf(EbpHdr)..]);221 const result_binary = try arena.dupe(u8, body[@sizeOf(EbpHdr)..]);
198 if (stderr.readableLength() > 0) {222 if (stderr.readableLength() > 0) {
199 const stderr_data = try stderr.toOwnedSlice();223 const stderr_data = try stderr.toOwnedSlice();
200 fatal("emit_bin_path included unexpected stderr:\n{s}", .{stderr_data});224 if (eval.allow_stderr) {
225 std.log.info("emit_bin_path included stderr:\n{s}", .{stderr_data});
226 } else {
227 fatal("emit_bin_path included unexpected stderr:\n{s}", .{stderr_data});
228 }
201 }229 }
202 try eval.checkSuccessOutcome(update, result_binary);230 try eval.checkSuccessOutcome(update, result_binary);
203 // This message indicates the end of the update.231 // This message indicates the end of the update.
...@@ -213,7 +241,11 @@ const Eval = struct {...@@ -213,7 +241,11 @@ const Eval = struct {
213241
214 if (stderr.readableLength() > 0) {242 if (stderr.readableLength() > 0) {
215 const stderr_data = try stderr.toOwnedSlice();243 const stderr_data = try stderr.toOwnedSlice();
216 fatal("update '{s}' failed:\n{s}", .{ update.name, stderr_data });244 if (eval.allow_stderr) {
245 std.log.info("update '{s}' included stderr:\n{s}", .{ update.name, stderr_data });
246 } else {
247 fatal("update '{s}' failed:\n{s}", .{ update.name, stderr_data });
248 }
217 }249 }
218250
219 waitChild(eval.child);251 waitChild(eval.child);