all: fail faster on dirty working tree

It's annoying to get through all the tests for five different language
versions to discover at the end that you've got an uncommitted file
sitting around in your working tree, or you forgot to run
regenerate.bash.

Report uncommitted changes at the start of tests (so you can ^C and
fix the problem right off if you didn't know about it), but hold off on
failing the test until the end so you can still run tests on uncommitted
changes.

Fail immediately if generated files are out of date.

Change-Id: I12feaecaa3c5038ac0a4cca9cc9ff3447b57a08a
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/220517
Reviewed-by: Joe Tsai <joetsai@google.com>
This commit is contained in:
Damien Neil 2020-02-21 10:32:56 -08:00
parent 3a18560b88
commit 4d8936d0db

View File

@ -49,6 +49,42 @@ func Test(t *testing.T) {
mustInitDeps(t)
mustHandleFlags(t)
// Report dirt in the working tree quickly, rather than after
// going through all the presubmits.
//
// Fail the test late, so we can test uncommitted changes with -failfast.
diff := mustRunCommand(t, "git", "diff", "--compact-summary", "HEAD")
if strings.TrimSpace(diff) != "" {
fmt.Printf("WARNING: working tree contains uncommitted changes:\n%v\n", diff)
}
untracked := mustRunCommand(t, "git", "ls-files", "--others", "--exclude-standard")
if strings.TrimSpace(untracked) != "" {
fmt.Printf("WARNING: working tree contains untracked files:\n%v", untracked)
}
// Do the relatively fast checks up-front.
t.Run("GeneratedGoFiles", func(t *testing.T) {
diff := mustRunCommand(t, "go", "run", "-tags", "protolegacy", "./internal/cmd/generate-types")
if strings.TrimSpace(diff) != "" {
t.Fatalf("stale generated files:\n%v", diff)
}
diff = mustRunCommand(t, "go", "run", "-tags", "protolegacy", "./internal/cmd/generate-protos")
if strings.TrimSpace(diff) != "" {
t.Fatalf("stale generated files:\n%v", diff)
}
})
t.Run("FormattedGoFiles", func(t *testing.T) {
files := strings.Split(strings.TrimSpace(mustRunCommand(t, "git", "ls-files", "*.go")), "\n")
diff := mustRunCommand(t, append([]string{"gofmt", "-d"}, files...)...)
if strings.TrimSpace(diff) != "" {
t.Fatalf("unformatted source files:\n%v", diff)
}
})
t.Run("CopyrightHeaders", func(t *testing.T) {
files := strings.Split(strings.TrimSpace(mustRunCommand(t, "git", "ls-files", "*.go", "*.proto")), "\n")
mustHaveCopyrightHeader(t, files)
})
var wg sync.WaitGroup
sema := make(chan bool, (runtime.NumCPU()+1)/2)
for i := range golangVersions {
@ -79,37 +115,14 @@ func Test(t *testing.T) {
}
wg.Wait()
t.Run("GeneratedGoFiles", func(t *testing.T) {
diff := mustRunCommand(t, "go", "run", "-tags", "protolegacy", "./internal/cmd/generate-types")
if strings.TrimSpace(diff) != "" {
t.Fatalf("stale generated files:\n%v", diff)
}
diff = mustRunCommand(t, "go", "run", "-tags", "protolegacy", "./internal/cmd/generate-protos")
if strings.TrimSpace(diff) != "" {
t.Fatalf("stale generated files:\n%v", diff)
}
})
t.Run("FormattedGoFiles", func(t *testing.T) {
files := strings.Split(strings.TrimSpace(mustRunCommand(t, "git", "ls-files", "*.go")), "\n")
diff := mustRunCommand(t, append([]string{"gofmt", "-d"}, files...)...)
if strings.TrimSpace(diff) != "" {
t.Fatalf("unformatted source files:\n%v", diff)
}
})
t.Run("CopyrightHeaders", func(t *testing.T) {
files := strings.Split(strings.TrimSpace(mustRunCommand(t, "git", "ls-files", "*.go", "*.proto")), "\n")
mustHaveCopyrightHeader(t, files)
})
t.Run("CommittedGitChanges", func(t *testing.T) {
diff := mustRunCommand(t, "git", "diff", "--no-prefix", "HEAD")
if strings.TrimSpace(diff) != "" {
t.Fatalf("uncommitted changes:\n%v", diff)
t.Fatalf("uncommitted changes")
}
})
t.Run("TrackedGitFiles", func(t *testing.T) {
diff := mustRunCommand(t, "git", "ls-files", "--others", "--exclude-standard")
if strings.TrimSpace(diff) != "" {
t.Fatalf("untracked files:\n%v", diff)
if strings.TrimSpace(untracked) != "" {
t.Fatalf("untracked files")
}
})
}