authorgravatar for pat.github@tullmann.orgPat Tullmann <pat.github@tullmann.org> 2024-08-05 20:24:52-07:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-03-09 07:41:06+01:00
logeace31c6b34037225a8331156a1faec9a2831beb
treead50e8b30a4f82c2930969a59d131f4dc2f7d245
parent02f63fdee9b7b183611cd02e98e66bbdec8ed462

std/lib: {fs,io,posix} test clean up

* use `tmp.dir.realpathAlloc()` to get full path into tmpDir instances * use `testing.allocator` where that simplifies things (vs. manual ArenaAllocator for 1 or 2 allocs) * Trust `TmpDir.cleanup()` to clean up contained files and sub-trees * Remove some unnecessary absolute paths (enabling WASI to run the tests) * Drop some no-longer necessary `[_][]const u8` casts * Add scopes to reduce `var` usage in favor of `const`

3 files changed, 223 insertions(+), 239 deletions(-)

lib/std/fs/test.zig+62-41
...@@ -320,14 +320,8 @@ test "accessAbsolute" {...@@ -320,14 +320,8 @@ test "accessAbsolute" {
320 var tmp = tmpDir(.{});320 var tmp = tmpDir(.{});
321 defer tmp.cleanup();321 defer tmp.cleanup();
322322
323 var arena = ArenaAllocator.init(testing.allocator);323 const base_path = try tmp.dir.realpathAlloc(testing.allocator, ".");
324 defer arena.deinit();324 defer testing.allocator.free(base_path);
325 const allocator = arena.allocator();
326
327 const base_path = blk: {
328 const relative_path = try fs.path.join(allocator, &.{ ".zig-cache", "tmp", tmp.sub_path[0..] });
329 break :blk try fs.realpathAlloc(allocator, relative_path);
330 };
331325
332 try fs.accessAbsolute(base_path, .{});326 try fs.accessAbsolute(base_path, .{});
333}327}
...@@ -338,25 +332,52 @@ test "openDirAbsolute" {...@@ -338,25 +332,52 @@ test "openDirAbsolute" {
338 var tmp = tmpDir(.{});332 var tmp = tmpDir(.{});
339 defer tmp.cleanup();333 defer tmp.cleanup();
340334
335 const tmp_ino = (try tmp.dir.stat()).inode;
336
341 try tmp.dir.makeDir("subdir");337 try tmp.dir.makeDir("subdir");
342 var arena = ArenaAllocator.init(testing.allocator);338 const sub_path = try tmp.dir.realpathAlloc(testing.allocator, "subdir");
343 defer arena.deinit();339 defer testing.allocator.free(sub_path);
344 const allocator = arena.allocator();
345340
346 const base_path = blk: {341 // Can open sub_path
347 const relative_path = try fs.path.join(allocator, &.{ ".zig-cache", "tmp", tmp.sub_path[0..], "subdir" });342 var tmp_sub = try fs.openDirAbsolute(sub_path, .{});
348 break :blk try fs.realpathAlloc(allocator, relative_path);343 defer tmp_sub.close();
349 };344
345 const sub_ino = (try tmp_sub.stat()).inode;
350346
351 {347 {
352 var dir = try fs.openDirAbsolute(base_path, .{});348 // Can open sub_path + ".."
349 const dir_path = try fs.path.join(testing.allocator, &.{ sub_path, ".." });
350 defer testing.allocator.free(dir_path);
351
352 var dir = try fs.openDirAbsolute(dir_path, .{});
353 defer dir.close();353 defer dir.close();
354
355 const ino = (try dir.stat()).inode;
356 try testing.expectEqual(tmp_ino, ino);
354 }357 }
355358
356 for ([_][]const u8{ ".", ".." }) |sub_path| {359 {
357 const dir_path = try fs.path.join(allocator, &.{ base_path, sub_path });360 // Can open sub_path + "."
361 const dir_path = try fs.path.join(testing.allocator, &.{ sub_path, "." });
362 defer testing.allocator.free(dir_path);
363
358 var dir = try fs.openDirAbsolute(dir_path, .{});364 var dir = try fs.openDirAbsolute(dir_path, .{});
359 defer dir.close();365 defer dir.close();
366
367 const ino = (try dir.stat()).inode;
368 try testing.expectEqual(sub_ino, ino);
369 }
370
371 {
372 // Can open subdir + "..", with some extra "."
373 const dir_path = try fs.path.join(testing.allocator, &.{ sub_path, ".", "..", "." });
374 defer testing.allocator.free(dir_path);
375
376 var dir = try fs.openDirAbsolute(dir_path, .{});
377 defer dir.close();
378
379 const ino = (try dir.stat()).inode;
380 try testing.expectEqual(tmp_ino, ino);
360 }381 }
361}382}
362383
...@@ -409,10 +430,7 @@ test "readLinkAbsolute" {...@@ -409,10 +430,7 @@ test "readLinkAbsolute" {
409 defer arena.deinit();430 defer arena.deinit();
410 const allocator = arena.allocator();431 const allocator = arena.allocator();
411432
412 const base_path = blk: {433 const base_path = try tmp.dir.realpathAlloc(allocator, ".");
413 const relative_path = try fs.path.join(allocator, &.{ ".zig-cache", "tmp", tmp.sub_path[0..] });
414 break :blk try fs.realpathAlloc(allocator, relative_path);
415 };
416434
417 {435 {
418 const target_path = try fs.path.join(allocator, &.{ base_path, "file.txt" });436 const target_path = try fs.path.join(allocator, &.{ base_path, "file.txt" });
...@@ -748,7 +766,6 @@ test "directory operations on files" {...@@ -748,7 +766,6 @@ test "directory operations on files" {
748test "file operations on directories" {766test "file operations on directories" {
749 // TODO: fix this test on FreeBSD. https://github.com/ziglang/zig/issues/1759767 // TODO: fix this test on FreeBSD. https://github.com/ziglang/zig/issues/1759
750 if (native_os == .freebsd) return error.SkipZigTest;768 if (native_os == .freebsd) return error.SkipZigTest;
751 if (native_os == .wasi and builtin.link_libc) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/20747
752769
753 try testWithAllSupportedPathTypes(struct {770 try testWithAllSupportedPathTypes(struct {
754 fn impl(ctx: *TestContext) !void {771 fn impl(ctx: *TestContext) !void {
...@@ -759,18 +776,30 @@ test "file operations on directories" {...@@ -759,18 +776,30 @@ test "file operations on directories" {
759 try testing.expectError(error.IsDir, ctx.dir.createFile(test_dir_name, .{}));776 try testing.expectError(error.IsDir, ctx.dir.createFile(test_dir_name, .{}));
760 try testing.expectError(error.IsDir, ctx.dir.deleteFile(test_dir_name));777 try testing.expectError(error.IsDir, ctx.dir.deleteFile(test_dir_name));
761 switch (native_os) {778 switch (native_os) {
762 // no error when reading a directory.779 .dragonfly, .netbsd => {
763 .dragonfly, .netbsd => {},780 // no error when reading a directory. See https://github.com/ziglang/zig/issues/5732
764 // Currently, WASI will return error.Unexpected (via ENOTCAPABLE) when attempting fd_read on a directory handle.781 const buf = try ctx.dir.readFileAlloc(testing.allocator, test_dir_name, std.math.maxInt(usize));
765 // TODO: Re-enable on WASI once https://github.com/bytecodealliance/wasmtime/issues/1935 is resolved.782 testing.allocator.free(buf);
766 .wasi => {},783 },
784 .wasi => {
785 // WASI return EBADF, which gets mapped to NotOpenForReading.
786 // See https://github.com/bytecodealliance/wasmtime/issues/1935
787 try testing.expectError(error.NotOpenForReading, ctx.dir.readFileAlloc(testing.allocator, test_dir_name, std.math.maxInt(usize)));
788 },
767 else => {789 else => {
768 try testing.expectError(error.IsDir, ctx.dir.readFileAlloc(testing.allocator, test_dir_name, std.math.maxInt(usize)));790 try testing.expectError(error.IsDir, ctx.dir.readFileAlloc(testing.allocator, test_dir_name, std.math.maxInt(usize)));
769 },791 },
770 }792 }
771 // Note: The `.mode = .read_write` is necessary to ensure the error occurs on all platforms.793
772 // TODO: Add a read-only test as well, see https://github.com/ziglang/zig/issues/5732794 if (native_os == .wasi and builtin.link_libc) {
773 try testing.expectError(error.IsDir, ctx.dir.openFile(test_dir_name, .{ .mode = .read_write }));795 // wasmtime unexpectedly succeeds here, see https://github.com/ziglang/zig/issues/20747
796 const handle = try ctx.dir.openFile(test_dir_name, .{ .mode = .read_write });
797 handle.close();
798 } else {
799 // Note: The `.mode = .read_write` is necessary to ensure the error occurs on all platforms.
800 // TODO: Add a read-only test as well, see https://github.com/ziglang/zig/issues/5732
801 try testing.expectError(error.IsDir, ctx.dir.openFile(test_dir_name, .{ .mode = .read_write }));
802 }
774803
775 if (ctx.path_type == .absolute and comptime PathType.absolute.isSupported(builtin.os)) {804 if (ctx.path_type == .absolute and comptime PathType.absolute.isSupported(builtin.os)) {
776 try testing.expectError(error.IsDir, fs.createFileAbsolute(test_dir_name, .{}));805 try testing.expectError(error.IsDir, fs.createFileAbsolute(test_dir_name, .{}));
...@@ -993,10 +1022,7 @@ test "renameAbsolute" {...@@ -993,10 +1022,7 @@ test "renameAbsolute" {
993 defer arena.deinit();1022 defer arena.deinit();
994 const allocator = arena.allocator();1023 const allocator = arena.allocator();
9951024
996 const base_path = blk: {1025 const base_path = try tmp_dir.dir.realpathAlloc(allocator, ".");
997 const relative_path = try fs.path.join(allocator, &.{ ".zig-cache", "tmp", tmp_dir.sub_path[0..] });
998 break :blk try fs.realpathAlloc(allocator, relative_path);
999 };
10001026
1001 try testing.expectError(error.FileNotFound, fs.renameAbsolute(1027 try testing.expectError(error.FileNotFound, fs.renameAbsolute(
1002 try fs.path.join(allocator, &.{ base_path, "missing_file_name" }),1028 try fs.path.join(allocator, &.{ base_path, "missing_file_name" }),
...@@ -1386,7 +1412,6 @@ test "sendfile" {...@@ -1386,7 +1412,6 @@ test "sendfile" {
1386 defer tmp.cleanup();1412 defer tmp.cleanup();
13871413
1388 try tmp.dir.makePath("os_test_tmp");1414 try tmp.dir.makePath("os_test_tmp");
1389 defer tmp.dir.deleteTree("os_test_tmp") catch {};
13901415
1391 var dir = try tmp.dir.openDir("os_test_tmp", .{});1416 var dir = try tmp.dir.openDir("os_test_tmp", .{});
1392 defer dir.close();1417 defer dir.close();
...@@ -1451,7 +1476,6 @@ test "copyRangeAll" {...@@ -1451,7 +1476,6 @@ test "copyRangeAll" {
1451 defer tmp.cleanup();1476 defer tmp.cleanup();
14521477
1453 try tmp.dir.makePath("os_test_tmp");1478 try tmp.dir.makePath("os_test_tmp");
1454 defer tmp.dir.deleteTree("os_test_tmp") catch {};
14551479
1456 var dir = try tmp.dir.openDir("os_test_tmp", .{});1480 var dir = try tmp.dir.openDir("os_test_tmp", .{});
1457 defer dir.close();1481 defer dir.close();
...@@ -1800,10 +1824,7 @@ test "'.' and '..' in absolute functions" {...@@ -1800,10 +1824,7 @@ test "'.' and '..' in absolute functions" {
1800 defer arena.deinit();1824 defer arena.deinit();
1801 const allocator = arena.allocator();1825 const allocator = arena.allocator();
18021826
1803 const base_path = blk: {1827 const base_path = try tmp.dir.realpathAlloc(allocator, ".");
1804 const relative_path = try fs.path.join(allocator, &.{ ".zig-cache", "tmp", tmp.sub_path[0..] });
1805 break :blk try fs.realpathAlloc(allocator, relative_path);
1806 };
18071828
1808 const subdir_path = try fs.path.join(allocator, &.{ base_path, "./subdir" });1829 const subdir_path = try fs.path.join(allocator, &.{ base_path, "./subdir" });
1809 try fs.makeDirAbsolute(subdir_path);1830 try fs.makeDirAbsolute(subdir_path);
lib/std/io/test.zig+4-12
...@@ -108,10 +108,7 @@ test "File seek ops" {...@@ -108,10 +108,7 @@ test "File seek ops" {
108108
109 const tmp_file_name = "temp_test_file.txt";109 const tmp_file_name = "temp_test_file.txt";
110 var file = try tmp.dir.createFile(tmp_file_name, .{});110 var file = try tmp.dir.createFile(tmp_file_name, .{});
111 defer {111 defer file.close();
112 file.close();
113 tmp.dir.deleteFile(tmp_file_name) catch {};
114 }
115112
116 try file.writeAll(&([_]u8{0x55} ** 8192));113 try file.writeAll(&([_]u8{0x55} ** 8192));
117114
...@@ -135,10 +132,7 @@ test "setEndPos" {...@@ -135,10 +132,7 @@ test "setEndPos" {
135132
136 const tmp_file_name = "temp_test_file.txt";133 const tmp_file_name = "temp_test_file.txt";
137 var file = try tmp.dir.createFile(tmp_file_name, .{});134 var file = try tmp.dir.createFile(tmp_file_name, .{});
138 defer {135 defer file.close();
139 file.close();
140 tmp.dir.deleteFile(tmp_file_name) catch {};
141 }
142136
143 // Verify that the file size changes and the file offset is not moved137 // Verify that the file size changes and the file offset is not moved
144 try std.testing.expect((try file.getEndPos()) == 0);138 try std.testing.expect((try file.getEndPos()) == 0);
...@@ -161,10 +155,8 @@ test "updateTimes" {...@@ -161,10 +155,8 @@ test "updateTimes" {
161155
162 const tmp_file_name = "just_a_temporary_file.txt";156 const tmp_file_name = "just_a_temporary_file.txt";
163 var file = try tmp.dir.createFile(tmp_file_name, .{ .read = true });157 var file = try tmp.dir.createFile(tmp_file_name, .{ .read = true });
164 defer {158 defer file.close();
165 file.close();159
166 tmp.dir.deleteFile(tmp_file_name) catch {};
167 }
168 const stat_old = try file.stat();160 const stat_old = try file.stat();
169 // Set atime and mtime to 5s before161 // Set atime and mtime to 5s before
170 try file.updateTimes(162 try file.updateTimes(
lib/std/posix/test.zig+157-186
...@@ -8,7 +8,6 @@ const io = std.io;...@@ -8,7 +8,6 @@ const io = std.io;
8const fs = std.fs;8const fs = std.fs;
9const mem = std.mem;9const mem = std.mem;
10const elf = std.elf;10const elf = std.elf;
11const File = std.fs.File;
12const Thread = std.Thread;11const Thread = std.Thread;
13const linux = std.os.linux;12const linux = std.os.linux;
1413
...@@ -19,8 +18,6 @@ const AtomicRmwOp = std.builtin.AtomicRmwOp;...@@ -19,8 +18,6 @@ const AtomicRmwOp = std.builtin.AtomicRmwOp;
19const AtomicOrder = std.builtin.AtomicOrder;18const AtomicOrder = std.builtin.AtomicOrder;
20const native_os = builtin.target.os.tag;19const native_os = builtin.target.os.tag;
21const tmpDir = std.testing.tmpDir;20const tmpDir = std.testing.tmpDir;
22const Dir = std.fs.Dir;
23const ArenaAllocator = std.heap.ArenaAllocator;
2421
25// https://github.com/ziglang/zig/issues/2028822// https://github.com/ziglang/zig/issues/20288
26test "WTF-8 to WTF-16 conversion buffer overflows" {23test "WTF-8 to WTF-16 conversion buffer overflows" {
...@@ -115,50 +112,62 @@ test "open smoke test" {...@@ -115,50 +112,62 @@ test "open smoke test" {
115 var tmp = tmpDir(.{});112 var tmp = tmpDir(.{});
116 defer tmp.cleanup();113 defer tmp.cleanup();
117114
118 // Get base abs path115 const base_path = try tmp.dir.realpathAlloc(a, ".");
119 var arena = ArenaAllocator.init(testing.allocator);116 defer a.free(base_path);
120 defer arena.deinit();
121 const allocator = arena.allocator();
122117
123 const base_path = blk: {
124 const relative_path = try fs.path.join(allocator, &[_][]const u8{ ".zig-cache", "tmp", tmp.sub_path[0..] });
125 break :blk try fs.realpathAlloc(allocator, relative_path);
126 };
127
128 var file_path: []u8 = undefined;
129 var fd: posix.fd_t = undefined;
130 const mode: posix.mode_t = if (native_os == .windows) 0 else 0o666;118 const mode: posix.mode_t = if (native_os == .windows) 0 else 0o666;
131119
132 // Create some file using `open`.120 {
133 file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_file" });121 // Create some file using `open`.
134 fd = try posix.open(file_path, .{ .ACCMODE = .RDWR, .CREAT = true, .EXCL = true }, mode);122 const file_path = try fs.path.join(a, &.{ base_path, "some_file" });
135 posix.close(fd);123 defer a.free(file_path);
124 const fd = try posix.open(file_path, .{ .ACCMODE = .RDWR, .CREAT = true, .EXCL = true }, mode);
125 posix.close(fd);
126 }
136127
137 // Try this again with the same flags. This op should fail with error.PathAlreadyExists.128 {
138 file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_file" });129 // Try this again with the same flags. This op should fail with error.PathAlreadyExists.
139 try expectError(error.PathAlreadyExists, posix.open(file_path, .{ .ACCMODE = .RDWR, .CREAT = true, .EXCL = true }, mode));130 const file_path = try fs.path.join(a, &.{ base_path, "some_file" });
131 defer a.free(file_path);
132 try expectError(error.PathAlreadyExists, posix.open(file_path, .{ .ACCMODE = .RDWR, .CREAT = true, .EXCL = true }, mode));
133 }
140134
141 // Try opening without `EXCL` flag.135 {
142 file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_file" });136 // Try opening without `EXCL` flag.
143 fd = try posix.open(file_path, .{ .ACCMODE = .RDWR, .CREAT = true }, mode);137 const file_path = try fs.path.join(a, &.{ base_path, "some_file" });
144 posix.close(fd);138 defer a.free(file_path);
139 const fd = try posix.open(file_path, .{ .ACCMODE = .RDWR, .CREAT = true }, mode);
140 posix.close(fd);
141 }
145142
146 // Try opening as a directory which should fail.143 {
147 file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_file" });144 // Try opening as a directory which should fail.
148 try expectError(error.NotDir, posix.open(file_path, .{ .ACCMODE = .RDWR, .DIRECTORY = true }, mode));145 const file_path = try fs.path.join(a, &.{ base_path, "some_file" });
146 defer a.free(file_path);
147 try expectError(error.NotDir, posix.open(file_path, .{ .ACCMODE = .RDWR, .DIRECTORY = true }, mode));
148 }
149149
150 // Create some directory150 {
151 file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_dir" });151 // Create some directory
152 try posix.mkdir(file_path, mode);152 const file_path = try fs.path.join(a, &.{ base_path, "some_dir" });
153 defer a.free(file_path);
154 try posix.mkdir(file_path, mode);
155 }
153156
154 // Open dir using `open`157 {
155 file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_dir" });158 // Open dir using `open`
156 fd = try posix.open(file_path, .{ .ACCMODE = .RDONLY, .DIRECTORY = true }, mode);159 const file_path = try fs.path.join(a, &.{ base_path, "some_dir" });
157 posix.close(fd);160 defer a.free(file_path);
161 const fd = try posix.open(file_path, .{ .ACCMODE = .RDONLY, .DIRECTORY = true }, mode);
162 posix.close(fd);
163 }
158164
159 // Try opening as file which should fail.165 {
160 file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_dir" });166 // Try opening as file which should fail.
161 try expectError(error.IsDir, posix.open(file_path, .{ .ACCMODE = .RDWR }, mode));167 const file_path = try fs.path.join(a, &.{ base_path, "some_dir" });
168 defer a.free(file_path);
169 try expectError(error.IsDir, posix.open(file_path, .{ .ACCMODE = .RDWR }, mode));
170 }
162}171}
163172
164test "openat smoke test" {173test "openat smoke test" {
...@@ -705,8 +714,6 @@ test "mmap" {...@@ -705,8 +714,6 @@ test "mmap" {
705 try testing.expectEqual(i, try stream.readInt(u32, .little));714 try testing.expectEqual(i, try stream.readInt(u32, .little));
706 }715 }
707 }716 }
708
709 try tmp.dir.deleteFile(test_out_file);
710}717}
711718
712test "getenv" {719test "getenv" {
...@@ -732,10 +739,7 @@ test "fcntl" {...@@ -732,10 +739,7 @@ test "fcntl" {
732 const test_out_file = "os_tmp_test";739 const test_out_file = "os_tmp_test";
733740
734 const file = try tmp.dir.createFile(test_out_file, .{});741 const file = try tmp.dir.createFile(test_out_file, .{});
735 defer {742 defer file.close();
736 file.close();
737 tmp.dir.deleteFile(test_out_file) catch {};
738 }
739743
740 // Note: The test assumes createFile opens the file with CLOEXEC744 // Note: The test assumes createFile opens the file with CLOEXEC
741 {745 {
...@@ -771,10 +775,7 @@ test "sync" {...@@ -771,10 +775,7 @@ test "sync" {
771775
772 const test_out_file = "os_tmp_test";776 const test_out_file = "os_tmp_test";
773 const file = try tmp.dir.createFile(test_out_file, .{});777 const file = try tmp.dir.createFile(test_out_file, .{});
774 defer {778 defer file.close();
775 file.close();
776 tmp.dir.deleteFile(test_out_file) catch {};
777 }
778779
779 posix.sync();780 posix.sync();
780 try posix.syncfs(file.handle);781 try posix.syncfs(file.handle);
...@@ -791,10 +792,7 @@ test "fsync" {...@@ -791,10 +792,7 @@ test "fsync" {
791792
792 const test_out_file = "os_tmp_test";793 const test_out_file = "os_tmp_test";
793 const file = try tmp.dir.createFile(test_out_file, .{});794 const file = try tmp.dir.createFile(test_out_file, .{});
794 defer {795 defer file.close();
795 file.close();
796 tmp.dir.deleteFile(test_out_file) catch {};
797 }
798796
799 try posix.fsync(file.handle);797 try posix.fsync(file.handle);
800 try posix.fdatasync(file.handle);798 try posix.fdatasync(file.handle);
...@@ -1041,54 +1039,65 @@ test "rename smoke test" {...@@ -1041,54 +1039,65 @@ test "rename smoke test" {
1041 var tmp = tmpDir(.{});1039 var tmp = tmpDir(.{});
1042 defer tmp.cleanup();1040 defer tmp.cleanup();
10431041
1044 // Get base abs path1042 const base_path = try tmp.dir.realpathAlloc(a, ".");
1045 var arena = ArenaAllocator.init(testing.allocator);1043 defer a.free(base_path);
1046 defer arena.deinit();
1047 const allocator = arena.allocator();
1048
1049 const base_path = blk: {
1050 const relative_path = try fs.path.join(allocator, &[_][]const u8{ ".zig-cache", "tmp", tmp.sub_path[0..] });
1051 break :blk try fs.realpathAlloc(allocator, relative_path);
1052 };
10531044
1054 var file_path: []u8 = undefined;
1055 var fd: posix.fd_t = undefined;
1056 const mode: posix.mode_t = if (native_os == .windows) 0 else 0o666;1045 const mode: posix.mode_t = if (native_os == .windows) 0 else 0o666;
10571046
1058 // Create some file using `open`.1047 {
1059 file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_file" });1048 // Create some file using `open`.
1060 fd = try posix.open(file_path, .{ .ACCMODE = .RDWR, .CREAT = true, .EXCL = true }, mode);1049 const file_path = try fs.path.join(a, &.{ base_path, "some_file" });
1061 posix.close(fd);1050 defer a.free(file_path);
10621051 const fd = try posix.open(file_path, .{ .ACCMODE = .RDWR, .CREAT = true, .EXCL = true }, mode);
1063 // Rename the file1052 posix.close(fd);
1064 var new_file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_other_file" });1053
1065 try posix.rename(file_path, new_file_path);1054 // Rename the file
10661055 const new_file_path = try fs.path.join(a, &.{ base_path, "some_other_file" });
1067 // Try opening renamed file1056 defer a.free(new_file_path);
1068 file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_other_file" });1057 try posix.rename(file_path, new_file_path);
1069 fd = try posix.open(file_path, .{ .ACCMODE = .RDWR }, mode);1058 }
1070 posix.close(fd);
10711059
1072 // Try opening original file - should fail with error.FileNotFound1060 {
1073 file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_file" });1061 // Try opening renamed file
1074 try expectError(error.FileNotFound, posix.open(file_path, .{ .ACCMODE = .RDWR }, mode));1062 const file_path = try fs.path.join(a, &.{ base_path, "some_other_file" });
1063 defer a.free(file_path);
1064 const fd = try posix.open(file_path, .{ .ACCMODE = .RDWR }, mode);
1065 posix.close(fd);
1066 }
10751067
1076 // Create some directory1068 {
1077 file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_dir" });1069 // Try opening original file - should fail with error.FileNotFound
1078 try posix.mkdir(file_path, mode);1070 const file_path = try fs.path.join(a, &.{ base_path, "some_file" });
1071 defer a.free(file_path);
1072 try expectError(error.FileNotFound, posix.open(file_path, .{ .ACCMODE = .RDWR }, mode));
1073 }
10791074
1080 // Rename the directory1075 {
1081 new_file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_other_dir" });1076 // Create some directory
1082 try posix.rename(file_path, new_file_path);1077 const file_path = try fs.path.join(a, &.{ base_path, "some_dir" });
1078 defer a.free(file_path);
1079 try posix.mkdir(file_path, mode);
1080
1081 // Rename the directory
1082 const new_file_path = try fs.path.join(a, &.{ base_path, "some_other_dir" });
1083 defer a.free(new_file_path);
1084 try posix.rename(file_path, new_file_path);
1085 }
10831086
1084 // Try opening renamed directory1087 {
1085 file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_other_dir" });1088 // Try opening renamed directory
1086 fd = try posix.open(file_path, .{ .ACCMODE = .RDONLY, .DIRECTORY = true }, mode);1089 const file_path = try fs.path.join(a, &.{ base_path, "some_other_dir" });
1087 posix.close(fd);1090 defer a.free(file_path);
1091 const fd = try posix.open(file_path, .{ .ACCMODE = .RDONLY, .DIRECTORY = true }, mode);
1092 posix.close(fd);
1093 }
10881094
1089 // Try opening original directory - should fail with error.FileNotFound1095 {
1090 file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_dir" });1096 // Try opening original directory - should fail with error.FileNotFound
1091 try expectError(error.FileNotFound, posix.open(file_path, .{ .ACCMODE = .RDONLY, .DIRECTORY = true }, mode));1097 const file_path = try fs.path.join(a, &.{ base_path, "some_dir" });
1098 defer a.free(file_path);
1099 try expectError(error.FileNotFound, posix.open(file_path, .{ .ACCMODE = .RDONLY, .DIRECTORY = true }, mode));
1100 }
1092}1101}
10931102
1094test "access smoke test" {1103test "access smoke test" {
...@@ -1098,44 +1107,50 @@ test "access smoke test" {...@@ -1098,44 +1107,50 @@ test "access smoke test" {
1098 var tmp = tmpDir(.{});1107 var tmp = tmpDir(.{});
1099 defer tmp.cleanup();1108 defer tmp.cleanup();
11001109
1101 // Get base abs path1110 const base_path = try tmp.dir.realpathAlloc(a, ".");
1102 var arena = ArenaAllocator.init(testing.allocator);1111 defer a.free(base_path);
1103 defer arena.deinit();
1104 const allocator = arena.allocator();
1105
1106 const base_path = blk: {
1107 const relative_path = try fs.path.join(allocator, &[_][]const u8{ ".zig-cache", "tmp", tmp.sub_path[0..] });
1108 break :blk try fs.realpathAlloc(allocator, relative_path);
1109 };
11101112
1111 var file_path: []u8 = undefined;
1112 var fd: posix.fd_t = undefined;
1113 const mode: posix.mode_t = if (native_os == .windows) 0 else 0o666;1113 const mode: posix.mode_t = if (native_os == .windows) 0 else 0o666;
1114 {
1115 // Create some file using `open`.
1116 const file_path = try fs.path.join(a, &.{ base_path, "some_file" });
1117 defer a.free(file_path);
1118 const fd = try posix.open(file_path, .{ .ACCMODE = .RDWR, .CREAT = true, .EXCL = true }, mode);
1119 posix.close(fd);
1120 }
11141121
1115 // Create some file using `open`.1122 {
1116 file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_file" });1123 // Try to access() the file
1117 fd = try posix.open(file_path, .{ .ACCMODE = .RDWR, .CREAT = true, .EXCL = true }, mode);1124 const file_path = try fs.path.join(a, &.{ base_path, "some_file" });
1118 posix.close(fd);1125 defer a.free(file_path);
1126 if (native_os == .windows) {
1127 try posix.access(file_path, posix.F_OK);
1128 } else {
1129 try posix.access(file_path, posix.F_OK | posix.W_OK | posix.R_OK);
1130 }
1131 }
11191132
1120 // Try to access() the file1133 {
1121 file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_file" });1134 // Try to access() a non-existent file - should fail with error.FileNotFound
1122 if (native_os == .windows) {1135 const file_path = try fs.path.join(a, &.{ base_path, "some_other_file" });
1123 try posix.access(file_path, posix.F_OK);1136 defer a.free(file_path);
1124 } else {1137 try expectError(error.FileNotFound, posix.access(file_path, posix.F_OK));
1125 try posix.access(file_path, posix.F_OK | posix.W_OK | posix.R_OK);
1126 }1138 }
11271139
1128 // Try to access() a non-existent file - should fail with error.FileNotFound1140 {
1129 file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_other_file" });1141 // Create some directory
1130 try expectError(error.FileNotFound, posix.access(file_path, posix.F_OK));1142 const file_path = try fs.path.join(a, &.{ base_path, "some_dir" });
1143 defer a.free(file_path);
1144 try posix.mkdir(file_path, mode);
1145 }
11311146
1132 // Create some directory1147 {
1133 file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_dir" });1148 // Try to access() the directory
1134 try posix.mkdir(file_path, mode);1149 const file_path = try fs.path.join(a, &.{ base_path, "some_dir" });
1150 defer a.free(file_path);
11351151
1136 // Try to access() the directory1152 try posix.access(file_path, posix.F_OK);
1137 file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_dir" });1153 }
1138 try posix.access(file_path, posix.F_OK);
1139}1154}
11401155
1141test "timerfd" {1156test "timerfd" {
...@@ -1167,103 +1182,59 @@ test "isatty" {...@@ -1167,103 +1182,59 @@ test "isatty" {
1167}1182}
11681183
1169test "read with empty buffer" {1184test "read with empty buffer" {
1170 if (native_os == .wasi) return error.SkipZigTest;
1171
1172 var tmp = tmpDir(.{});1185 var tmp = tmpDir(.{});
1173 defer tmp.cleanup();1186 defer tmp.cleanup();
11741187
1175 var arena = ArenaAllocator.init(testing.allocator);1188 var file = try tmp.dir.createFile("read_empty", .{ .read = true });
1176 defer arena.deinit();
1177 const allocator = arena.allocator();
1178
1179 // Get base abs path
1180 const base_path = blk: {
1181 const relative_path = try fs.path.join(allocator, &[_][]const u8{ ".zig-cache", "tmp", tmp.sub_path[0..] });
1182 break :blk try fs.realpathAlloc(allocator, relative_path);
1183 };
1184
1185 const file_path: []u8 = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_file" });
1186 var file = try fs.cwd().createFile(file_path, .{ .read = true });
1187 defer file.close();1189 defer file.close();
11881190
1189 const bytes = try allocator.alloc(u8, 0);1191 const bytes = try a.alloc(u8, 0);
1192 defer a.free(bytes);
11901193
1191 _ = try posix.read(file.handle, bytes);1194 const rc = try posix.read(file.handle, bytes);
1195 try expectEqual(rc, 0);
1192}1196}
11931197
1194test "pread with empty buffer" {1198test "pread with empty buffer" {
1195 if (native_os == .wasi) return error.SkipZigTest;
1196
1197 var tmp = tmpDir(.{});1199 var tmp = tmpDir(.{});
1198 defer tmp.cleanup();1200 defer tmp.cleanup();
11991201
1200 var arena = ArenaAllocator.init(testing.allocator);1202 var file = try tmp.dir.createFile("pread_empty", .{ .read = true });
1201 defer arena.deinit();
1202 const allocator = arena.allocator();
1203
1204 // Get base abs path
1205 const base_path = blk: {
1206 const relative_path = try fs.path.join(allocator, &[_][]const u8{ ".zig-cache", "tmp", tmp.sub_path[0..] });
1207 break :blk try fs.realpathAlloc(allocator, relative_path);
1208 };
1209
1210 const file_path: []u8 = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_file" });
1211 var file = try fs.cwd().createFile(file_path, .{ .read = true });
1212 defer file.close();1203 defer file.close();
12131204
1214 const bytes = try allocator.alloc(u8, 0);1205 const bytes = try a.alloc(u8, 0);
1206 defer a.free(bytes);
12151207
1216 _ = try posix.pread(file.handle, bytes, 0);1208 const rc = try posix.pread(file.handle, bytes, 0);
1209 try expectEqual(rc, 0);
1217}1210}
12181211
1219test "write with empty buffer" {1212test "write with empty buffer" {
1220 if (native_os == .wasi) return error.SkipZigTest;
1221
1222 var tmp = tmpDir(.{});1213 var tmp = tmpDir(.{});
1223 defer tmp.cleanup();1214 defer tmp.cleanup();
12241215
1225 var arena = ArenaAllocator.init(testing.allocator);1216 var file = try tmp.dir.createFile("write_empty", .{});
1226 defer arena.deinit();
1227 const allocator = arena.allocator();
1228
1229 // Get base abs path
1230 const base_path = blk: {
1231 const relative_path = try fs.path.join(allocator, &[_][]const u8{ ".zig-cache", "tmp", tmp.sub_path[0..] });
1232 break :blk try fs.realpathAlloc(allocator, relative_path);
1233 };
1234
1235 const file_path: []u8 = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_file" });
1236 var file = try fs.cwd().createFile(file_path, .{});
1237 defer file.close();1217 defer file.close();
12381218
1239 const bytes = try allocator.alloc(u8, 0);1219 const bytes = try a.alloc(u8, 0);
1220 defer a.free(bytes);
12401221
1241 _ = try posix.write(file.handle, bytes);1222 const rc = try posix.write(file.handle, bytes);
1223 try expectEqual(rc, 0);
1242}1224}
12431225
1244test "pwrite with empty buffer" {1226test "pwrite with empty buffer" {
1245 if (native_os == .wasi) return error.SkipZigTest;
1246
1247 var tmp = tmpDir(.{});1227 var tmp = tmpDir(.{});
1248 defer tmp.cleanup();1228 defer tmp.cleanup();
12491229
1250 var arena = ArenaAllocator.init(testing.allocator);1230 var file = try tmp.dir.createFile("pwrite_empty", .{});
1251 defer arena.deinit();
1252 const allocator = arena.allocator();
1253
1254 // Get base abs path
1255 const base_path = blk: {
1256 const relative_path = try fs.path.join(allocator, &[_][]const u8{ ".zig-cache", "tmp", tmp.sub_path[0..] });
1257 break :blk try fs.realpathAlloc(allocator, relative_path);
1258 };
1259
1260 const file_path: []u8 = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_file" });
1261 var file = try fs.cwd().createFile(file_path, .{});
1262 defer file.close();1231 defer file.close();
12631232
1264 const bytes = try allocator.alloc(u8, 0);1233 const bytes = try a.alloc(u8, 0);
1234 defer a.free(bytes);
12651235
1266 _ = try posix.pwrite(file.handle, bytes, 0);1236 const rc = try posix.pwrite(file.handle, bytes, 0);
1237 try expectEqual(rc, 0);
1267}1238}
12681239
1269fn expectMode(dir: posix.fd_t, file: []const u8, mode: posix.mode_t) !void {1240fn expectMode(dir: posix.fd_t, file: []const u8, mode: posix.mode_t) !void {