diff --git a/terraform/diff.go b/terraform/diff.go index dbaf37e024..97fb6cc478 100644 --- a/terraform/diff.go +++ b/terraform/diff.go @@ -357,18 +357,20 @@ func (d *InstanceDiff) RequiresNew() bool { // we say "same", it is not necessarily exactly equal. Instead, it is // just checking that the same attributes are changing, a destroy // isn't suddenly happening, etc. -func (d *InstanceDiff) Same(d2 *InstanceDiff) bool { +func (d *InstanceDiff) Same(d2 *InstanceDiff) (bool, string) { if d == nil && d2 == nil { - return true + return true, "" } else if d == nil || d2 == nil { - return false + return false, "both nil" } if d.Destroy != d2.Destroy { - return false + return false, fmt.Sprintf( + "diff: Destroy; old: %t, new: %t", d.Destroy, d2.Destroy) } if d.RequiresNew() != d2.RequiresNew() { - return false + return false, fmt.Sprintf( + "diff RequiresNew; old: %t, new: %t", d.RequiresNew(), d2.RequiresNew()) } // Go through the old diff and make sure the new diff has all the @@ -420,7 +422,7 @@ func (d *InstanceDiff) Same(d2 *InstanceDiff) bool { } re, err := regexp.Compile("^" + strings.Join(parts2, `\.`) + "$") if err != nil { - return false + return false, fmt.Sprintf("regexp failed to compile; err: %#v", err) } for k2, _ := range checkNew { if re.MatchString(k2) { @@ -452,7 +454,7 @@ func (d *InstanceDiff) Same(d2 *InstanceDiff) bool { } if !ok { - return false + return false, fmt.Sprintf("attribute mismatch: %s", k) } } @@ -477,8 +479,13 @@ func (d *InstanceDiff) Same(d2 *InstanceDiff) bool { // Check for leftover attributes if len(checkNew) > 0 { - return false + extras := make([]string, 0, len(checkNew)) + for attr, _ := range checkNew { + extras = append(extras, attr) + } + return false, + fmt.Sprintf("extra attributes: %s", strings.Join(extras, ", ")) } - return true + return true, "" } diff --git a/terraform/diff_test.go b/terraform/diff_test.go index 00e958cfea..d65ff455d8 100644 --- a/terraform/diff_test.go +++ b/terraform/diff_test.go @@ -361,29 +361,34 @@ func TestInstanceDiffSame(t *testing.T) { cases := []struct { One, Two *InstanceDiff Same bool + Reason string }{ { &InstanceDiff{}, &InstanceDiff{}, true, + "", }, { nil, nil, true, + "", }, { &InstanceDiff{Destroy: false}, &InstanceDiff{Destroy: true}, false, + "diff: Destroy; old: false, new: true", }, { &InstanceDiff{Destroy: true}, &InstanceDiff{Destroy: true}, true, + "", }, { @@ -398,6 +403,7 @@ func TestInstanceDiffSame(t *testing.T) { }, }, true, + "", }, { @@ -412,6 +418,7 @@ func TestInstanceDiffSame(t *testing.T) { }, }, false, + "attribute mismatch: bar", }, // Extra attributes @@ -428,6 +435,7 @@ func TestInstanceDiffSame(t *testing.T) { }, }, false, + "extra attributes: bar", }, { @@ -442,6 +450,7 @@ func TestInstanceDiffSame(t *testing.T) { }, }, false, + "diff RequiresNew; old: true, new: false", }, { @@ -463,6 +472,7 @@ func TestInstanceDiffSame(t *testing.T) { }, }, true, + "", }, { @@ -491,6 +501,7 @@ func TestInstanceDiffSame(t *testing.T) { }, }, true, + "", }, { @@ -506,14 +517,19 @@ func TestInstanceDiffSame(t *testing.T) { Attributes: map[string]*ResourceAttrDiff{}, }, true, + "", }, } for i, tc := range cases { - actual := tc.One.Same(tc.Two) - if actual != tc.Same { + same, reason := tc.One.Same(tc.Two) + if same != tc.Same { t.Fatalf("%d:\n\n%#v\n\n%#v", i, tc.One, tc.Two) } + if reason != tc.Reason { + t.Fatalf( + "%d: bad reason\n\nexpected: %#v\n\ngot: %#v", i, tc.Reason, reason) + } } } diff --git a/terraform/eval_diff.go b/terraform/eval_diff.go index 4a06f4c431..0dfc96589c 100644 --- a/terraform/eval_diff.go +++ b/terraform/eval_diff.go @@ -38,8 +38,9 @@ func (n *EvalCompareDiff) Eval(ctx EvalContext) (interface{}, error) { } }() - if !one.Same(two) { - log.Printf("[ERROR] %s: diff's didn't match", n.Info.Id) + if same, reason := one.Same(two); !same { + log.Printf("[ERROR] %s: diffs didn't match", n.Info.Id) + log.Printf("[ERROR] %s: reason: %s", n.Info.Id, reason) log.Printf("[ERROR] %s: diff one: %#v", n.Info.Id, one) log.Printf("[ERROR] %s: diff two: %#v", n.Info.Id, two) return nil, fmt.Errorf(