terraform/internal/cloud/e2e/apply_auto_approve_test.go

239 lines
7.3 KiB
Go

//go:build e2e
// +build e2e
package main
import (
"context"
"io/ioutil"
"log"
"strings"
"testing"
tfe "github.com/hashicorp/go-tfe"
"github.com/hashicorp/terraform/internal/e2e"
)
func Test_terraform_apply_autoApprove(t *testing.T) {
ctx := context.Background()
cases := map[string]struct {
setup func(t *testing.T) (map[string]string, func())
commands []tfCommand
validations func(t *testing.T, orgName, wsName string)
}{
"workspace manual apply, terraform apply without auto-approve": {
setup: func(t *testing.T) (map[string]string, func()) {
org, orgCleanup := createOrganization(t)
wOpts := tfe.WorkspaceCreateOptions{
Name: tfe.String(randomString(t)),
TerraformVersion: tfe.String(terraformVersion),
AutoApply: tfe.Bool(false),
}
workspace := createWorkspace(t, org.Name, wOpts)
cleanup := func() {
defer orgCleanup()
}
names := map[string]string{
"organization": org.Name,
"workspace": workspace.Name,
}
return names, cleanup
},
commands: []tfCommand{
{
command: []string{"init"},
expectedCmdOutput: "Terraform has been successfully initialized",
expectedErr: "",
},
{
command: []string{"apply"},
expectedCmdOutput: "Do you want to perform these actions in workspace",
expectedErr: "Error asking approve",
},
},
validations: func(t *testing.T, orgName, wsName string) {
workspace, err := tfeClient.Workspaces.ReadWithOptions(ctx, orgName, wsName, &tfe.WorkspaceReadOptions{Include: "current_run"})
if err != nil {
t.Fatal(err)
}
if workspace.CurrentRun == nil {
t.Fatal("Expected workspace to have run, but got nil")
}
if workspace.CurrentRun.Status != tfe.RunPlanned {
t.Fatalf("Expected run status to be `planned`, but is %s", workspace.CurrentRun.Status)
}
},
},
"workspace auto apply, terraform apply without auto-approve": {
setup: func(t *testing.T) (map[string]string, func()) {
org, orgCleanup := createOrganization(t)
wOpts := tfe.WorkspaceCreateOptions{
Name: tfe.String(randomString(t)),
TerraformVersion: tfe.String(terraformVersion),
AutoApply: tfe.Bool(true),
}
workspace := createWorkspace(t, org.Name, wOpts)
cleanup := func() {
defer orgCleanup()
}
names := map[string]string{
"organization": org.Name,
"workspace": workspace.Name,
}
return names, cleanup
},
commands: []tfCommand{
{
command: []string{"init"},
expectedCmdOutput: "Terraform has been successfully initialized",
expectedErr: "",
},
{
command: []string{"apply"},
expectedCmdOutput: "Do you want to perform these actions in workspace",
expectedErr: "Error asking approve",
},
},
validations: func(t *testing.T, orgName, wsName string) {
workspace, err := tfeClient.Workspaces.ReadWithOptions(ctx, orgName, wsName, &tfe.WorkspaceReadOptions{Include: "current_run"})
if err != nil {
t.Fatal(err)
}
if workspace.CurrentRun == nil {
t.Fatalf("Expected workspace to have run, but got nil")
}
if workspace.CurrentRun.Status != tfe.RunPlanned {
t.Fatalf("Expected run status to be `planned`, but is %s", workspace.CurrentRun.Status)
}
},
},
"workspace manual apply, terraform apply auto-approve": {
setup: func(t *testing.T) (map[string]string, func()) {
org, orgCleanup := createOrganization(t)
wOpts := tfe.WorkspaceCreateOptions{
Name: tfe.String(randomString(t)),
TerraformVersion: tfe.String(terraformVersion),
AutoApply: tfe.Bool(false),
}
workspace := createWorkspace(t, org.Name, wOpts)
cleanup := func() {
defer orgCleanup()
}
names := map[string]string{
"organization": org.Name,
"workspace": workspace.Name,
}
return names, cleanup
},
commands: []tfCommand{
{
command: []string{"init"},
expectedCmdOutput: "Terraform has been successfully initialized",
expectedErr: "",
},
{
command: []string{"apply", "-auto-approve"},
expectedCmdOutput: "Apply complete! Resources: 1 added, 0 changed, 0 destroyed.",
expectedErr: "",
},
},
validations: func(t *testing.T, orgName, wsName string) {
workspace, err := tfeClient.Workspaces.ReadWithOptions(ctx, orgName, wsName, &tfe.WorkspaceReadOptions{Include: "current_run"})
if err != nil {
t.Fatal(err)
}
if workspace.CurrentRun == nil {
t.Fatalf("Expected workspace to have run, but got nil")
}
if workspace.CurrentRun.Status != tfe.RunApplied {
t.Fatalf("Expected run status to be `applied`, but is %s", workspace.CurrentRun.Status)
}
},
},
"workspace auto apply, terraform apply auto-approve": {
setup: func(t *testing.T) (map[string]string, func()) {
org, orgCleanup := createOrganization(t)
wOpts := tfe.WorkspaceCreateOptions{
Name: tfe.String(randomString(t)),
TerraformVersion: tfe.String(terraformVersion),
AutoApply: tfe.Bool(true),
}
workspace := createWorkspace(t, org.Name, wOpts)
cleanup := func() {
defer orgCleanup()
}
names := map[string]string{
"organization": org.Name,
"workspace": workspace.Name,
}
return names, cleanup
},
commands: []tfCommand{
{
command: []string{"init"},
expectedCmdOutput: "Terraform has been successfully initialized",
expectedErr: "",
},
{
command: []string{"apply", "-auto-approve"},
expectedCmdOutput: "Apply complete! Resources: 1 added, 0 changed, 0 destroyed.",
expectedErr: "",
},
},
validations: func(t *testing.T, orgName, wsName string) {
workspace, err := tfeClient.Workspaces.ReadWithOptions(ctx, orgName, wsName, &tfe.WorkspaceReadOptions{Include: "current_run"})
if err != nil {
t.Fatal(err)
}
if workspace.CurrentRun == nil {
t.Fatalf("Expected workspace to have run, but got nil")
}
if workspace.CurrentRun.Status != tfe.RunApplied {
t.Fatalf("Expected run status to be `applied`, but is %s", workspace.CurrentRun.Status)
}
},
},
}
for name, tc := range cases {
log.Println("Test: ", name)
resourceData, cleanup := tc.setup(t)
defer cleanup()
tmpDir, err := ioutil.TempDir("", "terraform-test")
if err != nil {
t.Fatal(err)
}
orgName := resourceData["organization"]
wsName := resourceData["workspace"]
tfBlock := terraformConfigCloudBackendName(orgName, wsName)
writeMainTF(t, tfBlock, tmpDir)
tf := e2e.NewBinary(terraformBin, tmpDir)
defer tf.Close()
tf.AddEnv("TF_LOG=debug")
tf.AddEnv(cliConfigFileEnv)
for _, cmd := range tc.commands {
stdout, stderr, err := tf.Run(cmd.command...)
if cmd.expectedErr == "" && err != nil {
t.Fatalf("Expected no error, but got %v. stderr\n: %s", err, stderr)
}
if cmd.expectedErr != "" {
if !strings.Contains(stderr, cmd.expectedErr) {
t.Fatalf("Expected to find error %s, but got %s", cmd.expectedErr, stderr)
}
}
if cmd.expectedCmdOutput != "" && !strings.Contains(stdout, cmd.expectedCmdOutput) {
t.Fatalf("Expected to find output %s, but did not find in\n%s", cmd.expectedCmdOutput, stdout)
}
}
tc.validations(t, orgName, wsName)
}
}