whatcanGOwrong
This commit is contained in:
@@ -0,0 +1,128 @@
|
||||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package testenv
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"sync"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var origEnv = os.Environ()
|
||||
|
||||
// NeedsExec checks that the current system can start new processes
|
||||
// using os.StartProcess or (more commonly) exec.Command.
|
||||
// If not, NeedsExec calls t.Skip with an explanation.
|
||||
//
|
||||
// On some platforms NeedsExec checks for exec support by re-executing the
|
||||
// current executable, which must be a binary built by 'go test'.
|
||||
// We intentionally do not provide a HasExec function because of the risk of
|
||||
// inappropriate recursion in TestMain functions.
|
||||
func NeedsExec(t testing.TB) {
|
||||
tryExecOnce.Do(func() {
|
||||
tryExecErr = tryExec()
|
||||
})
|
||||
if tryExecErr != nil {
|
||||
t.Helper()
|
||||
t.Skipf("skipping test: cannot exec subprocess on %s/%s: %v", runtime.GOOS, runtime.GOARCH, tryExecErr)
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
tryExecOnce sync.Once
|
||||
tryExecErr error
|
||||
)
|
||||
|
||||
func tryExec() error {
|
||||
switch runtime.GOOS {
|
||||
case "aix",
|
||||
"android",
|
||||
"darwin",
|
||||
"dragonfly",
|
||||
"freebsd",
|
||||
"illumos",
|
||||
"linux",
|
||||
"netbsd",
|
||||
"openbsd",
|
||||
"plan9",
|
||||
"solaris",
|
||||
"windows":
|
||||
// Known OS that isn't ios or wasm; assume that exec works.
|
||||
return nil
|
||||
default:
|
||||
}
|
||||
|
||||
// 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 flag.Lookup("test.list") == nil {
|
||||
// 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.
|
||||
return errors.New("can't probe for exec support with a non-test executable")
|
||||
}
|
||||
|
||||
// We know that this is a test executable. We should be able to run it with a
|
||||
// no-op flag to check for overall exec support.
|
||||
exe, err := os.Executable()
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't probe for exec support: %w", err)
|
||||
}
|
||||
cmd := exec.Command(exe, "-test.list=^$")
|
||||
cmd.Env = origEnv
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
func NeedsGoBuild(t testing.TB) {
|
||||
goBuildOnce.Do(func() {
|
||||
dir, err := os.MkdirTemp("", "testenv-*")
|
||||
if err != nil {
|
||||
goBuildErr = err
|
||||
return
|
||||
}
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
mainGo := filepath.Join(dir, "main.go")
|
||||
if err := os.WriteFile(mainGo, []byte("package main\nfunc main() {}\n"), 0644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cmd := exec.Command("go", "build", "-o", os.DevNull, mainGo)
|
||||
cmd.Dir = dir
|
||||
if err := cmd.Run(); err != nil {
|
||||
goBuildErr = fmt.Errorf("%v: %v", cmd, err)
|
||||
}
|
||||
})
|
||||
|
||||
if goBuildErr != nil {
|
||||
t.Helper()
|
||||
t.Skipf("skipping test: 'go build' not supported on %s/%s", runtime.GOOS, runtime.GOARCH)
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
goBuildOnce sync.Once
|
||||
goBuildErr error
|
||||
)
|
||||
|
||||
// NeedsLocalhostNet skips t if networking does not work for ports opened
|
||||
// with "localhost".
|
||||
func NeedsLocalhostNet(t testing.TB) {
|
||||
switch runtime.GOOS {
|
||||
case "js", "wasip1":
|
||||
t.Skipf(`Listening on "localhost" fails on %s; see https://go.dev/issue/59718`, runtime.GOOS)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user