|
| 1 | +const std = @import("../std.zig"); |
| 2 | + |
| 3 | +const readTestScenario = struct { |
| 4 | + data: []const u8, |
| 5 | + expect: std.StringHashMap(metadata), |
| 6 | +}; |
| 7 | + |
| 8 | +const metadata = struct { |
| 9 | + md5: []const u8, |
| 10 | + mode: usize, |
| 11 | + size: u64, |
| 12 | + mtime: i128, |
| 13 | +}; |
| 14 | + |
| 15 | +test "gnu tar" { |
| 16 | + var expect = std.StringHashMap(metadata).init(std.testing.allocator); |
| 17 | + defer expect.deinit(); |
| 18 | + try expect.put("small.txt", metadata{ |
| 19 | + .md5 = "e38b27eaccb4391bdec553a7f3ae6b2f", |
| 20 | + .mode = 0o640, |
| 21 | + .size = 5, |
| 22 | + .mtime = 1244428340 * std.time.ns_per_s, |
| 23 | + }); |
| 24 | + try expect.put("small2.txt", metadata{ |
| 25 | + .md5 = "c65bd2e50a56a2138bf1716f2fd56fe9", |
| 26 | + .mode = 0o640, |
| 27 | + .size = 11, |
| 28 | + .mtime = 1244436044 * std.time.ns_per_s, |
| 29 | + }); |
| 30 | + |
| 31 | + readTest(.{ |
| 32 | + .data = @embedFile("testdata/gnu.tar"), |
| 33 | + .expect = expect, |
| 34 | + }) catch { |
| 35 | + return error.SkipZigTest; |
| 36 | + }; |
| 37 | +} |
| 38 | + |
| 39 | +fn readTest(scenario: readTestScenario) !void { |
| 40 | + var file_stream = std.io.fixedBufferStream(scenario.data); |
| 41 | + |
| 42 | + var tmp = std.testing.tmpIterableDir(.{}); |
| 43 | + defer tmp.cleanup(); |
| 44 | + |
| 45 | + try std.tar.pipeToFileSystem( |
| 46 | + tmp.iterable_dir.dir, |
| 47 | + file_stream.reader(), |
| 48 | + .{ .mode_mode = .ignore }, |
| 49 | + ); |
| 50 | + |
| 51 | + var iter = tmp.iterable_dir.iterate(); |
| 52 | + |
| 53 | + var elements: u8 = 0; |
| 54 | + while (try iter.next()) |entry| { |
| 55 | + var expectFile = scenario.expect.get(entry.name) orelse return error.TestFailure; |
| 56 | + var f = try tmp.iterable_dir.dir.openFile( |
| 57 | + entry.name, |
| 58 | + .{ .mode = .read_only }, |
| 59 | + ); |
| 60 | + defer f.close(); |
| 61 | + |
| 62 | + const content = try f.readToEndAlloc(std.testing.allocator, std.math.maxInt(u32)); |
| 63 | + defer std.testing.allocator.free(content); |
| 64 | + |
| 65 | + var md5Hash: [std.crypto.hash.Md5.digest_length]u8 = undefined; |
| 66 | + std.crypto.hash.Md5.hash(content, &md5Hash, .{}); |
| 67 | + var b: [2 * std.crypto.hash.Md5.digest_length]u8 = undefined; |
| 68 | + _ = try std.fmt.bufPrint(&b, "{s}", .{std.fmt.fmtSliceHexLower(&md5Hash)}); |
| 69 | + try std.testing.expectEqualStrings(expectFile.md5, &b); |
| 70 | + elements += 1; |
| 71 | + |
| 72 | + var stat = try f.stat(); |
| 73 | + try std.testing.expectEqual(expectFile.size, stat.size); |
| 74 | + // TODO: fix possibly broken behavior. |
| 75 | + try std.testing.expectEqual(expectFile.mtime, stat.mtime); |
| 76 | + try std.testing.expectEqual(expectFile.mode, stat.mode); |
| 77 | + } |
| 78 | + |
| 79 | + try std.testing.expectEqual(scenario.expect.count(), elements); |
| 80 | +} |
0 commit comments