Browse Source

convert BASH test to Zig so we can start testing on Windows

Jonathan Marler 3 years ago
parent
commit
ea1f4a3bed
4 changed files with 172 additions and 44 deletions
  1. 1 0
      .gitignore
  2. 16 0
      build.zig
  3. 0 44
      test
  4. 155 0
      test.zig

+ 1 - 0
.gitignore

@@ -1,4 +1,5 @@
 *~
 zig-cache/
+zig-out/
 /dep
 /scratch

+ 16 - 0
build.zig

@@ -41,6 +41,22 @@ pub fn build(b: *Builder) !void {
 
     const run_step = b.step("run", "Run the app");
     run_step.dependOn(&run_cmd.step);
+
+    addTest(b, exe, target, mode);
+}
+
+fn addTest(b: *Builder, exe: *std.build.LibExeObjStep, target: std.zig.CrossTarget, mode: std.builtin.Mode) void {
+    const test_exe = b.addExecutable("test", "test.zig");
+    test_exe.setTarget(target);
+    test_exe.setBuildMode(mode);
+    const run_cmd = test_exe.run();
+
+    // TODO: make this work, add exe install path as argument to test
+    //run_cmd.addArg(exe.getInstallPath());
+    run_cmd.step.dependOn(b.getInstallStep());
+
+    const test_step = b.step("test", "test the executable");
+    test_step.dependOn(&run_cmd.step);
 }
 
 fn addZigupExe(b: *Builder, ziget_repo: []const u8, target: std.zig.CrossTarget, mode: std.builtin.Mode, ssl_backend: ?SslBackend) !*std.build.LibExeObjStep {

+ 0 - 44
test

@@ -1,44 +0,0 @@
-#!/usr/bin/env sh
-set -ex
-
-testCompilerCount() {
-  compiler_count=$(find scratch/install -mindepth 1 -maxdepth 1 -type d | wc -l)
-  test "$compiler_count" = $1
-}
-
-rm -rf scratch
-mkdir scratch
-mkdir scratch/install scratch/bin
-
-zigup="./zig-out/bin/zigup --install-dir scratch/install --path-link scratch/bin/zig"
-
-$zigup -h 2>&1 | grep Usage
-$zigup --help 2>&1 | grep Usage
-$zigup $opt || true
-$zigup default
-$zigup fetch-index
-$zigup 0.5.0
-$zigup fetch 0.5.0
-$zigup master
-$zigup 0.6.0
-$zigup list
-$zigup default 0.5.0
-
-testCompilerCount 3
-
-$zigup keep 0.6.0
-$zigup clean # doesn't delete anything because we have keepfile and master doens't get deleted
-testCompilerCount 3
-
-$zigup clean 0.6.0 2>&1 | grep "deleting '.*0.6.0'"
-testCompilerCount 2
-$zigup clean 2>&1 | grep "it is master" # DOESN't delete master because we dont delete master, but DOES delete 0.6.0
-testCompilerCount 2
-
-$zigup master
-testCompilerCount 2
-
-$zigup DOESNOTEXIST 2>&1 | grep "HTTP request failed"
-testCompilerCount 2
-
-echo Success

+ 155 - 0
test.zig

@@ -0,0 +1,155 @@
+const std = @import("std");
+const testing = std.testing;
+
+const sep = std.fs.path.sep_str;
+
+pub fn main() !void {
+    std.log.info("running test!", .{});
+    try std.fs.cwd().deleteTree("scratch");
+    try std.fs.cwd().makeDir("scratch");
+    const install_dir = "scratch" ++ sep ++ "install";
+    const bin_dir = "scratch" ++ sep ++ "bin";
+    try std.fs.cwd().makeDir(install_dir);
+    try std.fs.cwd().makeDir(bin_dir);
+
+    // NOTE: for now we are incorrectly assuming the install dir is CWD/zig-out
+    const zigup = "." ++ sep ++ "zig-out" ++ sep ++ "bin" ++ sep ++ "zigup" ++ std.builtin.target.exeFileExt();
+    const zigup_args = &[_][]const u8 { zigup, "--install-dir", install_dir, "--path-link", bin_dir ++ sep ++ "zig" };
+
+    var allocator_store = std.heap.ArenaAllocator.init(std.heap.page_allocator);
+    defer allocator_store.deinit();
+    const allocator = &allocator_store.allocator;
+
+    {
+        const result = try runCaptureOuts(allocator, ".", zigup_args ++ &[_][]const u8 {"-h"});
+        defer { allocator.free(result.stdout); allocator.free(result.stderr); }
+        try testing.expect(std.mem.containsAtLeast(u8, result.stderr, 1, "Usage"));
+    }
+    {
+        const result = try runCaptureOuts(allocator, ".", zigup_args ++ &[_][]const u8 {"--help"});
+        defer { allocator.free(result.stdout); allocator.free(result.stderr); }
+        try testing.expect(std.mem.containsAtLeast(u8, result.stderr, 1, "Usage"));
+    }
+
+    {
+        const result = try runCaptureOuts(allocator, ".", zigup_args ++ &[_][]const u8 {"default"});
+        defer { allocator.free(result.stdout); allocator.free(result.stderr); }
+        try passOrDumpAndThrow(result);
+        try testing.expect(std.mem.containsAtLeast(u8, result.stderr, 1, "<no-default>"));
+    }
+    {
+        const result = try runCaptureOuts(allocator, ".", zigup_args ++ &[_][]const u8 {"fetch-index"});
+        defer { allocator.free(result.stdout); allocator.free(result.stderr); }
+        try passOrDumpAndThrow(result);
+        try testing.expect(std.mem.containsAtLeast(u8, result.stdout, 1, "master"));
+    }
+    try runNoCapture(".", zigup_args ++ &[_][]const u8 {"0.5.0"});
+    {
+        const result = try runCaptureOuts(allocator, ".", zigup_args ++ &[_][]const u8 {"fetch", "0.5.0"});
+        defer { allocator.free(result.stdout); allocator.free(result.stderr); }
+        try passOrDumpAndThrow(result);
+        try testing.expect(std.mem.containsAtLeast(u8, result.stderr, 1, "already installed"));
+    }
+    try runNoCapture(".", zigup_args ++ &[_][]const u8 {"master"});
+    try runNoCapture(".", zigup_args ++ &[_][]const u8 {"0.6.0"});
+    {
+        const result = try runCaptureOuts(allocator, ".", zigup_args ++ &[_][]const u8 {"list"});
+        defer { allocator.free(result.stdout); allocator.free(result.stderr); }
+        try passOrDumpAndThrow(result);
+        try testing.expect(std.mem.containsAtLeast(u8, result.stdout, 1, "0.5.0"));
+        try testing.expect(std.mem.containsAtLeast(u8, result.stdout, 1, "0.6.0"));
+    }
+    try runNoCapture(".", zigup_args ++ &[_][]const u8 {"default", "0.5.0"});
+    try testing.expectEqual(@as(u32, 3), try getCompilerCount(install_dir));
+
+    try runNoCapture(".", zigup_args ++ &[_][]const u8 {"keep", "0.6.0"});
+    // doesn't delete anything because we have keepfile and master doens't get deleted
+    try runNoCapture(".", zigup_args ++ &[_][]const u8 {"clean"});
+    try testing.expectEqual(@as(u32, 3), try getCompilerCount(install_dir));
+
+    {
+        const result = try runCaptureOuts(allocator, ".", zigup_args ++ &[_][]const u8 {"clean", "0.6.0"});
+        defer { allocator.free(result.stdout); allocator.free(result.stderr); }
+        try passOrDumpAndThrow(result);
+        try testing.expect(std.mem.containsAtLeast(u8, result.stderr, 1, "deleting "));
+        try testing.expect(std.mem.containsAtLeast(u8, result.stderr, 1, "0.6.0"));
+    }
+    try testing.expectEqual(@as(u32, 2), try getCompilerCount(install_dir));
+
+    {
+        const result = try runCaptureOuts(allocator, ".", zigup_args ++ &[_][]const u8 {"clean"});
+        defer { allocator.free(result.stdout); allocator.free(result.stderr); }
+        try passOrDumpAndThrow(result);
+        try testing.expect(std.mem.containsAtLeast(u8, result.stderr, 1, "it is master"));
+    }
+    try testing.expectEqual(@as(u32, 2), try getCompilerCount(install_dir));
+
+    try runNoCapture(".", zigup_args ++ &[_][]const u8 {"master"});
+    try testing.expectEqual(@as(u32, 2), try getCompilerCount(install_dir));
+
+    {
+        const result = try runCaptureOuts(allocator, ".", zigup_args ++ &[_][]const u8 {"DOESNOTEXST"});
+        defer { allocator.free(result.stdout); allocator.free(result.stderr); }
+        try testing.expect(std.mem.containsAtLeast(u8, result.stderr, 1, "HTTP request failed"));
+    }
+    try testing.expectEqual(@as(u32, 2), try getCompilerCount(install_dir));
+}
+
+fn getCompilerCount(install_dir: []const u8) !u32 {
+    var dir = try std.fs.cwd().openDir(install_dir, .{.iterate=true});
+    defer dir.close();
+    var it = dir.iterate();
+    var count: u32 = 0;
+    while (try it.next()) |entry| {
+        if (entry.kind == .Directory) {
+            count += 1;
+        } else {
+            try testing.expect(entry.kind == .SymLink);
+        }
+    }
+    return count;
+}
+
+fn dumpExecResult(result: std.ChildProcess.ExecResult) void {
+    if (result.stdout.len > 0) {
+        std.log.info("STDOUT: '{s}'", .{result.stdout});
+    }
+    if (result.stderr.len > 0) {
+        std.log.info("STDERR: '{s}'", .{result.stderr});
+    }
+}
+
+fn runNoCapture(cwd: []const u8, argv: []const []const u8) !void {
+    var arena_store = std.heap.ArenaAllocator.init(std.heap.page_allocator);
+    defer arena_store.deinit();
+    const result = try runCaptureOuts(&arena_store.allocator, cwd, argv);
+    dumpExecResult(result);
+    try passOrThrow(result.term);
+}
+fn runCaptureOuts(allocator: *std.mem.Allocator, cwd: []const u8, argv: []const []const u8) !std.ChildProcess.ExecResult {
+    {
+        const cmd = try std.mem.join(allocator, " ", argv);
+        defer allocator.free(cmd);
+        std.log.info("RUN(cwd={s}): {s}", .{cwd, cmd});
+    }
+    return try std.ChildProcess.exec(.{.allocator = allocator, .argv = argv, .cwd = cwd});
+}
+fn passOrThrow(term: std.ChildProcess.Term) error{ChildProcessFailed}!void {
+    if (!execResultPassed(term)) {
+        std.log.err("child process failed with {}", .{term});
+        return error.ChildProcessFailed;
+    }
+}
+fn passOrDumpAndThrow(result: std.ChildProcess.ExecResult) error{ChildProcessFailed}!void {
+    if (!execResultPassed(result.term)) {
+        dumpExecResult(result);
+        std.log.err("child process failed with {}", .{result.term});
+        return error.ChildProcessFailed;
+    }
+}
+fn execResultPassed(term: std.ChildProcess.Term) bool {
+    switch (term) {
+        .Exited => |code| return code == 0,
+        else => return false,
+    }
+}