github.com/vic3lord/terraform@v0.8.0-rc1.0.20170626102919-16c6dd2cb372/command/workspace_command_test.go (about)

     1  package command
     2  
     3  import (
     4  	"io/ioutil"
     5  	"os"
     6  	"path/filepath"
     7  	"strings"
     8  	"testing"
     9  
    10  	"github.com/hashicorp/terraform/backend"
    11  	"github.com/hashicorp/terraform/backend/local"
    12  	"github.com/hashicorp/terraform/state"
    13  	"github.com/hashicorp/terraform/terraform"
    14  	"github.com/mitchellh/cli"
    15  )
    16  
    17  func TestWorkspace_createAndChange(t *testing.T) {
    18  	// Create a temporary working directory that is empty
    19  	td := tempDir(t)
    20  	os.MkdirAll(td, 0755)
    21  	defer os.RemoveAll(td)
    22  	defer testChdir(t, td)()
    23  
    24  	newCmd := &WorkspaceNewCommand{}
    25  
    26  	current := newCmd.Workspace()
    27  	if current != backend.DefaultStateName {
    28  		t.Fatal("current workspace should be 'default'")
    29  	}
    30  
    31  	args := []string{"test"}
    32  	ui := new(cli.MockUi)
    33  	newCmd.Meta = Meta{Ui: ui}
    34  	if code := newCmd.Run(args); code != 0 {
    35  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter)
    36  	}
    37  
    38  	current = newCmd.Workspace()
    39  	if current != "test" {
    40  		t.Fatalf("current workspace should be 'test', got %q", current)
    41  	}
    42  
    43  	selCmd := &WorkspaceSelectCommand{}
    44  	args = []string{backend.DefaultStateName}
    45  	ui = new(cli.MockUi)
    46  	selCmd.Meta = Meta{Ui: ui}
    47  	if code := selCmd.Run(args); code != 0 {
    48  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter)
    49  	}
    50  
    51  	current = newCmd.Workspace()
    52  	if current != backend.DefaultStateName {
    53  		t.Fatal("current workspace should be 'default'")
    54  	}
    55  
    56  }
    57  
    58  // Create some workspaces and test the list output.
    59  // This also ensures we switch to the correct env after each call
    60  func TestWorkspace_createAndList(t *testing.T) {
    61  	// Create a temporary working directory that is empty
    62  	td := tempDir(t)
    63  	os.MkdirAll(td, 0755)
    64  	defer os.RemoveAll(td)
    65  	defer testChdir(t, td)()
    66  
    67  	// make sure a vars file doesn't interfere
    68  	err := ioutil.WriteFile(
    69  		DefaultVarsFilename,
    70  		[]byte(`foo = "bar"`),
    71  		0644,
    72  	)
    73  	if err != nil {
    74  		t.Fatal(err)
    75  	}
    76  
    77  	newCmd := &WorkspaceNewCommand{}
    78  
    79  	envs := []string{"test_a", "test_b", "test_c"}
    80  
    81  	// create multiple workspaces
    82  	for _, env := range envs {
    83  		ui := new(cli.MockUi)
    84  		newCmd.Meta = Meta{Ui: ui}
    85  		if code := newCmd.Run([]string{env}); code != 0 {
    86  			t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter)
    87  		}
    88  	}
    89  
    90  	listCmd := &WorkspaceListCommand{}
    91  	ui := new(cli.MockUi)
    92  	listCmd.Meta = Meta{Ui: ui}
    93  
    94  	if code := listCmd.Run(nil); code != 0 {
    95  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter)
    96  	}
    97  
    98  	actual := strings.TrimSpace(ui.OutputWriter.String())
    99  	expected := "default\n  test_a\n  test_b\n* test_c"
   100  
   101  	if actual != expected {
   102  		t.Fatalf("\nexpcted: %q\nactual:  %q", expected, actual)
   103  	}
   104  }
   105  
   106  // Don't allow names that aren't URL safe
   107  func TestWorkspace_createInvalid(t *testing.T) {
   108  	// Create a temporary working directory that is empty
   109  	td := tempDir(t)
   110  	os.MkdirAll(td, 0755)
   111  	defer os.RemoveAll(td)
   112  	defer testChdir(t, td)()
   113  
   114  	newCmd := &WorkspaceNewCommand{}
   115  
   116  	envs := []string{"test_a*", "test_b/foo", "../../../test_c", "好_d"}
   117  
   118  	// create multiple workspaces
   119  	for _, env := range envs {
   120  		ui := new(cli.MockUi)
   121  		newCmd.Meta = Meta{Ui: ui}
   122  		if code := newCmd.Run([]string{env}); code == 0 {
   123  			t.Fatalf("expected failure: \n%s", ui.OutputWriter)
   124  		}
   125  	}
   126  
   127  	// list workspaces to make sure none were created
   128  	listCmd := &WorkspaceListCommand{}
   129  	ui := new(cli.MockUi)
   130  	listCmd.Meta = Meta{Ui: ui}
   131  
   132  	if code := listCmd.Run(nil); code != 0 {
   133  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter)
   134  	}
   135  
   136  	actual := strings.TrimSpace(ui.OutputWriter.String())
   137  	expected := "* default"
   138  
   139  	if actual != expected {
   140  		t.Fatalf("\nexpected: %q\nactual:  %q", expected, actual)
   141  	}
   142  }
   143  
   144  func TestWorkspace_createWithState(t *testing.T) {
   145  	td := tempDir(t)
   146  	os.MkdirAll(td, 0755)
   147  	defer os.RemoveAll(td)
   148  	defer testChdir(t, td)()
   149  
   150  	// create a non-empty state
   151  	originalState := &terraform.State{
   152  		Modules: []*terraform.ModuleState{
   153  			&terraform.ModuleState{
   154  				Path: []string{"root"},
   155  				Resources: map[string]*terraform.ResourceState{
   156  					"test_instance.foo": &terraform.ResourceState{
   157  						Type: "test_instance",
   158  						Primary: &terraform.InstanceState{
   159  							ID: "bar",
   160  						},
   161  					},
   162  				},
   163  			},
   164  		},
   165  	}
   166  
   167  	err := (&state.LocalState{Path: "test.tfstate"}).WriteState(originalState)
   168  	if err != nil {
   169  		t.Fatal(err)
   170  	}
   171  
   172  	args := []string{"-state", "test.tfstate", "test"}
   173  	ui := new(cli.MockUi)
   174  	newCmd := &WorkspaceNewCommand{
   175  		Meta: Meta{Ui: ui},
   176  	}
   177  	if code := newCmd.Run(args); code != 0 {
   178  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter)
   179  	}
   180  
   181  	newPath := filepath.Join(local.DefaultWorkspaceDir, "test", DefaultStateFilename)
   182  	envState := state.LocalState{Path: newPath}
   183  	err = envState.RefreshState()
   184  	if err != nil {
   185  		t.Fatal(err)
   186  	}
   187  
   188  	newState := envState.State()
   189  	if !originalState.Equal(newState) {
   190  		t.Fatalf("states not equal\norig: %s\nnew: %s", originalState, newState)
   191  	}
   192  }
   193  
   194  func TestWorkspace_delete(t *testing.T) {
   195  	td := tempDir(t)
   196  	os.MkdirAll(td, 0755)
   197  	defer os.RemoveAll(td)
   198  	defer testChdir(t, td)()
   199  
   200  	// create the workspace directories
   201  	if err := os.MkdirAll(filepath.Join(local.DefaultWorkspaceDir, "test"), 0755); err != nil {
   202  		t.Fatal(err)
   203  	}
   204  
   205  	// create the workspace file
   206  	if err := os.MkdirAll(DefaultDataDir, 0755); err != nil {
   207  		t.Fatal(err)
   208  	}
   209  	if err := ioutil.WriteFile(filepath.Join(DefaultDataDir, local.DefaultWorkspaceFile), []byte("test"), 0644); err != nil {
   210  		t.Fatal(err)
   211  	}
   212  
   213  	ui := new(cli.MockUi)
   214  	delCmd := &WorkspaceDeleteCommand{
   215  		Meta: Meta{Ui: ui},
   216  	}
   217  
   218  	current := delCmd.Workspace()
   219  	if current != "test" {
   220  		t.Fatal("wrong workspace:", current)
   221  	}
   222  
   223  	// we can't delete our current workspace
   224  	args := []string{"test"}
   225  	if code := delCmd.Run(args); code == 0 {
   226  		t.Fatal("expected error deleting current workspace")
   227  	}
   228  
   229  	// change back to default
   230  	if err := delCmd.SetWorkspace(backend.DefaultStateName); err != nil {
   231  		t.Fatal(err)
   232  	}
   233  
   234  	// try the delete again
   235  	ui = new(cli.MockUi)
   236  	delCmd.Meta.Ui = ui
   237  	if code := delCmd.Run(args); code != 0 {
   238  		t.Fatalf("error deleting workspace: %s", ui.ErrorWriter)
   239  	}
   240  
   241  	current = delCmd.Workspace()
   242  	if current != backend.DefaultStateName {
   243  		t.Fatalf("wrong workspace: %q", current)
   244  	}
   245  }
   246  func TestWorkspace_deleteWithState(t *testing.T) {
   247  	td := tempDir(t)
   248  	os.MkdirAll(td, 0755)
   249  	defer os.RemoveAll(td)
   250  	defer testChdir(t, td)()
   251  
   252  	// create the workspace directories
   253  	if err := os.MkdirAll(filepath.Join(local.DefaultWorkspaceDir, "test"), 0755); err != nil {
   254  		t.Fatal(err)
   255  	}
   256  
   257  	// create a non-empty state
   258  	originalState := &terraform.State{
   259  		Modules: []*terraform.ModuleState{
   260  			&terraform.ModuleState{
   261  				Path: []string{"root"},
   262  				Resources: map[string]*terraform.ResourceState{
   263  					"test_instance.foo": &terraform.ResourceState{
   264  						Type: "test_instance",
   265  						Primary: &terraform.InstanceState{
   266  							ID: "bar",
   267  						},
   268  					},
   269  				},
   270  			},
   271  		},
   272  	}
   273  
   274  	envStatePath := filepath.Join(local.DefaultWorkspaceDir, "test", DefaultStateFilename)
   275  	err := (&state.LocalState{Path: envStatePath}).WriteState(originalState)
   276  	if err != nil {
   277  		t.Fatal(err)
   278  	}
   279  
   280  	ui := new(cli.MockUi)
   281  	delCmd := &WorkspaceDeleteCommand{
   282  		Meta: Meta{Ui: ui},
   283  	}
   284  	args := []string{"test"}
   285  	if code := delCmd.Run(args); code == 0 {
   286  		t.Fatalf("expected failure without -force.\noutput: %s", ui.OutputWriter)
   287  	}
   288  
   289  	ui = new(cli.MockUi)
   290  	delCmd.Meta.Ui = ui
   291  
   292  	args = []string{"-force", "test"}
   293  	if code := delCmd.Run(args); code != 0 {
   294  		t.Fatalf("failure: %s", ui.ErrorWriter)
   295  	}
   296  
   297  	if _, err := os.Stat(filepath.Join(local.DefaultWorkspaceDir, "test")); !os.IsNotExist(err) {
   298  		t.Fatal("env 'test' still exists!")
   299  	}
   300  }