diff options
| author | Bryan C. Mills <bcmills@google.com> | 2023-04-19 10:46:26 -0400 |
|---|---|---|
| committer | Gopher Robot <gobot@golang.org> | 2023-04-22 00:41:24 +0000 |
| commit | 5a10d8a2042224c77dc41e8efbbc124f10b26172 (patch) | |
| tree | 2d8aa0f204885f3cc124e2cfc0376af386376a10 /src/internal/testenv/exec.go | |
| parent | d5fea5078b5d2b9f3c4da0f7cd4292f80806ca4b (diff) | |
| download | go-5a10d8a2042224c77dc41e8efbbc124f10b26172.tar.xz | |
internal/testenv: in HasExec, try to actually exec on ios and wasm platforms
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>
Diffstat (limited to 'src/internal/testenv/exec.go')
| -rw-r--r-- | src/internal/testenv/exec.go | 56 |
1 files changed, 55 insertions, 1 deletions
diff --git a/src/internal/testenv/exec.go b/src/internal/testenv/exec.go index ec2f2e295c..948e0f29f8 100644 --- a/src/internal/testenv/exec.go +++ b/src/internal/testenv/exec.go @@ -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 |
