Merge pull request #13502 from hashicorp/jbardin/dedupe-depends_on
Remove duplicate entries from resource Dependencies
This commit is contained in:
commit
7d4cceb787
|
@ -8100,3 +8100,32 @@ func TestContext2Apply_terraformEnv(t *testing.T) {
|
|||
t.Fatalf("bad: \n%s", actual)
|
||||
}
|
||||
}
|
||||
|
||||
// verify that multiple config references only create a single depends_on entry
|
||||
func TestContext2Apply_multiRef(t *testing.T) {
|
||||
m := testModule(t, "apply-multi-ref")
|
||||
p := testProvider("aws")
|
||||
p.ApplyFn = testApplyFn
|
||||
p.DiffFn = testDiffFn
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Module: m,
|
||||
Providers: map[string]ResourceProviderFactory{
|
||||
"aws": testProviderFuncFixed(p),
|
||||
},
|
||||
})
|
||||
|
||||
if _, err := ctx.Plan(); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
state, err := ctx.Apply()
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
deps := state.Modules[0].Resources["aws_instance.other"].Dependencies
|
||||
if len(deps) > 1 || deps[0] != "aws_instance.create" {
|
||||
t.Fatalf("expected 1 depends_on entry for aws_instance.create, got %q", deps)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -102,7 +102,7 @@ func (n *NodeAbstractResource) References() []string {
|
|||
}
|
||||
}
|
||||
|
||||
return result
|
||||
return uniqueStrings(result)
|
||||
}
|
||||
|
||||
// If we have state, that is our next source
|
||||
|
|
|
@ -1163,6 +1163,8 @@ func (m *ModuleState) prune() {
|
|||
delete(m.Outputs, k)
|
||||
}
|
||||
}
|
||||
|
||||
m.Dependencies = uniqueStrings(m.Dependencies)
|
||||
}
|
||||
|
||||
func (m *ModuleState) sort() {
|
||||
|
@ -1526,8 +1528,9 @@ func (s *ResourceState) prune() {
|
|||
i--
|
||||
}
|
||||
}
|
||||
|
||||
s.Deposed = s.Deposed[:n]
|
||||
|
||||
s.Dependencies = uniqueStrings(s.Dependencies)
|
||||
}
|
||||
|
||||
func (s *ResourceState) sort() {
|
||||
|
|
|
@ -1898,6 +1898,62 @@ func TestReadState_prune(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestReadState_pruneDependencies(t *testing.T) {
|
||||
state := &State{
|
||||
Serial: 9,
|
||||
Lineage: "5d1ad1a1-4027-4665-a908-dbe6adff11d8",
|
||||
Remote: &RemoteState{
|
||||
Type: "http",
|
||||
Config: map[string]string{
|
||||
"url": "http://my-cool-server.com/",
|
||||
},
|
||||
},
|
||||
Modules: []*ModuleState{
|
||||
&ModuleState{
|
||||
Path: rootModulePath,
|
||||
Dependencies: []string{
|
||||
"aws_instance.bar",
|
||||
"aws_instance.bar",
|
||||
},
|
||||
Resources: map[string]*ResourceState{
|
||||
"foo": &ResourceState{
|
||||
Dependencies: []string{
|
||||
"aws_instance.baz",
|
||||
"aws_instance.baz",
|
||||
},
|
||||
Primary: &InstanceState{
|
||||
ID: "bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
state.init()
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
if err := WriteState(state, buf); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
actual, err := ReadState(buf)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
// make sure the duplicate Dependencies are filtered
|
||||
modDeps := actual.Modules[0].Dependencies
|
||||
resourceDeps := actual.Modules[0].Resources["foo"].Dependencies
|
||||
|
||||
if len(modDeps) > 1 || modDeps[0] != "aws_instance.bar" {
|
||||
t.Fatalf("expected 1 module depends_on entry, got %q", modDeps)
|
||||
}
|
||||
|
||||
if len(resourceDeps) > 1 || resourceDeps[0] != "aws_instance.baz" {
|
||||
t.Fatalf("expected 1 resource depends_on entry, got %q", resourceDeps)
|
||||
}
|
||||
}
|
||||
|
||||
func TestResourceNameSort(t *testing.T) {
|
||||
names := []string{
|
||||
"a",
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
resource "aws_instance" "create" {
|
||||
bar = "abc"
|
||||
}
|
||||
|
||||
resource "aws_instance" "other" {
|
||||
var = "${aws_instance.create.id}"
|
||||
foo = "${aws_instance.create.bar}"
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package terraform
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
|
@ -73,3 +74,20 @@ func strSliceContains(haystack []string, needle string) bool {
|
|||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// deduplicate a slice of strings
|
||||
func uniqueStrings(s []string) []string {
|
||||
if len(s) < 2 {
|
||||
return s
|
||||
}
|
||||
|
||||
sort.Strings(s)
|
||||
result := make([]string, 1, len(s))
|
||||
result[0] = s[0]
|
||||
for i := 1; i < len(s); i++ {
|
||||
if s[i] != result[len(result)-1] {
|
||||
result = append(result, s[i])
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package terraform
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
@ -96,3 +98,44 @@ func TestUtilResourceProvider(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestUniqueStrings(t *testing.T) {
|
||||
cases := []struct {
|
||||
Input []string
|
||||
Expected []string
|
||||
}{
|
||||
{
|
||||
[]string{},
|
||||
[]string{},
|
||||
},
|
||||
{
|
||||
[]string{"x"},
|
||||
[]string{"x"},
|
||||
},
|
||||
{
|
||||
[]string{"a", "b", "c"},
|
||||
[]string{"a", "b", "c"},
|
||||
},
|
||||
{
|
||||
[]string{"a", "a", "a"},
|
||||
[]string{"a"},
|
||||
},
|
||||
{
|
||||
[]string{"a", "b", "a", "b", "a", "a"},
|
||||
[]string{"a", "b"},
|
||||
},
|
||||
{
|
||||
[]string{"c", "b", "a", "c", "b"},
|
||||
[]string{"a", "b", "c"},
|
||||
},
|
||||
}
|
||||
|
||||
for i, tc := range cases {
|
||||
t.Run(fmt.Sprintf("unique-%d", i), func(t *testing.T) {
|
||||
actual := uniqueStrings(tc.Input)
|
||||
if !reflect.DeepEqual(tc.Expected, actual) {
|
||||
t.Fatalf("Expected: %q\nGot: %q", tc.Expected, actual)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue