| ... | ... | @@ -2121,119 +2121,3 @@ fn createTestTarball(dir: fs.Dir, tarball_name: []const u8, with_manifest: bool) |
| 2121 | 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 | | } |