Skip to content

Commit 962b295

Browse files
committed
chore: Fix some linter errors
1 parent e7d058d commit 962b295

3 files changed

Lines changed: 106 additions & 79 deletions

File tree

ctrf/ctrf.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,6 @@ func (summary *Summary) Validate() []error {
192192
testsSum := summary.Passed + summary.Failed + summary.Pending + summary.Skipped + summary.Other + summary.Flaky
193193
if summary.Tests != testsSum {
194194
errs = append(errs, fmt.Errorf("invalid summary counts: tests (%d) must be the sum of passed, failed, pending, skipped, and other (%d)", summary.Tests, testsSum))
195-
196195
}
197196
return errs
198197
}

reporter/reporter.go

Lines changed: 75 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,16 @@ type TestEvent struct {
2323
Output string
2424
}
2525

26+
const (
27+
ActionBuildOutput = "build-output"
28+
ActionBuildFail = "build-fail"
29+
ActionOutput = "output"
30+
ActionRun = "run"
31+
ActionPass = "pass"
32+
ActionFail = "fail"
33+
ActionSkip = "skip"
34+
)
35+
2636
var buildOutput []string
2737

2838
func ParseTestResults(r io.Reader, verbose bool, env *ctrf.Environment) (*ctrf.Report, error) {
@@ -33,6 +43,11 @@ func ParseTestResults(r io.Reader, verbose bool, env *ctrf.Environment) (*ctrf.R
3343
report.Results.Summary.Start = time.Now().UnixNano() / int64(time.Millisecond)
3444

3545
testStartTimes := make(map[string]int64)
46+
extraMap := make(map[string]any)
47+
buildOutputEvents := make([]TestEvent, 0)
48+
buildFailEvents := make([]TestEvent, 0)
49+
50+
report.Results.Extra = extraMap
3651

3752
for {
3853
var event TestEvent
@@ -44,56 +59,45 @@ func ParseTestResults(r io.Reader, verbose bool, env *ctrf.Environment) (*ctrf.R
4459
testEvents = append(testEvents, event)
4560

4661
if verbose {
47-
if event.Action == "build-output" || event.Action == "output" {
62+
if event.Action == ActionBuildOutput || event.Action == ActionOutput {
4863
fmt.Print(event.Output)
4964
}
5065
}
5166
}
5267

5368
for i, event := range testEvents {
69+
// If we see any test failures, mark an overall failure in the Extra fields
70+
if event.Action == ActionFail {
71+
extraMap["FailedBuild"] = true
72+
}
5473

55-
if event.Action == "build-output" || event.Action == "build-fail" || event.Action == "fail" {
56-
if report.Results.Extra == nil {
57-
report.Results.Extra = make(map[string]any)
58-
}
59-
extraMap, ok := report.Results.Extra.(map[string]any)
60-
if !ok {
61-
return nil, fmt.Errorf("expected a map, but got %T instead", report.Results.Extra)
62-
}
63-
64-
if event.Action == "fail" {
65-
if _, ok := extraMap["FailedBuild"]; !ok {
66-
extraMap["FailedBuild"] = true
67-
}
68-
}
74+
if event.Action == ActionBuildOutput {
75+
// Capture the full events to the extras
76+
buildOutputEvents = append(buildOutputEvents, event)
77+
extraMap["buildOutput"] = buildOutputEvents
6978

70-
if event.Action == "build-output" {
71-
if _, ok := extraMap["buildOutput"]; !ok {
72-
extraMap["buildOutput"] = []TestEvent{}
73-
}
74-
buildOutputEvents := extraMap["buildOutput"].([]TestEvent)
75-
extraMap["buildOutput"] = append(buildOutputEvents, event)
76-
buildOutput = append(buildOutput, event.Output)
77-
continue
78-
}
79+
// Capture the actual build output as well
80+
buildOutput = append(buildOutput, event.Output)
81+
continue
82+
}
7983

80-
if event.Action == "build-fail" {
81-
if _, ok := extraMap["buildFail"]; !ok {
82-
extraMap["buildFail"] = []TestEvent{}
83-
}
84-
buildFailEvents := extraMap["buildFail"].([]TestEvent)
85-
extraMap["buildFail"] = append(buildFailEvents, event)
86-
break
87-
}
84+
// Mark if we see a build failure in the extras field
85+
if event.Action == ActionBuildFail {
86+
buildFailEvents = append(buildFailEvents, event)
87+
extraMap["buildFail"] = buildFailEvents
88+
break
8889
}
8990

90-
if event.Action == "output" {
91+
if event.Action == ActionOutput {
9192
buildOutput = append(buildOutput, event.Output)
9293
}
9394

95+
// From this point, we only care about events associated with an actual test
9496
if event.Test == "" {
9597
continue
9698
}
99+
100+
// Parse timestamp data from the event
97101
eventTime, err := parseTimeString(event.Time)
98102
if err != nil {
99103
fmt.Fprintf(os.Stderr, "error parsing test event start time '%s' : %v\n", event.Time, err)
@@ -107,14 +111,14 @@ func ParseTestResults(r io.Reader, verbose bool, env *ctrf.Environment) (*ctrf.R
107111

108112
// If this is a "run" event, record the start time of the test. We'll look this up later when
109113
// we process the "pass"/"fail"/"skip" event for the test to create the TestResult
110-
if event.Action == "run" {
114+
if event.Action == ActionRun {
111115
testStartTimes[testNameKey(event.Package, event.Test)] = eventTime
112116
}
113117
}
114118

115119
// From this point on, we only deal with pass, fail, and skip events, which indicate that the
116120
// test has completed, and we can create/update a TestResult for it.
117-
if event.Action == "pass" || event.Action == "fail" || event.Action == "skip" {
121+
if event.Action == ActionPass || event.Action == ActionFail || event.Action == ActionSkip {
118122
// Look up the start time, and use this event's time as the endTime, to mark the start/stop times
119123
// for the test result. Duration we get from the event.Elapsed field, which better takes into
120124
// account parallel tests, setup/teardown time, etc...
@@ -127,7 +131,7 @@ func ParseTestResults(r io.Reader, verbose bool, env *ctrf.Environment) (*ctrf.R
127131
// Determine the message for this test result. We only include messages on failures though,
128132
// per the CTRF spec, so if this is not a failure, we pass an empty string for the message.
129133
message := ""
130-
if event.Action == "fail" {
134+
if event.Action == ActionFail {
131135
message = getMessagesForTest(testEvents, i, event.Package, event.Test, startTime)
132136
}
133137

@@ -158,7 +162,7 @@ func ParseTestResults(r io.Reader, verbose bool, env *ctrf.Environment) (*ctrf.R
158162
return report, nil
159163
}
160164

161-
// addResult adds a new test result to the report, filling out all the relevant details
165+
// addResult adds a new test result to the report, filling out all the relevant details.
162166
func addResult(report *ctrf.Report, result *ctrf.TestResult) {
163167
// Update the overall test count in the Summary
164168
report.Results.Summary.Tests++
@@ -171,59 +175,63 @@ func addResult(report *ctrf.Report, result *ctrf.TestResult) {
171175
report.Results.Summary.Failed++
172176
case ctrf.TestSkipped:
173177
report.Results.Summary.Skipped++
178+
case ctrf.TestPending:
179+
report.Results.Summary.Pending++
180+
default:
181+
report.Results.Summary.Other++
174182
}
175183

176184
// Append the result to the report's results
177185
report.Results.Tests = append(report.Results.Tests, result)
178186
}
179187

180-
func updateResult(report *ctrf.Report, existing, new *ctrf.TestResult) {
188+
func updateResult(report *ctrf.Report, oldResult, newResult *ctrf.TestResult) {
181189
// If the existing result does not have a retries field, initialize it, and move the
182190
// results to the first RetryAttempts object
183-
if existing.RetryAttempts == nil {
184-
existing.Retries = 1
185-
existing.RetryAttempts = append(existing.RetryAttempts, ctrf.RetryAttempt{
191+
if oldResult.RetryAttempts == nil {
192+
oldResult.Retries = 1
193+
oldResult.RetryAttempts = append(oldResult.RetryAttempts, ctrf.RetryAttempt{
186194
Attempt: 1,
187-
Status: existing.Status,
188-
Message: existing.Message,
189-
Duration: existing.Duration,
190-
Start: existing.Start,
191-
Stop: existing.Stop,
195+
Status: oldResult.Status,
196+
Message: oldResult.Message,
197+
Duration: oldResult.Duration,
198+
Start: oldResult.Start,
199+
Stop: oldResult.Stop,
192200
})
193201
}
194202

195203
// If this is a pass after a failure, mark the test as flaky, not failed,
196204
// and update the summary counts accordingly
197-
if existing.Status == ctrf.TestFailed && new.Status == ctrf.TestPassed {
198-
existing.Flaky = true
205+
if oldResult.Status == ctrf.TestFailed && newResult.Status == ctrf.TestPassed {
206+
oldResult.Flaky = true
199207
report.Results.Summary.Flaky++
200208
report.Results.Summary.Failed--
201209
}
202210

203211
// Update the overall test status to match that of the new result
204-
existing.Status = new.Status
212+
oldResult.Status = newResult.Status
205213

206214
// Clear out the top-level message on the overall result, since the messages are in the retries
207-
existing.Message = ""
215+
oldResult.Message = ""
208216

209217
// Update the times of the overall test result
210-
existing.Duration += new.Duration
211-
if new.Stop > existing.Stop {
212-
existing.Stop = new.Stop
218+
oldResult.Duration += newResult.Duration
219+
if newResult.Stop > oldResult.Stop {
220+
oldResult.Stop = newResult.Stop
213221
}
214-
if new.Start < existing.Start {
215-
existing.Start = new.Start
222+
if newResult.Start < oldResult.Start {
223+
oldResult.Start = newResult.Start
216224
}
217225

218226
// Now add the new attempt to the retries
219-
existing.Retries++
220-
existing.RetryAttempts = append(existing.RetryAttempts, ctrf.RetryAttempt{
221-
Attempt: existing.Retries,
222-
Status: new.Status,
223-
Message: new.Message,
224-
Duration: new.Duration,
225-
Start: new.Start,
226-
Stop: new.Stop,
227+
oldResult.Retries++
228+
oldResult.RetryAttempts = append(oldResult.RetryAttempts, ctrf.RetryAttempt{
229+
Attempt: oldResult.Retries,
230+
Status: newResult.Status,
231+
Message: newResult.Message,
232+
Duration: newResult.Duration,
233+
Start: newResult.Start,
234+
Stop: newResult.Stop,
227235
})
228236
}
229237

@@ -234,11 +242,11 @@ func testNameKey(suite, name string) string {
234242

235243
func actionToTestResult(action string) ctrf.TestStatus {
236244
switch action {
237-
case "pass":
245+
case ActionPass:
238246
return ctrf.TestPassed
239-
case "fail":
247+
case ActionFail:
240248
return ctrf.TestFailed
241-
case "skip":
249+
case ActionSkip:
242250
return ctrf.TestSkipped
243251
default:
244252
return ctrf.TestOther
@@ -310,7 +318,7 @@ func getMessagesForTest(testEvents []TestEvent, index int, packageName, testName
310318
}
311319
}
312320

313-
if testEvents[i].Action == "output" {
321+
if testEvents[i].Action == ActionOutput {
314322
messages = append(messages, testEvents[i].Output)
315323
}
316324
}

reporter/reporter_test.go

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ func Test_Enrich_Reporter(t *testing.T) {
2121
Stop: 1740874081832,
2222
},
2323
}}}
24+
25+
//nolint:lll // The test inputs are raw strings taken from real test runs
2426
input := `{"Time":"2025-03-02T01:08:01.832222033+01:00","Action":"start","Package":"github.com/ctrf-io/go-ctrf-json-reporter/reporter"}
2527
{"Time":"2025-03-02T01:08:01.832309292+01:00","Action":"run","Package":"github.com/ctrf-io/go-ctrf-json-reporter/reporter","Test":"Test_Enrich_Reporter"}
2628
{"Time":"2025-03-02T01:08:01.832321979+01:00","Action":"output","Package":"github.com/ctrf-io/go-ctrf-json-reporter/reporter","Test":"Test_Enrich_Reporter","Output":"=== RUN Test_Enrich_Reporter\n"}
@@ -105,6 +107,8 @@ func Test_Enrich_ReporterWithUnorderedMessages(t *testing.T) {
105107
Stop: 1760718477126,
106108
},
107109
}}}
110+
111+
//nolint:lll // The test inputs are raw strings taken from real test runs
108112
input := `{"Time":"2025-10-17T12:27:57.126761-04:00","Action":"run","Package":"github.com/ctrf-io/go-ctrf-json-reporter/reporter","Test":"Test_Enrich_Reporter"}
109113
{"Time":"2025-10-17T12:27:57.126764-04:00","Action":"output","Package":"github.com/ctrf-io/go-ctrf-json-reporter/reporter","Test":"Test_Enrich_Reporter","Output":"=== RUN Test_Enrich_Reporter\n"}
110114
{"Time":"2025-10-17T12:27:57.126769-04:00","Action":"run","Package":"github.com/ctrf-io/go-ctrf-json-reporter/reporter","Test":"Test_Enrich_Reporter/Test1"}
@@ -156,6 +160,9 @@ func TestDetectFlakyTests(t *testing.T) {
156160
Start: 1775245677812, // The event timestamp of the first processed event
157161
Stop: 1775245679646, // The event timestamp of the last processed event
158162
},
163+
Extra: map[string]any{
164+
"FailedBuild": true,
165+
},
159166
Tests: []*ctrf.TestResult{
160167
{
161168
Name: "Test_Flaky_Pass",
@@ -177,12 +184,18 @@ func TestDetectFlakyTests(t *testing.T) {
177184
Duration: 150,
178185
Message: "",
179186
RetryAttempts: []ctrf.RetryAttempt{
180-
{Attempt: 1, Status: ctrf.TestFailed, Start: 1775245677863, Stop: 1775245677914, Duration: 50,
181-
Message: "=== RUN Test_Flaky_Fail\n flaky_test.go:21: This test is designed to fail.\n--- FAIL: Test_Flaky_Fail (0.05s)\n"},
182-
{Attempt: 2, Status: ctrf.TestFailed, Start: 1775245678350, Stop: 1775245678401, Duration: 50,
183-
Message: "=== RUN Test_Flaky_Fail\n flaky_test.go:21: This test is designed to fail.\n--- FAIL: Test_Flaky_Fail (0.05s)\n"},
184-
{Attempt: 3, Status: ctrf.TestFailed, Start: 1775245679196, Stop: 1775245679247, Duration: 50,
185-
Message: "=== RUN Test_Flaky_Fail\n flaky_test.go:21: This test is designed to fail.\n--- FAIL: Test_Flaky_Fail (0.05s)\n"},
187+
{
188+
Attempt: 1, Status: ctrf.TestFailed, Start: 1775245677863, Stop: 1775245677914, Duration: 50,
189+
Message: "=== RUN Test_Flaky_Fail\n flaky_test.go:21: This test is designed to fail.\n--- FAIL: Test_Flaky_Fail (0.05s)\n",
190+
},
191+
{
192+
Attempt: 2, Status: ctrf.TestFailed, Start: 1775245678350, Stop: 1775245678401, Duration: 50,
193+
Message: "=== RUN Test_Flaky_Fail\n flaky_test.go:21: This test is designed to fail.\n--- FAIL: Test_Flaky_Fail (0.05s)\n",
194+
},
195+
{
196+
Attempt: 3, Status: ctrf.TestFailed, Start: 1775245679196, Stop: 1775245679247, Duration: 50,
197+
Message: "=== RUN Test_Flaky_Fail\n flaky_test.go:21: This test is designed to fail.\n--- FAIL: Test_Flaky_Fail (0.05s)\n",
198+
},
186199
},
187200
},
188201
{
@@ -204,15 +217,21 @@ func TestDetectFlakyTests(t *testing.T) {
204217
Start: 1775245677914,
205218
Stop: 1775245679646,
206219
RetryAttempts: []ctrf.RetryAttempt{
207-
{Attempt: 1, Status: ctrf.TestFailed, Duration: 50, Start: 1775245677914, Stop: 1775245677967,
208-
Message: "=== RUN Test_Flaky_Flaky\n flaky_test.go:37: Flaky Failure (attempt 1)\n--- FAIL: Test_Flaky_Flaky (0.05s)\n"},
209-
{Attempt: 2, Status: ctrf.TestFailed, Duration: 50, Start: 1775245678784, Stop: 1775245678837,
210-
Message: "=== RUN Test_Flaky_Flaky\n flaky_test.go:54: Flaky Failure (attempt 2)\n--- FAIL: Test_Flaky_Flaky (0.05s)\n"},
220+
{
221+
Attempt: 1, Status: ctrf.TestFailed, Duration: 50, Start: 1775245677914, Stop: 1775245677967,
222+
Message: "=== RUN Test_Flaky_Flaky\n flaky_test.go:37: Flaky Failure (attempt 1)\n--- FAIL: Test_Flaky_Flaky (0.05s)\n",
223+
},
224+
{
225+
Attempt: 2, Status: ctrf.TestFailed, Duration: 50, Start: 1775245678784, Stop: 1775245678837,
226+
Message: "=== RUN Test_Flaky_Flaky\n flaky_test.go:54: Flaky Failure (attempt 2)\n--- FAIL: Test_Flaky_Flaky (0.05s)\n",
227+
},
211228
{Attempt: 3, Status: ctrf.TestPassed, Duration: 50, Start: 1775245679595, Stop: 1775245679646},
212229
},
213230
},
214-
}}}
231+
},
232+
}}
215233

234+
//nolint:lll // The test inputs are raw strings taken from real test runs
216235
input := `{"Time":"2026-04-03T13:47:57.561046-06:00","Action":"start","Package":"github.com/ctrf-io/go-ctrf-json-reporter/examples/flaky"}
217236
{"Time":"2026-04-03T13:47:57.812415-06:00","Action":"run","Package":"github.com/ctrf-io/go-ctrf-json-reporter/examples/flaky","Test":"Test_Flaky_Pass"}
218237
{"Time":"2026-04-03T13:47:57.812541-06:00","Action":"output","Package":"github.com/ctrf-io/go-ctrf-json-reporter/examples/flaky","Test":"Test_Flaky_Pass","Output":"=== RUN Test_Flaky_Pass\n"}
@@ -277,4 +296,5 @@ func TestDetectFlakyTests(t *testing.T) {
277296
require.NoError(t, err)
278297
assert.Equal(t, expected.Results.Summary, actual.Results.Summary)
279298
assert.Equal(t, expected.Results.Tests, actual.Results.Tests)
299+
assert.Equal(t, expected.Results.Extra, actual.Results.Extra)
280300
}

0 commit comments

Comments
 (0)