diff options
| author | Bryan C. Mills <bcmills@google.com> | 2023-02-02 10:42:46 -0500 |
|---|---|---|
| committer | Gopher Robot <gobot@golang.org> | 2023-02-02 19:27:33 +0000 |
| commit | 4b43d668c2ae42465af7cbad4bc5fa86d0b6cc15 (patch) | |
| tree | cc68055be7392a361312de837006dc8cbeb56c54 /src/internal/testenv | |
| parent | 18772915a1b9ca211a4bb707de59ee0941b4773b (diff) | |
| download | go-4b43d668c2ae42465af7cbad4bc5fa86d0b6cc15.tar.xz | |
internal/testenv: avoid rebuilding all of std in WriteImportcfg
Instead, have the caller pass in an explicit list of the packages
(if any) they need.
After #47257, a builder running a test does not necessarily have the
entire standard library already cached, especially when running tests
in sharded mode. testenv.WriteImportcfg used to write an importcfg for
the entire standard library — which required rebuilding the entire
standard library — even though most tests need only a tiny subset.
This reduces the time to test internal/abi with a cold build cache on
my workstation from ~16s to ~0.05s.
It somewhat increases the time for 'go test go/internal/gcimporter'
with a cold cache, from ~43s to ~54s, presumably due to decreased
parallelism in rebuilding the standard library and increased overhead
in re-resolving the import map. However, 'go test -short' running time
remains stable (~5.5s before and after).
Fixes #58248.
Change-Id: I9be6b61ae6e28b75b53af85207c281bb93b9346f
Reviewed-on: https://go-review.googlesource.com/c/go/+/464736
Run-TryBot: Bryan Mills <bcmills@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Auto-Submit: Bryan Mills <bcmills@google.com>
Diffstat (limited to 'src/internal/testenv')
| -rw-r--r-- | src/internal/testenv/testenv.go | 51 |
1 files changed, 39 insertions, 12 deletions
diff --git a/src/internal/testenv/testenv.go b/src/internal/testenv/testenv.go index 6a28b25278..82fdfb6ff6 100644 --- a/src/internal/testenv/testenv.go +++ b/src/internal/testenv/testenv.go @@ -11,11 +11,11 @@ package testenv import ( + "bytes" "errors" "flag" "fmt" "internal/cfg" - "internal/goroot" "internal/platform" "os" "os/exec" @@ -347,18 +347,45 @@ func SkipIfOptimizationOff(t testing.TB) { } // WriteImportcfg writes an importcfg file used by the compiler or linker to -// dstPath containing entries for the packages in std and cmd in addition -// to the package to package file mappings in additionalPackageFiles. -func WriteImportcfg(t testing.TB, dstPath string, additionalPackageFiles map[string]string) { - importcfg, err := goroot.Importcfg() - for k, v := range additionalPackageFiles { - importcfg += fmt.Sprintf("\npackagefile %s=%s", k, v) +// dstPath containing entries for the file mappings in packageFiles, as well +// as for the packages transitively imported by the package(s) in pkgs. +// +// pkgs may include any package pattern that is valid to pass to 'go list', +// so it may also be a list of Go source files all in the same directory. +func WriteImportcfg(t testing.TB, dstPath string, packageFiles map[string]string, pkgs ...string) { + t.Helper() + + icfg := new(bytes.Buffer) + icfg.WriteString("# import config\n") + for k, v := range packageFiles { + fmt.Fprintf(icfg, "packagefile %s=%s\n", k, v) } - if err != nil { - t.Fatalf("preparing the importcfg failed: %s", err) + + if len(pkgs) > 0 { + // Use 'go list' to resolve any missing packages and rewrite the import map. + cmd := Command(t, GoToolPath(t), "list", "-export", "-deps", "-f", `{{if ne .ImportPath "command-line-arguments"}}{{if .Export}}{{.ImportPath}}={{.Export}}{{end}}{{end}}`) + cmd.Args = append(cmd.Args, pkgs...) + cmd.Stderr = new(strings.Builder) + out, err := cmd.Output() + if err != nil { + t.Fatalf("%v: %v\n%s", cmd, err, cmd.Stderr) + } + + for _, line := range strings.Split(string(out), "\n") { + if line == "" { + continue + } + importPath, export, ok := strings.Cut(line, "=") + if !ok { + t.Fatalf("invalid line in output from %v:\n%s", cmd, line) + } + if packageFiles[importPath] == "" { + fmt.Fprintf(icfg, "packagefile %s=%s\n", importPath, export) + } + } } - err = os.WriteFile(dstPath, []byte(importcfg), 0655) - if err != nil { - t.Fatalf("writing the importcfg failed: %s", err) + + if err := os.WriteFile(dstPath, icfg.Bytes(), 0666); err != nil { + t.Fatal(err) } } |
