Files
opentf/internal/command/e2etest/plan_test.go
James Humphries c5fd93482a Fix crash in unmarkDeepWithPathsDeprecated (#3105)
Signed-off-by: James Humphries <james@james-humphries.co.uk>
Signed-off-by: James Humphries <James@james-humphries.co.uk>
Co-authored-by: Andrei Ciobanu <andrei.ciobanu@opentofu.org>
2025-08-06 15:40:19 +01:00

171 lines
4.8 KiB
Go

// Copyright (c) The OpenTofu Authors
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) 2023 HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package e2etest
import (
"path/filepath"
"strings"
"testing"
"github.com/google/go-cmp/cmp"
"github.com/opentofu/opentofu/internal/e2e"
)
// The tests in this file are for the following sequence:
// tofu init
// tofu plan
func TestPlanConsolidatedWarningsForDeprecatedMarks(t *testing.T) {
t.Parallel()
implicitFixturePath := filepath.Join("testdata", "consolidated-warnings-for-deprecated-marks")
tf := e2e.NewBinary(t, tofuBin, implicitFixturePath)
t.Run("consolidated warnings for deprecated marks", func(t *testing.T) {
_, initErr, err := tf.Run("init")
if err != nil {
t.Fatalf("expected no errors on init, got error %v: %s", err, initErr)
}
planStdout, planErr, err := tf.Run("plan")
if err != nil {
t.Fatalf("expected no errors on plan, got error %v: %s", err, planErr)
}
expectedOutput := `
No changes. Your infrastructure matches the configuration.
OpenTofu has compared your real infrastructure against your configuration and
found no differences, so no changes are needed.
│ Warning: Variable marked as deprecated by the module author
│ on main.tf line 3, in module "call":
│ 3: input = "test"
│ Variable "input" is marked as deprecated with the following message:
│ this is local deprecated
│ (and one more similar warning elsewhere)
│ Warning: Variable marked as deprecated by the module author
│ on main.tf line 4, in module "call":
│ 4: input2 = "test2"
│ Variable "input2" is marked as deprecated with the following message:
│ this is local deprecated2
│ (and one more similar warning elsewhere)
│ Warning: Value derived from a deprecated source
│ on main.tf line 14, in locals:
│ 14: i1 = module.call.modout1
│ This value is derived from module.call.modout1, which is deprecated with
│ the following message:
│ output deprecated
│ (and 2 more similar warnings elsewhere)
│ Warning: Value derived from a deprecated source
│ on main.tf line 15, in locals:
│ 15: i2 = module.call.modout2
│ This value is derived from module.call.modout2, which is deprecated with
│ the following message:
│ output deprecated
│ (and 2 more similar warnings elsewhere)
`
if diff := cmp.Diff(strings.TrimSpace(stripAnsi(planStdout)), strings.TrimSpace(stripAnsi(expectedOutput))); diff != "" {
t.Errorf("wrong output.\n%s", diff)
}
})
}
func TestPlanOnDeprecated(t *testing.T) {
t.Parallel()
fixturePath := filepath.Join("testdata", "deprecated-values")
tf := e2e.NewBinary(t, tofuBin, fixturePath)
//// INIT
_, stderr, err := tf.Run("init", "-input=false")
if err != nil {
t.Fatalf("unexpected init error: %s\nstderr:\n%s", err, stderr)
}
//// PLAN
stdout, stderr, err := tf.Run("plan")
if err != nil {
t.Fatalf("unexpected plan error: %s\nstderr:\n%s", err, stderr)
}
expected := []string{
`Variable marked as deprecated by the module author`,
`Variable "input" is marked as deprecated with the following message`,
`This var is deprecated`,
`Value derived from a deprecated source`,
`This value is derived from module.call.output, which is deprecated with the`,
`following message:`,
`this output is deprecated`,
}
for _, want := range expected {
if !strings.Contains(stdout, want) {
t.Errorf("invalid plan output. expected to contain %q but it does not:\n%s", want, stdout)
}
}
}
func TestPlanOnMultipleDeprecatedMarksSliceBug(t *testing.T) {
t.Parallel()
// Test for [the bug](https://github.com/opentofu/opentofu/issues/3104) where modifying
// pathMarks slice during iteration would cause slice bounds errors when multiple
// deprecated marks exist
fixturePath := filepath.Join("testdata", "multiple-deprecated-marks-slice-bug")
tf := e2e.NewBinary(t, tofuBin, fixturePath)
t.Run("multiple deprecated marks slice bug", func(t *testing.T) {
_, initErr, err := tf.Run("init")
if err != nil {
t.Fatalf("expected no errors on init, got error %v: %s", err, initErr)
}
planStdout, planErr, err := tf.Run("plan")
if err != nil {
t.Fatalf("expected no errors on plan, got error %v: %s", err, planErr)
}
// Should not crash and should show deprecation warnings for all outputs
expectedContents := []string{
"Changes to Outputs:",
"trigger = {",
"Value derived from a deprecated source",
"Use new_out1",
"Use new_out2",
"Use new_out3",
}
// Strip ANSI codes for consistent testing
cleanOutput := stripAnsi(planStdout)
for _, want := range expectedContents {
if !strings.Contains(cleanOutput, want) {
t.Errorf("plan output missing expected content %q:\n%s", want, cleanOutput)
}
}
})
}