authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-07-23 00:35:53-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-07-23 00:35:53-04:00
logd767fae47e89aef53505191cf11ce7e592a784b2
treed72db72137e11c77f58b3407b4ed3399e428a328
parent93e78ee72259b98840f63db0ad87fdddb071e384

self-hosted: add first compare-output test


6 files changed, 101 insertions(+), 28 deletions(-)

src-self-hosted/compilation.zig+2-4
...@@ -128,7 +128,6 @@ pub const Compilation = struct {...@@ -128,7 +128,6 @@ pub const Compilation = struct {
128 version_patch: u32,128 version_patch: u32,
129129
130 linker_script: ?[]const u8,130 linker_script: ?[]const u8,
131 cache_dir: []const u8,
132 out_h_path: ?[]const u8,131 out_h_path: ?[]const u8,
133132
134 is_test: bool,133 is_test: bool,
...@@ -326,7 +325,6 @@ pub const Compilation = struct {...@@ -326,7 +325,6 @@ pub const Compilation = struct {
326 build_mode: builtin.Mode,325 build_mode: builtin.Mode,
327 is_static: bool,326 is_static: bool,
328 zig_lib_dir: []const u8,327 zig_lib_dir: []const u8,
329 cache_dir: []const u8,
330 ) !*Compilation {328 ) !*Compilation {
331 const loop = event_loop_local.loop;329 const loop = event_loop_local.loop;
332 const comp = try event_loop_local.loop.allocator.create(Compilation{330 const comp = try event_loop_local.loop.allocator.create(Compilation{
...@@ -341,7 +339,6 @@ pub const Compilation = struct {...@@ -341,7 +339,6 @@ pub const Compilation = struct {
341 .build_mode = build_mode,339 .build_mode = build_mode,
342 .zig_lib_dir = zig_lib_dir,340 .zig_lib_dir = zig_lib_dir,
343 .zig_std_dir = undefined,341 .zig_std_dir = undefined,
344 .cache_dir = cache_dir,
345 .tmp_dir = event.Future(BuildError![]u8).init(loop),342 .tmp_dir = event.Future(BuildError![]u8).init(loop),
346343
347 .name = undefined,344 .name = undefined,
...@@ -777,7 +774,8 @@ pub const Compilation = struct {...@@ -777,7 +774,8 @@ pub const Compilation = struct {
777 defer decls.base.deref(self);774 defer decls.base.deref(self);
778775
779 var decl_group = event.Group(BuildError!void).init(self.loop);776 var decl_group = event.Group(BuildError!void).init(self.loop);
780 errdefer decl_group.cancelAll();777 // TODO https://github.com/ziglang/zig/issues/1261
778 //errdefer decl_group.cancelAll();
781779
782 var it = tree.root_node.decls.iterator(0);780 var it = tree.root_node.decls.iterator(0);
783 while (it.next()) |decl_ptr| {781 while (it.next()) |decl_ptr| {
src-self-hosted/main.zig+1-11
...@@ -138,7 +138,6 @@ const usage_build_generic =...@@ -138,7 +138,6 @@ const usage_build_generic =
138 \\Compile Options:138 \\Compile Options:
139 \\ --libc [file] Provide a file which specifies libc paths139 \\ --libc [file] Provide a file which specifies libc paths
140 \\ --assembly [source] Add assembly file to build140 \\ --assembly [source] Add assembly file to build
141 \\ --cache-dir [path] Override the cache directory
142 \\ --emit [filetype] Emit a specific file format as compilation output141 \\ --emit [filetype] Emit a specific file format as compilation output
143 \\ --enable-timing-info Print timing diagnostics142 \\ --enable-timing-info Print timing diagnostics
144 \\ --name [name] Override output name143 \\ --name [name] Override output name
...@@ -204,7 +203,6 @@ const args_build_generic = []Flag{...@@ -204,7 +203,6 @@ const args_build_generic = []Flag{
204 }),203 }),
205204
206 Flag.ArgMergeN("--assembly", 1),205 Flag.ArgMergeN("--assembly", 1),
207 Flag.Arg1("--cache-dir"),
208 Flag.Option("--emit", []const []const u8{206 Flag.Option("--emit", []const []const u8{
209 "asm",207 "asm",
210 "bin",208 "bin",
...@@ -373,13 +371,6 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Co...@@ -373,13 +371,6 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Co
373 os.exit(1);371 os.exit(1);
374 }372 }
375373
376 const rel_cache_dir = flags.single("cache-dir") orelse "zig-cache"[0..];
377 const full_cache_dir = os.path.resolve(allocator, ".", rel_cache_dir) catch {
378 try stderr.print("invalid cache dir: {}\n", rel_cache_dir);
379 os.exit(1);
380 };
381 defer allocator.free(full_cache_dir);
382
383 const zig_lib_dir = introspect.resolveZigLibDir(allocator) catch os.exit(1);374 const zig_lib_dir = introspect.resolveZigLibDir(allocator) catch os.exit(1);
384 defer allocator.free(zig_lib_dir);375 defer allocator.free(zig_lib_dir);
385376
...@@ -401,7 +392,6 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Co...@@ -401,7 +392,6 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Co
401 build_mode,392 build_mode,
402 is_static,393 is_static,
403 zig_lib_dir,394 zig_lib_dir,
404 full_cache_dir,
405 );395 );
406 defer comp.destroy();396 defer comp.destroy();
407397
...@@ -472,7 +462,7 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Co...@@ -472,7 +462,7 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Co
472462
473 comp.emit_file_type = emit_type;463 comp.emit_file_type = emit_type;
474 comp.assembly_files = assembly_files;464 comp.assembly_files = assembly_files;
475 comp.link_out_file = flags.single("out-file");465 comp.link_out_file = flags.single("output");
476 comp.link_objects = link_objects;466 comp.link_objects = link_objects;
477467
478 try comp.build();468 try comp.build();
src-self-hosted/test.zig+81-10
...@@ -8,13 +8,14 @@ const assertOrPanic = std.debug.assertOrPanic;...@@ -8,13 +8,14 @@ const assertOrPanic = std.debug.assertOrPanic;
8const errmsg = @import("errmsg.zig");8const errmsg = @import("errmsg.zig");
9const EventLoopLocal = @import("compilation.zig").EventLoopLocal;9const EventLoopLocal = @import("compilation.zig").EventLoopLocal;
1010
11test "compile errors" {11var ctx: TestContext = undefined;
12 var ctx: TestContext = undefined;12
13test "stage2" {
13 try ctx.init();14 try ctx.init();
14 defer ctx.deinit();15 defer ctx.deinit();
1516
16 try @import("../test/stage2/compile_errors.zig").addCases(&ctx);17 try @import("../test/stage2/compile_errors.zig").addCases(&ctx);
17 //try @import("../test/stage2/compare_output.zig").addCases(&ctx);18 try @import("../test/stage2/compare_output.zig").addCases(&ctx);
1819
19 try ctx.run();20 try ctx.run();
20}21}
...@@ -26,7 +27,6 @@ pub const TestContext = struct {...@@ -26,7 +27,6 @@ pub const TestContext = struct {
26 loop: std.event.Loop,27 loop: std.event.Loop,
27 event_loop_local: EventLoopLocal,28 event_loop_local: EventLoopLocal,
28 zig_lib_dir: []u8,29 zig_lib_dir: []u8,
29 zig_cache_dir: []u8,
30 file_index: std.atomic.Int(usize),30 file_index: std.atomic.Int(usize),
31 group: std.event.Group(error!void),31 group: std.event.Group(error!void),
32 any_err: error!void,32 any_err: error!void,
...@@ -39,7 +39,6 @@ pub const TestContext = struct {...@@ -39,7 +39,6 @@ pub const TestContext = struct {
39 .loop = undefined,39 .loop = undefined,
40 .event_loop_local = undefined,40 .event_loop_local = undefined,
41 .zig_lib_dir = undefined,41 .zig_lib_dir = undefined,
42 .zig_cache_dir = undefined,
43 .group = undefined,42 .group = undefined,
44 .file_index = std.atomic.Int(usize).init(0),43 .file_index = std.atomic.Int(usize).init(0),
45 };44 };
...@@ -56,16 +55,12 @@ pub const TestContext = struct {...@@ -56,16 +55,12 @@ pub const TestContext = struct {
56 self.zig_lib_dir = try introspect.resolveZigLibDir(allocator);55 self.zig_lib_dir = try introspect.resolveZigLibDir(allocator);
57 errdefer allocator.free(self.zig_lib_dir);56 errdefer allocator.free(self.zig_lib_dir);
5857
59 self.zig_cache_dir = try introspect.resolveZigCacheDir(allocator);
60 errdefer allocator.free(self.zig_cache_dir);
61
62 try std.os.makePath(allocator, tmp_dir_name);58 try std.os.makePath(allocator, tmp_dir_name);
63 errdefer std.os.deleteTree(allocator, tmp_dir_name) catch {};59 errdefer std.os.deleteTree(allocator, tmp_dir_name) catch {};
64 }60 }
6561
66 fn deinit(self: *TestContext) void {62 fn deinit(self: *TestContext) void {
67 std.os.deleteTree(allocator, tmp_dir_name) catch {};63 std.os.deleteTree(allocator, tmp_dir_name) catch {};
68 allocator.free(self.zig_cache_dir);
69 allocator.free(self.zig_lib_dir);64 allocator.free(self.zig_lib_dir);
70 self.event_loop_local.deinit();65 self.event_loop_local.deinit();
71 self.loop.deinit();66 self.loop.deinit();
...@@ -110,7 +105,6 @@ pub const TestContext = struct {...@@ -110,7 +105,6 @@ pub const TestContext = struct {
110 builtin.Mode.Debug,105 builtin.Mode.Debug,
111 true, // is_static106 true, // is_static
112 self.zig_lib_dir,107 self.zig_lib_dir,
113 self.zig_cache_dir,
114 );108 );
115 errdefer comp.destroy();109 errdefer comp.destroy();
116110
...@@ -119,6 +113,83 @@ pub const TestContext = struct {...@@ -119,6 +113,83 @@ pub const TestContext = struct {
119 try self.group.call(getModuleEvent, comp, source, path, line, column, msg);113 try self.group.call(getModuleEvent, comp, source, path, line, column, msg);
120 }114 }
121115
116 fn testCompareOutputLibC(
117 self: *TestContext,
118 source: []const u8,
119 expected_output: []const u8,
120 ) !void {
121 var file_index_buf: [20]u8 = undefined;
122 const file_index = try std.fmt.bufPrint(file_index_buf[0..], "{}", self.file_index.incr());
123 const file1_path = try std.os.path.join(allocator, tmp_dir_name, file_index, file1);
124
125 const output_file = try std.fmt.allocPrint(allocator, "{}-out{}", file1_path, Target(Target.Native).exeFileExt());
126 if (std.os.path.dirname(file1_path)) |dirname| {
127 try std.os.makePath(allocator, dirname);
128 }
129
130 // TODO async I/O
131 try std.io.writeFile(allocator, file1_path, source);
132
133 var comp = try Compilation.create(
134 &self.event_loop_local,
135 "test",
136 file1_path,
137 Target.Native,
138 Compilation.Kind.Exe,
139 builtin.Mode.Debug,
140 false,
141 self.zig_lib_dir,
142 );
143 errdefer comp.destroy();
144
145 _ = try comp.addLinkLib("c", true);
146 comp.link_out_file = output_file;
147 try comp.build();
148
149 try self.group.call(getModuleEventSuccess, comp, output_file, expected_output);
150 }
151
152 async fn getModuleEventSuccess(
153 comp: *Compilation,
154 exe_file: []const u8,
155 expected_output: []const u8,
156 ) !void {
157 // TODO this should not be necessary
158 const exe_file_2 = try std.mem.dupe(allocator, u8, exe_file);
159
160 defer comp.destroy();
161 const build_event = await (async comp.events.get() catch unreachable);
162
163 switch (build_event) {
164 Compilation.Event.Ok => {
165 const argv = []const []const u8{exe_file_2};
166 // TODO use event loop
167 const child = try std.os.ChildProcess.exec(allocator, argv, null, null, 1024 * 1024);
168 switch (child.term) {
169 std.os.ChildProcess.Term.Exited => |code| {
170 if (code != 0) {
171 return error.BadReturnCode;
172 }
173 },
174 else => {
175 return error.Crashed;
176 },
177 }
178 if (!mem.eql(u8, child.stdout, expected_output)) {
179 return error.OutputMismatch;
180 }
181 },
182 Compilation.Event.Error => |err| return err,
183 Compilation.Event.Fail => |msgs| {
184 var stderr = try std.io.getStdErr();
185 try stderr.write("build incorrectly failed:\n");
186 for (msgs) |msg| {
187 try errmsg.printToFile(&stderr, msg, errmsg.Color.Auto);
188 }
189 },
190 }
191 }
192
122 async fn getModuleEvent(193 async fn getModuleEvent(
123 comp: *Compilation,194 comp: *Compilation,
124 source: []const u8,195 source: []const u8,
src/windows_sdk.h+2
...@@ -14,6 +14,8 @@...@@ -14,6 +14,8 @@
14#define ZIG_EXTERN_C14#define ZIG_EXTERN_C
15#endif15#endif
1616
17#include <stddef.h>
18
17struct ZigWindowsSDK {19struct ZigWindowsSDK {
18 const char *path10_ptr;20 const char *path10_ptr;
19 size_t path10_len;21 size_t path10_len;
std/os/test.zig+3-3
...@@ -23,14 +23,14 @@ test "makePath, put some files in it, deleteTree" {...@@ -23,14 +23,14 @@ test "makePath, put some files in it, deleteTree" {
2323
24test "access file" {24test "access file" {
25 try os.makePath(a, "os_test_tmp");25 try os.makePath(a, "os_test_tmp");
26 if (os.File.access(a, "os_test_tmp/file.txt", os.default_file_mode)) |ok| {26 if (os.File.access(a, "os_test_tmp/file.txt")) |ok| {
27 unreachable;27 @panic("expected error");
28 } else |err| {28 } else |err| {
29 assert(err == error.NotFound);29 assert(err == error.NotFound);
30 }30 }
3131
32 try io.writeFile(a, "os_test_tmp/file.txt", "");32 try io.writeFile(a, "os_test_tmp/file.txt", "");
33 assert((try os.File.access(a, "os_test_tmp/file.txt", os.default_file_mode)) == true);33 try os.File.access(a, "os_test_tmp/file.txt");
34 try os.deleteTree(a, "os_test_tmp");34 try os.deleteTree(a, "os_test_tmp");
35}35}
3636
test/stage2/compare_output.zig created+12
...@@ -0,0 +1,12 @@
1const std = @import("std");
2const TestContext = @import("../../src-self-hosted/test.zig").TestContext;
3
4pub fn addCases(ctx: *TestContext) !void {
5 try ctx.testCompareOutputLibC(
6 \\extern fn puts([*]const u8) void;
7 \\export fn main() c_int {
8 \\ puts(c"Hello, world!");
9 \\ return 0;
10 \\}
11 , "Hello, world!" ++ std.cstr.line_sep);
12}