From 8e1d36681cbd804cd113f22a0ffa1e6e1b7e27fb Mon Sep 17 00:00:00 2001 From: Sarah French <15078782+SarahFrench@users.noreply.github.com> Date: Wed, 15 Jan 2025 11:44:35 +0000 Subject: [PATCH] Promote JUnit output 'terraform test' feature from experimental status, make incompatibility with remote test execution explicit via flag validation (#36324) * Promote JUnit reports for `terraform test` out of experimental status * Make JUnit output explicitly for local execution only * Refactor how local test runner is passed JUnit data * Add change file * Add test for incompatible flags --- .../NEW FEATURES-20250115-110818.yaml | 5 +++ internal/command/arguments/test.go | 7 ++++ internal/command/arguments/test_test.go | 18 ++++++++++ internal/command/test.go | 36 ++++++------------- 4 files changed, 40 insertions(+), 26 deletions(-) create mode 100644 .changes/unreleased/NEW FEATURES-20250115-110818.yaml diff --git a/.changes/unreleased/NEW FEATURES-20250115-110818.yaml b/.changes/unreleased/NEW FEATURES-20250115-110818.yaml new file mode 100644 index 0000000000..de5f6b601b --- /dev/null +++ b/.changes/unreleased/NEW FEATURES-20250115-110818.yaml @@ -0,0 +1,5 @@ +kind: NEW FEATURES +body: '`terraform test`: The `-junit-xml` option for the terraform test command is now generally available. This option allows the command to create a test report in JUnit XML format. Feedback during the experimental phase helped map terraform test concepts to the JUnit XML format, and new additons may happen in future releases.' +time: 2025-01-15T11:08:18.566206Z +custom: + Issue: "36324" diff --git a/internal/command/arguments/test.go b/internal/command/arguments/test.go index 497980972f..848ac81915 100644 --- a/internal/command/arguments/test.go +++ b/internal/command/arguments/test.go @@ -66,6 +66,13 @@ func ParseTest(args []string) (*Test, tfdiags.Diagnostics) { err.Error())) } + if len(test.JUnitXMLFile) > 0 && len(test.CloudRunSource) > 0 { + diags = diags.Append(tfdiags.Sourceless( + tfdiags.Error, + "Incompatible command-line flags", + "The -junit-xml option is currently not compatible with remote test execution via the -cloud-run flag. If you are interested in JUnit XML output for remotely-executed tests please open an issue in GitHub.")) + } + switch { case jsonOutput: test.ViewType = ViewJSON diff --git a/internal/command/arguments/test_test.go b/internal/command/arguments/test_test.go index b54b0ce90a..07993bbd8e 100644 --- a/internal/command/arguments/test_test.go +++ b/internal/command/arguments/test_test.go @@ -137,6 +137,24 @@ func TestParseTest(t *testing.T) { ), }, }, + "incompatible flags: -junit-xml and -cloud-run": { + args: []string{"-junit-xml=./output.xml", "-cloud-run=foobar"}, + want: &Test{ + CloudRunSource: "foobar", + JUnitXMLFile: "./output.xml", + Filter: nil, + TestDirectory: "tests", + ViewType: ViewHuman, + Vars: &Vars{}, + }, + wantDiags: tfdiags.Diagnostics{ + tfdiags.Sourceless( + tfdiags.Error, + "Incompatible command-line flags", + "The -junit-xml option is currently not compatible with remote test execution via the -cloud-run flag. If you are interested in JUnit XML output for remotely-executed tests please open an issue in GitHub.", + ), + }, + }, } cmpOpts := cmpopts.IgnoreUnexported(Operation{}, Vars{}, State{}) diff --git a/internal/command/test.go b/internal/command/test.go index c6fb8cfd93..f6759cd220 100644 --- a/internal/command/test.go +++ b/internal/command/test.go @@ -121,30 +121,6 @@ func (c *TestCommand) Run(rawArgs []string) int { return 1 } - var junitFile junit.JUnit - if args.JUnitXMLFile != "" { - // JUnit XML output is currently experimental, so that we can gather - // feedback on exactly how we should map the test results to this - // JUnit-oriented format before anyone starts depending on it for real. - if !c.AllowExperimentalFeatures { - diags = diags.Append(tfdiags.Sourceless( - tfdiags.Error, - "JUnit XML output is not available", - "The -junit-xml option is currently experimental and therefore available only in alpha releases of Terraform CLI.", - )) - view.Diagnostics(nil, nil, diags) - return 1 - } - diags = diags.Append(tfdiags.Sourceless( - tfdiags.Warning, - "JUnit XML output is experimental", - "The -junit-xml option is currently experimental and therefore subject to breaking changes or removal, even in patch releases.", - )) - - // This line must happen after the TestCommand's calls loadConfigWithTests and has the configLoader field set - junitFile = junit.NewTestJUnitXMLFile(args.JUnitXMLFile, c.configLoader) - } - // Users can also specify variables via the command line, so we'll parse // all that here. var items []arguments.FlagNameValue @@ -224,7 +200,8 @@ func (c *TestCommand) Run(rawArgs []string) int { Streams: c.Streams, } } else { - runner = &local.TestSuiteRunner{ + + localRunner := &local.TestSuiteRunner{ Config: config, // The GlobalVariables are loaded from the // main configuration directory @@ -235,7 +212,6 @@ func (c *TestCommand) Run(rawArgs []string) int { TestingDirectory: args.TestDirectory, Opts: opts, View: view, - JUnit: junitFile, Stopped: false, Cancelled: false, StoppedCtx: stopCtx, @@ -243,6 +219,14 @@ func (c *TestCommand) Run(rawArgs []string) int { Filter: args.Filter, Verbose: args.Verbose, } + + // JUnit output is only compatible with local test execution + if args.JUnitXMLFile != "" { + // Make sure TestCommand's calls loadConfigWithTests before this code, so configLoader is not nil + localRunner.JUnit = junit.NewTestJUnitXMLFile(args.JUnitXMLFile, c.configLoader) + } + + runner = localRunner } var testDiags tfdiags.Diagnostics