| ... | @@ -2121,119 +2121,3 @@ fn createTestTarball(dir: fs.Dir, tarball_name: []const u8, with_manifest: bool) | ... | @@ -2121,119 +2121,3 @@ fn createTestTarball(dir: fs.Dir, tarball_name: []const u8, with_manifest: bool) |
| 2121 | try file.writeAll(&[_]u8{0} ** (512 - build_zig_zon.len)); | 2121 | try file.writeAll(&[_]u8{0} ** (512 - build_zig_zon.len)); |
| 2122 | } | 2122 | } |
| 2123 | } | 2123 | } |
| 2124 | | | |
| 2125 | // Using test cases from: https://github.com/ianprime0509/pathological-packages | | |
| 2126 | // repository. Depends on existence of the FAT32 file system at /tmp/fat32.mnt | | |
| 2127 | // (look at the fat32TmpDir function below how to create it). If that folder is | | |
| 2128 | // not found test will be skipped. Folder is in FAT32 file system because it is | | |
| 2129 | // case insensitive and and does not support symlinks. | | |
| 2130 | test "pathological packages" { | | |
| 2131 | const gpa = std.testing.allocator; | | |
| 2132 | var buf: [128]u8 = undefined; | | |
| 2133 | | | |
| 2134 | const urls: []const []const u8 = &.{ | | |
| 2135 | "https://github.com/ianprime0509/pathological-packages/archive/{s}.tar.gz", | | |
| 2136 | "git+https://github.com/ianprime0509/pathological-packages#{s}", | | |
| 2137 | }; | | |
| 2138 | const branches: []const []const u8 = &.{ | | |
| 2139 | "excluded-case-collisions", | | |
| 2140 | "excluded-symlinks", | | |
| 2141 | "included-case-collisions", | | |
| 2142 | "included-symlinks", | | |
| 2143 | }; | | |
| 2144 | | | |
| 2145 | // Expected fetched package files or error message for each combination of url/branch. | | |
| 2146 | const expected = [_]struct { | | |
| 2147 | files: []const []const u8 = &.{}, | | |
| 2148 | err_msg: []const u8 = "", | | |
| 2149 | }{ | | |
| 2150 | // tar | | |
| 2151 | .{ .files = &.{ "build.zig", "build.zig.zon" } }, | | |
| 2152 | .{ .files = &.{ "build.zig", "build.zig.zon", "main" } }, | | |
| 2153 | .{ .err_msg = | | |
| 2154 | \\error: unable to unpack tarball | | |
| 2155 | \\ note: unable to create file 'main': PathAlreadyExists | | |
| 2156 | \\ note: unable to create file 'subdir/main': PathAlreadyExists | | |
| 2157 | \\ | | |
| 2158 | }, | | |
| 2159 | .{ .err_msg = | | |
| 2160 | \\error: unable to unpack tarball | | |
| 2161 | \\ note: unable to create symlink from 'link' to 'main': AccessDenied | | |
| 2162 | \\ note: unable to create symlink from 'subdir/link' to 'main': AccessDenied | | |
| 2163 | \\ | | |
| 2164 | }, | | |
| 2165 | // git | | |
| 2166 | .{ .files = &.{ "build.zig", "build.zig.zon" } }, | | |
| 2167 | .{ .files = &.{ "build.zig", "build.zig.zon", "main" } }, | | |
| 2168 | .{ .err_msg = | | |
| 2169 | \\error: unable to unpack packfile | | |
| 2170 | \\ note: unable to create file 'main': PathAlreadyExists | | |
| 2171 | \\ note: unable to create file 'subdir/main': PathAlreadyExists | | |
| 2172 | \\ | | |
| 2173 | }, | | |
| 2174 | .{ .err_msg = | | |
| 2175 | \\error: unable to unpack packfile | | |
| 2176 | \\ note: unable to create symlink from 'link' to 'main': AccessDenied | | |
| 2177 | \\ note: unable to create symlink from 'subdir/link' to 'main': AccessDenied | | |
| 2178 | \\ | | |
| 2179 | }, | | |
| 2180 | }; | | |
| 2181 | | | |
| 2182 | var expected_no: usize = 0; | | |
| 2183 | inline for (urls) |url_fmt| { | | |
| 2184 | var tmp = try fat32TmpDir(); | | |
| 2185 | defer tmp.cleanup(); | | |
| 2186 | | | |
| 2187 | for (branches) |branch| { | | |
| 2188 | defer expected_no += 1; | | |
| 2189 | const url = try std.fmt.bufPrint(&buf, url_fmt, .{branch}); | | |
| 2190 | // std.debug.print("fetching url: {s}\n", .{url}); | | |
| 2191 | | | |
| 2192 | var fb: TestFetchBuilder = undefined; | | |
| 2193 | var fetch = try fb.build(gpa, tmp.dir, url); | | |
| 2194 | defer fb.deinit(); | | |
| 2195 | | | |
| 2196 | const ex = expected[expected_no]; | | |
| 2197 | if (ex.err_msg.len > 0) { | | |
| 2198 | try std.testing.expectError(error.FetchFailed, fetch.run()); | | |
| 2199 | try fb.expectFetchErrors(0, ex.err_msg); | | |
| 2200 | } else { | | |
| 2201 | try fetch.run(); | | |
| 2202 | try fb.expectPackageFiles(ex.files); | | |
| 2203 | } | | |
| 2204 | } | | |
| 2205 | } | | |
| 2206 | } | | |
| 2207 | | | |
| 2208 | // Using logic from std.testing.tmpDir() to make temporary directory at specific | | |
| 2209 | // location. | | |
| 2210 | // | | |
| 2211 | // This assumes FAT32 file system in /tmp/fat32.mnt folder, | | |
| 2212 | // created with something like this: | | |
| 2213 | // $ cd /tmp && fallocate -l 1M fat32.fs && mkfs.fat -F32 fat32.fs && mkdir fat32.mnt && sudo mount -o rw,umask=0000 fat32.fs fat32.mnt | | |
| 2214 | // | | |
| 2215 | // To remove that folder: | | |
| 2216 | // $ cd /tmp && sudo umount fat32.mnt && rm -rf fat32.mnt fat32.fs | | |
| 2217 | // | | |
| 2218 | pub fn fat32TmpDir() !std.testing.TmpDir { | | |
| 2219 | const fat32fs_path = "/tmp/fat32.mnt/"; | | |
| 2220 | | | |
| 2221 | const random_bytes_count = 12; | | |
| 2222 | var random_bytes: [random_bytes_count]u8 = undefined; | | |
| 2223 | std.crypto.random.bytes(&random_bytes); | | |
| 2224 | var sub_path: [std.fs.base64_encoder.calcSize(random_bytes_count)]u8 = undefined; | | |
| 2225 | _ = std.fs.base64_encoder.encode(&sub_path, &random_bytes); | | |
| 2226 | | | |
| 2227 | const parent_dir = std.fs.openDirAbsolute(fat32fs_path, .{}) catch |err| switch (err) { | | |
| 2228 | error.FileNotFound => return error.SkipZigTest, | | |
| 2229 | else => return err, | | |
| 2230 | }; | | |
| 2231 | const dir = parent_dir.makeOpenPath(&sub_path, .{}) catch | | |
| 2232 | @panic("unable to make tmp dir for testing: unable to make and open the tmp dir"); | | |
| 2233 | | | |
| 2234 | return .{ | | |
| 2235 | .dir = dir, | | |
| 2236 | .parent_dir = parent_dir, | | |
| 2237 | .sub_path = sub_path, | | |
| 2238 | }; | | |
| 2239 | } | | |