diff --git a/cmd/prune-junit-xml/prunexml.go b/cmd/prune-junit-xml/prunexml.go index 66f8ced5e8c..9e80c406456 100644 --- a/cmd/prune-junit-xml/prunexml.go +++ b/cmd/prune-junit-xml/prunexml.go @@ -22,12 +22,15 @@ import ( "fmt" "io" "os" + "regexp" "k8s.io/kubernetes/third_party/forked/gotestsum/junitxml" ) func main() { maxTextSize := flag.Int("max-text-size", 1, "maximum size of attribute or text (in MB)") + pruneTests := flag.Bool("prune-tests", true, + "prune's xml files to display only top level tests and failed sub-tests") flag.Parse() for _, path := range flag.Args() { fmt.Printf("processing junit xml file : %s\n", path) @@ -42,6 +45,9 @@ func main() { } pruneXML(suites, *maxTextSize*1e6) // convert MB into bytes (roughly!) + if *pruneTests { + pruneTESTS(suites) + } xmlWriter, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666) if err != nil { @@ -79,6 +85,40 @@ func pruneXML(suites *junitxml.JUnitTestSuites, maxBytes int) { } } +// This function condenses the junit xml to have package name as top level identifier +// and nesting under that. +func pruneTESTS(suites *junitxml.JUnitTestSuites) { + var updatedTestsuites []junitxml.JUnitTestSuite + + for _, suite := range suites.Suites { + var updatedTestcases []junitxml.JUnitTestCase + var updatedTestcase junitxml.JUnitTestCase + var updatedTestcaseFailure junitxml.JUnitFailure + failflag := false + name := suite.Name + regex := regexp.MustCompile(`^(.*?)/([^/]+)/?$`) + match := regex.FindStringSubmatch(name) + updatedTestcase.Classname = match[1] + updatedTestcase.Name = match[2] + updatedTestcase.Time = suite.Time + for _, testcase := range suite.TestCases { + // The top level testcase element in a JUnit xml file does not have the / character. + if testcase.Failure != nil { + failflag = true + updatedTestcaseFailure.Message = updatedTestcaseFailure.Message + testcase.Failure.Message + ";" + updatedTestcaseFailure.Contents = updatedTestcaseFailure.Contents + testcase.Failure.Contents + ";" + updatedTestcaseFailure.Type = updatedTestcaseFailure.Type + testcase.Failure.Type + } + } + if failflag { + updatedTestcase.Failure = &updatedTestcaseFailure + } + suite.TestCases = append(updatedTestcases, updatedTestcase) + updatedTestsuites = append(updatedTestsuites, suite) + } + suites.Suites = updatedTestsuites +} + func fetchXML(xmlReader io.Reader) (*junitxml.JUnitTestSuites, error) { decoder := xml.NewDecoder(xmlReader) var suites junitxml.JUnitTestSuites diff --git a/cmd/prune-junit-xml/prunexml_test.go b/cmd/prune-junit-xml/prunexml_test.go index 343e2261c81..f0b325f2d85 100644 --- a/cmd/prune-junit-xml/prunexml_test.go +++ b/cmd/prune-junit-xml/prunexml_test.go @@ -65,3 +65,54 @@ func TestPruneXML(t *testing.T) { _ = writer.Flush() assert.Equal(t, outputXML, string(output.Bytes()), "xml was not pruned correctly") } + +func TestPruneTESTS(t *testing.T) { + sourceXML := ` + + + + + + + + + + + + + + + + + + + FailureContent + + +` + + outputXML := ` + + + + + + + + + + + + + FailureContent; + + +` + suites, _ := fetchXML(strings.NewReader(sourceXML)) + pruneTESTS(suites) + var output bytes.Buffer + writer := bufio.NewWriter(&output) + _ = streamXML(writer, suites) + _ = writer.Flush() + assert.Equal(t, outputXML, string(output.Bytes()), "tests in xml was not pruned correctly") +}