From 6b6c64b1cc918633824e7a9165816c81f0c08b21 Mon Sep 17 00:00:00 2001 From: "Bryan C. Mills" Date: Fri, 24 Jun 2022 17:02:24 -0400 Subject: [PATCH] cmd/internal/archive: don't rely on an erroneous install target in tests Non-main packages in module mode should not be installed to GOPATH/pkg, but due to #37015 they were installed there anyway. This change switches the 'go install' command to instead use 'go build -buildmode=archive' with an explicit archive path. For #37015. Change-Id: Ib0c8f213100b6473a7657af96f31395703e28493 Reviewed-on: https://go-review.googlesource.com/c/go/+/414055 Auto-Submit: Bryan Mills Reviewed-by: Cherry Mui TryBot-Result: Gopher Robot Reviewed-by: Michael Matloob Run-TryBot: Bryan Mills --- src/cmd/internal/archive/archive_test.go | 163 ++++++++++++----------- 1 file changed, 87 insertions(+), 76 deletions(-) diff --git a/src/cmd/internal/archive/archive_test.go b/src/cmd/internal/archive/archive_test.go index 9573495dec..bbaa72cbf8 100644 --- a/src/cmd/internal/archive/archive_test.go +++ b/src/cmd/internal/archive/archive_test.go @@ -18,32 +18,23 @@ import ( "os/exec" "path/filepath" "runtime" + "sync" "testing" "unicode/utf8" ) -var ( - buildDir string - go1obj string - go2obj string - goarchive string - cgoarchive string -) +var buildDir string func TestMain(m *testing.M) { if !testenv.HasGoBuild() { return } - if err := buildGoobj(); err != nil { - fmt.Println(err) - os.RemoveAll(buildDir) - os.Exit(1) - } - exit := m.Run() - os.RemoveAll(buildDir) + if buildDir != "" { + os.RemoveAll(buildDir) + } os.Exit(exit) } @@ -89,71 +80,91 @@ func copyFile(dst, src string) (err error) { return nil } -func buildGoobj() error { - var err error +var ( + buildOnce sync.Once + builtGoobjs goobjPaths + buildErr error +) - buildDir, err = ioutil.TempDir("", "TestGoobj") - if err != nil { - return err +type goobjPaths struct { + go1obj string + go2obj string + goarchive string + cgoarchive string +} + +func buildGoobj(t *testing.T) goobjPaths { + buildOnce.Do(func() { + buildErr = func() (err error) { + buildDir, err = ioutil.TempDir("", "TestGoobj") + if err != nil { + return err + } + + go1obj := filepath.Join(buildDir, "go1.o") + go2obj := filepath.Join(buildDir, "go2.o") + goarchive := filepath.Join(buildDir, "go.a") + cgoarchive := "" + + gotool, err := testenv.GoTool() + if err != nil { + return err + } + + go1src := filepath.Join("testdata", "go1.go") + go2src := filepath.Join("testdata", "go2.go") + + out, err := exec.Command(gotool, "tool", "compile", "-p=p", "-o", go1obj, go1src).CombinedOutput() + if err != nil { + return fmt.Errorf("go tool compile -o %s %s: %v\n%s", go1obj, go1src, err, out) + } + out, err = exec.Command(gotool, "tool", "compile", "-p=p", "-o", go2obj, go2src).CombinedOutput() + if err != nil { + return fmt.Errorf("go tool compile -o %s %s: %v\n%s", go2obj, go2src, err, out) + } + out, err = exec.Command(gotool, "tool", "pack", "c", goarchive, go1obj, go2obj).CombinedOutput() + if err != nil { + return fmt.Errorf("go tool pack c %s %s %s: %v\n%s", goarchive, go1obj, go2obj, err, out) + } + + if testenv.HasCGO() { + cgoarchive = filepath.Join(buildDir, "mycgo.a") + gopath := filepath.Join(buildDir, "gopath") + err = copyDir(filepath.Join(gopath, "src", "mycgo"), filepath.Join("testdata", "mycgo")) + if err == nil { + err = ioutil.WriteFile(filepath.Join(gopath, "src", "mycgo", "go.mod"), []byte("module mycgo\n"), 0666) + } + if err != nil { + return err + } + cmd := exec.Command(gotool, "build", "-buildmode=archive", "-o", cgoarchive, "-gcflags=all="+os.Getenv("GO_GCFLAGS"), "mycgo") + cmd.Dir = filepath.Join(gopath, "src", "mycgo") + cmd.Env = append(os.Environ(), "GOPATH="+gopath) + out, err = cmd.CombinedOutput() + if err != nil { + return fmt.Errorf("go install mycgo: %v\n%s", err, out) + } + } + + builtGoobjs = goobjPaths{ + go1obj: go1obj, + go2obj: go2obj, + goarchive: goarchive, + cgoarchive: cgoarchive, + } + return nil + }() + }) + + if buildErr != nil { + t.Helper() + t.Fatal(buildErr) } - - go1obj = filepath.Join(buildDir, "go1.o") - go2obj = filepath.Join(buildDir, "go2.o") - goarchive = filepath.Join(buildDir, "go.a") - - gotool, err := testenv.GoTool() - if err != nil { - return err - } - - go1src := filepath.Join("testdata", "go1.go") - go2src := filepath.Join("testdata", "go2.go") - - out, err := exec.Command(gotool, "tool", "compile", "-p=p", "-o", go1obj, go1src).CombinedOutput() - if err != nil { - return fmt.Errorf("go tool compile -o %s %s: %v\n%s", go1obj, go1src, err, out) - } - out, err = exec.Command(gotool, "tool", "compile", "-p=p", "-o", go2obj, go2src).CombinedOutput() - if err != nil { - return fmt.Errorf("go tool compile -o %s %s: %v\n%s", go2obj, go2src, err, out) - } - out, err = exec.Command(gotool, "tool", "pack", "c", goarchive, go1obj, go2obj).CombinedOutput() - if err != nil { - return fmt.Errorf("go tool pack c %s %s %s: %v\n%s", goarchive, go1obj, go2obj, err, out) - } - - if testenv.HasCGO() { - gopath := filepath.Join(buildDir, "gopath") - err = copyDir(filepath.Join(gopath, "src", "mycgo"), filepath.Join("testdata", "mycgo")) - if err == nil { - err = ioutil.WriteFile(filepath.Join(gopath, "src", "mycgo", "go.mod"), []byte("module mycgo\n"), 0666) - } - if err != nil { - return err - } - cmd := exec.Command(gotool, "install", "-gcflags=all="+os.Getenv("GO_GCFLAGS"), "mycgo") - cmd.Dir = filepath.Join(gopath, "src", "mycgo") - cmd.Env = append(os.Environ(), "GOPATH="+gopath) - out, err = cmd.CombinedOutput() - if err != nil { - return fmt.Errorf("go install mycgo: %v\n%s", err, out) - } - pat := filepath.Join(gopath, "pkg", "*", "mycgo.a") - ms, err := filepath.Glob(pat) - if err != nil { - return err - } - if len(ms) == 0 { - return fmt.Errorf("cannot found paths for pattern %s", pat) - } - cgoarchive = ms[0] - } - - return nil + return builtGoobjs } func TestParseGoobj(t *testing.T) { - path := go1obj + path := buildGoobj(t).go1obj f, err := os.Open(path) if err != nil { @@ -182,7 +193,7 @@ func TestParseGoobj(t *testing.T) { } func TestParseArchive(t *testing.T) { - path := goarchive + path := buildGoobj(t).goarchive f, err := os.Open(path) if err != nil { @@ -227,7 +238,7 @@ func TestParseArchive(t *testing.T) { func TestParseCGOArchive(t *testing.T) { testenv.MustHaveCGO(t) - path := cgoarchive + path := buildGoobj(t).cgoarchive f, err := os.Open(path) if err != nil {