diff --git a/CHANGELOG.md b/CHANGELOG.md index 31f763a936..c5895d7f7c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -54,6 +54,7 @@ BUG FIXES: * Ensure that generated mock values for testing correctly follows the provider schema. ([#3069](https://github.com/opentofu/opentofu/pull/3069)) * Remote provisioners now reject SSH certificates whose signature key is a certificate key, as required by the current SSH Certificate Format specification draft. ([#3180](https://github.com/opentofu/opentofu/pull/3180)) * `tofu import` command now correctly validates when the target address contains non-existent for_each key ([#3106](https://github.com/opentofu/opentofu/pull/3106)) +* Fix crash in tofu test when using deprecated outputs ([#3249](https://github.com/opentofu/opentofu/pull/3249)) BREAKING CHANGES: * In the `azurerm` backend, the following backend variables have been changed ([#3034](https://github.com/opentofu/opentofu/pull/3034)): diff --git a/internal/command/test_test.go b/internal/command/test_test.go index 1c7bb8f9cf..0400ca3098 100644 --- a/internal/command/test_test.go +++ b/internal/command/test_test.go @@ -1609,3 +1609,27 @@ func TestTest_MockProviderValidationForEach(t *testing.T) { t.Fatalf("expected status code 0 but got %d: %s", code, output.All()) } } + +// See https://github.com/opentofu/opentofu/issues/3246 +func TestTest_DeprecatedOutputs(t *testing.T) { + td := t.TempDir() + testCopyDir(t, testFixturePath("test/deprecated_outputs"), td) + t.Chdir(td) + + view, done := testView(t) + ui := new(cli.MockUi) + meta := Meta{ + Ui: ui, + View: view, + } + + testCmd := &TestCommand{ + Meta: meta, + } + + code := testCmd.Run(nil) + output := done(t) + if code != 0 { + t.Fatalf("expected status code 0 but got %d: %s", code, output.All()) + } +} diff --git a/internal/command/testdata/test/deprecated_outputs/main.tf b/internal/command/testdata/test/deprecated_outputs/main.tf new file mode 100644 index 0000000000..cae3452686 --- /dev/null +++ b/internal/command/testdata/test/deprecated_outputs/main.tf @@ -0,0 +1,4 @@ +output "example" { + value = "example" + deprecated = "for reasons" +} diff --git a/internal/command/testdata/test/deprecated_outputs/main.tftest.hcl b/internal/command/testdata/test/deprecated_outputs/main.tftest.hcl new file mode 100644 index 0000000000..ce75d540ca --- /dev/null +++ b/internal/command/testdata/test/deprecated_outputs/main.tftest.hcl @@ -0,0 +1,8 @@ +run "example" { + command = plan + + assert { + condition = output.example == "example" + error_message = "ruh-roh" + } +} diff --git a/internal/lang/marks/marks.go b/internal/lang/marks/marks.go index e36a957a1f..5660366af2 100644 --- a/internal/lang/marks/marks.go +++ b/internal/lang/marks/marks.go @@ -117,6 +117,12 @@ func Deprecated(v cty.Value, cause DeprecationCause) cty.Value { // DeprecatedOutput marks a given values as deprecated constructing a DeprecationCause // from module output specific data. func DeprecatedOutput(v cty.Value, addr addrs.AbsOutputValue, msg string, isFromRemoteModule bool) cty.Value { + if addr.Module.IsRoot() { + // Marking a root output as deprecated has no impact. + // We hit this case when using the test framework on a module however. + // This is requried as the ModuleCallOutput() below will panic on the root module. + return v + } _, callOutAddr := addr.ModuleCallOutput() return Deprecated(v, DeprecationCause{ IsFromRemoteModule: isFromRemoteModule,