Remove computed maps from the diff Same check

Just like computed sets, computed maps may have both different values
and different cardinality after they're computed. Remove the computed
maps and the values from the compared diffs.
This commit is contained in:
James Bardin 2016-06-20 18:18:25 -04:00
parent 33053f8170
commit 0e507e7e5e
2 changed files with 44 additions and 10 deletions

View File

@ -471,12 +471,12 @@ func (d *InstanceDiff) Same(d2 *InstanceDiff) (bool, string) {
} }
} }
// This is a little tricky, but when a diff contains a computed list // This is a little tricky, but when a diff contains a computed
// or set that can only be interpolated after the apply command has // list, set, or map that can only be interpolated after the apply
// created the dependent resources, it could turn out that the result // command has created the dependent resources, it could turn out
// is actually the same as the existing state which would remove the // that the result is actually the same as the existing state which
// key from the diff. // would remove the key from the diff.
if diffOld.NewComputed && strings.HasSuffix(k, ".#") { if diffOld.NewComputed && (strings.HasSuffix(k, ".#") || strings.HasSuffix(k, ".%")) {
ok = true ok = true
} }
@ -492,10 +492,16 @@ func (d *InstanceDiff) Same(d2 *InstanceDiff) (bool, string) {
} }
} }
if diffOld.NewComputed && strings.HasSuffix(k, ".#") { // search for the suffix of the base of a [computed] map, list or set.
// This is a computed list or set, so remove any keys with this multiVal := regexp.MustCompile(`\.(#|~#|%)$`)
// prefix from the check list. match := multiVal.FindStringSubmatch(k)
kprefix := k[:len(k)-1]
if diffOld.NewComputed && len(match) == 2 {
matchLen := len(match[1])
// This is a computed list, set, or map, so remove any keys with
// this prefix from the check list.
kprefix := k[:len(k)-matchLen]
for k2, _ := range checkOld { for k2, _ := range checkOld {
if strings.HasPrefix(k2, kprefix) { if strings.HasPrefix(k2, kprefix) {
delete(checkOld, k2) delete(checkOld, k2)

View File

@ -566,6 +566,34 @@ func TestInstanceDiffSame(t *testing.T) {
"", "",
}, },
// Computed values in maps will fail the "Same" check as well
{
&InstanceDiff{
Attributes: map[string]*ResourceAttrDiff{
"foo.%": &ResourceAttrDiff{
Old: "",
New: "",
NewComputed: true,
},
},
},
&InstanceDiff{
Attributes: map[string]*ResourceAttrDiff{
"foo.%": &ResourceAttrDiff{
Old: "0",
New: "1",
NewComputed: false,
},
"foo.val": &ResourceAttrDiff{
Old: "",
New: "something",
},
},
},
true,
"",
},
// In a DESTROY/CREATE scenario, the plan diff will be run against the // In a DESTROY/CREATE scenario, the plan diff will be run against the
// state of the old instance, while the apply diff will be run against an // state of the old instance, while the apply diff will be run against an
// empty state (because the state is cleared when the destroy runs.) // empty state (because the state is cleared when the destroy runs.)