From daba07c76205e1dbc463880618901b4dfa291a2e Mon Sep 17 00:00:00 2001 From: Daniel Schmidt Date: Thu, 12 Feb 2026 16:37:49 +0100 Subject: [PATCH] replicate basic test --- internal/terraform/context_plan2_test.go | 93 ++++++++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/internal/terraform/context_plan2_test.go b/internal/terraform/context_plan2_test.go index d7f5eaae5c..5e0af8e5fe 100644 --- a/internal/terraform/context_plan2_test.go +++ b/internal/terraform/context_plan2_test.go @@ -22,6 +22,7 @@ import ( "github.com/hashicorp/terraform/internal/addrs" "github.com/hashicorp/terraform/internal/checks" + "github.com/hashicorp/terraform/internal/configs" "github.com/hashicorp/terraform/internal/configs/configschema" "github.com/hashicorp/terraform/internal/lang/marks" "github.com/hashicorp/terraform/internal/plans" @@ -2572,6 +2573,98 @@ func TestContext2Plan_movedResourceRefreshOnly(t *testing.T) { }) } +func TestContext2Plan_move_with_expansions(t *testing.T) { + for name, tc := range map[string]struct { + modules map[string]string + buildState func(s *states.SyncState) + expectPlanDiagnostics func(m *configs.Config) tfdiags.Diagnostics + assertPlan func(t *testing.T, plan *plans.Plan) + }{ + "basic": { + modules: map[string]string{ + "main.tf": ` + resource "test_object" "b" { + count = 3 + } + + moved { + from = test_object.a + to = test_object.b + } + `, + }, + buildState: func(s *states.SyncState) { + s.SetResourceInstanceCurrent(mustResourceInstanceAddr("test_object.a[0]"), &states.ResourceInstanceObjectSrc{ + AttrsJSON: []byte(`{"value":"before0"}`), + Status: states.ObjectReady, + }, mustProviderConfig(`provider["registry.terraform.io/hashicorp/test"]`)) + s.SetResourceInstanceCurrent(mustResourceInstanceAddr("test_object.a[1]"), &states.ResourceInstanceObjectSrc{ + AttrsJSON: []byte(`{"value":"before1"}`), + Status: states.ObjectReady, + }, mustProviderConfig(`provider["registry.terraform.io/hashicorp/test"]`)) + s.SetResourceInstanceCurrent(mustResourceInstanceAddr("test_object.a[2]"), &states.ResourceInstanceObjectSrc{ + AttrsJSON: []byte(`{"value":"before2"}`), + Status: states.ObjectReady, + }, mustProviderConfig(`provider["registry.terraform.io/hashicorp/test"]`)) + }, + assertPlan: func(t *testing.T, plan *plans.Plan) { + for i := range 3 { + addrA := mustResourceInstanceAddr(fmt.Sprintf("test_object.a[%d]", i)) + addrB := mustResourceInstanceAddr(fmt.Sprintf("test_object.b[%d]", i)) + instPlan := plan.Changes.ResourceInstance(addrA) + if instPlan != nil { + t.Fatalf("unexpected plan for %s; should've moved to %s", addrA, addrB) + } + + instPlan = plan.Changes.ResourceInstance(addrB) + if instPlan == nil { + t.Fatalf("no plan for %s at all", addrB) + } + + if got, want := instPlan.Addr, addrB; !got.Equal(want) { + t.Errorf("wrong current address\ngot: %s\nwant: %s", got, want) + } + if got, want := instPlan.PrevRunAddr, addrA; !got.Equal(want) { + t.Errorf("wrong previous run address\ngot: %s\nwant: %s", got, want) + } + if got, want := instPlan.Action, plans.NoOp; got != want { + t.Errorf("wrong planned action\ngot: %s\nwant: %s", got, want) + } + if got, want := instPlan.ActionReason, plans.ResourceInstanceChangeNoReason; got != want { + t.Errorf("wrong action reason\ngot: %s\nwant: %s", got, want) + } + } + }, + }, + } { + t.Run(name, func(t *testing.T) { + m := testModuleInline(t, tc.modules) + state := states.BuildState(tc.buildState) + + p := simpleMockProvider() + ctx := testContext2(t, &ContextOpts{ + Providers: map[addrs.Provider]providers.Factory{ + addrs.NewDefaultProvider("test"): testProviderFuncFixed(p), + }, + }) + + plan, diags := ctx.Plan(m, state, &PlanOpts{ + Mode: plans.NormalMode, + }) + if tc.expectPlanDiagnostics == nil { + tfdiags.AssertNoDiagnostics(t, diags) + } else { + expectedDiags := tc.expectPlanDiagnostics(m) + tfdiags.AssertDiagnosticsMatch(t, diags, expectedDiags) + } + + if tc.assertPlan != nil { + tc.assertPlan(t, plan) + } + }) + } +} + func TestContext2Plan_refreshOnlyMode(t *testing.T) { addr := mustResourceInstanceAddr("test_object.a")