Commit d767fae47e

Andrew Kelley <superjoe30@gmail.com>
2018-07-23 06:35:53
self-hosted: add first compare-output test
1 parent 93e78ee
Changed files (6)
src/windows_sdk.h
@@ -14,6 +14,8 @@
 #define ZIG_EXTERN_C
 #endif
 
+#include <stddef.h>
+
 struct ZigWindowsSDK {
     const char *path10_ptr;
     size_t path10_len;
src-self-hosted/compilation.zig
@@ -128,7 +128,6 @@ pub const Compilation = struct {
     version_patch: u32,
 
     linker_script: ?[]const u8,
-    cache_dir: []const u8,
     out_h_path: ?[]const u8,
 
     is_test: bool,
@@ -326,7 +325,6 @@ pub const Compilation = struct {
         build_mode: builtin.Mode,
         is_static: bool,
         zig_lib_dir: []const u8,
-        cache_dir: []const u8,
     ) !*Compilation {
         const loop = event_loop_local.loop;
         const comp = try event_loop_local.loop.allocator.create(Compilation{
@@ -341,7 +339,6 @@ pub const Compilation = struct {
             .build_mode = build_mode,
             .zig_lib_dir = zig_lib_dir,
             .zig_std_dir = undefined,
-            .cache_dir = cache_dir,
             .tmp_dir = event.Future(BuildError![]u8).init(loop),
 
             .name = undefined,
@@ -777,7 +774,8 @@ pub const Compilation = struct {
             defer decls.base.deref(self);
 
             var decl_group = event.Group(BuildError!void).init(self.loop);
-            errdefer decl_group.cancelAll();
+            // TODO https://github.com/ziglang/zig/issues/1261
+            //errdefer decl_group.cancelAll();
 
             var it = tree.root_node.decls.iterator(0);
             while (it.next()) |decl_ptr| {
src-self-hosted/main.zig
@@ -138,7 +138,6 @@ const usage_build_generic =
     \\Compile Options:
     \\  --libc [file]                Provide a file which specifies libc paths
     \\  --assembly [source]          Add assembly file to build
-    \\  --cache-dir [path]           Override the cache directory
     \\  --emit [filetype]            Emit a specific file format as compilation output
     \\  --enable-timing-info         Print timing diagnostics
     \\  --name [name]                Override output name
@@ -204,7 +203,6 @@ const args_build_generic = []Flag{
     }),
 
     Flag.ArgMergeN("--assembly", 1),
-    Flag.Arg1("--cache-dir"),
     Flag.Option("--emit", []const []const u8{
         "asm",
         "bin",
@@ -373,13 +371,6 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Co
         os.exit(1);
     }
 
-    const rel_cache_dir = flags.single("cache-dir") orelse "zig-cache"[0..];
-    const full_cache_dir = os.path.resolve(allocator, ".", rel_cache_dir) catch {
-        try stderr.print("invalid cache dir: {}\n", rel_cache_dir);
-        os.exit(1);
-    };
-    defer allocator.free(full_cache_dir);
-
     const zig_lib_dir = introspect.resolveZigLibDir(allocator) catch os.exit(1);
     defer allocator.free(zig_lib_dir);
 
@@ -401,7 +392,6 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Co
         build_mode,
         is_static,
         zig_lib_dir,
-        full_cache_dir,
     );
     defer comp.destroy();
 
@@ -472,7 +462,7 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Co
 
     comp.emit_file_type = emit_type;
     comp.assembly_files = assembly_files;
-    comp.link_out_file = flags.single("out-file");
+    comp.link_out_file = flags.single("output");
     comp.link_objects = link_objects;
 
     try comp.build();
src-self-hosted/test.zig
@@ -8,13 +8,14 @@ const assertOrPanic = std.debug.assertOrPanic;
 const errmsg = @import("errmsg.zig");
 const EventLoopLocal = @import("compilation.zig").EventLoopLocal;
 
-test "compile errors" {
-    var ctx: TestContext = undefined;
+var ctx: TestContext = undefined;
+
+test "stage2" {
     try ctx.init();
     defer ctx.deinit();
 
     try @import("../test/stage2/compile_errors.zig").addCases(&ctx);
-    //try @import("../test/stage2/compare_output.zig").addCases(&ctx);
+    try @import("../test/stage2/compare_output.zig").addCases(&ctx);
 
     try ctx.run();
 }
@@ -26,7 +27,6 @@ pub const TestContext = struct {
     loop: std.event.Loop,
     event_loop_local: EventLoopLocal,
     zig_lib_dir: []u8,
-    zig_cache_dir: []u8,
     file_index: std.atomic.Int(usize),
     group: std.event.Group(error!void),
     any_err: error!void,
@@ -39,7 +39,6 @@ pub const TestContext = struct {
             .loop = undefined,
             .event_loop_local = undefined,
             .zig_lib_dir = undefined,
-            .zig_cache_dir = undefined,
             .group = undefined,
             .file_index = std.atomic.Int(usize).init(0),
         };
@@ -56,16 +55,12 @@ pub const TestContext = struct {
         self.zig_lib_dir = try introspect.resolveZigLibDir(allocator);
         errdefer allocator.free(self.zig_lib_dir);
 
-        self.zig_cache_dir = try introspect.resolveZigCacheDir(allocator);
-        errdefer allocator.free(self.zig_cache_dir);
-
         try std.os.makePath(allocator, tmp_dir_name);
         errdefer std.os.deleteTree(allocator, tmp_dir_name) catch {};
     }
 
     fn deinit(self: *TestContext) void {
         std.os.deleteTree(allocator, tmp_dir_name) catch {};
-        allocator.free(self.zig_cache_dir);
         allocator.free(self.zig_lib_dir);
         self.event_loop_local.deinit();
         self.loop.deinit();
@@ -110,7 +105,6 @@ pub const TestContext = struct {
             builtin.Mode.Debug,
             true, // is_static
             self.zig_lib_dir,
-            self.zig_cache_dir,
         );
         errdefer comp.destroy();
 
@@ -119,6 +113,83 @@ pub const TestContext = struct {
         try self.group.call(getModuleEvent, comp, source, path, line, column, msg);
     }
 
+    fn testCompareOutputLibC(
+        self: *TestContext,
+        source: []const u8,
+        expected_output: []const u8,
+    ) !void {
+        var file_index_buf: [20]u8 = undefined;
+        const file_index = try std.fmt.bufPrint(file_index_buf[0..], "{}", self.file_index.incr());
+        const file1_path = try std.os.path.join(allocator, tmp_dir_name, file_index, file1);
+
+        const output_file = try std.fmt.allocPrint(allocator, "{}-out{}", file1_path, Target(Target.Native).exeFileExt());
+        if (std.os.path.dirname(file1_path)) |dirname| {
+            try std.os.makePath(allocator, dirname);
+        }
+
+        // TODO async I/O
+        try std.io.writeFile(allocator, file1_path, source);
+
+        var comp = try Compilation.create(
+            &self.event_loop_local,
+            "test",
+            file1_path,
+            Target.Native,
+            Compilation.Kind.Exe,
+            builtin.Mode.Debug,
+            false,
+            self.zig_lib_dir,
+        );
+        errdefer comp.destroy();
+
+        _ = try comp.addLinkLib("c", true);
+        comp.link_out_file = output_file;
+        try comp.build();
+
+        try self.group.call(getModuleEventSuccess, comp, output_file, expected_output);
+    }
+
+    async fn getModuleEventSuccess(
+        comp: *Compilation,
+        exe_file: []const u8,
+        expected_output: []const u8,
+    ) !void {
+        // TODO this should not be necessary
+        const exe_file_2 = try std.mem.dupe(allocator, u8, exe_file);
+
+        defer comp.destroy();
+        const build_event = await (async comp.events.get() catch unreachable);
+
+        switch (build_event) {
+            Compilation.Event.Ok => {
+                const argv = []const []const u8{exe_file_2};
+                // TODO use event loop
+                const child = try std.os.ChildProcess.exec(allocator, argv, null, null, 1024 * 1024);
+                switch (child.term) {
+                    std.os.ChildProcess.Term.Exited => |code| {
+                        if (code != 0) {
+                            return error.BadReturnCode;
+                        }
+                    },
+                    else => {
+                        return error.Crashed;
+                    },
+                }
+                if (!mem.eql(u8, child.stdout, expected_output)) {
+                    return error.OutputMismatch;
+                }
+            },
+            Compilation.Event.Error => |err| return err,
+            Compilation.Event.Fail => |msgs| {
+                var stderr = try std.io.getStdErr();
+                try stderr.write("build incorrectly failed:\n");
+                for (msgs) |msg| {
+                    try errmsg.printToFile(&stderr, msg, errmsg.Color.Auto);
+                }
+            },
+        }
+    }
+
     async fn getModuleEvent(
         comp: *Compilation,
         source: []const u8,
std/os/test.zig
@@ -23,14 +23,14 @@ test "makePath, put some files in it, deleteTree" {
 
 test "access file" {
     try os.makePath(a, "os_test_tmp");
-    if (os.File.access(a, "os_test_tmp/file.txt", os.default_file_mode)) |ok| {
-        unreachable;
+    if (os.File.access(a, "os_test_tmp/file.txt")) |ok| {
+        @panic("expected error");
     } else |err| {
         assert(err == error.NotFound);
     }
 
     try io.writeFile(a, "os_test_tmp/file.txt", "");
-    assert((try os.File.access(a, "os_test_tmp/file.txt", os.default_file_mode)) == true);
+    try os.File.access(a, "os_test_tmp/file.txt");
     try os.deleteTree(a, "os_test_tmp");
 }
 
test/stage2/compare_output.zig
@@ -0,0 +1,12 @@
+const std = @import("std");
+const TestContext = @import("../../src-self-hosted/test.zig").TestContext;
+
+pub fn addCases(ctx: *TestContext) !void {
+    try ctx.testCompareOutputLibC(
+        \\extern fn puts([*]const u8) void;
+        \\export fn main() c_int {
+        \\    puts(c"Hello, world!");
+        \\    return 0;
+        \\}
+    , "Hello, world!" ++ std.cstr.line_sep);
+}