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 (
"context"
"io/ioutil"
"os"
"testing"
expect "github.com/Netflix/go-expect"
tfe "github.com/hashicorp/go-tfe"
"github.com/hashicorp/terraform/internal/e2e"
tfversion "github.com/hashicorp/terraform/version"
)
@ -19,10 +15,7 @@ func Test_terraform_apply_autoApprove(t *testing.T) {
ctx := context.Background()
cases := map[string]struct {
operations []operationSets
validations func(t *testing.T, orgName string)
}{
cases := testCases{
"workspace manual apply, terraform apply without auto-approve, expect prompt": {
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")
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)
}
})
}
testRunner(t, cases, 1)
}

View File

@ -1,12 +1,7 @@
package main
import (
"io/ioutil"
"os"
"testing"
expect "github.com/Netflix/go-expect"
"github.com/hashicorp/terraform/internal/e2e"
)
func Test_backend_apply_before_init(t *testing.T) {
@ -14,9 +9,7 @@ func Test_backend_apply_before_init(t *testing.T) {
skipIfMissingEnvVar(t)
skipWithoutRemoteTerraformVersion(t)
cases := map[string]struct {
operations []operationSets
}{
cases := testCases{
"terraform apply with cloud block - blank state": {
operations: []operationSets{
{
@ -71,72 +64,5 @@ func Test_backend_apply_before_init(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")
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)
}
}
}
})
}
testRunner(t, cases, 1)
}

View File

@ -15,7 +15,9 @@ import (
)
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 {

View File

@ -1,12 +1,7 @@
package main
import (
"io/ioutil"
"os"
"testing"
expect "github.com/Netflix/go-expect"
"github.com/hashicorp/terraform/internal/e2e"
)
func Test_init_with_empty_tags(t *testing.T) {
@ -14,9 +9,7 @@ func Test_init_with_empty_tags(t *testing.T) {
skipIfMissingEnvVar(t)
skipWithoutRemoteTerraformVersion(t)
cases := map[string]struct {
operations []operationSets
}{
cases := testCases{
"terraform init with cloud block - no tagged workspaces exist yet": {
operations: []operationSets{
{
@ -38,71 +31,5 @@ func Test_init_with_empty_tags(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")
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)
}
}
}
})
}
testRunner(t, cases, 1)
}

View File

@ -10,7 +10,9 @@ import (
"strings"
"testing"
expect "github.com/Netflix/go-expect"
tfe "github.com/hashicorp/go-tfe"
"github.com/hashicorp/terraform/internal/e2e"
tfversion "github.com/hashicorp/terraform/version"
)
@ -66,6 +68,96 @@ func setup() func() {
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() {
tfeHostname = os.Getenv("TFE_HOSTNAME")

View File

@ -2,13 +2,9 @@ package main
import (
"context"
"io/ioutil"
"os"
"testing"
expect "github.com/Netflix/go-expect"
tfe "github.com/hashicorp/go-tfe"
"github.com/hashicorp/terraform/internal/e2e"
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()
cases := map[string]struct {
operations []operationSets
validations func(t *testing.T, orgName string)
}{
cases := testCases{
"migrating multiple workspaces to cloud using name strategy; current workspace is 'default'": {
operations: []operationSets{
{
@ -225,78 +218,7 @@ func Test_migrate_multi_to_tfc_cloud_name_strategy(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")
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)
}
})
}
testRunner(t, cases, 1)
}
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 {
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)
}
})
}
testRunner(t, cases, 1)
}

File diff suppressed because it is too large Load Diff

View File

@ -2,13 +2,9 @@ package main
import (
"context"
"io/ioutil"
"os"
"testing"
expect "github.com/Netflix/go-expect"
tfe "github.com/hashicorp/go-tfe"
"github.com/hashicorp/terraform/internal/e2e"
)
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()
cases := map[string]struct {
operations []operationSets
validations func(t *testing.T, orgName string)
}{
cases := testCases{
"migrate using cloud workspace name strategy": {
operations: []operationSets{
{
@ -129,76 +122,5 @@ func Test_migrate_single_to_tfc(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")
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)
}
})
}
testRunner(t, cases, 1)
}

View File

@ -1,21 +1,14 @@
package main
import (
"io/ioutil"
"os"
"testing"
expect "github.com/Netflix/go-expect"
"github.com/hashicorp/terraform/internal/e2e"
)
func Test_migrate_tfc_to_other(t *testing.T) {
t.Parallel()
skipIfMissingEnvVar(t)
cases := map[string]struct {
operations []operationSets
}{
cases := testCases{
"migrate from cloud to local backend": {
operations: []operationSets{
{
@ -48,71 +41,5 @@ func Test_migrate_tfc_to_other(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")
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)
}
}
}
})
}
testRunner(t, cases, 1)
}

View File

@ -2,13 +2,9 @@ package main
import (
"context"
"io/ioutil"
"os"
"testing"
expect "github.com/Netflix/go-expect"
tfe "github.com/hashicorp/go-tfe"
"github.com/hashicorp/terraform/internal/e2e"
tfversion "github.com/hashicorp/terraform/version"
)
@ -19,16 +15,8 @@ func Test_migrate_tfc_to_tfc_single_workspace(t *testing.T) {
ctx := context.Background()
cases := map[string]struct {
setup func(t *testing.T) (string, func())
operations []operationSets
validations func(t *testing.T, orgName string)
}{
cases := testCases{
"migrating from name to name": {
setup: func(t *testing.T) (string, func()) {
organization, cleanup := createOrganization(t)
return organization.Name, cleanup
},
operations: []operationSets{
{
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": {
setup: func(t *testing.T) (string, func()) {
organization, cleanup := createOrganization(t)
return organization.Name, cleanup
},
operations: []operationSets{
{
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": {
setup: func(t *testing.T) (string, func()) {
organization, cleanup := createOrganization(t)
return organization.Name, cleanup
},
operations: []operationSets{
{
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 {
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)
}
})
}
testRunner(t, cases, 1)
}
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()
cases := map[string]struct {
setup func(t *testing.T) (string, func())
operations []operationSets
validations func(t *testing.T, orgName string)
}{
cases := testCases{
"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{
{
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": {
setup: func(t *testing.T) (string, func()) {
organization, cleanup := createOrganization(t)
return organization.Name, cleanup
},
operations: []operationSets{
{
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 {
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)
}
})
}
testRunner(t, cases, 1)
}

View File

@ -2,13 +2,9 @@ package main
import (
"fmt"
"io/ioutil"
"os"
"testing"
expect "github.com/Netflix/go-expect"
tfe "github.com/hashicorp/go-tfe"
"github.com/hashicorp/terraform/internal/e2e"
tfversion "github.com/hashicorp/terraform/version"
)
@ -81,78 +77,5 @@ func Test_cloud_run_variables(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")
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)
}
}
})
}
testRunner(t, cases, 1, "TF_CLI_ARGS=-no-color", "TF_VAR_baz=qux")
}