Cloud: fix e2e tests

- Fix tests and remove commented code
- Remove parallel for some flaky tests
- Add README
This commit is contained in:
Barrett Clark 2021-11-03 15:47:14 -05:00 committed by Omar Ismail
parent e07a7c472b
commit 5ef82ddd2f
14 changed files with 1609 additions and 1451 deletions

2
go.mod
View File

@ -43,7 +43,7 @@ require (
github.com/hashicorp/go-retryablehttp v0.7.0 github.com/hashicorp/go-retryablehttp v0.7.0
github.com/hashicorp/go-tfe v0.20.1-0.20211110172530-c43c6b574caa github.com/hashicorp/go-tfe v0.20.1-0.20211110172530-c43c6b574caa
github.com/hashicorp/go-uuid v1.0.2 github.com/hashicorp/go-uuid v1.0.2
github.com/hashicorp/go-version v1.2.1 github.com/hashicorp/go-version v1.3.0
github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f
github.com/hashicorp/hcl/v2 v2.10.1 github.com/hashicorp/hcl/v2 v2.10.1
github.com/hashicorp/terraform-config-inspect v0.0.0-20210209133302-4fd17a0faac2 github.com/hashicorp/terraform-config-inspect v0.0.0-20210209133302-4fd17a0faac2

3
go.sum
View File

@ -388,8 +388,9 @@ github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b
github.com/hashicorp/go-version v1.0.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.0.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pBJ3TkI=
github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go-version v1.3.0 h1:McDWVJIU/y+u1BRV06dPaLfLCaT7fUTJLp5r04x7iNw=
github.com/hashicorp/go-version v1.3.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=

View File

@ -0,0 +1,25 @@
# How to run tests
To run them, use:
```
TF_ACC=1 go test -tags=e2e ./internal/cloud/e2e/... -ldflags "-X \"github.com/hashicorp/terraform/version.Prerelease=<PRE-RELEASE>\""
```
Required flags
* `-tags=e2e` for running e2e tests.
* `TF_ACC=1`. This variable is used as part of terraform for tests that make
external network calls. This is needed to run these tests. Without it, the
tests do not run.
* `TFE_TOKEN=<admin token>` and `TFE_HOSTNAME=<hostname>`. The helpers
for these tests require admin access to a TFC/TFE instance.
* `-timeout=30m`. Some of these tests take longer than the default 10m timeout for `go test`.
### Flags
* Use the `-v` flag for normal verbose mode.
* Use the `-tfoutput` flag to print the terraform output to standard out.
* Use `-ldflags` to change the version Prerelease to match a version
available remotely. Some behaviors rely on the exact local version Terraform
being available in TFC/TFE, and manipulating the Prerelease during build is
often the only way to ensure this.
[(More on `-ldflags`.)](https://www.digitalocean.com/community/tutorials/using-ldflags-to-set-version-information-for-go-applications)

View File

@ -6,7 +6,6 @@ package main
import ( import (
"context" "context"
"io/ioutil" "io/ioutil"
"log"
"os" "os"
"testing" "testing"
@ -17,7 +16,6 @@ import (
) )
func Test_terraform_apply_autoApprove(t *testing.T) { func Test_terraform_apply_autoApprove(t *testing.T) {
t.Parallel()
skipWithoutRemoteTerraformVersion(t) skipWithoutRemoteTerraformVersion(t)
ctx := context.Background() ctx := context.Background()
@ -184,74 +182,75 @@ func Test_terraform_apply_autoApprove(t *testing.T) {
}, },
} }
for name, tc := range cases { for name, tc := range cases {
log.Println("Test: ", name) tc := tc
t.Run(name, func(t *testing.T) {
t.Parallel()
organization, cleanup := createOrganization(t)
defer cleanup()
exp, err := expect.NewConsole(defaultOpts()...)
if err != nil {
t.Fatal(err)
}
defer exp.Close()
organization, cleanup := createOrganization(t) tmpDir, err := ioutil.TempDir("", "terraform-test")
defer cleanup() if err != nil {
exp, err := expect.NewConsole(expect.WithStdout(os.Stdout), expect.WithDefaultTimeout(expectConsoleTimeout)) t.Fatal(err)
if err != nil { }
t.Fatal(err) defer os.RemoveAll(tmpDir)
}
defer exp.Close()
tmpDir, err := ioutil.TempDir("", "terraform-test") tf := e2e.NewBinary(terraformBin, tmpDir)
if err != nil { tf.AddEnv(cliConfigFileEnv)
t.Fatal(err) defer tf.Close()
}
defer os.RemoveAll(tmpDir)
tf := e2e.NewBinary(terraformBin, tmpDir) for _, op := range tc.operations {
tf.AddEnv("TF_LOG=info") op.prep(t, organization.Name, tf.WorkDir())
tf.AddEnv(cliConfigFileEnv) for _, tfCmd := range op.commands {
defer tf.Close() cmd := tf.Cmd(tfCmd.command...)
cmd.Stdin = exp.Tty()
cmd.Stdout = exp.Tty()
cmd.Stderr = exp.Tty()
for _, op := range tc.operations { err = cmd.Start()
op.prep(t, organization.Name, tf.WorkDir()) if err != nil {
for _, tfCmd := range op.commands { t.Fatal(err)
cmd := tf.Cmd(tfCmd.command...) }
cmd.Stdin = exp.Tty()
cmd.Stdout = exp.Tty()
cmd.Stderr = exp.Tty()
err = cmd.Start() if tfCmd.expectedCmdOutput != "" {
if err != nil { _, err := exp.ExpectString(tfCmd.expectedCmdOutput)
t.Fatal(err) if err != nil {
} t.Fatal(err)
}
}
if tfCmd.expectedCmdOutput != "" { lenInput := len(tfCmd.userInput)
_, err := exp.ExpectString(tfCmd.expectedCmdOutput) 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 {
t.Fatal(err)
}
}
}
}
err = cmd.Wait()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
} }
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 {
t.Fatal(err)
}
}
}
}
err = cmd.Wait()
if err != nil {
t.Fatal(err)
}
} }
}
if tc.validations != nil { if tc.validations != nil {
tc.validations(t, organization.Name) tc.validations(t, organization.Name)
} }
})
} }
} }

View File

