Refactor cloud table test runs

As the cloud e2e tests evolved some common patters became apparent. This
standardizes and consolidates the patterns into a common test runner
that takes the table tests and runs them in parallel. Some tests also
needed to be converted to utilize table tests.
This commit is contained in:
Barrett Clark 2021-12-16 14:23:42 -06:00
parent c647b41d65
commit d196d2870a
11 changed files with 594 additions and 1847 deletions

View File

@ -2,13 +2,9 @@ package main
import ( import (
"context" "context"
"io/ioutil"
"os"
"testing" "testing"
expect "github.com/Netflix/go-expect"
tfe "github.com/hashicorp/go-tfe" tfe "github.com/hashicorp/go-tfe"
"github.com/hashicorp/terraform/internal/e2e"
tfversion "github.com/hashicorp/terraform/version" tfversion "github.com/hashicorp/terraform/version"
) )
@ -19,10 +15,7 @@ func Test_terraform_apply_autoApprove(t *testing.T) {
ctx := context.Background() ctx := context.Background()
cases := map[string]struct { cases := testCases{
operations []operationSets
validations func(t *testing.T, orgName string)
}{
"workspace manual apply, terraform apply without auto-approve, expect prompt": { "workspace manual apply, terraform apply without auto-approve, expect prompt": {
operations: []operationSets{ operations: []operationSets{
{ {
@ -180,76 +173,6 @@ func Test_terraform_apply_autoApprove(t *testing.T) {
}, },
}, },
} }
for name, tc := range cases {
tc := tc // rebind tc into this lexical scope
t.Run(name, func(subtest *testing.T) {
subtest.Parallel()
organization, cleanup := createOrganization(t)
defer cleanup()
exp, err := expect.NewConsole(defaultOpts()...)
if err != nil {
subtest.Fatal(err)
}
defer exp.Close()
tmpDir, err := ioutil.TempDir("", "terraform-test") testRunner(t, cases, 1)
if err != nil {
subtest.Fatal(err)
}
defer os.RemoveAll(tmpDir)
tf := e2e.NewBinary(terraformBin, tmpDir)
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 {
subtest.Fatal(err)
}
if tfCmd.expectedCmdOutput != "" {
got, err := exp.ExpectString(tfCmd.expectedCmdOutput)
if err != nil {
subtest.Fatalf("error while waiting for output\nwant: %s\nerror: %s\noutput\n%s", tfCmd.expectedCmdOutput, err, got)
}
}
lenInput := len(tfCmd.userInput)
lenInputOutput := len(tfCmd.postInputOutput)
if lenInput > 0 {
for i := 0; i < lenInput; i++ {
input := tfCmd.userInput[i]
exp.SendLine(input)
// use the index to find the corresponding
// output that matches the input.
if lenInputOutput-1 >= i {
output := tfCmd.postInputOutput[i]
_, err := exp.ExpectString(output)
if err != nil {
subtest.Fatal(err)
}
}
}
}
err = cmd.Wait()
if err != nil && !tfCmd.expectError {
subtest.Fatal(err)
}
}
}
if tc.validations != nil {
tc.validations(t, organization.Name)
}
})
}
} }

View File

