Skip to content

Commit

Permalink
Merge pull request #271 from bcrochet/junit
Browse files Browse the repository at this point in the history
Reintroduce the JUnit XML formatter
  • Loading branch information
bcrochet authored Sep 24, 2021
2 parents 1b67d3f + c240010 commit f756bf4
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 2 deletions.
5 changes: 3 additions & 2 deletions certification/formatters/formatters.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ func (f *genericFormatter) FileExtension() string {
// availableFormatters maps configuration-friendly values to pretty representations
// of the same value, and their corresponding Formatter included with this library.
var availableFormatters = map[string]ResponseFormatter{
"json": &genericFormatter{"Generic JSON", "json", genericJSONFormatter},
"xml": &genericFormatter{"Generic XML", "xml", genericXMLFormatter},
"json": &genericFormatter{"Generic JSON", "json", genericJSONFormatter},
"xml": &genericFormatter{"Generic XML", "xml", genericXMLFormatter},
"junitxml": &genericFormatter{"JUnit XML", "xml", junitXMLFormatter},
}
108 changes: 108 additions & 0 deletions certification/formatters/junitxml.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package formatters

import (
"encoding/xml"
"fmt"
"time"

"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/errors"
"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/runtime"
)

type JUnitTestSuites struct {
XMLName xml.Name `xml:"testsuites"`
Suites []JUnitTestSuite `xml:"testsuite"`
}

type JUnitTestSuite struct {
XMLName xml.Name `xml:"testsuite"`
Tests int `xml:"tests,attr"`
Failures int `xml:"failures,attr"`
Time string `xml:"time,attr"`
Name string `xml:"name,attr"`
Properties []JUnitProperty `xml:"properties>property,omitempty"`
TestCases []JUnitTestCase `xml:"testcase"`
}

type JUnitTestCase struct {
XMLName xml.Name `xml:"testcase"`
Classname string `xml:"classname,attr"`
Name string `xml:"name,attr"`
Time string `xml:"time,attr"`
SkipMessage *JUnitSkipMessage `xml:"skipped,omitempty"`
Failure *JUnitFailure `xml:"failure,omitempty"`
SystemOut string `xml:"system-out,omitempty"`
Message string `xml:",chardata"`
}

type JUnitSkipMessage struct {
Message string `xml:"message,attr"`
}

type JUnitProperty struct {
Name string `xml:"name,attr"`
Value string `xml:"value,attr"`
}

type JUnitFailure struct {
Message string `xml:"message,attr"`
Type string `xml:"type,attr"`
Contents string `xml:",chardata"`
}

func junitXMLFormatter(r runtime.Results) ([]byte, error) {
response := getResponse(r)
suites := JUnitTestSuites{}
testsuite := JUnitTestSuite{
Tests: len(r.Errors) + len(r.Failed) + len(r.Passed),
Failures: len(r.Errors) + len(r.Failed),
Time: "0s",
Name: "Red Hat Certification",
Properties: []JUnitProperty{},
TestCases: []JUnitTestCase{},
}

totalDuration := time.Duration(0)
for _, result := range r.Passed {
testCase := JUnitTestCase{
Classname: response.Image,
Name: result.Name(),
Time: result.ElapsedTime.String(),
Failure: nil,
Message: result.Metadata().Description,
}
testsuite.TestCases = append(testsuite.TestCases, testCase)
totalDuration += result.ElapsedTime
}

for _, result := range append(r.Errors, r.Failed...) {
testCase := JUnitTestCase{
Classname: response.Image,
Name: result.Name(),
Time: result.ElapsedTime.String(),
Failure: &JUnitFailure{
Message: "Failed",
Type: "",
Contents: fmt.Sprintf("%s: Suggested Fix: %s", result.Help().Message, result.Help().Suggestion),
},
}
testsuite.TestCases = append(testsuite.TestCases, testCase)
totalDuration += result.ElapsedTime
}

testsuite.Time = totalDuration.String()
suites.Suites = append(suites.Suites, testsuite)

bytes, err := xml.MarshalIndent(suites, "", "\t")
if err != nil {
o := fmt.Errorf("%w with formatter %s: %s",
errors.ErrFormattingResults,
"junitxml",
err,
)

return nil, o
}

return bytes, nil
}
31 changes: 31 additions & 0 deletions cmd/check.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
package cmd

import (
"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/artifacts"
"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/formatters"
"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/runtime"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)

var checkCmd = &cobra.Command{
Expand All @@ -13,3 +18,29 @@ var checkCmd = &cobra.Command{
func init() {
rootCmd.AddCommand(checkCmd)
}

func writeJunitIfEnabled(results runtime.Results) error {
if !viper.GetBool("junit") {
return nil
}

var cfg runtime.Config
cfg.ResponseFormat = "junitxml"

junitformatter, err := formatters.NewForConfig(cfg)
if err != nil {
return err
}
junitResults, err := junitformatter.Format(results)
if err != nil {
return err
}

junitFilename, err := artifacts.WriteFile("results-junit.xml", string(junitResults))
if err != nil {
return err
}
log.Tracef("JUnitXML written to %s", junitFilename)

return nil
}
4 changes: 4 additions & 0 deletions cmd/check_container.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ var checkContainerCmd = &cobra.Command{
return err
}

if err := writeJunitIfEnabled(results); err != nil {
return err
}

return nil
},
}
Expand Down
4 changes: 4 additions & 0 deletions cmd/check_operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ var checkOperatorCmd = &cobra.Command{
return err
}

if err := writeJunitIfEnabled(results); err != nil {
return err
}

return nil
},
}
Expand Down

0 comments on commit f756bf4

Please sign in to comment.