@ -4,7 +4,6 @@
package main package main
import ( import (
"fmt"
"io/ioutil" "io/ioutil"
"os" "os"
"testing" "testing"
@ -51,10 +50,8 @@ func Test_backend_apply_before_init(t *testing.T) {
expectedCmdOutput: `Successfully configured the backend "local"!`, expectedCmdOutput: `Successfully configured the backend "local"!`,
}, },
{ {
command: []string{"apply"}, command: []string{"apply", "-auto-approve"},
expectedCmdOutput: `Do you want to perform these actions?`, postInputOutput: []string{`Apply complete!`},
userInput: []string{"yes"},
postInputOutput: []string{`Apply complete!`},
}, },
}, },
}, },
@ -77,68 +74,70 @@ func Test_backend_apply_before_init(t *testing.T) {
} }
for name, tc := range cases { for name, tc := range cases {
fmt.Println("Test: ", name) tc := tc
organization, cleanup := createOrganization(t) t.Run(name, func(t *testing.T) {
defer cleanup() t.Parallel()
exp, err := expect.NewConsole(expect.WithStdout(os.Stdout), expect.WithDefaultTimeout(expectConsoleTimeout)) organization, cleanup := createOrganization(t)
if err != nil { defer cleanup()
t.Fatal(err) exp, err := expect.NewConsole(defaultOpts()...)
} if err != nil {
defer exp.Close() t.Fatal(err)
}
defer exp.Close()
tmpDir, err := ioutil.TempDir("", "terraform-test") tmpDir, err := ioutil.TempDir("", "terraform-test")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
tf := e2e.NewBinary(terraformBin, tmpDir) tf := e2e.NewBinary(terraformBin, tmpDir)
tf.AddEnv("TF_LOG=info") tf.AddEnv(cliConfigFileEnv)
tf.AddEnv(cliConfigFileEnv) defer tf.Close()
defer tf.Close()
for _, op := range tc.operations { for _, op := range tc.operations {
op.prep(t, organization.Name, tf.WorkDir()) op.prep(t, organization.Name, tf.WorkDir())
for _, tfCmd := range op.commands { for _, tfCmd := range op.commands {
cmd := tf.Cmd(tfCmd.command...) cmd := tf.Cmd(tfCmd.command...)
cmd.Stdin = exp.Tty() cmd.Stdin = exp.Tty()
cmd.Stdout = exp.Tty() cmd.Stdout = exp.Tty()
cmd.Stderr = exp.Tty() cmd.Stderr = exp.Tty()
err = cmd.Start() err = cmd.Start()
if err != nil {
t.Fatal(err)
}
if tfCmd.expectedCmdOutput != "" {
_, err := exp.ExpectString(tfCmd.expectedCmdOutput)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
}
lenInput := len(tfCmd.userInput) if tfCmd.expectedCmdOutput != "" {
lenInputOutput := len(tfCmd.postInputOutput) _, err := exp.ExpectString(tfCmd.expectedCmdOutput)
if lenInput > 0 { if err != nil {
for i := 0; i < lenInput; i++ { t.Fatal(err)
input := tfCmd.userInput[i] }
exp.SendLine(input) }
// use the index to find the corresponding
// output that matches the input. lenInput := len(tfCmd.userInput)
if lenInputOutput-1 >= i { lenInputOutput := len(tfCmd.postInputOutput)
output := tfCmd.postInputOutput[i] if lenInput > 0 {
_, err := exp.ExpectString(output) for i := 0; i < lenInput; i++ {
if err != nil { input := tfCmd.userInput[i]
t.Fatal(err) 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 {
t.Fatal(err)
}
} }
} }
} }
} err = cmd.Wait()
err = cmd.Wait() if err != nil && !tfCmd.expectError {
if err != nil && !tfCmd.expectError { t.Fatal(err)
t.Fatal(err) }
} }
} }
} })
} }
} }

View File