@ -1,12 +1,7 @@
package main package main
import ( import (
"io/ioutil"
"os"
"testing" "testing"
expect "github.com/Netflix/go-expect"
"github.com/hashicorp/terraform/internal/e2e"
) )
func Test_backend_apply_before_init(t *testing.T) { func Test_backend_apply_before_init(t *testing.T) {
@ -14,9 +9,7 @@ func Test_backend_apply_before_init(t *testing.T) {
skipIfMissingEnvVar(t) skipIfMissingEnvVar(t)
skipWithoutRemoteTerraformVersion(t) skipWithoutRemoteTerraformVersion(t)
cases := map[string]struct { cases := testCases{
operations []operationSets
}{
"terraform apply with cloud block - blank state": { "terraform apply with cloud block - blank state": {
operations: []operationSets{ operations: []operationSets{
{ {
@ -71,72 +64,5 @@ func Test_backend_apply_before_init(t *testing.T) {
}, },
} }
for name, tc := range cases { testRunner(t, cases, 1)
tc := tc // rebind tc into this lexical scope
t.Run(name, func(subtest *testing.T) {
subtest.Parallel()
organization, cleanup := createOrganization(t)
defer cleanup()
exp, err := expect.NewConsole(defaultOpts()...)
if err != nil {
subtest.Fatal(err)
}
defer exp.Close()
tmpDir, err := ioutil.TempDir("", "terraform-test")
if err != nil {
subtest.Fatal(err)
}
defer os.RemoveAll(tmpDir)
tf := e2e.NewBinary(terraformBin, tmpDir)
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 {
subtest.Fatal(err)
}
if tfCmd.expectedCmdOutput != "" {
got, err := exp.ExpectString(tfCmd.expectedCmdOutput)
if err != nil {
subtest.Fatalf("error while waiting for output\nwant: %s\nerror: %s\noutput\n%s", tfCmd.expectedCmdOutput, err, got)
}
}
lenInput := len(tfCmd.userInput)
lenInputOutput := len(tfCmd.postInputOutput)
if lenInput > 0 {
for i := 0; i < lenInput; i++ {
input := tfCmd.userInput[i]
exp.SendLine(input)
// use the index to find the corresponding
// output that matches the input.
if lenInputOutput-1 >= i {
output := tfCmd.postInputOutput[i]
_, err := exp.ExpectString(output)
if err != nil {
subtest.Fatal(err)
}
}
}
}
err = cmd.Wait()
if err != nil && !tfCmd.expectError {
subtest.Fatal(err)
}
}
}
})
}
} }

View File

@ -15,7 +15,9 @@ import (
) )
const ( const (
expectConsoleTimeout = 60 * time.Second * 3 // We need to give the console enough time to hear back.
// 1 minute was too short in some cases, so this gives it ample time.
expectConsoleTimeout = 3 * time.Minute
) )
type tfCommand struct { type tfCommand struct {

View File

@ -1,12 +1,7 @@
package main package main
import ( import (
"io/ioutil"
"os"
"testing" "testing"
expect "github.com/Netflix/go-expect"
"github.com/hashicorp/terraform/internal/e2e"
) )
func Test_init_with_empty_tags(t *testing.T) { func Test_init_with_empty_tags(t *testing.T) {
@ -14,9 +9,7 @@ func Test_init_with_empty_tags(t *testing.T) {
skipIfMissingEnvVar(t) skipIfMissingEnvVar(t)
skipWithoutRemoteTerraformVersion(t) skipWithoutRemoteTerraformVersion(t)
cases := map[string]struct { cases := testCases{
operations []operationSets
}{
"terraform init with cloud block - no tagged workspaces exist yet": { "terraform init with cloud block - no tagged workspaces exist yet": {
operations: []operationSets{ operations: []operationSets{
{ {
@ -38,71 +31,5 @@ func Test_init_with_empty_tags(t *testing.T) {
}, },
} }
for name, tc := range cases { testRunner(t, cases, 1)
tc := tc // rebind tc into this lexical scope
t.Run(name, func(subtest *testing.T) {
subtest.Parallel()
organization, cleanup := createOrganization(t)
defer cleanup()
exp, err := expect.NewConsole(defaultOpts()...)
if err != nil {
subtest.Fatal(err)
}
defer exp.Close()
tmpDir, err := ioutil.TempDir("", "terraform-test")
if err != nil {
subtest.Fatal(err)
}
defer os.RemoveAll(tmpDir)
tf := e2e.NewBinary(terraformBin, tmpDir)
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 {
subtest.Fatal(err)
}
if tfCmd.expectedCmdOutput != "" {
got, err := exp.ExpectString(tfCmd.expectedCmdOutput)
if err != nil {
subtest.Fatalf("error while waiting for output\nwant: %s\nerror: %s\noutput\n%s", tfCmd.expectedCmdOutput, err, got)
}
}
lenInput := len(tfCmd.userInput)
lenInputOutput := len(tfCmd.postInputOutput)
if lenInput > 0 {
for i := 0; i < lenInput; i++ {
input := tfCmd.userInput[i]
exp.SendLine(input)
// use the index to find the corresponding
// output that matches the input.
if lenInputOutput-1 >= i {
output := tfCmd.postInputOutput[i]
_, err := exp.ExpectString(output)
if err != nil {
subtest.Fatal(err)
}
}
}
}
err = cmd.Wait()
if err != nil && !tfCmd.expectError {
subtest.Fatal(err)
}
}
}
})
}
} }

View File

@ -10,7 +10,9 @@ import (
"strings" "strings"
"testing" "testing"
expect "github.com/Netflix/go-expect"
tfe "github.com/hashicorp/go-tfe" tfe "github.com/hashicorp/go-tfe"
"github.com/hashicorp/terraform/internal/e2e"
tfversion "github.com/hashicorp/terraform/version" tfversion "github.com/hashicorp/terraform/version"
) )
@ -66,6 +68,96 @@ func setup() func() {
teardown() teardown()
} }
} }
func testRunner(t *testing.T, cases testCases, orgCount int, tfEnvFlags ...string) {
for name, tc := range cases {
tc := tc // rebind tc into this lexical scope
t.Run(name, func(subtest *testing.T) {
subtest.Parallel()
orgNames := []string{}
for i := 0; i < orgCount; i++ {
organization, cleanup := createOrganization(t)
t.Cleanup(cleanup)
orgNames = append(orgNames, organization.Name)
}
exp, err := expect.NewConsole(defaultOpts()...)
if err != nil {
subtest.Fatal(err)
}
defer exp.Close()
tmpDir, err := ioutil.TempDir("", "terraform-test")
if err != nil {
subtest.Fatal(err)
}
defer os.RemoveAll(tmpDir)
tf := e2e.NewBinary(terraformBin, tmpDir)
tfEnvFlags = append(tfEnvFlags, "TF_LOG=INFO")
tfEnvFlags = append(tfEnvFlags, cliConfigFileEnv)
for _, env := range tfEnvFlags {
tf.AddEnv(env)
}
defer tf.Close()
var orgName string
for index, op := range tc.operations {
if orgCount == 1 {
orgName = orgNames[0]
} else {
orgName = orgNames[index]
}
op.prep(t, orgName, 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 {
subtest.Fatal(err)
}
if tfCmd.expectedCmdOutput != "" {
got, err := exp.ExpectString(tfCmd.expectedCmdOutput)
if err != nil {
subtest.Fatalf("error while waiting for output\nwant: %s\nerror: %s\noutput\n%s", tfCmd.expectedCmdOutput, err, got)
}
}
lenInput := len(tfCmd.userInput)
lenInputOutput := len(tfCmd.postInputOutput)
if lenInput > 0 {
for i := 0; i < lenInput; i++ {
input := tfCmd.userInput[i]
exp.SendLine(input)
// use the index to find the corresponding
// output that matches the input.
if lenInputOutput-1 >= i {
output := tfCmd.postInputOutput[i]
_, err := exp.ExpectString(output)
if err != nil {
subtest.Fatal(err)
}
}
}
}
err = cmd.Wait()
if err != nil && !tfCmd.expectError {
subtest.Fatal(err)
}
}
}
if tc.validations != nil {
tc.validations(t, orgName)
}
})
}
}
func setTfeClient() { func setTfeClient() {
tfeHostname = os.Getenv("TFE_HOSTNAME") tfeHostname = os.Getenv("TFE_HOSTNAME")

View File

@ -2,13 +2,9 @@ package main
import ( import (
"context" "context"
"io/ioutil"
"os"
"testing" "testing"
expect "github.com/Netflix/go-expect"
tfe "github.com/hashicorp/go-tfe" tfe "github.com/hashicorp/go-tfe"
"github.com/hashicorp/terraform/internal/e2e"
tfversion "github.com/hashicorp/terraform/version" tfversion "github.com/hashicorp/terraform/version"
) )
@ -19,10 +15,7 @@ func Test_migrate_multi_to_tfc_cloud_name_strategy(t *testing.T) {
ctx := context.Background() ctx := context.Background()
cases := map[string]struct { cases := testCases{
operations []operationSets
validations func(t *testing.T, orgName string)
}{
"migrating multiple workspaces to cloud using name strategy; current workspace is 'default'": { "migrating multiple workspaces to cloud using name strategy; current workspace is 'default'": {
operations: []operationSets{ operations: []operationSets{
{ {
@ -225,78 +218,7 @@ func Test_migrate_multi_to_tfc_cloud_name_strategy(t *testing.T) {
}, },
} }
for name, tc := range cases { testRunner(t, cases, 1)
tc := tc // rebind tc into this lexical scope
t.Run(name, func(subtest *testing.T) {
subtest.Parallel()
organization, cleanup := createOrganization(t)
defer cleanup()
exp, err := expect.NewConsole(defaultOpts()...)
if err != nil {
subtest.Fatal(err)
}
defer exp.Close()
tmpDir, err := ioutil.TempDir("", "terraform-test")
if err != nil {
subtest.Fatal(err)
}
defer os.RemoveAll(tmpDir)
tf := e2e.NewBinary(terraformBin, tmpDir)
defer tf.Close()
tf.AddEnv(cliConfigFileEnv)
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 {
subtest.Fatal(err)
}
if tfCmd.expectedCmdOutput != "" {
got, err := exp.ExpectString(tfCmd.expectedCmdOutput)
if err != nil {
subtest.Fatalf("error while waiting for output\nwant: %s\nerror: %s\noutput\n%s", tfCmd.expectedCmdOutput, err, got)
}
}
lenInput := len(tfCmd.userInput)
lenInputOutput := len(tfCmd.postInputOutput)
if lenInput > 0 {
for i := 0; i < lenInput; i++ {
input := tfCmd.userInput[i]
exp.SendLine(input)
// use the index to find the corresponding
// output that matches the input.
if lenInputOutput-1 >= i {
output := tfCmd.postInputOutput[i]
_, err := exp.ExpectString(output)
if err != nil {
subtest.Fatal(err)
}
}
}
}
err = cmd.Wait()
if err != nil && !tfCmd.expectError {
subtest.Fatal(err)
}
}
}
if tc.validations != nil {
tc.validations(t, organization.Name)
}
})
}
} }
func Test_migrate_multi_to_tfc_cloud_tags_strategy(t *testing.T) { func Test_migrate_multi_to_tfc_cloud_tags_strategy(t *testing.T) {
@ -514,79 +436,5 @@ func Test_migrate_multi_to_tfc_cloud_tags_strategy(t *testing.T) {
}, },
} }
for name, tc := range cases { testRunner(t, cases, 1)
tc := tc // rebind tc into this lexical scope
t.Run(name, func(subtest *testing.T) {
subtest.Parallel()
organization, cleanup := createOrganization(t)
defer cleanup()
exp, err := expect.NewConsole(defaultOpts()...)
if err != nil {
subtest.Fatal(err)
}
defer exp.Close()
tmpDir, err := ioutil.TempDir("", "terraform-test")
if err != nil {
subtest.Fatal(err)
}
defer os.RemoveAll(tmpDir)
tf := e2e.NewBinary(terraformBin, tmpDir)
defer tf.Close()
tf.AddEnv(cliConfigFileEnv)
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 {
subtest.Fatal(err)
}
if tfCmd.expectedCmdOutput != "" {
got, err := exp.ExpectString(tfCmd.expectedCmdOutput)
if err != nil {
subtest.Fatalf("error while waiting for output\nwant: %s\nerror: %s\noutput\n%s", tfCmd.expectedCmdOutput, err, got)
}
}
lenInput := len(tfCmd.userInput)
lenInputOutput := len(tfCmd.postInputOutput)
if lenInput > 0 {
for i := 0; i < lenInput; i++ {
input := tfCmd.userInput[i]
exp.SendLine(input)
// use the index to find the corresponding
// output that matches the input.
if lenInputOutput-1 >= i {
output := tfCmd.postInputOutput[i]
if output == "" {
continue
}
_, err := exp.ExpectString(output)
if err != nil {
subtest.Fatal(err)
}
}
}
}
err = cmd.Wait()
if err != nil {
subtest.Fatal(err)
}
}
}
if tc.validations != nil {
tc.validations(t, organization.Name)
}
})
}
} }

File diff suppressed because it is too large Load Diff

View File

@ -2,13 +2,9 @@ package main
import ( import (
"context" "context"
"io/ioutil"
"os"
"testing" "testing"
expect "github.com/Netflix/go-expect"
tfe "github.com/hashicorp/go-tfe" tfe "github.com/hashicorp/go-tfe"
"github.com/hashicorp/terraform/internal/e2e"
) )
func Test_migrate_single_to_tfc(t *testing.T) { func Test_migrate_single_to_tfc(t *testing.T) {
@ -18,10 +14,7 @@ func Test_migrate_single_to_tfc(t *testing.T) {
ctx := context.Background() ctx := context.Background()
cases := map[string]struct { cases := testCases{
operations []operationSets
validations func(t *testing.T, orgName string)
}{
"migrate using cloud workspace name strategy": { "migrate using cloud workspace name strategy": {
operations: []operationSets{ operations: []operationSets{
{ {
@ -129,76 +122,5 @@ func Test_migrate_single_to_tfc(t *testing.T) {
}, },
} }
for name, tc := range cases { testRunner(t, cases, 1)
tc := tc // rebind tc into this lexical scope
t.Run(name, func(subtest *testing.T) {
subtest.Parallel()
organization, cleanup := createOrganization(t)
defer cleanup()
exp, err := expect.NewConsole(defaultOpts()...)
if err != nil {
subtest.Fatal(err)
}
defer exp.Close()
tmpDir, err := ioutil.TempDir("", "terraform-test")
if err != nil {
subtest.Fatal(err)
}
defer os.RemoveAll(tmpDir)
tf := e2e.NewBinary(terraformBin, tmpDir)
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 {
subtest.Fatal(err)
}
if tfCmd.expectedCmdOutput != "" {
got, err := exp.ExpectString(tfCmd.expectedCmdOutput)
if err != nil {
subtest.Fatalf("error while waiting for output\nwant: %s\nerror: %s\noutput\n%s", tfCmd.expectedCmdOutput, err, got)
}
}
lenInput := len(tfCmd.userInput)
lenInputOutput := len(tfCmd.postInputOutput)
if lenInput > 0 {
for i := 0; i < lenInput; i++ {
input := tfCmd.userInput[i]
exp.SendLine(input)
// use the index to find the corresponding
// output that matches the input.
if lenInputOutput-1 >= i {
output := tfCmd.postInputOutput[i]
_, err := exp.ExpectString(output)
if err != nil {
subtest.Fatal(err)
}
}
}
}
err = cmd.Wait()
if err != nil {
subtest.Fatal(err)
}
}
}
if tc.validations != nil {
tc.validations(t, organization.Name)
}
})
}
} }

View File

@ -1,21 +1,14 @@
package main package main
import ( import (
"io/ioutil"
"os"
"testing" "testing"
expect "github.com/Netflix/go-expect"
"github.com/hashicorp/terraform/internal/e2e"
) )
func Test_migrate_tfc_to_other(t *testing.T) { func Test_migrate_tfc_to_other(t *testing.T) {
t.Parallel() t.Parallel()
skipIfMissingEnvVar(t) skipIfMissingEnvVar(t)
cases := map[string]struct { cases := testCases{
operations []operationSets
}{
"migrate from cloud to local backend": { "migrate from cloud to local backend": {
operations: []operationSets{ operations: []operationSets{
{ {
@ -48,71 +41,5 @@ func Test_migrate_tfc_to_other(t *testing.T) {
}, },
} }
for name, tc := range cases { testRunner(t, cases, 1)
tc := tc // rebind tc into this lexical scope
t.Run(name, func(subtest *testing.T) {
subtest.Parallel()
organization, cleanup := createOrganization(t)
defer cleanup()
exp, err := expect.NewConsole(defaultOpts()...)
if err != nil {
subtest.Fatal(err)
}
defer exp.Close()
tmpDir, err := ioutil.TempDir("", "terraform-test")
if err != nil {
subtest.Fatal(err)
}
defer os.RemoveAll(tmpDir)
tf := e2e.NewBinary(terraformBin, tmpDir)
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 {
subtest.Fatal(err)
}
if tfCmd.expectedCmdOutput != "" {
got, err := exp.ExpectString(tfCmd.expectedCmdOutput)
if err != nil {
subtest.Fatalf("error while waiting for output\nwant: %s\nerror: %s\noutput\n%s", tfCmd.expectedCmdOutput, err, got)
}
}
lenInput := len(tfCmd.userInput)
lenInputOutput := len(tfCmd.postInputOutput)
if lenInput > 0 {
for i := 0; i < lenInput; i++ {
input := tfCmd.userInput[i]
exp.SendLine(input)
// use the index to find the corresponding
// output that matches the input.
if lenInputOutput-1 >= i {
output := tfCmd.postInputOutput[i]
_, err := exp.ExpectString(output)
if err != nil {
subtest.Fatal(err)
}
}
}
}
err = cmd.Wait()
if err != nil && !tfCmd.expectError {
subtest.Fatal(err)
}
}
}
})
}
} }

View File

@ -2,13 +2,9 @@ package main
import ( import (
"context" "context"
"io/ioutil"
"os"
"testing" "testing"
expect "github.com/Netflix/go-expect"
tfe "github.com/hashicorp/go-tfe" tfe "github.com/hashicorp/go-tfe"
"github.com/hashicorp/terraform/internal/e2e"
tfversion "github.com/hashicorp/terraform/version" tfversion "github.com/hashicorp/terraform/version"
) )
@ -19,16 +15,8 @@ func Test_migrate_tfc_to_tfc_single_workspace(t *testing.T) {
ctx := context.Background() ctx := context.Background()
cases := map[string]struct { cases := testCases{
setup func(t *testing.T) (string, func())
operations []operationSets
validations func(t *testing.T, orgName string)
}{
"migrating from name to name": { "migrating from name to name": {
setup: func(t *testing.T) (string, func()) {
organization, cleanup := createOrganization(t)
return organization.Name, cleanup
},
operations: []operationSets{ operations: []operationSets{
{ {
prep: func(t *testing.T, orgName, dir string) { prep: func(t *testing.T, orgName, dir string) {
@ -93,10 +81,6 @@ func Test_migrate_tfc_to_tfc_single_workspace(t *testing.T) {
}, },
}, },
"migrating from name to tags": { "migrating from name to tags": {
setup: func(t *testing.T) (string, func()) {
organization, cleanup := createOrganization(t)
return organization.Name, cleanup
},
operations: []operationSets{ operations: []operationSets{
{ {
prep: func(t *testing.T, orgName, dir string) { prep: func(t *testing.T, orgName, dir string) {
@ -155,10 +139,6 @@ func Test_migrate_tfc_to_tfc_single_workspace(t *testing.T) {
}, },
}, },
"migrating from name to tags without ignore-version flag": { "migrating from name to tags without ignore-version flag": {
setup: func(t *testing.T) (string, func()) {
organization, cleanup := createOrganization(t)
return organization.Name, cleanup
},
operations: []operationSets{ operations: []operationSets{
{ {
prep: func(t *testing.T, orgName, dir string) { prep: func(t *testing.T, orgName, dir string) {
@ -220,78 +200,7 @@ func Test_migrate_tfc_to_tfc_single_workspace(t *testing.T) {
}, },
} }
for name, tc := range cases { testRunner(t, cases, 1)
tc := tc // rebind tc into this lexical scope
t.Run(name, func(subtest *testing.T) {
subtest.Parallel()
exp, err := expect.NewConsole(defaultOpts()...)
if err != nil {
subtest.Fatal(err)
}
defer exp.Close()
tmpDir, err := ioutil.TempDir("", "terraform-test")
if err != nil {
subtest.Fatal(err)
}
defer os.RemoveAll(tmpDir)
tf := e2e.NewBinary(terraformBin, tmpDir)
defer tf.Close()
tf.AddEnv(cliConfigFileEnv)
orgName, cleanup := tc.setup(t)
defer cleanup()
for _, op := range tc.operations {
op.prep(t, orgName, 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 {
subtest.Fatal(err)
}
if tfCmd.expectedCmdOutput != "" {
got, err := exp.ExpectString(tfCmd.expectedCmdOutput)
if err != nil {
subtest.Fatalf("error while waiting for output\nwant: %s\nerror: %s\noutput\n%s", tfCmd.expectedCmdOutput, err, got)
}
}
lenInput := len(tfCmd.userInput)
lenInputOutput := len(tfCmd.postInputOutput)
if lenInput > 0 {
for i := 0; i < lenInput; i++ {
input := tfCmd.userInput[i]
exp.SendLine(input)
// use the index to find the corresponding
// output that matches the input.
if lenInputOutput-1 >= i {
output := tfCmd.postInputOutput[i]
_, err := exp.ExpectString(output)
if err != nil {
subtest.Fatal(err)
}
}
}
}
err = cmd.Wait()
if err != nil && !tfCmd.expectError {
subtest.Fatal(err.Error())
}
}
}
if tc.validations != nil {
tc.validations(t, orgName)
}
})
}
} }
func Test_migrate_tfc_to_tfc_multiple_workspace(t *testing.T) { func Test_migrate_tfc_to_tfc_multiple_workspace(t *testing.T) {
@ -301,16 +210,8 @@ func Test_migrate_tfc_to_tfc_multiple_workspace(t *testing.T) {
ctx := context.Background() ctx := context.Background()
cases := map[string]struct { cases := testCases{
setup func(t *testing.T) (string, func())
operations []operationSets
validations func(t *testing.T, orgName string)
}{
"migrating from multiple workspaces via tags to name": { "migrating from multiple workspaces via tags to name": {
setup: func(t *testing.T) (string, func()) {
organization, cleanup := createOrganization(t)
return organization.Name, cleanup
},
operations: []operationSets{ operations: []operationSets{
{ {
prep: func(t *testing.T, orgName, dir string) { prep: func(t *testing.T, orgName, dir string) {
@ -392,10 +293,6 @@ func Test_migrate_tfc_to_tfc_multiple_workspace(t *testing.T) {
}, },
}, },
"migrating from multiple workspaces via tags to other tags": { "migrating from multiple workspaces via tags to other tags": {
setup: func(t *testing.T) (string, func()) {
organization, cleanup := createOrganization(t)
return organization.Name, cleanup
},
operations: []operationSets{ operations: []operationSets{
{ {
prep: func(t *testing.T, orgName, dir string) { prep: func(t *testing.T, orgName, dir string) {
@ -468,76 +365,5 @@ func Test_migrate_tfc_to_tfc_multiple_workspace(t *testing.T) {
}, },
} }
for name, tc := range cases { testRunner(t, cases, 1)
tc := tc // rebind tc into this lexical scope
t.Run(name, func(subtest *testing.T) {
subtest.Parallel()
exp, err := expect.NewConsole(defaultOpts()...)
if err != nil {
subtest.Fatal(err)
}
defer exp.Close()
tmpDir, err := ioutil.TempDir("", "terraform-test")
if err != nil {
subtest.Fatal(err)
}
defer os.RemoveAll(tmpDir)
tf := e2e.NewBinary(terraformBin, tmpDir)
defer tf.Close()
tf.AddEnv(cliConfigFileEnv)
orgName, cleanup := tc.setup(t)
defer cleanup()
for _, op := range tc.operations {
op.prep(t, orgName, 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 {
subtest.Fatal(err)
}
if tfCmd.expectedCmdOutput != "" {
got, err := exp.ExpectString(tfCmd.expectedCmdOutput)
if err != nil {
subtest.Fatalf("error while waiting for output\nwant: %s\nerror: %s\noutput\n%s", tfCmd.expectedCmdOutput, err, got)
}
}
lenInput := len(tfCmd.userInput)
lenInputOutput := len(tfCmd.postInputOutput)
if lenInput > 0 {
for i := 0; i < lenInput; i++ {
input := tfCmd.userInput[i]
exp.SendLine(input)
// use the index to find the corresponding
// output that matches the input.
if lenInputOutput-1 >= i {
output := tfCmd.postInputOutput[i]
_, err := exp.ExpectString(output)
if err != nil {
subtest.Fatal(err)
}
}
}
}
err = cmd.Wait()
if err != nil {
subtest.Fatal(err.Error())
}
}
}
if tc.validations != nil {
tc.validations(t, orgName)
}
})
}
} }

View File

@ -2,13 +2,9 @@ package main
import ( import (
"fmt" "fmt"
"io/ioutil"
"os"
"testing" "testing"
expect "github.com/Netflix/go-expect"
tfe "github.com/hashicorp/go-tfe" tfe "github.com/hashicorp/go-tfe"
"github.com/hashicorp/terraform/internal/e2e"
tfversion "github.com/hashicorp/terraform/version" tfversion "github.com/hashicorp/terraform/version"
) )
@ -81,78 +77,5 @@ func Test_cloud_run_variables(t *testing.T) {
}, },
} }
for name, tc := range cases { testRunner(t, cases, 1, "TF_CLI_ARGS=-no-color", "TF_VAR_baz=qux")
tc := tc // rebind tc into this lexical scope
t.Run(name, func(subtest *testing.T) {
subtest.Parallel()
organization, cleanup := createOrganization(t)
defer cleanup()
exp, err := expect.NewConsole(defaultOpts()...)
if err != nil {
subtest.Fatal(err)
}
defer exp.Close()
tmpDir, err := ioutil.TempDir("", "terraform-test")
if err != nil {
subtest.Fatal(err)
}
defer os.RemoveAll(tmpDir)
tf := e2e.NewBinary(terraformBin, tmpDir)
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 {
subtest.Fatal(err)
}
if tfCmd.expectedCmdOutput != "" {
got, err := exp.ExpectString(tfCmd.expectedCmdOutput)
if err != nil {
subtest.Fatalf("error while waiting for output\nwant: %s\nerror: %s\noutput\n%s", tfCmd.expectedCmdOutput, err, got)
}
}
lenInput := len(tfCmd.userInput)
lenInputOutput := len(tfCmd.postInputOutput)
if lenInput > 0 {
for i := 0; i < lenInput; i++ {
input := tfCmd.userInput[i]
exp.SendLine(input)
// use the index to find the corresponding
// output that matches the input.
if lenInputOutput-1 >= i {
output := tfCmd.postInputOutput[i]
_, err := exp.ExpectString(output)
if err != nil {
subtest.Fatalf(`Expected command output "%s", but got %v `, tfCmd.expectedCmdOutput, err)
}
}
}
}
err = cmd.Wait()
if err != nil && !tfCmd.expectError {
subtest.Fatal(err)
}
}
if tc.validations != nil {
tc.validations(t, organization.Name)
}
}
})
}
} }