diff --git a/internal/cloud/e2e/apply_auto_approve_test.go b/internal/cloud/e2e/apply_auto_approve_test.go index 8ece4836dd..4e5a65a022 100644 --- a/internal/cloud/e2e/apply_auto_approve_test.go +++ b/internal/cloud/e2e/apply_auto_approve_test.go @@ -5,10 +5,8 @@ package main import ( "context" - "fmt" "io/ioutil" "log" - "os" "strings" "testing" @@ -238,15 +236,3 @@ func Test_terraform_apply_autoApprove(t *testing.T) { tc.validations(t, orgName, wsName) } } - -func writeMainTF(t *testing.T, block string, dir string) { - f, err := os.Create(fmt.Sprintf("%s/main.tf", dir)) - if err != nil { - t.Fatal(err) - } - _, err = f.WriteString(block) - if err != nil { - t.Fatal(err) - } - f.Close() -} diff --git a/internal/cloud/e2e/helper_test.go b/internal/cloud/e2e/helper_test.go index cad01a5c1a..5af66bf1c6 100644 --- a/internal/cloud/e2e/helper_test.go +++ b/internal/cloud/e2e/helper_test.go @@ -6,6 +6,7 @@ package main import ( "context" "fmt" + "os" "testing" "time" @@ -31,6 +32,11 @@ type operationSets struct { prep func(t *testing.T, orgName, dir string) } +type testCases map[string]struct { + operations []operationSets + validations func(t *testing.T, orgName string) +} + func createOrganization(t *testing.T) (*tfe.Organization, func()) { ctx := context.Background() org, err := tfeClient.Organizations.Create(ctx, tfe.OrganizationCreateOptions{ @@ -126,3 +132,15 @@ resource "random_pet" "server" { } `, tfeHostname, org, name) } + +func writeMainTF(t *testing.T, block string, dir string) { + f, err := os.Create(fmt.Sprintf("%s/main.tf", dir)) + if err != nil { + t.Fatal(err) + } + _, err = f.WriteString(block) + if err != nil { + t.Fatal(err) + } + f.Close() +} diff --git a/internal/cloud/e2e/run_variables_test.go b/internal/cloud/e2e/run_variables_test.go new file mode 100644 index 0000000000..ba20077a14 --- /dev/null +++ b/internal/cloud/e2e/run_variables_test.go @@ -0,0 +1,144 @@ +//go:build e2e +// +build e2e + +package main + +import ( + "fmt" + "io/ioutil" + "os" + "testing" + + expect "github.com/Netflix/go-expect" + "github.com/hashicorp/terraform/internal/e2e" +) + +func terraformConfigRequiredVariable(org, name string) string { + return fmt.Sprintf(` +terraform { + cloud { + hostname = "%s" + organization = "%s" + + workspaces { + name = "%s" + } + } +} + +variable "foo" { + type = string +} + +variable "baz" { + type = string +} + +output "test_cli" { + value = var.foo +} + +output "test_env" { + value = var.baz +} + +`, tfeHostname, org, name) +} + +func Test_cloud_run_variables(t *testing.T) { + cases := testCases{ + "run variables from CLI arg": { + operations: []operationSets{ + { + prep: func(t *testing.T, orgName, dir string) { + wsName := "new-workspace" + tfBlock := terraformConfigRequiredVariable(orgName, wsName) + writeMainTF(t, tfBlock, dir) + }, + commands: []tfCommand{ + { + command: []string{"init"}, + expectedOutput: `Successfully configured the backend "cloud"!`, + }, + { + command: []string{"plan", "-var", "foo=bar"}, + expectedOutput: ` + test_cli = "bar"`, + }, + { + command: []string{"plan", "-var", "foo=bar"}, + expectedOutput: ` + test_env = "qux"`, + }, + }, + }, + }, + }, + } + + for name, tc := range cases { + fmt.Println("Test: ", name) + organization, cleanup := createOrganization(t) + defer cleanup() + exp, err := expect.NewConsole(expect.WithStdout(os.Stdout), expect.WithDefaultTimeout(expectConsoleTimeout)) + if err != nil { + t.Fatal(err) + } + defer exp.Close() + + tmpDir, err := ioutil.TempDir("", "terraform-test") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(tmpDir) + + tf := e2e.NewBinary(terraformBin, tmpDir) + tf.AddEnv("TF_LOG=info") + tf.AddEnv("TF_CLI_ARGS=-no-color") + tf.AddEnv("TF_VAR_baz=qux") + tf.AddEnv(cliConfigFileEnv) + defer tf.Close() + + for _, op := range tc.operations { + op.prep(t, organization.Name, tf.WorkDir()) + for _, tfCmd := range op.commands { + cmd := tf.Cmd(tfCmd.command...) + cmd.Stdin = exp.Tty() + cmd.Stdout = exp.Tty() + cmd.Stderr = exp.Tty() + + err = cmd.Start() + if err != nil { + t.Fatal(err) + } + + if tfCmd.expectedOutput != "" { + _, err := exp.ExpectString(tfCmd.expectedOutput) + if err != nil { + t.Fatal(err) + } + } + + if len(tfCmd.userInput) > 0 { + for _, input := range tfCmd.userInput { + exp.SendLine(input) + } + } + + if tfCmd.postInputOutput != "" { + _, err := exp.ExpectString(tfCmd.postInputOutput) + if err != nil { + t.Fatal(err) + } + } + + err = cmd.Wait() + if err != nil && !tfCmd.expectError { + t.Fatal(err) + } + } + + if tc.validations != nil { + tc.validations(t, organization.Name) + } + } + } +}