mirror of
https://github.com/opentofu/opentofu.git
synced 2025-02-25 18:45:20 -06:00
As the cloud e2e tests evolved some common patters became apparent. This standardizes and consolidates the patterns into a common test runner that takes the table tests and runs them in parallel. Some tests also needed to be converted to utilize table tests.
370 lines
12 KiB
Go
370 lines
12 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
tfe "github.com/hashicorp/go-tfe"
|
|
tfversion "github.com/hashicorp/terraform/version"
|
|
)
|
|
|
|
func Test_migrate_tfc_to_tfc_single_workspace(t *testing.T) {
|
|
t.Parallel()
|
|
skipIfMissingEnvVar(t)
|
|
skipWithoutRemoteTerraformVersion(t)
|
|
|
|
ctx := context.Background()
|
|
|
|
cases := testCases{
|
|
"migrating from name to name": {
|
|
operations: []operationSets{
|
|
{
|
|
prep: func(t *testing.T, orgName, dir string) {
|
|
wsName := "prod"
|
|
// Creating the workspace here instead of it being created
|
|
// dynamically in the Cloud StateMgr because we want to ensure that
|
|
// the terraform version selected for the workspace matches the
|
|
// terraform version of this current branch.
|
|
_ = createWorkspace(t, orgName, tfe.WorkspaceCreateOptions{
|
|
Name: tfe.String("prod"),
|
|
TerraformVersion: tfe.String(tfversion.String()),
|
|
})
|
|
tfBlock := terraformConfigCloudBackendName(orgName, wsName)
|
|
writeMainTF(t, tfBlock, dir)
|
|
},
|
|
commands: []tfCommand{
|
|
{
|
|
command: []string{"init"},
|
|
expectedCmdOutput: `Terraform Cloud has been successfully initialized!`,
|
|
},
|
|
{
|
|
command: []string{"workspace", "show"},
|
|
expectedCmdOutput: `prod`, // this comes from the `prep` function
|
|
},
|
|
{
|
|
command: []string{"apply", "-auto-approve"},
|
|
postInputOutput: []string{`Apply complete!`},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
prep: func(t *testing.T, orgName, dir string) {
|
|
wsName := "dev"
|
|
_ = createWorkspace(t, orgName, tfe.WorkspaceCreateOptions{
|
|
Name: tfe.String(wsName),
|
|
TerraformVersion: tfe.String(tfversion.String()),
|
|
})
|
|
tfBlock := terraformConfigCloudBackendName(orgName, wsName)
|
|
writeMainTF(t, tfBlock, dir)
|
|
},
|
|
commands: []tfCommand{
|
|
{
|
|
command: []string{"init", "-ignore-remote-version"},
|
|
postInputOutput: []string{`Terraform Cloud has been successfully initialized!`},
|
|
},
|
|
{
|
|
command: []string{"workspace", "show"},
|
|
expectedCmdOutput: `dev`, // this comes from the `prep` function
|
|
},
|
|
},
|
|
},
|
|
},
|
|
validations: func(t *testing.T, orgName string) {
|
|
wsList, err := tfeClient.Workspaces.List(ctx, orgName, tfe.WorkspaceListOptions{})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
// this workspace name is what exists in the cloud backend configuration block
|
|
if len(wsList.Items) != 2 {
|
|
t.Fatal("Expected number of workspaces to be 2")
|
|
}
|
|
},
|
|
},
|
|
"migrating from name to tags": {
|
|
operations: []operationSets{
|
|
{
|
|
prep: func(t *testing.T, orgName, dir string) {
|
|
wsName := "prod"
|
|
_ = createWorkspace(t, orgName, tfe.WorkspaceCreateOptions{
|
|
Name: tfe.String("prod"),
|
|
TerraformVersion: tfe.String(tfversion.String()),
|
|
})
|
|
tfBlock := terraformConfigCloudBackendName(orgName, wsName)
|
|
writeMainTF(t, tfBlock, dir)
|
|
},
|
|
commands: []tfCommand{
|
|
{
|
|
command: []string{"init"},
|
|
expectedCmdOutput: `Terraform Cloud has been successfully initialized!`,
|
|
},
|
|
{
|
|
command: []string{"apply", "-auto-approve"},
|
|
postInputOutput: []string{`Apply complete!`},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
prep: func(t *testing.T, orgName, dir string) {
|
|
tag := "app"
|
|
tfBlock := terraformConfigCloudBackendTags(orgName, tag)
|
|
writeMainTF(t, tfBlock, dir)
|
|
},
|
|
commands: []tfCommand{
|
|
{
|
|
command: []string{"init", "-ignore-remote-version"},
|
|
expectedCmdOutput: `There are no workspaces with the configured tags (app)`,
|
|
userInput: []string{"new-workspace"},
|
|
postInputOutput: []string{
|
|
`Terraform can create a properly tagged workspace for you now.`,
|
|
`Terraform Cloud has been successfully initialized!`},
|
|
},
|
|
{
|
|
command: []string{"workspace", "show"},
|
|
expectedCmdOutput: `new-workspace`, // this comes from the `prep` function
|
|
},
|
|
},
|
|
},
|
|
},
|
|
validations: func(t *testing.T, orgName string) {
|
|
wsList, err := tfeClient.Workspaces.List(ctx, orgName, tfe.WorkspaceListOptions{
|
|
Tags: tfe.String("app"),
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
// this workspace name is what exists in the cloud backend configuration block
|
|
if len(wsList.Items) != 1 {
|
|
t.Fatal("Expected number of workspaces to be 1")
|
|
}
|
|
},
|
|
},
|
|
"migrating from name to tags without ignore-version flag": {
|
|
operations: []operationSets{
|
|
{
|
|
prep: func(t *testing.T, orgName, dir string) {
|
|
wsName := "prod"
|
|
_ = createWorkspace(t, orgName, tfe.WorkspaceCreateOptions{
|
|
Name: tfe.String("prod"),
|
|
TerraformVersion: tfe.String(tfversion.String()),
|
|
})
|
|
tfBlock := terraformConfigCloudBackendName(orgName, wsName)
|
|
writeMainTF(t, tfBlock, dir)
|
|
},
|
|
commands: []tfCommand{
|
|
{
|
|
command: []string{"init"},
|
|
expectedCmdOutput: `Terraform Cloud has been successfully initialized!`,
|
|
},
|
|
{
|
|
command: []string{"apply", "-auto-approve"},
|
|
postInputOutput: []string{`Apply complete!`},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
prep: func(t *testing.T, orgName, dir string) {
|
|
tag := "app"
|
|
// This is only here to ensure that the updated terraform version is
|
|
// present in the workspace, and it does not default to a lower
|
|
// version that does not support `cloud`.
|
|
_ = createWorkspace(t, orgName, tfe.WorkspaceCreateOptions{
|
|
Name: tfe.String("new-workspace"),
|
|
TerraformVersion: tfe.String(tfversion.String()),
|
|
})
|
|
tfBlock := terraformConfigCloudBackendTags(orgName, tag)
|
|
writeMainTF(t, tfBlock, dir)
|
|
},
|
|
commands: []tfCommand{
|
|
{
|
|
command: []string{"init"},
|
|
expectedCmdOutput: `There are no workspaces with the configured tags (app)`,
|
|
userInput: []string{"new-workspace"},
|
|
postInputOutput: []string{
|
|
`Terraform can create a properly tagged workspace for you now.`,
|
|
`Terraform Cloud has been successfully initialized!`},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
validations: func(t *testing.T, orgName string) {
|
|
// 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)
|
|
}
|
|
if ws.CurrentRun != nil {
|
|
t.Fatal("Expected to workspace be empty")
|
|
}
|
|
},
|
|
},
|
|
}
|
|
|
|
testRunner(t, cases, 1)
|
|
}
|
|
|
|
func Test_migrate_tfc_to_tfc_multiple_workspace(t *testing.T) {
|
|
t.Parallel()
|
|
skipIfMissingEnvVar(t)
|
|
skipWithoutRemoteTerraformVersion(t)
|
|
|
|
ctx := context.Background()
|
|
|
|
cases := testCases{
|
|
"migrating from multiple workspaces via tags to name": {
|
|
operations: []operationSets{
|
|
{
|
|
prep: func(t *testing.T, orgName, dir string) {
|
|
tag := "app"
|
|
_ = createWorkspace(t, orgName, tfe.WorkspaceCreateOptions{
|
|
Name: tfe.String("app-prod"),
|
|
Tags: []*tfe.Tag{{Name: tag}},
|
|
TerraformVersion: tfe.String(tfversion.String()),
|
|
})
|
|
_ = createWorkspace(t, orgName, tfe.WorkspaceCreateOptions{
|
|
Name: tfe.String("app-staging"),
|
|
Tags: []*tfe.Tag{{Name: tag}},
|
|
TerraformVersion: tfe.String(tfversion.String()),
|
|
})
|
|
tfBlock := terraformConfigCloudBackendTags(orgName, tag)
|
|
writeMainTF(t, tfBlock, dir)
|
|
},
|
|
commands: []tfCommand{
|
|
{
|
|
command: []string{"init"},
|
|
expectedCmdOutput: `The currently selected workspace (default) does not exist.`,
|
|
userInput: []string{"1"},
|
|
postInputOutput: []string{`Terraform Cloud has been successfully initialized!`},
|
|
},
|
|
{
|
|
command: []string{"apply"},
|
|
expectedCmdOutput: `Do you want to perform these actions in workspace "app-prod"?`,
|
|
userInput: []string{"yes"},
|
|
postInputOutput: []string{`Apply complete!`},
|
|
},
|
|
{
|
|
command: []string{"workspace", "select", "app-staging"},
|
|
expectedCmdOutput: `Switched to workspace "app-staging".`,
|
|
},
|
|
{
|
|
command: []string{"apply", "-auto-approve"},
|
|
postInputOutput: []string{`Apply complete!`},
|
|
},
|
|
{
|
|
command: []string{"output"},
|
|
expectedCmdOutput: `tag_val = "app"`,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
prep: func(t *testing.T, orgName, dir string) {
|
|
name := "service"
|
|
// Doing this here instead of relying on dynamic workspace creation
|
|
// because we want to set the terraform version here so that it is
|
|
// using the right version for post init operations.
|
|
_ = createWorkspace(t, orgName, tfe.WorkspaceCreateOptions{
|
|
Name: tfe.String(name),
|
|
TerraformVersion: tfe.String(tfversion.String()),
|
|
})
|
|
tfBlock := terraformConfigCloudBackendName(orgName, name)
|
|
writeMainTF(t, tfBlock, dir)
|
|
},
|
|
commands: []tfCommand{
|
|
{
|
|
command: []string{"init", "-ignore-remote-version"},
|
|
expectedCmdOutput: `Terraform Cloud has been successfully initialized!`,
|
|
postInputOutput: []string{`tag_val = "service"`},
|
|
},
|
|
{
|
|
command: []string{"workspace", "show"},
|
|
expectedCmdOutput: `service`, // this comes from the `prep` function
|
|
},
|
|
},
|
|
},
|
|
},
|
|
validations: func(t *testing.T, orgName string) {
|
|
ws, err := tfeClient.Workspaces.Read(ctx, orgName, "service")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if ws == nil {
|
|
t.Fatal("Expected to workspace not be empty")
|
|
}
|
|
},
|
|
},
|
|
"migrating from multiple workspaces via tags to other tags": {
|
|
operations: []operationSets{
|
|
{
|
|
prep: func(t *testing.T, orgName, dir string) {
|
|
tag := "app"
|
|
_ = createWorkspace(t, orgName, tfe.WorkspaceCreateOptions{
|
|
Name: tfe.String("app-prod"),
|
|
Tags: []*tfe.Tag{{Name: tag}},
|
|
TerraformVersion: tfe.String(tfversion.String()),
|
|
})
|
|
_ = createWorkspace(t, orgName, tfe.WorkspaceCreateOptions{
|
|
Name: tfe.String("app-staging"),
|
|
Tags: []*tfe.Tag{{Name: tag}},
|
|
TerraformVersion: tfe.String(tfversion.String()),
|
|
})
|
|
tfBlock := terraformConfigCloudBackendTags(orgName, tag)
|
|
writeMainTF(t, tfBlock, dir)
|
|
},
|
|
commands: []tfCommand{
|
|
{
|
|
command: []string{"init"},
|
|
expectedCmdOutput: `The currently selected workspace (default) does not exist.`,
|
|
userInput: []string{"1"},
|
|
postInputOutput: []string{`Terraform Cloud has been successfully initialized!`},
|
|
},
|
|
{
|
|
command: []string{"apply", "-auto-approve"},
|
|
expectedCmdOutput: `Apply complete!`,
|
|
},
|
|
{
|
|
command: []string{"workspace", "select", "app-staging"},
|
|
expectedCmdOutput: `Switched to workspace "app-staging".`,
|
|
},
|
|
{
|
|
command: []string{"apply", "-auto-approve"},
|
|
expectedCmdOutput: `Apply complete!`,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
prep: func(t *testing.T, orgName, dir string) {
|
|
tag := "billing"
|
|
tfBlock := terraformConfigCloudBackendTags(orgName, tag)
|
|
writeMainTF(t, tfBlock, dir)
|
|
},
|
|
commands: []tfCommand{
|
|
{
|
|
command: []string{"init", "-ignore-remote-version"},
|
|
expectedCmdOutput: `There are no workspaces with the configured tags (billing)`,
|
|
userInput: []string{"new-app-prod"},
|
|
postInputOutput: []string{`Terraform Cloud has been successfully initialized!`},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
validations: func(t *testing.T, orgName string) {
|
|
wsList, err := tfeClient.Workspaces.List(ctx, orgName, tfe.WorkspaceListOptions{
|
|
Tags: tfe.String("billing"),
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(wsList.Items) != 1 {
|
|
t.Logf("Expected the number of workspaces to be 2, but got %d", len(wsList.Items))
|
|
}
|
|
_, empty := getWorkspace(wsList.Items, "new-app-prod")
|
|
if empty {
|
|
t.Fatalf("expected workspaces to include 'new-app-prod' but didn't.")
|
|
}
|
|
},
|
|
},
|
|
}
|
|
|
|
testRunner(t, cases, 1)
|
|
}
|