@ -10,8 +10,10 @@ import (
"testing" "testing"
"time" "time"
expect "github.com/Netflix/go-expect"
tfe "github.com/hashicorp/go-tfe" tfe "github.com/hashicorp/go-tfe"
"github.com/hashicorp/go-uuid" "github.com/hashicorp/go-uuid"
goversion "github.com/hashicorp/go-version"
tfversion "github.com/hashicorp/terraform/version" tfversion "github.com/hashicorp/terraform/version"
) )
@ -38,6 +40,16 @@ type testCases map[string]struct {
validations func(t *testing.T, orgName string) validations func(t *testing.T, orgName string)
} }
func defaultOpts() []expect.ConsoleOpt {
opts := []expect.ConsoleOpt{
expect.WithDefaultTimeout(expectConsoleTimeout),
}
if verboseMode {
opts = append(opts, expect.WithStdout(os.Stdout))
}
return opts
}
func createOrganization(t *testing.T) (*tfe.Organization, func()) { func createOrganization(t *testing.T) (*tfe.Organization, func()) {
ctx := context.Background() ctx := context.Background()
org, err := tfeClient.Organizations.Create(ctx, tfe.OrganizationCreateOptions{ org, err := tfeClient.Organizations.Create(ctx, tfe.OrganizationCreateOptions{
@ -193,9 +205,16 @@ func writeMainTF(t *testing.T, block string, dir string) {
f.Close() f.Close()
} }
// Ensure that TFC/E has a particular terraform version. // The e2e tests rely on the fact that the terraform version in TFC/E is able to
// run the `cloud` configuration block, which is available in 1.1 and will
// continue to be available in later versions. So this function checks that
// there is a version that is >= 1.1.
func skipWithoutRemoteTerraformVersion(t *testing.T) { func skipWithoutRemoteTerraformVersion(t *testing.T) {
version := tfversion.String() version := tfversion.Version
baseVersion, err := goversion.NewVersion(version)
if err != nil {
t.Fatalf(fmt.Sprintf("Error instantiating go-version for %s", version))
}
opts := tfe.AdminTerraformVersionsListOptions{ opts := tfe.AdminTerraformVersionsListOptions{
ListOptions: tfe.ListOptions{ ListOptions: tfe.ListOptions{
PageNumber: 1, PageNumber: 1,
@ -213,7 +232,12 @@ findTfVersion:
t.Fatalf("Could not retrieve list of terraform versions: %v", err) t.Fatalf("Could not retrieve list of terraform versions: %v", err)
} }
for _, item := range tfVersionList.Items { for _, item := range tfVersionList.Items {
if item.Version == version { availableVersion, err := goversion.NewVersion(item.Version)
if err != nil {
t.Logf("Error instantiating go-version for %s", item.Version)
continue
}
if availableVersion.Core().GreaterThanOrEqual(baseVersion.Core()) {
hasVersion = true hasVersion = true
break findTfVersion break findTfVersion
} }

View File

@ -4,7 +4,6 @@
package main package main
import ( import (
"fmt"
"io/ioutil" "io/ioutil"
"os" "os"
"testing" "testing"
@ -42,68 +41,70 @@ func Test_init_with_empty_tags(t *testing.T) {
} }
for name, tc := range cases { for name, tc := range cases {
fmt.Println("Test: ", name) tc := tc
organization, cleanup := createOrganization(t) t.Run(name, func(t *testing.T) {
defer cleanup() t.Parallel()
exp, err := expect.NewConsole(expect.WithStdout(os.Stdout), expect.WithDefaultTimeout(expectConsoleTimeout)) organization, cleanup := createOrganization(t)
if err != nil { defer cleanup()
t.Fatal(err) exp, err := expect.NewConsole(defaultOpts()...)
} if err != nil {
defer exp.Close() t.Fatal(err)
}
defer exp.Close()
tmpDir, err := ioutil.TempDir("", "terraform-test") tmpDir, err := ioutil.TempDir("", "terraform-test")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
tf := e2e.NewBinary(terraformBin, tmpDir) tf := e2e.NewBinary(terraformBin, tmpDir)
tf.AddEnv("TF_LOG=info") tf.AddEnv(cliConfigFileEnv)
tf.AddEnv(cliConfigFileEnv) defer tf.Close()
defer tf.Close()
for _, op := range tc.operations { for _, op := range tc.operations {
op.prep(t, organization.Name, tf.WorkDir()) op.prep(t, organization.Name, tf.WorkDir())
for _, tfCmd := range op.commands { for _, tfCmd := range op.commands {
cmd := tf.Cmd(tfCmd.command...) cmd := tf.Cmd(tfCmd.command...)
cmd.Stdin = exp.Tty() cmd.Stdin = exp.Tty()
cmd.Stdout = exp.Tty() cmd.Stdout = exp.Tty()
cmd.Stderr = exp.Tty() cmd.Stderr = exp.Tty()
err = cmd.Start() err = cmd.Start()
if err != nil {
t.Fatal(err)
}
if tfCmd.expectedCmdOutput != "" {
_, err := exp.ExpectString(tfCmd.expectedCmdOutput)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
}
lenInput := len(tfCmd.userInput) if tfCmd.expectedCmdOutput != "" {
lenInputOutput := len(tfCmd.postInputOutput) _, err := exp.ExpectString(tfCmd.expectedCmdOutput)
if lenInput > 0 { if err != nil {
for i := 0; i < lenInput; i++ { t.Fatal(err)
input := tfCmd.userInput[i] }
exp.SendLine(input) }
// use the index to find the corresponding
// output that matches the input. lenInput := len(tfCmd.userInput)
if lenInputOutput-1 >= i { lenInputOutput := len(tfCmd.postInputOutput)
output := tfCmd.postInputOutput[i] if lenInput > 0 {
_, err := exp.ExpectString(output) for i := 0; i < lenInput; i++ {
if err != nil { input := tfCmd.userInput[i]
t.Fatal(err) 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 {
t.Fatal(err)
}
} }
} }
} }
} err = cmd.Wait()
err = cmd.Wait() if err != nil && !tfCmd.expectError {
if err != nil && !tfCmd.expectError { t.Fatal(err)
t.Fatal(err) }
} }
} }
} })
} }
} }

View File

@ -4,6 +4,7 @@
package main package main
import ( import (
"flag"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"log" "log"
@ -22,6 +23,7 @@ var cliConfigFileEnv string
var tfeClient *tfe.Client var tfeClient *tfe.Client
var tfeHostname string var tfeHostname string
var tfeToken string var tfeToken string
var verboseMode bool
func TestMain(m *testing.M) { func TestMain(m *testing.M) {
log.SetFlags(log.LstdFlags | log.Lshortfile) log.SetFlags(log.LstdFlags | log.Lshortfile)
@ -43,6 +45,10 @@ func accTest() bool {
} }
func setup() func() { func setup() func() {
tfOutput := flag.Bool("tfoutput", false, "This flag produces the terraform output from tests.")
flag.Parse()
verboseMode = *tfOutput
setTfeClient() setTfeClient()
teardown := setupBinary() teardown := setupBinary()

View File

@ -16,7 +16,6 @@ import (
) )
func Test_migrate_multi_to_tfc_cloud_name_strategy(t *testing.T) { func Test_migrate_multi_to_tfc_cloud_name_strategy(t *testing.T) {
t.Parallel()
skipWithoutRemoteTerraformVersion(t) skipWithoutRemoteTerraformVersion(t)
ctx := context.Background() ctx := context.Background()
@ -38,20 +37,16 @@ func Test_migrate_multi_to_tfc_cloud_name_strategy(t *testing.T) {
expectedCmdOutput: `Successfully configured the backend "local"!`, expectedCmdOutput: `Successfully configured the backend "local"!`,
}, },
{ {
command: []string{"apply"}, command: []string{"apply", "-auto-approve"},
expectedCmdOutput: `Do you want to perform these actions?`, postInputOutput: []string{`Apply complete!`},
userInput: []string{"yes"},
postInputOutput: []string{`Apply complete!`},
}, },
{ {
command: []string{"workspace", "new", "prod"}, command: []string{"workspace", "new", "prod"},
expectedCmdOutput: `Created and switched to workspace "prod"!`, expectedCmdOutput: `Created and switched to workspace "prod"!`,
}, },
{ {
command: []string{"apply"}, command: []string{"apply", "-auto-approve"},
expectedCmdOutput: `Do you want to perform these actions`, postInputOutput: []string{`Apply complete!`},
userInput: []string{"yes"},
postInputOutput: []string{`Apply complete!`},
}, },
{ {
command: []string{"workspace", "select", "default"}, command: []string{"workspace", "select", "default"},
@ -113,20 +108,16 @@ func Test_migrate_multi_to_tfc_cloud_name_strategy(t *testing.T) {
expectedCmdOutput: `Successfully configured the backend "local"!`, expectedCmdOutput: `Successfully configured the backend "local"!`,
}, },
{ {
command: []string{"apply"}, command: []string{"apply", "-auto-approve"},
expectedCmdOutput: `Do you want to perform these actions?`, postInputOutput: []string{`Apply complete!`},
userInput: []string{"yes"},
postInputOutput: []string{`Apply complete!`},
}, },
{ {
command: []string{"workspace", "new", "prod"}, command: []string{"workspace", "new", "prod"},
expectedCmdOutput: `Created and switched to workspace "prod"!`, expectedCmdOutput: `Created and switched to workspace "prod"!`,
}, },
{ {
command: []string{"apply"}, command: []string{"apply", "-auto-approve"},
expectedCmdOutput: `Do you want to perform these actions`, postInputOutput: []string{`Apply complete!`},
userInput: []string{"yes"},
postInputOutput: []string{`Apply complete!`},
}, },
}, },
}, },
@ -171,82 +162,81 @@ func Test_migrate_multi_to_tfc_cloud_name_strategy(t *testing.T) {
} }
for name, tc := range cases { for name, tc := range cases {
t.Log("Test: ", name) tc := tc
organization, cleanup := createOrganization(t) t.Run(name, func(t *testing.T) {
defer cleanup() t.Parallel()
exp, err := expect.NewConsole(expect.WithStdout(os.Stdout), expect.WithDefaultTimeout(expectConsoleTimeout)) organization, cleanup := createOrganization(t)
if err != nil { defer cleanup()
t.Fatal(err) exp, err := expect.NewConsole(defaultOpts()...)
} if err != nil {
defer exp.Close() t.Fatal(err)
}
defer exp.Close()
tmpDir, err := ioutil.TempDir("", "terraform-test") tmpDir, err := ioutil.TempDir("", "terraform-test")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
tf := e2e.NewBinary(terraformBin, tmpDir) tf := e2e.NewBinary(terraformBin, tmpDir)
defer tf.Close() defer tf.Close()
tf.AddEnv("TF_LOG=INFO") tf.AddEnv(cliConfigFileEnv)
tf.AddEnv(cliConfigFileEnv)
for _, op := range tc.operations { for _, op := range tc.operations {
op.prep(t, organization.Name, tf.WorkDir()) op.prep(t, organization.Name, tf.WorkDir())
for _, tfCmd := range op.commands { for _, tfCmd := range op.commands {
t.Log("Running commands: ", tfCmd.command) tfCmd.command = append(tfCmd.command)
tfCmd.command = append(tfCmd.command) cmd := tf.Cmd(tfCmd.command...)
cmd := tf.Cmd(tfCmd.command...) cmd.Stdin = exp.Tty()
cmd.Stdin = exp.Tty() cmd.Stdout = exp.Tty()
cmd.Stdout = exp.Tty() cmd.Stderr = exp.Tty()
cmd.Stderr = exp.Tty()
err = cmd.Start() err = cmd.Start()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if tfCmd.expectedCmdOutput != "" { if tfCmd.expectedCmdOutput != "" {
_, err := exp.ExpectString(tfCmd.expectedCmdOutput) _, err := exp.ExpectString(tfCmd.expectedCmdOutput)
if err != nil {
t.Fatal(err)
}
}
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 {
t.Fatal(err)
}
}
}
}
err = cmd.Wait()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
} }
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 {
t.Fatal(err)
}
}
}
}
err = cmd.Wait()
if err != nil {
t.Fatal(err)
}
} }
}
if tc.validations != nil { if tc.validations != nil {
tc.validations(t, organization.Name) 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) {
t.Parallel()
skipWithoutRemoteTerraformVersion(t) skipWithoutRemoteTerraformVersion(t)
ctx := context.Background() ctx := context.Background()
@ -268,20 +258,16 @@ func Test_migrate_multi_to_tfc_cloud_tags_strategy(t *testing.T) {
expectedCmdOutput: `Successfully configured the backend "local"!`, expectedCmdOutput: `Successfully configured the backend "local"!`,
}, },
{ {
command: []string{"apply"}, command: []string{"apply", "-auto-approve"},
expectedCmdOutput: `Do you want to perform these actions?`, postInputOutput: []string{`Apply complete!`},
userInput: []string{"yes"},
postInputOutput: []string{`Apply complete!`},
}, },
{ {
command: []string{"workspace", "new", "prod"}, command: []string{"workspace", "new", "prod"},
expectedCmdOutput: `Created and switched to workspace "prod"!`, expectedCmdOutput: `Created and switched to workspace "prod"!`,
}, },
{ {
command: []string{"apply"}, command: []string{"apply", "-auto-approve"},
expectedCmdOutput: `Do you want to perform these actions`, postInputOutput: []string{`Apply complete!`},
userInput: []string{"yes"},
postInputOutput: []string{`Apply complete!`},
}, },
{ {
command: []string{"workspace", "select", "default"}, command: []string{"workspace", "select", "default"},
@ -311,21 +297,12 @@ func Test_migrate_multi_to_tfc_cloud_tags_strategy(t *testing.T) {
{ {
command: []string{"init", "-migrate-state"}, command: []string{"init", "-migrate-state"},
expectedCmdOutput: `Terraform Cloud requires all workspaces to be given an explicit name.`, expectedCmdOutput: `Terraform Cloud requires all workspaces to be given an explicit name.`,
userInput: []string{"dev", "1", "app-*", "1"}, userInput: []string{"dev", "1", "app-*"},
postInputOutput: []string{ postInputOutput: []string{
`Would you like to rename your workspaces?`, `Would you like to rename your workspaces?`,
"What pattern would you like to add to all your workspaces?", "How would you like to rename your workspaces?",
"The currently selected workspace (prod) does not exist.",
"Terraform Cloud has been successfully initialized!"}, "Terraform Cloud has been successfully initialized!"},
}, },
{
command: []string{"workspace", "select", "app-prod"},
expectedCmdOutput: `Switched to workspace "app-prod".`,
},
{
command: []string{"output"},
expectedCmdOutput: `val = "prod"`,
},
{ {
command: []string{"workspace", "select", "app-dev"}, command: []string{"workspace", "select", "app-dev"},
expectedCmdOutput: `Switched to workspace "app-dev".`, expectedCmdOutput: `Switched to workspace "app-dev".`,
@ -334,6 +311,14 @@ func Test_migrate_multi_to_tfc_cloud_tags_strategy(t *testing.T) {
command: []string{"output"}, command: []string{"output"},
expectedCmdOutput: `val = "default"`, expectedCmdOutput: `val = "default"`,
}, },
{
command: []string{"workspace", "select", "app-prod"},
expectedCmdOutput: `Switched to workspace "app-prod".`,
},
{
command: []string{"output"},
expectedCmdOutput: `val = "prod"`,
},
}, },
}, },
}, },
@ -417,17 +402,12 @@ func Test_migrate_multi_to_tfc_cloud_tags_strategy(t *testing.T) {
{ {
command: []string{"init", "-migrate-state"}, command: []string{"init", "-migrate-state"},
expectedCmdOutput: `Terraform Cloud requires all workspaces to be given an explicit name.`, expectedCmdOutput: `Terraform Cloud requires all workspaces to be given an explicit name.`,
userInput: []string{"dev", "1", "app-*", "1"}, userInput: []string{"dev", "1", "app-*"},
postInputOutput: []string{ postInputOutput: []string{
`Would you like to rename your workspaces?`, `Would you like to rename your workspaces?`,
"What pattern would you like to add to all your workspaces?", "How would you like to rename your workspaces?",
"The currently selected workspace (default) does not exist.",
"Terraform Cloud has been successfully initialized!"}, "Terraform Cloud has been successfully initialized!"},
}, },
{
command: []string{"workspace", "select", "app-dev"},
expectedCmdOutput: `Switched to workspace "app-dev".`,
},
{ {
command: []string{"workspace", "select", "app-billing"}, command: []string{"workspace", "select", "app-billing"},
expectedCmdOutput: `Switched to workspace "app-billing".`, expectedCmdOutput: `Switched to workspace "app-billing".`,
@ -436,6 +416,10 @@ func Test_migrate_multi_to_tfc_cloud_tags_strategy(t *testing.T) {
command: []string{"workspace", "select", "app-identity"}, command: []string{"workspace", "select", "app-identity"},
expectedCmdOutput: `Switched to workspace "app-identity".`, expectedCmdOutput: `Switched to workspace "app-identity".`,
}, },
{
command: []string{"workspace", "select", "app-dev"},
expectedCmdOutput: `Switched to workspace "app-dev".`,
},
}, },
}, },
}, },
@ -466,78 +450,78 @@ func Test_migrate_multi_to_tfc_cloud_tags_strategy(t *testing.T) {
} }
for name, tc := range cases { for name, tc := range cases {
t.Log("Test: ", name) tc := tc
organization, cleanup := createOrganization(t) t.Run(name, func(t *testing.T) {
t.Log(organization.Name) t.Parallel()
defer cleanup() organization, cleanup := createOrganization(t)
exp, err := expect.NewConsole(expect.WithStdout(os.Stdout), expect.WithDefaultTimeout(expectConsoleTimeout)) defer cleanup()
if err != nil { exp, err := expect.NewConsole(defaultOpts()...)
t.Fatal(err) if err != nil {
} t.Fatal(err)
defer exp.Close() }
defer exp.Close()
tmpDir, err := ioutil.TempDir("", "terraform-test") tmpDir, err := ioutil.TempDir("", "terraform-test")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
tf := e2e.NewBinary(terraformBin, tmpDir) tf := e2e.NewBinary(terraformBin, tmpDir)
defer tf.Close() defer tf.Close()
tf.AddEnv("TF_LOG=INFO") tf.AddEnv(cliConfigFileEnv)
tf.AddEnv(cliConfigFileEnv)
for _, op := range tc.operations { for _, op := range tc.operations {
op.prep(t, organization.Name, tf.WorkDir()) op.prep(t, organization.Name, tf.WorkDir())
for _, tfCmd := range op.commands { for _, tfCmd := range op.commands {
t.Log("running commands: ", tfCmd.command) cmd := tf.Cmd(tfCmd.command...)
cmd := tf.Cmd(tfCmd.command...) cmd.Stdin = exp.Tty()
cmd.Stdin = exp.Tty() cmd.Stdout = exp.Tty()
cmd.Stdout = exp.Tty() cmd.Stderr = exp.Tty()
cmd.Stderr = exp.Tty()
err = cmd.Start() err = cmd.Start()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if tfCmd.expectedCmdOutput != "" { if tfCmd.expectedCmdOutput != "" {
_, err := exp.ExpectString(tfCmd.expectedCmdOutput) _, err := exp.ExpectString(tfCmd.expectedCmdOutput)
if err != nil {
t.Fatal(err)
}
}
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 {
t.Fatal(err)
}
}
}
}
err = cmd.Wait()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
} }
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 {
t.Fatal(err)
}
}
}
}
err = cmd.Wait()
if err != nil {
t.Fatal(err)
}
} }
}
if tc.validations != nil { if tc.validations != nil {
tc.validations(t, organization.Name) tc.validations(t, organization.Name)
} }
})
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -15,7 +15,6 @@ import (
) )
func Test_migrate_single_to_tfc(t *testing.T) { func Test_migrate_single_to_tfc(t *testing.T) {
t.Parallel()
skipWithoutRemoteTerraformVersion(t) skipWithoutRemoteTerraformVersion(t)
ctx := context.Background() ctx := context.Background()
@ -37,10 +36,8 @@ func Test_migrate_single_to_tfc(t *testing.T) {
expectedCmdOutput: `Successfully configured the backend "local"!`, expectedCmdOutput: `Successfully configured the backend "local"!`,
}, },
{ {
command: []string{"apply"}, command: []string{"apply", "-auto-approve"},
expectedCmdOutput: `Do you want to perform these actions?`, postInputOutput: []string{`Apply complete!`},
userInput: []string{"yes"},
postInputOutput: []string{`Apply complete!`},
}, },
}, },
}, },
@ -88,10 +85,8 @@ func Test_migrate_single_to_tfc(t *testing.T) {
expectedCmdOutput: `Successfully configured the backend "local"!`, expectedCmdOutput: `Successfully configured the backend "local"!`,
}, },
{ {
command: []string{"apply"}, command: []string{"apply", "-auto-approve"},
expectedCmdOutput: `Do you want to perform these actions?`, postInputOutput: []string{`Apply complete!`},
userInput: []string{"yes"},
postInputOutput: []string{`Apply complete!`},
}, },
}, },
}, },
@ -133,73 +128,75 @@ func Test_migrate_single_to_tfc(t *testing.T) {
} }
for name, tc := range cases { for name, tc := range cases {
t.Log("Test: ", name) tc := tc
organization, cleanup := createOrganization(t) t.Run(name, func(t *testing.T) {
defer cleanup() t.Parallel()
exp, err := expect.NewConsole(expect.WithStdout(os.Stdout), expect.WithDefaultTimeout(expectConsoleTimeout)) organization, cleanup := createOrganization(t)
if err != nil { defer cleanup()
t.Fatal(err) exp, err := expect.NewConsole(defaultOpts()...)
} if err != nil {
defer exp.Close() t.Fatal(err)
}
defer exp.Close()
tmpDir, err := ioutil.TempDir("", "terraform-test") tmpDir, err := ioutil.TempDir("", "terraform-test")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
tf := e2e.NewBinary(terraformBin, tmpDir) tf := e2e.NewBinary(terraformBin, tmpDir)
tf.AddEnv("TF_LOG=info") tf.AddEnv(cliConfigFileEnv)
tf.AddEnv(cliConfigFileEnv) defer tf.Close()
defer tf.Close()
for _, op := range tc.operations { for _, op := range tc.operations {
op.prep(t, organization.Name, tf.WorkDir()) op.prep(t, organization.Name, tf.WorkDir())
for _, tfCmd := range op.commands { for _, tfCmd := range op.commands {
cmd := tf.Cmd(tfCmd.command...) cmd := tf.Cmd(tfCmd.command...)
cmd.Stdin = exp.Tty() cmd.Stdin = exp.Tty()
cmd.Stdout = exp.Tty() cmd.Stdout = exp.Tty()
cmd.Stderr = exp.Tty() cmd.Stderr = exp.Tty()
err = cmd.Start() err = cmd.Start()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if tfCmd.expectedCmdOutput != "" { if tfCmd.expectedCmdOutput != "" {
_, err := exp.ExpectString(tfCmd.expectedCmdOutput) _, err := exp.ExpectString(tfCmd.expectedCmdOutput)
if err != nil {
t.Fatal(err)
}
}
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 {
t.Fatal(err)
}
}
}
}
err = cmd.Wait()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
} }
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 {
t.Fatal(err)
}
}
}
}
err = cmd.Wait()
if err != nil {
t.Fatal(err)
}
} }
}
if tc.validations != nil { if tc.validations != nil {
tc.validations(t, organization.Name) tc.validations(t, organization.Name)
} }
})
} }
} }

