Skip to content

Commit

Permalink
Merge pull request #1949 from hashicorp/b-module-cbd-computed-count-d…
Browse files Browse the repository at this point in the history
…eadlock

core: fix deadlock w/ CBD + modules
  • Loading branch information
phinze committed May 13, 2015
2 parents 725f667 + b0eafeb commit e1b4bf3
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 0 deletions.
50 changes: 50 additions & 0 deletions terraform/context_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,56 @@ func TestContext2Plan_moduleCycle(t *testing.T) {
}
}

func TestContext2Plan_moduleDeadlock(t *testing.T) {
m := testModule(t, "plan-module-deadlock")
p := testProvider("aws")
p.DiffFn = testDiffFn
timeout := make(chan bool, 1)
done := make(chan bool, 1)
go func() {
time.Sleep(3 * time.Second)
timeout <- true
}()
go func() {
ctx := testContext2(t, &ContextOpts{
Module: m,
Providers: map[string]ResourceProviderFactory{
"aws": testProviderFuncFixed(p),
},
})

plan, err := ctx.Plan()
done <- true
if err != nil {
t.Fatalf("err: %s", err)
}

actual := strings.TrimSpace(plan.String())
expected := strings.TrimSpace(`
DIFF:
module.child:
CREATE: aws_instance.foo.0
CREATE: aws_instance.foo.1
CREATE: aws_instance.foo.2
STATE:
<no state>
`)
if actual != expected {
t.Fatalf("expected:\n%sgot:\n%s", expected, actual)
}
}()

select {
case <-timeout:
t.Fatalf("timed out! probably deadlock")
case <-done:
// ok
}
}

func TestContext2Plan_moduleInput(t *testing.T) {
m := testModule(t, "plan-module-input")
p := testProvider("aws")
Expand Down
8 changes: 8 additions & 0 deletions terraform/graph_config_node_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -311,13 +311,17 @@ func (n *GraphNodeConfigResourceFlat) DestroyNode(mode GraphNodeDestroyMode) Gra
return &graphNodeResourceDestroyFlat{
graphNodeResourceDestroy: node,
PathValue: n.PathValue,
FlatCreateNode: n,
}
}

type graphNodeResourceDestroyFlat struct {
*graphNodeResourceDestroy

PathValue []string

// Needs to be able to properly yield back a flattened create node to prevent
FlatCreateNode *GraphNodeConfigResourceFlat
}

func (n *graphNodeResourceDestroyFlat) Name() string {
Expand All @@ -329,6 +333,10 @@ func (n *graphNodeResourceDestroyFlat) Path() []string {
return n.PathValue
}

func (n *graphNodeResourceDestroyFlat) CreateNode() dag.Vertex {
return n.FlatCreateNode
}

// graphNodeResourceDestroy represents the logical destruction of a
// resource. This node doesn't mean it will be destroyed for sure, but
// instead that if a destroy were to happen, it must happen at this point.
Expand Down
4 changes: 4 additions & 0 deletions terraform/test-fixtures/plan-module-deadlock/child/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
resource "aws_instance" "foo" {
count = "${length("abc")}"
lifecycle { create_before_destroy = true }
}
3 changes: 3 additions & 0 deletions terraform/test-fixtures/plan-module-deadlock/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module "child" {
source = "./child"
}

0 comments on commit e1b4bf3

Please sign in to comment.