Merge pull request #23435 from hashicorp/jbardin/cbd-deps

fix CreateBeforeDestroy de-duplication
This commit is contained in:
James Bardin 2019-11-20 22:15:28 -05:00 committed by GitHub
commit 98b0e62fb9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 81 additions and 5 deletions

View File

@ -0,0 +1,15 @@
resource "test_object" "A" {
lifecycle {
create_before_destroy = true
}
}
resource "test_object" "B" {
lifecycle {
create_before_destroy = true
}
}
resource "test_object" "C" {
test_string = "${test_object.A.id}-${test_object.B.id}"
}

View File

@ -259,7 +259,9 @@ func (t *CBDEdgeTransformer) depMap(g *Graph, destroyMap map[string][]dag.Vertex
// Build the list of destroy nodes that each resource address should depend
// on. For example, when we find B, we map the address of B to A_d in the
// "depMap" variable below.
depMap := make(map[string][]dag.Vertex)
// Use a nested map to remove duplicate edges.
depMap := make(map[string]map[dag.Vertex]struct{})
for _, v := range g.Vertices() {
// We're looking for resources.
rn, ok := v.(GraphNodeResource)
@ -294,12 +296,24 @@ func (t *CBDEdgeTransformer) depMap(g *Graph, destroyMap map[string][]dag.Vertex
// needs to depend on.
key := rn.ResourceAddr().String()
// we only need to record the same dns once
if _, ok := depMap[key]; !ok {
depMap[key] = append(depMap[key], dns...)
deps, ok := depMap[key]
if !ok {
deps = make(map[dag.Vertex]struct{})
}
for _, d := range dns {
deps[d] = struct{}{}
}
depMap[key] = deps
}
}
return depMap, nil
result := map[string][]dag.Vertex{}
for k, m := range depMap {
for v := range m {
result[k] = append(result[k], v)
}
}
return result, nil
}

View File

@ -95,6 +95,53 @@ test_object.B
}
}
func TestCBDEdgeTransformerMulti(t *testing.T) {
changes := &plans.Changes{
Resources: []*plans.ResourceInstanceChangeSrc{
{
Addr: mustResourceInstanceAddr("test_object.A"),
ChangeSrc: plans.ChangeSrc{
Action: plans.CreateThenDelete,
},
},
{
Addr: mustResourceInstanceAddr("test_object.B"),
ChangeSrc: plans.ChangeSrc{
Action: plans.CreateThenDelete,
},
},
{
Addr: mustResourceInstanceAddr("test_object.C"),
ChangeSrc: plans.ChangeSrc{
Action: plans.Update,
},
},
},
}
g := cbdTestGraph(t, "transform-destroy-cbd-edge-multi", changes)
g = filterInstances(g)
actual := strings.TrimSpace(g.String())
expected := regexp.MustCompile(strings.TrimSpace(`
(?m)test_object.A
test_object.A \(destroy deposed \w+\)
test_object.A
test_object.C
test_object.B
test_object.B \(destroy deposed \w+\)
test_object.B
test_object.C
test_object.C
test_object.A
test_object.B
`))
if !expected.MatchString(actual) {
t.Fatalf("wrong result\n\ngot:\n%s\n\nwant:\n%s", actual, expected)
}
}
func TestCBDEdgeTransformer_depNonCBDCount(t *testing.T) {
changes := &plans.Changes{
Resources: []*plans.ResourceInstanceChangeSrc{