github.com/muratcelep/terraform@v1.1.0-beta2-not-internal-4/not-internal/terraform/node_resource_abstract_test.go (about) 1 package terraform 2 3 import ( 4 "fmt" 5 "testing" 6 7 "github.com/muratcelep/terraform/not-internal/addrs" 8 "github.com/muratcelep/terraform/not-internal/configs" 9 "github.com/muratcelep/terraform/not-internal/configs/configschema" 10 "github.com/muratcelep/terraform/not-internal/providers" 11 "github.com/muratcelep/terraform/not-internal/states" 12 "github.com/zclconf/go-cty/cty" 13 ) 14 15 func TestNodeAbstractResourceProvider(t *testing.T) { 16 tests := []struct { 17 Addr addrs.ConfigResource 18 Config *configs.Resource 19 Want addrs.Provider 20 }{ 21 { 22 Addr: addrs.Resource{ 23 Mode: addrs.ManagedResourceMode, 24 Type: "null_resource", 25 Name: "baz", 26 }.InModule(addrs.RootModule), 27 Want: addrs.Provider{ 28 Hostname: addrs.DefaultProviderRegistryHost, 29 Namespace: "hashicorp", 30 Type: "null", 31 }, 32 }, 33 { 34 Addr: addrs.Resource{ 35 Mode: addrs.DataResourceMode, 36 Type: "terraform_remote_state", 37 Name: "baz", 38 }.InModule(addrs.RootModule), 39 Want: addrs.Provider{ 40 // As a special case, the type prefix "terraform_" maps to 41 // the builtin provider, not the default one. 42 Hostname: addrs.BuiltInProviderHost, 43 Namespace: addrs.BuiltInProviderNamespace, 44 Type: "terraform", 45 }, 46 }, 47 { 48 Addr: addrs.Resource{ 49 Mode: addrs.ManagedResourceMode, 50 Type: "null_resource", 51 Name: "baz", 52 }.InModule(addrs.RootModule), 53 Config: &configs.Resource{ 54 // Just enough configs.Resource for the Provider method. Not 55 // actually valid for general use. 56 Provider: addrs.Provider{ 57 Hostname: addrs.DefaultProviderRegistryHost, 58 Namespace: "awesomecorp", 59 Type: "happycloud", 60 }, 61 }, 62 // The config overrides the default behavior. 63 Want: addrs.Provider{ 64 Hostname: addrs.DefaultProviderRegistryHost, 65 Namespace: "awesomecorp", 66 Type: "happycloud", 67 }, 68 }, 69 { 70 Addr: addrs.Resource{ 71 Mode: addrs.DataResourceMode, 72 Type: "terraform_remote_state", 73 Name: "baz", 74 }.InModule(addrs.RootModule), 75 Config: &configs.Resource{ 76 // Just enough configs.Resource for the Provider method. Not 77 // actually valid for general use. 78 Provider: addrs.Provider{ 79 Hostname: addrs.DefaultProviderRegistryHost, 80 Namespace: "awesomecorp", 81 Type: "happycloud", 82 }, 83 }, 84 // The config overrides the default behavior. 85 Want: addrs.Provider{ 86 Hostname: addrs.DefaultProviderRegistryHost, 87 Namespace: "awesomecorp", 88 Type: "happycloud", 89 }, 90 }, 91 } 92 93 for _, test := range tests { 94 var name string 95 if test.Config != nil { 96 name = fmt.Sprintf("%s with configured %s", test.Addr, test.Config.Provider) 97 } else { 98 name = fmt.Sprintf("%s with no configuration", test.Addr) 99 } 100 t.Run(name, func(t *testing.T) { 101 node := &NodeAbstractResource{ 102 // Just enough NodeAbstractResource for the Provider function. 103 // (This would not be valid for some other functions.) 104 Addr: test.Addr, 105 Config: test.Config, 106 } 107 got := node.Provider() 108 if got != test.Want { 109 t.Errorf("wrong result\naddr: %s\nconfig: %#v\ngot: %s\nwant: %s", test.Addr, test.Config, got, test.Want) 110 } 111 }) 112 } 113 } 114 115 func TestNodeAbstractResource_ReadResourceInstanceState(t *testing.T) { 116 mockProvider := mockProviderWithResourceTypeSchema("aws_instance", &configschema.Block{ 117 Attributes: map[string]*configschema.Attribute{ 118 "id": { 119 Type: cty.String, 120 Optional: true, 121 }, 122 }, 123 }) 124 125 tests := map[string]struct { 126 State *states.State 127 Node *NodeAbstractResource 128 ExpectedInstanceId string 129 }{ 130 "ReadState gets primary instance state": { 131 State: states.BuildState(func(s *states.SyncState) { 132 providerAddr := addrs.AbsProviderConfig{ 133 Provider: addrs.NewDefaultProvider("aws"), 134 Module: addrs.RootModule, 135 } 136 oneAddr := addrs.Resource{ 137 Mode: addrs.ManagedResourceMode, 138 Type: "aws_instance", 139 Name: "bar", 140 }.Absolute(addrs.RootModuleInstance) 141 s.SetResourceProvider(oneAddr, providerAddr) 142 s.SetResourceInstanceCurrent(oneAddr.Instance(addrs.NoKey), &states.ResourceInstanceObjectSrc{ 143 Status: states.ObjectReady, 144 AttrsJSON: []byte(`{"id":"i-abc123"}`), 145 }, providerAddr) 146 }), 147 Node: &NodeAbstractResource{ 148 Addr: mustConfigResourceAddr("aws_instance.bar"), 149 ResolvedProvider: mustProviderConfig(`provider["registry.terraform.io/hashicorp/aws"]`), 150 }, 151 ExpectedInstanceId: "i-abc123", 152 }, 153 } 154 155 for k, test := range tests { 156 t.Run(k, func(t *testing.T) { 157 ctx := new(MockEvalContext) 158 ctx.StateState = test.State.SyncWrapper() 159 ctx.PathPath = addrs.RootModuleInstance 160 ctx.ProviderSchemaSchema = mockProvider.ProviderSchema() 161 ctx.ProviderProvider = providers.Interface(mockProvider) 162 163 got, readDiags := test.Node.readResourceInstanceState(ctx, test.Node.Addr.Resource.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance)) 164 if readDiags.HasErrors() { 165 t.Fatalf("[%s] Got err: %#v", k, readDiags.Err()) 166 } 167 168 expected := test.ExpectedInstanceId 169 170 if !(got != nil && got.Value.GetAttr("id") == cty.StringVal(expected)) { 171 t.Fatalf("[%s] Expected output with ID %#v, got: %#v", k, expected, got) 172 } 173 }) 174 } 175 } 176 177 func TestNodeAbstractResource_ReadResourceInstanceStateDeposed(t *testing.T) { 178 mockProvider := mockProviderWithResourceTypeSchema("aws_instance", &configschema.Block{ 179 Attributes: map[string]*configschema.Attribute{ 180 "id": { 181 Type: cty.String, 182 Optional: true, 183 }, 184 }, 185 }) 186 187 tests := map[string]struct { 188 State *states.State 189 Node *NodeAbstractResource 190 ExpectedInstanceId string 191 }{ 192 "ReadStateDeposed gets deposed instance": { 193 State: states.BuildState(func(s *states.SyncState) { 194 providerAddr := addrs.AbsProviderConfig{ 195 Provider: addrs.NewDefaultProvider("aws"), 196 Module: addrs.RootModule, 197 } 198 oneAddr := addrs.Resource{ 199 Mode: addrs.ManagedResourceMode, 200 Type: "aws_instance", 201 Name: "bar", 202 }.Absolute(addrs.RootModuleInstance) 203 s.SetResourceProvider(oneAddr, providerAddr) 204 s.SetResourceInstanceDeposed(oneAddr.Instance(addrs.NoKey), states.DeposedKey("00000001"), &states.ResourceInstanceObjectSrc{ 205 Status: states.ObjectReady, 206 AttrsJSON: []byte(`{"id":"i-abc123"}`), 207 }, providerAddr) 208 }), 209 Node: &NodeAbstractResource{ 210 Addr: mustConfigResourceAddr("aws_instance.bar"), 211 ResolvedProvider: mustProviderConfig(`provider["registry.terraform.io/hashicorp/aws"]`), 212 }, 213 ExpectedInstanceId: "i-abc123", 214 }, 215 } 216 for k, test := range tests { 217 t.Run(k, func(t *testing.T) { 218 ctx := new(MockEvalContext) 219 ctx.StateState = test.State.SyncWrapper() 220 ctx.PathPath = addrs.RootModuleInstance 221 ctx.ProviderSchemaSchema = mockProvider.ProviderSchema() 222 ctx.ProviderProvider = providers.Interface(mockProvider) 223 224 key := states.DeposedKey("00000001") // shim from legacy state assigns 0th deposed index this key 225 226 got, readDiags := test.Node.readResourceInstanceStateDeposed(ctx, test.Node.Addr.Resource.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance), key) 227 if readDiags.HasErrors() { 228 t.Fatalf("[%s] Got err: %#v", k, readDiags.Err()) 229 } 230 231 expected := test.ExpectedInstanceId 232 233 if !(got != nil && got.Value.GetAttr("id") == cty.StringVal(expected)) { 234 t.Fatalf("[%s] Expected output with ID %#v, got: %#v", k, expected, got) 235 } 236 }) 237 } 238 }