44package command
55
66import (
7+ "fmt"
78 "os"
89 "path/filepath"
910 "strings"
@@ -15,11 +16,159 @@ import (
1516 "github.com/hashicorp/terraform/internal/backend"
1617 "github.com/hashicorp/terraform/internal/backend/local"
1718 "github.com/hashicorp/terraform/internal/backend/remote-state/inmem"
19+ "github.com/hashicorp/terraform/internal/providers"
1820 "github.com/hashicorp/terraform/internal/states"
1921 "github.com/hashicorp/terraform/internal/states/statefile"
2022 "github.com/hashicorp/terraform/internal/states/statemgr"
2123)
2224
25+ func TestWorkspace_allCommands_pluggableStateStore (t * testing.T ) {
26+ // Create a temporary working directory with pluggable state storage in the config
27+ td := t .TempDir ()
28+ testCopyDir (t , testFixturePath ("state-store-new" ), td )
29+ t .Chdir (td )
30+
31+ mock := testStateStoreMockWithChunkNegotiation (t , 1000 )
32+ newMeta := func (provider providers.Interface ) (meta Meta , ui * cli.MockUi , close func ()) {
33+ // Assumes the mocked provider is hashicorp/test
34+ providerSource , close := newMockProviderSource (t , map [string ][]string {
35+ "hashicorp/test" : {"1.2.3" },
36+ })
37+
38+ ui = new (cli.MockUi )
39+ view , _ := testView (t )
40+ meta = Meta {
41+ AllowExperimentalFeatures : true ,
42+ Ui : ui ,
43+ View : view ,
44+ testingOverrides : & testingOverrides {
45+ Providers : map [addrs.Provider ]providers.Factory {
46+ addrs .NewDefaultProvider ("test" ): providers .FactoryFixed (mock ),
47+ },
48+ },
49+ ProviderSource : providerSource ,
50+ }
51+ return meta , ui , close
52+ }
53+
54+ //// Init
55+ meta , ui , close := newMeta (mock )
56+ defer close ()
57+ intCmd := & InitCommand {
58+ Meta : meta ,
59+ }
60+ args := []string {"-enable-pluggable-state-storage-experiment" } // Needed to test init changes for PSS project
61+ code := intCmd .Run (args )
62+ if code != 0 {
63+ t .Fatalf ("bad: %d\n \n %s\n %s" , code , ui .ErrorWriter , ui .OutputWriter )
64+ }
65+ // We expect a state to have been created for the default workspace
66+ if _ , ok := mock .MockStates ["default" ]; ! ok {
67+ t .Fatal ("expected the default workspace to exist, but it didn't" )
68+ }
69+
70+ //// Create Workspace
71+ newWorkspace := "foobar"
72+
73+ meta , ui , close = newMeta (mock )
74+ defer close ()
75+ newCmd := & WorkspaceNewCommand {
76+ Meta : meta ,
77+ }
78+
79+ current , _ := newCmd .Workspace ()
80+ if current != backend .DefaultStateName {
81+ t .Fatal ("before creating any custom workspaces, the current workspace should be 'default'" )
82+ }
83+
84+ args = []string {newWorkspace }
85+ code = newCmd .Run (args )
86+ if code != 0 {
87+ t .Fatalf ("bad: %d\n \n %s\n %s" , code , ui .ErrorWriter , ui .OutputWriter )
88+ }
89+ expectedMsg := fmt .Sprintf ("Created and switched to workspace %q!" , newWorkspace )
90+ if ! strings .Contains (ui .OutputWriter .String (), expectedMsg ) {
91+ t .Errorf ("unexpected output, expected %q, but got:\n %s" , expectedMsg , ui .OutputWriter )
92+ }
93+ // We expect a state to have been created for the new custom workspace
94+ if _ , ok := mock .MockStates [newWorkspace ]; ! ok {
95+ t .Fatalf ("expected the %s workspace to exist, but it didn't" , newWorkspace )
96+ }
97+ current , _ = newCmd .Workspace ()
98+ if current != newWorkspace {
99+ t .Fatalf ("current workspace should be %q, got %q" , newWorkspace , current )
100+ }
101+
102+ //// List Workspaces
103+ meta , ui , close = newMeta (mock )
104+ defer close ()
105+ listCmd := & WorkspaceListCommand {
106+ Meta : meta ,
107+ }
108+ args = []string {}
109+ code = listCmd .Run (args )
110+ if code != 0 {
111+ t .Fatalf ("bad: %d\n \n %s\n %s" , code , ui .ErrorWriter , ui .OutputWriter )
112+ }
113+ if ! strings .Contains (ui .OutputWriter .String (), newWorkspace ) {
114+ t .Errorf ("unexpected output, expected the new %q workspace to be listed present, but it's missing. Got:\n %s" , newWorkspace , ui .OutputWriter )
115+ }
116+
117+ //// Select Workspace
118+ meta , ui , close = newMeta (mock )
119+ defer close ()
120+ selCmd := & WorkspaceSelectCommand {
121+ Meta : meta ,
122+ }
123+ selectedWorkspace := backend .DefaultStateName
124+ args = []string {selectedWorkspace }
125+ code = selCmd .Run (args )
126+ if code != 0 {
127+ t .Fatalf ("bad: %d\n \n %s\n %s" , code , ui .ErrorWriter , ui .OutputWriter )
128+ }
129+ expectedMsg = fmt .Sprintf ("Switched to workspace %q." , selectedWorkspace )
130+ if ! strings .Contains (ui .OutputWriter .String (), expectedMsg ) {
131+ t .Errorf ("unexpected output, expected %q, but got:\n %s" , expectedMsg , ui .OutputWriter )
132+ }
133+
134+ //// Show Workspace
135+ meta , ui , close = newMeta (mock )
136+ defer close ()
137+ showCmd := & WorkspaceShowCommand {
138+ Meta : meta ,
139+ }
140+ args = []string {}
141+ code = showCmd .Run (args )
142+ if code != 0 {
143+ t .Fatalf ("bad: %d\n \n %s\n %s" , code , ui .ErrorWriter , ui .OutputWriter )
144+ }
145+ expectedMsg = fmt .Sprintf ("%s\n " , selectedWorkspace )
146+ if ! strings .Contains (ui .OutputWriter .String (), expectedMsg ) {
147+ t .Errorf ("unexpected output, expected %q, but got:\n %s" , expectedMsg , ui .OutputWriter )
148+ }
149+
150+ current , _ = newCmd .Workspace ()
151+ if current != backend .DefaultStateName {
152+ t .Fatal ("current workspace should be 'default'" )
153+ }
154+
155+ //// Delete Workspace
156+ meta , ui , close = newMeta (mock )
157+ defer close ()
158+ deleteCmd := & WorkspaceDeleteCommand {
159+ Meta : meta ,
160+ }
161+ args = []string {newWorkspace }
162+ code = deleteCmd .Run (args )
163+ if code != 0 {
164+ t .Fatalf ("bad: %d\n \n %s\n %s" , code , ui .ErrorWriter , ui .OutputWriter )
165+ }
166+ expectedMsg = fmt .Sprintf ("Deleted workspace %q!\n " , newWorkspace )
167+ if ! strings .Contains (ui .OutputWriter .String (), expectedMsg ) {
168+ t .Errorf ("unexpected output, expected %q, but got:\n %s" , expectedMsg , ui .OutputWriter )
169+ }
170+ }
171+
23172func TestWorkspace_createAndChange (t * testing.T ) {
24173 // Create a temporary working directory that is empty
25174 td := t .TempDir ()
0 commit comments