terraform: Add more exception cases for value comparison

Needed to add more cases to support value comparison exceptions that the
rest of TF expects to work (this fixes tests in various places).

Also moved things to a switch block so that it's a little more compact.
This commit is contained in:
Chris Marchesi 2017-07-03 12:59:42 -07:00 committed by Martin Atkins
parent 12378b4ee2
commit 5031767b93
2 changed files with 77 additions and 30 deletions

View File

@ -840,36 +840,27 @@ func (d *InstanceDiff) Same(d2 *InstanceDiff) (bool, string) {
// If our attributes are not computed, then there is no reason why we can't // 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. // check to make sure the diff values are the same. Do that now.
// //
// Single-value NewComputed values pass // There are several conditions that we need to pass here as they are
if diffOld.NewComputed { // allowed cases even if values don't match, so let's check those first.
continue switch {
} case diffOld.NewComputed:
// NewComputed values pass
// Computed keys for sets and lists pass case strings.Contains(k, "~"):
if strings.Contains(k, "~") { // Computed keys for sets and lists
continue case strings.HasSuffix(k, "#"):
} // Counts for sets need to be skipped as well as we have determined that
// we may not know the full value due to interpolation
// Counts for sets need to be skipped as well as we have determined that we case strings.HasSuffix(k, "%") && diffOld.New == "0" && diffOld.Old != "0":
// may not know the full value due to interpolation // Lists can be skipped if they are being removed (going from n > 0 to 0)
if strings.HasSuffix(k, "#") { case d.DestroyTainted && d2.GetDestroyTainted() && diffOld.New == diffNew.New:
continue // Same for DestoryTainted
} case d.requiresNew() && d2.RequiresNew() && diffOld.New == diffNew.New:
// Same for RequiresNew
// Lists can be skipped if they are being removed (going from n > 0 to 0) default:
if strings.HasSuffix(k, "%") && diffOld.New == "0" && diffOld.Old != "0" { // Anything that gets here should be able to be checked for deep equality.
continue if !reflect.DeepEqual(diffOld, diffNew) {
} return false, fmt.Sprintf("value mismatch: %s", k)
}
// 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)
} }
} }

View File

@ -1151,6 +1151,62 @@ func TestInstanceDiffSame(t *testing.T) {
false, false,
"value mismatch: foo", "value mismatch: foo",
}, },
// Make sure that DestroyTainted diffs pass as well, especially when diff
// two works off of no state.
{
&InstanceDiff{
DestroyTainted: true,
Attributes: map[string]*ResourceAttrDiff{
"foo": &ResourceAttrDiff{
Old: "foo",
New: "foo",
},
},
},
&InstanceDiff{
DestroyTainted: true,
Attributes: map[string]*ResourceAttrDiff{
"foo": &ResourceAttrDiff{
Old: "",
New: "foo",
},
},
},
true,
"",
},
// RequiresNew in different attribute
{
&InstanceDiff{
Attributes: map[string]*ResourceAttrDiff{
"foo": &ResourceAttrDiff{
Old: "foo",
New: "foo",
},
"bar": &ResourceAttrDiff{
Old: "bar",
New: "baz",
RequiresNew: true,
},
},
},
&InstanceDiff{
Attributes: map[string]*ResourceAttrDiff{
"foo": &ResourceAttrDiff{
Old: "",
New: "foo",
},
"bar": &ResourceAttrDiff{
Old: "",
New: "baz",
RequiresNew: true,
},
},
},
true,
"",
},
} }
for i, tc := range cases { for i, tc := range cases {