test.zig 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. const std = @import("std");
  2. const testing = std.testing;
  3. const sep = std.fs.path.sep_str;
  4. pub fn main() !void {
  5. std.log.info("running test!", .{});
  6. try std.fs.cwd().deleteTree("scratch");
  7. try std.fs.cwd().makeDir("scratch");
  8. const install_dir = "scratch" ++ sep ++ "install";
  9. const bin_dir = "scratch" ++ sep ++ "bin";
  10. try std.fs.cwd().makeDir(install_dir);
  11. try std.fs.cwd().makeDir(bin_dir);
  12. // NOTE: for now we are incorrectly assuming the install dir is CWD/zig-out
  13. const zigup = "." ++ sep ++ "zig-out" ++ sep ++ "bin" ++ sep ++ "zigup" ++ std.builtin.target.exeFileExt();
  14. const zigup_args = &[_][]const u8 { zigup, "--install-dir", install_dir, "--path-link", bin_dir ++ sep ++ "zig" };
  15. var allocator_store = std.heap.ArenaAllocator.init(std.heap.page_allocator);
  16. defer allocator_store.deinit();
  17. const allocator = &allocator_store.allocator;
  18. {
  19. const result = try runCaptureOuts(allocator, ".", zigup_args ++ &[_][]const u8 {"-h"});
  20. defer { allocator.free(result.stdout); allocator.free(result.stderr); }
  21. try testing.expect(std.mem.containsAtLeast(u8, result.stderr, 1, "Usage"));
  22. }
  23. {
  24. const result = try runCaptureOuts(allocator, ".", zigup_args ++ &[_][]const u8 {"--help"});
  25. defer { allocator.free(result.stdout); allocator.free(result.stderr); }
  26. try testing.expect(std.mem.containsAtLeast(u8, result.stderr, 1, "Usage"));
  27. }
  28. {
  29. const result = try runCaptureOuts(allocator, ".", zigup_args ++ &[_][]const u8 {"default"});
  30. defer { allocator.free(result.stdout); allocator.free(result.stderr); }
  31. try passOrDumpAndThrow(result);
  32. try testing.expect(std.mem.containsAtLeast(u8, result.stderr, 1, "<no-default>"));
  33. }
  34. {
  35. const result = try runCaptureOuts(allocator, ".", zigup_args ++ &[_][]const u8 {"fetch-index"});
  36. defer { allocator.free(result.stdout); allocator.free(result.stderr); }
  37. try passOrDumpAndThrow(result);
  38. try testing.expect(std.mem.containsAtLeast(u8, result.stdout, 1, "master"));
  39. }
  40. try runNoCapture(".", zigup_args ++ &[_][]const u8 {"0.5.0"});
  41. {
  42. const result = try runCaptureOuts(allocator, ".", zigup_args ++ &[_][]const u8 {"fetch", "0.5.0"});
  43. defer { allocator.free(result.stdout); allocator.free(result.stderr); }
  44. try passOrDumpAndThrow(result);
  45. try testing.expect(std.mem.containsAtLeast(u8, result.stderr, 1, "already installed"));
  46. }
  47. try runNoCapture(".", zigup_args ++ &[_][]const u8 {"master"});
  48. try runNoCapture(".", zigup_args ++ &[_][]const u8 {"0.6.0"});
  49. {
  50. const result = try runCaptureOuts(allocator, ".", zigup_args ++ &[_][]const u8 {"list"});
  51. defer { allocator.free(result.stdout); allocator.free(result.stderr); }
  52. try passOrDumpAndThrow(result);
  53. try testing.expect(std.mem.containsAtLeast(u8, result.stdout, 1, "0.5.0"));
  54. try testing.expect(std.mem.containsAtLeast(u8, result.stdout, 1, "0.6.0"));
  55. }
  56. try runNoCapture(".", zigup_args ++ &[_][]const u8 {"default", "0.5.0"});
  57. try testing.expectEqual(@as(u32, 3), try getCompilerCount(install_dir));
  58. try runNoCapture(".", zigup_args ++ &[_][]const u8 {"keep", "0.6.0"});
  59. // doesn't delete anything because we have keepfile and master doens't get deleted
  60. try runNoCapture(".", zigup_args ++ &[_][]const u8 {"clean"});
  61. try testing.expectEqual(@as(u32, 3), try getCompilerCount(install_dir));
  62. {
  63. const result = try runCaptureOuts(allocator, ".", zigup_args ++ &[_][]const u8 {"clean", "0.6.0"});
  64. defer { allocator.free(result.stdout); allocator.free(result.stderr); }
  65. try passOrDumpAndThrow(result);
  66. try testing.expect(std.mem.containsAtLeast(u8, result.stderr, 1, "deleting "));
  67. try testing.expect(std.mem.containsAtLeast(u8, result.stderr, 1, "0.6.0"));
  68. }
  69. try testing.expectEqual(@as(u32, 2), try getCompilerCount(install_dir));
  70. {
  71. const result = try runCaptureOuts(allocator, ".", zigup_args ++ &[_][]const u8 {"clean"});
  72. defer { allocator.free(result.stdout); allocator.free(result.stderr); }
  73. try passOrDumpAndThrow(result);
  74. try testing.expect(std.mem.containsAtLeast(u8, result.stderr, 1, "it is master"));
  75. }
  76. try testing.expectEqual(@as(u32, 2), try getCompilerCount(install_dir));
  77. try runNoCapture(".", zigup_args ++ &[_][]const u8 {"master"});
  78. try testing.expectEqual(@as(u32, 2), try getCompilerCount(install_dir));
  79. {
  80. const result = try runCaptureOuts(allocator, ".", zigup_args ++ &[_][]const u8 {"DOESNOTEXST"});
  81. defer { allocator.free(result.stdout); allocator.free(result.stderr); }
  82. try testing.expect(std.mem.containsAtLeast(u8, result.stderr, 1, "HTTP request failed"));
  83. }
  84. try testing.expectEqual(@as(u32, 2), try getCompilerCount(install_dir));
  85. }
  86. fn getCompilerCount(install_dir: []const u8) !u32 {
  87. var dir = try std.fs.cwd().openDir(install_dir, .{.iterate=true});
  88. defer dir.close();
  89. var it = dir.iterate();
  90. var count: u32 = 0;
  91. while (try it.next()) |entry| {
  92. if (entry.kind == .Directory) {
  93. count += 1;
  94. } else {
  95. try testing.expect(entry.kind == .SymLink);
  96. }
  97. }
  98. return count;
  99. }
  100. fn dumpExecResult(result: std.ChildProcess.ExecResult) void {
  101. if (result.stdout.len > 0) {
  102. std.log.info("STDOUT: '{s}'", .{result.stdout});
  103. }
  104. if (result.stderr.len > 0) {
  105. std.log.info("STDERR: '{s}'", .{result.stderr});
  106. }
  107. }
  108. fn runNoCapture(cwd: []const u8, argv: []const []const u8) !void {
  109. var arena_store = std.heap.ArenaAllocator.init(std.heap.page_allocator);
  110. defer arena_store.deinit();
  111. const result = try runCaptureOuts(&arena_store.allocator, cwd, argv);
  112. dumpExecResult(result);
  113. try passOrThrow(result.term);
  114. }
  115. fn runCaptureOuts(allocator: *std.mem.Allocator, cwd: []const u8, argv: []const []const u8) !std.ChildProcess.ExecResult {
  116. {
  117. const cmd = try std.mem.join(allocator, " ", argv);
  118. defer allocator.free(cmd);
  119. std.log.info("RUN(cwd={s}): {s}", .{cwd, cmd});
  120. }
  121. return try std.ChildProcess.exec(.{.allocator = allocator, .argv = argv, .cwd = cwd});
  122. }
  123. fn passOrThrow(term: std.ChildProcess.Term) error{ChildProcessFailed}!void {
  124. if (!execResultPassed(term)) {
  125. std.log.err("child process failed with {}", .{term});
  126. return error.ChildProcessFailed;
  127. }
  128. }
  129. fn passOrDumpAndThrow(result: std.ChildProcess.ExecResult) error{ChildProcessFailed}!void {
  130. if (!execResultPassed(result.term)) {
  131. dumpExecResult(result);
  132. std.log.err("child process failed with {}", .{result.term});
  133. return error.ChildProcessFailed;
  134. }
  135. }
  136. fn execResultPassed(term: std.ChildProcess.Term) bool {
  137. switch (term) {
  138. .Exited => |code| return code == 0,
  139. else => return false,
  140. }
  141. }