Skip to content

Commit

Permalink
internal/testenv: in HasExec, try to actually exec on ios and wasm pl…
Browse files Browse the repository at this point in the history
…atforms

Some iOS environments may support exec. wasip1 and js do not, but
trying to exec on those platforms is inexpensive anyway and gives
better test coverage for the ios path.

Change-Id: I4baffb2ef5dc7d81e6a260f69033bfb229f13d92
Reviewed-on: https://go-review.googlesource.com/c/go/+/486275
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Bryan Mills <bcmills@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Auto-Submit: Bryan Mills <bcmills@google.com>
  • Loading branch information
Bryan C. Mills authored and gopherbot committed Apr 22, 2023
1 parent d5fea50 commit 5a10d8a
Showing 1 changed file with 55 additions and 1 deletion.
56 changes: 55 additions & 1 deletion src/internal/testenv/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,65 @@ import (
// HasExec reports whether the current system can start new processes
// using os.StartProcess or (more commonly) exec.Command.
func HasExec() bool {
tryExecOnce.Do(func() {
tryExecOk = tryExec()
})
return tryExecOk
}

var (
tryExec = func() bool { return true }
tryExecOnce sync.Once
tryExecOk bool
)

func init() {
switch runtime.GOOS {
case "wasip1", "js", "ios":
default:
// Assume that exec always works on non-mobile platforms and Android.
return
}

// ios has an exec syscall but on real iOS devices it might return a
// permission error. In an emulated environment (such as a Corellium host)
// it might succeed, so if we need to exec we'll just have to try it and
// find out.
//
// As of 2023-04-19 wasip1 and js don't have exec syscalls at all, but we
// may as well use the same path so that this branch can be tested without
// an ios environment.

if !testing.Testing() {
// This isn't a standard 'go test' binary, so we don't know how to
// self-exec in a way that should succeed without side effects.
// Just forget it.
tryExec = func() bool { return false }
return
}

// We know that this is a test executable.
// We should be able to run it with a no-op flag and the original test
// execution environment to check for overall exec support.

// Save the original environment during init for use in the check. A test
// binary may modify its environment before calling HasExec to change its
// behavior// (such as mimicking a command-line tool), and that modified
// environment might cause our self-test to behave unpredictably.
origEnv := os.Environ()

tryExec = func() bool {
exe, err := os.Executable()
if err != nil {
return false
}
cmd := exec.Command(exe, "-test.list=^$")
cmd.Env = origEnv
if err := cmd.Run(); err == nil {
tryExecOk = true
}
return false
}
return true
}

// MustHaveExec checks that the current system can start new processes
Expand Down

0 comments on commit 5a10d8a

Please sign in to comment.