1
0
mirror of https://github.com/golang/go synced 2024-11-14 14:00:25 -07:00

internal/testenv: probe for symlink on wasip1

Certain WASI runtimes do not support generic symlinks, and
instead return permission errors when they are attempted.
Perform a runtime probe of symlink support in hasSymlink
on wasip1 to determine whether the runtime supports
generic symlinks.

Also perform the same probe on android.

For #59583

Change-Id: Iae5b704e670650d38ee350a5a98f99dcce8b5b28
Reviewed-on: https://go-review.googlesource.com/c/go/+/490115
Auto-Submit: Johan Brandhorst-Satzkorn <johan.brandhorst@gmail.com>
Reviewed-by: Achille Roussel <achille.roussel@gmail.com>
TryBot-Bypass: Johan Brandhorst-Satzkorn <johan.brandhorst@gmail.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Run-TryBot: Johan Brandhorst-Satzkorn <johan.brandhorst@gmail.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
This commit is contained in:
Johan Brandhorst-Satzkorn 2023-04-27 21:39:57 -07:00
parent 4e8c6af239
commit 53279a6af3
3 changed files with 30 additions and 3 deletions

View File

@ -387,7 +387,7 @@ func HasSymlink() bool {
func MustHaveSymlink(t testing.TB) { func MustHaveSymlink(t testing.TB) {
ok, reason := hasSymlink() ok, reason := hasSymlink()
if !ok { if !ok {
t.Skipf("skipping test: cannot make symlinks on %s/%s%s", runtime.GOOS, runtime.GOARCH, reason) t.Skipf("skipping test: cannot make symlinks on %s/%s: %s", runtime.GOOS, runtime.GOARCH, reason)
} }
} }

View File

@ -8,6 +8,7 @@ package testenv
import ( import (
"errors" "errors"
"io/fs"
"os" "os"
) )
@ -16,5 +17,5 @@ import (
var Sigquit = os.Kill var Sigquit = os.Kill
func syscallIsNotSupported(err error) bool { func syscallIsNotSupported(err error) bool {
return errors.Is(err, errors.ErrUnsupported) return errors.Is(err, fs.ErrPermission) || errors.Is(err, errors.ErrUnsupported)
} }

View File

@ -7,13 +7,39 @@
package testenv package testenv
import ( import (
"fmt"
"os"
"path/filepath"
"runtime" "runtime"
) )
func hasSymlink() (ok bool, reason string) { func hasSymlink() (ok bool, reason string) {
switch runtime.GOOS { switch runtime.GOOS {
case "android", "plan9": case "plan9":
return false, "" return false, ""
case "android", "wasip1":
// For wasip1, some runtimes forbid absolute symlinks,
// or symlinks that escape the current working directory.
// Perform a simple test to see whether the runtime
// supports symlinks or not. If we get a permission
// error, the runtime does not support symlinks.
dir, err := os.MkdirTemp("", "")
if err != nil {
return false, ""
}
defer func() {
_ = os.RemoveAll(dir)
}()
fpath := filepath.Join(dir, "testfile.txt")
if err := os.WriteFile(fpath, nil, 0644); err != nil {
return false, ""
}
if err := os.Symlink(fpath, filepath.Join(dir, "testlink")); err != nil {
if SyscallIsNotSupported(err) {
return false, fmt.Sprintf("symlinks unsupported: %s", err.Error())
}
return false, ""
}
} }
return true, "" return true, ""