github.com/rstandt/terraform@v0.12.32-0.20230710220336-b1063613405c/command/state_show_test.go (about)

     1  package command
     2  
     3  import (
     4  	"strings"
     5  	"testing"
     6  
     7  	"github.com/hashicorp/terraform/addrs"
     8  	"github.com/hashicorp/terraform/configs/configschema"
     9  	"github.com/hashicorp/terraform/providers"
    10  	"github.com/hashicorp/terraform/states"
    11  	"github.com/hashicorp/terraform/terraform"
    12  	"github.com/mitchellh/cli"
    13  	"github.com/zclconf/go-cty/cty"
    14  )
    15  
    16  func TestStateShow(t *testing.T) {
    17  	state := states.BuildState(func(s *states.SyncState) {
    18  		s.SetResourceInstanceCurrent(
    19  			addrs.Resource{
    20  				Mode: addrs.ManagedResourceMode,
    21  				Type: "test_instance",
    22  				Name: "foo",
    23  			}.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance),
    24  			&states.ResourceInstanceObjectSrc{
    25  				AttrsJSON: []byte(`{"id":"bar","foo":"value","bar":"value"}`),
    26  				Status:    states.ObjectReady,
    27  			},
    28  			addrs.ProviderConfig{Type: addrs.NewLegacyProvider("test")}.Absolute(addrs.RootModuleInstance),
    29  		)
    30  	})
    31  	statePath := testStateFile(t, state)
    32  
    33  	p := testProvider()
    34  	p.GetSchemaReturn = &terraform.ProviderSchema{
    35  		ResourceTypes: map[string]*configschema.Block{
    36  			"test_instance": {
    37  				Attributes: map[string]*configschema.Attribute{
    38  					"id":  {Type: cty.String, Optional: true, Computed: true},
    39  					"foo": {Type: cty.String, Optional: true},
    40  					"bar": {Type: cty.String, Optional: true},
    41  				},
    42  			},
    43  		},
    44  	}
    45  
    46  	ui := new(cli.MockUi)
    47  	c := &StateShowCommand{
    48  		Meta: Meta{
    49  			testingOverrides: metaOverridesForProvider(p),
    50  			Ui:               ui,
    51  		},
    52  	}
    53  
    54  	args := []string{
    55  		"-state", statePath,
    56  		"test_instance.foo",
    57  	}
    58  	if code := c.Run(args); code != 0 {
    59  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
    60  	}
    61  
    62  	// Test that outputs were displayed
    63  	expected := strings.TrimSpace(testStateShowOutput) + "\n"
    64  	actual := ui.OutputWriter.String()
    65  	if actual != expected {
    66  		t.Fatalf("Expected:\n%q\n\nTo equal:\n%q", actual, expected)
    67  	}
    68  }
    69  
    70  func TestStateShow_multi(t *testing.T) {
    71  	submod, _ := addrs.ParseModuleInstanceStr("module.sub")
    72  	state := states.BuildState(func(s *states.SyncState) {
    73  		s.SetResourceInstanceCurrent(
    74  			addrs.Resource{
    75  				Mode: addrs.ManagedResourceMode,
    76  				Type: "test_instance",
    77  				Name: "foo",
    78  			}.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance),
    79  			&states.ResourceInstanceObjectSrc{
    80  				AttrsJSON: []byte(`{"id":"bar","foo":"value","bar":"value"}`),
    81  				Status:    states.ObjectReady,
    82  			},
    83  			addrs.ProviderConfig{Type: addrs.NewLegacyProvider("test")}.Absolute(addrs.RootModuleInstance),
    84  		)
    85  		s.SetResourceInstanceCurrent(
    86  			addrs.Resource{
    87  				Mode: addrs.ManagedResourceMode,
    88  				Type: "test_instance",
    89  				Name: "foo",
    90  			}.Instance(addrs.NoKey).Absolute(submod),
    91  			&states.ResourceInstanceObjectSrc{
    92  				AttrsJSON: []byte(`{"id":"foo","foo":"value","bar":"value"}`),
    93  				Status:    states.ObjectReady,
    94  			},
    95  			addrs.ProviderConfig{Type: addrs.NewLegacyProvider("test")}.Absolute(submod),
    96  		)
    97  	})
    98  	statePath := testStateFile(t, state)
    99  
   100  	p := testProvider()
   101  	p.GetSchemaReturn = &terraform.ProviderSchema{
   102  		ResourceTypes: map[string]*configschema.Block{
   103  			"test_instance": {
   104  				Attributes: map[string]*configschema.Attribute{
   105  					"id":  {Type: cty.String, Optional: true, Computed: true},
   106  					"foo": {Type: cty.String, Optional: true},
   107  					"bar": {Type: cty.String, Optional: true},
   108  				},
   109  			},
   110  		},
   111  	}
   112  
   113  	ui := new(cli.MockUi)
   114  	c := &StateShowCommand{
   115  		Meta: Meta{
   116  			testingOverrides: metaOverridesForProvider(p),
   117  			Ui:               ui,
   118  		},
   119  	}
   120  
   121  	args := []string{
   122  		"-state", statePath,
   123  		"test_instance.foo",
   124  	}
   125  	if code := c.Run(args); code != 0 {
   126  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
   127  	}
   128  
   129  	// Test that outputs were displayed
   130  	expected := strings.TrimSpace(testStateShowOutput) + "\n"
   131  	actual := ui.OutputWriter.String()
   132  	if actual != expected {
   133  		t.Fatalf("Expected:\n%q\n\nTo equal:\n%q", actual, expected)
   134  	}
   135  }
   136  
   137  func TestStateShow_noState(t *testing.T) {
   138  	tmp, cwd := testCwd(t)
   139  	defer testFixCwd(t, tmp, cwd)
   140  
   141  	p := testProvider()
   142  	ui := new(cli.MockUi)
   143  	c := &StateShowCommand{
   144  		Meta: Meta{
   145  			testingOverrides: metaOverridesForProvider(p),
   146  			Ui:               ui,
   147  		},
   148  	}
   149  
   150  	args := []string{
   151  		"test_instance.foo",
   152  	}
   153  	if code := c.Run(args); code != 1 {
   154  		t.Fatalf("bad: %d", code)
   155  	}
   156  	if !strings.Contains(ui.ErrorWriter.String(), "No state file was found!") {
   157  		t.Fatalf("expected a no state file error, got: %s", ui.ErrorWriter.String())
   158  	}
   159  }
   160  
   161  func TestStateShow_emptyState(t *testing.T) {
   162  	state := states.NewState()
   163  	statePath := testStateFile(t, state)
   164  
   165  	p := testProvider()
   166  	ui := new(cli.MockUi)
   167  	c := &StateShowCommand{
   168  		Meta: Meta{
   169  			testingOverrides: metaOverridesForProvider(p),
   170  			Ui:               ui,
   171  		},
   172  	}
   173  
   174  	args := []string{
   175  		"-state", statePath,
   176  		"test_instance.foo",
   177  	}
   178  	if code := c.Run(args); code != 1 {
   179  		t.Fatalf("bad: %d", code)
   180  	}
   181  	if !strings.Contains(ui.ErrorWriter.String(), "No instance found for the given address!") {
   182  		t.Fatalf("expected a no instance found error, got: %s", ui.ErrorWriter.String())
   183  	}
   184  }
   185  
   186  func TestStateShow_configured_provider(t *testing.T) {
   187  	state := states.BuildState(func(s *states.SyncState) {
   188  		s.SetResourceInstanceCurrent(
   189  			addrs.Resource{
   190  				Mode: addrs.ManagedResourceMode,
   191  				Type: "test_instance",
   192  				Name: "foo",
   193  			}.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance),
   194  			&states.ResourceInstanceObjectSrc{
   195  				AttrsJSON: []byte(`{"id":"bar","foo":"value","bar":"value"}`),
   196  				Status:    states.ObjectReady,
   197  			},
   198  			addrs.ProviderConfig{Type: addrs.NewLegacyProvider("test-beta")}.Absolute(addrs.RootModuleInstance),
   199  		)
   200  	})
   201  	statePath := testStateFile(t, state)
   202  
   203  	p := testProvider()
   204  	p.GetSchemaReturn = &terraform.ProviderSchema{
   205  		ResourceTypes: map[string]*configschema.Block{
   206  			"test_instance": {
   207  				Attributes: map[string]*configschema.Attribute{
   208  					"id":  {Type: cty.String, Optional: true, Computed: true},
   209  					"foo": {Type: cty.String, Optional: true},
   210  					"bar": {Type: cty.String, Optional: true},
   211  				},
   212  			},
   213  		},
   214  	}
   215  
   216  	ui := new(cli.MockUi)
   217  	c := &StateShowCommand{
   218  		Meta: Meta{
   219  			testingOverrides: &testingOverrides{
   220  				ProviderResolver: providers.ResolverFixed(
   221  					map[addrs.Provider]providers.Factory{
   222  						addrs.NewLegacyProvider("test-beta"): providers.FactoryFixed(p),
   223  					},
   224  				),
   225  			},
   226  			Ui: ui,
   227  		},
   228  	}
   229  
   230  	args := []string{
   231  		"-state", statePath,
   232  		"test_instance.foo",
   233  	}
   234  	if code := c.Run(args); code != 0 {
   235  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
   236  	}
   237  
   238  	// Test that outputs were displayed
   239  	expected := strings.TrimSpace(testStateShowOutput) + "\n"
   240  	actual := ui.OutputWriter.String()
   241  	if actual != expected {
   242  		t.Fatalf("Expected:\n%q\n\nTo equal:\n%q", actual, expected)
   243  	}
   244  }
   245  
   246  const testStateShowOutput = `
   247  # test_instance.foo:
   248  resource "test_instance" "foo" {
   249      bar = "value"
   250      foo = "value"
   251      id  = "bar"
   252  }
   253  `