kittenipc/kitcom/internal/tsgo/vfs/osvfs/realpath_test.go
2025-10-15 10:12:44 +03:00

131 lines
3.4 KiB
Go

package osvfs
import (
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"
"testing"
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/tspath"
"gotest.tools/v3/assert"
"gotest.tools/v3/assert/cmp"
)
func TestSymlinkRealpath(t *testing.T) {
t.Parallel()
targetFile, linkFile := setupSymlinks(t)
gotContents, err := os.ReadFile(linkFile)
assert.NilError(t, err)
assert.Equal(t, string(gotContents), "hello")
fs := FS()
targetRealpath := fs.Realpath(tspath.NormalizePath(targetFile))
linkRealpath := fs.Realpath(tspath.NormalizePath(linkFile))
if !assert.Check(t, cmp.Equal(targetRealpath, linkRealpath)) {
cmd := exec.Command("node", "-e", `console.log({ native: fs.realpathSync.native(process.argv[1]), node: fs.realpathSync(process.argv[1]) })`, linkFile)
out, err := cmd.CombinedOutput()
assert.NilError(t, err)
t.Logf("node: %s", out)
}
}
func setupSymlinks(tb testing.TB) (targetFile, linkFile string) {
tb.Helper()
tmp := tb.TempDir()
target := filepath.Join(tmp, "target")
targetFile = filepath.Join(target, "file")
link := filepath.Join(tmp, "link")
linkFile = filepath.Join(link, "file")
assert.NilError(tb, os.MkdirAll(target, 0o777))
assert.NilError(tb, os.WriteFile(targetFile, []byte("hello"), 0o666))
mklink(tb, target, link, true)
return targetFile, linkFile
}
func mklink(tb testing.TB, target, link string, isDir bool) {
tb.Helper()
if runtime.GOOS == "windows" && isDir {
// Don't use os.Symlink on Windows, as it creates a "real" symlink, not a junction.
assert.NilError(tb, exec.Command("cmd", "/c", "mklink", "/J", link, target).Run())
} else {
err := os.Symlink(target, link)
if err != nil && !isDir && runtime.GOOS == "windows" && strings.Contains(err.Error(), "A required privilege is not held by the client") {
tb.Log(err)
tb.Skip("file symlink support is not enabled without elevation or developer mode")
}
assert.NilError(tb, err)
}
}
func BenchmarkRealpath(b *testing.B) {
targetFile, linkFile := setupSymlinks(b)
fs := FS()
normalizedTargetFile := tspath.NormalizePath(targetFile)
normalizedLinkFile := tspath.NormalizePath(linkFile)
b.Run("target", func(b *testing.B) {
b.ReportAllocs()
for b.Loop() {
fs.Realpath(normalizedTargetFile)
}
})
b.Run("link", func(b *testing.B) {
b.ReportAllocs()
for b.Loop() {
fs.Realpath(normalizedLinkFile)
}
})
}
func TestGetAccessibleEntries(t *testing.T) {
t.Parallel()
tmp := t.TempDir()
target := filepath.Join(tmp, "target")
link := filepath.Join(tmp, "link")
assert.NilError(t, os.MkdirAll(target, 0o777))
assert.NilError(t, os.MkdirAll(link, 0o777))
targetFile1 := filepath.Join(target, "file1")
targetFile2 := filepath.Join(target, "file2")
assert.NilError(t, os.WriteFile(targetFile1, []byte("hello"), 0o666))
assert.NilError(t, os.WriteFile(targetFile2, []byte("world"), 0o666))
targetDir1 := filepath.Join(target, "dir1")
targetDir2 := filepath.Join(target, "dir2")
assert.NilError(t, os.MkdirAll(targetDir1, 0o777))
assert.NilError(t, os.MkdirAll(targetDir2, 0o777))
mklink(t, targetFile1, filepath.Join(link, "file1"), false)
mklink(t, targetFile2, filepath.Join(link, "file2"), false)
mklink(t, targetDir1, filepath.Join(link, "dir1"), true)
mklink(t, targetDir2, filepath.Join(link, "dir2"), true)
fs := FS()
entries := fs.GetAccessibleEntries(tspath.NormalizePath(link))
assert.DeepEqual(t, entries.Directories, []string{"dir1", "dir2"})
assert.DeepEqual(t, entries.Files, []string{"file1", "file2"})
}