| package terraform |
| |
| import ( |
| "fmt" |
| "testing" |
| |
| "github.com/hashicorp/terraform/internal/addrs" |
| "github.com/hashicorp/terraform/internal/configs" |
| "github.com/hashicorp/terraform/internal/configs/configschema" |
| "github.com/hashicorp/terraform/internal/states" |
| "github.com/zclconf/go-cty/cty" |
| ) |
| |
| func TestNodeAbstractResourceInstanceProvider(t *testing.T) { |
| tests := []struct { |
| Addr addrs.AbsResourceInstance |
| Config *configs.Resource |
| StoredProviderConfig addrs.AbsProviderConfig |
| Want addrs.Provider |
| }{ |
| { |
| Addr: addrs.Resource{ |
| Mode: addrs.ManagedResourceMode, |
| Type: "null_resource", |
| Name: "baz", |
| }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance), |
| Want: addrs.Provider{ |
| Hostname: addrs.DefaultProviderRegistryHost, |
| Namespace: "hashicorp", |
| Type: "null", |
| }, |
| }, |
| { |
| Addr: addrs.Resource{ |
| Mode: addrs.DataResourceMode, |
| Type: "terraform_remote_state", |
| Name: "baz", |
| }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance), |
| Want: addrs.Provider{ |
| // As a special case, the type prefix "terraform_" maps to |
| // the builtin provider, not the default one. |
| Hostname: addrs.BuiltInProviderHost, |
| Namespace: addrs.BuiltInProviderNamespace, |
| Type: "terraform", |
| }, |
| }, |
| { |
| Addr: addrs.Resource{ |
| Mode: addrs.ManagedResourceMode, |
| Type: "null_resource", |
| Name: "baz", |
| }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance), |
| Config: &configs.Resource{ |
| // Just enough configs.Resource for the Provider method. Not |
| // actually valid for general use. |
| Provider: addrs.Provider{ |
| Hostname: addrs.DefaultProviderRegistryHost, |
| Namespace: "awesomecorp", |
| Type: "happycloud", |
| }, |
| }, |
| // The config overrides the default behavior. |
| Want: addrs.Provider{ |
| Hostname: addrs.DefaultProviderRegistryHost, |
| Namespace: "awesomecorp", |
| Type: "happycloud", |
| }, |
| }, |
| { |
| Addr: addrs.Resource{ |
| Mode: addrs.DataResourceMode, |
| Type: "terraform_remote_state", |
| Name: "baz", |
| }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance), |
| Config: &configs.Resource{ |
| // Just enough configs.Resource for the Provider method. Not |
| // actually valid for general use. |
| Provider: addrs.Provider{ |
| Hostname: addrs.DefaultProviderRegistryHost, |
| Namespace: "awesomecorp", |
| Type: "happycloud", |
| }, |
| }, |
| // The config overrides the default behavior. |
| Want: addrs.Provider{ |
| Hostname: addrs.DefaultProviderRegistryHost, |
| Namespace: "awesomecorp", |
| Type: "happycloud", |
| }, |
| }, |
| { |
| Addr: addrs.Resource{ |
| Mode: addrs.DataResourceMode, |
| Type: "null_resource", |
| Name: "baz", |
| }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance), |
| Config: nil, |
| StoredProviderConfig: addrs.AbsProviderConfig{ |
| Module: addrs.RootModule, |
| Provider: addrs.Provider{ |
| Hostname: addrs.DefaultProviderRegistryHost, |
| Namespace: "awesomecorp", |
| Type: "null", |
| }, |
| }, |
| // The stored provider config overrides the default behavior. |
| Want: addrs.Provider{ |
| Hostname: addrs.DefaultProviderRegistryHost, |
| Namespace: "awesomecorp", |
| Type: "null", |
| }, |
| }, |
| } |
| |
| for _, test := range tests { |
| var name string |
| if test.Config != nil { |
| name = fmt.Sprintf("%s with configured %s", test.Addr, test.Config.Provider) |
| } else { |
| name = fmt.Sprintf("%s with no configuration", test.Addr) |
| } |
| t.Run(name, func(t *testing.T) { |
| node := &NodeAbstractResourceInstance{ |
| // Just enough NodeAbstractResourceInstance for the Provider |
| // function. (This would not be valid for some other functions.) |
| Addr: test.Addr, |
| NodeAbstractResource: NodeAbstractResource{ |
| Addr: test.Addr.ConfigResource(), |
| Config: test.Config, |
| storedProviderConfig: test.StoredProviderConfig, |
| }, |
| } |
| got := node.Provider() |
| if got != test.Want { |
| t.Errorf("wrong result\naddr: %s\nconfig: %#v\ngot: %s\nwant: %s", test.Addr, test.Config, got, test.Want) |
| } |
| }) |
| } |
| } |
| |
| func TestNodeAbstractResourceInstance_WriteResourceInstanceState(t *testing.T) { |
| state := states.NewState() |
| ctx := new(MockEvalContext) |
| ctx.StateState = state.SyncWrapper() |
| ctx.PathPath = addrs.RootModuleInstance |
| |
| mockProvider := mockProviderWithResourceTypeSchema("aws_instance", &configschema.Block{ |
| Attributes: map[string]*configschema.Attribute{ |
| "id": { |
| Type: cty.String, |
| Optional: true, |
| }, |
| }, |
| }) |
| |
| obj := &states.ResourceInstanceObject{ |
| Value: cty.ObjectVal(map[string]cty.Value{ |
| "id": cty.StringVal("i-abc123"), |
| }), |
| Status: states.ObjectReady, |
| } |
| |
| node := &NodeAbstractResourceInstance{ |
| Addr: mustResourceInstanceAddr("aws_instance.foo"), |
| // instanceState: obj, |
| NodeAbstractResource: NodeAbstractResource{ |
| ResolvedProvider: mustProviderConfig(`provider["registry.terraform.io/hashicorp/aws"]`), |
| }, |
| } |
| ctx.ProviderProvider = mockProvider |
| ctx.ProviderSchemaSchema = mockProvider.ProviderSchema() |
| |
| err := node.writeResourceInstanceState(ctx, obj, workingState) |
| if err != nil { |
| t.Fatalf("unexpected error: %s", err.Error()) |
| } |
| |
| checkStateString(t, state, ` |
| aws_instance.foo: |
| ID = i-abc123 |
| provider = provider["registry.terraform.io/hashicorp/aws"] |
| `) |
| } |