diff --git a/terraform/context_apply_test.go b/terraform/context_apply_test.go index 4b2113d63..1fd069db0 100644 --- a/terraform/context_apply_test.go +++ b/terraform/context_apply_test.go @@ -10,6 +10,8 @@ import ( "sync/atomic" "testing" "time" + + "github.com/hashicorp/terraform/config/module" ) func TestContext2Apply(t *testing.T) { @@ -298,6 +300,88 @@ func TestContext2Apply_destroyComputed(t *testing.T) { } } +// https://github.com/hashicorp/terraform/issues/2892 +func TestContext2Apply_destroyCrossProviders(t *testing.T) { + m := testModule(t, "apply-destroy-cross-providers") + + p_aws := testProvider("aws") + p_aws.ApplyFn = testApplyFn + p_aws.DiffFn = testDiffFn + + p_tf := testProvider("terraform") + p_tf.ApplyFn = testApplyFn + p_tf.DiffFn = testDiffFn + + providers := map[string]ResourceProviderFactory{ + "aws": testProviderFuncFixed(p_aws), + "terraform": testProviderFuncFixed(p_tf), + } + + // Bug only appears from time to time, + // so we run this test multiple times + // to check for the race-condition + for i := 0; i <= 10; i++ { + ctx := getContextForApply_destroyCrossProviders( + t, m, providers) + + if p, err := ctx.Plan(); err != nil { + t.Fatalf("err: %s", err) + } else { + t.Logf(p.String()) + } + + if _, err := ctx.Apply(); err != nil { + t.Fatalf("err: %s", err) + } + } +} + +func getContextForApply_destroyCrossProviders( + t *testing.T, + m *module.Tree, + providers map[string]ResourceProviderFactory) *Context { + state := &State{ + Modules: []*ModuleState{ + &ModuleState{ + Path: rootModulePath, + Resources: map[string]*ResourceState{ + "terraform_remote_state.shared": &ResourceState{ + Type: "terraform_remote_state", + Primary: &InstanceState{ + ID: "remote-2652591293", + Attributes: map[string]string{ + "output.env_name": "test", + }, + }, + }, + }, + }, + &ModuleState{ + Path: []string{"root", "example"}, + Resources: map[string]*ResourceState{ + "aws_vpc.bar": &ResourceState{ + Type: "aws_vpc", + Primary: &InstanceState{ + ID: "vpc-aaabbb12", + Attributes: map[string]string{ + "value": "test", + }, + }, + }, + }, + }, + }, + } + ctx := testContext2(t, &ContextOpts{ + Module: m, + Providers: providers, + State: state, + Destroy: true, + }) + + return ctx +} + func TestContext2Apply_minimal(t *testing.T) { m := testModule(t, "apply-minimal") p := testProvider("aws") diff --git a/terraform/test-fixtures/apply-destroy-cross-providers/child/main.tf b/terraform/test-fixtures/apply-destroy-cross-providers/child/main.tf new file mode 100644 index 000000000..048b26dec --- /dev/null +++ b/terraform/test-fixtures/apply-destroy-cross-providers/child/main.tf @@ -0,0 +1,5 @@ +variable "value" {} + +resource "aws_vpc" "bar" { + value = "${var.value}" +} diff --git a/terraform/test-fixtures/apply-destroy-cross-providers/main.tf b/terraform/test-fixtures/apply-destroy-cross-providers/main.tf new file mode 100644 index 000000000..b0595b9e8 --- /dev/null +++ b/terraform/test-fixtures/apply-destroy-cross-providers/main.tf @@ -0,0 +1,6 @@ +resource "terraform_remote_state" "shared" {} + +module "child" { + source = "./child" + value = "${terraform_remote_state.shared.output.env_name}" +}