authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-03-15 10:32:32-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-03-15 10:48:15-07:00
logcdda39559020b8d2c14a49d670738a3d265b496f
tree3e73e18b774cff98498f5243394fcbc6ca4052b2
parent5c6adbeb3931c209c651239cffb60831bcf02949

std lib tests: avoid cwd races by using std.testing.tmpDir


2 files changed, 86 insertions(+), 84 deletions(-)

lib/std/os/linux/io_uring.zig+71-66
......@@ -1728,10 +1728,12 @@ test "writev/fsync/readv" {
17281728 };
17291729 defer ring.deinit();
17301730
1731 var tmp = std.testing.tmpDir(.{});
1732 defer tmp.cleanup();
1733
17311734 const path = "test_io_uring_writev_fsync_readv";
1732 const file = try std.fs.cwd().createFile(path, .{ .read = true, .truncate = true });
1735 const file = try tmp.dir.createFile(path, .{ .read = true, .truncate = true });
17331736 defer file.close();
1734 defer std.fs.cwd().deleteFile(path) catch {};
17351737 const fd = file.handle;
17361738
17371739 const buffer_write = [_]u8{42} ** 128;
......@@ -1796,10 +1798,11 @@ test "write/read" {
17961798 };
17971799 defer ring.deinit();
17981800
1801 var tmp = std.testing.tmpDir(.{});
1802 defer tmp.cleanup();
17991803 const path = "test_io_uring_write_read";
1800 const file = try std.fs.cwd().createFile(path, .{ .read = true, .truncate = true });
1804 const file = try tmp.dir.createFile(path, .{ .read = true, .truncate = true });
18011805 defer file.close();
1802 defer std.fs.cwd().deleteFile(path) catch {};
18031806 const fd = file.handle;
18041807
18051808 const buffer_write = [_]u8{97} ** 20;
......@@ -1842,10 +1845,12 @@ test "write_fixed/read_fixed" {
18421845 };
18431846 defer ring.deinit();
18441847
1848 var tmp = std.testing.tmpDir(.{});
1849 defer tmp.cleanup();
1850
18451851 const path = "test_io_uring_write_read_fixed";
1846 const file = try std.fs.cwd().createFile(path, .{ .read = true, .truncate = true });
1852 const file = try tmp.dir.createFile(path, .{ .read = true, .truncate = true });
18471853 defer file.close();
1848 defer std.fs.cwd().deleteFile(path) catch {};
18491854 const fd = file.handle;
18501855
18511856 var raw_buffers: [2][11]u8 = undefined;
......@@ -1899,8 +1904,10 @@ test "openat" {
18991904 };
19001905 defer ring.deinit();
19011906
1907 var tmp = std.testing.tmpDir(.{});
1908 defer tmp.cleanup();
1909
19021910 const path = "test_io_uring_openat";
1903 defer std.fs.cwd().deleteFile(path) catch {};
19041911
19051912 // Workaround for LLVM bug: https://github.com/ziglang/zig/issues/12014
19061913 const path_addr = if (builtin.zig_backend == .stage2_llvm) p: {
......@@ -1910,12 +1917,12 @@ test "openat" {
19101917
19111918 const flags: u32 = os.O.CLOEXEC | os.O.RDWR | os.O.CREAT;
19121919 const mode: os.mode_t = 0o666;
1913 const sqe_openat = try ring.openat(0x33333333, linux.AT.FDCWD, path, flags, mode);
1920 const sqe_openat = try ring.openat(0x33333333, tmp.dir.fd, path, flags, mode);
19141921 try testing.expectEqual(linux.io_uring_sqe{
19151922 .opcode = .OPENAT,
19161923 .flags = 0,
19171924 .ioprio = 0,
1918 .fd = linux.AT.FDCWD,
1925 .fd = tmp.dir.fd,
19191926 .off = 0,
19201927 .addr = path_addr,
19211928 .len = mode,
......@@ -1931,12 +1938,6 @@ test "openat" {
19311938 const cqe_openat = try ring.copy_cqe();
19321939 try testing.expectEqual(@as(u64, 0x33333333), cqe_openat.user_data);
19331940 if (cqe_openat.err() == .INVAL) return error.SkipZigTest;
1934 // AT.FDCWD is not fully supported before kernel 5.6:
1935 // See https://lore.kernel.org/io-uring/20200207155039.12819-1-axboe@kernel.dk/T/
1936 // We use IORING_FEAT_RW_CUR_POS to know if we are pre-5.6 since that feature was added in 5.6.
1937 if (cqe_openat.err() == .BADF and (ring.features & linux.IORING_FEAT_RW_CUR_POS) == 0) {
1938 return error.SkipZigTest;
1939 }
19401941 if (cqe_openat.res <= 0) std.debug.print("\ncqe_openat.res={}\n", .{cqe_openat.res});
19411942 try testing.expect(cqe_openat.res > 0);
19421943 try testing.expectEqual(@as(u32, 0), cqe_openat.flags);
......@@ -1954,10 +1955,12 @@ test "close" {
19541955 };
19551956 defer ring.deinit();
19561957
1958 var tmp = std.testing.tmpDir(.{});
1959 defer tmp.cleanup();
1960
19571961 const path = "test_io_uring_close";
1958 const file = try std.fs.cwd().createFile(path, .{});
1962 const file = try tmp.dir.createFile(path, .{});
19591963 errdefer file.close();
1960 defer std.fs.cwd().deleteFile(path) catch {};
19611964
19621965 const sqe_close = try ring.close(0x44444444, file.handle);
19631966 try testing.expectEqual(linux.IORING_OP.CLOSE, sqe_close.opcode);
......@@ -2295,10 +2298,12 @@ test "fallocate" {
22952298 };
22962299 defer ring.deinit();
22972300
2301 var tmp = std.testing.tmpDir(.{});
2302 defer tmp.cleanup();
2303
22982304 const path = "test_io_uring_fallocate";
2299 const file = try std.fs.cwd().createFile(path, .{ .truncate = true, .mode = 0o666 });
2305 const file = try tmp.dir.createFile(path, .{ .truncate = true, .mode = 0o666 });
23002306 defer file.close();
2301 defer std.fs.cwd().deleteFile(path) catch {};
23022307
23032308 try testing.expectEqual(@as(u64, 0), (try file.stat()).size);
23042309
......@@ -2339,10 +2344,11 @@ test "statx" {
23392344 };
23402345 defer ring.deinit();
23412346
2347 var tmp = std.testing.tmpDir(.{});
2348 defer tmp.cleanup();
23422349 const path = "test_io_uring_statx";
2343 const file = try std.fs.cwd().createFile(path, .{ .truncate = true, .mode = 0o666 });
2350 const file = try tmp.dir.createFile(path, .{ .truncate = true, .mode = 0o666 });
23442351 defer file.close();
2345 defer std.fs.cwd().deleteFile(path) catch {};
23462352
23472353 try testing.expectEqual(@as(u64, 0), (try file.stat()).size);
23482354
......@@ -2351,14 +2357,14 @@ test "statx" {
23512357 var buf: linux.Statx = undefined;
23522358 const sqe = try ring.statx(
23532359 0xaaaaaaaa,
2354 linux.AT.FDCWD,
2360 tmp.dir.fd,
23552361 path,
23562362 0,
23572363 linux.STATX_SIZE,
23582364 &buf,
23592365 );
23602366 try testing.expectEqual(linux.IORING_OP.STATX, sqe.opcode);
2361 try testing.expectEqual(@as(i32, linux.AT.FDCWD), sqe.fd);
2367 try testing.expectEqual(@as(i32, tmp.dir.fd), sqe.fd);
23622368 try testing.expectEqual(@as(u32, 1), try ring.submit());
23632369
23642370 const cqe = try ring.copy_cqe();
......@@ -2371,8 +2377,6 @@ test "statx" {
23712377 // The filesystem containing the file referred to by fd does not support this operation;
23722378 // or the mode is not supported by the filesystem containing the file referred to by fd:
23732379 .OPNOTSUPP => return error.SkipZigTest,
2374 // The kernel is too old to support FDCWD for dir_fd
2375 .BADF => return error.SkipZigTest,
23762380 else => |errno| std.debug.panic("unhandled errno: {}", .{errno}),
23772381 }
23782382 try testing.expectEqual(linux.io_uring_cqe{
......@@ -2606,28 +2610,28 @@ test "renameat" {
26062610 const old_path = "test_io_uring_renameat_old";
26072611 const new_path = "test_io_uring_renameat_new";
26082612
2613 var tmp = std.testing.tmpDir(.{});
2614 defer tmp.cleanup();
2615
26092616 // Write old file with data
26102617
2611 const old_file = try std.fs.cwd().createFile(old_path, .{ .truncate = true, .mode = 0o666 });
2612 defer {
2613 old_file.close();
2614 std.fs.cwd().deleteFile(new_path) catch {};
2615 }
2618 const old_file = try tmp.dir.createFile(old_path, .{ .truncate = true, .mode = 0o666 });
2619 defer old_file.close();
26162620 try old_file.writeAll("hello");
26172621
26182622 // Submit renameat
26192623
26202624 var sqe = try ring.renameat(
26212625 0x12121212,
2622 linux.AT.FDCWD,
2626 tmp.dir.fd,
26232627 old_path,
2624 linux.AT.FDCWD,
2628 tmp.dir.fd,
26252629 new_path,
26262630 0,
26272631 );
26282632 try testing.expectEqual(linux.IORING_OP.RENAMEAT, sqe.opcode);
2629 try testing.expectEqual(@as(i32, linux.AT.FDCWD), sqe.fd);
2630 try testing.expectEqual(@as(i32, linux.AT.FDCWD), @bitCast(i32, sqe.len));
2633 try testing.expectEqual(@as(i32, tmp.dir.fd), sqe.fd);
2634 try testing.expectEqual(@as(i32, tmp.dir.fd), @bitCast(i32, sqe.len));
26312635 try testing.expectEqual(@as(u32, 1), try ring.submit());
26322636
26332637 const cqe = try ring.copy_cqe();
......@@ -2645,7 +2649,7 @@ test "renameat" {
26452649
26462650 // Validate that the old file doesn't exist anymore
26472651 {
2648 _ = std.fs.cwd().openFile(old_path, .{}) catch |err| switch (err) {
2652 _ = tmp.dir.openFile(old_path, .{}) catch |err| switch (err) {
26492653 error.FileNotFound => {},
26502654 else => std.debug.panic("unexpected error: {}", .{err}),
26512655 };
......@@ -2653,7 +2657,7 @@ test "renameat" {
26532657
26542658 // Validate that the new file exists with the proper content
26552659 {
2656 const new_file = try std.fs.cwd().openFile(new_path, .{});
2660 const new_file = try tmp.dir.openFile(new_path, .{});
26572661 defer new_file.close();
26582662
26592663 var new_file_data: [16]u8 = undefined;
......@@ -2674,22 +2678,24 @@ test "unlinkat" {
26742678
26752679 const path = "test_io_uring_unlinkat";
26762680
2681 var tmp = std.testing.tmpDir(.{});
2682 defer tmp.cleanup();
2683
26772684 // Write old file with data
26782685
2679 const file = try std.fs.cwd().createFile(path, .{ .truncate = true, .mode = 0o666 });
2686 const file = try tmp.dir.createFile(path, .{ .truncate = true, .mode = 0o666 });
26802687 defer file.close();
2681 defer std.fs.cwd().deleteFile(path) catch {};
26822688
26832689 // Submit unlinkat
26842690
26852691 var sqe = try ring.unlinkat(
26862692 0x12121212,
2687 linux.AT.FDCWD,
2693 tmp.dir.fd,
26882694 path,
26892695 0,
26902696 );
26912697 try testing.expectEqual(linux.IORING_OP.UNLINKAT, sqe.opcode);
2692 try testing.expectEqual(@as(i32, linux.AT.FDCWD), sqe.fd);
2698 try testing.expectEqual(@as(i32, tmp.dir.fd), sqe.fd);
26932699 try testing.expectEqual(@as(u32, 1), try ring.submit());
26942700
26952701 const cqe = try ring.copy_cqe();
......@@ -2706,7 +2712,7 @@ test "unlinkat" {
27062712 }, cqe);
27072713
27082714 // Validate that the file doesn't exist anymore
2709 _ = std.fs.cwd().openFile(path, .{}) catch |err| switch (err) {
2715 _ = tmp.dir.openFile(path, .{}) catch |err| switch (err) {
27102716 error.FileNotFound => {},
27112717 else => std.debug.panic("unexpected error: {}", .{err}),
27122718 };
......@@ -2722,20 +2728,21 @@ test "mkdirat" {
27222728 };
27232729 defer ring.deinit();
27242730
2725 const path = "test_io_uring_mkdirat";
2731 var tmp = std.testing.tmpDir(.{});
2732 defer tmp.cleanup();
27262733
2727 defer std.fs.cwd().deleteDir(path) catch {};
2734 const path = "test_io_uring_mkdirat";
27282735
27292736 // Submit mkdirat
27302737
27312738 var sqe = try ring.mkdirat(
27322739 0x12121212,
2733 linux.AT.FDCWD,
2740 tmp.dir.fd,
27342741 path,
27352742 0o0755,
27362743 );
27372744 try testing.expectEqual(linux.IORING_OP.MKDIRAT, sqe.opcode);
2738 try testing.expectEqual(@as(i32, linux.AT.FDCWD), sqe.fd);
2745 try testing.expectEqual(@as(i32, tmp.dir.fd), sqe.fd);
27392746 try testing.expectEqual(@as(u32, 1), try ring.submit());
27402747
27412748 const cqe = try ring.copy_cqe();
......@@ -2752,7 +2759,7 @@ test "mkdirat" {
27522759 }, cqe);
27532760
27542761 // Validate that the directory exist
2755 _ = try std.fs.cwd().openDir(path, .{});
2762 _ = try tmp.dir.openDir(path, .{});
27562763}
27572764
27582765test "symlinkat" {
......@@ -2765,26 +2772,25 @@ test "symlinkat" {
27652772 };
27662773 defer ring.deinit();
27672774
2775 var tmp = std.testing.tmpDir(.{});
2776 defer tmp.cleanup();
2777
27682778 const path = "test_io_uring_symlinkat";
27692779 const link_path = "test_io_uring_symlinkat_link";
27702780
2771 const file = try std.fs.cwd().createFile(path, .{ .truncate = true, .mode = 0o666 });
2772 defer {
2773 file.close();
2774 std.fs.cwd().deleteFile(path) catch {};
2775 std.fs.cwd().deleteFile(link_path) catch {};
2776 }
2781 const file = try tmp.dir.createFile(path, .{ .truncate = true, .mode = 0o666 });
2782 defer file.close();
27772783
27782784 // Submit symlinkat
27792785
27802786 var sqe = try ring.symlinkat(
27812787 0x12121212,
27822788 path,
2783 linux.AT.FDCWD,
2789 tmp.dir.fd,
27842790 link_path,
27852791 );
27862792 try testing.expectEqual(linux.IORING_OP.SYMLINKAT, sqe.opcode);
2787 try testing.expectEqual(@as(i32, linux.AT.FDCWD), sqe.fd);
2793 try testing.expectEqual(@as(i32, tmp.dir.fd), sqe.fd);
27882794 try testing.expectEqual(@as(u32, 1), try ring.submit());
27892795
27902796 const cqe = try ring.copy_cqe();
......@@ -2801,7 +2807,7 @@ test "symlinkat" {
28012807 }, cqe);
28022808
28032809 // Validate that the symlink exist
2804 _ = try std.fs.cwd().openFile(link_path, .{});
2810 _ = try tmp.dir.openFile(link_path, .{});
28052811}
28062812
28072813test "linkat" {
......@@ -2814,32 +2820,31 @@ test "linkat" {
28142820 };
28152821 defer ring.deinit();
28162822
2823 var tmp = std.testing.tmpDir(.{});
2824 defer tmp.cleanup();
2825
28172826 const first_path = "test_io_uring_linkat_first";
28182827 const second_path = "test_io_uring_linkat_second";
28192828
28202829 // Write file with data
28212830
2822 const first_file = try std.fs.cwd().createFile(first_path, .{ .truncate = true, .mode = 0o666 });
2823 defer {
2824 first_file.close();
2825 std.fs.cwd().deleteFile(first_path) catch {};
2826 std.fs.cwd().deleteFile(second_path) catch {};
2827 }
2831 const first_file = try tmp.dir.createFile(first_path, .{ .truncate = true, .mode = 0o666 });
2832 defer first_file.close();
28282833 try first_file.writeAll("hello");
28292834
28302835 // Submit linkat
28312836
28322837 var sqe = try ring.linkat(
28332838 0x12121212,
2834 linux.AT.FDCWD,
2839 tmp.dir.fd,
28352840 first_path,
2836 linux.AT.FDCWD,
2841 tmp.dir.fd,
28372842 second_path,
28382843 0,
28392844 );
28402845 try testing.expectEqual(linux.IORING_OP.LINKAT, sqe.opcode);
2841 try testing.expectEqual(@as(i32, linux.AT.FDCWD), sqe.fd);
2842 try testing.expectEqual(@as(i32, linux.AT.FDCWD), @bitCast(i32, sqe.len));
2846 try testing.expectEqual(@as(i32, tmp.dir.fd), sqe.fd);
2847 try testing.expectEqual(@as(i32, tmp.dir.fd), @bitCast(i32, sqe.len));
28432848 try testing.expectEqual(@as(u32, 1), try ring.submit());
28442849
28452850 const cqe = try ring.copy_cqe();
......@@ -2856,7 +2861,7 @@ test "linkat" {
28562861 }, cqe);
28572862
28582863 // Validate the second file
2859 const second_file = try std.fs.cwd().openFile(second_path, .{});
2864 const second_file = try tmp.dir.openFile(second_path, .{});
28602865 defer second_file.close();
28612866
28622867 var second_file_data: [16]u8 = undefined;
lib/std/os/linux/test.zig+15-18
......@@ -8,10 +8,12 @@ const expectEqual = std.testing.expectEqual;
88const fs = std.fs;
99
1010test "fallocate" {
11 var tmp = std.testing.tmpDir(.{});
12 defer tmp.cleanup();
13
1114 const path = "test_fallocate";
12 const file = try fs.cwd().createFile(path, .{ .truncate = true, .mode = 0o666 });
15 const file = try tmp.dir.createFile(path, .{ .truncate = true, .mode = 0o666 });
1316 defer file.close();
14 defer fs.cwd().deleteFile(path) catch {};
1517
1618 try expect((try file.stat()).size == 0);
1719
......@@ -67,12 +69,12 @@ test "timer" {
6769}
6870
6971test "statx" {
72 var tmp = std.testing.tmpDir(.{});
73 defer tmp.cleanup();
74
7075 const tmp_file_name = "just_a_temporary_file.txt";
71 var file = try fs.cwd().createFile(tmp_file_name, .{});
72 defer {
73 file.close();
74 fs.cwd().deleteFile(tmp_file_name) catch {};
75 }
76 var file = try tmp.dir.createFile(tmp_file_name, .{});
77 defer file.close();
7678
7779 var statx_buf: linux.Statx = undefined;
7880 switch (linux.getErrno(linux.statx(file.handle, "", linux.AT.EMPTY_PATH, linux.STATX_BASIC_STATS, &statx_buf))) {
......@@ -105,21 +107,16 @@ test "user and group ids" {
105107}
106108
107109test "fadvise" {
110 var tmp = std.testing.tmpDir(.{});
111 defer tmp.cleanup();
112
108113 const tmp_file_name = "temp_posix_fadvise.txt";
109 var file = try fs.cwd().createFile(tmp_file_name, .{});
110 defer {
111 file.close();
112 fs.cwd().deleteFile(tmp_file_name) catch {};
113 }
114 var file = try tmp.dir.createFile(tmp_file_name, .{});
115 defer file.close();
114116
115117 var buf: [2048]u8 = undefined;
116118 try file.writeAll(&buf);
117119
118 const ret = linux.fadvise(
119 file.handle,
120 0,
121 0,
122 linux.POSIX_FADV.SEQUENTIAL,
123 );
120 const ret = linux.fadvise(file.handle, 0, 0, linux.POSIX_FADV.SEQUENTIAL);
124121 try expectEqual(@as(usize, 0), ret);
125122}