From bcfec4e24eb538e43beab4d30a95c527b172ca82 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sat, 12 Nov 2016 15:22:48 -0800 Subject: [PATCH] terraform: test that dependencies in the state are enough to maintain order --- terraform/context_apply_test.go | 89 +++++++++++++++++++ .../main.tf | 1 + 2 files changed, 90 insertions(+) create mode 100644 terraform/test-fixtures/apply-resource-depends-on-module-empty/main.tf diff --git a/terraform/context_apply_test.go b/terraform/context_apply_test.go index 53c211807..00be062b8 100644 --- a/terraform/context_apply_test.go +++ b/terraform/context_apply_test.go @@ -164,6 +164,95 @@ func TestContext2Apply_resourceDependsOnModule(t *testing.T) { } } +// Test that without a config, the Dependencies in the state are enough +// to maintain proper ordering. +func TestContext2Apply_resourceDependsOnModuleStateOnly(t *testing.T) { + m := testModule(t, "apply-resource-depends-on-module-empty") + p := testProvider("aws") + p.DiffFn = testDiffFn + + state := &State{ + Modules: []*ModuleState{ + &ModuleState{ + Path: rootModulePath, + Resources: map[string]*ResourceState{ + "aws_instance.a": &ResourceState{ + Type: "aws_instance", + Primary: &InstanceState{ + ID: "bar", + }, + Dependencies: []string{"module.child"}, + }, + }, + }, + &ModuleState{ + Path: []string{"root", "child"}, + Resources: map[string]*ResourceState{ + "aws_instance.child": &ResourceState{ + Type: "aws_instance", + Primary: &InstanceState{ + ID: "bar", + }, + }, + }, + }, + }, + } + + { + // Wait for the dependency, sleep, and verify the graph never + // called a child. + var called int32 + var checked bool + p.ApplyFn = func( + info *InstanceInfo, + is *InstanceState, + id *InstanceDiff) (*InstanceState, error) { + if info.HumanId() == "aws_instance.a" { + checked = true + + // Sleep to allow parallel execution + time.Sleep(50 * time.Millisecond) + + // Verify that called is 0 (dep not called) + if atomic.LoadInt32(&called) != 0 { + return nil, fmt.Errorf("module child should not be called") + } + } + + atomic.AddInt32(&called, 1) + return testApplyFn(info, is, id) + } + + ctx := testContext2(t, &ContextOpts{ + Module: m, + Providers: map[string]ResourceProviderFactory{ + "aws": testProviderFuncFixed(p), + }, + State: state, + }) + + if _, err := ctx.Plan(); err != nil { + t.Fatalf("err: %s", err) + } + + state, err := ctx.Apply() + if err != nil { + t.Fatalf("err: %s", err) + } + + if !checked { + t.Fatal("should check") + } + + checkStateString(t, state, ` + +module.child: + + `) + } +} + func TestContext2Apply_resourceDependsOnModuleDestroy(t *testing.T) { m := testModule(t, "apply-resource-depends-on-module") p := testProvider("aws") diff --git a/terraform/test-fixtures/apply-resource-depends-on-module-empty/main.tf b/terraform/test-fixtures/apply-resource-depends-on-module-empty/main.tf new file mode 100644 index 000000000..f2316bd73 --- /dev/null +++ b/terraform/test-fixtures/apply-resource-depends-on-module-empty/main.tf @@ -0,0 +1 @@ +# Empty!