std.tar: add tests for file and symlink create

Should do that before I broke package manager!
This commit is contained in:
Igor Anić 2024-03-01 21:37:47 +01:00
parent d0c06ca712
commit af0502f6c4
2 changed files with 26 additions and 4 deletions

View File

@ -1,3 +1,4 @@
<<<<<<< HEAD
//! Tar archive is single ordinary file which can contain many files (or //! Tar archive is single ordinary file which can contain many files (or
//! directories, symlinks, ...). It's build by series of blocks each size of 512 //! directories, symlinks, ...). It's build by series of blocks each size of 512
//! bytes. First block of each entry is header which defines type, name, size //! bytes. First block of each entry is header which defines type, name, size
@ -127,6 +128,8 @@ pub const Header = struct {
return buffer[0 .. p.len + 1 + n.len]; return buffer[0 .. p.len + 1 + n.len];
} }
/// When kind is symbolic_link linked-to name (target_path) is specified in
/// the linkname field.
pub fn linkName(header: Header, buffer: *[LINK_NAME_SIZE]u8) []const u8 { pub fn linkName(header: Header, buffer: *[LINK_NAME_SIZE]u8) []const u8 {
const link_name = header.str(157, 100); const link_name = header.str(157, 100);
if (link_name.len == 0) { if (link_name.len == 0) {
@ -619,6 +622,7 @@ fn createDirAndFile(dir: std.fs.Dir, file_name: []const u8) !std.fs.File {
return fs_file; return fs_file;
} }
// Creates a symbolic link at path `file_name` which points to `link_name`.
fn createDirAndSymlink(dir: std.fs.Dir, link_name: []const u8, file_name: []const u8) !void { fn createDirAndSymlink(dir: std.fs.Dir, link_name: []const u8, file_name: []const u8) !void {
dir.symLink(link_name, file_name, .{}) catch |err| { dir.symLink(link_name, file_name, .{}) catch |err| {
if (err == error.FileNotFound) { if (err == error.FileNotFound) {
@ -841,3 +845,22 @@ test "tar header parse mode" {
} }
} }
} }
test "create file and symlink" {
var root = std.testing.tmpDir(.{});
defer root.cleanup();
_ = try createDirAndFile(root.dir, "file1");
_ = try createDirAndFile(root.dir, "a/b/c/file2");
_ = createDirAndSymlink(root.dir, "a/b/c/file2", "symlink1") catch |err| {
// On Windows when developer mode is not enabled
if (err == error.AccessDenied) return error.SkipZigTest;
return err;
};
_ = try createDirAndSymlink(root.dir, "../../../file1", "d/e/f/symlink2");
// Danglink symlnik, file created later
_ = try createDirAndSymlink(root.dir, "../../../g/h/i/file4", "j/k/l/symlink3");
_ = try createDirAndFile(root.dir, "g/h/i/file4");
}

View File

@ -1,5 +1,5 @@
const std = @import("../std.zig"); const std = @import("std");
const tar = std.tar; const tar = @import("../tar.zig");
const testing = std.testing; const testing = std.testing;
test "tar run Go test cases" { test "tar run Go test cases" {
@ -489,8 +489,7 @@ test "tar pipeToFileSystem" {
try testing.expectError(error.FileNotFound, root.dir.statFile("empty")); try testing.expectError(error.FileNotFound, root.dir.statFile("empty"));
try testing.expect((try root.dir.statFile("a/file")).kind == .file); try testing.expect((try root.dir.statFile("a/file")).kind == .file);
// TODO is there better way to test symlink
try testing.expect((try root.dir.statFile("b/symlink")).kind == .file); // statFile follows symlink try testing.expect((try root.dir.statFile("b/symlink")).kind == .file); // statFile follows symlink
var buf: [32]u8 = undefined; var buf: [32]u8 = undefined;
_ = try root.dir.readLink("b/symlink", &buf); try testing.expectEqualSlices(u8, "../a/file", try root.dir.readLink("b/symlink", &buf));
} }