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