From dc9d7108dddae3d83e2b7455380a48d38b7631f4 Mon Sep 17 00:00:00 2001 From: James Bardin Date: Fri, 22 Jul 2022 12:51:55 -0400 Subject: [PATCH] use TopologicalOrder for evaluating moves The dag package did not previously provide a topological walk of a given graph. While the existing combination of a transitive reduction with a depth-first walk appeared to accomplish this, depth-first is only equivalent with a simple tree. If there are multiple paths to a node, a depth-first approach will skip dependencies from alternate paths. --- internal/refactoring/move_execute.go | 6 +- internal/refactoring/move_execute_test.go | 321 +++++++++------------- 2 files changed, 130 insertions(+), 197 deletions(-) diff --git a/internal/refactoring/move_execute.go b/internal/refactoring/move_execute.go index 1880da00a0..9a6d577cfb 100644 --- a/internal/refactoring/move_execute.go +++ b/internal/refactoring/move_execute.go @@ -87,7 +87,7 @@ func ApplyMoves(stmts []MoveStatement, state *states.State) MoveResults { }) } - g.ReverseDepthFirstWalk(startNodes, func(v dag.Vertex, depth int) error { + for _, v := range g.ReverseTopologicalOrder() { stmt := v.(*MoveStatement) for _, ms := range state.Modules { @@ -182,9 +182,7 @@ func ApplyMoves(stmts []MoveStatement, state *states.State) MoveResults { panic(fmt.Sprintf("unhandled move object kind %s", kind)) } } - - return nil - }) + } return ret } diff --git a/internal/refactoring/move_execute_test.go b/internal/refactoring/move_execute_test.go index 7a8185b18d..f1e4cd04a2 100644 --- a/internal/refactoring/move_execute_test.go +++ b/internal/refactoring/move_execute_test.go @@ -20,120 +20,12 @@ func TestApplyMoves(t *testing.T) { Provider: addrs.MustParseProviderSourceString("example.com/foo/bar"), } - moduleBoo, _ := addrs.ParseModuleInstanceStr("module.boo") - moduleBar, _ := addrs.ParseModuleInstanceStr("module.bar") - moduleBarKey, _ := addrs.ParseModuleInstanceStr("module.bar[0]") - moduleBooHoo, _ := addrs.ParseModuleInstanceStr("module.boo.module.hoo") - moduleBarHoo, _ := addrs.ParseModuleInstanceStr("module.bar.module.hoo") - - instAddrs := map[string]addrs.AbsResourceInstance{ - "foo.from": addrs.Resource{ - Mode: addrs.ManagedResourceMode, - Type: "foo", - Name: "from", - }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance), - - "foo.mid": addrs.Resource{ - Mode: addrs.ManagedResourceMode, - Type: "foo", - Name: "mid", - }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance), - - "foo.to": addrs.Resource{ - Mode: addrs.ManagedResourceMode, - Type: "foo", - Name: "to", - }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance), - - "foo.from[0]": addrs.Resource{ - Mode: addrs.ManagedResourceMode, - Type: "foo", - Name: "from", - }.Instance(addrs.IntKey(0)).Absolute(addrs.RootModuleInstance), - - "foo.to[0]": addrs.Resource{ - Mode: addrs.ManagedResourceMode, - Type: "foo", - Name: "to", - }.Instance(addrs.IntKey(0)).Absolute(addrs.RootModuleInstance), - - "module.boo.foo.from": addrs.Resource{ - Mode: addrs.ManagedResourceMode, - Type: "foo", - Name: "from", - }.Instance(addrs.NoKey).Absolute(moduleBoo), - - "module.boo.foo.mid": addrs.Resource{ - Mode: addrs.ManagedResourceMode, - Type: "foo", - Name: "mid", - }.Instance(addrs.NoKey).Absolute(moduleBoo), - - "module.boo.foo.to": addrs.Resource{ - Mode: addrs.ManagedResourceMode, - Type: "foo", - Name: "to", - }.Instance(addrs.NoKey).Absolute(moduleBoo), - - "module.boo.foo.from[0]": addrs.Resource{ - Mode: addrs.ManagedResourceMode, - Type: "foo", - Name: "from", - }.Instance(addrs.IntKey(0)).Absolute(moduleBoo), - - "module.boo.foo.to[0]": addrs.Resource{ - Mode: addrs.ManagedResourceMode, - Type: "foo", - Name: "to", - }.Instance(addrs.IntKey(0)).Absolute(moduleBoo), - - "module.bar.foo.from": addrs.Resource{ - Mode: addrs.ManagedResourceMode, - Type: "foo", - Name: "from", - }.Instance(addrs.NoKey).Absolute(moduleBar), - - "module.bar[0].foo.from": addrs.Resource{ - Mode: addrs.ManagedResourceMode, - Type: "foo", - Name: "from", - }.Instance(addrs.NoKey).Absolute(moduleBarKey), - - "module.bar[0].foo.mid": addrs.Resource{ - Mode: addrs.ManagedResourceMode, - Type: "foo", - Name: "mid", - }.Instance(addrs.NoKey).Absolute(moduleBarKey), - - "module.bar[0].foo.to": addrs.Resource{ - Mode: addrs.ManagedResourceMode, - Type: "foo", - Name: "to", - }.Instance(addrs.NoKey).Absolute(moduleBarKey), - - "module.bar[0].foo.from[0]": addrs.Resource{ - Mode: addrs.ManagedResourceMode, - Type: "foo", - Name: "from", - }.Instance(addrs.IntKey(0)).Absolute(moduleBarKey), - - "module.bar[0].foo.to[0]": addrs.Resource{ - Mode: addrs.ManagedResourceMode, - Type: "foo", - Name: "to", - }.Instance(addrs.IntKey(0)).Absolute(moduleBarKey), - - "module.boo.module.hoo.foo.from": addrs.Resource{ - Mode: addrs.ManagedResourceMode, - Type: "foo", - Name: "from", - }.Instance(addrs.NoKey).Absolute(moduleBooHoo), - - "module.bar.module.hoo.foo.from": addrs.Resource{ - Mode: addrs.ManagedResourceMode, - Type: "foo", - Name: "from", - }.Instance(addrs.NoKey).Absolute(moduleBarHoo), + mustParseInstAddr := func(s string) addrs.AbsResourceInstance { + addr, err := addrs.ParseAbsResourceInstanceStr(s) + if err != nil { + t.Fatal(err) + } + return addr } emptyResults := makeMoveResults() @@ -155,7 +47,7 @@ func TestApplyMoves(t *testing.T) { []MoveStatement{}, states.BuildState(func(s *states.SyncState) { s.SetResourceInstanceCurrent( - instAddrs["foo.from"], + mustParseInstAddr("foo.from"), &states.ResourceInstanceObjectSrc{ Status: states.ObjectReady, AttrsJSON: []byte(`{}`), @@ -174,7 +66,7 @@ func TestApplyMoves(t *testing.T) { }, states.BuildState(func(s *states.SyncState) { s.SetResourceInstanceCurrent( - instAddrs["foo.from"], + mustParseInstAddr("foo.from"), &states.ResourceInstanceObjectSrc{ Status: states.ObjectReady, AttrsJSON: []byte(`{}`), @@ -184,9 +76,9 @@ func TestApplyMoves(t *testing.T) { }), MoveResults{ Changes: addrs.MakeMap( - addrs.MakeMapElem(instAddrs["foo.to"], MoveSuccess{ - From: instAddrs["foo.from"], - To: instAddrs["foo.to"], + addrs.MakeMapElem(mustParseInstAddr("foo.to"), MoveSuccess{ + From: mustParseInstAddr("foo.from"), + To: mustParseInstAddr("foo.to"), }), ), Blocked: emptyResults.Blocked, @@ -201,7 +93,7 @@ func TestApplyMoves(t *testing.T) { }, states.BuildState(func(s *states.SyncState) { s.SetResourceInstanceCurrent( - instAddrs["foo.from[0]"], + mustParseInstAddr("foo.from[0]"), &states.ResourceInstanceObjectSrc{ Status: states.ObjectReady, AttrsJSON: []byte(`{}`), @@ -211,9 +103,9 @@ func TestApplyMoves(t *testing.T) { }), MoveResults{ Changes: addrs.MakeMap( - addrs.MakeMapElem(instAddrs["foo.to[0]"], MoveSuccess{ - From: instAddrs["foo.from[0]"], - To: instAddrs["foo.to[0]"], + addrs.MakeMapElem(mustParseInstAddr("foo.to[0]"), MoveSuccess{ + From: mustParseInstAddr("foo.from[0]"), + To: mustParseInstAddr("foo.to[0]"), }), ), Blocked: emptyResults.Blocked, @@ -229,7 +121,7 @@ func TestApplyMoves(t *testing.T) { }, states.BuildState(func(s *states.SyncState) { s.SetResourceInstanceCurrent( - instAddrs["foo.from"], + mustParseInstAddr("foo.from"), &states.ResourceInstanceObjectSrc{ Status: states.ObjectReady, AttrsJSON: []byte(`{}`), @@ -239,9 +131,9 @@ func TestApplyMoves(t *testing.T) { }), MoveResults{ Changes: addrs.MakeMap( - addrs.MakeMapElem(instAddrs["foo.to"], MoveSuccess{ - From: instAddrs["foo.from"], - To: instAddrs["foo.to"], + addrs.MakeMapElem(mustParseInstAddr("foo.to"), MoveSuccess{ + From: mustParseInstAddr("foo.from"), + To: mustParseInstAddr("foo.to"), }), ), Blocked: emptyResults.Blocked, @@ -257,7 +149,7 @@ func TestApplyMoves(t *testing.T) { }, states.BuildState(func(s *states.SyncState) { s.SetResourceInstanceCurrent( - instAddrs["foo.from[0]"], + mustParseInstAddr("foo.from[0]"), &states.ResourceInstanceObjectSrc{ Status: states.ObjectReady, AttrsJSON: []byte(`{}`), @@ -267,9 +159,9 @@ func TestApplyMoves(t *testing.T) { }), MoveResults{ Changes: addrs.MakeMap( - addrs.MakeMapElem(instAddrs["module.boo.foo.to[0]"], MoveSuccess{ - From: instAddrs["foo.from[0]"], - To: instAddrs["module.boo.foo.to[0]"], + addrs.MakeMapElem(mustParseInstAddr("module.boo.foo.to[0]"), MoveSuccess{ + From: mustParseInstAddr("foo.from[0]"), + To: mustParseInstAddr("module.boo.foo.to[0]"), }), ), Blocked: emptyResults.Blocked, @@ -285,7 +177,7 @@ func TestApplyMoves(t *testing.T) { }, states.BuildState(func(s *states.SyncState) { s.SetResourceInstanceCurrent( - instAddrs["module.boo.foo.from[0]"], + mustParseInstAddr("module.boo.foo.from[0]"), &states.ResourceInstanceObjectSrc{ Status: states.ObjectReady, AttrsJSON: []byte(`{}`), @@ -295,9 +187,9 @@ func TestApplyMoves(t *testing.T) { }), MoveResults{ Changes: addrs.MakeMap( - addrs.MakeMapElem(instAddrs["module.bar[0].foo.to[0]"], MoveSuccess{ - From: instAddrs["module.boo.foo.from[0]"], - To: instAddrs["module.bar[0].foo.to[0]"], + addrs.MakeMapElem(mustParseInstAddr("module.bar[0].foo.to[0]"), MoveSuccess{ + From: mustParseInstAddr("module.boo.foo.from[0]"), + To: mustParseInstAddr("module.bar[0].foo.to[0]"), }), ), Blocked: emptyResults.Blocked, @@ -313,7 +205,7 @@ func TestApplyMoves(t *testing.T) { }, states.BuildState(func(s *states.SyncState) { s.SetResourceInstanceCurrent( - instAddrs["module.boo.foo.from"], + mustParseInstAddr("module.boo.foo.from"), &states.ResourceInstanceObjectSrc{ Status: states.ObjectReady, AttrsJSON: []byte(`{}`), @@ -321,7 +213,7 @@ func TestApplyMoves(t *testing.T) { providerAddr, ) s.SetResourceInstanceCurrent( - instAddrs["module.boo.module.hoo.foo.from"], + mustParseInstAddr("module.boo.module.hoo.foo.from"), &states.ResourceInstanceObjectSrc{ Status: states.ObjectReady, AttrsJSON: []byte(`{}`), @@ -331,13 +223,13 @@ func TestApplyMoves(t *testing.T) { }), MoveResults{ Changes: addrs.MakeMap( - addrs.MakeMapElem(instAddrs["module.bar.foo.from"], MoveSuccess{ - From: instAddrs["module.boo.foo.from"], - To: instAddrs["module.bar.foo.from"], + addrs.MakeMapElem(mustParseInstAddr("module.bar.foo.from"), MoveSuccess{ + From: mustParseInstAddr("module.boo.foo.from"), + To: mustParseInstAddr("module.bar.foo.from"), }), - addrs.MakeMapElem(instAddrs["module.bar.module.hoo.foo.from"], MoveSuccess{ - From: instAddrs["module.boo.module.hoo.foo.from"], - To: instAddrs["module.bar.module.hoo.foo.from"], + addrs.MakeMapElem(mustParseInstAddr("module.bar.module.hoo.foo.from"), MoveSuccess{ + From: mustParseInstAddr("module.boo.module.hoo.foo.from"), + To: mustParseInstAddr("module.bar.module.hoo.foo.from"), }), ), Blocked: emptyResults.Blocked, @@ -354,7 +246,7 @@ func TestApplyMoves(t *testing.T) { }, states.BuildState(func(s *states.SyncState) { s.SetResourceInstanceCurrent( - instAddrs["module.boo.foo.from[0]"], + mustParseInstAddr("module.boo.foo.from[0]"), &states.ResourceInstanceObjectSrc{ Status: states.ObjectReady, AttrsJSON: []byte(`{}`), @@ -364,9 +256,9 @@ func TestApplyMoves(t *testing.T) { }), MoveResults{ Changes: addrs.MakeMap( - addrs.MakeMapElem(instAddrs["module.bar[0].foo.from[0]"], MoveSuccess{ - From: instAddrs["module.boo.foo.from[0]"], - To: instAddrs["module.bar[0].foo.from[0]"], + addrs.MakeMapElem(mustParseInstAddr("module.bar[0].foo.from[0]"), MoveSuccess{ + From: mustParseInstAddr("module.boo.foo.from[0]"), + To: mustParseInstAddr("module.bar[0].foo.from[0]"), }), ), Blocked: emptyResults.Blocked, @@ -383,7 +275,7 @@ func TestApplyMoves(t *testing.T) { }, states.BuildState(func(s *states.SyncState) { s.SetResourceInstanceCurrent( - instAddrs["module.boo.foo.from[0]"], + mustParseInstAddr("module.boo.foo.from[0]"), &states.ResourceInstanceObjectSrc{ Status: states.ObjectReady, AttrsJSON: []byte(`{}`), @@ -393,9 +285,9 @@ func TestApplyMoves(t *testing.T) { }), MoveResults{ Changes: addrs.MakeMap( - addrs.MakeMapElem(instAddrs["module.bar[0].foo.to[0]"], MoveSuccess{ - From: instAddrs["module.boo.foo.from[0]"], - To: instAddrs["module.bar[0].foo.to[0]"], + addrs.MakeMapElem(mustParseInstAddr("module.bar[0].foo.to[0]"), MoveSuccess{ + From: mustParseInstAddr("module.boo.foo.from[0]"), + To: mustParseInstAddr("module.bar[0].foo.to[0]"), }), ), Blocked: emptyResults.Blocked, @@ -412,7 +304,7 @@ func TestApplyMoves(t *testing.T) { }, states.BuildState(func(s *states.SyncState) { s.SetResourceInstanceCurrent( - instAddrs["module.boo.foo.from[0]"], + mustParseInstAddr("module.boo.foo.from[0]"), &states.ResourceInstanceObjectSrc{ Status: states.ObjectReady, AttrsJSON: []byte(`{}`), @@ -422,9 +314,9 @@ func TestApplyMoves(t *testing.T) { }), MoveResults{ Changes: addrs.MakeMap( - addrs.MakeMapElem(instAddrs["module.bar[0].foo.to[0]"], MoveSuccess{ - From: instAddrs["module.boo.foo.from[0]"], - To: instAddrs["module.bar[0].foo.to[0]"], + addrs.MakeMapElem(mustParseInstAddr("module.bar[0].foo.to[0]"), MoveSuccess{ + From: mustParseInstAddr("module.boo.foo.from[0]"), + To: mustParseInstAddr("module.bar[0].foo.to[0]"), }), ), Blocked: emptyResults.Blocked, @@ -440,7 +332,7 @@ func TestApplyMoves(t *testing.T) { }, states.BuildState(func(s *states.SyncState) { s.SetResourceInstanceCurrent( - instAddrs["module.bar[0].foo.from"], + mustParseInstAddr("module.bar[0].foo.from"), &states.ResourceInstanceObjectSrc{ Status: states.ObjectReady, AttrsJSON: []byte(`{}`), @@ -448,7 +340,7 @@ func TestApplyMoves(t *testing.T) { providerAddr, ) s.SetResourceInstanceCurrent( - instAddrs["module.boo.foo.to[0]"], + mustParseInstAddr("module.boo.foo.to[0]"), &states.ResourceInstanceObjectSrc{ Status: states.ObjectReady, AttrsJSON: []byte(`{}`), @@ -462,10 +354,10 @@ func TestApplyMoves(t *testing.T) { Changes: emptyResults.Changes, Blocked: addrs.MakeMap( addrs.MakeMapElem[addrs.AbsMoveable]( - instAddrs["module.bar[0].foo.from"].Module, + mustParseInstAddr("module.bar[0].foo.from").Module, MoveBlocked{ - Wanted: instAddrs["module.boo.foo.to[0]"].Module, - Actual: instAddrs["module.bar[0].foo.from"].Module, + Wanted: mustParseInstAddr("module.boo.foo.to[0]").Module, + Actual: mustParseInstAddr("module.bar[0].foo.from").Module, }, ), ), @@ -482,7 +374,7 @@ func TestApplyMoves(t *testing.T) { }, states.BuildState(func(s *states.SyncState) { s.SetResourceInstanceCurrent( - instAddrs["foo.from"], + mustParseInstAddr("foo.from"), &states.ResourceInstanceObjectSrc{ Status: states.ObjectReady, AttrsJSON: []byte(`{}`), @@ -490,7 +382,7 @@ func TestApplyMoves(t *testing.T) { providerAddr, ) s.SetResourceInstanceCurrent( - instAddrs["foo.to"], + mustParseInstAddr("foo.to"), &states.ResourceInstanceObjectSrc{ Status: states.ObjectReady, AttrsJSON: []byte(`{}`), @@ -504,10 +396,10 @@ func TestApplyMoves(t *testing.T) { Changes: emptyResults.Changes, Blocked: addrs.MakeMap( addrs.MakeMapElem[addrs.AbsMoveable]( - instAddrs["foo.from"].ContainingResource(), + mustParseInstAddr("foo.from").ContainingResource(), MoveBlocked{ - Wanted: instAddrs["foo.to"].ContainingResource(), - Actual: instAddrs["foo.from"].ContainingResource(), + Wanted: mustParseInstAddr("foo.to").ContainingResource(), + Actual: mustParseInstAddr("foo.from").ContainingResource(), }, ), ), @@ -524,7 +416,7 @@ func TestApplyMoves(t *testing.T) { }, states.BuildState(func(s *states.SyncState) { s.SetResourceInstanceCurrent( - instAddrs["foo.from"], + mustParseInstAddr("foo.from"), &states.ResourceInstanceObjectSrc{ Status: states.ObjectReady, AttrsJSON: []byte(`{}`), @@ -532,7 +424,7 @@ func TestApplyMoves(t *testing.T) { providerAddr, ) s.SetResourceInstanceCurrent( - instAddrs["foo.to[0]"], + mustParseInstAddr("foo.to[0]"), &states.ResourceInstanceObjectSrc{ Status: states.ObjectReady, AttrsJSON: []byte(`{}`), @@ -546,10 +438,10 @@ func TestApplyMoves(t *testing.T) { Changes: emptyResults.Changes, Blocked: addrs.MakeMap( addrs.MakeMapElem[addrs.AbsMoveable]( - instAddrs["foo.from"], + mustParseInstAddr("foo.from"), MoveBlocked{ - Wanted: instAddrs["foo.to[0]"], - Actual: instAddrs["foo.from"], + Wanted: mustParseInstAddr("foo.to[0]"), + Actual: mustParseInstAddr("foo.from"), }, ), ), @@ -566,7 +458,7 @@ func TestApplyMoves(t *testing.T) { }, states.BuildState(func(s *states.SyncState) { s.SetResourceInstanceCurrent( - instAddrs["module.boo.foo.from"], + mustParseInstAddr("module.boo.foo.from"), &states.ResourceInstanceObjectSrc{ Status: states.ObjectReady, AttrsJSON: []byte(`{}`), @@ -576,9 +468,9 @@ func TestApplyMoves(t *testing.T) { }), MoveResults{ Changes: addrs.MakeMap( - addrs.MakeMapElem(instAddrs["module.bar[0].foo.to"], MoveSuccess{ - From: instAddrs["module.boo.foo.from"], - To: instAddrs["module.bar[0].foo.to"], + addrs.MakeMapElem(mustParseInstAddr("module.bar[0].foo.to"), MoveSuccess{ + From: mustParseInstAddr("module.boo.foo.from"), + To: mustParseInstAddr("module.bar[0].foo.to"), }), ), Blocked: emptyResults.Blocked, @@ -595,7 +487,7 @@ func TestApplyMoves(t *testing.T) { }, states.BuildState(func(s *states.SyncState) { s.SetResourceInstanceCurrent( - instAddrs["module.bar[0].foo.to"], + mustParseInstAddr("module.bar[0].foo.to"), &states.ResourceInstanceObjectSrc{ Status: states.ObjectReady, AttrsJSON: []byte(`{}`), @@ -603,7 +495,7 @@ func TestApplyMoves(t *testing.T) { providerAddr, ) s.SetResourceInstanceCurrent( - instAddrs["foo.from"], + mustParseInstAddr("foo.from"), &states.ResourceInstanceObjectSrc{ Status: states.ObjectReady, AttrsJSON: []byte(`{}`), @@ -613,13 +505,13 @@ func TestApplyMoves(t *testing.T) { }), MoveResults{ Changes: addrs.MakeMap( - addrs.MakeMapElem(instAddrs["module.boo.foo.from"], MoveSuccess{ - instAddrs["foo.from"], - instAddrs["module.boo.foo.from"], + addrs.MakeMapElem(mustParseInstAddr("module.boo.foo.from"), MoveSuccess{ + mustParseInstAddr("foo.from"), + mustParseInstAddr("module.boo.foo.from"), }), - addrs.MakeMapElem(instAddrs["module.boo.foo.to"], MoveSuccess{ - instAddrs["module.bar[0].foo.to"], - instAddrs["module.boo.foo.to"], + addrs.MakeMapElem(mustParseInstAddr("module.boo.foo.to"), MoveSuccess{ + mustParseInstAddr("module.bar[0].foo.to"), + mustParseInstAddr("module.boo.foo.to"), }), ), Blocked: emptyResults.Blocked, @@ -630,14 +522,15 @@ func TestApplyMoves(t *testing.T) { }, }, - "module move collides with resource move": { + "move resources into module and then move module": { []MoveStatement{ - testMoveStatement(t, "", "module.bar[0]", "module.boo"), - testMoveStatement(t, "", "foo.from", "module.boo.foo.from"), + testMoveStatement(t, "", "foo.from", "module.boo.foo.to"), + testMoveStatement(t, "", "bar.from", "module.boo.bar.to"), + testMoveStatement(t, "", "module.boo", "module.bar[0]"), }, states.BuildState(func(s *states.SyncState) { s.SetResourceInstanceCurrent( - instAddrs["module.bar[0].foo.from"], + mustParseInstAddr("foo.from"), &states.ResourceInstanceObjectSrc{ Status: states.ObjectReady, AttrsJSON: []byte(`{}`), @@ -645,7 +538,7 @@ func TestApplyMoves(t *testing.T) { providerAddr, ) s.SetResourceInstanceCurrent( - instAddrs["foo.from"], + mustParseInstAddr("bar.from"), &states.ResourceInstanceObjectSrc{ Status: states.ObjectReady, AttrsJSON: []byte(`{}`), @@ -655,17 +548,59 @@ func TestApplyMoves(t *testing.T) { }), MoveResults{ Changes: addrs.MakeMap( - addrs.MakeMapElem(instAddrs["module.boo.foo.from"], MoveSuccess{ - instAddrs["module.bar[0].foo.from"], - instAddrs["module.boo.foo.from"], + addrs.MakeMapElem(mustParseInstAddr("module.bar[0].foo.to"), MoveSuccess{ + mustParseInstAddr("foo.from"), + mustParseInstAddr("module.bar[0].foo.to"), + }), + addrs.MakeMapElem(mustParseInstAddr("module.bar[0].bar.to"), MoveSuccess{ + mustParseInstAddr("bar.from"), + mustParseInstAddr("module.bar[0].bar.to"), + }), + ), + Blocked: emptyResults.Blocked, + }, + []string{ + `module.bar[0].bar.to`, + `module.bar[0].foo.to`, + }, + }, + + "module move collides with resource move": { + []MoveStatement{ + testMoveStatement(t, "", "module.bar[0]", "module.boo"), + testMoveStatement(t, "", "foo.from", "module.boo.foo.from"), + }, + states.BuildState(func(s *states.SyncState) { + s.SetResourceInstanceCurrent( + mustParseInstAddr("module.bar[0].foo.from"), + &states.ResourceInstanceObjectSrc{ + Status: states.ObjectReady, + AttrsJSON: []byte(`{}`), + }, + providerAddr, + ) + s.SetResourceInstanceCurrent( + mustParseInstAddr("foo.from"), + &states.ResourceInstanceObjectSrc{ + Status: states.ObjectReady, + AttrsJSON: []byte(`{}`), + }, + providerAddr, + ) + }), + MoveResults{ + Changes: addrs.MakeMap( + addrs.MakeMapElem(mustParseInstAddr("module.boo.foo.from"), MoveSuccess{ + mustParseInstAddr("module.bar[0].foo.from"), + mustParseInstAddr("module.boo.foo.from"), }), ), Blocked: addrs.MakeMap( addrs.MakeMapElem[addrs.AbsMoveable]( - instAddrs["foo.from"].ContainingResource(), + mustParseInstAddr("foo.from").ContainingResource(), MoveBlocked{ - Actual: instAddrs["foo.from"].ContainingResource(), - Wanted: instAddrs["module.boo.foo.from"].ContainingResource(), + Actual: mustParseInstAddr("foo.from").ContainingResource(), + Wanted: mustParseInstAddr("module.boo.foo.from").ContainingResource(), }, ), ),