test_planner: move pruning-related methods to new source file
These methods are all related to removing test suites from the eventual
test plan.
This refactor will simplify changes for crbug.com/976530
BUG=chromium:976530
TEST=unit tests (generator_test.go covers this new file)
Change-Id: I3ba45b8ce116595a34faa7080a089ac13c522b59
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/infra/test_planner/+/1673550
Reviewed-by: Jason Clinton <jclinton@chromium.org>
Commit-Queue: Sean Abraham <seanabraham@chromium.org>
Tested-by: Sean Abraham <seanabraham@chromium.org>
diff --git a/src/testplans/go.mod b/src/testplans/go.mod
index 7c0d0b9..1449a9c 100644
--- a/src/testplans/go.mod
+++ b/src/testplans/go.mod
@@ -16,7 +16,7 @@
github.com/smartystreets/assertions v0.0.0-20190401211740-f487f9de1cd3 // indirect
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a // indirect
github.com/texttheater/golang-levenshtein v0.0.0-20180516184445-d188e65d659e // indirect
- go.chromium.org/chromiumos/infra/proto/go v0.0.0-20190523171533-39bf919eecb4
+ go.chromium.org/chromiumos/infra/proto/go v0.0.0-20190620221159-9206f8f25ade
go.chromium.org/luci v0.0.0-20190404171609-14fb4fbce8ea
golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a // indirect
google.golang.org/grpc v1.19.1 // indirect
diff --git a/src/testplans/go.sum b/src/testplans/go.sum
index 2790da4..cb2ccc5 100644
--- a/src/testplans/go.sum
+++ b/src/testplans/go.sum
@@ -128,6 +128,7 @@
go.chromium.org/chromiumos/infra/proto v0.0.0-20190521155230-020e6e4c3db7 h1:NfZmFRahNWbucJxPu590Uango4DhkZf+/sghHrboRAo=
go.chromium.org/chromiumos/infra/proto v0.0.0-20190522220408-28d21b420351 h1:KNLtgp0J88Hncy7GXvYUec8VVarBWQmkiG1yVJqiMcc=
go.chromium.org/chromiumos/infra/proto v0.0.0-20190523171533-39bf919eecb4 h1:MbjVVWG/KH+oEO3Vb1/ru10VbrnYHwbpyRNJsi1lFpo=
+go.chromium.org/chromiumos/infra/proto v0.0.0-20190620221159-9206f8f25ade h1:Ryr72FOi62Wa6HXtykgbNyp3yA+tXmRRSCSHOw4ALhY=
go.chromium.org/chromiumos/infra/proto/go v0.0.0-20190506153826-232eeaaa29a9 h1:87ML72wybRl6dKe4qyvTH5Y6ihvrTxT13+xTsz7F6tE=
go.chromium.org/chromiumos/infra/proto/go v0.0.0-20190506153826-232eeaaa29a9/go.mod h1:Y1AiM5bpNKKecKy3wgiBwF9q1PJ/f57z86DpkNrMehk=
go.chromium.org/chromiumos/infra/proto/go v0.0.0-20190514195506-9aeeb525f8a2 h1:kAJWnYFu1Vvk3RdZLKz9rDDBsi4m8WPDXv7r9plSEaY=
@@ -148,6 +149,8 @@
go.chromium.org/chromiumos/infra/proto/go v0.0.0-20190522220408-28d21b420351/go.mod h1:Y1AiM5bpNKKecKy3wgiBwF9q1PJ/f57z86DpkNrMehk=
go.chromium.org/chromiumos/infra/proto/go v0.0.0-20190523171533-39bf919eecb4 h1:WLlJOjc1h7tWmpiaB/fZsf9a12fcj1NstLJjbX7soM0=
go.chromium.org/chromiumos/infra/proto/go v0.0.0-20190523171533-39bf919eecb4/go.mod h1:Y1AiM5bpNKKecKy3wgiBwF9q1PJ/f57z86DpkNrMehk=
+go.chromium.org/chromiumos/infra/proto/go v0.0.0-20190620221159-9206f8f25ade h1:nEbrOlXy2f7gxNceKIdRj+epA1DsydTERwGiW5llzjM=
+go.chromium.org/chromiumos/infra/proto/go v0.0.0-20190620221159-9206f8f25ade/go.mod h1:Y1AiM5bpNKKecKy3wgiBwF9q1PJ/f57z86DpkNrMehk=
go.chromium.org/luci v0.0.0-20190404171609-14fb4fbce8ea h1:qf3Ri7sv3yJPL4E0iq4hBYn3AFSf2dNNJpuZDBXAT2E=
go.chromium.org/luci v0.0.0-20190404171609-14fb4fbce8ea/go.mod h1:MIQewVTLvOvc0UioV0JNqTNO/RspKFS0XEeoKrOxsdM=
go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
diff --git a/src/testplans/internal/generator/generator.go b/src/testplans/internal/generator/generator.go
index bda4563..a111f6d 100644
--- a/src/testplans/internal/generator/generator.go
+++ b/src/testplans/internal/generator/generator.go
@@ -1,6 +1,7 @@
// Copyright 2019 The Chromium 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 generator
import (
@@ -11,27 +12,9 @@
"go.chromium.org/chromiumos/infra/proto/go/testplans"
bbproto "go.chromium.org/luci/buildbucket/proto"
"log"
- "strings"
"testplans/internal/git"
)
-type testType int
-
-const (
- hw testType = iota
- vm
-)
-
-var (
- testTypeFilter = map[testType]func(testReqs *testplans.TestRestriction) bool{
- hw: func(testReqs *testplans.TestRestriction) bool { return testReqs.DisableHwTests },
- vm: func(testReqs *testplans.TestRestriction) bool { return testReqs.DisableVmTests },
- }
-)
-
-func (tt testType) String() string {
- return [...]string{"Hw", "Vm"}[tt]
-}
// BuildTarget is an OS build target, such as "kevin" or "eve".
type BuildTarget string
@@ -235,34 +218,6 @@
return tsc
}
-// extractSkippableTests maps BuildTargets to the test types that can be skipped for those targets,
-// based on source tree test restrictions.
-func extractSkippableTests(
- sourceTreeCfg *testplans.SourceTreeTestCfg,
- buildReports []*bbproto.Build,
- changeRevs *git.ChangeRevData,
- repoToSrcRoot map[string]string) (map[BuildTarget]map[testType]bool, error) {
-
- skippableTests := make(map[BuildTarget]map[testType]bool)
- for _, report := range buildReports {
- buildTarget := BuildTarget(getBuildTarget(report))
- skippableTests[buildTarget] = make(map[testType]bool)
-
- disableHWTesting, err := canDisableTesting(sourceTreeCfg, report, changeRevs, repoToSrcRoot, hw)
- if err != nil {
- return skippableTests, err
- }
- skippableTests[buildTarget][hw] = disableHWTesting
- disableVMTesting, err := canDisableTesting(sourceTreeCfg, report, changeRevs, repoToSrcRoot, vm)
- if err != nil {
- return skippableTests, err
- }
- skippableTests[buildTarget][vm] = disableVMTesting
- log.Printf("For build %s, got disableHWTesting = %t, disableVMTesting = %t", getBuildTarget(report), disableHWTesting, disableVMTesting)
- }
- return skippableTests, nil
-}
-
// selectBuildForRequirements finds a build that best matches the provided PerTargetTestRequirements.
// e.g. if the requirements want a build for a reef build target, this method will find a successful,
// non-early-terminated build.
@@ -323,61 +278,3 @@
log.Printf("can't test for build target(s) %v because all builders failed\n", buildTargets)
return nil, nil
}
-
-// canDisableTesting determines whether a particular testing type is unnecessary for a given
-// builder, based on source tree test restrictions.
-func canDisableTesting(
- sourceTreeCfg *testplans.SourceTreeTestCfg,
- buildResult *bbproto.Build,
- changeRevs *git.ChangeRevData,
- repoToSrcRoot map[string]string,
- tt testType) (bool, error) {
- if len(buildResult.Input.GerritChanges) == 0 {
- // This happens during postsubmit runs, for example.
- log.Printf("build doesn't contain gerrit_changes %s, so no tests will be skipped", getBuildTarget(buildResult))
- return false, nil
- }
- fileCount := 0
- for _, commit := range buildResult.Input.GerritChanges {
- chRev, err := changeRevs.GetChangeRev(commit.Host, commit.Change, int32(commit.Patchset))
- if err != nil {
- return false, err
- }
- for _, file := range chRev.Files {
- fileCount++
- srcRootMapping, found := repoToSrcRoot[chRev.Project]
- if !found {
- return false, fmt.Errorf("Found no source mapping for project %s", chRev.Project)
- }
- fileSrcPath := fmt.Sprintf("%s/%s", srcRootMapping, file)
- disableTesting, err := canDisableTestingForPath(fileSrcPath, sourceTreeCfg, tt)
- if err != nil {
- return false, err
- }
- if !disableTesting {
- log.Printf("Can't disable %s testing due to file %s", tt, fileSrcPath)
- return false, nil
- }
- }
- }
- // Either testing is disabled for all of the files or there are zero files.
- log.Printf("%s testing is not needed for %d files in the %s build", tt, fileCount, getBuildTarget(buildResult))
- return true, nil
-}
-
-// canDisableTestingForPath determines whether a particular testing type is unnecessary for
-// a given file, based on source tree test restrictions.
-func canDisableTestingForPath(sourceTreePath string, sourceTreeCfg *testplans.SourceTreeTestCfg, tt testType) (bool, error) {
- for _, sourceTreeRestriction := range sourceTreeCfg.SourceTreeTestRestriction {
- testFilter, ok := testTypeFilter[tt]
- if !ok {
- return false, fmt.Errorf("Missing test filter for %v", tt)
- }
- if testFilter(sourceTreeRestriction.TestRestriction) {
- if strings.HasPrefix(sourceTreePath, sourceTreeRestriction.SourceTree.Path) {
- return true, nil
- }
- }
- }
- return false, nil
-}
diff --git a/src/testplans/internal/generator/test_pruner.go b/src/testplans/internal/generator/test_pruner.go
new file mode 100644
index 0000000..0ec61bf
--- /dev/null
+++ b/src/testplans/internal/generator/test_pruner.go
@@ -0,0 +1,119 @@
+// Copyright 2019 The Chromium 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 generator
+
+import (
+ "fmt"
+ "go.chromium.org/chromiumos/infra/proto/go/testplans"
+ bbproto "go.chromium.org/luci/buildbucket/proto"
+ "log"
+ "strings"
+ "testplans/internal/git"
+)
+
+type testType int
+
+const (
+ hw testType = iota
+ vm
+)
+
+var (
+ testTypeFilter = map[testType]func(testReqs *testplans.TestRestriction) bool{
+ hw: func(testReqs *testplans.TestRestriction) bool { return testReqs.DisableHwTests },
+ vm: func(testReqs *testplans.TestRestriction) bool { return testReqs.DisableVmTests },
+ }
+)
+
+func (tt testType) String() string {
+ return [...]string{"Hw", "Vm"}[tt]
+}
+
+// extractSkippableTests maps BuildTargets to the test types that can be skipped for those targets,
+// based on source tree test restrictions.
+func extractSkippableTests(
+ sourceTreeCfg *testplans.SourceTreeTestCfg,
+ buildReports []*bbproto.Build,
+ changeRevs *git.ChangeRevData,
+ repoToSrcRoot map[string]string) (map[BuildTarget]map[testType]bool, error) {
+
+ skippableTests := make(map[BuildTarget]map[testType]bool)
+ for _, report := range buildReports {
+ buildTarget := BuildTarget(getBuildTarget(report))
+ skippableTests[buildTarget] = make(map[testType]bool)
+
+ disableHWTesting, err := canDisableTesting(sourceTreeCfg, report, changeRevs, repoToSrcRoot, hw)
+ if err != nil {
+ return skippableTests, err
+ }
+ skippableTests[buildTarget][hw] = disableHWTesting
+ disableVMTesting, err := canDisableTesting(sourceTreeCfg, report, changeRevs, repoToSrcRoot, vm)
+ if err != nil {
+ return skippableTests, err
+ }
+ skippableTests[buildTarget][vm] = disableVMTesting
+ log.Printf("For build %s, got disableHWTesting = %t, disableVMTesting = %t", getBuildTarget(report), disableHWTesting, disableVMTesting)
+ }
+ return skippableTests, nil
+}
+
+
+// canDisableTesting determines whether a particular testing type is unnecessary for a given
+// builder, based on source tree test restrictions.
+func canDisableTesting(
+ sourceTreeCfg *testplans.SourceTreeTestCfg,
+ buildResult *bbproto.Build,
+ changeRevs *git.ChangeRevData,
+ repoToSrcRoot map[string]string,
+ tt testType) (bool, error) {
+ if len(buildResult.Input.GerritChanges) == 0 {
+ // This happens during postsubmit runs, for example.
+ log.Printf("build doesn't contain gerrit_changes %s, so no tests will be skipped", getBuildTarget(buildResult))
+ return false, nil
+ }
+ fileCount := 0
+ for _, commit := range buildResult.Input.GerritChanges {
+ chRev, err := changeRevs.GetChangeRev(commit.Host, commit.Change, int32(commit.Patchset))
+ if err != nil {
+ return false, err
+ }
+ for _, file := range chRev.Files {
+ fileCount++
+ srcRootMapping, found := repoToSrcRoot[chRev.Project]
+ if !found {
+ return false, fmt.Errorf("Found no source mapping for project %s", chRev.Project)
+ }
+ fileSrcPath := fmt.Sprintf("%s/%s", srcRootMapping, file)
+ disableTesting, err := canDisableTestingForPath(fileSrcPath, sourceTreeCfg, tt)
+ if err != nil {
+ return false, err
+ }
+ if !disableTesting {
+ log.Printf("Can't disable %s testing due to file %s", tt, fileSrcPath)
+ return false, nil
+ }
+ }
+ }
+ // Either testing is disabled for all of the files or there are zero files.
+ log.Printf("%s testing is not needed for %d files in the %s build", tt, fileCount, getBuildTarget(buildResult))
+ return true, nil
+}
+
+// canDisableTestingForPath determines whether a particular testing type is unnecessary for
+// a given file, based on source tree test restrictions.
+func canDisableTestingForPath(sourceTreePath string, sourceTreeCfg *testplans.SourceTreeTestCfg, tt testType) (bool, error) {
+ for _, sourceTreeRestriction := range sourceTreeCfg.SourceTreeTestRestriction {
+ testFilter, ok := testTypeFilter[tt]
+ if !ok {
+ return false, fmt.Errorf("Missing test filter for %v", tt)
+ }
+ if testFilter(sourceTreeRestriction.TestRestriction) {
+ if strings.HasPrefix(sourceTreePath, sourceTreeRestriction.SourceTree.Path) {
+ return true, nil
+ }
+ }
+ }
+ return false, nil
+}