Merge pull request #29883 from hashicorp/barrettclark/cloud-e2e-tests

Cloud: Make e2e Tests Less Chatty, and More Stable
This commit is contained in:
Barrett Clark 2021-11-15 10:45:14 -06:00 committed by GitHub
commit 388c430ece
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 1619 additions and 1463 deletions

2
go.mod
View File

@ -43,7 +43,7 @@ require (
github.com/hashicorp/go-retryablehttp v0.7.0
github.com/hashicorp/go-tfe v0.20.1-0.20211110172530-c43c6b574caa
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/v2 v2.10.1
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.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.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pBJ3TkI=
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.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=

View File

@ -0,0 +1,24 @@
# How to run tests
To run them, use:
```
TFE_TOKEN=<token> TFE_HOSTNAME=<hostname> TF_ACC=1 go test ./internal/cloud/e2e/... -ldflags "-X \"github.com/hashicorp/terraform/version.Prerelease=<PRE-RELEASE>\""
```
Required flags
* `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

@ -1,12 +1,8 @@
//go:build e2e
// +build e2e
package main
import (
"context"
"io/ioutil"
"log"
"os"
"testing"
@ -17,7 +13,7 @@ import (
)
func Test_terraform_apply_autoApprove(t *testing.T) {
t.Parallel()
skipIfMissingEnvVar(t)
skipWithoutRemoteTerraformVersion(t)
ctx := context.Background()
@ -183,12 +179,10 @@ func Test_terraform_apply_autoApprove(t *testing.T) {
},
},
}
for name, tc := range cases {
log.Println("Test: ", name)
for _, tc := range cases {
organization, cleanup := createOrganization(t)
defer cleanup()
exp, err := expect.NewConsole(expect.WithStdout(os.Stdout), expect.WithDefaultTimeout(expectConsoleTimeout))
exp, err := expect.NewConsole(defaultOpts()...)
if err != nil {
t.Fatal(err)
}
@ -201,7 +195,6 @@ func Test_terraform_apply_autoApprove(t *testing.T) {
defer os.RemoveAll(tmpDir)
tf := e2e.NewBinary(terraformBin, tmpDir)
tf.AddEnv("TF_LOG=info")
tf.AddEnv(cliConfigFileEnv)
defer tf.Close()

View File

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

View File

@ -1,6 +1,3 @@
//go:build e2e
// +build e2e
package main
import (
@ -10,8 +7,10 @@ import (
"testing"
"time"
expect "github.com/Netflix/go-expect"
tfe "github.com/hashicorp/go-tfe"
"github.com/hashicorp/go-uuid"
goversion "github.com/hashicorp/go-version"
tfversion "github.com/hashicorp/terraform/version"
)
@ -22,7 +21,6 @@ const (
type tfCommand struct {
command []string
expectedCmdOutput string
expectedErr string
expectError bool
userInput []string
postInputOutput []string
@ -38,6 +36,16 @@ type testCases map[string]struct {
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()) {
ctx := context.Background()
org, err := tfeClient.Organizations.Create(ctx, tfe.OrganizationCreateOptions{
@ -93,7 +101,7 @@ func randomString(t *testing.T) string {
}
func terraformConfigLocalBackend() string {
return fmt.Sprintf(`
return `
terraform {
backend "local" {
}
@ -102,7 +110,7 @@ terraform {
output "val" {
value = "${terraform.workspace}"
}
`)
`
}
func terraformConfigRemoteBackendName(org, name string) string {
@ -193,9 +201,16 @@ func writeMainTF(t *testing.T, block string, dir string) {
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) {
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{
ListOptions: tfe.ListOptions{
PageNumber: 1,
@ -213,7 +228,12 @@ findTfVersion:
t.Fatalf("Could not retrieve list of terraform versions: %v", err)
}
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
break findTfVersion
}

View File

@ -1,10 +1,6 @@
//go:build e2e
// +build e2e
package main
import (
"fmt"
"io/ioutil"
"os"
"testing"
@ -14,6 +10,7 @@ import (
)
func Test_init_with_empty_tags(t *testing.T) {
skipIfMissingEnvVar(t)
t.Parallel()
skipWithoutRemoteTerraformVersion(t)
@ -42,68 +39,70 @@ func Test_init_with_empty_tags(t *testing.T) {
}
for name, tc := range cases {
fmt.Println("Test: ", name)
organization, cleanup := createOrganization(t)
defer cleanup()
exp, err := expect.NewConsole(expect.WithStdout(os.Stdout), expect.WithDefaultTimeout(expectConsoleTimeout))
if err != nil {
t.Fatal(err)
}
defer exp.Close()
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()
tmpDir, err := ioutil.TempDir("", "terraform-test")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(tmpDir)
tmpDir, err := ioutil.TempDir("", "terraform-test")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(tmpDir)
tf := e2e.NewBinary(terraformBin, tmpDir)
tf.AddEnv("TF_LOG=info")
tf.AddEnv(cliConfigFileEnv)
defer tf.Close()
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()
for _, op := range tc.operations {
op.prep(t, organization.Name, tf.WorkDir())
for _, tfCmd := range op.commands {
cmd := tf.Cmd(tfCmd.command...)
cmd.Stdin = exp.Tty()
cmd.Stdout = exp.Tty()
cmd.Stderr = exp.Tty()
err = cmd.Start()
if err != nil {
t.Fatal(err)
}
if tfCmd.expectedCmdOutput != "" {
_, err := exp.ExpectString(tfCmd.expectedCmdOutput)
err = cmd.Start()
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)
if 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 && !tfCmd.expectError {
t.Fatal(err)
err = cmd.Wait()
if err != nil && !tfCmd.expectError {
t.Fatal(err)
}
}
}
}
})
}
}

View File

@ -1,9 +1,7 @@
//go:build e2e
// +build e2e
package main
import (
"flag"
"fmt"
"io/ioutil"
"log"
@ -22,13 +20,9 @@ var cliConfigFileEnv string
var tfeClient *tfe.Client
var tfeHostname string
var tfeToken string
var verboseMode bool
func TestMain(m *testing.M) {
log.SetFlags(log.LstdFlags | log.Lshortfile)
if !accTest() {
// if TF_ACC is not set, we want to skip all these tests.
return
}
teardown := setup()
code := m.Run()
teardown()
@ -42,7 +36,29 @@ func accTest() bool {
return os.Getenv("TF_ACC") != ""
}
func hasHostname() bool {
return os.Getenv("TFE_HOSTNAME") != ""
}
func hasToken() bool {
return os.Getenv("TFE_TOKEN") != ""
}
func hasRequiredEnvVars() bool {
return accTest() && hasHostname() && hasToken()
}
func skipIfMissingEnvVar(t *testing.T) {
if !hasRequiredEnvVars() {
t.Skip("Skipping test, required environment variables missing. Use `TF_ACC`, `TFE_HOSTNAME`, `TFE_TOKEN`")
}
}
func setup() func() {
tfOutput := flag.Bool("tfoutput", false, "This flag produces the terraform output from tests.")
flag.Parse()
verboseMode = *tfOutput
setTfeClient()
teardown := setupBinary()
@ -52,41 +68,38 @@ func setup() func() {
}
func setTfeClient() {
hostname := os.Getenv("TFE_HOSTNAME")
token := os.Getenv("TFE_TOKEN")
if hostname == "" {
log.Fatal("hostname cannot be empty")
}
if token == "" {
log.Fatal("token cannot be empty")
}
tfeHostname = hostname
tfeToken = token
tfeHostname = os.Getenv("TFE_HOSTNAME")
tfeToken = os.Getenv("TFE_TOKEN")
cfg := &tfe.Config{
Address: fmt.Sprintf("https://%s", hostname),
Token: token,
Address: fmt.Sprintf("https://%s", tfeHostname),
Token: tfeToken,
}
// Create a new TFE client.
client, err := tfe.NewClient(cfg)
if err != nil {
log.Fatal(err)
if tfeHostname != "" && tfeToken != "" {
// Create a new TFE client.
client, err := tfe.NewClient(cfg)
if err != nil {
fmt.Printf("Could not create new tfe client: %v\n", err)
os.Exit(1)
}
tfeClient = client
}
tfeClient = client
}
func setupBinary() func() {
log.Println("Setting up terraform binary")
tmpTerraformBinaryDir, err := ioutil.TempDir("", "terraform-test")
if err != nil {
log.Fatal(err)
fmt.Printf("Could not create temp directory: %v\n", err)
os.Exit(1)
}
log.Println(tmpTerraformBinaryDir)
currentDir, err := os.Getwd()
defer os.Chdir(currentDir)
if err != nil {
log.Fatal(err)
fmt.Printf("Could not change directories: %v\n", err)
os.Exit(1)
}
// Getting top level dir
dirPaths := strings.Split(currentDir, "/")
@ -95,7 +108,8 @@ func setupBinary() func() {
topDir := strings.Join(dirPaths[0:topLevel], "/")
if err := os.Chdir(topDir); err != nil {
log.Fatal(err)
fmt.Printf("Could not change directories: %v\n", err)
os.Exit(1)
}
cmd := exec.Command(
@ -106,7 +120,8 @@ func setupBinary() func() {
)
err = cmd.Run()
if err != nil {
log.Fatal(err)
fmt.Printf("Could not run exec command: %v\n", err)
os.Exit(1)
}
credFile := fmt.Sprintf("%s/dev.tfrc", tmpTerraformBinaryDir)
@ -124,11 +139,13 @@ func writeCredRC(file string) {
creds := credentialBlock()
f, err := os.Create(file)
if err != nil {
log.Fatal(err)
fmt.Printf("Could not create file: %v\n", err)
os.Exit(1)
}
_, err = f.WriteString(creds)
if err != nil {
log.Fatal(err)
fmt.Printf("Could not write credentials: %v\n", err)
os.Exit(1)
}
f.Close()
}

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -1,10 +1,6 @@
//go:build e2e
// +build e2e
package main
import (
"fmt"
"io/ioutil"
"os"
"testing"
@ -14,7 +10,7 @@ import (
)
func Test_migrate_tfc_to_other(t *testing.T) {
t.Parallel()
skipIfMissingEnvVar(t)
cases := map[string]struct {
operations []operationSets
}{
@ -51,68 +47,70 @@ func Test_migrate_tfc_to_other(t *testing.T) {
}
for name, tc := range cases {
fmt.Println("Test: ", name)
organization, cleanup := createOrganization(t)
defer cleanup()
exp, err := expect.NewConsole(expect.WithStdout(os.Stdout), expect.WithDefaultTimeout(expectConsoleTimeout))
if err != nil {
t.Fatal(err)
}
defer exp.Close()
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()
tmpDir, err := ioutil.TempDir("", "terraform-test")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(tmpDir)
tmpDir, err := ioutil.TempDir("", "terraform-test")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(tmpDir)
tf := e2e.NewBinary(terraformBin, tmpDir)
tf.AddEnv("TF_LOG=info")
tf.AddEnv(cliConfigFileEnv)
defer tf.Close()
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()
for _, op := range tc.operations {
op.prep(t, organization.Name, tf.WorkDir())
for _, tfCmd := range op.commands {
cmd := tf.Cmd(tfCmd.command...)
cmd.Stdin = exp.Tty()
cmd.Stdout = exp.Tty()
cmd.Stderr = exp.Tty()
err = cmd.Start()
if err != nil {
t.Fatal(err)
}
if tfCmd.expectedCmdOutput != "" {
_, err := exp.ExpectString(tfCmd.expectedCmdOutput)
err = cmd.Start()
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)
if 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 && !tfCmd.expectError {
t.Fatal(err)
err = cmd.Wait()
if err != nil && !tfCmd.expectError {
t.Fatal(err)
}
}
}
}
})
}
}

View File

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

View File

@ -1,6 +1,3 @@
//go:build e2e
// +build e2e
package main
import (
@ -10,7 +7,9 @@ import (
"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"
)
func terraformConfigRequiredVariable(org, name string) string {
@ -46,7 +45,7 @@ output "test_env" {
}
func Test_cloud_run_variables(t *testing.T) {
t.Parallel()
skipIfMissingEnvVar(t)
skipWithoutRemoteTerraformVersion(t)
cases := testCases{
@ -55,6 +54,10 @@ func Test_cloud_run_variables(t *testing.T) {
{
prep: func(t *testing.T, orgName, dir string) {
wsName := "new-workspace"
_ = createWorkspace(t, orgName, tfe.WorkspaceCreateOptions{
Name: tfe.String(wsName),
TerraformVersion: tfe.String(tfversion.String()),
})
tfBlock := terraformConfigRequiredVariable(orgName, wsName)
writeMainTF(t, tfBlock, dir)
},
@ -78,75 +81,75 @@ func Test_cloud_run_variables(t *testing.T) {
}
for name, tc := range cases {
fmt.Println("Test: ", name)
organization, cleanup := createOrganization(t)
defer cleanup()
exp, err := expect.NewConsole(expect.WithStdout(os.Stdout), expect.WithDefaultTimeout(expectConsoleTimeout))
if err != nil {
t.Fatal(err)
}
defer exp.Close()
t.Run(name, func(t *testing.T) {
organization, cleanup := createOrganization(t)
defer cleanup()
exp, err := expect.NewConsole(defaultOpts()...)
if err != nil {
t.Fatal(err)
}
defer exp.Close()
tmpDir, err := ioutil.TempDir("", "terraform-test")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(tmpDir)
tmpDir, err := ioutil.TempDir("", "terraform-test")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(tmpDir)
tf := e2e.NewBinary(terraformBin, tmpDir)
tf.AddEnv("TF_LOG=info")
tf.AddEnv("TF_CLI_ARGS=-no-color")
tf.AddEnv("TF_VAR_baz=qux")
tf.AddEnv(cliConfigFileEnv)
defer tf.Close()
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()
for _, op := range tc.operations {
op.prep(t, organization.Name, tf.WorkDir())
for _, tfCmd := range op.commands {
cmd := tf.Cmd(tfCmd.command...)
cmd.Stdin = exp.Tty()
cmd.Stdout = exp.Tty()
cmd.Stderr = exp.Tty()
err = cmd.Start()
if err != nil {
t.Fatal(err)
}
if tfCmd.expectedCmdOutput != "" {
_, err := exp.ExpectString(tfCmd.expectedCmdOutput)
err = cmd.Start()
if err != nil {
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)
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 && !tfCmd.expectError {
t.Fatal(err)
if tc.validations != nil {
tc.validations(t, organization.Name)
}
}
if tc.validations != nil {
tc.validations(t, organization.Name)
}
}
})
}
}