aboutsummaryrefslogtreecommitdiff
path: root/src/internal/testenv
diff options
context:
space:
mode:
authorBryan C. Mills <bcmills@google.com>2023-02-02 10:42:46 -0500
committerGopher Robot <gobot@golang.org>2023-02-02 19:27:33 +0000
commit4b43d668c2ae42465af7cbad4bc5fa86d0b6cc15 (patch)
treecc68055be7392a361312de837006dc8cbeb56c54 /src/internal/testenv
parent18772915a1b9ca211a4bb707de59ee0941b4773b (diff)
downloadgo-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.go51
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)
}
}