Skip to content

Commit 6d9442c

Browse files
committed
test: Add command-level test for state show showing integration with pluggable state storage code.
1 parent 25e27b4 commit 6d9442c

File tree

1 file changed

+82
-0
lines changed

1 file changed

+82
-0
lines changed

internal/command/state_show_test.go

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,16 @@
44
package command
55

66
import (
7+
"bytes"
78
"strings"
89
"testing"
910

11+
"github.com/hashicorp/cli"
1012
"github.com/hashicorp/terraform/internal/addrs"
1113
"github.com/hashicorp/terraform/internal/configs/configschema"
1214
"github.com/hashicorp/terraform/internal/providers"
1315
"github.com/hashicorp/terraform/internal/states"
16+
"github.com/hashicorp/terraform/internal/states/statefile"
1417
"github.com/hashicorp/terraform/internal/terminal"
1518
"github.com/zclconf/go-cty/cty"
1619
)
@@ -269,6 +272,85 @@ func TestStateShow_configured_provider(t *testing.T) {
269272
}
270273
}
271274

275+
// Tests using `terraform state show` subcommand in combination with pluggable state storage
276+
//
277+
// Note: Whereas other tests in this file use the local backend and require a state file in the test fixures,
278+
// with pluggable state storage we can define the state via the mocked provider.
279+
func TestStateShow_stateStore(t *testing.T) {
280+
// Create a temporary working directory that is empty
281+
td := t.TempDir()
282+
testCopyDir(t, testFixturePath("state-list-state-store"), td)
283+
t.Chdir(td)
284+
285+
// Get bytes describing a state containing a resource
286+
state := states.NewState()
287+
rootModule := state.RootModule()
288+
rootModule.SetResourceInstanceCurrent(
289+
addrs.Resource{
290+
Mode: addrs.ManagedResourceMode,
291+
Type: "test_instance",
292+
Name: "foo",
293+
}.Instance(addrs.NoKey),
294+
&states.ResourceInstanceObjectSrc{
295+
Status: states.ObjectReady,
296+
AttrsJSON: []byte(`{
297+
"input": "foobar"
298+
}`),
299+
},
300+
addrs.AbsProviderConfig{
301+
Provider: addrs.NewDefaultProvider("test"),
302+
Module: addrs.RootModule,
303+
},
304+
)
305+
var stateBuf bytes.Buffer
306+
if err := statefile.Write(statefile.New(state, "", 1), &stateBuf); err != nil {
307+
t.Fatalf("error during test setup: %s", err)
308+
}
309+
310+
// Create a mock that contains a persisted "default" state that uses the bytes from above.
311+
mockProvider := mockPluggableStateStorageProvider(t)
312+
mockProvider.MockStates = map[string]interface{}{
313+
"default": stateBuf.Bytes(),
314+
}
315+
mockProviderAddress := addrs.NewDefaultProvider("test")
316+
providerSource, close := newMockProviderSource(t, map[string][]string{
317+
"hashicorp/test": {"1.0.0"},
318+
})
319+
defer close()
320+
321+
ui := cli.NewMockUi()
322+
streams, done := terminal.StreamsForTesting(t)
323+
c := &StateShowCommand{
324+
Meta: Meta{
325+
AllowExperimentalFeatures: true,
326+
testingOverrides: &testingOverrides{
327+
Providers: map[addrs.Provider]providers.Factory{
328+
mockProviderAddress: providers.FactoryFixed(mockProvider),
329+
},
330+
},
331+
ProviderSource: providerSource,
332+
Ui: ui,
333+
Streams: streams,
334+
},
335+
}
336+
337+
// `terraform show` command specifying a given resource addr
338+
expectedResourceAddr := "test_instance.foo"
339+
args := []string{expectedResourceAddr}
340+
code := c.Run(args)
341+
output := done(t)
342+
if code != 0 {
343+
t.Fatalf("bad: %d\n\n%s", code, output.Stderr())
344+
}
345+
346+
// Test that outputs were displayed
347+
expected := "# test_instance.foo:\nresource \"test_instance\" \"foo\" {\n input = \"foobar\"\n}\n"
348+
actual := output.Stdout()
349+
if actual != expected {
350+
t.Fatalf("Expected:\n%q\n\nTo equal: %q", actual, expected)
351+
}
352+
}
353+
272354
const testStateShowOutput = `
273355
# test_instance.foo:
274356
resource "test_instance" "foo" {

0 commit comments

Comments
 (0)