blob: 21cd0dc5599d3fdb4ee3426cd665ca5e5b5ef548 [file] [log] [blame]
// 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 (
"os"
"os/exec"
"path/filepath"
"golang.org/x/benchmarks/sweet/common"
"golang.org/x/benchmarks/sweet/common/log"
)
type Etcd struct{}
func (h Etcd) CheckPrerequisites() error {
return nil
}
func (h Etcd) Get(gcfg *common.GetConfig) error {
// Build against the latest alpha.
//
// Because of the way etcd is released (as a binary blob),
// deployed copies tend to be stuck with a specific Go version.
// Improving performance of these versions doesn't really matter.
// Instead, try to track something close to HEAD.
return gitShallowClone(
gcfg.SrcDir,
"https://github.com/etcd-io/etcd",
"v3.6.0-alpha.0",
)
}
func (h Etcd) Build(cfg *common.Config, bcfg *common.BuildConfig) error {
env := cfg.BuildEnv.Env
// Add the Go tool to PATH, since etcd's Makefile doesn't provide enough
// visibility into how etcd is built to allow us to pass this information
// directly. Also set the GOROOT explicitly because it might have propagated
// differently from the environment.
env = env.Prefix("PATH", filepath.Join(cfg.GoRoot, "bin")+":")
env = env.MustSet("GOROOT=" + cfg.GoRoot)
cmd := exec.Command("make", "-C", bcfg.SrcDir, "build")
cmd.Env = env.Collapse()
log.TraceCommand(cmd, false)
// Call Output here to get an *ExitError with a populated Stderr field.
if _, err := cmd.Output(); err != nil {
return err
}
// Note that no matter what we do, the build script insists on putting the
// binaries into the source directory, so copy the one we care about into
// BinDir.
if err := copyFile(filepath.Join(bcfg.BinDir, "etcd"), filepath.Join(bcfg.SrcDir, "bin", "etcd")); err != nil {
return err
}
// Build etcd's benchmarking tool. Our benchmark is just a wrapper around that.
benchmarkPkg := filepath.Join(bcfg.SrcDir, "tools", "benchmark")
if err := cfg.GoTool().BuildPath(benchmarkPkg, filepath.Join(bcfg.BinDir, "benchmark")); err != nil {
return err
}
// Build the benchmark wrapper.
return cfg.GoTool().BuildPath(bcfg.BenchDir, filepath.Join(bcfg.BinDir, "etcd-bench"))
}
func (h Etcd) Run(cfg *common.Config, rcfg *common.RunConfig) error {
for _, bench := range []string{"put", "stm"} {
args := append(rcfg.Args, []string{
"-bench", bench,
"-etcd-bin", filepath.Join(rcfg.BinDir, "etcd"),
"-benchmark-bin", filepath.Join(rcfg.BinDir, "benchmark"),
"-tmp", rcfg.TmpDir,
}...)
if rcfg.Short {
args = append(args, "-short")
}
cmd := exec.Command(
filepath.Join(rcfg.BinDir, "etcd-bench"),
args...,
)
cmd.Env = cfg.ExecEnv.Collapse()
cmd.Stdout = rcfg.Results
cmd.Stderr = rcfg.Log
log.TraceCommand(cmd, false)
if err := cmd.Run(); err != nil {
return err
}
// Delete tmp because etcd will have written something there and
// might attempt to reuse it.
if err := rmDirContents(rcfg.TmpDir); err != nil {
return err
}
}
return nil
}
func rmDirContents(dir string) error {
log.CommandPrintf("rm -rf %s/*", dir)
fs, err := os.ReadDir(dir)
if err != nil {
return err
}
for _, fi := range fs {
if err := os.RemoveAll(filepath.Join(dir, fi.Name())); err != nil {
return err
}
}
return nil
}