Skip to content

Commit

Permalink
Merge branch 'main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
janisz authored Apr 3, 2024
2 parents cdcceb6 + 03b0e38 commit 9128de8
Show file tree
Hide file tree
Showing 3 changed files with 182 additions and 11 deletions.
81 changes: 72 additions & 9 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ func main() {
flag.StringVar(&p.slackOutput, "slack-output", "", "Generate JSON output in slack format (use dash [-] for stdout)")
flag.StringVar(&p.htmlOutput, "html-output", "", "Generate HTML report to this file (use dash [-] for stdout)")
flag.StringVar(&p.csvOutput, "csv-output", "", "Convert XML to a CSV file (use dash [-] for stdout)")
flag.StringVar(&p.summaryOutput, "summary-output", "", "Write a summary in JSON to this file (use dash [-] for stdout)")
flag.StringVar(&jiraUrl, "jira-url", "https://issues.redhat.com/", "Url of JIRA instance")
flag.StringVar(&p.jiraProject, "jira-project", "ROX", "The JIRA project for issues")
flag.StringVar(&p.junitReportsDir, "junit-reports-dir", os.Getenv("ARTIFACT_DIR"), "Dir that contains jUnit reports XML files")
Expand Down Expand Up @@ -85,6 +86,7 @@ type junit2jira struct {

type testIssue struct {
issue *jira.Issue
newJIRA bool
testCase testCase
}

Expand All @@ -108,22 +110,24 @@ func run(p params) error {

testSuites, err := junit.IngestDir(p.junitReportsDir)
if err != nil {
log.Fatalf("coud not read files: %s", err)
log.Fatalf("could not read files: %s", err)
}

err = j.createCsv(testSuites)
if err != nil {
log.Fatalf("coud create CSV: %s", err)
log.Fatalf("could not create CSV: %s", err)
}

failedTests, err := j.findFailedTests(testSuites)
if err != nil {
return errors.Wrap(err, "could not find failed tests")
}

issues, err := j.createIssuesOrComments(failedTests)
if err != nil {
return errors.Wrap(err, "could not create issues or comments")
}

err = j.createSlackMessage(issues)
if err != nil {
return errors.Wrap(err, "could not convert to slack")
Expand All @@ -138,6 +142,12 @@ func run(p params) error {
if err != nil {
return errors.Wrap(err, "could not link issues")
}

err = j.writeSummary(issues)
if err != nil {
return errors.Wrap(err, "could not write summary")
}

return errors.Wrap(j.createHtml(jiraIssues), "could not create HTML report")
}

Expand Down Expand Up @@ -302,6 +312,7 @@ func (j junit2jira) createIssueOrComment(tc testCase) (*testIssue, error) {
issue.Self = create.Self
logEntry(issue.Key, summary).Info("Created new issue")
issueWithTestCase.issue = issue
issueWithTestCase.newJIRA = true
return &issueWithTestCase, nil
}

Expand All @@ -325,6 +336,49 @@ func (j junit2jira) createIssueOrComment(tc testCase) (*testIssue, error) {
return &issueWithTestCase, nil
}

func (j junit2jira) writeSummary(tc []*testIssue) error {
if j.summaryOutput == "" {
return nil
}
out := os.Stdout
if j.summaryOutput != "-" {
file, err := os.Create(j.summaryOutput)
if err != nil {
return fmt.Errorf("could not create file %s: %w", j.summaryOutput, err)
}
out = file
defer file.Close()
}

return generateSummary(tc, out)
}

type summary struct {
NewJIRAs int `json:"newJIRAs"`
}

func generateSummary(tc []*testIssue, output io.Writer) error {
newJIRAs := 0

for _, testIssue := range tc {
if testIssue.newJIRA {
newJIRAs++
}
}
summary := summary{
NewJIRAs: newJIRAs,
}

json, err := json.Marshal(summary)
if err != nil {
return err
}

_, err = output.Write(json)

return err
}

func logEntry(id, summary string) *log.Entry {

return log.WithField("ID", id).WithField("summary", summary)
Expand Down Expand Up @@ -410,12 +464,7 @@ func junit2csv(testSuites []junit.Suite, p params, output io.Writer) error {
func (j junit2jira) findFailedTests(testSuites []junit.Suite) ([]testCase, error) {
failedTests := make([]testCase, 0)
for _, ts := range testSuites {
for _, tc := range ts.Tests {
if tc.Error == nil {
continue
}
failedTests = j.addFailedTest(failedTests, tc)
}
failedTests = j.addFailedTests(ts, failedTests)
}
log.Infof("Found %d failed tests", len(failedTests))

Expand All @@ -426,6 +475,19 @@ func (j junit2jira) findFailedTests(testSuites []junit.Suite) ([]testCase, error
return failedTests, nil
}

func (j junit2jira) addFailedTests(ts junit.Suite, failedTests []testCase) []testCase {
for _, suite := range ts.Suites {
failedTests = j.addFailedTests(suite, failedTests)
}
for _, tc := range ts.Tests {
if tc.Error == nil {
continue
}
failedTests = j.addTest(failedTests, tc)
}
return failedTests
}

func (j junit2jira) mergeFailedTests(failedTests []testCase) ([]testCase, error) {
log.Warning("Too many failed tests, reporting them as a one failure.")
msg := ""
Expand All @@ -448,7 +510,7 @@ func (j junit2jira) mergeFailedTests(failedTests []testCase) ([]testCase, error)
return []testCase{tc}, nil
}

func (j junit2jira) addFailedTest(failedTests []testCase, tc junit.Test) []testCase {
func (j junit2jira) addTest(failedTests []testCase, tc junit.Test) []testCase {
if !isSubTest(tc) {
return append(failedTests, NewTestCase(tc, j.params))
}
Expand Down Expand Up @@ -543,6 +605,7 @@ type params struct {
csvOutput string
htmlOutput string
slackOutput string
summaryOutput string
}

func NewTestCase(tc junit.Test, p params) testCase {
Expand Down
45 changes: 43 additions & 2 deletions main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ package main
import (
"bytes"
_ "embed"
"net/url"
"testing"

"github.com/andygrunwald/go-jira"
"github.com/joshdk/go-junit"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"net/url"
"testing"
)

func TestParseJunitReport(t *testing.T) {
Expand Down Expand Up @@ -74,6 +75,7 @@ github.com/stackrox/rox/sensor/kubernetes/localscanner / TestLocalScannerTLSIssu
[]testCase{
{
Message: `DefaultPoliciesTest / Verify policy Apache Struts CVE-2017-5638 is triggered FAILED
central-basic / step 90-activate-scanner-v4 FAILED
github.com/stackrox/rox/pkg/booleanpolicy/evaluator / TestDifferentBaseTypes FAILED
github.com/stackrox/rox/sensor/kubernetes/localscanner / TestLocalScannerTLSIssuerIntegrationTests FAILED
github.com/stackrox/rox/central/resourcecollection/datastore/store/postgres / TestCollectionsStore FAILED
Expand Down Expand Up @@ -161,6 +163,13 @@ command-line-arguments / TestTimeout FAILED
Error: "panic: test timed out after 1ns\n\ngoroutine 7 [running]:\ntesting.(*M).startAlarm.func1()\n\t/snap/go/10030/src/testing/testing.go:2036 +0x8e\ncreated by time.goFunc\n\t/snap/go/10030/src/time/sleep.go:176 +0x32\n\ngoroutine 1 [chan receive]:\ntesting.(*T).Run(0xc0000076c0, {0x5254af?, 0x4b7c05?}, 0x52f280)\n\t/snap/go/10030/src/testing/testing.go:1494 +0x37a\ntesting.runTests.func1(0xc00007e390?)\n\t/snap/go/10030/src/testing/testing.go:1846 +0x6e\ntesting.tRunner(0xc0000076c0, 0xc000104cd8)\n\t/snap/go/10030/src/testing/testing.go:1446 +0x10b\ntesting.runTests(0xc000000140?, {0x5fde10, 0x1, 0x1}, {0x7f398ed8a108?, 0x40?, 0x606c20?})\n\t/snap/go/10030/src/testing/testing.go:1844 +0x456\ntesting.(*M).Run(0xc000000140)\n\t/snap/go/10030/src/testing/testing.go:1726 +0x5d9\nmain.main()\n\t_testmain.go:47 +0x1aa\n\ngoroutine 6 [runnable]:\ntesting.pcToName(0x4b7dd4)\n\t/snap/go/10030/src/testing/testing.go:1226 +0x3d\ntesting.callerName(0x0?)\n\t/snap/go/10030/src/testing/testing.go:1222 +0x45\ntesting.tRunner(0xc000007860, 0x52f280)\n\t/snap/go/10030/src/testing/testing.go:1307 +0x34\ncreated by testing.(*T).Run\n\t/snap/go/10030/src/testing/testing.go:1493 +0x35f",
BuildId: "1",
},
{
Name: "step 90-activate-scanner-v4",
Suite: "central-basic",
Message: "failed in step 90-activate-scanner-v4",
Error: "resource PersistentVolumeClaim:kuttl-test-apparent-gelding/scanner-v4-db: .spec.accessModes: value mismatch, expected: ReadWriteOncex != actual: ReadWriteOnce",
BuildId: "1",
},
},
tests,
)
Expand Down Expand Up @@ -355,3 +364,35 @@ func TestHtmlOutput(t *testing.T) {

assert.Equal(t, expectedHtmlOutput, buf.String())
}

func TestSummaryNoNewJIRAs(t *testing.T) {
expectedSummaryNoNewJIRAs := `{"newJIRAs":0}`
buf := bytes.NewBufferString("")
require.NoError(t, generateSummary(nil, buf))
assert.Equal(t, expectedSummaryNoNewJIRAs, buf.String())
}

func TestSummaryNoFailures(t *testing.T) {
expectedSummarySomeNewJIRAs := `{"newJIRAs":2}`
tc := []*testIssue{
{
issue: &jira.Issue{Key: "ROX-1"},
newJIRA: false,
testCase: testCase{},
},
{
issue: &jira.Issue{Key: "ROX-2"},
newJIRA: true,
testCase: testCase{},
},
{
issue: &jira.Issue{Key: "ROX-3"},
newJIRA: true,
testCase: testCase{},
},
}

buf := bytes.NewBufferString("")
require.NoError(t, generateSummary(tc, buf))
assert.Equal(t, expectedSummarySomeNewJIRAs, buf.String())
}
67 changes: 67 additions & 0 deletions testdata/jira/kuttl-report.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<testsuites name="" tests="0" failures="0" time="2115.358">
<testsuite tests="0" failures="0" timestamp="2024-03-11T09:19:35.250138536+01:00" time="0.000" name="./tests/central">
<testsuite tests="11" failures="0" timestamp="2024-03-11T09:19:35.257557888+01:00" time="" name="central-basic">
<testcase classname="central-basic" name="setup" timestamp="2024-03-11T09:19:35.257558192+01:00" time="0.000" assertions="0"/>
<testcase classname="central-basic" name="step 0-image-pull-secrets" timestamp="2024-03-11T09:19:35.546319474+01:00" time="0.000" assertions="0"/>
<testcase classname="central-basic" name="step 10-central-cr" timestamp="2024-03-11T09:19:36.595834267+01:00" time="0.000" assertions="12"/>
<testcase classname="central-basic" name="step 11-" timestamp="2024-03-11T09:22:50.907680332+01:00" time="0.000" assertions="3"/>
<testcase classname="central-basic" name="step 20-verify-password" timestamp="2024-03-11T09:22:51.817070984+01:00" time="0.000" assertions="0"/>
<testcase classname="central-basic" name="step 30-change-password" timestamp="2024-03-11T09:22:53.710940889+01:00" time="0.000" assertions="0"/>
<testcase classname="central-basic" name="step 40-reconcile" timestamp="2024-03-11T09:22:54.471988804+01:00" time="0.000" assertions="2"/>
<testcase classname="central-basic" name="step 60-use-new-password" timestamp="2024-03-11T09:24:27.54231141+01:00" time="0.000" assertions="0"/>
<testcase classname="central-basic" name="step 75-switch-to-external-central-db" timestamp="2024-03-11T09:24:29.65030348+01:00" time="0.000" assertions="3"/>
<testcase classname="central-basic" name="step 76-switch-back-to-internal-central-db" timestamp="2024-03-11T09:25:30.568030169+01:00" time="0.000" assertions="8"/>
<testcase classname="central-basic" name="step 90-activate-scanner-v4" timestamp="2024-03-11T09:28:51.267096088+01:00" time="0.000" assertions="10">
<failure message="failed in step 90-activate-scanner-v4" type="">resource PersistentVolumeClaim:kuttl-test-apparent-gelding/scanner-v4-db: .spec.accessModes: value mismatch, expected: ReadWriteOncex != actual: ReadWriteOnce</failure>
</testcase>
</testsuite>
<testsuite tests="15" failures="0" timestamp="2024-03-11T09:19:35.261230002+01:00" time="" name="central-misc">
<testcase classname="central-misc" name="setup" timestamp="2024-03-11T09:19:35.261230219+01:00" time="0.000" assertions="0"/>
<testcase classname="central-misc" name="step 0-image-pull-secrets" timestamp="2024-03-11T09:19:35.526829403+01:00" time="0.000" assertions="0"/>
<testcase classname="central-misc" name="step 10-central-cr" timestamp="2024-03-11T09:19:36.596963264+01:00" time="0.000" assertions="12"/>
<testcase classname="central-misc" name="step 11-" timestamp="2024-03-11T09:23:09.391105115+01:00" time="0.000" assertions="1"/>
<testcase classname="central-misc" name="step 40-enable-declarative-config" timestamp="2024-03-11T09:23:10.509766935+01:00" time="0.000" assertions="7"/>
<testcase classname="central-misc" name="step 41-disable-declarative-config" timestamp="2024-03-11T09:24:43.52599129+01:00" time="0.000" assertions="7"/>
<testcase classname="central-misc" name="step 61-set-expose-monitoring" timestamp="2024-03-11T09:26:05.0306941+01:00" time="0.000" assertions="10"/>
<testcase classname="central-misc" name="step 62-" timestamp="2024-03-11T09:28:41.125375569+01:00" time="0.000" assertions="1"/>
<testcase classname="central-misc" name="step 63-unset-expose-monitoring" timestamp="2024-03-11T09:28:42.090536955+01:00" time="0.000" assertions="10"/>
<testcase classname="central-misc" name="step 64-" timestamp="2024-03-11T09:30:16.290671474+01:00" time="0.000" assertions="1"/>
<testcase classname="central-misc" name="step 80-enable-telemetry" timestamp="2024-03-11T09:30:17.522745147+01:00" time="0.000" assertions="7"/>
<testcase classname="central-misc" name="step 81-disable-telemetry" timestamp="2024-03-11T09:30:43.839958948+01:00" time="0.000" assertions="7"/>
<testcase classname="central-misc" name="step 85-add-additional-ca" timestamp="2024-03-11T09:31:50.195464314+01:00" time="0.000" assertions="7"/>
<testcase classname="central-misc" name="step 900-delete-cr" timestamp="2024-03-11T09:32:17.639280434+01:00" time="0.000" assertions="88"/>
<testcase classname="central-misc" name="step 990-" timestamp="2024-03-11T09:33:08.988074197+01:00" time="0.000" assertions="10"/>
</testsuite>
</testsuite>
<testsuite tests="0" failures="0" timestamp="2024-03-11T09:19:35.250178094+01:00" time="0.000" name="./tests/controller">
<testsuite tests="3" failures="0" timestamp="2024-03-11T09:19:35.252150775+01:00" time="" name="metrics">
<testcase classname="metrics" name="setup" timestamp="2024-03-11T09:19:35.252151087+01:00" time="0.000" assertions="0"/>
<testcase classname="metrics" name="step 100-rbac" timestamp="2024-03-11T09:19:35.536421893+01:00" time="0.000" assertions="0"/>
<testcase classname="metrics" name="step 200-access-no-auth" timestamp="2024-03-11T09:19:37.34609883+01:00" time="0.000" assertions="4"/>
</testsuite>
</testsuite>
<testsuite tests="0" failures="0" timestamp="2024-03-11T09:19:35.250189349+01:00" time="0.000" name="./tests/securedcluster">
<testsuite tests="20" failures="0" timestamp="2024-03-11T09:19:35.257858536+01:00" time="" name="sc-basic">
<testcase classname="sc-basic" name="setup" timestamp="2024-03-11T09:19:35.257858714+01:00" time="0.000" assertions="0"/>
<testcase classname="sc-basic" name="step 0-image-pull-secrets" timestamp="2024-03-11T09:19:35.528730355+01:00" time="0.000" assertions="0"/>
<testcase classname="sc-basic" name="step 5-central-cr" timestamp="2024-03-11T09:19:36.586298814+01:00" time="0.000" assertions="6"/>
<testcase classname="sc-basic" name="step 7-fetch-bundle" timestamp="2024-03-11T09:22:14.172876559+01:00" time="0.000" assertions="3"/>
<testcase classname="sc-basic" name="step 10-secured-cluster-cr" timestamp="2024-03-11T09:22:19.133516061+01:00" time="0.000" assertions="5"/>
<testcase classname="sc-basic" name="step 12-" timestamp="2024-03-11T09:23:31.889693826+01:00" time="0.000" assertions="0"/>
<testcase classname="sc-basic" name="step 13-" timestamp="2024-03-11T09:23:31.889764064+01:00" time="0.000" assertions="0"/>
<testcase classname="sc-basic" name="step 14-" timestamp="2024-03-11T09:23:31.889797675+01:00" time="0.000" assertions="0"/>
<testcase classname="sc-basic" name="step 15-" timestamp="2024-03-11T09:23:31.889831734+01:00" time="0.000" assertions="0"/>
<testcase classname="sc-basic" name="step 16-" timestamp="2024-03-11T09:23:31.889880701+01:00" time="0.000" assertions="0"/>
<testcase classname="sc-basic" name="step 20-try-change-cluster-name" timestamp="2024-03-11T09:23:31.889904131+01:00" time="0.000" assertions="1"/>
<testcase classname="sc-basic" name="step 30-change-cluster-name-back" timestamp="2024-03-11T09:23:32.933877824+01:00" time="0.000" assertions="5"/>
<testcase classname="sc-basic" name="step 40-enable-monitoring" timestamp="2024-03-11T09:23:55.205576704+01:00" time="0.000" assertions="1"/>
<testcase classname="sc-basic" name="step 41-" timestamp="2024-03-11T09:23:57.721971599+01:00" time="0.000" assertions="5"/>
<testcase classname="sc-basic" name="step 42-disable-monitoring" timestamp="2024-03-11T09:23:59.744647568+01:00" time="0.000" assertions="1"/>
<testcase classname="sc-basic" name="step 43-" timestamp="2024-03-11T09:25:02.021906203+01:00" time="0.000" assertions="5"/>
<testcase classname="sc-basic" name="step 900-delete-central-cr" timestamp="2024-03-11T09:25:21.262558079+01:00" time="0.000" assertions="2"/>
<testcase classname="sc-basic" name="step 910-" timestamp="2024-03-11T09:26:07.586210014+01:00" time="0.000" assertions="1"/>
<testcase classname="sc-basic" name="step 950-delete-secured-cluster-cr" timestamp="2024-03-11T09:27:04.476050533+01:00" time="0.000" assertions="71"/>
<testcase classname="sc-basic" name="step 990-" timestamp="2024-03-11T09:27:30.877137376+01:00" time="0.000" assertions="10"/>
</testsuite>
</testsuite>
</testsuites>

0 comments on commit 9128de8

Please sign in to comment.