2017-02-17 00:29:19 +01:00
|
|
|
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"
|
|
|
|
)
|
|
|
|
|
2017-05-31 00:06:13 +02:00
|
|
|
func TestWorkspace_createAndChange(t *testing.T) {
|
2017-02-17 00:29:19 +01:00
|
|
|
// Create a temporary working directory that is empty
|
|
|
|
td := tempDir(t)
|
|
|
|
os.MkdirAll(td, 0755)
|
|
|
|
defer os.RemoveAll(td)
|
|
|
|
defer testChdir(t, td)()
|
|
|
|
|
2017-05-31 00:06:13 +02:00
|
|
|
newCmd := &WorkspaceNewCommand{}
|
2017-02-17 00:29:19 +01:00
|
|
|
|
2017-05-31 02:13:43 +02:00
|
|
|
current := newCmd.Workspace()
|
2017-02-17 00:29:19 +01:00
|
|
|
if current != backend.DefaultStateName {
|
2017-05-31 00:06:13 +02:00
|
|
|
t.Fatal("current workspace should be 'default'")
|
2017-02-17 00:29:19 +01:00
|
|
|
}
|
|
|
|
|
2017-02-23 19:13:28 +01:00
|
|
|
args := []string{"test"}
|
2017-02-17 00:29:19 +01:00
|
|
|
ui := new(cli.MockUi)
|
2017-02-23 19:13:28 +01:00
|
|
|
newCmd.Meta = Meta{Ui: ui}
|
|
|
|
if code := newCmd.Run(args); code != 0 {
|
2017-02-17 00:29:19 +01:00
|
|
|
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter)
|
|
|
|
}
|
|
|
|
|
2017-05-31 02:13:43 +02:00
|
|
|
current = newCmd.Workspace()
|
2017-02-17 00:29:19 +01:00
|
|
|
if current != "test" {
|
2017-05-31 00:06:13 +02:00
|
|
|
t.Fatalf("current workspace should be 'test', got %q", current)
|
2017-02-17 00:29:19 +01:00
|
|
|
}
|
|
|
|
|
2017-05-31 00:06:13 +02:00
|
|
|
selCmd := &WorkspaceSelectCommand{}
|
2017-02-17 00:29:19 +01:00
|
|
|
args = []string{backend.DefaultStateName}
|
|
|
|
ui = new(cli.MockUi)
|
2017-02-23 19:13:28 +01:00
|
|
|
selCmd.Meta = Meta{Ui: ui}
|
|
|
|
if code := selCmd.Run(args); code != 0 {
|
2017-02-17 00:29:19 +01:00
|
|
|
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter)
|
|
|
|
}
|
|
|
|
|
2017-05-31 02:13:43 +02:00
|
|
|
current = newCmd.Workspace()
|
2017-02-17 00:29:19 +01:00
|
|
|
if current != backend.DefaultStateName {
|
2017-05-31 00:06:13 +02:00
|
|
|
t.Fatal("current workspace should be 'default'")
|
2017-02-17 00:29:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2017-05-31 00:06:13 +02:00
|
|
|
// Create some workspaces and test the list output.
|
2017-02-17 00:29:19 +01:00
|
|
|
// This also ensures we switch to the correct env after each call
|
2017-05-31 00:06:13 +02:00
|
|
|
func TestWorkspace_createAndList(t *testing.T) {
|
2017-02-17 00:29:19 +01:00
|
|
|
// Create a temporary working directory that is empty
|
|
|
|
td := tempDir(t)
|
|
|
|
os.MkdirAll(td, 0755)
|
|
|
|
defer os.RemoveAll(td)
|
|
|
|
defer testChdir(t, td)()
|
|
|
|
|
2017-03-04 00:19:56 +01:00
|
|
|
// make sure a vars file doesn't interfere
|
|
|
|
err := ioutil.WriteFile(
|
|
|
|
DefaultVarsFilename,
|
|
|
|
[]byte(`foo = "bar"`),
|
|
|
|
0644,
|
|
|
|
)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2017-05-31 00:06:13 +02:00
|
|
|
newCmd := &WorkspaceNewCommand{}
|
2017-02-17 00:29:19 +01:00
|
|
|
|
|
|
|
envs := []string{"test_a", "test_b", "test_c"}
|
|
|
|
|
2017-05-31 00:06:13 +02:00
|
|
|
// create multiple workspaces
|
2017-02-17 00:29:19 +01:00
|
|
|
for _, env := range envs {
|
|
|
|
ui := new(cli.MockUi)
|
2017-02-23 19:13:28 +01:00
|
|
|
newCmd.Meta = Meta{Ui: ui}
|
|
|
|
if code := newCmd.Run([]string{env}); code != 0 {
|
2017-02-17 00:29:19 +01:00
|
|
|
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-31 00:06:13 +02:00
|
|
|
listCmd := &WorkspaceListCommand{}
|
2017-02-17 00:29:19 +01:00
|
|
|
ui := new(cli.MockUi)
|
2017-02-23 19:13:28 +01:00
|
|
|
listCmd.Meta = Meta{Ui: ui}
|
2017-02-17 00:29:19 +01:00
|
|
|
|
2017-02-23 19:13:28 +01:00
|
|
|
if code := listCmd.Run(nil); code != 0 {
|
2017-02-17 00:29:19 +01:00
|
|
|
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter)
|
|
|
|
}
|
|
|
|
|
|
|
|
actual := strings.TrimSpace(ui.OutputWriter.String())
|
2017-02-23 19:13:28 +01:00
|
|
|
expected := "default\n test_a\n test_b\n* test_c"
|
|
|
|
|
2017-02-17 00:29:19 +01:00
|
|
|
if actual != expected {
|
|
|
|
t.Fatalf("\nexpcted: %q\nactual: %q", expected, actual)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-27 22:16:09 +02:00
|
|
|
// Don't allow names that aren't URL safe
|
2017-05-31 00:06:13 +02:00
|
|
|
func TestWorkspace_createInvalid(t *testing.T) {
|
2017-03-27 22:16:09 +02:00
|
|
|
// Create a temporary working directory that is empty
|
|
|
|
td := tempDir(t)
|
|
|
|
os.MkdirAll(td, 0755)
|
|
|
|
defer os.RemoveAll(td)
|
|
|
|
defer testChdir(t, td)()
|
|
|
|
|
2017-05-31 00:06:13 +02:00
|
|
|
newCmd := &WorkspaceNewCommand{}
|
2017-03-27 22:16:09 +02:00
|
|
|
|
|
|
|
envs := []string{"test_a*", "test_b/foo", "../../../test_c", "好_d"}
|
|
|
|
|
2017-05-31 00:06:13 +02:00
|
|
|
// create multiple workspaces
|
2017-03-27 22:16:09 +02:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-31 00:06:13 +02:00
|
|
|
// list workspaces to make sure none were created
|
|
|
|
listCmd := &WorkspaceListCommand{}
|
2017-03-27 22:16:09 +02:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-31 00:06:13 +02:00
|
|
|
func TestWorkspace_createWithState(t *testing.T) {
|
2017-02-17 00:29:19 +01:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
|
2017-02-23 19:13:28 +01:00
|
|
|
args := []string{"-state", "test.tfstate", "test"}
|
2017-02-17 00:29:19 +01:00
|
|
|
ui := new(cli.MockUi)
|
2017-05-31 00:06:13 +02:00
|
|
|
newCmd := &WorkspaceNewCommand{
|
2017-02-17 00:29:19 +01:00
|
|
|
Meta: Meta{Ui: ui},
|
|
|
|
}
|
2017-02-23 19:13:28 +01:00
|
|
|
if code := newCmd.Run(args); code != 0 {
|
2017-02-17 00:29:19 +01:00
|
|
|
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter)
|
|
|
|
}
|
|
|
|
|
2017-05-31 02:13:43 +02:00
|
|
|
newPath := filepath.Join(local.DefaultWorkspaceDir, "test", DefaultStateFilename)
|
2017-02-17 00:29:19 +01:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-31 00:06:13 +02:00
|
|
|
func TestWorkspace_delete(t *testing.T) {
|
2017-02-17 00:29:19 +01:00
|
|
|
td := tempDir(t)
|
|
|
|
os.MkdirAll(td, 0755)
|
|
|
|
defer os.RemoveAll(td)
|
|
|
|
defer testChdir(t, td)()
|
|
|
|
|
2017-05-31 00:06:13 +02:00
|
|
|
// create the workspace directories
|
2017-05-31 02:13:43 +02:00
|
|
|
if err := os.MkdirAll(filepath.Join(local.DefaultWorkspaceDir, "test"), 0755); err != nil {
|
2017-02-17 00:29:19 +01:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2017-05-31 00:06:13 +02:00
|
|
|
// create the workspace file
|
2017-02-17 00:29:19 +01:00
|
|
|
if err := os.MkdirAll(DefaultDataDir, 0755); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2017-05-31 02:13:43 +02:00
|
|
|
if err := ioutil.WriteFile(filepath.Join(DefaultDataDir, local.DefaultWorkspaceFile), []byte("test"), 0644); err != nil {
|
2017-02-17 00:29:19 +01:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2017-02-28 19:13:03 +01:00
|
|
|
ui := new(cli.MockUi)
|
2017-05-31 00:06:13 +02:00
|
|
|
delCmd := &WorkspaceDeleteCommand{
|
2017-02-28 19:13:03 +01:00
|
|
|
Meta: Meta{Ui: ui},
|
2017-02-17 00:29:19 +01:00
|
|
|
}
|
|
|
|
|
2017-05-31 02:13:43 +02:00
|
|
|
current := delCmd.Workspace()
|
2017-02-17 00:29:19 +01:00
|
|
|
if current != "test" {
|
2017-05-31 00:06:13 +02:00
|
|
|
t.Fatal("wrong workspace:", current)
|
2017-02-17 00:29:19 +01:00
|
|
|
}
|
|
|
|
|
2017-05-31 00:06:13 +02:00
|
|
|
// we can't delete our current workspace
|
2017-02-23 19:13:28 +01:00
|
|
|
args := []string{"test"}
|
2017-02-28 19:13:03 +01:00
|
|
|
if code := delCmd.Run(args); code == 0 {
|
2017-05-31 00:06:13 +02:00
|
|
|
t.Fatal("expected error deleting current workspace")
|
2017-02-17 00:29:19 +01:00
|
|
|
}
|
|
|
|
|
2017-02-28 19:13:03 +01:00
|
|
|
// change back to default
|
2017-05-31 02:13:43 +02:00
|
|
|
if err := delCmd.SetWorkspace(backend.DefaultStateName); err != nil {
|
2017-02-17 00:29:19 +01:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2017-02-28 19:13:03 +01:00
|
|
|
// try the delete again
|
|
|
|
ui = new(cli.MockUi)
|
|
|
|
delCmd.Meta.Ui = ui
|
|
|
|
if code := delCmd.Run(args); code != 0 {
|
2017-05-31 00:06:13 +02:00
|
|
|
t.Fatalf("error deleting workspace: %s", ui.ErrorWriter)
|
2017-02-28 19:13:03 +01:00
|
|
|
}
|
|
|
|
|
2017-05-31 02:13:43 +02:00
|
|
|
current = delCmd.Workspace()
|
2017-02-17 00:29:19 +01:00
|
|
|
if current != backend.DefaultStateName {
|
2017-05-31 00:06:13 +02:00
|
|
|
t.Fatalf("wrong workspace: %q", current)
|
2017-02-17 00:29:19 +01:00
|
|
|
}
|
|
|
|
}
|
2017-05-31 00:06:13 +02:00
|
|
|
func TestWorkspace_deleteWithState(t *testing.T) {
|
2017-02-17 00:29:19 +01:00
|
|
|
td := tempDir(t)
|
|
|
|
os.MkdirAll(td, 0755)
|
|
|
|
defer os.RemoveAll(td)
|
|
|
|
defer testChdir(t, td)()
|
|
|
|
|
2017-05-31 00:06:13 +02:00
|
|
|
// create the workspace directories
|
2017-05-31 02:13:43 +02:00
|
|
|
if err := os.MkdirAll(filepath.Join(local.DefaultWorkspaceDir, "test"), 0755); err != nil {
|
2017-02-17 00:29:19 +01:00
|
|
|
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",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2017-05-31 02:13:43 +02:00
|
|
|
envStatePath := filepath.Join(local.DefaultWorkspaceDir, "test", DefaultStateFilename)
|
2017-02-17 00:29:19 +01:00
|
|
|
err := (&state.LocalState{Path: envStatePath}).WriteState(originalState)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
ui := new(cli.MockUi)
|
2017-05-31 00:06:13 +02:00
|
|
|
delCmd := &WorkspaceDeleteCommand{
|
2017-02-17 00:29:19 +01:00
|
|
|
Meta: Meta{Ui: ui},
|
|
|
|
}
|
2017-02-23 19:13:28 +01:00
|
|
|
args := []string{"test"}
|
|
|
|
if code := delCmd.Run(args); code == 0 {
|
2017-02-17 00:29:19 +01:00
|
|
|
t.Fatalf("expected failure without -force.\noutput: %s", ui.OutputWriter)
|
|
|
|
}
|
|
|
|
|
|
|
|
ui = new(cli.MockUi)
|
2017-02-23 19:13:28 +01:00
|
|
|
delCmd.Meta.Ui = ui
|
2017-02-17 00:29:19 +01:00
|
|
|
|
2017-02-23 19:13:28 +01:00
|
|
|
args = []string{"-force", "test"}
|
|
|
|
if code := delCmd.Run(args); code != 0 {
|
2017-02-17 00:29:19 +01:00
|
|
|
t.Fatalf("failure: %s", ui.ErrorWriter)
|
|
|
|
}
|
|
|
|
|
2017-05-31 02:13:43 +02:00
|
|
|
if _, err := os.Stat(filepath.Join(local.DefaultWorkspaceDir, "test")); !os.IsNotExist(err) {
|
2017-02-17 00:29:19 +01:00
|
|
|
t.Fatal("env 'test' still exists!")
|
|
|
|
}
|
|
|
|
}
|