terraform: Add value check to diff.Same

A diff new needs to pass basic value checks to be considered the
"same". Several provisions have been added to ensure that the list, set,
and RequiresNew behaviours that have needed some exceptions in the past
are preserved in this new logic.

This ensures that we are checking for value equality as much as
possible, which will be more important when we transition to the
possibility of diffs being sourced from external data.
This commit is contained in:
Chris Marchesi 2017-07-03 10:19:35 -07:00 committed by Martin Atkins
parent f5bdbc0911
commit 12378b4ee2
2 changed files with 55 additions and 2 deletions

View File

@ -748,7 +748,7 @@ func (d *InstanceDiff) Same(d2 *InstanceDiff) (bool, string) {
delete(checkOld, k)
delete(checkNew, k)
_, ok := d2.GetAttribute(k)
diffNew, ok := d2.GetAttribute(k)
if !ok {
// If there's no new attribute, and the old diff expected the attribute
// to be removed, that's just fine.
@ -837,7 +837,40 @@ func (d *InstanceDiff) Same(d2 *InstanceDiff) (bool, string) {
}
}
// TODO: check for the same value if not computed
// If our attributes are not computed, then there is no reason why we can't
// check to make sure the diff values are the same. Do that now.
//
// Single-value NewComputed values pass
if diffOld.NewComputed {
continue
}
// Computed keys for sets and lists pass
if strings.Contains(k, "~") {
continue
}
// Counts for sets need to be skipped as well as we have determined that we
// may not know the full value due to interpolation
if strings.HasSuffix(k, "#") {
continue
}
// Lists can be skipped if they are being removed (going from n > 0 to 0)
if strings.HasSuffix(k, "%") && diffOld.New == "0" && diffOld.Old != "0" {
continue
}
// If both old and new are RequiresNew, we are okay if both new values
// match.
if diffOld.RequiresNew && diffNew.RequiresNew && diffOld.New == diffNew.New {
continue
}
// At this point, we should be able to just check for deep equality.
if !reflect.DeepEqual(diffOld, diffNew) {
return false, fmt.Sprintf("value mismatch: %s", k)
}
}
// Check for leftover attributes

View File

@ -1131,6 +1131,26 @@ func TestInstanceDiffSame(t *testing.T) {
true,
"",
},
{
&InstanceDiff{
Attributes: map[string]*ResourceAttrDiff{
"foo": &ResourceAttrDiff{
Old: "1",
New: "2",
},
},
},
&InstanceDiff{
Attributes: map[string]*ResourceAttrDiff{
"foo": &ResourceAttrDiff{
Old: "1",
New: "3",
},
},
},
false,
"value mismatch: foo",
},
}
for i, tc := range cases {