Skip to content

Commit 5dade7c

Browse files
authored
Merge pull request #158710 from rickystewart/blathers/backport-release-25.2-158548
release-25.2: codeowners: extract GetTestOwner function into new public helper method
2 parents 0985ac1 + 197fd3e commit 5dade7c

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

@@ -448,21 +454,22 @@ func listFailuresFromJSON(
448454
// 2) Otherwise, we don't blame anybody in particular. We file a generic issue
449455
// listing the package name containing the report of long-running tests.
450456
if timedOutCulprit.name != "" {
457+
initCo()
451458
slowest := slowFailEvents[0]
452459
if len(slowPassEvents) > 0 && slowPassEvents[0].Elapsed > slowest.Elapsed {
453460
slowest = slowPassEvents[0]
454461
}
455462

456-
culpritOwner := fmt.Sprintf("%v", getOwner(ctx, timedOutCulprit.pkg, timedOutCulprit.name))
463+
culpritOwner, _ := co.GetTestOwner(timedOutCulprit.pkg, timedOutCulprit.name)
457464
slowEvents := append(slowFailEvents, slowPassEvents...)
458465
// The predicate determines if the union of the slow events is owned by the _same_ team(s) as timedOutCulprit.
459466
hasSameOwner := func() bool {
460467
for _, slowEvent := range slowEvents {
461468
scopedEvent := scoped(slowEvent)
462-
owner := fmt.Sprintf("%v", getOwner(ctx, scopedEvent.pkg, scopedEvent.name))
469+
owner, _ := co.GetTestOwner(scopedEvent.pkg, scopedEvent.name)
463470

464-
if culpritOwner != owner {
465-
log.Printf("%v has a different owner: %s;bailing out...\n", scopedEvent, owner)
471+
if len(culpritOwner) < 1 || len(owner) < 1 || culpritOwner[0].TeamName != owner[0].TeamName {
472+
log.Printf("%v has a different owner: %v;bailing out...\n", scopedEvent, owner)
466473
return false
467474
}
468475
}
@@ -623,95 +630,6 @@ func writeSlowTestsReport(report string) error {
623630
return os.WriteFile("artifacts/slow-tests-report.txt", []byte(report), 0644)
624631
}
625632

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

0 commit comments

Comments
 (0)