View File

@ -4,7 +4,6 @@
package main package main
import ( import (
"fmt"
"io/ioutil" "io/ioutil"
"os" "os"
"testing" "testing"
@ -14,7 +13,6 @@ import (
) )
func Test_migrate_tfc_to_other(t *testing.T) { func Test_migrate_tfc_to_other(t *testing.T) {
t.Parallel()
cases := map[string]struct { cases := map[string]struct {
operations []operationSets operations []operationSets
}{ }{
@ -51,68 +49,70 @@ func Test_migrate_tfc_to_other(t *testing.T) {
} }
for name, tc := range cases { for name, tc := range cases {
fmt.Println("Test: ", name) tc := tc
organization, cleanup := createOrganization(t) t.Run(name, func(t *testing.T) {
defer cleanup() t.Parallel()
exp, err := expect.NewConsole(expect.WithStdout(os.Stdout), expect.WithDefaultTimeout(expectConsoleTimeout)) organization, cleanup := createOrganization(t)
if err != nil { defer cleanup()
t.Fatal(err) exp, err := expect.NewConsole(defaultOpts()...)
} if err != nil {
defer exp.Close() t.Fatal(err)
}
defer exp.Close()
tmpDir, err := ioutil.TempDir("", "terraform-test") tmpDir, err := ioutil.TempDir("", "terraform-test")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
tf := e2e.NewBinary(terraformBin, tmpDir) tf := e2e.NewBinary(terraformBin, tmpDir)
tf.AddEnv("TF_LOG=info") tf.AddEnv(cliConfigFileEnv)
tf.AddEnv(cliConfigFileEnv) defer tf.Close()
defer tf.Close()
for _, op := range tc.operations { for _, op := range tc.operations {
op.prep(t, organization.Name, tf.WorkDir()) op.prep(t, organization.Name, tf.WorkDir())
for _, tfCmd := range op.commands { for _, tfCmd := range op.commands {
cmd := tf.Cmd(tfCmd.command...) cmd := tf.Cmd(tfCmd.command...)
cmd.Stdin = exp.Tty() cmd.Stdin = exp.Tty()
cmd.Stdout = exp.Tty() cmd.Stdout = exp.Tty()
cmd.Stderr = exp.Tty() cmd.Stderr = exp.Tty()
err = cmd.Start() err = cmd.Start()
if err != nil {
t.Fatal(err)
}
if tfCmd.expectedCmdOutput != "" {
_, err := exp.ExpectString(tfCmd.expectedCmdOutput)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
}
lenInput := len(tfCmd.userInput) if tfCmd.expectedCmdOutput != "" {
lenInputOutput := len(tfCmd.postInputOutput) _, err := exp.ExpectString(tfCmd.expectedCmdOutput)
if lenInput > 0 { if err != nil {
for i := 0; i < lenInput; i++ { t.Fatal(err)
input := tfCmd.userInput[i] }
exp.SendLine(input) }
// use the index to find the corresponding
// output that matches the input. lenInput := len(tfCmd.userInput)
if lenInputOutput-1 >= i { lenInputOutput := len(tfCmd.postInputOutput)
output := tfCmd.postInputOutput[i] if lenInput > 0 {
_, err := exp.ExpectString(output) for i := 0; i < lenInput; i++ {
if err != nil { input := tfCmd.userInput[i]
t.Fatal(err) 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 {
t.Fatal(err)
}
} }
} }
} }
} err = cmd.Wait()
err = cmd.Wait() if err != nil && !tfCmd.expectError {
if err != nil && !tfCmd.expectError { t.Fatal(err)
t.Fatal(err) }
} }
} }
} })
} }
} }

View File

@ -16,7 +16,6 @@ import (
) )
func Test_migrate_tfc_to_tfc_single_workspace(t *testing.T) { func Test_migrate_tfc_to_tfc_single_workspace(t *testing.T) {
t.Parallel()
skipWithoutRemoteTerraformVersion(t) skipWithoutRemoteTerraformVersion(t)
ctx := context.Background() ctx := context.Background()
@ -55,10 +54,8 @@ func Test_migrate_tfc_to_tfc_single_workspace(t *testing.T) {
expectedCmdOutput: `prod`, // this comes from the `prep` function expectedCmdOutput: `prod`, // this comes from the `prep` function
}, },
{ {
command: []string{"apply"}, command: []string{"apply", "-auto-approve"},
expectedCmdOutput: `Do you want to perform these actions in workspace "prod"?`, postInputOutput: []string{`Apply complete!`},
userInput: []string{"yes"},
postInputOutput: []string{`Apply complete!`},
}, },
}, },
}, },
@ -119,10 +116,8 @@ func Test_migrate_tfc_to_tfc_single_workspace(t *testing.T) {
expectedCmdOutput: `Terraform Cloud has been successfully initialized!`, expectedCmdOutput: `Terraform Cloud has been successfully initialized!`,
}, },
{ {
command: []string{"apply"}, command: []string{"apply", "-auto-approve"},
expectedCmdOutput: `Do you want to perform these actions in workspace "prod"?`, postInputOutput: []string{`Apply complete!`},
userInput: []string{"yes"},
postInputOutput: []string{`Apply complete!`},
}, },
}, },
}, },
@ -183,10 +178,8 @@ func Test_migrate_tfc_to_tfc_single_workspace(t *testing.T) {
expectedCmdOutput: `Terraform Cloud has been successfully initialized!`, expectedCmdOutput: `Terraform Cloud has been successfully initialized!`,
}, },
{ {
command: []string{"apply"}, command: []string{"apply", "-auto-approve"},
expectedCmdOutput: `Do you want to perform these actions in workspace "prod"?`, postInputOutput: []string{`Apply complete!`},
userInput: []string{"yes"},
postInputOutput: []string{`Apply complete!`},
}, },
}, },
}, },
@ -214,95 +207,92 @@ func Test_migrate_tfc_to_tfc_single_workspace(t *testing.T) {
}, },
}, },
validations: func(t *testing.T, orgName string) { validations: func(t *testing.T, orgName string) {
wsList, err := tfeClient.Workspaces.List(ctx, orgName, tfe.WorkspaceListOptions{ // We created the workspace, so it will be there. We could not complete the state migration,
Tags: tfe.String("app"), // though, so the workspace should be empty.
}) ws, err := tfeClient.Workspaces.ReadWithOptions(ctx, orgName, "new-workspace", &tfe.WorkspaceReadOptions{Include: "current_run"})
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
// The migration never occured, so we have no workspaces with this tag. if ws.CurrentRun != nil {
if len(wsList.Items) != 0 { t.Fatal("Expected to workspace be empty")
t.Fatalf("Expected number of workspaces to be 0, but got %d", len(wsList.Items))
} }
}, },
}, },
} }
for name, tc := range cases { for name, tc := range cases {
t.Log("Test: ", name) t.Run(name, func(t *testing.T) {
exp, err := expect.NewConsole(expect.WithStdout(os.Stdout), expect.WithDefaultTimeout(expectConsoleTimeout)) exp, err := expect.NewConsole(defaultOpts()...)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
defer exp.Close() defer exp.Close()
tmpDir, err := ioutil.TempDir("", "terraform-test") tmpDir, err := ioutil.TempDir("", "terraform-test")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
tf := e2e.NewBinary(terraformBin, tmpDir) tf := e2e.NewBinary(terraformBin, tmpDir)
defer tf.Close() defer tf.Close()
tf.AddEnv("TF_LOG=INFO") tf.AddEnv(cliConfigFileEnv)
tf.AddEnv(cliConfigFileEnv)
orgName, cleanup := tc.setup(t) orgName, cleanup := tc.setup(t)
defer cleanup() defer cleanup()
for _, op := range tc.operations { for _, op := range tc.operations {
op.prep(t, orgName, tf.WorkDir()) op.prep(t, orgName, tf.WorkDir())
for _, tfCmd := range op.commands { for _, tfCmd := range op.commands {
t.Log("Running commands: ", tfCmd.command) cmd := tf.Cmd(tfCmd.command...)
cmd := tf.Cmd(tfCmd.command...) cmd.Stdin = exp.Tty()
cmd.Stdin = exp.Tty() cmd.Stdout = exp.Tty()
cmd.Stdout = exp.Tty() cmd.Stderr = exp.Tty()
cmd.Stderr = exp.Tty()
err = cmd.Start() err = cmd.Start()
if err != nil {
t.Fatal(err)
}
if tfCmd.expectedCmdOutput != "" {
_, err := exp.ExpectString(tfCmd.expectedCmdOutput)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
}
lenInput := len(tfCmd.userInput) if tfCmd.expectedCmdOutput != "" {
lenInputOutput := len(tfCmd.postInputOutput) _, err := exp.ExpectString(tfCmd.expectedCmdOutput)
if lenInput > 0 { if err != nil {
for i := 0; i < lenInput; i++ { t.Fatal(err)
input := tfCmd.userInput[i] }
exp.SendLine(input) }
// use the index to find the corresponding
// output that matches the input. lenInput := len(tfCmd.userInput)
if lenInputOutput-1 >= i { lenInputOutput := len(tfCmd.postInputOutput)
output := tfCmd.postInputOutput[i] if lenInput > 0 {
_, err := exp.ExpectString(output) for i := 0; i < lenInput; i++ {
if err != nil { input := tfCmd.userInput[i]
t.Fatal(err) 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 {
t.Fatal(err)
}
} }
} }
} }
}
err = cmd.Wait() err = cmd.Wait()
if err != nil && !tfCmd.expectError { if err != nil && !tfCmd.expectError {
t.Fatal(err.Error()) t.Fatal(err.Error())
}
} }
} }
}
if tc.validations != nil { if tc.validations != nil {
tc.validations(t, orgName) 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) {
t.Parallel()
skipWithoutRemoteTerraformVersion(t) skipWithoutRemoteTerraformVersion(t)
ctx := context.Background() ctx := context.Background()
@ -454,7 +444,6 @@ func Test_migrate_tfc_to_tfc_multiple_workspace(t *testing.T) {
tag := "billing" tag := "billing"
tfBlock := terraformConfigCloudBackendTags(orgName, tag) tfBlock := terraformConfigCloudBackendTags(orgName, tag)
writeMainTF(t, tfBlock, dir) writeMainTF(t, tfBlock, dir)
t.Log(orgName)
}, },
commands: []tfCommand{ commands: []tfCommand{
{ {
@ -462,8 +451,7 @@ func Test_migrate_tfc_to_tfc_multiple_workspace(t *testing.T) {
expectedCmdOutput: `Would you like to rename your workspaces?`, expectedCmdOutput: `Would you like to rename your workspaces?`,
userInput: []string{"1", "new-*", "1"}, userInput: []string{"1", "new-*", "1"},
postInputOutput: []string{ postInputOutput: []string{
`What pattern would you like to add to all your workspaces?`, `How would you like to rename your workspaces?`,
`The currently selected workspace (app-staging) does not exist.`,
`Terraform Cloud has been successfully initialized!`}, `Terraform Cloud has been successfully initialized!`},
}, },
}, },
@ -492,75 +480,73 @@ func Test_migrate_tfc_to_tfc_multiple_workspace(t *testing.T) {
} }
for name, tc := range cases { for name, tc := range cases {
t.Log("Test: ", name) t.Run(name, func(t *testing.T) {
exp, err := expect.NewConsole(expect.WithStdout(os.Stdout), expect.WithDefaultTimeout(expectConsoleTimeout)) exp, err := expect.NewConsole(defaultOpts()...)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
defer exp.Close() defer exp.Close()
tmpDir, err := ioutil.TempDir("", "terraform-test") tmpDir, err := ioutil.TempDir("", "terraform-test")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
tf := e2e.NewBinary(terraformBin, tmpDir) tf := e2e.NewBinary(terraformBin, tmpDir)
defer tf.Close() defer tf.Close()
tf.AddEnv("TF_LOG=INFO") tf.AddEnv(cliConfigFileEnv)
tf.AddEnv(cliConfigFileEnv)
orgName, cleanup := tc.setup(t) orgName, cleanup := tc.setup(t)
defer cleanup() defer cleanup()
for _, op := range tc.operations { for _, op := range tc.operations {
op.prep(t, orgName, tf.WorkDir()) op.prep(t, orgName, tf.WorkDir())
for _, tfCmd := range op.commands { for _, tfCmd := range op.commands {
t.Log("Running commands: ", tfCmd.command) cmd := tf.Cmd(tfCmd.command...)
cmd := tf.Cmd(tfCmd.command...) cmd.Stdin = exp.Tty()
cmd.Stdin = exp.Tty() cmd.Stdout = exp.Tty()
cmd.Stdout = exp.Tty() cmd.Stderr = exp.Tty()
cmd.Stderr = exp.Tty()
err = cmd.Start() err = cmd.Start()
if err != nil {
t.Fatal(err)
}
if tfCmd.expectedCmdOutput != "" {
_, err := exp.ExpectString(tfCmd.expectedCmdOutput)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
}
lenInput := len(tfCmd.userInput) if tfCmd.expectedCmdOutput != "" {
lenInputOutput := len(tfCmd.postInputOutput) _, err := exp.ExpectString(tfCmd.expectedCmdOutput)
if lenInput > 0 { if err != nil {
for i := 0; i < lenInput; i++ { t.Fatal(err)
input := tfCmd.userInput[i] }
exp.SendLine(input) }
// use the index to find the corresponding
// output that matches the input. lenInput := len(tfCmd.userInput)
if lenInputOutput-1 >= i { lenInputOutput := len(tfCmd.postInputOutput)
output := tfCmd.postInputOutput[i] if lenInput > 0 {
_, err := exp.ExpectString(output) for i := 0; i < lenInput; i++ {
if err != nil { input := tfCmd.userInput[i]
t.Fatal(err) 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 {
t.Fatal(err)
}
} }
} }
} }
}
t.Log(cmd.Stderr) err = cmd.Wait()
err = cmd.Wait() if err != nil {
if err != nil { t.Fatal(err.Error())
t.Fatal(err.Error()) }
} }
} }
}
if tc.validations != nil { if tc.validations != nil {
tc.validations(t, orgName) tc.validations(t, orgName)
} }
})
} }
} }

View File

@ -46,7 +46,6 @@ output "test_env" {
} }
func Test_cloud_run_variables(t *testing.T) { func Test_cloud_run_variables(t *testing.T) {
t.Parallel()
skipWithoutRemoteTerraformVersion(t) skipWithoutRemoteTerraformVersion(t)
cases := testCases{ cases := testCases{
@ -78,75 +77,75 @@ func Test_cloud_run_variables(t *testing.T) {
} }
for name, tc := range cases { for name, tc := range cases {
fmt.Println("Test: ", name) t.Run(name, func(t *testing.T) {
organization, cleanup := createOrganization(t) organization, cleanup := createOrganization(t)
defer cleanup() defer cleanup()
exp, err := expect.NewConsole(expect.WithStdout(os.Stdout), expect.WithDefaultTimeout(expectConsoleTimeout)) exp, err := expect.NewConsole(defaultOpts()...)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
defer exp.Close() defer exp.Close()
tmpDir, err := ioutil.TempDir("", "terraform-test") tmpDir, err := ioutil.TempDir("", "terraform-test")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
tf := e2e.NewBinary(terraformBin, tmpDir) tf := e2e.NewBinary(terraformBin, tmpDir)
tf.AddEnv("TF_LOG=info") tf.AddEnv("TF_CLI_ARGS=-no-color")
tf.AddEnv("TF_CLI_ARGS=-no-color") tf.AddEnv("TF_VAR_baz=qux")
tf.AddEnv("TF_VAR_baz=qux") tf.AddEnv(cliConfigFileEnv)
tf.AddEnv(cliConfigFileEnv) defer tf.Close()
defer tf.Close()
for _, op := range tc.operations { for _, op := range tc.operations {
op.prep(t, organization.Name, tf.WorkDir()) op.prep(t, organization.Name, tf.WorkDir())
for _, tfCmd := range op.commands { for _, tfCmd := range op.commands {
cmd := tf.Cmd(tfCmd.command...) cmd := tf.Cmd(tfCmd.command...)
cmd.Stdin = exp.Tty() cmd.Stdin = exp.Tty()
cmd.Stdout = exp.Tty() cmd.Stdout = exp.Tty()
cmd.Stderr = exp.Tty() cmd.Stderr = exp.Tty()
err = cmd.Start() err = cmd.Start()
if err != nil {
t.Fatal(err)
}
if tfCmd.expectedCmdOutput != "" {
_, err := exp.ExpectString(tfCmd.expectedCmdOutput)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if tfCmd.expectedCmdOutput != "" {
_, err := exp.ExpectString(tfCmd.expectedCmdOutput)
if err != nil {
t.Fatalf(`Expected command output "%s", but got %v `, tfCmd.expectedCmdOutput, err)
}
}
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 {
t.Fatalf(`Expected command output "%s", but got %v `, tfCmd.expectedCmdOutput, err)
}
}
}
}
err = cmd.Wait()
if err != nil && !tfCmd.expectError {
t.Fatal(err)
}
} }
lenInput := len(tfCmd.userInput) if tc.validations != nil {
lenInputOutput := len(tfCmd.postInputOutput) tc.validations(t, organization.Name)
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 {
t.Fatal(err)
}
}
}
}
err = cmd.Wait()
if err != nil && !tfCmd.expectError {
t.Fatal(err)
} }
} }
})
if tc.validations != nil {
tc.validations(t, organization.Name)
}
}
} }
} }