33
44package states
55
6- import (
7- "reflect"
8-
9- "github.com/hashicorp/terraform/internal/addrs"
10- )
11-
126// Equal returns true if the receiver is functionally equivalent to other,
137// including any ephemeral portions of the state that would not be included
148// if the state were saved to files.
159//
1610// To test only the persistent portions of two states for equality, instead
1711// use statefile.StatesMarshalEqual.
1812func (s * State ) Equal (other * State ) bool {
19- // For the moment this is sufficient, but we may need to do something
20- // more elaborate in future if we have any portions of state that require
21- // more sophisticated comparisons.
22- return reflect .DeepEqual (s , other )
13+ if s == other {
14+ return true
15+ }
16+ if s == nil || other == nil {
17+ return false
18+ }
19+
20+ if ! s .RootOutputValuesEqual (other ) {
21+ return false
22+ }
23+
24+ if ! s .CheckResults .Equal (other .CheckResults ) {
25+ return false
26+ }
27+
28+ return s .ManagedResourcesEqual (other )
2329}
2430
2531// ManagedResourcesEqual returns true if all of the managed resources tracked
@@ -33,9 +39,14 @@ func (s *State) ManagedResourcesEqual(other *State) bool {
3339 // First, some accommodations for situations where one of the objects is
3440 // nil, for robustness since we sometimes use a nil state to represent
3541 // a prior state being entirely absent.
36- if s == nil && other == nil {
42+ if s == other {
43+ // covers both states being nil, or both states being the exact same
44+ // object.
3745 return true
3846 }
47+
48+ // Managed resources are technically equal if one state is nil while the
49+ // other has no resources.
3950 if s == nil {
4051 return ! other .HasManagedResourceInstanceObjects ()
4152 }
@@ -45,29 +56,37 @@ func (s *State) ManagedResourcesEqual(other *State) bool {
4556
4657 // If we get here then both states are non-nil.
4758
48- // sameManagedResources tests that its second argument has all the
49- // resources that the first one does, so we'll call it twice with the
50- // arguments inverted to ensure that we'll also catch situations where
51- // the second has resources that the first does not.
52- return sameManagedResources (s , other ) && sameManagedResources (other , s )
53- }
59+ if len (s .Modules ) != len (other .Modules ) {
60+ return false
61+ }
62+
63+ for key , sMod := range s .Modules {
64+ otherMod , ok := other .Modules [key ]
65+ if ! ok {
66+ return false
67+ }
68+ // Something else is wrong if the addresses don't match, but they are
69+ // definitely not equal
70+ if ! sMod .Addr .Equal (otherMod .Addr ) {
71+ return false
72+ }
73+
74+ if len (sMod .Resources ) != len (otherMod .Resources ) {
75+ return false
76+ }
5477
55- func sameManagedResources (s1 , s2 * State ) bool {
56- for _ , ms := range s1 .Modules {
57- for _ , rs := range ms .Resources {
58- addr := rs .Addr
59- if addr .Resource .Mode != addrs .ManagedResourceMode {
60- continue
78+ for key , sRes := range sMod .Resources {
79+ otherRes , ok := otherMod .Resources [key ]
80+ if ! ok {
81+ return false
6182 }
62- otherRS := s2 .Resource (addr )
63- if ! reflect .DeepEqual (rs , otherRS ) {
83+ if ! sRes .Equal (otherRes ) {
6484 return false
6585 }
6686 }
6787 }
6888
6989 return true
70-
7190}
7291
7392// RootOutputValuesEqual returns true if the root output values tracked in the
@@ -77,25 +96,14 @@ func (s *State) RootOutputValuesEqual(s2 *State) bool {
7796 if s == nil && s2 == nil {
7897 return true
7998 }
80- if s == nil {
81- return ! s2 .HasRootOutputValues ()
82- }
83- if s2 == nil {
84- return ! s .HasRootOutputValues ()
85- }
86-
87- return sameRootOutputValues (s , s2 )
88- }
8999
90- // sameRootOutputValues returns true if the two states have the same root output values.
91- func sameRootOutputValues (s1 , s2 * State ) bool {
92- if len (s1 .RootOutputValues ) != len (s2 .RootOutputValues ) {
100+ if len (s .RootOutputValues ) != len (s2 .RootOutputValues ) {
93101 return false
94102 }
95103
96- for k , v1 := range s1 .RootOutputValues {
104+ for k , v1 := range s2 .RootOutputValues {
97105 v2 , ok := s2 .RootOutputValues [k ]
98- if ! ok || ! reflect . DeepEqual ( v1 , v2 ) {
106+ if ! ok || ! v1 . Equal ( v2 ) {
99107 return false
100108 }
101109 }
0 commit comments