[sk] Add tests for `try`
Change-Id: I1517ebb98fc0b94fa0dbb80a615ac96c806e1105
Reviewed-on: https://skia-review.googlesource.com/c/buildbot/+/399856
Reviewed-by: Joe Gregorio <jcgregorio@google.com>
Commit-Queue: Eric Boren <borenet@google.com>
diff --git a/sk/go/try/BUILD.bazel b/sk/go/try/BUILD.bazel
index ace9905..6953fbc 100644
--- a/sk/go/try/BUILD.bazel
+++ b/sk/go/try/BUILD.bazel
@@ -1,3 +1,4 @@
+load("//bazel/go:go_test.bzl", "go_test")
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
@@ -15,3 +16,15 @@
"@com_github_urfave_cli_v2//:cli",
],
)
+
+go_test(
+ name = "try_test",
+ srcs = ["try_test.go"],
+ embed = [":try"],
+ deps = [
+ "//go/exec",
+ "//go/testutils/unittest",
+ "//go/util",
+ "@com_github_stretchr_testify//require",
+ ],
+)
diff --git a/sk/go/try/try.go b/sk/go/try/try.go
index b6f4bb0..2b5b983 100644
--- a/sk/go/try/try.go
+++ b/sk/go/try/try.go
@@ -4,6 +4,7 @@
"bufio"
"context"
"fmt"
+ "io"
"os"
"regexp"
"sort"
@@ -19,6 +20,14 @@
"go.skia.org/infra/task_scheduler/go/specs"
)
+var (
+ // stdin is an abstraction of os.Stdin which is convenient for testing.
+ stdin io.Reader = os.Stdin
+
+ // tryjobs is an instance of tryJobReader which may be replaced for testing.
+ tryjobs tryJobReader = &tryJobReaderImpl{}
+)
+
// Command returns a cli.Command instance which represents the "try" command.
func Command() *cli.Command {
yFlag := "y"
@@ -34,6 +43,9 @@
},
},
Action: func(ctx *cli.Context) error {
+ if err := fixupIssue(ctx.Context); err != nil {
+ return err
+ }
return try(ctx.Context, ctx.Args().Slice(), ctx.Bool(yFlag))
},
}
@@ -43,10 +55,7 @@
// triggers the try jobs selected by the user.
func try(ctx context.Context, jobRequests []string, triggerWithoutPrompt bool) error {
// Setup.
- if err := fixupIssue(ctx); err != nil {
- return err
- }
- jobs, err := getTryJobs(ctx)
+ jobs, err := tryjobs.getTryJobs(ctx)
if err != nil {
return err
}
@@ -98,7 +107,8 @@
jobsToTrigger := filteredJobs
if !triggerWithoutPrompt {
fmt.Printf("Do you want to trigger these jobs? (y/n or i for interactive): ")
- read, err := bufio.NewReader(os.Stdin).ReadString('\n')
+ reader := bufio.NewReader(stdin)
+ read, err := reader.ReadString('\n')
if err != nil {
return err
}
@@ -111,7 +121,7 @@
for bucket, jobList := range filteredJobs {
for _, job := range jobList {
fmt.Printf("Trigger %s? (y/n): ", job)
- trigger, err := bufio.NewReader(os.Stdin).ReadString('\n')
+ trigger, err := reader.ReadString('\n')
if err != nil {
return err
}
@@ -176,12 +186,20 @@
return nil
}
-// getTryJobs reads tasks.json from the current repo and returns a
-// map[string][]string of Buildbucket bucket names to try job names.
-// TODO(borenet): This assumes that the current repo is associated with the
-// skia.primary bucket. This will work for most repos but it would be better to
-// look up the correct bucket to use.
-func getTryJobs(ctx context.Context) (map[string][]string, error) {
+// tryJobReader provides an abstraction for reading the available set of try
+// jobs to facilitate testing.
+type tryJobReader interface {
+ // getTryJobs reads tasks.json from the current repo and returns a
+ // map[string][]string of Buildbucket bucket names to try job names.
+ getTryJobs(context.Context) (map[string][]string, error)
+}
+
+// tryJobReaderImpl is the default tryJobReader implementation which reads from
+// the tasks.json file in the current repo.
+type tryJobReaderImpl struct{}
+
+// GetTryJobs implements tryJobReader.
+func (r *tryJobReaderImpl) getTryJobs(ctx context.Context) (map[string][]string, error) {
repoRoot, err := repo_root.GetLocal()
if err != nil {
return nil, err
@@ -194,6 +212,9 @@
for name := range tasksCfg.Jobs {
jobs = append(jobs, name)
}
+ // TODO(borenet): This assumes that the current repo is associated with the
+ // skia.primary bucket. This will work for most repos but it would be better
+ // to look up the correct bucket to use.
return map[string][]string{
"skia/skia.primary": jobs,
}, nil
diff --git a/sk/go/try/try_test.go b/sk/go/try/try_test.go
new file mode 100644
index 0000000..fec3e3a
--- /dev/null
+++ b/sk/go/try/try_test.go
@@ -0,0 +1,63 @@
+package try
+
+import (
+ "context"
+ "strings"
+ "testing"
+
+ "github.com/stretchr/testify/require"
+ "go.skia.org/infra/go/exec"
+ "go.skia.org/infra/go/testutils/unittest"
+ "go.skia.org/infra/go/util"
+)
+
+// mockTryJobReader is a mock implementation of tryJobReader used for testing.
+type mockTryJobReader struct {
+ jobs map[string][]string
+}
+
+// getTryJobs implements tryJobReader.
+func (r *mockTryJobReader) getTryJobs(ctx context.Context) (map[string][]string, error) {
+ return r.jobs, nil
+}
+
+func TestTry(t *testing.T) {
+ unittest.SmallTest(t)
+
+ mockCmd := exec.CommandCollector{}
+ ctx := exec.NewContext(context.Background(), mockCmd.Run)
+ bucket := "skia/skia.primary"
+ tryjobs = &mockTryJobReader{
+ jobs: map[string][]string{
+ bucket: {
+ "my-job",
+ "another-job",
+ },
+ },
+ }
+ tryCmdPrefix := []string{"cl", "try", "-B", bucket}
+
+ check := func(jobs []string, noPrompt bool, input string, expectTriggered []string) {
+ mockCmd.ClearCommands()
+ stdin = strings.NewReader(input)
+ require.NoError(t, try(ctx, jobs, noPrompt))
+ triggeredJobs := []string{}
+ for _, cmd := range mockCmd.Commands() {
+ if len(cmd.Args) > len(tryCmdPrefix) && util.SSliceEqual(cmd.Args[:len(tryCmdPrefix)], tryCmdPrefix) {
+ for i := len(tryCmdPrefix); i < len(cmd.Args); i++ {
+ arg := cmd.Args[i]
+ if arg != "-b" {
+ triggeredJobs = append(triggeredJobs, arg)
+ }
+ }
+ }
+ }
+ require.Equal(t, expectTriggered, triggeredJobs)
+ }
+ check([]string{"my-job"}, true, "", []string{"my-job"})
+ check([]string{"my-job"}, false, "y\n", []string{"my-job"})
+ check([]string{".*-job"}, true, "", []string{"another-job", "my-job"})
+ check([]string{"my-job"}, false, "n\n", []string{})
+ check([]string{".*-job"}, false, "i\ny\ny\n", []string{"another-job", "my-job"})
+ check([]string{".*-job"}, false, "i\nn\ny\n", []string{"my-job"})
+}