Skip to content

[CI] Refactor testsreporter tool #13411

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Apr 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion dev/testsreporter/_static/summary.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
- {{ . }}
{{- end }}
{{ end -}}
{{ if ne (len .owners) 0 -}}
{{ if and (ne .owners nil) (ne (len .owners) 0) -}}
- Owners:
{{- range .owners }}
- {{ . }}
Expand Down
57 changes: 15 additions & 42 deletions dev/testsreporter/builderror.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
package testsreporter

import (
"fmt"
"strings"
)

Expand All @@ -14,14 +13,6 @@ const (
buildReportingTeamLabel = "Team:Ecosystem"
)

type dataError struct {
errorLinks
serverless bool
serverlessProject string
logsDB bool
stackVersion string
}

type buildError struct {
dataError
teams []string
Expand Down Expand Up @@ -65,53 +56,35 @@ func newBuildError(options buildErrorOptions) (*buildError, error) {
func (b *buildError) String() string {
var sb strings.Builder

if b.logsDB {
sb.WriteString("[LogsDB] ")
}
if b.serverless {
sb.WriteString(fmt.Sprintf("[Serverless %s] ", b.serverlessProject))
}
if b.stackVersion != "" {
sb.WriteString("[Stack ")
sb.WriteString(b.stackVersion)
sb.WriteString("] ")
}
sb.WriteString(b.dataError.String())
sb.WriteString("Too many packages failing in daily job")

return sb.String()
}

func (p *buildError) FirstBuild() string {
return p.errorLinks.firstBuild
func (b *buildError) FirstBuild() string {
return b.errorLinks.firstBuild
}

func (p *buildError) UpdateLinks(links errorLinks) {
p.errorLinks = links
func (b *buildError) UpdateLinks(links errorLinks) {
b.errorLinks = links
}

func (p *buildError) Teams() []string {
return p.teams
func (b *buildError) Teams() []string {
return b.teams
}

func (p *buildError) SummaryData() map[string]any {
return map[string]any{
"stackVersion": p.stackVersion,
"serverless": p.serverless,
"serverlessProject": p.serverlessProject,
"logsDB": p.logsDB,
"packages": p.packages,
"owners": p.teams,
}
func (b *buildError) SummaryData() map[string]any {
data := b.dataError.Data()
data["packages"] = b.packages
data["owners"] = b.teams
return data
}

func (p *buildError) DescriptionData() map[string]any {
return map[string]any{
"firstBuild": p.errorLinks.firstBuild,
"closedIssueURL": p.errorLinks.closedIssueURL,
"previousBuilds": p.errorLinks.previousBuilds,
}
func (b *buildError) DescriptionData() map[string]any {
return b.errorLinks.Data()
}

func (p *buildError) Labels() []string {
func (b *buildError) Labels() []string {
return []string{buildReportingTeamLabel}
}
44 changes: 44 additions & 0 deletions dev/testsreporter/dataerror.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
// or more contributor license agreements. Licensed under the Elastic License;
// you may not use this file except in compliance with the Elastic License.

package testsreporter

import (
"fmt"
"strings"
)

type dataError struct {
errorLinks
serverless bool
serverlessProject string
logsDB bool
stackVersion string
}

func (d *dataError) String() string {
var sb strings.Builder

if d.logsDB {
sb.WriteString("[LogsDB] ")
}
if d.serverless {
sb.WriteString(fmt.Sprintf("[Serverless %s] ", d.serverlessProject))
}
if d.stackVersion != "" {
sb.WriteString("[Stack ")
sb.WriteString(d.stackVersion)
sb.WriteString("] ")
}
return sb.String()
}

func (d *dataError) Data() map[string]any {
return map[string]any{
"stackVersion": d.stackVersion,
"serverless": d.serverless,
"serverlessProject": d.serverlessProject,
"logsDB": d.logsDB,
}
}
20 changes: 20 additions & 0 deletions dev/testsreporter/errorlinks.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
// or more contributor license agreements. Licensed under the Elastic License;
// you may not use this file except in compliance with the Elastic License.

package testsreporter

type errorLinks struct {
currentIssueURL string
firstBuild string
previousBuilds []string
closedIssueURL string
}

func (e *errorLinks) Data() map[string]any {
return map[string]any{
"firstBuild": e.firstBuild,
"closedIssueURL": e.closedIssueURL,
"previousBuilds": e.previousBuilds,
}
}
13 changes: 4 additions & 9 deletions dev/testsreporter/format_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func TestSummary(t *testing.T) {
`,
},
{
title: "summary stack version with owners wihtout data stream",
title: "summary stack version with owners without data stream",
resultError: &packageError{
dataError: dataError{
stackVersion: "8.14",
Expand Down Expand Up @@ -181,14 +181,12 @@ func TestSummary(t *testing.T) {
func TestDescription(t *testing.T) {
cases := []struct {
title string
summary string
resultError failureObserver
maxLinks int
expected string
}{
{
title: "description error all fields",
summary: "summary",
title: "description error all fields",
resultError: &packageError{
dataError: dataError{
stackVersion: "8.14",
Expand Down Expand Up @@ -226,8 +224,7 @@ Latest failed builds:
`,
},
{
title: "description failure all fields",
summary: "summary",
title: "description failure all fields",
resultError: &packageError{
dataError: dataError{
stackVersion: "8.14",
Expand Down Expand Up @@ -265,8 +262,7 @@ Latest failed builds:
`,
},
{
title: "description no closed issue",
summary: "summary",
title: "description no closed issue",
resultError: &packageError{
dataError: dataError{
stackVersion: "8.14",
Expand Down Expand Up @@ -302,7 +298,6 @@ Latest failed builds:
},
{
title: "description max links",
summary: "summary",
maxLinks: 2,
resultError: &packageError{
dataError: dataError{
Expand Down
46 changes: 11 additions & 35 deletions dev/testsreporter/packageerror.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,6 @@ import (
"github.com/elastic/integrations/dev/codeowners"
)

type errorLinks struct {
currentIssueURL string
firstBuild string
previousBuilds []string
closedIssueURL string
}

type packageError struct {
testCase
dataError
Expand Down Expand Up @@ -88,17 +81,7 @@ func (p *packageError) Teams() []string {
func (p *packageError) String() string {
var sb strings.Builder

if p.logsDB {
sb.WriteString("[LogsDB] ")
}
if p.serverless {
sb.WriteString(fmt.Sprintf("[Serverless %s] ", p.serverlessProject))
}
if p.stackVersion != "" {
sb.WriteString("[Stack ")
sb.WriteString(p.stackVersion)
sb.WriteString("] ")
}
sb.WriteString(p.dataError.String())
sb.WriteString("[")
sb.WriteString(p.packageName)
sb.WriteString("] ")
Expand All @@ -109,26 +92,19 @@ func (p *packageError) String() string {
}

func (p *packageError) SummaryData() map[string]any {
return map[string]any{
"stackVersion": p.stackVersion,
"serverless": p.serverless,
"serverlessProject": p.serverlessProject,
"logsDB": p.logsDB,
"packageName": p.packageName,
"testName": p.Name,
"dataStream": p.dataStream,
"owners": p.teams,
}
data := p.dataError.Data()
data["packageName"] = p.packageName
data["testName"] = p.Name
data["dataStream"] = p.dataStream
data["owners"] = p.teams
return data
}

func (p *packageError) DescriptionData() map[string]any {
return map[string]any{
"failure": truncateText(p.Failure, defaultMaxLengthMessages),
"error": truncateText(p.Error, defaultMaxLengthMessages),
"firstBuild": p.errorLinks.firstBuild,
"closedIssueURL": p.errorLinks.closedIssueURL,
"previousBuilds": p.errorLinks.previousBuilds,
}
data := p.errorLinks.Data()
data["failure"] = truncateText(p.Failure, defaultMaxLengthMessages)
data["error"] = truncateText(p.Error, defaultMaxLengthMessages)
return data
}

func (p *packageError) Labels() []string {
Expand Down
20 changes: 17 additions & 3 deletions dev/testsreporter/reporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,20 @@ import (
type reporter struct {
ghCli *ghCli
maxPreviousLinks int
verbose bool
}

func newReporter(ghCli *ghCli, maxPreviousLinks int) reporter {
type reporterOptions struct {
GhCli *ghCli
MaxPreviousLinks int
Verbose bool
}

func newReporter(options reporterOptions) reporter {
return reporter{
ghCli: ghCli,
maxPreviousLinks: maxPreviousLinks,
ghCli: options.GhCli,
maxPreviousLinks: options.MaxPreviousLinks,
verbose: options.Verbose,
}
}

Expand Down Expand Up @@ -57,6 +65,12 @@ func (r reporter) Report(ctx context.Context, issue *githubIssue, resultError fa
fmt.Printf("Summary:\n%s", summary)
fmt.Println("----")
fmt.Println()
if r.verbose {
fmt.Println("---- Full Description ----")
fmt.Print(description)
fmt.Println("----")
fmt.Println()
}

return r.createOrUpdateIssue(ctx, nextIssue)
}
Expand Down
5 changes: 4 additions & 1 deletion dev/testsreporter/reporter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,10 @@ func TestReporterUpdateLinks(t *testing.T) {
Runner: &runner,
})

reporter := newReporter(ghCli, 5)
reporter := newReporter(reporterOptions{
GhCli: ghCli,
MaxPreviousLinks: 5,
})

links, newIssue, err := reporter.updateLinks(context.Background(), c.issue, c.firstBuild)
require.NoError(t, err)
Expand Down
13 changes: 9 additions & 4 deletions dev/testsreporter/testsreporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ type CheckOptions struct {
MaxPreviousLinks int
MaxTestsReported int

DryRun bool
DryRun bool
Verbose bool
}

func Check(ctx context.Context, resultsPath string, options CheckOptions) error {
Expand All @@ -49,11 +50,15 @@ func Check(ctx context.Context, resultsPath string, options CheckOptions) error
DryRun: options.DryRun,
})

aReporter := newReporter(ghCli, options.MaxPreviousLinks)
aReporter := newReporter(reporterOptions{
GhCli: ghCli,
MaxPreviousLinks: options.MaxPreviousLinks,
Verbose: options.Verbose,
})

if len(packageErrors) > options.MaxTestsReported {
fmt.Printf("Skip creating GitHub issues, hit the maximum number (%d) of tests to be reported. Total failing tests: %d.\n", options.MaxTestsReported, len(packageErrors))
packages, err := packagesFromTests(resultsPath, options)
packages, err := packagesFromTests(resultsPath)
if err != nil {
return fmt.Errorf("failed to get packages from results files: %w", err)
}
Expand Down Expand Up @@ -137,7 +142,7 @@ func errorsFromTests(resultsPath string, options CheckOptions) ([]*packageError,
}

// packagesFromTests returns the sorted packages failing given the results file
func packagesFromTests(resultsPath string, options CheckOptions) ([]string, error) {
func packagesFromTests(resultsPath string) ([]string, error) {
packages := []string{}
err := filepath.Walk(resultsPath, func(path string, info os.FileInfo, err error) error {
if err != nil {
Expand Down
6 changes: 6 additions & 0 deletions magefile.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,11 @@ func ReportFailedTests(ctx context.Context, testResultsFolder string) error {
logsDBEnabled = true
}

verboseMode := false
if v, found := os.LookupEnv("VERBOSE_MODE_ENABLED"); found && v == "true" {
verboseMode = true
}

maxIssuesString := os.Getenv("CI_MAX_TESTS_REPORTED")
maxIssues := defaultMaximumTestsReported
if maxIssuesString != "" {
Expand Down Expand Up @@ -201,6 +206,7 @@ func ReportFailedTests(ctx context.Context, testResultsFolder string) error {
MaxPreviousLinks: defaultPreviousLinksNumber,
MaxTestsReported: maxIssues,
DryRun: dryRun,
Verbose: verboseMode,
}
return testsreporter.Check(ctx, testResultsFolder, options)
}