cmd/bench: add benchmark wrapper

The coordinator is getting support for running the benchmarks in this
repository. Since the benchmarks and interface are in flux, encoding all
of the details of running Go tests, bent arguments, etc into the
coordinator will likely cause churn and frustrating migration issues.

Instead, add cmd/bench which serves as the simple entrypoint for the
coordinator. The coordinator runs cmd/bench with the GOROOT to test
(eventually multiple GOROOTs), and this binary takes care of the
remaining details.

Right now, we just do a basic go test golang.org/x/benchmarks/... and
simple invocation of bent. Note that bent does not pass without
https://golang.org/cl/354634.

For golang/go#49207

Change-Id: I5c9cf89540cab605c0a64e17af85311d37985c25
Reviewed-on: https://go-review.googlesource.com/c/benchmarks/+/359854
Trust: Michael Pratt <mpratt@google.com>
Run-TryBot: Michael Pratt <mpratt@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
diff --git a/cmd/bench/main.go b/cmd/bench/main.go
new file mode 100644
index 0000000..3699331
--- /dev/null
+++ b/cmd/bench/main.go
@@ -0,0 +1,61 @@
+// 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.
+
+// Binary bench provides a unified wrapper around the different types of
+// benchmarks in x/benchmarks.
+package main
+
+import (
+	"log"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"strings"
+)
+
+func determineGOROOT() (string, error) {
+	g, ok := os.LookupEnv("GOROOT")
+	if ok {
+		return g, nil
+	}
+
+	cmd := exec.Command("go", "env", "GOROOT")
+	b, err := cmd.Output()
+	if err != nil {
+		return "", err
+	}
+	return strings.TrimSpace(string(b)), nil
+}
+
+func goCommand(goroot string, args ...string) *exec.Cmd {
+	bin := filepath.Join(goroot, "bin/go")
+	cmd := exec.Command(bin, args...)
+	return cmd
+}
+
+func main() {
+	goroot, err := determineGOROOT()
+	if err != nil {
+		log.Fatalf("Unable to determine GOROOT: %v", err)
+	}
+
+	log.Printf("GOROOT under test: %s", goroot)
+
+	pass := true
+
+	if err := goTest(goroot); err != nil {
+		pass = false
+		log.Printf("Error running Go tests: %v", err)
+	}
+
+	if err := bent(goroot); err != nil {
+		pass = false
+		log.Printf("Error running bent: %v", err)
+	}
+
+	if !pass {
+		log.Printf("FAIL")
+		os.Exit(1)
+	}
+}