fix: harden thothctl Windows safe I/O
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
// Package testsupport provides portable helpers shared by thothctl tests.
|
||||
package testsupport
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// SymlinkOrSkip creates a symlink or skips only when Windows reports that symlink privilege is
|
||||
// unavailable. All other failures remain test failures.
|
||||
func SymlinkOrSkip(t testing.TB, target, link string) {
|
||||
t.Helper()
|
||||
if err := os.Symlink(target, link); err != nil {
|
||||
if isSymlinkPrivilegeUnavailable(err) {
|
||||
t.Skip("Windows symlink privilege is unavailable")
|
||||
}
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
//go:build !windows
|
||||
|
||||
package testsupport
|
||||
|
||||
func isSymlinkPrivilegeUnavailable(_ error) bool {
|
||||
return false
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package testsupport
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSymlinkPrivilegeUnavailableDoesNotMatchUnrelatedErrors(t *testing.T) {
|
||||
if isSymlinkPrivilegeUnavailable(errors.New("unrelated symlink failure")) {
|
||||
t.Fatal("unrelated symlink failure was classified as a missing Windows privilege")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
//go:build windows
|
||||
|
||||
package testsupport
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
func isSymlinkPrivilegeUnavailable(err error) bool {
|
||||
return errors.Is(err, os.ErrPermission) || errors.Is(err, windows.ERROR_PRIVILEGE_NOT_HELD)
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
//go:build windows
|
||||
|
||||
package testsupport
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
func TestSymlinkPrivilegeUnavailableRecognizesOnlyWindowsPrivilegeErrors(t *testing.T) {
|
||||
for name, err := range map[string]error{
|
||||
"permission": os.ErrPermission,
|
||||
"privilege not held": &os.LinkError{
|
||||
Op: "symlink",
|
||||
Old: "target",
|
||||
New: "link",
|
||||
Err: windows.ERROR_PRIVILEGE_NOT_HELD,
|
||||
},
|
||||
} {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
if !isSymlinkPrivilegeUnavailable(err) {
|
||||
t.Fatalf("isSymlinkPrivilegeUnavailable(%v) = false, want true", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
unrelated := &os.LinkError{
|
||||
Op: "symlink",
|
||||
Old: "target",
|
||||
New: "link",
|
||||
Err: windows.ERROR_FILENAME_EXCED_RANGE,
|
||||
}
|
||||
if isSymlinkPrivilegeUnavailable(unrelated) {
|
||||
t.Fatal("unrelated Windows symlink failure was classified as a missing privilege")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user