diff --git a/terraform/graph_test.go b/terraform/graph_test.go index b634b9cce..d1ef90c3b 100644 --- a/terraform/graph_test.go +++ b/terraform/graph_test.go @@ -128,6 +128,80 @@ func TestGraphFull(t *testing.T) { } } +func TestGraphProvisioners(t *testing.T) { + rpAws := new(MockResourceProvider) + provShell := new(MockResourceProvisioner) + provWinRM := new(MockResourceProvisioner) + + rpAws.ResourcesReturn = []ResourceType{ + ResourceType{Name: "aws_instance"}, + ResourceType{Name: "aws_load_balancer"}, + ResourceType{Name: "aws_security_group"}, + } + + ps := map[string]ResourceProvisionerFactory{ + "shell": testProvisionerFuncFixed(provShell), + "winrm": testProvisionerFuncFixed(provWinRM), + } + + pf := map[string]ResourceProviderFactory{ + "aws": testProviderFuncFixed(rpAws), + } + + c := testConfig(t, "graph-provisioners") + g, err := Graph(&GraphOpts{Config: c, Providers: pf, Provisioners: ps}) + if err != nil { + t.Fatalf("err: %s", err) + } + + // A helper to help get us the provider for a resource. + graphProvisioner := func(n string, idx int) *ResourceProvisionerConfig { + return g.Noun(n).Meta.(*GraphNodeResource).Resource.Provisioners[idx] + } + + // A helper to verify depedencies + depends := func(a, b string) bool { + aNoun := g.Noun(a) + bNoun := g.Noun(b) + for _, dep := range aNoun.Deps { + if dep.Source == aNoun && dep.Target == bNoun { + return true + } + } + return false + } + + // Test a couple + prov := graphProvisioner("aws_instance.web", 0) + if prov.Provisioner != provWinRM { + t.Fatalf("bad: %#v", prov) + } + if prov.RawConfig.Config()["cmd"] != "echo foo" { + t.Fatalf("bad: %#v", prov) + } + + prov = graphProvisioner("aws_instance.web", 1) + if prov.Provisioner != provWinRM { + t.Fatalf("bad: %#v", prov) + } + if prov.RawConfig.Config()["cmd"] != "echo bar" { + t.Fatalf("bad: %#v", prov) + } + + prov = graphProvisioner("aws_load_balancer.weblb", 0) + if prov.Provisioner != provShell { + t.Fatalf("bad: %#v", prov) + } + if prov.RawConfig.Config()["cmd"] != "add ${aws_instance.web.id}" { + t.Fatalf("bad: %#v", prov) + } + + // Check that the variable dependency is handled + if !depends("aws_load_balancer.weblb", "aws_instance.web") { + t.Fatalf("missing dependency from provisioner variable") + } +} + func TestGraphAddDiff(t *testing.T) { config := testConfig(t, "graph-diff") diff := &Diff{ diff --git a/terraform/terraform_test.go b/terraform/terraform_test.go index 77a4ded34..74a72a5cc 100644 --- a/terraform/terraform_test.go +++ b/terraform/terraform_test.go @@ -45,6 +45,12 @@ func testProviderFuncFixed(rp ResourceProvider) ResourceProviderFactory { } } +func testProvisionerFuncFixed(rp ResourceProvisioner) ResourceProvisionerFactory { + return func() (ResourceProvisioner, error) { + return rp, nil + } +} + // HookRecordApplyOrder is a test hook that records the order of applies // by recording the PreApply event. type HookRecordApplyOrder struct { diff --git a/terraform/test-fixtures/graph-provisioners/main.tf b/terraform/test-fixtures/graph-provisioners/main.tf new file mode 100644 index 000000000..96035ecc4 --- /dev/null +++ b/terraform/test-fixtures/graph-provisioners/main.tf @@ -0,0 +1,28 @@ +variable "foo" { + default = "bar"; + description = "bar"; +} + +provider "aws" {} + +resource "aws_security_group" "firewall" {} + +resource "aws_instance" "web" { + ami = "${var.foo}" + security_groups = [ + "foo", + "${aws_security_group.firewall.foo}" + ] + provisioner "winrm" { + cmd = "echo foo" + } + provisioner "winrm" { + cmd = "echo bar" + } +} + +resource "aws_load_balancer" "weblb" { + provisioner "shell" { + cmd = "add ${aws_instance.web.id}" + } +}