diff --git a/internal/cobraext/flags.go b/internal/cobraext/flags.go index 2441040f45..ad0c1fdc5d 100644 --- a/internal/cobraext/flags.go +++ b/internal/cobraext/flags.go @@ -160,7 +160,7 @@ const ( ProfileFormatFlagDescription = "format of the profiles list (table | json)" ReportFormatFlagName = "report-format" - ReportFormatFlagDescription = "format of test report, eg: human, xUnit" + ReportFormatFlagDescription = "format of test report, eg: human, xUnit, json" ReportFullFlagName = "full" ReportFullFlagDescription = "whether to show the full report or a summary" diff --git a/internal/testrunner/reporters/formats/json.go b/internal/testrunner/reporters/formats/json.go new file mode 100644 index 0000000000..3e8f424731 --- /dev/null +++ b/internal/testrunner/reporters/formats/json.go @@ -0,0 +1,72 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. + +package formats + +import ( + "encoding/json" + "fmt" + + "github.com/elastic/elastic-package/internal/testrunner" +) + +func init() { + testrunner.RegisterReporterFormat(ReportFormatJSON, reportJSONFormat) +} + +const ( + // ReportFormatJSON reports test results in a JSON format + ReportFormatJSON testrunner.TestReportFormat = "json" +) + +type jsonResult struct { + Package string `json:"package"` + DataStream string `json:"data_stream,omitempty"` + TestType string `json:"test_type"` + Name string `json:"name"` + Result string `json:"result"` + TimeElapsed string `json:"time_elapsed"` + FailureDetails string `json:"failure_details,omitempty"` +} + +func reportJSONFormat(results []testrunner.TestResult) (string, error) { + if len(results) == 0 { + return "No test results", nil + } + + jsonReport := make([]jsonResult, 0, len(results)) + for _, r := range results { + jsonResult := jsonResult{ + Package: r.Package, + DataStream: r.DataStream, + TestType: string(r.TestType), + Name: r.Name, + TimeElapsed: r.TimeElapsed.String(), + } + + if r.FailureMsg != "" { + jsonResult.FailureDetails = fmt.Sprintf("%s/%s %s:\n%s\n", r.Package, r.DataStream, r.Name, r.FailureDetails) + } + + var result string + if r.ErrorMsg != "" { + result = fmt.Sprintf("ERROR: %s", r.ErrorMsg) + } else if r.FailureMsg != "" { + result = fmt.Sprintf("FAIL: %s", r.FailureMsg) + } else if r.Skipped != nil { + result = fmt.Sprintf("SKIPPED: %s", r.Skipped) + } else { + result = "PASS" + } + jsonResult.Result = result + + jsonReport = append(jsonReport, jsonResult) + } + + b, err := json.Marshal(jsonReport) + if err != nil { + return "", fmt.Errorf("marshaling test results to JSON: %w", err) + } + return string(b), nil +} diff --git a/internal/testrunner/reporters/outputs/file.go b/internal/testrunner/reporters/outputs/file.go index 4588357e56..bf04cfbc90 100644 --- a/internal/testrunner/reporters/outputs/file.go +++ b/internal/testrunner/reporters/outputs/file.go @@ -39,8 +39,11 @@ func reportToFile(pkg, report string, testType testrunner.TestType, format testr } ext := "txt" - if format == formats.ReportFormatXUnit { + switch format { + case formats.ReportFormatXUnit: ext = "xml" + case formats.ReportFormatJSON: + ext = "json" } fileName := fmt.Sprintf("%s-%s-%d.%s", pkg, testType, time.Now().UnixNano(), ext)