@@ -66,20 +66,118 @@ ok go.temporal.io/server/tests
6666 })
6767}
6868
69+ func alertsOfKind (alerts []alert , kind alertKind ) []alert {
70+ var out []alert
71+ for _ , a := range alerts {
72+ if a .Kind == kind {
73+ out = append (out , a )
74+ }
75+ }
76+ return out
77+ }
78+
79+ func TestParseAssertionFailures (t * testing.T ) {
80+ t .Run ("SingleFailure" , func (t * testing.T ) {
81+ stdout := `=== RUN TestFoo
82+ --- FAIL: TestFoo (0.01s)
83+ foo_test.go:42: Error Trace: foo_test.go:42
84+ foo_test.go:42: Error: Not equal
85+ foo_test.go:42: expected: 1
86+ foo_test.go:42: actual : 2
87+ FAIL
88+ `
89+ failures := parseAssertionFailures (stdout )
90+ require .Len (t , failures , 1 )
91+ require .Equal (t , "TestFoo" , failures [0 ].Summary )
92+ // Details holds the body without the timing-variant header line.
93+ require .NotContains (t , failures [0 ].Details , "--- FAIL:" )
94+ require .Contains (t , failures [0 ].Details , "Not equal" )
95+ })
96+
97+ t .Run ("MultipleFailures" , func (t * testing.T ) {
98+ stdout := `--- FAIL: TestFoo (0.01s)
99+ foo_test.go:10: first failure
100+ --- FAIL: TestBar (0.02s)
101+ bar_test.go:20: second failure
102+ FAIL
103+ `
104+ failures := parseAssertionFailures (stdout )
105+ require .Len (t , failures , 2 )
106+ require .Equal (t , "TestFoo" , failures [0 ].Summary )
107+ require .Equal (t , "TestBar" , failures [1 ].Summary )
108+ require .Contains (t , failures [0 ].Details , "first failure" )
109+ require .Contains (t , failures [1 ].Details , "second failure" )
110+ })
111+
112+ t .Run ("SubtestName" , func (t * testing.T ) {
113+ stdout := `--- FAIL: TestSuite/TestCase (0.00s)
114+ foo_test.go:5: assertion error
115+ FAIL
116+ `
117+ failures := parseAssertionFailures (stdout )
118+ require .Len (t , failures , 1 )
119+ require .Equal (t , "TestSuite/TestCase" , failures [0 ].Summary )
120+ })
121+
122+ t .Run ("StopsAtNextFailBlock" , func (t * testing.T ) {
123+ stdout := `--- FAIL: TestA (0.01s)
124+ a_test.go:1: only A's output
125+ --- FAIL: TestB (0.01s)
126+ b_test.go:2: only B's output
127+ FAIL
128+ `
129+ failures := parseAssertionFailures (stdout )
130+ require .Len (t , failures , 2 )
131+ require .NotContains (t , failures [0 ].Details , "only B's output" )
132+ require .NotContains (t , failures [1 ].Details , "only A's output" )
133+ })
134+
135+ t .Run ("PanicBodyCaptured" , func (t * testing.T ) {
136+ // When a test panics, "--- FAIL:" precedes the panic output. Because
137+ // parseAssertionFailures runs independently from parseAlerts, the panic
138+ // content appears in both the ASSERTION FAILURE and PANIC sections.
139+ stdout := `--- FAIL: TestPanic (0.00s)
140+ panic: something bad
141+ goroutine 1 [running]:
142+ FAIL
143+ `
144+ failures := parseAssertionFailures (stdout )
145+ require .Len (t , failures , 1 )
146+ require .Equal (t , "TestPanic" , failures [0 ].Summary )
147+ require .Contains (t , failures [0 ].Details , "panic: something bad" )
148+ })
149+
150+ t .Run ("NoFailures" , func (t * testing.T ) {
151+ stdout := `=== RUN TestPass
152+ --- PASS: TestPass (0.00s)
153+ ok go.temporal.io/server/tests 0.1s
154+ `
155+ require .Empty (t , parseAssertionFailures (stdout ))
156+ })
157+
158+ t .Run ("EmptyInput" , func (t * testing.T ) {
159+ require .Empty (t , parseAssertionFailures ("" ))
160+ })
161+ }
162+
69163func TestParseAlerts_DataRaceAndPanic (t * testing.T ) {
70164 input , err := os .ReadFile ("testdata/alerts-input.log" )
71165 require .NoError (t , err )
72166
73167 alerts := parseAlerts (string (input ))
74168 require .NotEmpty (t , alerts )
75- require .Equal (t , 2 , len (alerts ))
76-
77- require .Contains (t , alerts [0 ].Details , "WARNING: DATA RACE" )
78- require .Contains (t , alerts [0 ].Tests [0 ], "test.TestDataRaceExample" )
79- require .Contains (t , primaryTestName (alerts [0 ].Tests ), "test.TestDataRaceExample" )
80- require .Contains (t , alerts [1 ].Details , "panic: " )
81- require .Contains (t , alerts [1 ].Tests [0 ], "test.TestPanicExample" )
82- require .Contains (t , primaryTestName (alerts [1 ].Tests ), "TestPanicExample" )
169+
170+ raceAlerts := alertsOfKind (alerts , alertKindDataRace )
171+ require .Len (t , raceAlerts , 1 )
172+ require .Contains (t , raceAlerts [0 ].Details , "WARNING: DATA RACE" )
173+ require .Contains (t , raceAlerts [0 ].Tests [0 ], "test.TestDataRaceExample" )
174+ require .Contains (t , primaryTestName (raceAlerts [0 ].Tests ), "test.TestDataRaceExample" )
175+
176+ panicAlerts := alertsOfKind (alerts , alertKindPanic )
177+ require .Len (t , panicAlerts , 1 )
178+ require .Contains (t , panicAlerts [0 ].Details , "panic: " )
179+ require .Contains (t , panicAlerts [0 ].Tests [0 ], "test.TestPanicExample" )
180+ require .Contains (t , primaryTestName (panicAlerts [0 ].Tests ), "TestPanicExample" )
83181
84182 // Ensure dedupe works
85183 deduped := dedupeAlerts (append (alerts , alerts ... ))
0 commit comments