Skip to content

Commit 89dbaad

Browse files
authored
Merge pull request hashicorp#12218 from hashicorp/b-state-equal
terraform: State.Equal needs to use reflect for rich types
2 parents 99e839b + 41d2c14 commit 89dbaad

2 files changed

Lines changed: 64 additions & 13 deletions

File tree

‎terraform/state.go‎

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1633,13 +1633,11 @@ func (s *InstanceState) Equal(other *InstanceState) bool {
16331633
if len(s.Meta) != len(other.Meta) {
16341634
return false
16351635
}
1636-
for k, v := range s.Meta {
1637-
otherV, ok := other.Meta[k]
1638-
if !ok {
1639-
return false
1640-
}
1641-
1642-
if v != otherV {
1636+
if s.Meta != nil && other.Meta != nil {
1637+
// We only do the deep check if both are non-nil. If one is nil
1638+
// we treat it as equal since their lengths are both zero (check
1639+
// above).
1640+
if !reflect.DeepEqual(s.Meta, other.Meta) {
16431641
return false
16441642
}
16451643
}

‎terraform/state_test.go‎

Lines changed: 59 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -325,31 +325,36 @@ func TestStateDeepCopy(t *testing.T) {
325325

326326
func TestStateEqual(t *testing.T) {
327327
cases := []struct {
328+
Name string
328329
Result bool
329330
One, Two *State
330331
}{
331332
// Nils
332333
{
334+
"one nil",
333335
false,
334336
nil,
335337
&State{Version: 2},
336338
},
337339

338340
{
341+
"both nil",
339342
true,
340343
nil,
341344
nil,
342345
},
343346

344347
// Different versions
345348
{
349+
"different state versions",
346350
false,
347351
&State{Version: 5},
348352
&State{Version: 2},
349353
},
350354

351355
// Different modules
352356
{
357+
"different module states",
353358
false,
354359
&State{
355360
Modules: []*ModuleState{
@@ -362,6 +367,7 @@ func TestStateEqual(t *testing.T) {
362367
},
363368

364369
{
370+
"same module states",
365371
true,
366372
&State{
367373
Modules: []*ModuleState{
@@ -381,6 +387,7 @@ func TestStateEqual(t *testing.T) {
381387

382388
// Meta differs
383389
{
390+
"differing meta values with primitives",
384391
false,
385392
&State{
386393
Modules: []*ModuleState{
@@ -415,15 +422,61 @@ func TestStateEqual(t *testing.T) {
415422
},
416423
},
417424
},
425+
426+
// Meta with complex types
427+
{
428+
"same meta with complex types",
429+
true,
430+
&State{
431+
Modules: []*ModuleState{
432+
&ModuleState{
433+
Path: rootModulePath,
434+
Resources: map[string]*ResourceState{
435+
"test_instance.foo": &ResourceState{
436+
Primary: &InstanceState{
437+
Meta: map[string]interface{}{
438+
"timeouts": map[string]interface{}{
439+
"create": 42,
440+
"read": "27",
441+
},
442+
},
443+
},
444+
},
445+
},
446+
},
447+
},
448+
},
449+
&State{
450+
Modules: []*ModuleState{
451+
&ModuleState{
452+
Path: rootModulePath,
453+
Resources: map[string]*ResourceState{
454+
"test_instance.foo": &ResourceState{
455+
Primary: &InstanceState{
456+
Meta: map[string]interface{}{
457+
"timeouts": map[string]interface{}{
458+
"create": 42,
459+
"read": "27",
460+
},
461+
},
462+
},
463+
},
464+
},
465+
},
466+
},
467+
},
468+
},
418469
}
419470

420471
for i, tc := range cases {
421-
if tc.One.Equal(tc.Two) != tc.Result {
422-
t.Fatalf("Bad: %d\n\n%s\n\n%s", i, tc.One.String(), tc.Two.String())
423-
}
424-
if tc.Two.Equal(tc.One) != tc.Result {
425-
t.Fatalf("Bad: %d\n\n%s\n\n%s", i, tc.One.String(), tc.Two.String())
426-
}
472+
t.Run(fmt.Sprintf("%d-%s", i, tc.Name), func(t *testing.T) {
473+
if tc.One.Equal(tc.Two) != tc.Result {
474+
t.Fatalf("Bad: %d\n\n%s\n\n%s", i, tc.One.String(), tc.Two.String())
475+
}
476+
if tc.Two.Equal(tc.One) != tc.Result {
477+
t.Fatalf("Bad: %d\n\n%s\n\n%s", i, tc.One.String(), tc.Two.String())
478+
}
479+
})
427480
}
428481
}
429482

0 commit comments

Comments
 (0)