diff --git a/command/e2etest/primary_test.go b/command/e2etest/primary_test.go new file mode 100644 index 0000000000..f491683c9e --- /dev/null +++ b/command/e2etest/primary_test.go @@ -0,0 +1,123 @@ +package e2etest + +import ( + "reflect" + "sort" + "strings" + "testing" + + "github.com/davecgh/go-spew/spew" +) + +// The tests in this file are for the "primary workflow", which includes +// variants of the following sequence, with different details: +// terraform init +// terraform plan +// terraform apply +// terraform destroy + +func TestPrimarySeparatePlan(t *testing.T) { + t.Parallel() + + // This test reaches out to releases.hashicorp.com to download the + // template and null providers, so it can only run if network access is + // allowed. + skipIfCannotAccessNetwork(t) + + tf := newTerraform("full-workflow-null") + defer tf.Close() + + //// INIT + stdout, stderr, err := tf.Run("init") + if err != nil { + t.Fatalf("unexpected init error: %s\nstderr:\n%s", err, stderr) + } + + // Make sure we actually downloaded the plugins, rather than picking up + // copies that might be already installed globally on the system. + if !strings.Contains(stdout, "- Downloading plugin for provider \"template\"") { + t.Errorf("template provider download message is missing from init output:\n%s", stdout) + t.Logf("(this can happen if you have a copy of the plugin in one of the global plugin search dirs)") + } + if !strings.Contains(stdout, "- Downloading plugin for provider \"null\"") { + t.Errorf("null provider download message is missing from init output:\n%s", stdout) + t.Logf("(this can happen if you have a copy of the plugin in one of the global plugin search dirs)") + } + + //// PLAN + stdout, stderr, err = tf.Run("plan", "-out=tfplan") + if err != nil { + t.Fatalf("unexpected plan error: %s\nstderr:\n%s", err, stderr) + } + + if !strings.Contains(stdout, "1 to add, 0 to change, 0 to destroy") { + t.Errorf("incorrect plan tally; want 1 to add:\n%s", stdout) + } + + plan, err := tf.Plan("tfplan") + if err != nil { + t.Fatalf("failed to read plan file: %s", err) + } + + stateResources := plan.State.RootModule().Resources + diffResources := plan.Diff.RootModule().Resources + + if len(stateResources) != 1 || stateResources["data.template_file.test"] == nil { + t.Errorf("incorrect state in plan; want just data.template_file.test to have been rendered, but have:\n%s", spew.Sdump(stateResources)) + } + if len(diffResources) != 1 || diffResources["null_resource.test"] == nil { + t.Errorf("incorrect diff in plan; want just null_resource.test to have been rendered, but have:\n%s", spew.Sdump(diffResources)) + } + + //// APPLY + stdout, stderr, err = tf.Run("apply", "tfplan") + if err != nil { + t.Fatalf("unexpected apply error: %s\nstderr:\n%s", err, stderr) + } + + if !strings.Contains(stdout, "Resources: 1 added, 0 changed, 0 destroyed") { + t.Errorf("incorrect apply tally; want 1 added:\n%s", stdout) + } + + state, err := tf.LocalState() + if err != nil { + t.Fatalf("failed to read state file: %s", err) + } + + stateResources = state.RootModule().Resources + var gotResources []string + for n := range stateResources { + gotResources = append(gotResources, n) + } + sort.Strings(gotResources) + + wantResources := []string{ + "data.template_file.test", + "null_resource.test", + } + + if !reflect.DeepEqual(gotResources, wantResources) { + t.Errorf("wrong resources in state\ngot: %#v\nwant: %#v", gotResources, wantResources) + } + + //// DESTROY + stdout, stderr, err = tf.Run("destroy", "-force") + if err != nil { + t.Fatalf("unexpected destroy error: %s\nstderr:\n%s", err, stderr) + } + + if !strings.Contains(stdout, "Resources: 2 destroyed") { + t.Errorf("incorrect destroy tally; want 2 destroyed:\n%s", stdout) + } + + state, err = tf.LocalState() + if err != nil { + t.Fatalf("failed to read state file after destroy: %s", err) + } + + stateResources = state.RootModule().Resources + if len(stateResources) != 0 { + t.Errorf("wrong resources in state after destroy; want none, but still have:%s", spew.Sdump(stateResources)) + } + +} diff --git a/command/e2etest/test-fixtures/full-workflow-null/main.tf b/command/e2etest/test-fixtures/full-workflow-null/main.tf new file mode 100644 index 0000000000..1c3fc36e10 --- /dev/null +++ b/command/e2etest/test-fixtures/full-workflow-null/main.tf @@ -0,0 +1,22 @@ + +variable "name" { + default = "world" +} + +data "template_file" "test" { + template = "Hello, $${name}" + + vars = { + name = "${var.name}" + } +} + +resource "null_resource" "test" { + triggers = { + greeting = "${data.template_file.test.rendered}" + } +} + +output "greeting" { + value = "${null_resource.test.triggers["greeting"]}" +}