|
4 | 4 | package command |
5 | 5 |
|
6 | 6 | import ( |
| 7 | + "bytes" |
7 | 8 | "strings" |
8 | 9 | "testing" |
9 | 10 |
|
| 11 | + "github.com/hashicorp/cli" |
10 | 12 | "github.com/hashicorp/terraform/internal/addrs" |
11 | 13 | "github.com/hashicorp/terraform/internal/configs/configschema" |
12 | 14 | "github.com/hashicorp/terraform/internal/providers" |
13 | 15 | "github.com/hashicorp/terraform/internal/states" |
| 16 | + "github.com/hashicorp/terraform/internal/states/statefile" |
14 | 17 | "github.com/hashicorp/terraform/internal/terminal" |
15 | 18 | "github.com/zclconf/go-cty/cty" |
16 | 19 | ) |
@@ -269,6 +272,85 @@ func TestStateShow_configured_provider(t *testing.T) { |
269 | 272 | } |
270 | 273 | } |
271 | 274 |
|
| 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 | + |
272 | 354 | const testStateShowOutput = ` |
273 | 355 | # test_instance.foo: |
274 | 356 | resource "test_instance" "foo" { |
|
0 commit comments