Skip to content

Commit

Permalink
fix: parsing one-line JUnit reports
Browse files Browse the repository at this point in the history
  • Loading branch information
devcatalin committed Sep 30, 2024
1 parent 2c60416 commit d304e01
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 27 deletions.
37 changes: 14 additions & 23 deletions cmd/testworkflow-toolkit/artifacts/junit_post_processor.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package artifacts

import (
"bufio"
"bytes"
"context"
"fmt"
"io"
Expand Down Expand Up @@ -63,10 +61,7 @@ func (p *JUnitPostProcessor) Add(path string) error {
if err != nil {
return errors.Wrapf(err, "failed to read %s", path)
}
ok, err := isJUnitReport(xmlData)
if err != nil {
return errors.Wrapf(err, "failed to check if %s is a JUnit report", path)
}
ok := isJUnitReport(xmlData)
if !ok {
return nil
}
Expand Down Expand Up @@ -104,33 +99,29 @@ func isXMLFile(stat fs.FileInfo) bool {
return strings.HasSuffix(stat.Name(), ".xml")
}

// isJUnitReport checks if the file starts with a JUnit XML tag
func isJUnitReport(xmlData []byte) (bool, error) {
// isJUnitReport checks if the XML data is a JUnit report.
func isJUnitReport(xmlData []byte) bool {
const BYTE_SIZE_8KB = 8 * 1024

// Limit check to first 8KB
tags := []string{
"<?xml",
"<testsuite",
"<testsuites",
}

if len(xmlData) > BYTE_SIZE_8KB {
xmlData = xmlData[:BYTE_SIZE_8KB]
}

scanner := bufio.NewScanner(bytes.NewReader(xmlData))
for scanner.Scan() {
line := strings.TrimSpace(scanner.Text())
line = strings.TrimSpace(line) // Remove leading and trailing whitespace
content := string(xmlData)

// Skip comments and declarations
if strings.HasPrefix(line, "<!--") || strings.HasPrefix(line, "<?xml") {
continue
}
if strings.Contains(line, "<testsuite") || strings.Contains(line, "<testsuites") {
return true, nil
}
if strings.Contains(line, "<") { // Stop if any non-JUnit tag is found
break
for _, tag := range tags {
if !strings.Contains(content, tag) {
return false
}
}

return false, scanner.Err()
return true
}

func (p *JUnitPostProcessor) End() error {
Expand Down
10 changes: 6 additions & 4 deletions cmd/testworkflow-toolkit/artifacts/junit_post_processor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,11 @@ func TestIsJUnitReport(t *testing.T) {
file: filesystem.NewMockFile("invalid.xml", []byte(testdata.InvalidJUnit)),
want: false,
},
{
name: "one-line junit",
file: filesystem.NewMockFile("pytest.xml", []byte(testdata.OneLineJUnit)),
want: true,
},
}

for _, tc := range tests {
Expand All @@ -154,10 +159,7 @@ func TestIsJUnitReport(t *testing.T) {
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
ok, err := isJUnitReport(data)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
ok := isJUnitReport(data)
assert.Equal(t, tc.want, ok)
})
}
Expand Down
2 changes: 2 additions & 0 deletions cmd/testworkflow-toolkit/common/testdata/junit.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,3 +176,5 @@ var InvalidJUnit = `<?xml version="1.0" encoding="UTF-8"?>
<foo>
<bar>
</foo>`

var OneLineJUnit = `<?xml version="1.0" encoding="UTF-8"?><testsuites><testsuite name="TestSuite" tests="2" errors="0" failures="1" skipped="0"><testcase name="Test1" classname="TestClass"><failure message="Test failed">Failure details</failure></testcase><testcase name="Test2" classname="TestClass"/></testsuite></testsuites>`

0 comments on commit d304e01

Please sign in to comment.