mirror of
https://github.com/opentofu/opentofu.git
synced 2025-01-02 04:07:22 -06:00
418a8a8bc9
We're shifting terminology from "environment" to "workspace". This takes care of some of the main internal API surface that was using the old terminology, though is not intended to be entirely comprehensive and is mainly just to minimize the amount of confusion for maintainers as we continue moving towards eliminating the old terminology.
301 lines
7.2 KiB
Go
301 lines
7.2 KiB
Go
package command
|
|
|
|
import (
|
|
"io/ioutil"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/hashicorp/terraform/backend"
|
|
"github.com/hashicorp/terraform/backend/local"
|
|
"github.com/hashicorp/terraform/state"
|
|
"github.com/hashicorp/terraform/terraform"
|
|
"github.com/mitchellh/cli"
|
|
)
|
|
|
|
func TestWorkspace_createAndChange(t *testing.T) {
|
|
// Create a temporary working directory that is empty
|
|
td := tempDir(t)
|
|
os.MkdirAll(td, 0755)
|
|
defer os.RemoveAll(td)
|
|
defer testChdir(t, td)()
|
|
|
|
newCmd := &WorkspaceNewCommand{}
|
|
|
|
current := newCmd.Workspace()
|
|
if current != backend.DefaultStateName {
|
|
t.Fatal("current workspace should be 'default'")
|
|
}
|
|
|
|
args := []string{"test"}
|
|
ui := new(cli.MockUi)
|
|
newCmd.Meta = Meta{Ui: ui}
|
|
if code := newCmd.Run(args); code != 0 {
|
|
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter)
|
|
}
|
|
|
|
current = newCmd.Workspace()
|
|
if current != "test" {
|
|
t.Fatalf("current workspace should be 'test', got %q", current)
|
|
}
|
|
|
|
selCmd := &WorkspaceSelectCommand{}
|
|
args = []string{backend.DefaultStateName}
|
|
ui = new(cli.MockUi)
|
|
selCmd.Meta = Meta{Ui: ui}
|
|
if code := selCmd.Run(args); code != 0 {
|
|
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter)
|
|
}
|
|
|
|
current = newCmd.Workspace()
|
|
if current != backend.DefaultStateName {
|
|
t.Fatal("current workspace should be 'default'")
|
|
}
|
|
|
|
}
|
|
|
|
// Create some workspaces and test the list output.
|
|
// This also ensures we switch to the correct env after each call
|
|
func TestWorkspace_createAndList(t *testing.T) {
|
|
// Create a temporary working directory that is empty
|
|
td := tempDir(t)
|
|
os.MkdirAll(td, 0755)
|
|
defer os.RemoveAll(td)
|
|
defer testChdir(t, td)()
|
|
|
|
// make sure a vars file doesn't interfere
|
|
err := ioutil.WriteFile(
|
|
DefaultVarsFilename,
|
|
[]byte(`foo = "bar"`),
|
|
0644,
|
|
)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
newCmd := &WorkspaceNewCommand{}
|
|
|
|
envs := []string{"test_a", "test_b", "test_c"}
|
|
|
|
// create multiple workspaces
|
|
for _, env := range envs {
|
|
ui := new(cli.MockUi)
|
|
newCmd.Meta = Meta{Ui: ui}
|
|
if code := newCmd.Run([]string{env}); code != 0 {
|
|
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter)
|
|
}
|
|
}
|
|
|
|
listCmd := &WorkspaceListCommand{}
|
|
ui := new(cli.MockUi)
|
|
listCmd.Meta = Meta{Ui: ui}
|
|
|
|
if code := listCmd.Run(nil); code != 0 {
|
|
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter)
|
|
}
|
|
|
|
actual := strings.TrimSpace(ui.OutputWriter.String())
|
|
expected := "default\n test_a\n test_b\n* test_c"
|
|
|
|
if actual != expected {
|
|
t.Fatalf("\nexpcted: %q\nactual: %q", expected, actual)
|
|
}
|
|
}
|
|
|
|
// Don't allow names that aren't URL safe
|
|
func TestWorkspace_createInvalid(t *testing.T) {
|
|
// Create a temporary working directory that is empty
|
|
td := tempDir(t)
|
|
os.MkdirAll(td, 0755)
|
|
defer os.RemoveAll(td)
|
|
defer testChdir(t, td)()
|
|
|
|
newCmd := &WorkspaceNewCommand{}
|
|
|
|
envs := []string{"test_a*", "test_b/foo", "../../../test_c", "好_d"}
|
|
|
|
// create multiple workspaces
|
|
for _, env := range envs {
|
|
ui := new(cli.MockUi)
|
|
newCmd.Meta = Meta{Ui: ui}
|
|
if code := newCmd.Run([]string{env}); code == 0 {
|
|
t.Fatalf("expected failure: \n%s", ui.OutputWriter)
|
|
}
|
|
}
|
|
|
|
// list workspaces to make sure none were created
|
|
listCmd := &WorkspaceListCommand{}
|
|
ui := new(cli.MockUi)
|
|
listCmd.Meta = Meta{Ui: ui}
|
|
|
|
if code := listCmd.Run(nil); code != 0 {
|
|
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter)
|
|
}
|
|
|
|
actual := strings.TrimSpace(ui.OutputWriter.String())
|
|
expected := "* default"
|
|
|
|
if actual != expected {
|
|
t.Fatalf("\nexpected: %q\nactual: %q", expected, actual)
|
|
}
|
|
}
|
|
|
|
func TestWorkspace_createWithState(t *testing.T) {
|
|
td := tempDir(t)
|
|
os.MkdirAll(td, 0755)
|
|
defer os.RemoveAll(td)
|
|
defer testChdir(t, td)()
|
|
|
|
// create a non-empty state
|
|
originalState := &terraform.State{
|
|
Modules: []*terraform.ModuleState{
|
|
&terraform.ModuleState{
|
|
Path: []string{"root"},
|
|
Resources: map[string]*terraform.ResourceState{
|
|
"test_instance.foo": &terraform.ResourceState{
|
|
Type: "test_instance",
|
|
Primary: &terraform.InstanceState{
|
|
ID: "bar",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
err := (&state.LocalState{Path: "test.tfstate"}).WriteState(originalState)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
args := []string{"-state", "test.tfstate", "test"}
|
|
ui := new(cli.MockUi)
|
|
newCmd := &WorkspaceNewCommand{
|
|
Meta: Meta{Ui: ui},
|
|
}
|
|
if code := newCmd.Run(args); code != 0 {
|
|
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter)
|
|
}
|
|
|
|
newPath := filepath.Join(local.DefaultWorkspaceDir, "test", DefaultStateFilename)
|
|
envState := state.LocalState{Path: newPath}
|
|
err = envState.RefreshState()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
newState := envState.State()
|
|
if !originalState.Equal(newState) {
|
|
t.Fatalf("states not equal\norig: %s\nnew: %s", originalState, newState)
|
|
}
|
|
}
|
|
|
|
func TestWorkspace_delete(t *testing.T) {
|
|
td := tempDir(t)
|
|
os.MkdirAll(td, 0755)
|
|
defer os.RemoveAll(td)
|
|
defer testChdir(t, td)()
|
|
|
|
// create the workspace directories
|
|
if err := os.MkdirAll(filepath.Join(local.DefaultWorkspaceDir, "test"), 0755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// create the workspace file
|
|
if err := os.MkdirAll(DefaultDataDir, 0755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := ioutil.WriteFile(filepath.Join(DefaultDataDir, local.DefaultWorkspaceFile), []byte("test"), 0644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
ui := new(cli.MockUi)
|
|
delCmd := &WorkspaceDeleteCommand{
|
|
Meta: Meta{Ui: ui},
|
|
}
|
|
|
|
current := delCmd.Workspace()
|
|
if current != "test" {
|
|
t.Fatal("wrong workspace:", current)
|
|
}
|
|
|
|
// we can't delete our current workspace
|
|
args := []string{"test"}
|
|
if code := delCmd.Run(args); code == 0 {
|
|
t.Fatal("expected error deleting current workspace")
|
|
}
|
|
|
|
// change back to default
|
|
if err := delCmd.SetWorkspace(backend.DefaultStateName); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// try the delete again
|
|
ui = new(cli.MockUi)
|
|
delCmd.Meta.Ui = ui
|
|
if code := delCmd.Run(args); code != 0 {
|
|
t.Fatalf("error deleting workspace: %s", ui.ErrorWriter)
|
|
}
|
|
|
|
current = delCmd.Workspace()
|
|
if current != backend.DefaultStateName {
|
|
t.Fatalf("wrong workspace: %q", current)
|
|
}
|
|
}
|
|
func TestWorkspace_deleteWithState(t *testing.T) {
|
|
td := tempDir(t)
|
|
os.MkdirAll(td, 0755)
|
|
defer os.RemoveAll(td)
|
|
defer testChdir(t, td)()
|
|
|
|
// create the workspace directories
|
|
if err := os.MkdirAll(filepath.Join(local.DefaultWorkspaceDir, "test"), 0755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// create a non-empty state
|
|
originalState := &terraform.State{
|
|
Modules: []*terraform.ModuleState{
|
|
&terraform.ModuleState{
|
|
Path: []string{"root"},
|
|
Resources: map[string]*terraform.ResourceState{
|
|
"test_instance.foo": &terraform.ResourceState{
|
|
Type: "test_instance",
|
|
Primary: &terraform.InstanceState{
|
|
ID: "bar",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
envStatePath := filepath.Join(local.DefaultWorkspaceDir, "test", DefaultStateFilename)
|
|
err := (&state.LocalState{Path: envStatePath}).WriteState(originalState)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
ui := new(cli.MockUi)
|
|
delCmd := &WorkspaceDeleteCommand{
|
|
Meta: Meta{Ui: ui},
|
|
}
|
|
args := []string{"test"}
|
|
if code := delCmd.Run(args); code == 0 {
|
|
t.Fatalf("expected failure without -force.\noutput: %s", ui.OutputWriter)
|
|
}
|
|
|
|
ui = new(cli.MockUi)
|
|
delCmd.Meta.Ui = ui
|
|
|
|
args = []string{"-force", "test"}
|
|
if code := delCmd.Run(args); code != 0 {
|
|
t.Fatalf("failure: %s", ui.ErrorWriter)
|
|
}
|
|
|
|
if _, err := os.Stat(filepath.Join(local.DefaultWorkspaceDir, "test")); !os.IsNotExist(err) {
|
|
t.Fatal("env 'test' still exists!")
|
|
}
|
|
}
|