Skip to content

Commit

Permalink
feat: Add buildURL in JSON report (#848)
Browse files Browse the repository at this point in the history
* feat: Add buildURL in JSON report

* refact reporter

* make buildURL omitempty

* refine

* add cached build url

* re-structure the CloudRunner structure

* change log level

* Update internal/saucecloud/cloud.go

Co-authored-by: Alex Plischke <[email protected]>

* rename CachedData to Cache

---------

Co-authored-by: Alex Plischke <[email protected]>
  • Loading branch information
tianfeng92 and alexplischke authored Nov 2, 2023
1 parent 5121075 commit 5a44562
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 36 deletions.
2 changes: 1 addition & 1 deletion internal/cmd/run/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ func createReporters(c config.Reporters, ntfs config.Notifications, metadata con
}
}

buildReporter := buildtable.New(buildReader)
buildReporter := buildtable.New()
reps = append(reps, &buildReporter)

reps = append(reps, &slack.Reporter{
Expand Down
44 changes: 9 additions & 35 deletions internal/report/buildtable/buildtable.go
Original file line number Diff line number Diff line change
@@ -1,30 +1,24 @@
package buildtable

import (
"context"
"fmt"
"net/url"
"os"
"strings"

"github.com/fatih/color"
"github.com/rs/zerolog/log"
"github.com/saucelabs/saucectl/internal/build"
"github.com/saucelabs/saucectl/internal/report"
"github.com/saucelabs/saucectl/internal/report/table"
)

// Reporter is an implementation of report.Reporter
// It wraps a table reporter and decorates it with additional metadata
type Reporter struct {
Service build.Reader
VDCTableReport table.Reporter
RDCTableReport table.Reporter
}

func New(svc build.Reader) Reporter {
func New() Reporter {
return Reporter{
Service: svc,
VDCTableReport: table.Reporter{
Dst: os.Stdout,
},
Expand All @@ -49,18 +43,16 @@ func (r *Reporter) Render() {
printTitle()
printPadding(2)

var jURL string
var bURL string
if len(r.VDCTableReport.TestResults) > 0 {
r.VDCTableReport.Render()

for _, tr := range r.VDCTableReport.TestResults {
if tr.URL != "" {
jURL = tr.URL
var bURL string
for _, result := range r.VDCTableReport.TestResults {
if result.BuildURL != "" {
bURL = result.BuildURL
break
}
}
bURL = r.buildURLFromJobURL(jURL, build.VDC)

if bURL == "" {
bURL = "N/A"
Expand All @@ -72,13 +64,13 @@ func (r *Reporter) Render() {
if len(r.RDCTableReport.TestResults) > 0 {
r.RDCTableReport.Render()

for _, tr := range r.RDCTableReport.TestResults {
if tr.URL != "" {
jURL = tr.URL
var bURL string
for _, result := range r.RDCTableReport.TestResults {
if result.BuildURL != "" {
bURL = result.BuildURL
break
}
}
bURL = r.buildURLFromJobURL(jURL, build.RDC)

if bURL == "" {
bURL = "N/A"
Expand All @@ -100,24 +92,6 @@ func (r *Reporter) ArtifactRequirements() []report.ArtifactType {
return nil
}

func (r *Reporter) buildURLFromJobURL(jobURL string, buildSource build.Source) string {
pURL, err := url.Parse(jobURL)
if err != nil {
log.Debug().Err(err).Msgf("Failed to parse job url (%s)", jobURL)
return ""
}
p := strings.Split(pURL.Path, "/")
jID := p[len(p)-1]

bID, err := r.Service.GetBuildID(context.Background(), jID, buildSource)
if err != nil {
log.Debug().Err(err).Msgf("Failed to retrieve build id for job (%s)", jID)
return ""
}

return fmt.Sprintf("%s://%s/builds/%s/%s", pURL.Scheme, pURL.Host, buildSource, bID)
}

func printPadding(repeat int) {
fmt.Print(strings.Repeat("\n", repeat))
}
Expand Down
1 change: 1 addition & 0 deletions internal/report/report.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ type TestResult struct {
URL string `json:"url"`
Artifacts []Artifact `json:"artifacts,omitempty"`
Origin string `json:"origin"`
BuildURL string `json:"buildURL,omitempty"`
RDC bool `json:"-"`
TimedOut bool `json:"-"`
PassThreshold bool `json:"-"`
Expand Down
37 changes: 37 additions & 0 deletions internal/saucecloud/cloud.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ type CloudRunner struct {
NPMDependencies []string

interrupted bool
Cache Cache
}

type Cache struct {
VDCBuildURL string
RDCBuildURL string
}

type result struct {
Expand Down Expand Up @@ -155,6 +161,7 @@ func (r *CloudRunner) collectResults(artifactCfg config.ArtifactDownload, result
if res.job.ID != "" {
url = fmt.Sprintf("%s/tests/%s", r.Region.AppBaseURL(), res.job.ID)
}
buildURL := r.getBuildURL(res.job.ID, res.job.IsRDC)
tr := report.TestResult{
Name: res.name,
Duration: res.duration,
Expand All @@ -170,6 +177,7 @@ func (r *CloudRunner) collectResults(artifactCfg config.ArtifactDownload, result
RDC: res.job.IsRDC,
TimedOut: res.job.TimedOut,
Attempts: res.attempts,
BuildURL: buildURL,
}
for _, rep := range r.Reporters {
rep.Add(tr)
Expand All @@ -195,6 +203,35 @@ func (r *CloudRunner) collectResults(artifactCfg config.ArtifactDownload, result
return passed
}

func (r *CloudRunner) getBuildURL(jobID string, isRDC bool) string {
var buildSource build.Source
if !isRDC {
if r.Cache.VDCBuildURL != "" {
return r.Cache.VDCBuildURL
}
buildSource = build.VDC
} else {
if r.Cache.RDCBuildURL != "" {
return r.Cache.RDCBuildURL
}
buildSource = build.RDC
}

bID, err := r.BuildService.GetBuildID(context.Background(), jobID, buildSource)
if err != nil {
log.Warn().Err(err).Msgf("Failed to retrieve build id for job (%s)", jobID)
return ""
}

bURL := fmt.Sprintf("%s/builds/%s/%s", r.Region.AppBaseURL(), buildSource, bID)
if !isRDC {
r.Cache.VDCBuildURL = bURL
} else {
r.Cache.RDCBuildURL = bURL
}
return bURL
}

func (r *CloudRunner) runJob(opts job.StartOptions) (j job.Job, skipped bool, err error) {
log.Info().Str("suite", opts.DisplayName).Str("region", r.Region.String()).Msg("Starting suite.")

Expand Down

0 comments on commit 5a44562

Please sign in to comment.