github.com/hashicorp/terraform-plugin-sdk@v1.17.2/internal/states/state_test.go (about) 1 package states 2 3 import ( 4 "testing" 5 6 "github.com/go-test/deep" 7 "github.com/zclconf/go-cty/cty" 8 9 "github.com/hashicorp/terraform-plugin-sdk/internal/addrs" 10 ) 11 12 func TestState(t *testing.T) { 13 // This basic tests exercises the main mutation methods to construct 14 // a state. It is not fully comprehensive, so other tests should visit 15 // more esoteric codepaths. 16 17 state := NewState() 18 19 rootModule := state.RootModule() 20 if rootModule == nil { 21 t.Errorf("root module is nil; want valid object") 22 } 23 24 rootModule.SetLocalValue("foo", cty.StringVal("foo value")) 25 rootModule.SetOutputValue("bar", cty.StringVal("bar value"), false) 26 rootModule.SetOutputValue("secret", cty.StringVal("secret value"), true) 27 rootModule.SetResourceInstanceCurrent( 28 addrs.Resource{ 29 Mode: addrs.ManagedResourceMode, 30 Type: "test_thing", 31 Name: "baz", 32 }.Instance(addrs.IntKey(0)), 33 &ResourceInstanceObjectSrc{ 34 Status: ObjectReady, 35 SchemaVersion: 1, 36 AttrsJSON: []byte(`{"woozles":"confuzles"}`), 37 }, 38 addrs.ProviderConfig{ 39 Type: "test", 40 }.Absolute(addrs.RootModuleInstance), 41 ) 42 43 childModule := state.EnsureModule(addrs.RootModuleInstance.Child("child", addrs.NoKey)) 44 childModule.SetOutputValue("pizza", cty.StringVal("hawaiian"), false) 45 46 want := &State{ 47 Modules: map[string]*Module{ 48 "": { 49 Addr: addrs.RootModuleInstance, 50 LocalValues: map[string]cty.Value{ 51 "foo": cty.StringVal("foo value"), 52 }, 53 OutputValues: map[string]*OutputValue{ 54 "bar": { 55 Value: cty.StringVal("bar value"), 56 Sensitive: false, 57 }, 58 "secret": { 59 Value: cty.StringVal("secret value"), 60 Sensitive: true, 61 }, 62 }, 63 Resources: map[string]*Resource{ 64 "test_thing.baz": { 65 Addr: addrs.Resource{ 66 Mode: addrs.ManagedResourceMode, 67 Type: "test_thing", 68 Name: "baz", 69 }, 70 EachMode: EachList, 71 Instances: map[addrs.InstanceKey]*ResourceInstance{ 72 addrs.IntKey(0): { 73 Current: &ResourceInstanceObjectSrc{ 74 SchemaVersion: 1, 75 Status: ObjectReady, 76 AttrsJSON: []byte(`{"woozles":"confuzles"}`), 77 }, 78 Deposed: map[DeposedKey]*ResourceInstanceObjectSrc{}, 79 }, 80 }, 81 ProviderConfig: addrs.ProviderConfig{ 82 Type: "test", 83 }.Absolute(addrs.RootModuleInstance), 84 }, 85 }, 86 }, 87 "module.child": { 88 Addr: addrs.RootModuleInstance.Child("child", addrs.NoKey), 89 LocalValues: map[string]cty.Value{}, 90 OutputValues: map[string]*OutputValue{ 91 "pizza": { 92 Value: cty.StringVal("hawaiian"), 93 Sensitive: false, 94 }, 95 }, 96 Resources: map[string]*Resource{}, 97 }, 98 }, 99 } 100 101 { 102 // Our structure goes deep, so we need to temporarily override the 103 // deep package settings to ensure that we visit the full structure. 104 oldDeepDepth := deep.MaxDepth 105 oldDeepCompareUnexp := deep.CompareUnexportedFields 106 deep.MaxDepth = 50 107 deep.CompareUnexportedFields = true 108 defer func() { 109 deep.MaxDepth = oldDeepDepth 110 deep.CompareUnexportedFields = oldDeepCompareUnexp 111 }() 112 } 113 114 for _, problem := range deep.Equal(state, want) { 115 t.Error(problem) 116 } 117 } 118 119 func TestStateDeepCopy(t *testing.T) { 120 state := NewState() 121 122 rootModule := state.RootModule() 123 if rootModule == nil { 124 t.Errorf("root module is nil; want valid object") 125 } 126 127 rootModule.SetLocalValue("foo", cty.StringVal("foo value")) 128 rootModule.SetOutputValue("bar", cty.StringVal("bar value"), false) 129 rootModule.SetOutputValue("secret", cty.StringVal("secret value"), true) 130 rootModule.SetResourceInstanceCurrent( 131 addrs.Resource{ 132 Mode: addrs.ManagedResourceMode, 133 Type: "test_thing", 134 Name: "baz", 135 }.Instance(addrs.IntKey(0)), 136 &ResourceInstanceObjectSrc{ 137 Status: ObjectReady, 138 SchemaVersion: 1, 139 AttrsJSON: []byte(`{"woozles":"confuzles"}`), 140 Private: []byte("private data"), 141 Dependencies: []addrs.Referenceable{}, 142 }, 143 addrs.ProviderConfig{ 144 Type: "test", 145 }.Absolute(addrs.RootModuleInstance), 146 ) 147 rootModule.SetResourceInstanceCurrent( 148 addrs.Resource{ 149 Mode: addrs.ManagedResourceMode, 150 Type: "test_thing", 151 Name: "bar", 152 }.Instance(addrs.IntKey(0)), 153 &ResourceInstanceObjectSrc{ 154 Status: ObjectReady, 155 SchemaVersion: 1, 156 AttrsJSON: []byte(`{"woozles":"confuzles"}`), 157 Private: []byte("private data"), 158 Dependencies: []addrs.Referenceable{addrs.Resource{ 159 Mode: addrs.ManagedResourceMode, 160 Type: "test_thing", 161 Name: "baz", 162 }}, 163 }, 164 addrs.ProviderConfig{ 165 Type: "test", 166 }.Absolute(addrs.RootModuleInstance), 167 ) 168 169 childModule := state.EnsureModule(addrs.RootModuleInstance.Child("child", addrs.NoKey)) 170 childModule.SetOutputValue("pizza", cty.StringVal("hawaiian"), false) 171 172 stateCopy := state.DeepCopy() 173 if !state.Equal(stateCopy) { 174 t.Fatalf("\nexpected:\n%q\ngot:\n%q\n", state, stateCopy) 175 } 176 }