authorgravatar for pat.github@tullmann.orgPat Tullmann <pat.github@tullmann.org> 2025-09-08 21:31:51-07:00
committergravatar for pat.github@tullmann.orgPat Tullmann <pat.github@tullmann.org> 2025-09-09 22:07:44-07:00
log020eb622ee344d211946738ac1013deb60697381
treeeac923dc817372cdabdfbf8efd2d26353710dc74
parentc614d8d0081782116e94f3c8bfbf4ea515e7a3f3

standalone posix test for current working directory


2 files changed, 78 insertions(+), 69 deletions(-)

lib/std/posix/test.zig+3-68
...@@ -17,6 +17,9 @@ const AtomicOrder = std.builtin.AtomicOrder;...@@ -17,6 +17,9 @@ const AtomicOrder = std.builtin.AtomicOrder;
17const native_os = builtin.target.os.tag;17const native_os = builtin.target.os.tag;
18const tmpDir = std.testing.tmpDir;18const tmpDir = std.testing.tmpDir;
1919
20// NOTE: several additional tests are in test/standalone/posix/. Any tests that mutate
21// process-wide POSIX state (cwd, signals, etc) cannot be Zig unit tests and should be over there.
22
20// https://github.com/ziglang/zig/issues/2028823// https://github.com/ziglang/zig/issues/20288
21test "WTF-8 to WTF-16 conversion buffer overflows" {24test "WTF-8 to WTF-16 conversion buffer overflows" {
22 if (native_os != .windows) return error.SkipZigTest;25 if (native_os != .windows) return error.SkipZigTest;
...@@ -39,68 +42,6 @@ test "check WASI CWD" {...@@ -39,68 +42,6 @@ test "check WASI CWD" {
39 }42 }
40}43}
4144
42test "chdir absolute parent" {
43 if (native_os == .wasi) return error.SkipZigTest;
44
45 // Restore default CWD at end of test.
46 const orig_cwd = try fs.cwd().openDir(".", .{});
47 defer orig_cwd.setAsCwd() catch unreachable;
48
49 // Get current working directory path
50 var old_cwd_buf: [fs.max_path_bytes]u8 = undefined;
51 const old_cwd = try posix.getcwd(old_cwd_buf[0..]);
52
53 {
54 // Firstly, changing to itself should have no effect
55 try posix.chdir(old_cwd);
56 var new_cwd_buf: [fs.max_path_bytes]u8 = undefined;
57 const new_cwd = try posix.getcwd(new_cwd_buf[0..]);
58 try expect(mem.eql(u8, old_cwd, new_cwd));
59 }
60
61 // Next, change current working directory to one level above
62 const parent = fs.path.dirname(old_cwd) orelse unreachable; // old_cwd should be absolute
63 try posix.chdir(parent);
64
65 var new_cwd_buf: [fs.max_path_bytes]u8 = undefined;
66 const new_cwd = try posix.getcwd(new_cwd_buf[0..]);
67 try expect(mem.eql(u8, parent, new_cwd));
68}
69
70test "chdir relative" {
71 if (native_os == .wasi) return error.SkipZigTest;
72
73 var tmp = tmpDir(.{});
74 defer tmp.cleanup();
75
76 // Restore default CWD at end of test.
77 const orig_cwd = try fs.cwd().openDir(".", .{});
78 defer orig_cwd.setAsCwd() catch unreachable;
79
80 // Use the tmpDir parent_dir as the "base" for the test. Then cd into the child
81 try tmp.parent_dir.setAsCwd();
82
83 // Capture base working directory path, to build expected full path
84 var base_cwd_buf: [fs.max_path_bytes]u8 = undefined;
85 const base_cwd = try posix.getcwd(base_cwd_buf[0..]);
86
87 const dir_name = &tmp.sub_path;
88 const expected_path = try fs.path.resolve(a, &.{ base_cwd, dir_name });
89 defer a.free(expected_path);
90
91 // change current working directory to new directory
92 try posix.chdir(dir_name);
93
94 var new_cwd_buf: [fs.max_path_bytes]u8 = undefined;
95 const new_cwd = try posix.getcwd(new_cwd_buf[0..]);
96
97 // On Windows, fs.path.resolve returns an uppercase drive letter, but the drive letter returned by getcwd may be lowercase
98 const resolved_cwd = try fs.path.resolve(a, &.{new_cwd});
99 defer a.free(resolved_cwd);
100
101 try expect(mem.eql(u8, expected_path, resolved_cwd));
102}
103
104test "open smoke test" {45test "open smoke test" {
105 if (native_os == .wasi) return error.SkipZigTest;46 if (native_os == .wasi) return error.SkipZigTest;
106 if (native_os == .windows) return error.SkipZigTest;47 if (native_os == .windows) return error.SkipZigTest;
...@@ -455,12 +396,6 @@ test "getrandom" {...@@ -455,12 +396,6 @@ test "getrandom" {
455 try expect(!mem.eql(u8, &buf_a, &buf_b));396 try expect(!mem.eql(u8, &buf_a, &buf_b));
456}397}
457398
458test "getcwd" {
459 // at least call it so it gets compiled
460 var buf: [std.fs.max_path_bytes]u8 = undefined;
461 _ = posix.getcwd(&buf) catch undefined;
462}
463
464test "getuid" {399test "getuid" {
465 if (native_os == .windows or native_os == .wasi) return error.SkipZigTest;400 if (native_os == .windows or native_os == .wasi) return error.SkipZigTest;
466 _ = posix.getuid();401 _ = posix.getuid();
test/standalone/posix/cwd.zig+75-1
...@@ -1 +1,75 @@...@@ -1 +1,75 @@
1pub fn main() !void {}1const std = @import("std");
2const builtin = @import("builtin");
3
4const path_max = std.fs.max_path_bytes;
5
6pub fn main() !void {
7 if (builtin.target.os.tag == .wasi) {
8 // WASI doesn't support changing the working directory at all.
9 return;
10 }
11
12 var Allocator = std.heap.DebugAllocator(.{}){};
13 const a = Allocator.allocator();
14 defer std.debug.assert(Allocator.deinit() == .ok);
15
16 try test_chdir_self();
17 try test_chdir_absolute();
18 try test_chdir_relative(a);
19}
20
21// get current working directory and expect it to match given path
22fn expect_cwd(expected_cwd: []const u8) !void {
23 var cwd_buf: [path_max]u8 = undefined;
24 const actual_cwd = try std.posix.getcwd(cwd_buf[0..]);
25 try std.testing.expectEqualStrings(actual_cwd, expected_cwd);
26}
27
28fn test_chdir_self() !void {
29 var old_cwd_buf: [path_max]u8 = undefined;
30 const old_cwd = try std.posix.getcwd(old_cwd_buf[0..]);
31
32 // Try changing to the current directory
33 try std.posix.chdir(old_cwd);
34 try expect_cwd(old_cwd);
35}
36
37fn test_chdir_absolute() !void {
38 var old_cwd_buf: [path_max]u8 = undefined;
39 const old_cwd = try std.posix.getcwd(old_cwd_buf[0..]);
40
41 const parent = std.fs.path.dirname(old_cwd) orelse unreachable; // old_cwd should be absolute
42
43 // Try changing to the parent via a full path
44 try std.posix.chdir(parent);
45
46 try expect_cwd(parent);
47}
48
49fn test_chdir_relative(a: std.mem.Allocator) !void {
50 var tmp = std.testing.tmpDir(.{});
51 defer tmp.cleanup();
52
53 // Use the tmpDir parent_dir as the "base" for the test. Then cd into the child
54 try tmp.parent_dir.setAsCwd();
55
56 // Capture base working directory path, to build expected full path
57 var base_cwd_buf: [path_max]u8 = undefined;
58 const base_cwd = try std.posix.getcwd(base_cwd_buf[0..]);
59
60 const relative_dir_name = &tmp.sub_path;
61 const expected_path = try std.fs.path.resolve(a, &.{ base_cwd, relative_dir_name });
62 defer a.free(expected_path);
63
64 // change current working directory to new test directory
65 try std.posix.chdir(relative_dir_name);
66
67 var new_cwd_buf: [path_max]u8 = undefined;
68 const new_cwd = try std.posix.getcwd(new_cwd_buf[0..]);
69
70 // On Windows, fs.path.resolve returns an uppercase drive letter, but the drive letter returned by getcwd may be lowercase
71 const resolved_cwd = try std.fs.path.resolve(a, &.{new_cwd});
72 defer a.free(resolved_cwd);
73
74 try std.testing.expectEqualStrings(expected_path, resolved_cwd);
75}