| // Copyright 2021 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 harnesses |
| |
| import ( |
| "fmt" |
| "os/exec" |
| "path/filepath" |
| |
| "golang.org/x/benchmarks/sweet/common" |
| "golang.org/x/benchmarks/sweet/common/fileutil" |
| "golang.org/x/benchmarks/sweet/common/log" |
| ) |
| |
| type buildBenchmark struct { |
| name string |
| pkg string |
| clone func(outDir string) error |
| } |
| |
| var buildBenchmarks = []*buildBenchmark{ |
| { |
| name: "kubernetes", |
| pkg: "cmd/kubelet", |
| clone: func(outDir string) error { |
| return gitShallowClone( |
| outDir, |
| "https://github.com/kubernetes/kubernetes", |
| "v1.22.1", |
| ) |
| }, |
| }, |
| { |
| name: "istio", |
| pkg: "istioctl/cmd/istioctl", |
| clone: func(outDir string) error { |
| return gitShallowClone( |
| outDir, |
| "https://github.com/istio/istio", |
| "1.11.1", |
| ) |
| }, |
| }, |
| { |
| name: "pkgsite", |
| pkg: "cmd/frontend", |
| clone: func(outDir string) error { |
| return gitCloneToCommit( |
| outDir, |
| "https://go.googlesource.com/pkgsite", |
| "master", |
| "0a8194a898a1ceff6a0b29e3419650daf43d8567", |
| ) |
| }, |
| }, |
| } |
| |
| type GoBuild struct{} |
| |
| func (h GoBuild) CheckPrerequisites() error { |
| return nil |
| } |
| |
| func (h GoBuild) Get(srcDir string) error { |
| // Clone the sources that we're going to build. |
| for _, bench := range buildBenchmarks { |
| if err := bench.clone(filepath.Join(srcDir, bench.name)); err != nil { |
| return err |
| } |
| } |
| return nil |
| } |
| |
| func (h GoBuild) Build(pcfg *common.Config, bcfg *common.BuildConfig) error { |
| // Local copy of config for updating GOROOT. |
| cfg := pcfg.Copy() |
| |
| benchmarks := buildBenchmarks |
| if bcfg.Short { |
| // Do only the pkgsite benchmark. |
| benchmarks = []*buildBenchmark{buildBenchmarks[2]} |
| } |
| |
| // cfg.GoRoot is our source toolchain. We need to rebuild cmd/compile |
| // and cmd/link with cfg.BuildEnv to apply any configured build options |
| // (e.g., PGO). |
| // |
| // Do so by `go install`ing them into a copied GOROOT. |
| goroot := filepath.Join(bcfg.BinDir, "goroot") |
| if err := fileutil.CopyDir(goroot, cfg.GoRoot, nil); err != nil { |
| return fmt.Errorf("error copying GOROOT: %v", err) |
| } |
| cfg.GoRoot = goroot |
| if err := cfg.GoTool().Do("", "install", "cmd/compile", "cmd/link"); err != nil { |
| return fmt.Errorf("error building cmd/compile and cmd/link: %v", err) |
| } |
| |
| for _, bench := range benchmarks { |
| // Generate a symlink to the repository and put it in bin. |
| // It's not a binary, but it's the only place we can put it |
| // and still access it in Run. |
| link := filepath.Join(bcfg.BinDir, bench.name) |
| err := symlink(link, filepath.Join(bcfg.SrcDir, bench.name)) |
| if err != nil { |
| return err |
| } |
| |
| // Build the benchmark once, pulling in any requisite packages. |
| // |
| // Run the go tool with ExecEnv, as that is what we will use |
| // when benchmarking. |
| pkgPath := filepath.Join(bcfg.BinDir, bench.name, bench.pkg) |
| dummyBin := filepath.Join(bcfg.BinDir, "dummy") |
| goTool := cfg.GoTool() |
| goTool.Env = cfg.ExecEnv.MustSet("GOROOT=" + cfg.GoRoot) |
| if err := goTool.BuildPath(pkgPath, dummyBin); err != nil { |
| return fmt.Errorf("error building %s %s: %w", bench.name, bench.pkg, err) |
| } |
| } |
| |
| if err := cfg.GoTool().BuildPath(bcfg.BenchDir, filepath.Join(bcfg.BinDir, "go-build-bench")); err != nil { |
| return fmt.Errorf("error building go-build tool: %w", err) |
| } |
| return nil |
| } |
| |
| func (h GoBuild) Run(pcfg *common.Config, rcfg *common.RunConfig) error { |
| // Local copy of config for updating GOROOT. |
| cfg := pcfg.Copy() |
| cfg.GoRoot = filepath.Join(rcfg.BinDir, "goroot") // see Build, above. |
| |
| benchmarks := buildBenchmarks |
| if rcfg.Short { |
| // Do only the pkgsite benchmark. |
| benchmarks = []*buildBenchmark{buildBenchmarks[2]} |
| } |
| for _, bench := range benchmarks { |
| cmd := exec.Command( |
| filepath.Join(rcfg.BinDir, "go-build-bench"), |
| append(rcfg.Args, []string{ |
| "-go", cfg.GoTool().Tool, |
| "-tmp", rcfg.TmpDir, |
| filepath.Join(rcfg.BinDir, bench.name, bench.pkg), |
| }...)..., |
| ) |
| cmd.Env = cfg.ExecEnv.Collapse() |
| cmd.Stdout = rcfg.Results |
| cmd.Stderr = rcfg.Results |
| log.TraceCommand(cmd, false) |
| if err := cmd.Run(); err != nil { |
| return err |
| } |
| } |
| return nil |
| } |