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

     1  package command
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"fmt"
     7  	"io/ioutil"
     8  	"os"
     9  	"path/filepath"
    10  	"reflect"
    11  	"strings"
    12  	"testing"
    13  
    14  	"github.com/davecgh/go-spew/spew"
    15  	"github.com/google/go-cmp/cmp"
    16  	"github.com/google/go-cmp/cmp/cmpopts"
    17  	"github.com/mitchellh/cli"
    18  	"github.com/zclconf/go-cty/cty"
    19  
    20  	"github.com/hashicorp/terraform/addrs"
    21  	"github.com/hashicorp/terraform/configs/configschema"
    22  	"github.com/hashicorp/terraform/helper/copy"
    23  	"github.com/hashicorp/terraform/providers"
    24  	"github.com/hashicorp/terraform/states"
    25  	"github.com/hashicorp/terraform/states/statefile"
    26  	"github.com/hashicorp/terraform/states/statemgr"
    27  	"github.com/hashicorp/terraform/terraform"
    28  )
    29  
    30  var equateEmpty = cmpopts.EquateEmpty()
    31  
    32  func TestRefresh(t *testing.T) {
    33  	state := testState()
    34  	statePath := testStateFile(t, state)
    35  
    36  	p := testProvider()
    37  	ui := new(cli.MockUi)
    38  	c := &RefreshCommand{
    39  		Meta: Meta{
    40  			testingOverrides: metaOverridesForProvider(p),
    41  			Ui:               ui,
    42  		},
    43  	}
    44  
    45  	p.GetSchemaReturn = refreshFixtureSchema()
    46  	p.ReadResourceFn = nil
    47  	p.ReadResourceResponse = providers.ReadResourceResponse{
    48  		NewState: cty.ObjectVal(map[string]cty.Value{
    49  			"id": cty.StringVal("yes"),
    50  		}),
    51  	}
    52  
    53  	args := []string{
    54  		"-state", statePath,
    55  		testFixturePath("refresh"),
    56  	}
    57  	if code := c.Run(args); code != 0 {
    58  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
    59  	}
    60  
    61  	if !p.ReadResourceCalled {
    62  		t.Fatal("ReadResource should have been called")
    63  	}
    64  
    65  	f, err := os.Open(statePath)
    66  	if err != nil {
    67  		t.Fatalf("err: %s", err)
    68  	}
    69  
    70  	newStateFile, err := statefile.Read(f)
    71  	f.Close()
    72  	if err != nil {
    73  		t.Fatalf("err: %s", err)
    74  	}
    75  
    76  	actual := strings.TrimSpace(newStateFile.State.String())
    77  	expected := strings.TrimSpace(testRefreshStr)
    78  	if actual != expected {
    79  		t.Fatalf("bad:\n\n%s", actual)
    80  	}
    81  }
    82  
    83  func TestRefresh_empty(t *testing.T) {
    84  	// Create a temporary working directory that is empty
    85  	td := tempDir(t)
    86  	copy.CopyDir(testFixturePath("refresh-empty"), td)
    87  	defer os.RemoveAll(td)
    88  	defer testChdir(t, td)()
    89  
    90  	p := testProvider()
    91  	ui := new(cli.MockUi)
    92  	c := &RefreshCommand{
    93  		Meta: Meta{
    94  			testingOverrides: metaOverridesForProvider(p),
    95  			Ui:               ui,
    96  		},
    97  	}
    98  
    99  	p.ReadResourceFn = nil
   100  	p.ReadResourceResponse = providers.ReadResourceResponse{
   101  		NewState: cty.ObjectVal(map[string]cty.Value{
   102  			"id": cty.StringVal("yes"),
   103  		}),
   104  	}
   105  
   106  	args := []string{
   107  		td,
   108  	}
   109  	if code := c.Run(args); code != 0 {
   110  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
   111  	}
   112  
   113  	if p.ReadResourceCalled {
   114  		t.Fatal("ReadResource should not have been called")
   115  	}
   116  }
   117  
   118  func TestRefresh_lockedState(t *testing.T) {
   119  	state := testState()
   120  	statePath := testStateFile(t, state)
   121  
   122  	unlock, err := testLockState(testDataDir, statePath)
   123  	if err != nil {
   124  		t.Fatal(err)
   125  	}
   126  	defer unlock()
   127  
   128  	p := testProvider()
   129  	ui := new(cli.MockUi)
   130  	c := &RefreshCommand{
   131  		Meta: Meta{
   132  			testingOverrides: metaOverridesForProvider(p),
   133  			Ui:               ui,
   134  		},
   135  	}
   136  
   137  	p.GetSchemaReturn = refreshFixtureSchema()
   138  	p.ReadResourceFn = nil
   139  	p.ReadResourceResponse = providers.ReadResourceResponse{
   140  		NewState: cty.ObjectVal(map[string]cty.Value{
   141  			"id": cty.StringVal("yes"),
   142  		}),
   143  	}
   144  
   145  	args := []string{
   146  		"-state", statePath,
   147  		testFixturePath("refresh"),
   148  	}
   149  
   150  	if code := c.Run(args); code == 0 {
   151  		t.Fatal("expected error")
   152  	}
   153  
   154  	output := ui.ErrorWriter.String()
   155  	if !strings.Contains(output, "lock") {
   156  		t.Fatal("command output does not look like a lock error:", output)
   157  	}
   158  }
   159  
   160  func TestRefresh_cwd(t *testing.T) {
   161  	cwd, err := os.Getwd()
   162  	if err != nil {
   163  		t.Fatalf("err: %s", err)
   164  	}
   165  	if err := os.Chdir(testFixturePath("refresh")); err != nil {
   166  		t.Fatalf("err: %s", err)
   167  	}
   168  	defer os.Chdir(cwd)
   169  
   170  	state := testState()
   171  	statePath := testStateFile(t, state)
   172  
   173  	p := testProvider()
   174  	ui := new(cli.MockUi)
   175  	c := &RefreshCommand{
   176  		Meta: Meta{
   177  			testingOverrides: metaOverridesForProvider(p),
   178  			Ui:               ui,
   179  		},
   180  	}
   181  
   182  	p.GetSchemaReturn = refreshFixtureSchema()
   183  	p.ReadResourceFn = nil
   184  	p.ReadResourceResponse = providers.ReadResourceResponse{
   185  		NewState: cty.ObjectVal(map[string]cty.Value{
   186  			"id": cty.StringVal("yes"),
   187  		}),
   188  	}
   189  
   190  	args := []string{
   191  		"-state", statePath,
   192  	}
   193  	if code := c.Run(args); code != 0 {
   194  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
   195  	}
   196  
   197  	if !p.ReadResourceCalled {
   198  		t.Fatal("ReadResource should have been called")
   199  	}
   200  
   201  	f, err := os.Open(statePath)
   202  	if err != nil {
   203  		t.Fatalf("err: %s", err)
   204  	}
   205  
   206  	newStateFile, err := statefile.Read(f)
   207  	f.Close()
   208  	if err != nil {
   209  		t.Fatalf("err: %s", err)
   210  	}
   211  
   212  	actual := strings.TrimSpace(newStateFile.State.String())
   213  	expected := strings.TrimSpace(testRefreshCwdStr)
   214  	if actual != expected {
   215  		t.Fatalf("bad:\n\n%s", actual)
   216  	}
   217  }
   218  
   219  func TestRefresh_defaultState(t *testing.T) {
   220  	originalState := testState()
   221  
   222  	// Write the state file in a temporary directory with the
   223  	// default filename.
   224  	statePath := testStateFile(t, originalState)
   225  
   226  	localState := statemgr.NewFilesystem(statePath)
   227  	if err := localState.RefreshState(); err != nil {
   228  		t.Fatal(err)
   229  	}
   230  	s := localState.State()
   231  	if s == nil {
   232  		t.Fatal("empty test state")
   233  	}
   234  
   235  	// Change to that directory
   236  	cwd, err := os.Getwd()
   237  	if err != nil {
   238  		t.Fatalf("err: %s", err)
   239  	}
   240  	if err := os.Chdir(filepath.Dir(statePath)); err != nil {
   241  		t.Fatalf("err: %s", err)
   242  	}
   243  	defer os.Chdir(cwd)
   244  
   245  	p := testProvider()
   246  	ui := new(cli.MockUi)
   247  	c := &RefreshCommand{
   248  		Meta: Meta{
   249  			testingOverrides: metaOverridesForProvider(p),
   250  			Ui:               ui,
   251  		},
   252  	}
   253  
   254  	p.GetSchemaReturn = refreshFixtureSchema()
   255  	p.ReadResourceFn = nil
   256  	p.ReadResourceResponse = providers.ReadResourceResponse{
   257  		NewState: cty.ObjectVal(map[string]cty.Value{
   258  			"id": cty.StringVal("yes"),
   259  		}),
   260  	}
   261  
   262  	args := []string{
   263  		"-state", statePath,
   264  		testFixturePath("refresh"),
   265  	}
   266  	if code := c.Run(args); code != 0 {
   267  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
   268  	}
   269  
   270  	if !p.ReadResourceCalled {
   271  		t.Fatal("ReadResource should have been called")
   272  	}
   273  
   274  	newState := testStateRead(t, statePath)
   275  
   276  	actual := newState.RootModule().Resources["test_instance.foo"].Instances[addrs.NoKey].Current
   277  	expected := &states.ResourceInstanceObjectSrc{
   278  		Status:       states.ObjectReady,
   279  		AttrsJSON:    []byte("{\n            \"ami\": null,\n            \"id\": \"yes\"\n          }"),
   280  		Dependencies: []addrs.AbsResource{},
   281  		DependsOn:    []addrs.Referenceable{},
   282  	}
   283  	if !reflect.DeepEqual(actual, expected) {
   284  		t.Fatalf("wrong new object\ngot:  %swant: %s", spew.Sdump(actual), spew.Sdump(expected))
   285  	}
   286  
   287  	backupState := testStateRead(t, statePath+DefaultBackupExtension)
   288  
   289  	actual = backupState.RootModule().Resources["test_instance.foo"].Instances[addrs.NoKey].Current
   290  	expected = originalState.RootModule().Resources["test_instance.foo"].Instances[addrs.NoKey].Current
   291  	if !reflect.DeepEqual(actual, expected) {
   292  		t.Fatalf("wrong new object\ngot:  %swant: %s", spew.Sdump(actual), spew.Sdump(expected))
   293  	}
   294  }
   295  
   296  func TestRefresh_outPath(t *testing.T) {
   297  	state := testState()
   298  	statePath := testStateFile(t, state)
   299  
   300  	// Output path
   301  	outf, err := ioutil.TempFile(testingDir, "tf")
   302  	if err != nil {
   303  		t.Fatalf("err: %s", err)
   304  	}
   305  	outPath := outf.Name()
   306  	outf.Close()
   307  	os.Remove(outPath)
   308  
   309  	p := testProvider()
   310  	ui := new(cli.MockUi)
   311  	c := &RefreshCommand{
   312  		Meta: Meta{
   313  			testingOverrides: metaOverridesForProvider(p),
   314  			Ui:               ui,
   315  		},
   316  	}
   317  
   318  	p.GetSchemaReturn = refreshFixtureSchema()
   319  	p.ReadResourceFn = nil
   320  	p.ReadResourceResponse = providers.ReadResourceResponse{
   321  		NewState: cty.ObjectVal(map[string]cty.Value{
   322  			"id": cty.StringVal("yes"),
   323  		}),
   324  	}
   325  
   326  	args := []string{
   327  		"-state", statePath,
   328  		"-state-out", outPath,
   329  		testFixturePath("refresh"),
   330  	}
   331  	if code := c.Run(args); code != 0 {
   332  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
   333  	}
   334  
   335  	newState := testStateRead(t, statePath)
   336  	if !reflect.DeepEqual(newState, state) {
   337  		t.Fatalf("bad: %#v", newState)
   338  	}
   339  
   340  	newState = testStateRead(t, outPath)
   341  	actual := newState.RootModule().Resources["test_instance.foo"].Instances[addrs.NoKey].Current
   342  	expected := &states.ResourceInstanceObjectSrc{
   343  		Status:       states.ObjectReady,
   344  		AttrsJSON:    []byte("{\n            \"ami\": null,\n            \"id\": \"yes\"\n          }"),
   345  		Dependencies: []addrs.AbsResource{},
   346  		DependsOn:    []addrs.Referenceable{},
   347  	}
   348  	if !reflect.DeepEqual(actual, expected) {
   349  		t.Fatalf("wrong new object\ngot:  %swant: %s", spew.Sdump(actual), spew.Sdump(expected))
   350  	}
   351  
   352  	if _, err := os.Stat(outPath + DefaultBackupExtension); !os.IsNotExist(err) {
   353  		if err != nil {
   354  			t.Fatalf("failed to test for backup file: %s", err)
   355  		}
   356  		t.Fatalf("backup file exists, but it should not because output file did not initially exist")
   357  	}
   358  }
   359  
   360  func TestRefresh_var(t *testing.T) {
   361  	state := testState()
   362  	statePath := testStateFile(t, state)
   363  
   364  	p := testProvider()
   365  	ui := new(cli.MockUi)
   366  	c := &RefreshCommand{
   367  		Meta: Meta{
   368  			testingOverrides: metaOverridesForProvider(p),
   369  			Ui:               ui,
   370  		},
   371  	}
   372  	p.GetSchemaReturn = refreshVarFixtureSchema()
   373  
   374  	args := []string{
   375  		"-var", "foo=bar",
   376  		"-state", statePath,
   377  		testFixturePath("refresh-var"),
   378  	}
   379  	if code := c.Run(args); code != 0 {
   380  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
   381  	}
   382  
   383  	if !p.ConfigureCalled {
   384  		t.Fatal("configure should be called")
   385  	}
   386  	if got, want := p.ConfigureRequest.Config.GetAttr("value"), cty.StringVal("bar"); !want.RawEquals(got) {
   387  		t.Fatalf("wrong provider configuration\ngot:  %#v\nwant: %#v", got, want)
   388  	}
   389  }
   390  
   391  func TestRefresh_varFile(t *testing.T) {
   392  	state := testState()
   393  	statePath := testStateFile(t, state)
   394  
   395  	p := testProvider()
   396  	ui := new(cli.MockUi)
   397  	c := &RefreshCommand{
   398  		Meta: Meta{
   399  			testingOverrides: metaOverridesForProvider(p),
   400  			Ui:               ui,
   401  		},
   402  	}
   403  	p.GetSchemaReturn = refreshVarFixtureSchema()
   404  
   405  	varFilePath := testTempFile(t)
   406  	if err := ioutil.WriteFile(varFilePath, []byte(refreshVarFile), 0644); err != nil {
   407  		t.Fatalf("err: %s", err)
   408  	}
   409  
   410  	args := []string{
   411  		"-var-file", varFilePath,
   412  		"-state", statePath,
   413  		testFixturePath("refresh-var"),
   414  	}
   415  	if code := c.Run(args); code != 0 {
   416  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
   417  	}
   418  
   419  	if !p.ConfigureCalled {
   420  		t.Fatal("configure should be called")
   421  	}
   422  	if got, want := p.ConfigureRequest.Config.GetAttr("value"), cty.StringVal("bar"); !want.RawEquals(got) {
   423  		t.Fatalf("wrong provider configuration\ngot:  %#v\nwant: %#v", got, want)
   424  	}
   425  }
   426  
   427  func TestRefresh_varFileDefault(t *testing.T) {
   428  	state := testState()
   429  	statePath := testStateFile(t, state)
   430  
   431  	p := testProvider()
   432  	ui := new(cli.MockUi)
   433  	c := &RefreshCommand{
   434  		Meta: Meta{
   435  			testingOverrides: metaOverridesForProvider(p),
   436  			Ui:               ui,
   437  		},
   438  	}
   439  	p.GetSchemaReturn = refreshVarFixtureSchema()
   440  
   441  	varFileDir := testTempDir(t)
   442  	varFilePath := filepath.Join(varFileDir, "terraform.tfvars")
   443  	if err := ioutil.WriteFile(varFilePath, []byte(refreshVarFile), 0644); err != nil {
   444  		t.Fatalf("err: %s", err)
   445  	}
   446  
   447  	cwd, err := os.Getwd()
   448  	if err != nil {
   449  		t.Fatalf("err: %s", err)
   450  	}
   451  	if err := os.Chdir(varFileDir); err != nil {
   452  		t.Fatalf("err: %s", err)
   453  	}
   454  	defer os.Chdir(cwd)
   455  
   456  	args := []string{
   457  		"-state", statePath,
   458  		testFixturePath("refresh-var"),
   459  	}
   460  	if code := c.Run(args); code != 0 {
   461  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
   462  	}
   463  
   464  	if !p.ConfigureCalled {
   465  		t.Fatal("configure should be called")
   466  	}
   467  	if got, want := p.ConfigureRequest.Config.GetAttr("value"), cty.StringVal("bar"); !want.RawEquals(got) {
   468  		t.Fatalf("wrong provider configuration\ngot:  %#v\nwant: %#v", got, want)
   469  	}
   470  }
   471  
   472  func TestRefresh_varsUnset(t *testing.T) {
   473  	// Disable test mode so input would be asked
   474  	test = false
   475  	defer func() { test = true }()
   476  
   477  	defaultInputReader = bytes.NewBufferString("bar\n")
   478  
   479  	state := testState()
   480  	statePath := testStateFile(t, state)
   481  
   482  	p := testProvider()
   483  	ui := new(cli.MockUi)
   484  	c := &RefreshCommand{
   485  		Meta: Meta{
   486  			testingOverrides: metaOverridesForProvider(p),
   487  			Ui:               ui,
   488  		},
   489  	}
   490  	p.GetSchemaReturn = &terraform.ProviderSchema{
   491  		ResourceTypes: map[string]*configschema.Block{
   492  			"test_instance": {
   493  				Attributes: map[string]*configschema.Attribute{
   494  					"id":  {Type: cty.String, Optional: true, Computed: true},
   495  					"ami": {Type: cty.String, Optional: true},
   496  				},
   497  			},
   498  		},
   499  	}
   500  
   501  	args := []string{
   502  		"-state", statePath,
   503  		testFixturePath("refresh-unset-var"),
   504  	}
   505  	if code := c.Run(args); code != 0 {
   506  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
   507  	}
   508  }
   509  
   510  func TestRefresh_backup(t *testing.T) {
   511  	state := testState()
   512  	statePath := testStateFile(t, state)
   513  
   514  	// Output path
   515  	outf, err := ioutil.TempFile(testingDir, "tf")
   516  	if err != nil {
   517  		t.Fatalf("err: %s", err)
   518  	}
   519  	outPath := outf.Name()
   520  	defer outf.Close()
   521  
   522  	// Need to put some state content in the output file so that there's
   523  	// something to back up.
   524  	err = statefile.Write(statefile.New(state, "baz", 0), outf)
   525  	if err != nil {
   526  		t.Fatalf("error writing initial output state file %s", err)
   527  	}
   528  
   529  	// Backup path
   530  	backupf, err := ioutil.TempFile(testingDir, "tf")
   531  	if err != nil {
   532  		t.Fatalf("err: %s", err)
   533  	}
   534  	backupPath := backupf.Name()
   535  	backupf.Close()
   536  	os.Remove(backupPath)
   537  
   538  	p := testProvider()
   539  	ui := new(cli.MockUi)
   540  	c := &RefreshCommand{
   541  		Meta: Meta{
   542  			testingOverrides: metaOverridesForProvider(p),
   543  			Ui:               ui,
   544  		},
   545  	}
   546  
   547  	p.GetSchemaReturn = refreshFixtureSchema()
   548  	p.ReadResourceFn = nil
   549  	p.ReadResourceResponse = providers.ReadResourceResponse{
   550  		NewState: cty.ObjectVal(map[string]cty.Value{
   551  			"id": cty.StringVal("changed"),
   552  		}),
   553  	}
   554  
   555  	args := []string{
   556  		"-state", statePath,
   557  		"-state-out", outPath,
   558  		"-backup", backupPath,
   559  		testFixturePath("refresh"),
   560  	}
   561  	if code := c.Run(args); code != 0 {
   562  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
   563  	}
   564  
   565  	newState := testStateRead(t, statePath)
   566  	if !cmp.Equal(newState, state, cmpopts.EquateEmpty()) {
   567  		t.Fatalf("got:\n%s\nexpected:\n%s\n", newState, state)
   568  	}
   569  
   570  	newState = testStateRead(t, outPath)
   571  	actual := newState.RootModule().Resources["test_instance.foo"].Instances[addrs.NoKey].Current
   572  	expected := &states.ResourceInstanceObjectSrc{
   573  		Status:       states.ObjectReady,
   574  		AttrsJSON:    []byte("{\n            \"ami\": null,\n            \"id\": \"changed\"\n          }"),
   575  		Dependencies: []addrs.AbsResource{},
   576  		DependsOn:    []addrs.Referenceable{},
   577  	}
   578  	if !reflect.DeepEqual(actual, expected) {
   579  		t.Fatalf("wrong new object\ngot:  %swant: %s", spew.Sdump(actual), spew.Sdump(expected))
   580  	}
   581  
   582  	backupState := testStateRead(t, backupPath)
   583  	actualStr := strings.TrimSpace(backupState.String())
   584  	expectedStr := strings.TrimSpace(state.String())
   585  	if actualStr != expectedStr {
   586  		t.Fatalf("bad:\n\n%s\n\n%s", actualStr, expectedStr)
   587  	}
   588  }
   589  
   590  func TestRefresh_disableBackup(t *testing.T) {
   591  	state := testState()
   592  	statePath := testStateFile(t, state)
   593  
   594  	// Output path
   595  	outf, err := ioutil.TempFile(testingDir, "tf")
   596  	if err != nil {
   597  		t.Fatalf("err: %s", err)
   598  	}
   599  	outPath := outf.Name()
   600  	outf.Close()
   601  	os.Remove(outPath)
   602  
   603  	p := testProvider()
   604  	ui := new(cli.MockUi)
   605  	c := &RefreshCommand{
   606  		Meta: Meta{
   607  			testingOverrides: metaOverridesForProvider(p),
   608  			Ui:               ui,
   609  		},
   610  	}
   611  
   612  	p.GetSchemaReturn = refreshFixtureSchema()
   613  	p.ReadResourceFn = nil
   614  	p.ReadResourceResponse = providers.ReadResourceResponse{
   615  		NewState: cty.ObjectVal(map[string]cty.Value{
   616  			"id": cty.StringVal("yes"),
   617  		}),
   618  	}
   619  
   620  	args := []string{
   621  		"-state", statePath,
   622  		"-state-out", outPath,
   623  		"-backup", "-",
   624  		testFixturePath("refresh"),
   625  	}
   626  	if code := c.Run(args); code != 0 {
   627  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
   628  	}
   629  
   630  	newState := testStateRead(t, statePath)
   631  	if !cmp.Equal(state, newState, equateEmpty) {
   632  		spew.Config.DisableMethods = true
   633  		fmt.Println(cmp.Diff(state, newState, equateEmpty))
   634  		t.Fatalf("bad: %s", newState)
   635  	}
   636  
   637  	newState = testStateRead(t, outPath)
   638  	actual := newState.RootModule().Resources["test_instance.foo"].Instances[addrs.NoKey].Current
   639  	expected := &states.ResourceInstanceObjectSrc{
   640  		Status:       states.ObjectReady,
   641  		AttrsJSON:    []byte("{\n            \"ami\": null,\n            \"id\": \"yes\"\n          }"),
   642  		Dependencies: []addrs.AbsResource{},
   643  		DependsOn:    []addrs.Referenceable{},
   644  	}
   645  	if !reflect.DeepEqual(actual, expected) {
   646  		t.Fatalf("wrong new object\ngot:  %swant: %s", spew.Sdump(actual), spew.Sdump(expected))
   647  	}
   648  
   649  	// Ensure there is no backup
   650  	_, err = os.Stat(outPath + DefaultBackupExtension)
   651  	if err == nil || !os.IsNotExist(err) {
   652  		t.Fatalf("backup should not exist")
   653  	}
   654  	_, err = os.Stat("-")
   655  	if err == nil || !os.IsNotExist(err) {
   656  		t.Fatalf("backup should not exist")
   657  	}
   658  }
   659  
   660  func TestRefresh_displaysOutputs(t *testing.T) {
   661  	state := testState()
   662  	statePath := testStateFile(t, state)
   663  
   664  	p := testProvider()
   665  	ui := new(cli.MockUi)
   666  	c := &RefreshCommand{
   667  		Meta: Meta{
   668  			testingOverrides: metaOverridesForProvider(p),
   669  			Ui:               ui,
   670  		},
   671  	}
   672  	p.GetSchemaReturn = &terraform.ProviderSchema{
   673  		ResourceTypes: map[string]*configschema.Block{
   674  			"test_instance": {
   675  				Attributes: map[string]*configschema.Attribute{
   676  					"id":  {Type: cty.String, Optional: true, Computed: true},
   677  					"ami": {Type: cty.String, Optional: true},
   678  				},
   679  			},
   680  		},
   681  	}
   682  
   683  	args := []string{
   684  		"-state", statePath,
   685  		testFixturePath("refresh-output"),
   686  	}
   687  	if code := c.Run(args); code != 0 {
   688  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
   689  	}
   690  
   691  	// Test that outputs were displayed
   692  	outputValue := "foo.example.com"
   693  	actual := ui.OutputWriter.String()
   694  	if !strings.Contains(actual, outputValue) {
   695  		t.Fatalf("Expected:\n%s\n\nTo include: %q", actual, outputValue)
   696  	}
   697  }
   698  
   699  // newInstanceState creates a new states.ResourceInstanceObjectSrc with the
   700  // given value for its single id attribute. It is named newInstanceState for
   701  // historical reasons, because it was originally written for the poorly-named
   702  // terraform.InstanceState type.
   703  func newInstanceState(id string) *states.ResourceInstanceObjectSrc {
   704  	attrs := map[string]interface{}{
   705  		"id": id,
   706  	}
   707  	attrsJSON, err := json.Marshal(attrs)
   708  	if err != nil {
   709  		panic(fmt.Sprintf("failed to marshal attributes: %s", err)) // should never happen
   710  	}
   711  	return &states.ResourceInstanceObjectSrc{
   712  		AttrsJSON: attrsJSON,
   713  		Status:    states.ObjectReady,
   714  	}
   715  }
   716  
   717  // refreshFixtureSchema returns a schema suitable for processing the
   718  // configuration in testdata/refresh . This schema should be
   719  // assigned to a mock provider named "test".
   720  func refreshFixtureSchema() *terraform.ProviderSchema {
   721  	return &terraform.ProviderSchema{
   722  		ResourceTypes: map[string]*configschema.Block{
   723  			"test_instance": {
   724  				Attributes: map[string]*configschema.Attribute{
   725  					"id":  {Type: cty.String, Optional: true, Computed: true},
   726  					"ami": {Type: cty.String, Optional: true},
   727  				},
   728  			},
   729  		},
   730  	}
   731  }
   732  
   733  // refreshVarFixtureSchema returns a schema suitable for processing the
   734  // configuration in testdata/refresh-var . This schema should be
   735  // assigned to a mock provider named "test".
   736  func refreshVarFixtureSchema() *terraform.ProviderSchema {
   737  	return &terraform.ProviderSchema{
   738  		Provider: &configschema.Block{
   739  			Attributes: map[string]*configschema.Attribute{
   740  				"value": {Type: cty.String, Optional: true},
   741  			},
   742  		},
   743  		ResourceTypes: map[string]*configschema.Block{
   744  			"test_instance": {
   745  				Attributes: map[string]*configschema.Attribute{
   746  					"id": {Type: cty.String, Optional: true, Computed: true},
   747  				},
   748  			},
   749  		},
   750  	}
   751  }
   752  
   753  const refreshVarFile = `
   754  foo = "bar"
   755  `
   756  
   757  const testRefreshStr = `
   758  test_instance.foo:
   759    ID = yes
   760    provider = provider.test
   761  `
   762  const testRefreshCwdStr = `
   763  test_instance.foo:
   764    ID = yes
   765    provider = provider.test
   766  `