2014-06-05 15:57:06 +02:00
|
|
|
package terraform
|
|
|
|
|
|
|
|
import (
|
2014-10-10 22:46:44 +02:00
|
|
|
"reflect"
|
2014-06-10 20:22:32 +02:00
|
|
|
"strings"
|
|
|
|
"testing"
|
2014-06-05 15:57:06 +02:00
|
|
|
)
|
|
|
|
|
2014-09-24 23:37:24 +02:00
|
|
|
func TestDiffEmpty(t *testing.T) {
|
|
|
|
diff := new(Diff)
|
|
|
|
if !diff.Empty() {
|
|
|
|
t.Fatal("should be empty")
|
|
|
|
}
|
|
|
|
|
|
|
|
mod := diff.AddModule(rootModulePath)
|
|
|
|
mod.Resources["nodeA"] = &InstanceDiff{
|
|
|
|
Attributes: map[string]*ResourceAttrDiff{
|
|
|
|
"foo": &ResourceAttrDiff{
|
|
|
|
Old: "foo",
|
|
|
|
New: "bar",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
if diff.Empty() {
|
|
|
|
t.Fatal("should not be empty")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-13 00:20:09 +02:00
|
|
|
func TestDiffEmpty_taintedIsNotEmpty(t *testing.T) {
|
|
|
|
diff := new(Diff)
|
|
|
|
|
|
|
|
mod := diff.AddModule(rootModulePath)
|
|
|
|
mod.Resources["nodeA"] = &InstanceDiff{
|
|
|
|
DestroyTainted: true,
|
|
|
|
}
|
|
|
|
|
|
|
|
if diff.Empty() {
|
|
|
|
t.Fatal("should not be empty, since DestroyTainted was set")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-25 02:51:45 +02:00
|
|
|
func TestModuleDiff_ChangeType(t *testing.T) {
|
|
|
|
cases := []struct {
|
|
|
|
Diff *ModuleDiff
|
|
|
|
Result DiffChangeType
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
&ModuleDiff{},
|
|
|
|
DiffNone,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
&ModuleDiff{
|
|
|
|
Resources: map[string]*InstanceDiff{
|
|
|
|
"foo": &InstanceDiff{Destroy: true},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
DiffDestroy,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
&ModuleDiff{
|
|
|
|
Resources: map[string]*InstanceDiff{
|
|
|
|
"foo": &InstanceDiff{
|
|
|
|
Attributes: map[string]*ResourceAttrDiff{
|
|
|
|
"foo": &ResourceAttrDiff{
|
|
|
|
Old: "",
|
|
|
|
New: "bar",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
DiffUpdate,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
&ModuleDiff{
|
|
|
|
Resources: map[string]*InstanceDiff{
|
|
|
|
"foo": &InstanceDiff{
|
|
|
|
Attributes: map[string]*ResourceAttrDiff{
|
|
|
|
"foo": &ResourceAttrDiff{
|
|
|
|
Old: "",
|
|
|
|
New: "bar",
|
|
|
|
RequiresNew: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
DiffCreate,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
&ModuleDiff{
|
|
|
|
Resources: map[string]*InstanceDiff{
|
|
|
|
"foo": &InstanceDiff{
|
|
|
|
Destroy: true,
|
|
|
|
Attributes: map[string]*ResourceAttrDiff{
|
|
|
|
"foo": &ResourceAttrDiff{
|
|
|
|
Old: "",
|
|
|
|
New: "bar",
|
|
|
|
RequiresNew: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
DiffUpdate,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for i, tc := range cases {
|
|
|
|
actual := tc.Diff.ChangeType()
|
|
|
|
if actual != tc.Result {
|
2014-11-02 13:56:44 +01:00
|
|
|
t.Fatalf("%d: %#v", i, actual)
|
2014-09-25 02:51:45 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-03 20:13:49 +02:00
|
|
|
func TestDiff_DeepCopy(t *testing.T) {
|
|
|
|
cases := map[string]*Diff{
|
|
|
|
"empty": &Diff{},
|
|
|
|
|
|
|
|
"basic diff": &Diff{
|
|
|
|
Modules: []*ModuleDiff{
|
|
|
|
&ModuleDiff{
|
|
|
|
Path: []string{"root"},
|
|
|
|
Resources: map[string]*InstanceDiff{
|
|
|
|
"aws_instance.foo": &InstanceDiff{
|
|
|
|
Attributes: map[string]*ResourceAttrDiff{
|
|
|
|
"num": &ResourceAttrDiff{
|
|
|
|
Old: "0",
|
|
|
|
New: "2",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for name, tc := range cases {
|
|
|
|
t.Run(name, func(t *testing.T) {
|
|
|
|
dup := tc.DeepCopy()
|
|
|
|
if !reflect.DeepEqual(dup, tc) {
|
|
|
|
t.Fatalf("\n%#v\n\n%#v", dup, tc)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-23 20:43:21 +02:00
|
|
|
func TestModuleDiff_Empty(t *testing.T) {
|
|
|
|
diff := new(ModuleDiff)
|
2014-06-19 23:57:36 +02:00
|
|
|
if !diff.Empty() {
|
|
|
|
t.Fatal("should be empty")
|
|
|
|
}
|
|
|
|
|
2014-09-18 01:33:24 +02:00
|
|
|
diff.Resources = map[string]*InstanceDiff{
|
|
|
|
"nodeA": &InstanceDiff{},
|
2014-06-19 23:57:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if !diff.Empty() {
|
|
|
|
t.Fatal("should be empty")
|
|
|
|
}
|
|
|
|
|
|
|
|
diff.Resources["nodeA"].Attributes = map[string]*ResourceAttrDiff{
|
|
|
|
"foo": &ResourceAttrDiff{
|
|
|
|
Old: "foo",
|
|
|
|
New: "bar",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
if diff.Empty() {
|
|
|
|
t.Fatal("should not be empty")
|
|
|
|
}
|
2014-06-26 07:19:27 +02:00
|
|
|
|
|
|
|
diff.Resources["nodeA"].Attributes = nil
|
|
|
|
diff.Resources["nodeA"].Destroy = true
|
|
|
|
|
|
|
|
if diff.Empty() {
|
|
|
|
t.Fatal("should not be empty")
|
|
|
|
}
|
2014-06-19 23:57:36 +02:00
|
|
|
}
|
|
|
|
|
2014-09-23 20:43:21 +02:00
|
|
|
func TestModuleDiff_String(t *testing.T) {
|
|
|
|
diff := &ModuleDiff{
|
2014-09-18 01:33:24 +02:00
|
|
|
Resources: map[string]*InstanceDiff{
|
|
|
|
"nodeA": &InstanceDiff{
|
2014-06-10 20:22:32 +02:00
|
|
|
Attributes: map[string]*ResourceAttrDiff{
|
|
|
|
"foo": &ResourceAttrDiff{
|
|
|
|
Old: "foo",
|
|
|
|
New: "bar",
|
|
|
|
},
|
|
|
|
"bar": &ResourceAttrDiff{
|
|
|
|
Old: "foo",
|
|
|
|
NewComputed: true,
|
|
|
|
},
|
2014-06-10 20:30:54 +02:00
|
|
|
"longfoo": &ResourceAttrDiff{
|
2014-06-10 20:33:59 +02:00
|
|
|
Old: "foo",
|
|
|
|
New: "bar",
|
|
|
|
RequiresNew: true,
|
2014-06-10 20:30:54 +02:00
|
|
|
},
|
2016-05-28 02:00:59 +02:00
|
|
|
"secretfoo": &ResourceAttrDiff{
|
|
|
|
Old: "foo",
|
|
|
|
New: "bar",
|
|
|
|
Sensitive: true,
|
|
|
|
},
|
2014-06-10 20:22:32 +02:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2014-06-05 15:57:06 +02:00
|
|
|
}
|
2014-06-06 05:17:03 +02:00
|
|
|
|
2014-06-10 20:22:32 +02:00
|
|
|
actual := strings.TrimSpace(diff.String())
|
2014-09-23 20:43:21 +02:00
|
|
|
expected := strings.TrimSpace(moduleDiffStrBasic)
|
2014-06-10 20:22:32 +02:00
|
|
|
if actual != expected {
|
|
|
|
t.Fatalf("bad:\n%s", actual)
|
2014-06-05 15:57:06 +02:00
|
|
|
}
|
|
|
|
}
|
2014-06-10 20:22:32 +02:00
|
|
|
|
2014-09-25 02:51:45 +02:00
|
|
|
func TestInstanceDiff_ChangeType(t *testing.T) {
|
|
|
|
cases := []struct {
|
|
|
|
Diff *InstanceDiff
|
|
|
|
Result DiffChangeType
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
&InstanceDiff{},
|
|
|
|
DiffNone,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
&InstanceDiff{Destroy: true},
|
|
|
|
DiffDestroy,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
&InstanceDiff{
|
|
|
|
Attributes: map[string]*ResourceAttrDiff{
|
|
|
|
"foo": &ResourceAttrDiff{
|
|
|
|
Old: "",
|
|
|
|
New: "bar",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
DiffUpdate,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
&InstanceDiff{
|
|
|
|
Attributes: map[string]*ResourceAttrDiff{
|
|
|
|
"foo": &ResourceAttrDiff{
|
|
|
|
Old: "",
|
|
|
|
New: "bar",
|
|
|
|
RequiresNew: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
DiffCreate,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
&InstanceDiff{
|
|
|
|
Destroy: true,
|
|
|
|
Attributes: map[string]*ResourceAttrDiff{
|
|
|
|
"foo": &ResourceAttrDiff{
|
|
|
|
Old: "",
|
|
|
|
New: "bar",
|
|
|
|
RequiresNew: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
DiffDestroyCreate,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
&InstanceDiff{
|
|
|
|
DestroyTainted: true,
|
|
|
|
Attributes: map[string]*ResourceAttrDiff{
|
|
|
|
"foo": &ResourceAttrDiff{
|
|
|
|
Old: "",
|
|
|
|
New: "bar",
|
|
|
|
RequiresNew: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
DiffDestroyCreate,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for i, tc := range cases {
|
|
|
|
actual := tc.Diff.ChangeType()
|
|
|
|
if actual != tc.Result {
|
2014-11-02 13:56:44 +01:00
|
|
|
t.Fatalf("%d: %#v", i, actual)
|
2014-09-25 02:51:45 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestInstanceDiff_Empty(t *testing.T) {
|
2014-09-18 01:33:24 +02:00
|
|
|
var rd *InstanceDiff
|
2014-07-01 05:56:25 +02:00
|
|
|
|
|
|
|
if !rd.Empty() {
|
|
|
|
t.Fatal("should be empty")
|
|
|
|
}
|
|
|
|
|
2014-09-18 01:33:24 +02:00
|
|
|
rd = new(InstanceDiff)
|
2014-07-01 05:56:25 +02:00
|
|
|
|
|
|
|
if !rd.Empty() {
|
|
|
|
t.Fatal("should be empty")
|
|
|
|
}
|
|
|
|
|
2014-09-18 01:33:24 +02:00
|
|
|
rd = &InstanceDiff{Destroy: true}
|
2014-07-01 05:56:25 +02:00
|
|
|
|
|
|
|
if rd.Empty() {
|
|
|
|
t.Fatal("should not be empty")
|
|
|
|
}
|
|
|
|
|
2014-09-18 01:33:24 +02:00
|
|
|
rd = &InstanceDiff{
|
2014-07-01 05:56:25 +02:00
|
|
|
Attributes: map[string]*ResourceAttrDiff{
|
|
|
|
"foo": &ResourceAttrDiff{
|
|
|
|
New: "bar",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
if rd.Empty() {
|
|
|
|
t.Fatal("should not be empty")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-10 22:46:44 +02:00
|
|
|
func TestModuleDiff_Instances(t *testing.T) {
|
|
|
|
yesDiff := &InstanceDiff{Destroy: true}
|
|
|
|
noDiff := &InstanceDiff{Destroy: true, DestroyTainted: true}
|
|
|
|
|
|
|
|
cases := []struct {
|
|
|
|
Diff *ModuleDiff
|
|
|
|
Id string
|
|
|
|
Result []*InstanceDiff
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
&ModuleDiff{
|
|
|
|
Resources: map[string]*InstanceDiff{
|
|
|
|
"foo": yesDiff,
|
|
|
|
"bar": noDiff,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"foo",
|
|
|
|
[]*InstanceDiff{
|
|
|
|
yesDiff,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
&ModuleDiff{
|
|
|
|
Resources: map[string]*InstanceDiff{
|
|
|
|
"foo": yesDiff,
|
|
|
|
"foo.0": yesDiff,
|
|
|
|
"bar": noDiff,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"foo",
|
|
|
|
[]*InstanceDiff{
|
|
|
|
yesDiff,
|
|
|
|
yesDiff,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
&ModuleDiff{
|
|
|
|
Resources: map[string]*InstanceDiff{
|
|
|
|
"foo": yesDiff,
|
|
|
|
"foo.0": yesDiff,
|
|
|
|
"foo_bar": noDiff,
|
|
|
|
"bar": noDiff,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"foo",
|
|
|
|
[]*InstanceDiff{
|
|
|
|
yesDiff,
|
|
|
|
yesDiff,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for i, tc := range cases {
|
|
|
|
actual := tc.Diff.Instances(tc.Id)
|
|
|
|
if !reflect.DeepEqual(actual, tc.Result) {
|
|
|
|
t.Fatalf("%d: %#v", i, actual)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-25 02:51:45 +02:00
|
|
|
func TestInstanceDiff_RequiresNew(t *testing.T) {
|
2014-09-18 01:33:24 +02:00
|
|
|
rd := &InstanceDiff{
|
2014-06-18 03:10:38 +02:00
|
|
|
Attributes: map[string]*ResourceAttrDiff{
|
|
|
|
"foo": &ResourceAttrDiff{},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
if rd.RequiresNew() {
|
|
|
|
t.Fatal("should not require new")
|
|
|
|
}
|
|
|
|
|
|
|
|
rd.Attributes["foo"].RequiresNew = true
|
|
|
|
|
|
|
|
if !rd.RequiresNew() {
|
|
|
|
t.Fatal("should require new")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-25 02:51:45 +02:00
|
|
|
func TestInstanceDiff_RequiresNew_nil(t *testing.T) {
|
2014-09-18 01:33:24 +02:00
|
|
|
var rd *InstanceDiff
|
2014-06-18 03:10:38 +02:00
|
|
|
|
|
|
|
if rd.RequiresNew() {
|
|
|
|
t.Fatal("should not require new")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-25 02:51:45 +02:00
|
|
|
func TestInstanceDiffSame(t *testing.T) {
|
2014-07-23 04:39:48 +02:00
|
|
|
cases := []struct {
|
2014-09-18 01:33:24 +02:00
|
|
|
One, Two *InstanceDiff
|
2014-07-23 04:39:48 +02:00
|
|
|
Same bool
|
2015-04-13 16:28:47 +02:00
|
|
|
Reason string
|
2014-07-23 04:39:48 +02:00
|
|
|
}{
|
|
|
|
{
|
2014-09-18 01:33:24 +02:00
|
|
|
&InstanceDiff{},
|
|
|
|
&InstanceDiff{},
|
2014-07-23 04:39:48 +02:00
|
|
|
true,
|
2015-04-13 16:28:47 +02:00
|
|
|
"",
|
2014-07-23 04:39:48 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
nil,
|
|
|
|
nil,
|
|
|
|
true,
|
2015-04-13 16:28:47 +02:00
|
|
|
"",
|
2014-07-23 04:39:48 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
{
|
2014-09-18 01:33:24 +02:00
|
|
|
&InstanceDiff{Destroy: false},
|
|
|
|
&InstanceDiff{Destroy: true},
|
2014-07-23 04:39:48 +02:00
|
|
|
false,
|
2015-04-13 16:28:47 +02:00
|
|
|
"diff: Destroy; old: false, new: true",
|
2014-07-23 04:39:48 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
{
|
2014-09-18 01:33:24 +02:00
|
|
|
&InstanceDiff{Destroy: true},
|
|
|
|
&InstanceDiff{Destroy: true},
|
2014-07-23 04:39:48 +02:00
|
|
|
true,
|
2015-04-13 16:28:47 +02:00
|
|
|
"",
|
2014-07-23 04:39:48 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
{
|
2014-09-18 01:33:24 +02:00
|
|
|
&InstanceDiff{
|
2014-07-23 04:39:48 +02:00
|
|
|
Attributes: map[string]*ResourceAttrDiff{
|
|
|
|
"foo": &ResourceAttrDiff{},
|
|
|
|
},
|
|
|
|
},
|
2014-09-18 01:33:24 +02:00
|
|
|
&InstanceDiff{
|
2014-07-23 04:39:48 +02:00
|
|
|
Attributes: map[string]*ResourceAttrDiff{
|
|
|
|
"foo": &ResourceAttrDiff{},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
true,
|
2015-04-13 16:28:47 +02:00
|
|
|
"",
|
2014-07-23 04:39:48 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
{
|
2014-09-18 01:33:24 +02:00
|
|
|
&InstanceDiff{
|
2014-07-23 04:39:48 +02:00
|
|
|
Attributes: map[string]*ResourceAttrDiff{
|
|
|
|
"bar": &ResourceAttrDiff{},
|
|
|
|
},
|
|
|
|
},
|
2014-09-18 01:33:24 +02:00
|
|
|
&InstanceDiff{
|
2014-07-23 04:39:48 +02:00
|
|
|
Attributes: map[string]*ResourceAttrDiff{
|
|
|
|
"foo": &ResourceAttrDiff{},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
false,
|
2015-04-13 16:28:47 +02:00
|
|
|
"attribute mismatch: bar",
|
2014-07-23 04:39:48 +02:00
|
|
|
},
|
|
|
|
|
2014-10-10 05:52:38 +02:00
|
|
|
// Extra attributes
|
|
|
|
{
|
|
|
|
&InstanceDiff{
|
|
|
|
Attributes: map[string]*ResourceAttrDiff{
|
|
|
|
"foo": &ResourceAttrDiff{},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
&InstanceDiff{
|
|
|
|
Attributes: map[string]*ResourceAttrDiff{
|
|
|
|
"foo": &ResourceAttrDiff{},
|
|
|
|
"bar": &ResourceAttrDiff{},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
false,
|
2015-04-13 16:28:47 +02:00
|
|
|
"extra attributes: bar",
|
2014-10-10 05:52:38 +02:00
|
|
|
},
|
|
|
|
|
2014-07-23 04:39:48 +02:00
|
|
|
{
|
2014-09-18 01:33:24 +02:00
|
|
|
&InstanceDiff{
|
2014-07-23 04:39:48 +02:00
|
|
|
Attributes: map[string]*ResourceAttrDiff{
|
|
|
|
"foo": &ResourceAttrDiff{RequiresNew: true},
|
|
|
|
},
|
|
|
|
},
|
2014-09-18 01:33:24 +02:00
|
|
|
&InstanceDiff{
|
2014-07-23 04:39:48 +02:00
|
|
|
Attributes: map[string]*ResourceAttrDiff{
|
|
|
|
"foo": &ResourceAttrDiff{RequiresNew: false},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
false,
|
2015-04-13 16:28:47 +02:00
|
|
|
"diff RequiresNew; old: true, new: false",
|
2014-07-23 04:39:48 +02:00
|
|
|
},
|
2014-10-10 05:52:38 +02:00
|
|
|
|
|
|
|
{
|
|
|
|
&InstanceDiff{
|
|
|
|
Attributes: map[string]*ResourceAttrDiff{
|
|
|
|
"foo.#": &ResourceAttrDiff{NewComputed: true},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
&InstanceDiff{
|
|
|
|
Attributes: map[string]*ResourceAttrDiff{
|
|
|
|
"foo.#": &ResourceAttrDiff{
|
|
|
|
Old: "0",
|
|
|
|
New: "1",
|
|
|
|
},
|
|
|
|
"foo.0": &ResourceAttrDiff{
|
|
|
|
Old: "",
|
|
|
|
New: "12",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
true,
|
2015-04-13 16:28:47 +02:00
|
|
|
"",
|
2014-10-10 05:52:38 +02:00
|
|
|
},
|
2014-12-12 23:21:20 +01:00
|
|
|
|
|
|
|
{
|
|
|
|
&InstanceDiff{
|
|
|
|
Attributes: map[string]*ResourceAttrDiff{
|
|
|
|
"foo.#": &ResourceAttrDiff{
|
|
|
|
Old: "0",
|
|
|
|
New: "1",
|
|
|
|
},
|
|
|
|
"foo.~35964334.bar": &ResourceAttrDiff{
|
|
|
|
Old: "",
|
|
|
|
New: "${var.foo}",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
&InstanceDiff{
|
|
|
|
Attributes: map[string]*ResourceAttrDiff{
|
|
|
|
"foo.#": &ResourceAttrDiff{
|
|
|
|
Old: "0",
|
|
|
|
New: "1",
|
|
|
|
},
|
|
|
|
"foo.87654323.bar": &ResourceAttrDiff{
|
|
|
|
Old: "",
|
|
|
|
New: "12",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
true,
|
2015-04-13 16:28:47 +02:00
|
|
|
"",
|
2014-12-12 23:21:20 +01:00
|
|
|
},
|
2014-12-16 19:15:07 +01:00
|
|
|
|
|
|
|
{
|
|
|
|
&InstanceDiff{
|
|
|
|
Attributes: map[string]*ResourceAttrDiff{
|
|
|
|
"foo.#": &ResourceAttrDiff{
|
|
|
|
Old: "0",
|
|
|
|
NewComputed: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
&InstanceDiff{
|
|
|
|
Attributes: map[string]*ResourceAttrDiff{},
|
|
|
|
},
|
|
|
|
true,
|
2015-04-13 16:28:47 +02:00
|
|
|
"",
|
2014-12-16 19:15:07 +01:00
|
|
|
},
|
2015-04-14 01:56:48 +02:00
|
|
|
|
2016-06-17 00:37:11 +02:00
|
|
|
// Computed sets may not contain all fields in the original diff, and
|
|
|
|
// because multiple entries for the same set can compute to the same
|
|
|
|
// hash before the values are computed or interpolated, the overall
|
|
|
|
// count can change as well.
|
|
|
|
{
|
|
|
|
&InstanceDiff{
|
|
|
|
Attributes: map[string]*ResourceAttrDiff{
|
|
|
|
"foo.#": &ResourceAttrDiff{
|
|
|
|
Old: "0",
|
|
|
|
New: "1",
|
|
|
|
},
|
|
|
|
"foo.~35964334.bar": &ResourceAttrDiff{
|
|
|
|
Old: "",
|
|
|
|
New: "${var.foo}",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
&InstanceDiff{
|
|
|
|
Attributes: map[string]*ResourceAttrDiff{
|
|
|
|
"foo.#": &ResourceAttrDiff{
|
|
|
|
Old: "0",
|
|
|
|
New: "2",
|
|
|
|
},
|
|
|
|
"foo.87654323.bar": &ResourceAttrDiff{
|
|
|
|
Old: "",
|
|
|
|
New: "12",
|
|
|
|
},
|
|
|
|
"foo.87654325.bar": &ResourceAttrDiff{
|
|
|
|
Old: "",
|
|
|
|
New: "12",
|
|
|
|
},
|
|
|
|
"foo.87654325.baz": &ResourceAttrDiff{
|
|
|
|
Old: "",
|
|
|
|
New: "12",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
true,
|
|
|
|
"",
|
|
|
|
},
|
|
|
|
|
2016-06-21 00:18:25 +02:00
|
|
|
// 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,
|
|
|
|
"",
|
|
|
|
},
|
|
|
|
|
2015-04-14 01:56:48 +02:00
|
|
|
// 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.)
|
|
|
|
// For complex attributes, this can result in keys that seem to disappear
|
|
|
|
// between the two diffs, when in reality everything is working just fine.
|
|
|
|
//
|
|
|
|
// Same() needs to take into account this scenario by analyzing NewRemoved
|
|
|
|
// and treating as "Same" a diff that does indeed have that key removed.
|
|
|
|
{
|
|
|
|
&InstanceDiff{
|
|
|
|
Attributes: map[string]*ResourceAttrDiff{
|
|
|
|
"somemap.oldkey": &ResourceAttrDiff{
|
|
|
|
Old: "long ago",
|
|
|
|
New: "",
|
|
|
|
NewRemoved: true,
|
|
|
|
},
|
|
|
|
"somemap.newkey": &ResourceAttrDiff{
|
|
|
|
Old: "",
|
|
|
|
New: "brave new world",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
&InstanceDiff{
|
|
|
|
Attributes: map[string]*ResourceAttrDiff{
|
|
|
|
"somemap.newkey": &ResourceAttrDiff{
|
|
|
|
Old: "",
|
|
|
|
New: "brave new world",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
true,
|
|
|
|
"",
|
|
|
|
},
|
2016-01-19 22:28:48 +01:00
|
|
|
|
|
|
|
// Another thing that can occur in DESTROY/CREATE scenarios is that list
|
|
|
|
// values that are going to zero have diffs that show up at plan time but
|
|
|
|
// are gone at apply time. The NewRemoved handling catches the fields and
|
|
|
|
// treats them as OK, but it also needs to treat the .# field itself as
|
|
|
|
// okay to be present in the old diff but not in the new one.
|
|
|
|
{
|
|
|
|
&InstanceDiff{
|
|
|
|
Attributes: map[string]*ResourceAttrDiff{
|
|
|
|
"reqnew": &ResourceAttrDiff{
|
|
|
|
Old: "old",
|
|
|
|
New: "new",
|
|
|
|
RequiresNew: true,
|
|
|
|
},
|
|
|
|
"somemap.#": &ResourceAttrDiff{
|
|
|
|
Old: "1",
|
|
|
|
New: "0",
|
|
|
|
},
|
|
|
|
"somemap.oldkey": &ResourceAttrDiff{
|
|
|
|
Old: "long ago",
|
|
|
|
New: "",
|
|
|
|
NewRemoved: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
&InstanceDiff{
|
|
|
|
Attributes: map[string]*ResourceAttrDiff{
|
|
|
|
"reqnew": &ResourceAttrDiff{
|
|
|
|
Old: "",
|
|
|
|
New: "new",
|
|
|
|
RequiresNew: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
true,
|
|
|
|
"",
|
|
|
|
},
|
2016-06-17 01:22:21 +02:00
|
|
|
|
|
|
|
{
|
|
|
|
&InstanceDiff{
|
|
|
|
Attributes: map[string]*ResourceAttrDiff{
|
|
|
|
"reqnew": &ResourceAttrDiff{
|
|
|
|
Old: "old",
|
|
|
|
New: "new",
|
|
|
|
RequiresNew: true,
|
|
|
|
},
|
|
|
|
"somemap.%": &ResourceAttrDiff{
|
|
|
|
Old: "1",
|
|
|
|
New: "0",
|
|
|
|
},
|
|
|
|
"somemap.oldkey": &ResourceAttrDiff{
|
|
|
|
Old: "long ago",
|
|
|
|
New: "",
|
|
|
|
NewRemoved: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
&InstanceDiff{
|
|
|
|
Attributes: map[string]*ResourceAttrDiff{
|
|
|
|
"reqnew": &ResourceAttrDiff{
|
|
|
|
Old: "",
|
|
|
|
New: "new",
|
|
|
|
RequiresNew: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
true,
|
|
|
|
"",
|
|
|
|
},
|
2014-07-23 04:39:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
for i, tc := range cases {
|
2015-04-13 16:28:47 +02:00
|
|
|
same, reason := tc.One.Same(tc.Two)
|
|
|
|
if same != tc.Same {
|
2015-04-14 01:56:48 +02:00
|
|
|
t.Fatalf("%d: expected same: %t, got %t (%s)\n\n one: %#v\n\ntwo: %#v",
|
|
|
|
i, tc.Same, same, reason, tc.One, tc.Two)
|
2014-07-23 04:39:48 +02:00
|
|
|
}
|
2015-04-13 16:28:47 +02:00
|
|
|
if reason != tc.Reason {
|
|
|
|
t.Fatalf(
|
|
|
|
"%d: bad reason\n\nexpected: %#v\n\ngot: %#v", i, tc.Reason, reason)
|
|
|
|
}
|
2014-07-23 04:39:48 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-23 20:43:21 +02:00
|
|
|
const moduleDiffStrBasic = `
|
2014-06-10 20:37:04 +02:00
|
|
|
CREATE: nodeA
|
2016-05-28 02:00:59 +02:00
|
|
|
bar: "foo" => "<computed>"
|
|
|
|
foo: "foo" => "bar"
|
|
|
|
longfoo: "foo" => "bar" (forces new resource)
|
|
|
|
secretfoo: "<sensitive>" => "<sensitive>" (attribute changed)
|
2014-06-10 20:22:32 +02:00
|
|
|
`
|