224
225
// tryParseDataRace parses a data race alert at position i if present.
226
>
func tryParseDataRace(lines []string, i int, line string) (alert, int, bool) {
log.go
227
>
if !strings.HasPrefix(line, "WARNING: DATA RACE") {
228
>
return alert{}, i, false
229
>
}
230
>
start := findRaceBlockStart(lines, i)
231
>
// Merge contiguous race-report sections into a single alert. The Go race
232
>
// detector may emit multiple "WARNING: DATA RACE" blocks back-to-back,
233
>
// each wrapped by a line of ==================. Treat adjacent sections as
234
>
// a single logical alert until we either hit a test boundary or a race
235
>
// boundary that is not followed by another race section.
236
>
block, end := collectBlock(lines, start, func(curLine string, idx, start int) bool {
237
>
// Stop at PASS/FAIL boundaries always.
238
>
if isTestResultBoundary(curLine) {
239
return true
240
}
241
// If we hit a race boundary after we've started, only stop if the next
242
// non-current line does not continue the race report.
243
>
if idx > start && isRaceBoundary(curLine) {
log.go
244
>
if idx+1 < len(lines) {
245
>
next := strings.TrimSpace(lines[idx+1])
246
>
if isRaceBoundary(next) || strings.HasPrefix(next, "WARNING: DATA RACE") {
247
>
return false
248
>
}
249
}
251
}
253
})
255
>
Type: failureTypeDataRace,
256
>
Summary: "Data race detected",
257
>
Details: block,
258
>
Tests: extractTestNames(block),
259
>
}, end, true
260
}
261
262
// tryParsePanic parses a non-timeout panic alert at position i if present.
263
>
func tryParsePanic(lines []string, i int, line string) (alert, int, bool) {
log.go
264
>
if !strings.HasPrefix(line, "panic: ") || strings.HasPrefix(line, "panic: test timed out after") {
265
>
return alert{}, i, false
266
>
}
267
>
block, end := collectBlock(lines, i, shouldStopOnTestBoundary)
268
>
return alert{
269
>
Type: failureTypePanic,
270
>
Summary: strings.TrimSpace(strings.TrimPrefix(line, "panic: ")),
271
>
Details: block,
272
>
Tests: extractTestNames(block),
273
>
}, end, true
274
}
275
276
// tryParseFatal parses a runtime fatal error alert at position i if present.
277
>
func tryParseFatal(lines []string, i int, line string) (alert, int, bool) {
log.go
278
>
if !strings.HasPrefix(line, "fatal error: ") {
279
>
return alert{}, i, false
280
>
}
281
block, end := collectBlock(lines, i, shouldStopOnTestBoundary)
282
return alert{