"debug/elf"
"debug/macho"
"debug/pe"
+ "encoding/binary"
"flag"
"fmt"
"go/format"
"internal/race"
"internal/testenv"
"io"
+ "io/fs"
"io/ioutil"
"log"
"os"
"cmd/internal/sys"
)
+func init() {
+ // GOVCS defaults to public:git|hg,private:all,
+ // which breaks many tests here - they can't use non-git, non-hg VCS at all!
+ // Change to fully permissive.
+ // The tests of the GOVCS setting itself are in ../../testdata/script/govcs.txt.
+ os.Setenv("GOVCS", "*:all")
+}
+
var (
- canRun = true // whether we can run go or ./testgo
canRace = false // whether we can run the race detector
canCgo = false // whether we can use cgo
canMSan = false // whether we can run the memory sanitizer
-
- exeSuffix string // ".exe" on Windows
-
- skipExternal = false // skip external tests
)
+var exeSuffix string = func() string {
+ if runtime.GOOS == "windows" {
+ return ".exe"
+ }
+ return ""
+}()
+
func tooSlow(t *testing.T) {
if testing.Short() {
// In -short mode; skip test, except run it on the {darwin,linux,windows}/amd64 builders.
if testenv.Builder() != "" && runtime.GOARCH == "amd64" && (runtime.GOOS == "linux" || runtime.GOOS == "darwin" || runtime.GOOS == "windows") {
return
}
+ t.Helper()
t.Skip("skipping test in -short mode")
}
}
-func init() {
- switch runtime.GOOS {
- case "android", "js":
- canRun = false
- case "darwin":
- // nothing to do
- case "ios":
- canRun = false
- case "linux":
- switch runtime.GOARCH {
- case "arm":
- // many linux/arm machines are too slow to run
- // the full set of external tests.
- skipExternal = true
- case "mips", "mipsle", "mips64", "mips64le":
- // Also slow.
- skipExternal = true
- if testenv.Builder() != "" {
- // On the builders, skip the cmd/go
- // tests. They're too slow and already
- // covered by other ports. There's
- // nothing os/arch specific in the
- // tests.
- canRun = false
- }
- }
- case "freebsd":
- switch runtime.GOARCH {
- case "arm":
- // many freebsd/arm machines are too slow to run
- // the full set of external tests.
- skipExternal = true
- canRun = false
- }
- case "plan9":
- switch runtime.GOARCH {
- case "arm":
- // many plan9/arm machines are too slow to run
- // the full set of external tests.
- skipExternal = true
- }
- case "windows":
- exeSuffix = ".exe"
- }
-}
-
// testGOROOT is the GOROOT to use when running testgo, a cmd/go binary
// build from this process's current GOROOT, but run from a different
// (temp) directory.
}
testGOCACHE = cache.DefaultDir()
- if canRun {
+ if testenv.HasGoBuild() {
testBin = filepath.Join(testTmpDir, "testbin")
if err := os.Mkdir(testBin, 0777); err != nil {
log.Fatal(err)
cmd.Stderr = new(strings.Builder)
if out, err := cmd.Output(); err != nil {
fmt.Fprintf(os.Stderr, "running testgo failed: %v\n%s", err, cmd.Stderr)
- canRun = false
+ os.Exit(2)
} else {
canCgo, err = strconv.ParseBool(strings.TrimSpace(string(out)))
if err != nil {
func testgo(t *testing.T) *testgoData {
t.Helper()
testenv.MustHaveGoBuild(t)
-
- if skipExternal {
- t.Skipf("skipping external tests on %s/%s", runtime.GOOS, runtime.GOARCH)
- }
+ testenv.SkipIfShortAndSlow(t)
return &testgoData{t: t}
}
// returning exit status.
func (tg *testgoData) doRun(args []string) error {
tg.t.Helper()
- if !canRun {
- panic("testgoData.doRun called but canRun false")
- }
if tg.inParallel {
for _, arg := range args {
if strings.HasPrefix(arg, "testdata") || strings.HasPrefix(arg, "./testdata") {
func removeAll(dir string) error {
// module cache has 0444 directories;
// make them writable in order to remove content.
- filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
+ filepath.Walk(dir, func(path string, info fs.FileInfo, err error) error {
// chmod not only directories, but also things that we couldn't even stat
// due to permission errors: they may also be unreadable directories.
if err != nil || info.IsDir() {
srcdir := filepath.Join(testGOROOT, copydir)
tg.tempDir(filepath.Join("goroot", copydir))
err := filepath.Walk(srcdir,
- func(path string, info os.FileInfo, err error) error {
+ func(path string, info fs.FileInfo, err error) error {
if err != nil {
return err
}
if _, err := os.Stat(file); err != nil {
t.Fatalf("cannot find .Export result %s: %v", file, err)
}
+
+ tg.run("list", "-export", "-f", "{{.BuildID}}", "strings")
+ buildID := strings.TrimSpace(tg.stdout.String())
+ if buildID == "" {
+ t.Fatalf(".BuildID with -export was empty")
+ }
+
+ tg.run("tool", "buildid", file)
+ toolBuildID := strings.TrimSpace(tg.stdout.String())
+ if buildID != toolBuildID {
+ t.Fatalf(".BuildID with -export %q disagrees with 'go tool buildid' %q", buildID, toolBuildID)
+ }
}
// Issue 4096. Validate the output of unsuccessful go install foo/quxx.
tg.run("build", "-o", exe, "p")
}
-func copyFile(src, dst string, perm os.FileMode) error {
+func copyFile(src, dst string, perm fs.FileMode) error {
sf, err := os.Open(src)
if err != nil {
return err
platform := fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH)
switch platform {
- case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/s390x",
+ case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/riscv64", "linux/s390x",
"android/amd64", "android/arm", "android/arm64", "android/386",
"freebsd/amd64",
"windows/386", "windows/amd64", "windows/arm":
if (dc & pe.IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE) == 0 {
t.Error("IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE flag is not set")
}
+ if useCgo {
+ // Test that only one symbol is exported (#40795).
+ // PIE binaries don´t require .edata section but unfortunately
+ // binutils doesn´t generate a .reloc section unless there is
+ // at least one symbol exported.
+ // See https://sourceware.org/bugzilla/show_bug.cgi?id=19011
+ section := f.Section(".edata")
+ if section == nil {
+ t.Fatalf(".edata section is not present")
+ }
+ // TODO: deduplicate this struct from cmd/link/internal/ld/pe.go
+ type IMAGE_EXPORT_DIRECTORY struct {
+ _ [2]uint32
+ _ [2]uint16
+ _ [2]uint32
+ NumberOfFunctions uint32
+ NumberOfNames uint32
+ _ [3]uint32
+ }
+ var e IMAGE_EXPORT_DIRECTORY
+ if err := binary.Read(section.Open(), binary.LittleEndian, &e); err != nil {
+ t.Fatalf("binary.Read failed: %v", err)
+ }
+
+ // Only _cgo_dummy_export should be exported
+ if e.NumberOfFunctions != 1 {
+ t.Fatalf("got %d exported functions; want 1", e.NumberOfFunctions)
+ }
+ if e.NumberOfNames != 1 {
+ t.Fatalf("got %d exported names; want 1", e.NumberOfNames)
+ }
+ }
default:
panic("unreachable")
}