Skip to content

Commit 7bbd648

Browse files
committed
codeowners: extract GetTestOwner function into new public helper method
We will use this in a new helper tool later. Part of: DEVINF-1649 Release note: none Epic: DEVINF-1582
1 parent e6c6c4d commit 7bbd648

File tree

5 files changed

+155
-149
lines changed

5 files changed

+155
-149
lines changed

pkg/cmd/bazci/githubpost/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ go_test(
2626
deps = [
2727
"//pkg/build/util",
2828
"//pkg/cmd/bazci/githubpost/issues",
29+
"//pkg/internal/codeowners",
2930
"//pkg/testutils/datapathutils",
3031
"@com_github_stretchr_testify//assert",
3132
"@com_github_stretchr_testify//require",

pkg/cmd/bazci/githubpost/githubpost.go

Lines changed: 23 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,11 @@ import (
2020
"io"
2121
"log"
2222
"os"
23-
"os/exec"
24-
"path/filepath"
2523
"regexp"
2624
"sort"
2725
"strconv"
2826
"strings"
27+
"sync"
2928
"time"
3029

3130
buildutil "github.com/cockroachdb/cockroach/pkg/build/util"
@@ -40,23 +39,30 @@ const (
4039
unknown = "(unknown)"
4140
)
4241

43-
type packageAndTest struct {
44-
packageName, testName string
45-
}
42+
var (
43+
co *codeowners.CodeOwners
44+
codeownersOnce sync.Once
45+
)
4646

47-
type fileAndLine struct {
48-
filename, linenum string
47+
func initCo() {
48+
codeownersOnce.Do(func() {
49+
co_, err := codeowners.DefaultLoadCodeOwners()
50+
if err != nil {
51+
panic(err)
52+
}
53+
co = co_
54+
})
4955
}
5056

51-
// This should be set to some non-nil map in test scenarios. This is used to
52-
// mock out the results of the getFileLine function.
53-
var fileLineForTesting map[packageAndTest]fileAndLine
54-
5557
type Formatter func(context.Context, Failure) (issues.IssueFormatter, issues.PostRequest)
5658
type FailurePoster func(context.Context, Failure) error
5759

5860
func DefaultFormatter(ctx context.Context, f Failure) (issues.IssueFormatter, issues.PostRequest) {
59-
teams := getOwner(ctx, f.packageName, f.testName)
61+
initCo()
62+
teams, logs := co.GetTestOwner(f.packageName, f.testName)
63+
for _, line := range logs {
64+
log.Println(line)
65+
}
6066
repro := fmt.Sprintf("./dev test ./pkg/%s --race --stress -f %s",
6167
trimPkg(f.packageName), f.testName)
6268

@@ -455,21 +461,22 @@ func listFailuresFromJSON(
455461
// 2) Otherwise, we don't blame anybody in particular. We file a generic issue
456462
// listing the package name containing the report of long-running tests.
457463
if timedOutCulprit.name != "" {
464+
initCo()
458465
slowest := slowFailEvents[0]
459466
if len(slowPassEvents) > 0 && slowPassEvents[0].Elapsed > slowest.Elapsed {
460467
slowest = slowPassEvents[0]
461468
}
462469

463-
culpritOwner := fmt.Sprintf("%v", getOwner(ctx, timedOutCulprit.pkg, timedOutCulprit.name))
470+
culpritOwner, _ := co.GetTestOwner(timedOutCulprit.pkg, timedOutCulprit.name)
464471
slowEvents := append(slowFailEvents, slowPassEvents...)
465472
// The predicate determines if the union of the slow events is owned by the _same_ team(s) as timedOutCulprit.
466473
hasSameOwner := func() bool {
467474
for _, slowEvent := range slowEvents {
468475
scopedEvent := scoped(slowEvent)
469-
owner := fmt.Sprintf("%v", getOwner(ctx, scopedEvent.pkg, scopedEvent.name))
476+
owner, _ := co.GetTestOwner(scopedEvent.pkg, scopedEvent.name)
470477

471-
if culpritOwner != owner {
472-
log.Printf("%v has a different owner: %s;bailing out...\n", scopedEvent, owner)
478+
if len(culpritOwner) < 1 || len(owner) < 1 || culpritOwner[0].TeamName != owner[0].TeamName {
479+
log.Printf("%v has a different owner: %v;bailing out...\n", scopedEvent, owner)
473480
return false
474481
}
475482
}
@@ -630,95 +637,6 @@ func writeSlowTestsReport(report string) error {
630637
return os.WriteFile("artifacts/slow-tests-report.txt", []byte(report), 0644)
631638
}
632639

633-
// getFileLine returns the file (relative to repo root) and line for the given test.
634-
// The package name is assumed relative to the repo root as well, i.e. pkg/foo/bar.
635-
func getFileLine(
636-
ctx context.Context, packageName, testName string,
637-
) (_filename string, _linenum string, _ error) {
638-
if fileLineForTesting != nil {
639-
res, ok := fileLineForTesting[packageAndTest{packageName: packageName, testName: testName}]
640-
if ok {
641-
return res.filename, res.linenum, nil
642-
}
643-
return "", "", errors.Newf("could not find testing line:num for %s.%s", packageName, testName)
644-
}
645-
// Search the source code for the email address of the last committer to touch
646-
// the first line of the source code that contains testName. Then, ask GitHub
647-
// for the GitHub username of the user with that email address by searching
648-
// commits in cockroachdb/cockroach for commits authored by the address.
649-
subtests := strings.Split(testName, "/")
650-
testName = subtests[0]
651-
packageName = strings.TrimPrefix(packageName, "github.com/cockroachdb/cockroach/")
652-
for {
653-
if !strings.Contains(packageName, "pkg") {
654-
return "", "", errors.Newf("could not find test %s", testName)
655-
}
656-
cmd := exec.Command(`/bin/bash`, `-c`,
657-
fmt.Sprintf(`cd "$(git rev-parse --show-toplevel)" && git grep -n 'func %s(' '%s/*_test.go'`,
658-
testName, packageName))
659-
// This command returns output such as:
660-
// ../ccl/storageccl/export_test.go:31:func TestExportCmd(t *testing.T) {
661-
out, err := cmd.CombinedOutput()
662-
if err != nil {
663-
fmt.Printf("couldn't find test %s in %s: %s %+v\n",
664-
testName, packageName, string(out), err)
665-
packageName = filepath.Dir(packageName)
666-
continue
667-
}
668-
re := regexp.MustCompile(`(.*):(.*):`)
669-
// The first 2 :-delimited fields are the filename and line number.
670-
matches := re.FindSubmatch(out)
671-
if matches == nil {
672-
fmt.Printf("couldn't find filename/line number for test %s in %s: %s %+v\n",
673-
testName, packageName, string(out), err)
674-
packageName = filepath.Dir(packageName)
675-
continue
676-
}
677-
return string(matches[1]), string(matches[2]), nil
678-
}
679-
}
680-
681-
// getOwner looks up the file containing the given test and returns
682-
// the owning teams. It does not return
683-
// errors, but instead simply returns what it can.
684-
// In case no owning team is found, "test-eng" team is returned.
685-
func getOwner(ctx context.Context, packageName, testName string) (_teams []team.Team) {
686-
filename, _, err := getFileLine(ctx, packageName, testName)
687-
if err != nil {
688-
log.Printf("error getting file:line for %s.%s: %s", packageName, testName, err)
689-
// Let's continue so that we can assign the "catch-all" owner.
690-
}
691-
co, err := codeowners.DefaultLoadCodeOwners()
692-
if err != nil {
693-
log.Printf("loading codeowners: %s", err)
694-
return nil
695-
}
696-
match := co.Match(filename)
697-
698-
if match == nil {
699-
// N.B. if no owning team is found, we default to 'test-eng'. This should be a rare exception rather than the rule.
700-
testEng := co.GetTeamForAlias("cockroachdb/test-eng")
701-
if testEng.Name() == "" {
702-
log.Fatalf("test-eng team could not be found in TEAMS.yaml")
703-
}
704-
705-
// Workaround for #107885.
706-
if strings.Contains(packageName, "backup") {
707-
dr := co.GetTeamForAlias("cockroachdb/disaster-recovery")
708-
if dr.Name() == "" {
709-
log.Fatalf("disaster-recovery team could not be found in TEAMS.yaml")
710-
}
711-
712-
log.Printf("assigning %s.%s to 'disaster-recovery' due to #107885", packageName, testName)
713-
match = []team.Team{dr}
714-
} else {
715-
log.Printf("assigning %s.%s to 'test-eng' as catch-all", packageName, testName)
716-
match = []team.Team{testEng}
717-
}
718-
}
719-
return match
720-
}
721-
722640
func formatPebbleMetamorphicIssue(
723641
ctx context.Context, f Failure,
724642
) (issues.IssueFormatter, issues.PostRequest) {

pkg/cmd/bazci/githubpost/githubpost_test.go

Lines changed: 23 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414

1515
bazelutil "github.com/cockroachdb/cockroach/pkg/build/util"
1616
"github.com/cockroachdb/cockroach/pkg/cmd/bazci/githubpost/issues"
17+
"github.com/cockroachdb/cockroach/pkg/internal/codeowners"
1718
"github.com/cockroachdb/cockroach/pkg/testutils/datapathutils"
1819
"github.com/stretchr/testify/assert"
1920
"github.com/stretchr/testify/require"
@@ -30,56 +31,35 @@ type issue struct {
3031
}
3132

3233
func init() {
33-
fileLineForTesting = map[packageAndTest]fileAndLine{
34+
codeowners.FileMapForTesting = map[codeowners.PackageAndTest]string{
3435
{
35-
packageName: "github.com/cockroachdb/cockroach/pkg/util/stop",
36-
testName: "TestStopperWithCancelConcurrent",
37-
}: {
38-
filename: "pkg/util/stop/stopper_test.go",
39-
linenum: "375",
40-
},
36+
PackageName: "github.com/cockroachdb/cockroach/pkg/util/stop",
37+
TestName: "TestStopperWithCancelConcurrent",
38+
}: "pkg/util/stop/stopper_test.go",
4139
{
42-
packageName: "github.com/cockroachdb/cockroach/pkg/kv/kvserver",
43-
testName: "TestReplicateQueueRebalance",
44-
}: {
45-
filename: "pkg/kv/kvserver/replicate_queue_test.go",
46-
linenum: "56",
47-
},
40+
PackageName: "github.com/cockroachdb/cockroach/pkg/kv/kvserver",
41+
TestName: "TestReplicateQueueRebalance",
42+
}: "pkg/kv/kvserver/replicate_queue_test.go",
4843
{
49-
packageName: "github.com/cockroachdb/cockroach/pkg/kv/kvserver",
50-
testName: "TestGossipHandlesReplacedNode",
51-
}: {
52-
filename: "pkg/kv/kvserver/gossip_test.go",
53-
linenum: "142",
54-
},
44+
PackageName: "github.com/cockroachdb/cockroach/pkg/kv/kvserver",
45+
TestName: "TestGossipHandlesReplacedNode",
46+
}: "pkg/kv/kvserver/gossip_test.go",
5547
{
56-
packageName: "github.com/cockroachdb/cockroach/pkg/util/json",
57-
testName: "TestPretty",
58-
}: {
59-
filename: "pkg/util/json/json_test.go",
60-
linenum: "2234",
61-
},
48+
PackageName: "github.com/cockroachdb/cockroach/pkg/util/json",
49+
TestName: "TestPretty",
50+
}: "pkg/util/json/json_test.go",
6251
{
63-
packageName: "github.com/cockroachdb/cockroach/pkg/util/json",
64-
testName: "TestJSONErrors",
65-
}: {
66-
filename: "pkg/util/json/json_test.go",
67-
linenum: "249",
68-
},
52+
PackageName: "github.com/cockroachdb/cockroach/pkg/util/json",
53+
TestName: "TestJSONErrors",
54+
}: "pkg/util/json/json_test.go",
6955
{
70-
packageName: "github.com/cockroachdb/cockroach/pkg/kv/kvclient/kvcoord",
71-
testName: "TestTxnCoordSenderPipelining",
72-
}: {
73-
filename: "pkg/kv/kvclient/kvcoord/txn_coord_sender_test.go",
74-
linenum: "2429",
75-
},
56+
PackageName: "github.com/cockroachdb/cockroach/pkg/kv/kvclient/kvcoord",
57+
TestName: "TestTxnCoordSenderPipelining",
58+
}: "pkg/kv/kvclient/kvcoord/txn_coord_sender_test.go",
7659
{
77-
packageName: "github.com/cockroachdb/cockroach/pkg/kv/kvclient/kvcoord",
78-
testName: "TestAbortReadOnlyTransaction",
79-
}: {
80-
filename: "pkg/kv/kvclient/kvcoord/txn_coord_sender_test.go",
81-
linenum: "1990",
82-
},
60+
PackageName: "github.com/cockroachdb/cockroach/pkg/kv/kvclient/kvcoord",
61+
TestName: "TestAbortReadOnlyTransaction",
62+
}: "pkg/kv/kvclient/kvcoord/txn_coord_sender_test.go",
8363
}
8464
}
8565

pkg/cmd/roachprod-microbench/BUILD.bazel

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,10 @@ go_test(
5959
"export_test.go",
6060
"github_test.go",
6161
],
62-
data = glob(["testdata/**"]),
62+
data = glob(["testdata/**"]) + [
63+
"//:TEAMS.yaml",
64+
"//.github:CODEOWNERS",
65+
],
6366
embed = [":roachprod-microbench_lib"],
6467
deps = [
6568
"//pkg/cmd/bazci/githubpost/issues",

0 commit comments

Comments
 (0)