authorgravatar for squeek502@hotmail.comRyan Liptak <squeek502@hotmail.com> 2023-08-19 17:13:07-07:00
committergravatar for squeek502@hotmail.comRyan Liptak <squeek502@hotmail.com> 2023-08-19 17:48:19-07:00
log47343f9bcfb820b24d7e249c5cf52b80c3f9df83
treedb06a34c55c407181dcfbb4ee229ff1f5579d77a
parent2c2ecd624ad6d85d005f4728f834c0e3377f8f99

Add self_exe_symlink standalone test

Tests that fs.selfExePath follows symlinks by comparing it to the path of the File returned from fs.openSelfExe

4 files changed, 79 insertions(+), 0 deletions(-)

test/standalone.zig+4
...@@ -198,6 +198,10 @@ pub const build_cases = [_]BuildCase{...@@ -198,6 +198,10 @@ pub const build_cases = [_]BuildCase{
198 .build_root = "test/standalone/windows_spawn",198 .build_root = "test/standalone/windows_spawn",
199 .import = @import("standalone/windows_spawn/build.zig"),199 .import = @import("standalone/windows_spawn/build.zig"),
200 },200 },
201 .{
202 .build_root = "test/standalone/self_exe_symlink",
203 .import = @import("standalone/self_exe_symlink/build.zig"),
204 },
201 .{205 .{
202 .build_root = "test/standalone/c_compiler",206 .build_root = "test/standalone/c_compiler",
203 .import = @import("standalone/c_compiler/build.zig"),207 .import = @import("standalone/c_compiler/build.zig"),
test/standalone/self_exe_symlink/build.zig created+43
...@@ -0,0 +1,43 @@
1const std = @import("std");
2
3pub const requires_symlinks = true;
4
5pub fn build(b: *std.Build) void {
6 const test_step = b.step("test", "Test it");
7 b.default_step = test_step;
8
9 const optimize: std.builtin.OptimizeMode = .Debug;
10 const target: std.zig.CrossTarget = .{};
11
12 // The test requires getFdPath in order to to get the path of the
13 // File returned by openSelfExe
14 if (!std.os.isGetFdPathSupportedOnTarget(target.getOs())) return;
15
16 const main = b.addExecutable(.{
17 .name = "main",
18 .root_source_file = .{ .path = "main.zig" },
19 .optimize = optimize,
20 .target = target,
21 });
22
23 const create_symlink_exe = b.addExecutable(.{
24 .name = "create-symlink",
25 .root_source_file = .{ .path = "create-symlink.zig" },
26 .optimize = optimize,
27 .target = target,
28 });
29
30 var run_create_symlink = b.addRunArtifact(create_symlink_exe);
31 run_create_symlink.addArtifactArg(main);
32 const symlink_path = run_create_symlink.addOutputFileArg("main-symlink");
33 run_create_symlink.expectExitCode(0);
34 run_create_symlink.skip_foreign_checks = true;
35
36 var run_from_symlink = std.Build.Step.Run.create(b, "run symlink");
37 run_from_symlink.addFileArg(symlink_path);
38 run_from_symlink.expectExitCode(0);
39 run_from_symlink.skip_foreign_checks = true;
40 run_from_symlink.step.dependOn(&run_create_symlink.step);
41
42 test_step.dependOn(&run_from_symlink.step);
43}
test/standalone/self_exe_symlink/create-symlink.zig created+15
...@@ -0,0 +1,15 @@
1const std = @import("std");
2
3pub fn main() anyerror!void {
4 var gpa = std.heap.GeneralPurposeAllocator(.{}){};
5 defer if (gpa.deinit() == .leak) @panic("found memory leaks");
6 const allocator = gpa.allocator();
7
8 var it = try std.process.argsWithAllocator(allocator);
9 defer it.deinit();
10 _ = it.next() orelse unreachable; // skip binary name
11 const exe_path = it.next() orelse unreachable;
12 const symlink_path = it.next() orelse unreachable;
13
14 try std.fs.cwd().symLink(exe_path, symlink_path, .{});
15}
test/standalone/self_exe_symlink/main.zig created+17
...@@ -0,0 +1,17 @@
1const std = @import("std");
2
3pub fn main() !void {
4 var gpa = std.heap.GeneralPurposeAllocator(.{}){};
5 defer std.debug.assert(gpa.deinit() == .ok);
6 const allocator = gpa.allocator();
7
8 const self_path = try std.fs.selfExePathAlloc(allocator);
9 defer allocator.free(self_path);
10
11 var self_exe = try std.fs.openSelfExe(.{});
12 defer self_exe.close();
13 var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
14 const self_exe_path = try std.os.getFdPath(self_exe.handle, &buf);
15
16 try std.testing.expectEqualStrings(self_exe_path, self_path);
17}