mirror of
https://github.com/opentofu/opentofu.git
synced 2024-12-30 10:47:14 -06:00
a3403f2766
Due to how often the state and plan types are referenced throughout Terraform, there isn't a great way to switch them out gradually. As a consequence, this huge commit gets us from the old world to a _compilable_ new world, but still has a large number of known test failures due to key functionality being stubbed out. The stubs here are for anything that interacts with providers, since we now need to do the follow-up work to similarly replace the old terraform.ResourceProvider interface with its replacement in the new "providers" package. That work, along with work to fix the remaining failing tests, will follow in subsequent commits. The aim here was to replace all references to terraform.State and its downstream types with states.State, terraform.Plan with plans.Plan, state.State with statemgr.State, and switch to the new implementations of the state and plan file formats. However, due to the number of times those types are used, this also ended up affecting numerous other parts of core such as terraform.Hook, the backend.Backend interface, and most of the CLI commands. Just as with 5861dbf3fc49b19587a31816eb06f511ab861bb4 before, I apologize in advance to the person who inevitably just found this huge commit while spelunking through the commit history.
1473 lines
34 KiB
Go
1473 lines
34 KiB
Go
package terraform
|
|
|
|
import (
|
|
"reflect"
|
|
"regexp"
|
|
"sort"
|
|
"strings"
|
|
"sync"
|
|
"testing"
|
|
|
|
"github.com/zclconf/go-cty/cty"
|
|
|
|
"github.com/hashicorp/terraform/addrs"
|
|
"github.com/hashicorp/terraform/configs/configschema"
|
|
)
|
|
|
|
func TestContext2Refresh(t *testing.T) {
|
|
t.Fatalf("not yet updated for new provider interface")
|
|
/*
|
|
p := testProvider("aws")
|
|
m := testModule(t, "refresh-basic")
|
|
ctx := testContext2(t, &ContextOpts{
|
|
Config: m,
|
|
ProviderResolver: ResourceProviderResolverFixed(
|
|
map[string]ResourceProviderFactory{
|
|
"aws": testProviderFuncFixed(p),
|
|
},
|
|
),
|
|
State: mustShimLegacyState(&State{
|
|
Modules: []*ModuleState{
|
|
&ModuleState{
|
|
Path: rootModulePath,
|
|
Resources: map[string]*ResourceState{
|
|
"aws_instance.web": &ResourceState{
|
|
Type: "aws_instance",
|
|
Primary: &InstanceState{
|
|
ID: "foo",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}),
|
|
})
|
|
|
|
p.RefreshFn = nil
|
|
p.RefreshReturn = &InstanceState{
|
|
ID: "foo",
|
|
}
|
|
|
|
s, err := ctx.Refresh()
|
|
mod := s.RootModule()
|
|
if err != nil {
|
|
t.Fatalf("err: %s", err)
|
|
}
|
|
if !p.RefreshCalled {
|
|
t.Fatal("refresh should be called")
|
|
}
|
|
if p.RefreshState.ID != "foo" {
|
|
t.Fatalf("bad: %#v", p.RefreshState)
|
|
}
|
|
if !reflect.DeepEqual(mod.Resources["aws_instance.web"].Primary, p.RefreshReturn) {
|
|
t.Fatalf("bad: %#v %#v", mod.Resources["aws_instance.web"], p.RefreshReturn)
|
|
}
|
|
|
|
for _, r := range mod.Resources {
|
|
if r.Type == "" {
|
|
t.Fatalf("no type: %#v", r)
|
|
}
|
|
}
|
|
*/
|
|
}
|
|
|
|
func TestContext2Refresh_dataComputedModuleVar(t *testing.T) {
|
|
p := testProvider("aws")
|
|
m := testModule(t, "refresh-data-module-var")
|
|
ctx := testContext2(t, &ContextOpts{
|
|
Config: m,
|
|
ProviderResolver: ResourceProviderResolverFixed(
|
|
map[string]ResourceProviderFactory{
|
|
"aws": testProviderFuncFixed(p),
|
|
},
|
|
),
|
|
})
|
|
|
|
p.RefreshFn = nil
|
|
p.RefreshReturn = &InstanceState{
|
|
ID: "foo",
|
|
}
|
|
|
|
p.GetSchemaReturn = &ProviderSchema{
|
|
Provider: &configschema.Block{},
|
|
ResourceTypes: map[string]*configschema.Block{
|
|
"aws_instance": {
|
|
Attributes: map[string]*configschema.Attribute{
|
|
"foo": {
|
|
Type: cty.String,
|
|
Optional: true,
|
|
},
|
|
"id": {
|
|
Type: cty.String,
|
|
Computed: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
DataSources: map[string]*configschema.Block{
|
|
"aws_data_source": {
|
|
Attributes: map[string]*configschema.Attribute{
|
|
"id": {
|
|
Type: cty.String,
|
|
Optional: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
s, diags := ctx.Refresh()
|
|
if diags.HasErrors() {
|
|
t.Fatalf("refresh errors: %s", diags.Err())
|
|
}
|
|
|
|
checkStateString(t, s, `
|
|
<no state>
|
|
module.child:
|
|
<no state>`)
|
|
}
|
|
|
|
func TestContext2Refresh_targeted(t *testing.T) {
|
|
p := testProvider("aws")
|
|
p.GetSchemaReturn = &ProviderSchema{
|
|
Provider: &configschema.Block{},
|
|
ResourceTypes: map[string]*configschema.Block{
|
|
"aws_elb": {
|
|
Attributes: map[string]*configschema.Attribute{
|
|
"instances": {
|
|
Type: cty.Set(cty.String),
|
|
Optional: true,
|
|
},
|
|
},
|
|
},
|
|
"aws_instance": {
|
|
Attributes: map[string]*configschema.Attribute{
|
|
"id": {
|
|
Type: cty.String,
|
|
Computed: true,
|
|
},
|
|
"vpc_id": {
|
|
Type: cty.String,
|
|
Optional: true,
|
|
},
|
|
},
|
|
},
|
|
"aws_vpc": {
|
|
Attributes: map[string]*configschema.Attribute{
|
|
"id": {
|
|
Type: cty.String,
|
|
Computed: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
m := testModule(t, "refresh-targeted")
|
|
ctx := testContext2(t, &ContextOpts{
|
|
Config: m,
|
|
ProviderResolver: ResourceProviderResolverFixed(
|
|
map[string]ResourceProviderFactory{
|
|
"aws": testProviderFuncFixed(p),
|
|
},
|
|
),
|
|
State: mustShimLegacyState(&State{
|
|
Modules: []*ModuleState{
|
|
&ModuleState{
|
|
Path: rootModulePath,
|
|
Resources: map[string]*ResourceState{
|
|
"aws_vpc.metoo": resourceState("aws_vpc", "vpc-abc123"),
|
|
"aws_instance.notme": resourceState("aws_instance", "i-bcd345"),
|
|
"aws_instance.me": resourceState("aws_instance", "i-abc123"),
|
|
"aws_elb.meneither": resourceState("aws_elb", "lb-abc123"),
|
|
},
|
|
},
|
|
},
|
|
}),
|
|
Targets: []addrs.Targetable{
|
|
addrs.RootModuleInstance.Resource(
|
|
addrs.ManagedResourceMode, "aws_instance", "me",
|
|
),
|
|
},
|
|
})
|
|
|
|
refreshedResources := make([]string, 0, 2)
|
|
p.RefreshFn = func(i *InstanceInfo, is *InstanceState) (*InstanceState, error) {
|
|
refreshedResources = append(refreshedResources, i.Id)
|
|
return is, nil
|
|
}
|
|
|
|
_, diags := ctx.Refresh()
|
|
if diags.HasErrors() {
|
|
t.Fatalf("refresh errors: %s", diags.Err())
|
|
}
|
|
|
|
expected := []string{"aws_vpc.metoo", "aws_instance.me"}
|
|
if !reflect.DeepEqual(refreshedResources, expected) {
|
|
t.Fatalf("expected: %#v, got: %#v", expected, refreshedResources)
|
|
}
|
|
}
|
|
|
|
func TestContext2Refresh_targetedCount(t *testing.T) {
|
|
p := testProvider("aws")
|
|
p.GetSchemaReturn = &ProviderSchema{
|
|
Provider: &configschema.Block{},
|
|
ResourceTypes: map[string]*configschema.Block{
|
|
"aws_elb": {
|
|
Attributes: map[string]*configschema.Attribute{
|
|
"instances": {
|
|
Type: cty.Set(cty.String),
|
|
Optional: true,
|
|
},
|
|
},
|
|
},
|
|
"aws_instance": {
|
|
Attributes: map[string]*configschema.Attribute{
|
|
"id": {
|
|
Type: cty.String,
|
|
Computed: true,
|
|
},
|
|
"vpc_id": {
|
|
Type: cty.String,
|
|
Optional: true,
|
|
},
|
|
},
|
|
},
|
|
"aws_vpc": {
|
|
Attributes: map[string]*configschema.Attribute{
|
|
"id": {
|
|
Type: cty.String,
|
|
Computed: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
m := testModule(t, "refresh-targeted-count")
|
|
ctx := testContext2(t, &ContextOpts{
|
|
Config: m,
|
|
ProviderResolver: ResourceProviderResolverFixed(
|
|
map[string]ResourceProviderFactory{
|
|
"aws": testProviderFuncFixed(p),
|
|
},
|
|
),
|
|
State: mustShimLegacyState(&State{
|
|
Modules: []*ModuleState{
|
|
&ModuleState{
|
|
Path: rootModulePath,
|
|
Resources: map[string]*ResourceState{
|
|
"aws_vpc.metoo": resourceState("aws_vpc", "vpc-abc123"),
|
|
"aws_instance.notme": resourceState("aws_instance", "i-bcd345"),
|
|
"aws_instance.me.0": resourceState("aws_instance", "i-abc123"),
|
|
"aws_instance.me.1": resourceState("aws_instance", "i-cde567"),
|
|
"aws_instance.me.2": resourceState("aws_instance", "i-cde789"),
|
|
"aws_elb.meneither": resourceState("aws_elb", "lb-abc123"),
|
|
},
|
|
},
|
|
},
|
|
}),
|
|
Targets: []addrs.Targetable{
|
|
addrs.RootModuleInstance.Resource(
|
|
addrs.ManagedResourceMode, "aws_instance", "me",
|
|
),
|
|
},
|
|
})
|
|
|
|
refreshedResources := make([]string, 0, 2)
|
|
p.RefreshFn = func(i *InstanceInfo, is *InstanceState) (*InstanceState, error) {
|
|
refreshedResources = append(refreshedResources, i.Id)
|
|
return is, nil
|
|
}
|
|
|
|
_, diags := ctx.Refresh()
|
|
if diags.HasErrors() {
|
|
t.Fatalf("refresh errors: %s", diags.Err())
|
|
}
|
|
|
|
// Target didn't specify index, so we should get all our instances
|
|
expected := []string{
|
|
"aws_vpc.metoo",
|
|
"aws_instance.me.0",
|
|
"aws_instance.me.1",
|
|
"aws_instance.me.2",
|
|
}
|
|
sort.Strings(expected)
|
|
sort.Strings(refreshedResources)
|
|
if !reflect.DeepEqual(refreshedResources, expected) {
|
|
t.Fatalf("wrong result\ngot: %#v\nwant: %#v", refreshedResources, expected)
|
|
}
|
|
}
|
|
|
|
func TestContext2Refresh_targetedCountIndex(t *testing.T) {
|
|
p := testProvider("aws")
|
|
p.GetSchemaReturn = &ProviderSchema{
|
|
Provider: &configschema.Block{},
|
|
ResourceTypes: map[string]*configschema.Block{
|
|
"aws_elb": {
|
|
Attributes: map[string]*configschema.Attribute{
|
|
"instances": {
|
|
Type: cty.Set(cty.String),
|
|
Optional: true,
|
|
},
|
|
},
|
|
},
|
|
"aws_instance": {
|
|
Attributes: map[string]*configschema.Attribute{
|
|
"id": {
|
|
Type: cty.String,
|
|
Computed: true,
|
|
},
|
|
"vpc_id": {
|
|
Type: cty.String,
|
|
Optional: true,
|
|
},
|
|
},
|
|
},
|
|
"aws_vpc": {
|
|
Attributes: map[string]*configschema.Attribute{
|
|
"id": {
|
|
Type: cty.String,
|
|
Computed: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
m := testModule(t, "refresh-targeted-count")
|
|
ctx := testContext2(t, &ContextOpts{
|
|
Config: m,
|
|
ProviderResolver: ResourceProviderResolverFixed(
|
|
map[string]ResourceProviderFactory{
|
|
"aws": testProviderFuncFixed(p),
|
|
},
|
|
),
|
|
State: mustShimLegacyState(&State{
|
|
Modules: []*ModuleState{
|
|
&ModuleState{
|
|
Path: rootModulePath,
|
|
Resources: map[string]*ResourceState{
|
|
"aws_vpc.metoo": resourceState("aws_vpc", "vpc-abc123"),
|
|
"aws_instance.notme": resourceState("aws_instance", "i-bcd345"),
|
|
"aws_instance.me.0": resourceState("aws_instance", "i-abc123"),
|
|
"aws_instance.me.1": resourceState("aws_instance", "i-cde567"),
|
|
"aws_instance.me.2": resourceState("aws_instance", "i-cde789"),
|
|
"aws_elb.meneither": resourceState("aws_elb", "lb-abc123"),
|
|
},
|
|
},
|
|
},
|
|
}),
|
|
Targets: []addrs.Targetable{
|
|
addrs.RootModuleInstance.ResourceInstance(
|
|
addrs.ManagedResourceMode, "aws_instance", "me", addrs.IntKey(0),
|
|
),
|
|
},
|
|
})
|
|
|
|
refreshedResources := make([]string, 0, 2)
|
|
p.RefreshFn = func(i *InstanceInfo, is *InstanceState) (*InstanceState, error) {
|
|
refreshedResources = append(refreshedResources, i.Id)
|
|
return is, nil
|
|
}
|
|
|
|
_, diags := ctx.Refresh()
|
|
if diags.HasErrors() {
|
|
t.Fatalf("refresh errors: %s", diags.Err())
|
|
}
|
|
|
|
expected := []string{"aws_vpc.metoo", "aws_instance.me.0"}
|
|
if !reflect.DeepEqual(refreshedResources, expected) {
|
|
t.Fatalf("wrong result\ngot: %#v\nwant: %#v", refreshedResources, expected)
|
|
}
|
|
}
|
|
|
|
func TestContext2Refresh_moduleComputedVar(t *testing.T) {
|
|
p := testProvider("aws")
|
|
p.GetSchemaReturn = &ProviderSchema{
|
|
Provider: &configschema.Block{},
|
|
ResourceTypes: map[string]*configschema.Block{
|
|
"aws_instance": {
|
|
Attributes: map[string]*configschema.Attribute{
|
|
"id": {
|
|
Type: cty.String,
|
|
Computed: true,
|
|
},
|
|
"value": {
|
|
Type: cty.String,
|
|
Optional: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
m := testModule(t, "refresh-module-computed-var")
|
|
ctx := testContext2(t, &ContextOpts{
|
|
Config: m,
|
|
ProviderResolver: ResourceProviderResolverFixed(
|
|
map[string]ResourceProviderFactory{
|
|
"aws": testProviderFuncFixed(p),
|
|
},
|
|
),
|
|
})
|
|
|
|
// This was failing (see GH-2188) at some point, so this test just
|
|
// verifies that the failure goes away.
|
|
if _, diags := ctx.Refresh(); diags.HasErrors() {
|
|
t.Fatalf("refresh errs: %s", diags.Err())
|
|
}
|
|
}
|
|
|
|
func TestContext2Refresh_delete(t *testing.T) {
|
|
p := testProvider("aws")
|
|
m := testModule(t, "refresh-basic")
|
|
ctx := testContext2(t, &ContextOpts{
|
|
Config: m,
|
|
ProviderResolver: ResourceProviderResolverFixed(
|
|
map[string]ResourceProviderFactory{
|
|
"aws": testProviderFuncFixed(p),
|
|
},
|
|
),
|
|
State: mustShimLegacyState(&State{
|
|
Modules: []*ModuleState{
|
|
&ModuleState{
|
|
Path: rootModulePath,
|
|
Resources: map[string]*ResourceState{
|
|
"aws_instance.web": &ResourceState{
|
|
Type: "aws_instance",
|
|
Primary: &InstanceState{
|
|
ID: "foo",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}),
|
|
})
|
|
|
|
p.RefreshFn = nil
|
|
p.RefreshReturn = nil
|
|
|
|
s, diags := ctx.Refresh()
|
|
if diags.HasErrors() {
|
|
t.Fatalf("refresh errors: %s", diags.Err())
|
|
}
|
|
|
|
mod := s.RootModule()
|
|
if len(mod.Resources) > 0 {
|
|
t.Fatal("resources should be empty")
|
|
}
|
|
}
|
|
|
|
func TestContext2Refresh_ignoreUncreated(t *testing.T) {
|
|
p := testProvider("aws")
|
|
m := testModule(t, "refresh-basic")
|
|
ctx := testContext2(t, &ContextOpts{
|
|
Config: m,
|
|
ProviderResolver: ResourceProviderResolverFixed(
|
|
map[string]ResourceProviderFactory{
|
|
"aws": testProviderFuncFixed(p),
|
|
},
|
|
),
|
|
State: nil,
|
|
})
|
|
|
|
p.RefreshFn = nil
|
|
p.RefreshReturn = &InstanceState{
|
|
ID: "foo",
|
|
}
|
|
|
|
_, diags := ctx.Refresh()
|
|
if diags.HasErrors() {
|
|
t.Fatalf("refresh errors: %s", diags.Err())
|
|
}
|
|
if p.RefreshCalled {
|
|
t.Fatal("refresh should not be called")
|
|
}
|
|
}
|
|
|
|
func TestContext2Refresh_hook(t *testing.T) {
|
|
h := new(MockHook)
|
|
p := testProvider("aws")
|
|
m := testModule(t, "refresh-basic")
|
|
ctx := testContext2(t, &ContextOpts{
|
|
Config: m,
|
|
Hooks: []Hook{h},
|
|
ProviderResolver: ResourceProviderResolverFixed(
|
|
map[string]ResourceProviderFactory{
|
|
"aws": testProviderFuncFixed(p),
|
|
},
|
|
),
|
|
State: mustShimLegacyState(&State{
|
|
Modules: []*ModuleState{
|
|
&ModuleState{
|
|
Path: rootModulePath,
|
|
Resources: map[string]*ResourceState{
|
|
"aws_instance.web": &ResourceState{
|
|
Type: "aws_instance",
|
|
Primary: &InstanceState{
|
|
ID: "foo",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}),
|
|
})
|
|
|
|
if _, diags := ctx.Refresh(); diags.HasErrors() {
|
|
t.Fatalf("refresh errs: %s", diags.Err())
|
|
}
|
|
if !h.PreRefreshCalled {
|
|
t.Fatal("should be called")
|
|
}
|
|
if !h.PostRefreshCalled {
|
|
t.Fatal("should be called")
|
|
}
|
|
}
|
|
|
|
func TestContext2Refresh_modules(t *testing.T) {
|
|
p := testProvider("aws")
|
|
m := testModule(t, "refresh-modules")
|
|
state := mustShimLegacyState(&State{
|
|
Modules: []*ModuleState{
|
|
&ModuleState{
|
|
Path: rootModulePath,
|
|
Resources: map[string]*ResourceState{
|
|
"aws_instance.web": &ResourceState{
|
|
Type: "aws_instance",
|
|
Primary: &InstanceState{
|
|
ID: "bar",
|
|
Tainted: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
|
|
&ModuleState{
|
|
Path: []string{"root", "child"},
|
|
Resources: map[string]*ResourceState{
|
|
"aws_instance.web": &ResourceState{
|
|
Type: "aws_instance",
|
|
Primary: &InstanceState{
|
|
ID: "baz",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
})
|
|
ctx := testContext2(t, &ContextOpts{
|
|
Config: m,
|
|
ProviderResolver: ResourceProviderResolverFixed(
|
|
map[string]ResourceProviderFactory{
|
|
"aws": testProviderFuncFixed(p),
|
|
},
|
|
),
|
|
State: state,
|
|
})
|
|
|
|
p.RefreshFn = func(info *InstanceInfo, s *InstanceState) (*InstanceState, error) {
|
|
if s.ID != "baz" {
|
|
return s, nil
|
|
}
|
|
|
|
s.ID = "new"
|
|
return s, nil
|
|
}
|
|
|
|
s, diags := ctx.Refresh()
|
|
if diags.HasErrors() {
|
|
t.Fatalf("refresh errors: %s", diags.Err())
|
|
}
|
|
|
|
actual := strings.TrimSpace(s.String())
|
|
expected := strings.TrimSpace(testContextRefreshModuleStr)
|
|
if actual != expected {
|
|
t.Fatalf("wrong result\n\ngot:\n%s\n\nwant:\n%s", actual, expected)
|
|
}
|
|
}
|
|
|
|
func TestContext2Refresh_moduleInputComputedOutput(t *testing.T) {
|
|
m := testModule(t, "refresh-module-input-computed-output")
|
|
p := testProvider("aws")
|
|
p.DiffFn = testDiffFn
|
|
p.GetSchemaReturn = &ProviderSchema{
|
|
Provider: &configschema.Block{},
|
|
ResourceTypes: map[string]*configschema.Block{
|
|
"aws_instance": {
|
|
Attributes: map[string]*configschema.Attribute{
|
|
"foo": {
|
|
Type: cty.String,
|
|
Optional: true,
|
|
},
|
|
"compute": {
|
|
Type: cty.String,
|
|
Optional: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
ctx := testContext2(t, &ContextOpts{
|
|
Config: m,
|
|
ProviderResolver: ResourceProviderResolverFixed(
|
|
map[string]ResourceProviderFactory{
|
|
"aws": testProviderFuncFixed(p),
|
|
},
|
|
),
|
|
})
|
|
|
|
if _, diags := ctx.Refresh(); diags.HasErrors() {
|
|
t.Fatalf("refresh errs: %s", diags.Err())
|
|
}
|
|
}
|
|
|
|
func TestContext2Refresh_moduleVarModule(t *testing.T) {
|
|
m := testModule(t, "refresh-module-var-module")
|
|
p := testProvider("aws")
|
|
p.DiffFn = testDiffFn
|
|
ctx := testContext2(t, &ContextOpts{
|
|
Config: m,
|
|
ProviderResolver: ResourceProviderResolverFixed(
|
|
map[string]ResourceProviderFactory{
|
|
"aws": testProviderFuncFixed(p),
|
|
},
|
|
),
|
|
})
|
|
|
|
if _, diags := ctx.Refresh(); diags.HasErrors() {
|
|
t.Fatalf("refresh errs: %s", diags.Err())
|
|
}
|
|
}
|
|
|
|
// GH-70
|
|
func TestContext2Refresh_noState(t *testing.T) {
|
|
p := testProvider("aws")
|
|
m := testModule(t, "refresh-no-state")
|
|
ctx := testContext2(t, &ContextOpts{
|
|
Config: m,
|
|
ProviderResolver: ResourceProviderResolverFixed(
|
|
map[string]ResourceProviderFactory{
|
|
"aws": testProviderFuncFixed(p),
|
|
},
|
|
),
|
|
})
|
|
|
|
p.RefreshFn = nil
|
|
p.RefreshReturn = &InstanceState{
|
|
ID: "foo",
|
|
}
|
|
|
|
if _, diags := ctx.Refresh(); diags.HasErrors() {
|
|
t.Fatalf("refresh errs: %s", diags.Err())
|
|
}
|
|
}
|
|
|
|
func TestContext2Refresh_output(t *testing.T) {
|
|
p := testProvider("aws")
|
|
p.GetSchemaReturn = &ProviderSchema{
|
|
Provider: &configschema.Block{},
|
|
ResourceTypes: map[string]*configschema.Block{
|
|
"aws_instance": {
|
|
Attributes: map[string]*configschema.Attribute{
|
|
"foo": {
|
|
Type: cty.String,
|
|
Computed: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
m := testModule(t, "refresh-output")
|
|
ctx := testContext2(t, &ContextOpts{
|
|
Config: m,
|
|
ProviderResolver: ResourceProviderResolverFixed(
|
|
map[string]ResourceProviderFactory{
|
|
"aws": testProviderFuncFixed(p),
|
|
},
|
|
),
|
|
State: mustShimLegacyState(&State{
|
|
Modules: []*ModuleState{
|
|
&ModuleState{
|
|
Path: rootModulePath,
|
|
Resources: map[string]*ResourceState{
|
|
"aws_instance.web": &ResourceState{
|
|
Type: "aws_instance",
|
|
Primary: &InstanceState{
|
|
ID: "foo",
|
|
Attributes: map[string]string{
|
|
"foo": "bar",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
|
|
Outputs: map[string]*OutputState{
|
|
"foo": &OutputState{
|
|
Type: "string",
|
|
Sensitive: false,
|
|
Value: "foo",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}),
|
|
})
|
|
|
|
p.RefreshFn = func(info *InstanceInfo, s *InstanceState) (*InstanceState, error) {
|
|
return s, nil
|
|
}
|
|
|
|
s, diags := ctx.Refresh()
|
|
if diags.HasErrors() {
|
|
t.Fatalf("refresh errors: %s", diags.Err())
|
|
}
|
|
|
|
actual := strings.TrimSpace(s.String())
|
|
expected := strings.TrimSpace(testContextRefreshOutputStr)
|
|
if actual != expected {
|
|
t.Fatalf("wrong result\n\ngot:\n%s\n\nwant:\n%s", actual, expected)
|
|
}
|
|
}
|
|
|
|
func TestContext2Refresh_outputPartial(t *testing.T) {
|
|
p := testProvider("aws")
|
|
m := testModule(t, "refresh-output-partial")
|
|
ctx := testContext2(t, &ContextOpts{
|
|
Config: m,
|
|
ProviderResolver: ResourceProviderResolverFixed(
|
|
map[string]ResourceProviderFactory{
|
|
"aws": testProviderFuncFixed(p),
|
|
},
|
|
),
|
|
State: mustShimLegacyState(&State{
|
|
Modules: []*ModuleState{
|
|
&ModuleState{
|
|
Path: rootModulePath,
|
|
Resources: map[string]*ResourceState{
|
|
"aws_instance.foo": &ResourceState{
|
|
Type: "aws_instance",
|
|
Primary: &InstanceState{
|
|
ID: "foo",
|
|
},
|
|
},
|
|
},
|
|
Outputs: map[string]*OutputState{},
|
|
},
|
|
},
|
|
}),
|
|
})
|
|
|
|
p.RefreshFn = nil
|
|
p.RefreshReturn = nil
|
|
|
|
p.GetSchemaReturn = &ProviderSchema{
|
|
Provider: &configschema.Block{},
|
|
ResourceTypes: map[string]*configschema.Block{
|
|
"aws_instance": {
|
|
Attributes: map[string]*configschema.Attribute{
|
|
"foo": {
|
|
Type: cty.String,
|
|
Computed: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
s, diags := ctx.Refresh()
|
|
if diags.HasErrors() {
|
|
t.Fatalf("refresh errors: %s", diags.Err())
|
|
}
|
|
|
|
actual := strings.TrimSpace(s.String())
|
|
expected := strings.TrimSpace(testContextRefreshOutputPartialStr)
|
|
if actual != expected {
|
|
t.Fatalf("wrong result\n\ngot:\n%s\n\nwant:\n%s", actual, expected)
|
|
}
|
|
}
|
|
|
|
func TestContext2Refresh_stateBasic(t *testing.T) {
|
|
t.Fatalf("not yet updated for new provider interface")
|
|
/*
|
|
p := testProvider("aws")
|
|
m := testModule(t, "refresh-basic")
|
|
state := mustShimLegacyState(&State{
|
|
Modules: []*ModuleState{
|
|
&ModuleState{
|
|
Path: rootModulePath,
|
|
Resources: map[string]*ResourceState{
|
|
"aws_instance.web": &ResourceState{
|
|
Type: "aws_instance",
|
|
Primary: &InstanceState{
|
|
ID: "bar",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
})
|
|
ctx := testContext2(t, &ContextOpts{
|
|
Config: m,
|
|
ProviderResolver: ResourceProviderResolverFixed(
|
|
map[string]ResourceProviderFactory{
|
|
"aws": testProviderFuncFixed(p),
|
|
},
|
|
),
|
|
State: state,
|
|
})
|
|
|
|
p.RefreshFn = nil
|
|
p.RefreshReturn = &InstanceState{
|
|
ID: "foo",
|
|
}
|
|
|
|
s, diags := ctx.Refresh()
|
|
if diags.HasErrors() {
|
|
t.Fatalf("refresh errors: %s", diags.Err())
|
|
}
|
|
originalMod := state.RootModule()
|
|
mod := s.RootModule()
|
|
if !p.RefreshCalled {
|
|
t.Fatal("refresh should be called")
|
|
}
|
|
if !reflect.DeepEqual(p.RefreshState, originalMod.Resources["aws_instance.web"].Primary) {
|
|
t.Fatalf(
|
|
"bad:\n\n%#v\n\n%#v",
|
|
p.RefreshState,
|
|
originalMod.Resources["aws_instance.web"].Primary)
|
|
}
|
|
if !reflect.DeepEqual(mod.Resources["aws_instance.web"].Primary, p.RefreshReturn) {
|
|
t.Fatalf("bad: %#v", mod.Resources)
|
|
}
|
|
*/
|
|
}
|
|
|
|
func TestContext2Refresh_dataOrphan(t *testing.T) {
|
|
p := testProvider("null")
|
|
state := mustShimLegacyState(&State{
|
|
Modules: []*ModuleState{
|
|
&ModuleState{
|
|
Path: rootModulePath,
|
|
Resources: map[string]*ResourceState{
|
|
"data.null_data_source.bar": &ResourceState{
|
|
Type: "null_data_source",
|
|
Primary: &InstanceState{
|
|
ID: "foo",
|
|
},
|
|
Provider: "provider.null",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
})
|
|
ctx := testContext2(t, &ContextOpts{
|
|
ProviderResolver: ResourceProviderResolverFixed(
|
|
map[string]ResourceProviderFactory{
|
|
"null": testProviderFuncFixed(p),
|
|
},
|
|
),
|
|
State: state,
|
|
})
|
|
|
|
s, diags := ctx.Refresh()
|
|
if diags.HasErrors() {
|
|
t.Fatalf("refresh errors: %s", diags.Err())
|
|
}
|
|
|
|
checkStateString(t, s, `<no state>`)
|
|
}
|
|
|
|
func TestContext2Refresh_dataState(t *testing.T) {
|
|
t.Fatalf("not yet updated for new provider interface")
|
|
/*
|
|
m := testModule(t, "refresh-data-resource-basic")
|
|
|
|
state := mustShimLegacyState(&State{
|
|
Modules: []*ModuleState{
|
|
&ModuleState{
|
|
Path: rootModulePath,
|
|
// Intentionally no resources since data resources are
|
|
// supposed to refresh themselves even if they didn't
|
|
// already exist.
|
|
Resources: map[string]*ResourceState{},
|
|
},
|
|
},
|
|
})
|
|
|
|
p := testProvider("null")
|
|
p.GetSchemaReturn = &ProviderSchema{
|
|
Provider: &configschema.Block{},
|
|
DataSources: map[string]*configschema.Block{
|
|
"null_data_source": {
|
|
Attributes: map[string]*configschema.Attribute{
|
|
"inputs": {
|
|
Type: cty.Map(cty.String),
|
|
Optional: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
ctx := testContext2(t, &ContextOpts{
|
|
Config: m,
|
|
ProviderResolver: ResourceProviderResolverFixed(
|
|
map[string]ResourceProviderFactory{
|
|
"null": testProviderFuncFixed(p),
|
|
},
|
|
),
|
|
State: state,
|
|
})
|
|
|
|
p.ReadDataDiffFn = nil
|
|
p.ReadDataDiffReturn = &InstanceDiff{
|
|
Attributes: map[string]*ResourceAttrDiff{
|
|
"inputs.#": {
|
|
Old: "0",
|
|
New: "1",
|
|
Type: DiffAttrInput,
|
|
},
|
|
"inputs.test": {
|
|
Old: "",
|
|
New: "yes",
|
|
Type: DiffAttrInput,
|
|
},
|
|
"outputs.#": {
|
|
Old: "",
|
|
New: "",
|
|
NewComputed: true,
|
|
Type: DiffAttrOutput,
|
|
},
|
|
},
|
|
}
|
|
|
|
p.ReadDataApplyFn = nil
|
|
p.ReadDataApplyReturn = &InstanceState{
|
|
ID: "-",
|
|
}
|
|
|
|
s, diags := ctx.Refresh()
|
|
if diags.HasErrors() {
|
|
t.Fatalf("refresh errors: %s", diags.Err())
|
|
}
|
|
|
|
if !p.ReadDataDiffCalled {
|
|
t.Fatal("ReadDataDiff should have been called")
|
|
}
|
|
if !p.ReadDataApplyCalled {
|
|
t.Fatal("ReadDataApply should have been called")
|
|
}
|
|
|
|
mod := s.RootModule()
|
|
if got := mod.Resources["data.null_data_source.testing"].Primary.ID; got != "-" {
|
|
t.Fatalf("resource id is %q; want %s", got, "-")
|
|
}
|
|
if !reflect.DeepEqual(mod.Resources["data.null_data_source.testing"].Primary, p.ReadDataApplyReturn) {
|
|
t.Fatalf("bad: %#v", mod.Resources)
|
|
}
|
|
*/
|
|
}
|
|
|
|
func TestContext2Refresh_dataStateRefData(t *testing.T) {
|
|
p := testProvider("null")
|
|
p.GetSchemaReturn = &ProviderSchema{
|
|
Provider: &configschema.Block{},
|
|
DataSources: map[string]*configschema.Block{
|
|
"null_data_source": {
|
|
Attributes: map[string]*configschema.Attribute{
|
|
"foo": {
|
|
Type: cty.String,
|
|
Optional: true,
|
|
},
|
|
"bar": {
|
|
Type: cty.String,
|
|
Optional: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
m := testModule(t, "refresh-data-ref-data")
|
|
state := mustShimLegacyState(&State{
|
|
Modules: []*ModuleState{
|
|
&ModuleState{
|
|
Path: rootModulePath,
|
|
// Intentionally no resources since data resources are
|
|
// supposed to refresh themselves even if they didn't
|
|
// already exist.
|
|
Resources: map[string]*ResourceState{},
|
|
},
|
|
},
|
|
})
|
|
ctx := testContext2(t, &ContextOpts{
|
|
Config: m,
|
|
ProviderResolver: ResourceProviderResolverFixed(
|
|
map[string]ResourceProviderFactory{
|
|
"null": testProviderFuncFixed(p),
|
|
},
|
|
),
|
|
State: state,
|
|
})
|
|
|
|
p.ReadDataDiffFn = testDataDiffFn
|
|
p.ReadDataApplyFn = testDataApplyFn
|
|
|
|
s, diags := ctx.Refresh()
|
|
if diags.HasErrors() {
|
|
t.Fatalf("refresh errors: %s", diags.Err())
|
|
}
|
|
|
|
actual := strings.TrimSpace(s.String())
|
|
expected := strings.TrimSpace(testTerraformRefreshDataRefDataStr)
|
|
if actual != expected {
|
|
t.Fatalf("wrong result\n\ngot:\n%s\n\nwant:\n%s", actual, expected)
|
|
}
|
|
}
|
|
|
|
func TestContext2Refresh_tainted(t *testing.T) {
|
|
p := testProvider("aws")
|
|
m := testModule(t, "refresh-basic")
|
|
state := mustShimLegacyState(&State{
|
|
Modules: []*ModuleState{
|
|
&ModuleState{
|
|
Path: rootModulePath,
|
|
Resources: map[string]*ResourceState{
|
|
"aws_instance.web": &ResourceState{
|
|
Type: "aws_instance",
|
|
Primary: &InstanceState{
|
|
ID: "bar",
|
|
Tainted: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
})
|
|
ctx := testContext2(t, &ContextOpts{
|
|
Config: m,
|
|
ProviderResolver: ResourceProviderResolverFixed(
|
|
map[string]ResourceProviderFactory{
|
|
"aws": testProviderFuncFixed(p),
|
|
},
|
|
),
|
|
State: state,
|
|
})
|
|
|
|
p.RefreshFn = nil
|
|
p.RefreshReturn = &InstanceState{
|
|
ID: "foo",
|
|
Tainted: true,
|
|
}
|
|
|
|
s, diags := ctx.Refresh()
|
|
if diags.HasErrors() {
|
|
t.Fatalf("refresh errors: %s", diags.Err())
|
|
}
|
|
if !p.RefreshCalled {
|
|
t.Fatal("refresh should be called")
|
|
}
|
|
|
|
actual := strings.TrimSpace(s.String())
|
|
expected := strings.TrimSpace(testContextRefreshTaintedStr)
|
|
if actual != expected {
|
|
t.Fatalf("wrong result\n\ngot:\n%s\n\nwant:\n%s", actual, expected)
|
|
}
|
|
}
|
|
|
|
// Doing a Refresh (or any operation really, but Refresh usually
|
|
// happens first) with a config with an unknown provider should result in
|
|
// an error. The key bug this found was that this wasn't happening if
|
|
// Providers was _empty_.
|
|
func TestContext2Refresh_unknownProvider(t *testing.T) {
|
|
m := testModule(t, "refresh-unknown-provider")
|
|
p := testProvider("aws")
|
|
p.ApplyFn = testApplyFn
|
|
p.DiffFn = testDiffFn
|
|
|
|
_, diags := NewContext(&ContextOpts{
|
|
Config: m,
|
|
ProviderResolver: ResourceProviderResolverFixed(
|
|
map[string]ResourceProviderFactory{},
|
|
),
|
|
State: mustShimLegacyState(&State{
|
|
Modules: []*ModuleState{
|
|
&ModuleState{
|
|
Path: rootModulePath,
|
|
Resources: map[string]*ResourceState{
|
|
"aws_instance.web": &ResourceState{
|
|
Type: "aws_instance",
|
|
Primary: &InstanceState{
|
|
ID: "foo",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}),
|
|
})
|
|
|
|
if !diags.HasErrors() {
|
|
t.Fatal("successfully created context; want error")
|
|
}
|
|
|
|
if !regexp.MustCompile(`provider ".+" is not available`).MatchString(diags.Err().Error()) {
|
|
t.Fatalf("wrong error: %s", diags.Err())
|
|
}
|
|
}
|
|
|
|
func TestContext2Refresh_vars(t *testing.T) {
|
|
t.Fatalf("not yet updated for new provider interface")
|
|
/*
|
|
p := testProvider("aws")
|
|
p.GetSchemaReturn = &ProviderSchema{
|
|
Provider: &configschema.Block{},
|
|
ResourceTypes: map[string]*configschema.Block{
|
|
"aws_instance": {
|
|
Attributes: map[string]*configschema.Attribute{
|
|
"ami": {
|
|
Type: cty.String,
|
|
Optional: true,
|
|
},
|
|
"id": {
|
|
Type: cty.String,
|
|
Computed: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
m := testModule(t, "refresh-vars")
|
|
ctx := testContext2(t, &ContextOpts{
|
|
Config: m,
|
|
ProviderResolver: ResourceProviderResolverFixed(
|
|
map[string]ResourceProviderFactory{
|
|
"aws": testProviderFuncFixed(p),
|
|
},
|
|
),
|
|
State: mustShimLegacyState(&State{
|
|
|
|
Modules: []*ModuleState{
|
|
&ModuleState{
|
|
Path: rootModulePath,
|
|
Resources: map[string]*ResourceState{
|
|
"aws_instance.web": &ResourceState{
|
|
Type: "aws_instance",
|
|
Primary: &InstanceState{
|
|
ID: "foo",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}),
|
|
})
|
|
|
|
p.RefreshFn = nil
|
|
p.RefreshReturn = &InstanceState{
|
|
ID: "foo",
|
|
}
|
|
|
|
s, diags := ctx.Refresh()
|
|
if diags.HasErrors() {
|
|
t.Fatalf("refresh errors: %s", diags.Err())
|
|
}
|
|
mod := s.RootModule()
|
|
if !p.RefreshCalled {
|
|
t.Fatal("refresh should be called")
|
|
}
|
|
if p.RefreshState.ID != "foo" {
|
|
t.Fatalf("bad: %#v", p.RefreshState)
|
|
}
|
|
if !reflect.DeepEqual(mod.Resources["aws_instance.web"].Primary, p.RefreshReturn) {
|
|
t.Fatalf("bad: %#v", mod.Resources["aws_instance.web"])
|
|
}
|
|
|
|
for _, r := range mod.Resources {
|
|
if r.Addr.Type == "" {
|
|
t.Fatalf("no type: %#v", r)
|
|
}
|
|
}
|
|
*/
|
|
}
|
|
|
|
func TestContext2Refresh_orphanModule(t *testing.T) {
|
|
p := testProvider("aws")
|
|
m := testModule(t, "refresh-module-orphan")
|
|
|
|
// Create a custom refresh function to track the order they were visited
|
|
var order []string
|
|
var orderLock sync.Mutex
|
|
p.RefreshFn = func(
|
|
info *InstanceInfo,
|
|
is *InstanceState) (*InstanceState, error) {
|
|
orderLock.Lock()
|
|
defer orderLock.Unlock()
|
|
|
|
order = append(order, is.ID)
|
|
return is, nil
|
|
}
|
|
p.GetSchemaReturn = &ProviderSchema{
|
|
Provider: &configschema.Block{},
|
|
ResourceTypes: map[string]*configschema.Block{
|
|
"aws_instance": {},
|
|
},
|
|
}
|
|
|
|
state := mustShimLegacyState(&State{
|
|
Modules: []*ModuleState{
|
|
&ModuleState{
|
|
Path: rootModulePath,
|
|
Resources: map[string]*ResourceState{
|
|
"aws_instance.foo": &ResourceState{
|
|
Type: "aws_instance",
|
|
Primary: &InstanceState{
|
|
ID: "i-abc123",
|
|
Attributes: map[string]string{
|
|
"childid": "i-bcd234",
|
|
"grandchildid": "i-cde345",
|
|
},
|
|
},
|
|
Dependencies: []string{
|
|
"module.child",
|
|
"module.child",
|
|
},
|
|
Provider: "provider.aws",
|
|
},
|
|
},
|
|
},
|
|
&ModuleState{
|
|
Path: append(rootModulePath, "child"),
|
|
Resources: map[string]*ResourceState{
|
|
"aws_instance.bar": &ResourceState{
|
|
Type: "aws_instance",
|
|
Primary: &InstanceState{
|
|
ID: "i-bcd234",
|
|
Attributes: map[string]string{
|
|
"grandchildid": "i-cde345",
|
|
},
|
|
},
|
|
Dependencies: []string{
|
|
"module.grandchild",
|
|
},
|
|
Provider: "provider.aws",
|
|
},
|
|
},
|
|
Outputs: map[string]*OutputState{
|
|
"id": &OutputState{
|
|
Value: "i-bcd234",
|
|
Type: "string",
|
|
},
|
|
"grandchild_id": &OutputState{
|
|
Value: "i-cde345",
|
|
Type: "string",
|
|
},
|
|
},
|
|
},
|
|
&ModuleState{
|
|
Path: append(rootModulePath, "child", "grandchild"),
|
|
Resources: map[string]*ResourceState{
|
|
"aws_instance.baz": &ResourceState{
|
|
Type: "aws_instance",
|
|
Primary: &InstanceState{
|
|
ID: "i-cde345",
|
|
},
|
|
Provider: "provider.aws",
|
|
},
|
|
},
|
|
Outputs: map[string]*OutputState{
|
|
"id": &OutputState{
|
|
Value: "i-cde345",
|
|
Type: "string",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
})
|
|
ctx := testContext2(t, &ContextOpts{
|
|
Config: m,
|
|
ProviderResolver: ResourceProviderResolverFixed(
|
|
map[string]ResourceProviderFactory{
|
|
"aws": testProviderFuncFixed(p),
|
|
},
|
|
),
|
|
State: state,
|
|
})
|
|
|
|
testCheckDeadlock(t, func() {
|
|
_, err := ctx.Refresh()
|
|
if err != nil {
|
|
t.Fatalf("err: %s", err)
|
|
}
|
|
|
|
// TODO: handle order properly for orphaned modules / resources
|
|
// expected := []string{"i-abc123", "i-bcd234", "i-cde345"}
|
|
// if !reflect.DeepEqual(order, expected) {
|
|
// t.Fatalf("expected: %#v, got: %#v", expected, order)
|
|
// }
|
|
})
|
|
}
|
|
|
|
func TestContext2Validate(t *testing.T) {
|
|
p := testProvider("aws")
|
|
p.GetSchemaReturn = &ProviderSchema{
|
|
Provider: &configschema.Block{},
|
|
ResourceTypes: map[string]*configschema.Block{
|
|
"aws_instance": {
|
|
Attributes: map[string]*configschema.Attribute{
|
|
"foo": {
|
|
Type: cty.String,
|
|
Optional: true,
|
|
},
|
|
"num": {
|
|
Type: cty.String,
|
|
Optional: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
m := testModule(t, "validate-good")
|
|
c := testContext2(t, &ContextOpts{
|
|
Config: m,
|
|
ProviderResolver: ResourceProviderResolverFixed(
|
|
map[string]ResourceProviderFactory{
|
|
"aws": testProviderFuncFixed(p),
|
|
},
|
|
),
|
|
})
|
|
|
|
diags := c.Validate()
|
|
if len(diags) != 0 {
|
|
t.Fatalf("unexpected error: %#v", diags.ErrWithWarnings())
|
|
}
|
|
}
|
|
|
|
// TestContext2Refresh_noDiffHookOnScaleOut tests to make sure that
|
|
// pre/post-diff hooks are not called when running EvalDiff on scale-out nodes
|
|
// (nodes with no state). The effect here is to make sure that the diffs -
|
|
// which only exist for interpolation of parallel resources or data sources -
|
|
// do not end up being counted in the UI.
|
|
func TestContext2Refresh_noDiffHookOnScaleOut(t *testing.T) {
|
|
h := new(MockHook)
|
|
p := testProvider("aws")
|
|
m := testModule(t, "refresh-resource-scale-inout")
|
|
p.RefreshFn = nil
|
|
p.GetSchemaReturn = &ProviderSchema{
|
|
Provider: &configschema.Block{},
|
|
ResourceTypes: map[string]*configschema.Block{
|
|
"aws_instance": {},
|
|
},
|
|
}
|
|
|
|
state := mustShimLegacyState(&State{
|
|
Modules: []*ModuleState{
|
|
&ModuleState{
|
|
Path: rootModulePath,
|
|
Resources: map[string]*ResourceState{
|
|
"aws_instance.foo.0": &ResourceState{
|
|
Type: "aws_instance",
|
|
Deposed: []*InstanceState{
|
|
&InstanceState{
|
|
ID: "foo",
|
|
},
|
|
},
|
|
},
|
|
"aws_instance.foo.1": &ResourceState{
|
|
Type: "aws_instance",
|
|
Deposed: []*InstanceState{
|
|
&InstanceState{
|
|
ID: "bar",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
ctx := testContext2(t, &ContextOpts{
|
|
Config: m,
|
|
Hooks: []Hook{h},
|
|
ProviderResolver: ResourceProviderResolverFixed(
|
|
map[string]ResourceProviderFactory{
|
|
"aws": testProviderFuncFixed(p),
|
|
},
|
|
),
|
|
State: state,
|
|
})
|
|
|
|
_, diags := ctx.Refresh()
|
|
if diags.HasErrors() {
|
|
t.Fatalf("refresh errors: %s", diags.Err())
|
|
}
|
|
if h.PreDiffCalled {
|
|
t.Fatal("PreDiff should not have been called")
|
|
}
|
|
if h.PostDiffCalled {
|
|
t.Fatal("PostDiff should not have been called")
|
|
}
|
|
}
|
|
|
|
func TestContext2Refresh_updateProviderInState(t *testing.T) {
|
|
m := testModule(t, "update-resource-provider")
|
|
p := testProvider("aws")
|
|
p.DiffFn = testDiffFn
|
|
p.ApplyFn = testApplyFn
|
|
p.GetSchemaReturn = &ProviderSchema{
|
|
Provider: &configschema.Block{},
|
|
ResourceTypes: map[string]*configschema.Block{
|
|
"aws_instance": {},
|
|
},
|
|
}
|
|
|
|
s := mustShimLegacyState(&State{
|
|
Modules: []*ModuleState{
|
|
&ModuleState{
|
|
Path: rootModulePath,
|
|
Resources: map[string]*ResourceState{
|
|
"aws_instance.bar": &ResourceState{
|
|
Type: "aws_instance",
|
|
Primary: &InstanceState{
|
|
ID: "foo",
|
|
},
|
|
Provider: "provider.aws.baz",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
ctx := testContext2(t, &ContextOpts{
|
|
Config: m,
|
|
ProviderResolver: ResourceProviderResolverFixed(
|
|
map[string]ResourceProviderFactory{
|
|
"aws": testProviderFuncFixed(p),
|
|
},
|
|
),
|
|
State: s,
|
|
})
|
|
|
|
expected := strings.TrimSpace(`
|
|
aws_instance.bar:
|
|
ID = foo
|
|
provider = provider.aws.foo`)
|
|
|
|
state, diags := ctx.Refresh()
|
|
if diags.HasErrors() {
|
|
t.Fatal(diags.Err())
|
|
}
|
|
|
|
actual := state.String()
|
|
if actual != expected {
|
|
t.Fatalf("expected:\n%s\n\ngot:\n%s", expected, actual)
|
|
}
|
|
}
|