Skip to content

Commit a08dfd2

Browse files
committed
WIP - updating tests, currently blocked
1 parent 529542d commit a08dfd2

File tree

2 files changed

+79
-19
lines changed

2 files changed

+79
-19
lines changed

internal/command/meta_backend_test.go

Lines changed: 62 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2073,18 +2073,41 @@ func Test_determineInitReason(t *testing.T) {
20732073
// Newly configured state store
20742074
// Working directory has state_store in config but no preexisting backend state file
20752075
func TestMetaBackend_configureNewStateStore(t *testing.T) {
2076-
20772076
cases := map[string]struct {
2077+
// setup
20782078
isInitCommand bool
2079-
expectedError string
2079+
2080+
inputEnabled bool
2081+
inputText string
2082+
2083+
createDefaultWorkspace bool
2084+
// assertions
2085+
expectedError string
2086+
expectDefaultWorkspaceExists bool
20802087
}{
2081-
"during an init command, the working directory is initialized and a backend state file is created": {
2082-
isInitCommand: true,
2088+
"an init command prompts users for input when the default workspace needs to be created": {
2089+
inputEnabled: true,
2090+
createDefaultWorkspace: true,
2091+
inputText: "yes",
2092+
isInitCommand: true,
2093+
expectDefaultWorkspaceExists: true,
2094+
},
2095+
"an init command with input disabled will create the default workspace automatically": {
2096+
inputEnabled: false,
2097+
createDefaultWorkspace: true,
2098+
isInitCommand: true,
2099+
expectDefaultWorkspaceExists: true,
20832100
},
2084-
"during a non-init command, the command ends in with an error telling the user to run an init command": {
2085-
isInitCommand: false,
2086-
expectedError: "State store initialization required, please run \"terraform init\": Reason: Initial configuration of the requested state_store \"foo_bar\" in provider foo (\"registry.terraform.io/my-org/foo\")",
2101+
"an init command with input disabled and the flag -create-default-workspace=false will not make the default workspace": {
2102+
inputEnabled: false,
2103+
createDefaultWorkspace: false,
2104+
isInitCommand: true,
2105+
expectDefaultWorkspaceExists: false,
20872106
},
2107+
// "during a non-init command, the command ends in with an error telling the user to run an init command": {
2108+
// isInitCommand: false,
2109+
// expectedError: "State store initialization required, please run \"terraform init\": Reason: Initial configuration of the requested state_store \"foo_bar\" in provider foo (\"registry.terraform.io/my-org/foo\")",
2110+
// },
20882111
}
20892112

20902113
for tn, tc := range cases {
@@ -2096,6 +2119,10 @@ func TestMetaBackend_configureNewStateStore(t *testing.T) {
20962119
// Setup the meta
20972120
m := testMetaBackend(t, nil)
20982121
m.AllowExperimentalFeatures = true
2122+
m.input = tc.inputEnabled
2123+
if tc.inputEnabled {
2124+
defer testInteractiveInput(t, []string{tc.inputText})()
2125+
}
20992126

21002127
// Get the state store's config
21012128
mod, loadDiags := m.loadSingleModule(td)
@@ -2133,6 +2160,8 @@ func TestMetaBackend_configureNewStateStore(t *testing.T) {
21332160
},
21342161
},
21352162
},
2163+
// TODO: Add logic that makes the call to WriteState create a workspace within
2164+
// the mock
21362165
}
21372166
factory := func() (providers.Interface, error) {
21382167
return mock, nil
@@ -2154,15 +2183,16 @@ func TestMetaBackend_configureNewStateStore(t *testing.T) {
21542183
)
21552184

21562185
// Act - get the operations backend
2157-
_, beDiags := m.Backend(&BackendOpts{
2158-
Init: tc.isInitCommand, // Changes with test case
2159-
StateStoreConfig: mod.StateStore,
2160-
ProviderFactory: factory,
2161-
Locks: locks,
2186+
b, beDiags := m.Backend(&BackendOpts{
2187+
Init: tc.isInitCommand, // Changes with test case
2188+
StateStoreConfig: mod.StateStore,
2189+
ProviderFactory: factory,
2190+
Locks: locks,
2191+
CreateDefaultWorkspace: tc.createDefaultWorkspace,
21622192
})
21632193
if beDiags.HasErrors() {
21642194
if tc.expectedError == "" {
2165-
t.Fatalf("unexpected error: %s", err)
2195+
t.Fatalf("unexpected error: %s", beDiags.Err())
21662196
}
21672197
if !strings.Contains(cleanString(beDiags.Err().Error()), tc.expectedError) {
21682198
t.Fatalf("expected error to contain %s, but instead got: %s", tc.expectedError, cleanString(beDiags.Err().Error()))
@@ -2196,6 +2226,25 @@ func TestMetaBackend_configureNewStateStore(t *testing.T) {
21962226
if cleanString(string(s.StateStore.ConfigRaw)) != expectedStoreConfig {
21972227
t.Fatalf("backend state file contains unexpected raw config data for the state store, want %q, got %q", expectedStoreConfig, cleanString(string(s.StateStore.ConfigRaw)))
21982228
}
2229+
2230+
w, err := b.Workspaces()
2231+
if err != nil {
2232+
t.Fatalf("unexpected error: %s", err)
2233+
}
2234+
if len(w) == 0 {
2235+
if tc.expectDefaultWorkspaceExists {
2236+
t.Fatal("expected the default workspace to exist, but there are no workspaces")
2237+
}
2238+
return
2239+
}
2240+
if len(w) > 0 {
2241+
if tc.expectDefaultWorkspaceExists {
2242+
if len(w) == 1 && w[0] != "default" {
2243+
t.Fatalf("expected the default workspace to exist, but instead got: %v", w)
2244+
}
2245+
}
2246+
t.Fatalf("expected the default workspace to be the only existing workspace, but instead got: %v", w)
2247+
}
21992248
})
22002249
}
22012250
}

internal/providers/testing/provider_mock.go

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,15 @@ package testing
55

66
import (
77
"fmt"
8+
"maps"
9+
"slices"
810
"sync"
911

1012
"github.com/zclconf/go-cty/cty"
1113
ctyjson "github.com/zclconf/go-cty/cty/json"
1214
"github.com/zclconf/go-cty/cty/msgpack"
1315

16+
"github.com/hashicorp/hcl/v2"
1417
"github.com/hashicorp/terraform/internal/configs/hcl2shim"
1518
"github.com/hashicorp/terraform/internal/providers"
1619
)
@@ -141,6 +144,9 @@ type MockProvider struct {
141144
ConfigureStateStoreRequest providers.ConfigureStateStoreRequest
142145
ConfigureStateStoreFn func(providers.ConfigureStateStoreRequest) providers.ConfigureStateStoreResponse
143146

147+
// states is an internal field that tracks which workspaces have been created in a test
148+
states map[string]interface{}
149+
144150
GetStatesCalled bool
145151
GetStatesResponse *providers.GetStatesResponse
146152
GetStatesRequest providers.GetStatesRequest
@@ -977,11 +983,8 @@ func (p *MockProvider) GetStates(r providers.GetStatesRequest) (resp providers.G
977983
return p.GetStatesFn(r)
978984
}
979985

980-
// If the mock has no further inputs, return an empty list.
981-
// The state store should be reporting a minimum of the default workspace usually,
982-
// but this should be achieved by querying data storage and identifying the artifact
983-
// for that workspace, and reporting that the workspace exists.
984-
resp.States = []string{}
986+
// If the mock has no further inputs, return the internal states list
987+
resp.States = slices.Sorted(maps.Keys(p.states))
985988

986989
return resp
987990
}
@@ -1008,7 +1011,15 @@ func (p *MockProvider) DeleteState(r providers.DeleteStateRequest) (resp provide
10081011
return p.DeleteStateFn(r)
10091012
}
10101013

1011-
// There's no logic we can include here in the absence of other fields on the mock.
1014+
if _, match := p.states[r.StateId]; match {
1015+
delete(p.states, r.StateId)
1016+
} else {
1017+
resp.Diagnostics.Append(&hcl.Diagnostic{
1018+
Severity: hcl.DiagError,
1019+
Summary: "Workspace cannot be deleted",
1020+
Detail: fmt.Sprintf("The workspace %q does not exist, so cannot be deleted", r.StateId),
1021+
})
1022+
}
10121023

10131024
// If the response contains no diagnostics then the deletion is assumed to be successful.
10141025
return resp

0 commit comments

Comments
 (0)