authorgravatar for igor.anic@gmail.comIgor Anić <igor.anic@gmail.com> 2024-03-29 13:31:43+01:00
committergravatar for igor.anic@gmail.comIgor Anić <igor.anic@gmail.com> 2024-04-09 15:00:21+02:00
logdfec4918a3730df142bc7b58bfc0a6242cb3ca3b
tree883f490f87d43d1fde0daa1bc54feb729e9545a8
parent4d6a7e074bf79e35a58a4f4bc4199359a57ad0e4

fetch: remove absolute path from tests


1 files changed, 96 insertions(+), 123 deletions(-)

src/Package/Fetch.zig+96-123
......@@ -1193,14 +1193,14 @@ fn unpackTarball(f: *Fetch, out_dir: fs.Dir, reader: anytype) RunError!UnpackRes
11931193 res.root_dir = try gpa.dupe(u8, root_dir);
11941194 }
11951195 if (diagnostics.errors.items.len > 0) {
1196 try res.rootErrorMessage("unable to unpack tarball");
11961197 for (diagnostics.errors.items) |item| {
11971198 switch (item) {
1198 .unable_to_create_file => |i| try res.createFile(i.file_name, i.code),
1199 .unable_to_create_sym_link => |i| try res.symLink(i.file_name, i.link_name, i.code),
1199 .unable_to_create_file => |i| try res.unableToCreateFile(i.file_name, i.code),
1200 .unable_to_create_sym_link => |i| try res.unableToCreateSymLink(i.file_name, i.link_name, i.code),
12001201 .unsupported_file_type => |i| try res.unsupportedFileType(i.file_name, @intFromEnum(i.file_type)),
12011202 }
12021203 }
1203 try res.rootErrorMessage("unable to unpack tarball");
12041204 }
12051205 return res;
12061206}
......@@ -1246,14 +1246,12 @@ fn unpackGitPack(f: *Fetch, out_dir: fs.Dir, resource: *Resource) anyerror!Unpac
12461246 try repository.checkout(out_dir, want_oid, &diagnostics);
12471247
12481248 if (diagnostics.errors.items.len > 0) {
1249 defer res.deinit();
1250
1249 try res.rootErrorMessage("unable to unpack packfile");
12511250 for (diagnostics.errors.items) |item| {
12521251 switch (item) {
1253 .unable_to_create_sym_link => |i| try res.symLink(i.file_name, i.link_name, i.code),
1252 .unable_to_create_sym_link => |i| try res.unableToCreateSymLink(i.file_name, i.link_name, i.code),
12541253 }
12551254 }
1256 try res.rootErrorMessage("unable to unpack packfile");
12571255 }
12581256 }
12591257 }
......@@ -1812,14 +1810,14 @@ const UnpackResult = struct {
18121810 return self.errors.items.len > 0;
18131811 }
18141812
1815 fn createFile(self: *UnpackResult, file_name: []const u8, err: anyerror) !void {
1813 fn unableToCreateFile(self: *UnpackResult, file_name: []const u8, err: anyerror) !void {
18161814 try self.errors.append(self.allocator, .{ .unable_to_create_file = .{
18171815 .code = err,
18181816 .file_name = try self.allocator.dupe(u8, file_name),
18191817 } });
18201818 }
18211819
1822 fn symLink(self: *UnpackResult, file_name: []const u8, link_name: []const u8, err: anyerror) !void {
1820 fn unableToCreateSymLink(self: *UnpackResult, file_name: []const u8, link_name: []const u8, err: anyerror) !void {
18231821 try self.errors.append(self.allocator, .{ .unable_to_create_sym_link = .{
18241822 .code = err,
18251823 .file_name = try self.allocator.dupe(u8, file_name),
......@@ -1892,121 +1890,51 @@ const UnpackResult = struct {
18921890};
18931891
18941892test "fetch tarball: fail with unable to create file" {
1895 const testing = std.testing;
1896 var buf: [4096]u8 = undefined;
1897 var buf_pos: usize = 0;
1898
1899 // Create tmp dir
19001893 var tmp = std.testing.tmpDir(.{});
19011894 defer tmp.cleanup();
1902 const tmp_path = try tmp.dir.realpath(".", &buf);
1903 buf_pos += tmp_path.len;
19041895
1905 // Create tarball in tmp dir without build.zig.zon
19061896 const tarball_name = "package.tar";
19071897 try createTestTarball(tmp.dir, tarball_name, false);
19081898
1909 // Get path to the tarball
1910 const path_or_url = try std.fmt.bufPrint(buf[buf_pos..], "file://{s}/{s}", .{ tmp_path, tarball_name });
1911 buf_pos += path_or_url.len;
1912
1913 // Global cache directory in tmp
1914 const cache_path = try std.fmt.bufPrint(buf[buf_pos..], "{s}/{s}", .{ tmp_path, "global_cache" });
1915 buf_pos += cache_path.len;
1916
19171899 // Run tarball fetch, expect to fail
1918 var tf: TestFetch = undefined;
1919 try tf.init(testing.allocator, cache_path, path_or_url);
1920 defer tf.deinit();
1921 try testing.expectError(error.FetchFailed, tf.fetch.run());
1922
1923 // Expect fetch errors
1924 {
1925 var errors = try tf.fetch.error_bundle.toOwnedBundle("");
1926 defer errors.deinit(testing.allocator);
1927
1928 const em = errors.getErrorMessage(errors.getMessages()[0]);
1929 try testing.expectEqual(1, em.count);
1930 try testing.expectEqual(2, em.notes_len);
1931
1932 var al = std.ArrayList(u8).init(testing.allocator);
1933 defer al.deinit();
1934 try errors.renderToWriter(.{ .ttyconf = .no_color }, al.writer());
1935 try testing.expectEqualStrings(
1936 \\error: unable to unpack tarball
1937 \\ note: unable to create file 'dir/file': PathAlreadyExists
1938 \\ note: unable to create file 'dir1/file1': PathAlreadyExists
1939 \\
1940 , al.items);
1941 }
1900 var fb: TestFetchBuilder = undefined;
1901 var fetch = try fb.build(std.testing.allocator, tmp, tarball_name);
1902 defer fb.deinit();
1903 try std.testing.expectError(error.FetchFailed, fetch.run());
1904
1905 try fb.expectFetchErrors(2,
1906 \\error: unable to unpack tarball
1907 \\ note: unable to create file 'dir/file': PathAlreadyExists
1908 \\ note: unable to create file 'dir1/file1': PathAlreadyExists
1909 \\
1910 );
19421911}
19431912
19441913test "fetch tarball: error path are excluded" {
1945 const testing = std.testing;
1946 var buf: [4096]u8 = undefined;
1947 var buf_pos: usize = 0;
1948
1949 // Create tmp dir
19501914 var tmp = std.testing.tmpDir(.{});
19511915 defer tmp.cleanup();
1952 const tmp_path = try tmp.dir.realpath(".", &buf);
1953 buf_pos += tmp_path.len;
19541916
1955 // Create tarball in tmp dir
19561917 const tarball_name = "package.tar";
19571918 try createTestTarball(tmp.dir, tarball_name, true);
19581919
1959 // Get path to the tarball
1960 const path_or_url = try std.fmt.bufPrint(buf[buf_pos..], "file://{s}/{s}", .{ tmp_path, tarball_name });
1961 buf_pos += path_or_url.len;
1962
1963 // Global cache directory in tmp
1964 const cache_path = try std.fmt.bufPrint(buf[buf_pos..], "{s}/{s}", .{ tmp_path, "global_cache" });
1965 buf_pos += cache_path.len;
1920 // Run tarball fetch, should succeed
1921 var fb: TestFetchBuilder = undefined;
1922 var fetch = try fb.build(std.testing.allocator, tmp, tarball_name);
1923 defer fb.deinit();
1924 try fetch.run();
19661925
1967 // Run tarball fetch
1968 var tf: TestFetch = undefined;
1969 try tf.init(testing.allocator, cache_path, path_or_url);
1970 defer tf.deinit();
1971 try tf.fetch.run();
1972
1973 const hex_digest = Package.Manifest.hexDigest(tf.fetch.actual_hash);
1974 try testing.expectEqualStrings("122022afac878639d5ea6fcca14a123e21fd0395c1f2ef2c89017fa71390f73024af", &hex_digest);
1926 const hex_digest = Package.Manifest.hexDigest(fetch.actual_hash);
1927 try std.testing.expectEqualStrings("122022afac878639d5ea6fcca14a123e21fd0395c1f2ef2c89017fa71390f73024af", &hex_digest);
19751928
19761929 const expected_files: []const []const u8 = &.{
19771930 "build.zig",
19781931 "build.zig.zon",
19791932 "src/main.zig",
19801933 };
1981 // Unpacked package contains expected files
1982 {
1983 const package_path = try std.fmt.bufPrint(buf[buf_pos..], "global_cache/p/{s}", .{hex_digest});
1984 buf_pos += package_path.len;
1985 var package_dir = try tmp.dir.openDir(package_path, .{ .iterate = true });
1986
1987 var actual_files: std.ArrayListUnmanaged([]u8) = .{};
1988 defer actual_files.deinit(testing.allocator);
1989 defer for (actual_files.items) |file| testing.allocator.free(file);
1990 var walker = try package_dir.walk(testing.allocator);
1991 defer walker.deinit();
1992 while (try walker.next()) |entry| {
1993 if (entry.kind != .file) continue;
1994 //std.debug.print("{s}\n", .{entry.path});
1995 const path = try testing.allocator.dupe(u8, entry.path);
1996 errdefer testing.allocator.free(path);
1997 std.mem.replaceScalar(u8, path, std.fs.path.sep, '/');
1998 try actual_files.append(testing.allocator, path);
1999 }
2000 std.mem.sortUnstable([]u8, actual_files.items, {}, struct {
2001 fn lessThan(_: void, a: []u8, b: []u8) bool {
2002 return std.mem.lessThan(u8, a, b);
2003 }
2004 }.lessThan);
2005 try testing.expectEqualDeep(expected_files, actual_files.items);
2006 }
1934 try fb.expectPackageFiles(expected_files);
20071935}
20081936
2009const TestFetch = struct {
1937const TestFetchBuilder = struct {
20101938 thread_pool: ThreadPool,
20111939 http_client: std.http.Client,
20121940 global_cache_directory: Cache.Directory,
......@@ -2014,36 +1942,30 @@ const TestFetch = struct {
20141942 root_prog_node: *std.Progress.Node,
20151943 job_queue: Fetch.JobQueue,
20161944 fetch: Fetch,
2017 gpa: std.mem.Allocator,
20181945
2019 fn init(
2020 tf: *TestFetch,
2021 gpa: std.mem.Allocator,
2022 global_cache_directory_path: []const u8,
2023 path_or_url: []const u8,
2024 ) !void {
2025 try tf.thread_pool.init(.{ .allocator = gpa });
2026 tf.http_client = .{ .allocator = gpa };
2027 tf.global_cache_directory = .{
2028 .handle = try fs.cwd().makeOpenPath(global_cache_directory_path, .{}),
2029 .path = global_cache_directory_path,
2030 };
1946 fn build(self: *TestFetchBuilder, allocator: std.mem.Allocator, tmp: std.testing.TmpDir, tarball_name: []const u8) !*Fetch {
1947 const cache_dir = try tmp.dir.makeOpenPath("zig-global-cache", .{});
1948 const path_or_url = try std.fmt.allocPrint(allocator, "zig-cache/tmp/{s}/{s}", .{ tmp.sub_path, tarball_name });
1949
1950 try self.thread_pool.init(.{ .allocator = allocator });
1951 self.http_client = .{ .allocator = allocator };
1952 self.global_cache_directory = .{ .handle = cache_dir, .path = null };
20311953
2032 tf.progress = .{ .dont_print_on_dumb = true };
2033 tf.root_prog_node = tf.progress.start("Fetch", 0);
1954 self.progress = .{ .dont_print_on_dumb = true };
1955 self.root_prog_node = self.progress.start("Fetch", 0);
20341956
2035 tf.job_queue = .{
2036 .http_client = &tf.http_client,
2037 .thread_pool = &tf.thread_pool,
2038 .global_cache = tf.global_cache_directory,
1957 self.job_queue = .{
1958 .http_client = &self.http_client,
1959 .thread_pool = &self.thread_pool,
1960 .global_cache = self.global_cache_directory,
20391961 .recursive = false,
20401962 .read_only = false,
20411963 .debug_hash = false,
20421964 .work_around_btrfs_bug = false,
20431965 };
20441966
2045 tf.fetch = .{
2046 .arena = std.heap.ArenaAllocator.init(gpa),
1967 self.fetch = .{
1968 .arena = std.heap.ArenaAllocator.init(allocator),
20471969 .location = .{ .path_or_url = path_or_url },
20481970 .location_tok = 0,
20491971 .hash_tok = 0,
......@@ -2051,8 +1973,8 @@ const TestFetch = struct {
20511973 .lazy_status = .eager,
20521974 .parent_package_root = Cache.Path{ .root_dir = undefined },
20531975 .parent_manifest_ast = null,
2054 .prog_node = tf.root_prog_node,
2055 .job_queue = &tf.job_queue,
1976 .prog_node = self.root_prog_node,
1977 .job_queue = &self.job_queue,
20561978 .omit_missing_hash_error = true,
20571979 .allow_missing_paths_field = false,
20581980
......@@ -2066,9 +1988,11 @@ const TestFetch = struct {
20661988
20671989 .module = null,
20681990 };
1991 return &self.fetch;
20691992 }
20701993
2071 fn deinit(self: *TestFetch) void {
1994 fn deinit(self: *TestFetchBuilder) void {
1995 self.fetch.arena.child_allocator.free(self.fetch.location.path_or_url);
20721996 self.fetch.deinit();
20731997 self.job_queue.deinit();
20741998 self.root_prog_node.end();
......@@ -2076,6 +2000,55 @@ const TestFetch = struct {
20762000 self.http_client.deinit();
20772001 self.thread_pool.deinit();
20782002 }
2003
2004 fn packageDir(self: *TestFetchBuilder) !fs.Dir {
2005 const root = self.fetch.package_root;
2006 return try root.root_dir.handle.openDir(root.sub_path, .{ .iterate = true });
2007 }
2008
2009 fn expectPackageFiles(self: *TestFetchBuilder, expected_files: []const []const u8) !void {
2010 var package_dir = try self.packageDir();
2011 defer package_dir.close();
2012
2013 var actual_files: std.ArrayListUnmanaged([]u8) = .{};
2014 defer actual_files.deinit(std.testing.allocator);
2015 defer for (actual_files.items) |file| std.testing.allocator.free(file);
2016 var walker = try package_dir.walk(std.testing.allocator);
2017 defer walker.deinit();
2018 while (try walker.next()) |entry| {
2019 if (entry.kind != .file) continue;
2020 // std.debug.print("{s}\n", .{entry.path});
2021 const path = try std.testing.allocator.dupe(u8, entry.path);
2022 errdefer std.testing.allocator.free(path);
2023 std.mem.replaceScalar(u8, path, std.fs.path.sep, '/');
2024 try actual_files.append(std.testing.allocator, path);
2025 }
2026 std.mem.sortUnstable([]u8, actual_files.items, {}, struct {
2027 fn lessThan(_: void, a: []u8, b: []u8) bool {
2028 return std.mem.lessThan(u8, a, b);
2029 }
2030 }.lessThan);
2031
2032 try std.testing.expectEqual(expected_files.len, actual_files.items.len);
2033 for (expected_files, 0..) |file_name, i| {
2034 try std.testing.expectEqualStrings(file_name, actual_files.items[i]);
2035 }
2036 try std.testing.expectEqualDeep(expected_files, actual_files.items);
2037 }
2038
2039 fn expectFetchErrors(self: *TestFetchBuilder, notes_len: usize, msg: []const u8) !void {
2040 var errors = try self.fetch.error_bundle.toOwnedBundle("");
2041 defer errors.deinit(std.testing.allocator);
2042
2043 const em = errors.getErrorMessage(errors.getMessages()[0]);
2044 try std.testing.expectEqual(1, em.count);
2045 try std.testing.expectEqual(notes_len, em.notes_len);
2046
2047 var al = std.ArrayList(u8).init(std.testing.allocator);
2048 defer al.deinit();
2049 try errors.renderToWriter(.{ .ttyconf = .no_color }, al.writer());
2050 try std.testing.expectEqualStrings(msg, al.items);
2051 }
20792052};
20802053
20812054fn createTestTarball(dir: fs.Dir, tarball_name: []const u8, with_manifest: bool) !void {