Commit 47343f9bcf

Ryan Liptak <squeek502@hotmail.com>
2023-08-20 02:13:07
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
1 parent 2c2ecd6
Changed files (4)
test
test/standalone/self_exe_symlink/build.zig
@@ -0,0 +1,43 @@
+const std = @import("std");
+
+pub const requires_symlinks = true;
+
+pub fn build(b: *std.Build) void {
+    const test_step = b.step("test", "Test it");
+    b.default_step = test_step;
+
+    const optimize: std.builtin.OptimizeMode = .Debug;
+    const target: std.zig.CrossTarget = .{};
+
+    // The test requires getFdPath in order to to get the path of the
+    // File returned by openSelfExe
+    if (!std.os.isGetFdPathSupportedOnTarget(target.getOs())) return;
+
+    const main = b.addExecutable(.{
+        .name = "main",
+        .root_source_file = .{ .path = "main.zig" },
+        .optimize = optimize,
+        .target = target,
+    });
+
+    const create_symlink_exe = b.addExecutable(.{
+        .name = "create-symlink",
+        .root_source_file = .{ .path = "create-symlink.zig" },
+        .optimize = optimize,
+        .target = target,
+    });
+
+    var run_create_symlink = b.addRunArtifact(create_symlink_exe);
+    run_create_symlink.addArtifactArg(main);
+    const symlink_path = run_create_symlink.addOutputFileArg("main-symlink");
+    run_create_symlink.expectExitCode(0);
+    run_create_symlink.skip_foreign_checks = true;
+
+    var run_from_symlink = std.Build.Step.Run.create(b, "run symlink");
+    run_from_symlink.addFileArg(symlink_path);
+    run_from_symlink.expectExitCode(0);
+    run_from_symlink.skip_foreign_checks = true;
+    run_from_symlink.step.dependOn(&run_create_symlink.step);
+
+    test_step.dependOn(&run_from_symlink.step);
+}
test/standalone/self_exe_symlink/create-symlink.zig
@@ -0,0 +1,15 @@
+const std = @import("std");
+
+pub fn main() anyerror!void {
+    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
+    defer if (gpa.deinit() == .leak) @panic("found memory leaks");
+    const allocator = gpa.allocator();
+
+    var it = try std.process.argsWithAllocator(allocator);
+    defer it.deinit();
+    _ = it.next() orelse unreachable; // skip binary name
+    const exe_path = it.next() orelse unreachable;
+    const symlink_path = it.next() orelse unreachable;
+
+    try std.fs.cwd().symLink(exe_path, symlink_path, .{});
+}
test/standalone/self_exe_symlink/main.zig
@@ -0,0 +1,17 @@
+const std = @import("std");
+
+pub fn main() !void {
+    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
+    defer std.debug.assert(gpa.deinit() == .ok);
+    const allocator = gpa.allocator();
+
+    const self_path = try std.fs.selfExePathAlloc(allocator);
+    defer allocator.free(self_path);
+
+    var self_exe = try std.fs.openSelfExe(.{});
+    defer self_exe.close();
+    var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
+    const self_exe_path = try std.os.getFdPath(self_exe.handle, &buf);
+
+    try std.testing.expectEqualStrings(self_exe_path, self_path);
+}
test/standalone.zig
@@ -198,6 +198,10 @@ pub const build_cases = [_]BuildCase{
         .build_root = "test/standalone/windows_spawn",
         .import = @import("standalone/windows_spawn/build.zig"),
     },
+    .{
+        .build_root = "test/standalone/self_exe_symlink",
+        .import = @import("standalone/self_exe_symlink/build.zig"),
+    },
     .{
         .build_root = "test/standalone/c_compiler",
         .import = @import("standalone/c_compiler/build.zig"),