github.com/ggriffiths/terraform@v0.9.0-beta1.0.20170222213024-79c4935604cb/command/meta_backend_test.go (about)

     1  package command
     2  
     3  import (
     4  	"io/ioutil"
     5  	"os"
     6  	"path/filepath"
     7  	"strings"
     8  	"testing"
     9  
    10  	"github.com/hashicorp/terraform/helper/copy"
    11  	"github.com/hashicorp/terraform/state"
    12  	"github.com/hashicorp/terraform/terraform"
    13  	"github.com/mitchellh/cli"
    14  )
    15  
    16  // Test empty directory with no config/state creates a local state.
    17  func TestMetaBackend_emptyDir(t *testing.T) {
    18  	// Create a temporary working directory that is empty
    19  	td := tempDir(t)
    20  	os.MkdirAll(td, 0755)
    21  	defer os.RemoveAll(td)
    22  	defer testChdir(t, td)()
    23  
    24  	// Get the backend
    25  	m := testMetaBackend(t, nil)
    26  	b, err := m.Backend(&BackendOpts{Init: true})
    27  	if err != nil {
    28  		t.Fatalf("bad: %s", err)
    29  	}
    30  
    31  	// Write some state
    32  	s, err := b.State()
    33  	if err != nil {
    34  		t.Fatalf("bad: %s", err)
    35  	}
    36  	s.WriteState(testState())
    37  	if err := s.PersistState(); err != nil {
    38  		t.Fatalf("bad: %s", err)
    39  	}
    40  
    41  	// Verify it exists where we expect it to
    42  	if isEmptyState(DefaultStateFilename) {
    43  		t.Fatalf("no state was written")
    44  	}
    45  
    46  	// Verify no backup since it was empty to start
    47  	if !isEmptyState(DefaultStateFilename + DefaultBackupExtension) {
    48  		t.Fatal("backup state should be empty")
    49  	}
    50  
    51  	// Verify no backend state was made
    52  	if !isEmptyState(filepath.Join(m.DataDir(), DefaultStateFilename)) {
    53  		t.Fatal("backend state should be empty")
    54  	}
    55  }
    56  
    57  // check for no state. Either the file doesn't exist, or is empty
    58  func isEmptyState(path string) bool {
    59  	fi, err := os.Stat(path)
    60  	if os.IsNotExist(err) {
    61  		return true
    62  	}
    63  
    64  	if fi.Size() == 0 {
    65  		return true
    66  	}
    67  
    68  	return false
    69  }
    70  
    71  // Test a directory with a legacy state and no config continues to
    72  // use the legacy state.
    73  func TestMetaBackend_emptyWithDefaultState(t *testing.T) {
    74  	// Create a temporary working directory that is empty
    75  	td := tempDir(t)
    76  	os.MkdirAll(td, 0755)
    77  	defer os.RemoveAll(td)
    78  	defer testChdir(t, td)()
    79  
    80  	// Write the legacy state
    81  	statePath := DefaultStateFilename
    82  	{
    83  		f, err := os.Create(statePath)
    84  		if err != nil {
    85  			t.Fatalf("err: %s", err)
    86  		}
    87  		err = terraform.WriteState(testState(), f)
    88  		f.Close()
    89  		if err != nil {
    90  			t.Fatalf("err: %s", err)
    91  		}
    92  	}
    93  
    94  	// Get the backend
    95  	m := testMetaBackend(t, nil)
    96  	b, err := m.Backend(&BackendOpts{Init: true})
    97  	if err != nil {
    98  		t.Fatalf("bad: %s", err)
    99  	}
   100  
   101  	// Check the state
   102  	s, err := b.State()
   103  	if err != nil {
   104  		t.Fatalf("bad: %s", err)
   105  	}
   106  	if actual := s.State().String(); actual != testState().String() {
   107  		t.Fatalf("bad: %s", actual)
   108  	}
   109  
   110  	// Verify it exists where we expect it to
   111  	if _, err := os.Stat(DefaultStateFilename); err != nil {
   112  		t.Fatalf("err: %s", err)
   113  	}
   114  
   115  	stateName := filepath.Join(m.DataDir(), DefaultStateFilename)
   116  	if !isEmptyState(stateName) {
   117  		t.Fatal("expected no state at", stateName)
   118  	}
   119  
   120  	// Write some state
   121  	next := testState()
   122  	next.Modules[0].Outputs["foo"] = &terraform.OutputState{Value: "bar"}
   123  	s.WriteState(testState())
   124  	if err := s.PersistState(); err != nil {
   125  		t.Fatalf("bad: %s", err)
   126  	}
   127  
   128  	// Verify a backup was made since we're modifying a pre-existing state
   129  	if isEmptyState(DefaultStateFilename + DefaultBackupExtension) {
   130  		t.Fatal("backup state should not be empty")
   131  	}
   132  }
   133  
   134  // Test an empty directory with an explicit state path (outside the dir)
   135  func TestMetaBackend_emptyWithExplicitState(t *testing.T) {
   136  	// Create a temporary working directory that is empty
   137  	td := tempDir(t)
   138  	os.MkdirAll(td, 0755)
   139  	defer os.RemoveAll(td)
   140  	defer testChdir(t, td)()
   141  
   142  	// Create another directory to store our state
   143  	stateDir := tempDir(t)
   144  	os.MkdirAll(stateDir, 0755)
   145  	defer os.RemoveAll(stateDir)
   146  
   147  	// Write the legacy state
   148  	statePath := filepath.Join(stateDir, "foo")
   149  	{
   150  		f, err := os.Create(statePath)
   151  		if err != nil {
   152  			t.Fatalf("err: %s", err)
   153  		}
   154  		err = terraform.WriteState(testState(), f)
   155  		f.Close()
   156  		if err != nil {
   157  			t.Fatalf("err: %s", err)
   158  		}
   159  	}
   160  
   161  	// Setup the meta
   162  	m := testMetaBackend(t, nil)
   163  	m.statePath = statePath
   164  
   165  	// Get the backend
   166  	b, err := m.Backend(&BackendOpts{Init: true})
   167  	if err != nil {
   168  		t.Fatalf("bad: %s", err)
   169  	}
   170  
   171  	// Check the state
   172  	s, err := b.State()
   173  	if err != nil {
   174  		t.Fatalf("bad: %s", err)
   175  	}
   176  	if actual := s.State().String(); actual != testState().String() {
   177  		t.Fatalf("bad: %s", actual)
   178  	}
   179  
   180  	// Verify neither defaults exist
   181  	if _, err := os.Stat(DefaultStateFilename); err == nil {
   182  		t.Fatal("file should not exist")
   183  	}
   184  
   185  	stateName := filepath.Join(m.DataDir(), DefaultStateFilename)
   186  	if !isEmptyState(stateName) {
   187  		t.Fatal("expected no state at", stateName)
   188  	}
   189  
   190  	// Write some state
   191  	next := testState()
   192  	next.Modules[0].Outputs["foo"] = &terraform.OutputState{Value: "bar"}
   193  	s.WriteState(testState())
   194  	if err := s.PersistState(); err != nil {
   195  		t.Fatalf("bad: %s", err)
   196  	}
   197  
   198  	// Verify a backup was made since we're modifying a pre-existing state
   199  	if isEmptyState(statePath + DefaultBackupExtension) {
   200  		t.Fatal("backup state should not be empty")
   201  	}
   202  }
   203  
   204  // Empty directory with legacy remote state
   205  func TestMetaBackend_emptyLegacyRemote(t *testing.T) {
   206  	// Create a temporary working directory that is empty
   207  	td := tempDir(t)
   208  	os.MkdirAll(td, 0755)
   209  	defer os.RemoveAll(td)
   210  	defer testChdir(t, td)()
   211  
   212  	// Create some legacy remote state
   213  	legacyState := testState()
   214  	_, srv := testRemoteState(t, legacyState, 200)
   215  	defer srv.Close()
   216  	statePath := testStateFileRemote(t, legacyState)
   217  
   218  	// Setup the meta
   219  	m := testMetaBackend(t, nil)
   220  
   221  	// Get the backend
   222  	b, err := m.Backend(&BackendOpts{Init: true})
   223  	if err != nil {
   224  		t.Fatalf("bad: %s", err)
   225  	}
   226  
   227  	// Check the state
   228  	s, err := b.State()
   229  	if err != nil {
   230  		t.Fatalf("bad: %s", err)
   231  	}
   232  	if err := s.RefreshState(); err != nil {
   233  		t.Fatalf("bad: %s", err)
   234  	}
   235  	state := s.State()
   236  	if actual := state.String(); actual != legacyState.String() {
   237  		t.Fatalf("bad: %s", actual)
   238  	}
   239  
   240  	// Verify we didn't setup the backend state
   241  	if !state.Backend.Empty() {
   242  		t.Fatal("shouldn't configure backend")
   243  	}
   244  
   245  	// Verify the default paths don't exist
   246  	if _, err := os.Stat(DefaultStateFilename); err == nil {
   247  		t.Fatal("file should not exist")
   248  	}
   249  
   250  	// Verify a backup doesn't exist
   251  	if _, err := os.Stat(DefaultStateFilename + DefaultBackupExtension); err == nil {
   252  		t.Fatal("file should not exist")
   253  	}
   254  	if _, err := os.Stat(statePath + DefaultBackupExtension); err == nil {
   255  		t.Fatal("file should not exist")
   256  	}
   257  }
   258  
   259  // Newly configured backend
   260  func TestMetaBackend_configureNew(t *testing.T) {
   261  	// Create a temporary working directory that is empty
   262  	td := tempDir(t)
   263  	copy.CopyDir(testFixturePath("backend-new"), td)
   264  	defer os.RemoveAll(td)
   265  	defer testChdir(t, td)()
   266  
   267  	// Setup the meta
   268  	m := testMetaBackend(t, nil)
   269  
   270  	// Get the backend
   271  	b, err := m.Backend(&BackendOpts{Init: true})
   272  	if err != nil {
   273  		t.Fatalf("bad: %s", err)
   274  	}
   275  
   276  	// Check the state
   277  	s, err := b.State()
   278  	if err != nil {
   279  		t.Fatalf("bad: %s", err)
   280  	}
   281  	if err := s.RefreshState(); err != nil {
   282  		t.Fatalf("bad: %s", err)
   283  	}
   284  	state := s.State()
   285  	if state != nil {
   286  		t.Fatal("state should be nil")
   287  	}
   288  
   289  	// Write some state
   290  	state = terraform.NewState()
   291  	state.Lineage = "changing"
   292  	s.WriteState(state)
   293  	if err := s.PersistState(); err != nil {
   294  		t.Fatalf("bad: %s", err)
   295  	}
   296  
   297  	// Verify the state is where we expect
   298  	{
   299  		f, err := os.Open("local-state.tfstate")
   300  		if err != nil {
   301  			t.Fatalf("err: %s", err)
   302  		}
   303  		actual, err := terraform.ReadState(f)
   304  		f.Close()
   305  		if err != nil {
   306  			t.Fatalf("err: %s", err)
   307  		}
   308  
   309  		if actual.Lineage != state.Lineage {
   310  			t.Fatalf("bad: %#v", actual)
   311  		}
   312  	}
   313  
   314  	// Verify the default paths don't exist
   315  	if _, err := os.Stat(DefaultStateFilename); err == nil {
   316  		t.Fatal("file should not exist")
   317  	}
   318  
   319  	// Verify a backup doesn't exist
   320  	if _, err := os.Stat(DefaultStateFilename + DefaultBackupExtension); err == nil {
   321  		t.Fatal("file should not exist")
   322  	}
   323  }
   324  
   325  // Newly configured backend with prior local state and no remote state
   326  func TestMetaBackend_configureNewWithState(t *testing.T) {
   327  	// Create a temporary working directory that is empty
   328  	td := tempDir(t)
   329  	copy.CopyDir(testFixturePath("backend-new-migrate"), td)
   330  	defer os.RemoveAll(td)
   331  	defer testChdir(t, td)()
   332  
   333  	// Ask input
   334  	defer testInteractiveInput(t, []string{"yes"})()
   335  
   336  	// Setup the meta
   337  	m := testMetaBackend(t, nil)
   338  
   339  	// Get the backend
   340  	b, err := m.Backend(&BackendOpts{Init: true})
   341  	if err != nil {
   342  		t.Fatalf("bad: %s", err)
   343  	}
   344  
   345  	// Check the state
   346  	s, err := b.State()
   347  	if err != nil {
   348  		t.Fatalf("bad: %s", err)
   349  	}
   350  	if err := s.RefreshState(); err != nil {
   351  		t.Fatalf("bad: %s", err)
   352  	}
   353  	state := s.State()
   354  	if state == nil {
   355  		t.Fatal("state is nil")
   356  	}
   357  
   358  	if state.Lineage != "backend-new-migrate" {
   359  		t.Fatalf("bad: %#v", state)
   360  	}
   361  
   362  	// Write some state
   363  	state = terraform.NewState()
   364  	state.Lineage = "changing"
   365  	s.WriteState(state)
   366  	if err := s.PersistState(); err != nil {
   367  		t.Fatalf("bad: %s", err)
   368  	}
   369  
   370  	// Verify the state is where we expect
   371  	{
   372  		f, err := os.Open("local-state.tfstate")
   373  		if err != nil {
   374  			t.Fatalf("err: %s", err)
   375  		}
   376  		actual, err := terraform.ReadState(f)
   377  		f.Close()
   378  		if err != nil {
   379  			t.Fatalf("err: %s", err)
   380  		}
   381  
   382  		if actual.Lineage != state.Lineage {
   383  			t.Fatalf("bad: %#v", actual)
   384  		}
   385  	}
   386  
   387  	// Verify the default paths don't exist
   388  	if !isEmptyState(DefaultStateFilename) {
   389  		data, _ := ioutil.ReadFile(DefaultStateFilename)
   390  
   391  		t.Fatal("state should not exist, but contains:\n", string(data))
   392  	}
   393  
   394  	// Verify a backup does exist
   395  	if isEmptyState(DefaultStateFilename + DefaultBackupExtension) {
   396  		t.Fatal("backup state is empty or missing")
   397  	}
   398  }
   399  
   400  // Newly configured backend with prior local state and no remote state,
   401  // but opting to not migrate.
   402  func TestMetaBackend_configureNewWithStateNoMigrate(t *testing.T) {
   403  	// Create a temporary working directory that is empty
   404  	td := tempDir(t)
   405  	copy.CopyDir(testFixturePath("backend-new-migrate"), td)
   406  	defer os.RemoveAll(td)
   407  	defer testChdir(t, td)()
   408  
   409  	// Ask input
   410  	defer testInteractiveInput(t, []string{"no"})()
   411  
   412  	// Setup the meta
   413  	m := testMetaBackend(t, nil)
   414  
   415  	// Get the backend
   416  	b, err := m.Backend(&BackendOpts{Init: true})
   417  	if err != nil {
   418  		t.Fatalf("bad: %s", err)
   419  	}
   420  
   421  	// Check the state
   422  	s, err := b.State()
   423  	if err != nil {
   424  		t.Fatalf("bad: %s", err)
   425  	}
   426  	if err := s.RefreshState(); err != nil {
   427  		t.Fatalf("bad: %s", err)
   428  	}
   429  	if state := s.State(); state != nil {
   430  		t.Fatal("state is not nil")
   431  	}
   432  
   433  	// Verify the default paths don't exist
   434  	if !isEmptyState(DefaultStateFilename) {
   435  		data, _ := ioutil.ReadFile(DefaultStateFilename)
   436  
   437  		t.Fatal("state should not exist, but contains:\n", string(data))
   438  	}
   439  
   440  	// Verify a backup does exist
   441  	if isEmptyState(DefaultStateFilename + DefaultBackupExtension) {
   442  		t.Fatal("backup state is empty or missing")
   443  	}
   444  }
   445  
   446  // Newly configured backend with prior local state and remote state
   447  func TestMetaBackend_configureNewWithStateExisting(t *testing.T) {
   448  	// Create a temporary working directory that is empty
   449  	td := tempDir(t)
   450  	copy.CopyDir(testFixturePath("backend-new-migrate-existing"), td)
   451  	defer os.RemoveAll(td)
   452  	defer testChdir(t, td)()
   453  
   454  	// Ask input
   455  	defer testInteractiveInput(t, []string{"yes"})()
   456  
   457  	// Setup the meta
   458  	m := testMetaBackend(t, nil)
   459  
   460  	// Get the backend
   461  	b, err := m.Backend(&BackendOpts{Init: true})
   462  	if err != nil {
   463  		t.Fatalf("bad: %s", err)
   464  	}
   465  
   466  	// Check the state
   467  	s, err := b.State()
   468  	if err != nil {
   469  		t.Fatalf("bad: %s", err)
   470  	}
   471  	if err := s.RefreshState(); err != nil {
   472  		t.Fatalf("bad: %s", err)
   473  	}
   474  	state := s.State()
   475  	if state == nil {
   476  		t.Fatal("state is nil")
   477  	}
   478  	if state.Lineage != "local" {
   479  		t.Fatalf("bad: %#v", state)
   480  	}
   481  
   482  	// Write some state
   483  	state = terraform.NewState()
   484  	state.Lineage = "changing"
   485  	s.WriteState(state)
   486  	if err := s.PersistState(); err != nil {
   487  		t.Fatalf("bad: %s", err)
   488  	}
   489  
   490  	// Verify the state is where we expect
   491  	{
   492  		f, err := os.Open("local-state.tfstate")
   493  		if err != nil {
   494  			t.Fatalf("err: %s", err)
   495  		}
   496  		actual, err := terraform.ReadState(f)
   497  		f.Close()
   498  		if err != nil {
   499  			t.Fatalf("err: %s", err)
   500  		}
   501  
   502  		if actual.Lineage != state.Lineage {
   503  			t.Fatalf("bad: %#v", actual)
   504  		}
   505  	}
   506  
   507  	// Verify the default paths don't exist
   508  	if !isEmptyState(DefaultStateFilename) {
   509  		data, _ := ioutil.ReadFile(DefaultStateFilename)
   510  
   511  		t.Fatal("state should not exist, but contains:\n", string(data))
   512  	}
   513  
   514  	// Verify a backup does exist
   515  	if isEmptyState(DefaultStateFilename + DefaultBackupExtension) {
   516  		t.Fatal("backup state is empty or missing")
   517  	}
   518  }
   519  
   520  // Newly configured backend with prior local state and remote state
   521  func TestMetaBackend_configureNewWithStateExistingNoMigrate(t *testing.T) {
   522  	// Create a temporary working directory that is empty
   523  	td := tempDir(t)
   524  	copy.CopyDir(testFixturePath("backend-new-migrate-existing"), td)
   525  	defer os.RemoveAll(td)
   526  	defer testChdir(t, td)()
   527  
   528  	// Ask input
   529  	defer testInteractiveInput(t, []string{"no"})()
   530  
   531  	// Setup the meta
   532  	m := testMetaBackend(t, nil)
   533  
   534  	// Get the backend
   535  	b, err := m.Backend(&BackendOpts{Init: true})
   536  	if err != nil {
   537  		t.Fatalf("bad: %s", err)
   538  	}
   539  
   540  	// Check the state
   541  	s, err := b.State()
   542  	if err != nil {
   543  		t.Fatalf("bad: %s", err)
   544  	}
   545  	if err := s.RefreshState(); err != nil {
   546  		t.Fatalf("bad: %s", err)
   547  	}
   548  	state := s.State()
   549  	if state == nil {
   550  		t.Fatal("state is nil")
   551  	}
   552  	if state.Lineage != "remote" {
   553  		t.Fatalf("bad: %#v", state)
   554  	}
   555  
   556  	// Write some state
   557  	state = terraform.NewState()
   558  	state.Lineage = "changing"
   559  	s.WriteState(state)
   560  	if err := s.PersistState(); err != nil {
   561  		t.Fatalf("bad: %s", err)
   562  	}
   563  
   564  	// Verify the state is where we expect
   565  	{
   566  		f, err := os.Open("local-state.tfstate")
   567  		if err != nil {
   568  			t.Fatalf("err: %s", err)
   569  		}
   570  		actual, err := terraform.ReadState(f)
   571  		f.Close()
   572  		if err != nil {
   573  			t.Fatalf("err: %s", err)
   574  		}
   575  
   576  		if actual.Lineage != state.Lineage {
   577  			t.Fatalf("bad: %#v", actual)
   578  		}
   579  	}
   580  
   581  	// Verify the default paths don't exist
   582  	if !isEmptyState(DefaultStateFilename) {
   583  		data, _ := ioutil.ReadFile(DefaultStateFilename)
   584  
   585  		t.Fatal("state should not exist, but contains:\n", string(data))
   586  	}
   587  
   588  	// Verify a backup does exist
   589  	if isEmptyState(DefaultStateFilename + DefaultBackupExtension) {
   590  		t.Fatal("backup state is empty or missing")
   591  	}
   592  }
   593  
   594  // Newly configured backend with lgacy
   595  func TestMetaBackend_configureNewLegacy(t *testing.T) {
   596  	// Create a temporary working directory that is empty
   597  	td := tempDir(t)
   598  	copy.CopyDir(testFixturePath("backend-new-legacy"), td)
   599  	defer os.RemoveAll(td)
   600  	defer testChdir(t, td)()
   601  
   602  	// Ask input
   603  	defer testInteractiveInput(t, []string{"no"})()
   604  
   605  	// Setup the meta
   606  	m := testMetaBackend(t, nil)
   607  
   608  	// Get the backend
   609  	b, err := m.Backend(&BackendOpts{Init: true})
   610  	if err != nil {
   611  		t.Fatalf("bad: %s", err)
   612  	}
   613  
   614  	// Check the state
   615  	s, err := b.State()
   616  	if err != nil {
   617  		t.Fatalf("bad: %s", err)
   618  	}
   619  	if err := s.RefreshState(); err != nil {
   620  		t.Fatalf("bad: %s", err)
   621  	}
   622  	state := s.State()
   623  	if state != nil {
   624  		t.Fatal("state should be nil")
   625  	}
   626  
   627  	// Verify we have no configured legacy
   628  	{
   629  		path := filepath.Join(m.DataDir(), DefaultStateFilename)
   630  		f, err := os.Open(path)
   631  		if err != nil {
   632  			t.Fatalf("err: %s", err)
   633  		}
   634  		actual, err := terraform.ReadState(f)
   635  		f.Close()
   636  		if err != nil {
   637  			t.Fatalf("err: %s", err)
   638  		}
   639  
   640  		if !actual.Remote.Empty() {
   641  			t.Fatalf("bad: %#v", actual)
   642  		}
   643  		if actual.Backend.Empty() {
   644  			t.Fatalf("bad: %#v", actual)
   645  		}
   646  	}
   647  
   648  	// Write some state
   649  	state = terraform.NewState()
   650  	state.Lineage = "changing"
   651  	s.WriteState(state)
   652  	if err := s.PersistState(); err != nil {
   653  		t.Fatalf("bad: %s", err)
   654  	}
   655  
   656  	// Verify the state is where we expect
   657  	{
   658  		f, err := os.Open("local-state.tfstate")
   659  		if err != nil {
   660  			t.Fatalf("err: %s", err)
   661  		}
   662  		actual, err := terraform.ReadState(f)
   663  		f.Close()
   664  		if err != nil {
   665  			t.Fatalf("err: %s", err)
   666  		}
   667  
   668  		if actual.Lineage != state.Lineage {
   669  			t.Fatalf("bad: %#v", actual)
   670  		}
   671  	}
   672  
   673  	// Verify the default paths don't exist
   674  	if !isEmptyState(DefaultStateFilename) {
   675  		data, _ := ioutil.ReadFile(DefaultStateFilename)
   676  
   677  		t.Fatal("state should not exist, but contains:\n", string(data))
   678  	}
   679  
   680  	// Verify a backup doesn't exist
   681  	if !isEmptyState(DefaultStateFilename + DefaultBackupExtension) {
   682  		data, _ := ioutil.ReadFile(DefaultStateFilename)
   683  
   684  		t.Fatal("backup should be empty, but contains:\n", string(data))
   685  	}
   686  }
   687  
   688  // Newly configured backend with legacy
   689  func TestMetaBackend_configureNewLegacyCopy(t *testing.T) {
   690  	// Create a temporary working directory that is empty
   691  	td := tempDir(t)
   692  	copy.CopyDir(testFixturePath("backend-new-legacy"), td)
   693  	defer os.RemoveAll(td)
   694  	defer testChdir(t, td)()
   695  
   696  	// Ask input
   697  	defer testInteractiveInput(t, []string{"yes", "yes"})()
   698  
   699  	// Setup the meta
   700  	m := testMetaBackend(t, nil)
   701  
   702  	// Get the backend
   703  	b, err := m.Backend(&BackendOpts{Init: true})
   704  	if err != nil {
   705  		t.Fatalf("bad: %s", err)
   706  	}
   707  
   708  	// Check the state
   709  	s, err := b.State()
   710  	if err != nil {
   711  		t.Fatalf("bad: %s", err)
   712  	}
   713  	if err := s.RefreshState(); err != nil {
   714  		t.Fatalf("bad: %s", err)
   715  	}
   716  	state := s.State()
   717  	if state == nil {
   718  		t.Fatal("nil state")
   719  	}
   720  	if state.Lineage != "backend-new-legacy" {
   721  		t.Fatalf("bad: %#v", state)
   722  	}
   723  
   724  	// Verify we have no configured legacy
   725  	{
   726  		path := filepath.Join(m.DataDir(), DefaultStateFilename)
   727  		f, err := os.Open(path)
   728  		if err != nil {
   729  			t.Fatalf("err: %s", err)
   730  		}
   731  		actual, err := terraform.ReadState(f)
   732  		f.Close()
   733  		if err != nil {
   734  			t.Fatalf("err: %s", err)
   735  		}
   736  
   737  		if !actual.Remote.Empty() {
   738  			t.Fatalf("bad: %#v", actual)
   739  		}
   740  		if actual.Backend.Empty() {
   741  			t.Fatalf("bad: %#v", actual)
   742  		}
   743  	}
   744  
   745  	// Write some state
   746  	state = terraform.NewState()
   747  	state.Lineage = "changing"
   748  	s.WriteState(state)
   749  	if err := s.PersistState(); err != nil {
   750  		t.Fatalf("bad: %s", err)
   751  	}
   752  
   753  	// Verify the state is where we expect
   754  	{
   755  		f, err := os.Open("local-state.tfstate")
   756  		if err != nil {
   757  			t.Fatalf("err: %s", err)
   758  		}
   759  		actual, err := terraform.ReadState(f)
   760  		f.Close()
   761  		if err != nil {
   762  			t.Fatalf("err: %s", err)
   763  		}
   764  
   765  		if actual.Lineage != state.Lineage {
   766  			t.Fatalf("bad: %#v", actual)
   767  		}
   768  	}
   769  
   770  	// Verify the default paths don't exist
   771  	if _, err := os.Stat(DefaultStateFilename); err == nil {
   772  		t.Fatal("file should not exist")
   773  	}
   774  
   775  	// Verify a backup doesn't exist
   776  	if _, err := os.Stat(DefaultStateFilename + DefaultBackupExtension); err == nil {
   777  		t.Fatal("file should not exist")
   778  	}
   779  }
   780  
   781  // Saved backend state matching config
   782  func TestMetaBackend_configuredUnchanged(t *testing.T) {
   783  	defer testChdir(t, testFixturePath("backend-unchanged"))()
   784  
   785  	// Setup the meta
   786  	m := testMetaBackend(t, nil)
   787  
   788  	// Get the backend
   789  	b, err := m.Backend(&BackendOpts{Init: true})
   790  	if err != nil {
   791  		t.Fatalf("bad: %s", err)
   792  	}
   793  
   794  	// Check the state
   795  	s, err := b.State()
   796  	if err != nil {
   797  		t.Fatalf("bad: %s", err)
   798  	}
   799  	if err := s.RefreshState(); err != nil {
   800  		t.Fatalf("bad: %s", err)
   801  	}
   802  	state := s.State()
   803  	if state == nil {
   804  		t.Fatal("nil state")
   805  	}
   806  	if state.Lineage != "configuredUnchanged" {
   807  		t.Fatalf("bad: %#v", state)
   808  	}
   809  
   810  	// Verify the default paths don't exist
   811  	if _, err := os.Stat(DefaultStateFilename); err == nil {
   812  		t.Fatal("file should not exist")
   813  	}
   814  
   815  	// Verify a backup doesn't exist
   816  	if _, err := os.Stat(DefaultStateFilename + DefaultBackupExtension); err == nil {
   817  		t.Fatal("file should not exist")
   818  	}
   819  }
   820  
   821  // Changing a configured backend
   822  func TestMetaBackend_configuredChange(t *testing.T) {
   823  	// Create a temporary working directory that is empty
   824  	td := tempDir(t)
   825  	copy.CopyDir(testFixturePath("backend-change"), td)
   826  	defer os.RemoveAll(td)
   827  	defer testChdir(t, td)()
   828  
   829  	// Ask input
   830  	defer testInteractiveInput(t, []string{"no"})()
   831  
   832  	// Setup the meta
   833  	m := testMetaBackend(t, nil)
   834  
   835  	// Get the backend
   836  	b, err := m.Backend(&BackendOpts{Init: true})
   837  	if err != nil {
   838  		t.Fatalf("bad: %s", err)
   839  	}
   840  
   841  	// Check the state
   842  	s, err := b.State()
   843  	if err != nil {
   844  		t.Fatalf("bad: %s", err)
   845  	}
   846  	if err := s.RefreshState(); err != nil {
   847  		t.Fatalf("bad: %s", err)
   848  	}
   849  	state := s.State()
   850  	if state != nil {
   851  		t.Fatal("state should be nil")
   852  	}
   853  
   854  	// Verify the default paths don't exist
   855  	if _, err := os.Stat(DefaultStateFilename); err == nil {
   856  		t.Fatal("file should not exist")
   857  	}
   858  
   859  	// Verify a backup doesn't exist
   860  	if _, err := os.Stat(DefaultStateFilename + DefaultBackupExtension); err == nil {
   861  		t.Fatal("file should not exist")
   862  	}
   863  
   864  	// Write some state
   865  	state = terraform.NewState()
   866  	state.Lineage = "changing"
   867  	s.WriteState(state)
   868  	if err := s.PersistState(); err != nil {
   869  		t.Fatalf("bad: %s", err)
   870  	}
   871  
   872  	// Verify the state is where we expect
   873  	{
   874  		f, err := os.Open("local-state-2.tfstate")
   875  		if err != nil {
   876  			t.Fatalf("err: %s", err)
   877  		}
   878  		actual, err := terraform.ReadState(f)
   879  		f.Close()
   880  		if err != nil {
   881  			t.Fatalf("err: %s", err)
   882  		}
   883  
   884  		if actual.Lineage != state.Lineage {
   885  			t.Fatalf("bad: %#v", actual)
   886  		}
   887  	}
   888  
   889  	// Verify no local state
   890  	if _, err := os.Stat(DefaultStateFilename); err == nil {
   891  		t.Fatal("file should not exist")
   892  	}
   893  
   894  	// Verify no local backup
   895  	if _, err := os.Stat(DefaultStateFilename + DefaultBackupExtension); err == nil {
   896  		t.Fatal("file should not exist")
   897  	}
   898  }
   899  
   900  // Changing a configured backend, copying state
   901  func TestMetaBackend_configuredChangeCopy(t *testing.T) {
   902  	// Create a temporary working directory that is empty
   903  	td := tempDir(t)
   904  	copy.CopyDir(testFixturePath("backend-change"), td)
   905  	defer os.RemoveAll(td)
   906  	defer testChdir(t, td)()
   907  
   908  	// Ask input
   909  	defer testInteractiveInput(t, []string{"yes", "yes"})()
   910  
   911  	// Setup the meta
   912  	m := testMetaBackend(t, nil)
   913  
   914  	// Get the backend
   915  	b, err := m.Backend(&BackendOpts{Init: true})
   916  	if err != nil {
   917  		t.Fatalf("bad: %s", err)
   918  	}
   919  
   920  	// Check the state
   921  	s, err := b.State()
   922  	if err != nil {
   923  		t.Fatalf("bad: %s", err)
   924  	}
   925  	if err := s.RefreshState(); err != nil {
   926  		t.Fatalf("bad: %s", err)
   927  	}
   928  	state := s.State()
   929  	if state == nil {
   930  		t.Fatal("state should not be nil")
   931  	}
   932  	if state.Lineage != "backend-change" {
   933  		t.Fatalf("bad: %#v", state)
   934  	}
   935  
   936  	// Verify no local state
   937  	if _, err := os.Stat(DefaultStateFilename); err == nil {
   938  		t.Fatal("file should not exist")
   939  	}
   940  
   941  	// Verify no local backup
   942  	if _, err := os.Stat(DefaultStateFilename + DefaultBackupExtension); err == nil {
   943  		t.Fatal("file should not exist")
   944  	}
   945  }
   946  
   947  // Unsetting a saved backend
   948  func TestMetaBackend_configuredUnset(t *testing.T) {
   949  	// Create a temporary working directory that is empty
   950  	td := tempDir(t)
   951  	copy.CopyDir(testFixturePath("backend-unset"), td)
   952  	defer os.RemoveAll(td)
   953  	defer testChdir(t, td)()
   954  
   955  	// Ask input
   956  	defer testInteractiveInput(t, []string{"no"})()
   957  
   958  	// Setup the meta
   959  	m := testMetaBackend(t, nil)
   960  
   961  	// Get the backend
   962  	b, err := m.Backend(&BackendOpts{Init: true})
   963  	if err != nil {
   964  		t.Fatalf("bad: %s", err)
   965  	}
   966  
   967  	// Check the state
   968  	s, err := b.State()
   969  	if err != nil {
   970  		t.Fatalf("bad: %s", err)
   971  	}
   972  	if err := s.RefreshState(); err != nil {
   973  		t.Fatalf("bad: %s", err)
   974  	}
   975  	state := s.State()
   976  	if state != nil {
   977  		t.Fatal("state should be nil")
   978  	}
   979  
   980  	// Verify the default paths don't exist
   981  	if !isEmptyState(DefaultStateFilename) {
   982  		data, _ := ioutil.ReadFile(DefaultStateFilename)
   983  		t.Fatal("state should not exist, but contains:\n", string(data))
   984  	}
   985  
   986  	// Verify a backup doesn't exist
   987  	if !isEmptyState(DefaultStateFilename + DefaultBackupExtension) {
   988  		data, _ := ioutil.ReadFile(DefaultStateFilename + DefaultBackupExtension)
   989  		t.Fatal("backup should not exist, but contains:\n", string(data))
   990  	}
   991  
   992  	// Verify we have no configured backend/legacy
   993  	path := filepath.Join(m.DataDir(), DefaultStateFilename)
   994  	if _, err := os.Stat(path); err == nil {
   995  		f, err := os.Open(path)
   996  		if err != nil {
   997  			t.Fatalf("err: %s", err)
   998  		}
   999  		actual, err := terraform.ReadState(f)
  1000  		f.Close()
  1001  		if err != nil {
  1002  			t.Fatalf("err: %s", err)
  1003  		}
  1004  
  1005  		if !actual.Remote.Empty() {
  1006  			t.Fatalf("bad: %#v", actual)
  1007  		}
  1008  		if !actual.Backend.Empty() {
  1009  			t.Fatalf("bad: %#v", actual)
  1010  		}
  1011  	}
  1012  
  1013  	// Write some state
  1014  	s.WriteState(testState())
  1015  	if err := s.PersistState(); err != nil {
  1016  		t.Fatalf("bad: %s", err)
  1017  	}
  1018  
  1019  	// Verify it exists where we expect it to
  1020  	if isEmptyState(DefaultStateFilename) {
  1021  		t.Fatal(DefaultStateFilename, "is empty")
  1022  	}
  1023  
  1024  	// Verify no backup since it was empty to start
  1025  	if !isEmptyState(DefaultStateFilename + DefaultBackupExtension) {
  1026  		data, _ := ioutil.ReadFile(DefaultStateFilename + DefaultBackupExtension)
  1027  		t.Fatal("backup state should be empty, but contains:\n", string(data))
  1028  	}
  1029  }
  1030  
  1031  // Unsetting a saved backend and copying the remote state
  1032  func TestMetaBackend_configuredUnsetCopy(t *testing.T) {
  1033  	// Create a temporary working directory that is empty
  1034  	td := tempDir(t)
  1035  	copy.CopyDir(testFixturePath("backend-unset"), td)
  1036  	defer os.RemoveAll(td)
  1037  	defer testChdir(t, td)()
  1038  
  1039  	// Ask input
  1040  	defer testInteractiveInput(t, []string{"yes", "yes"})()
  1041  
  1042  	// Setup the meta
  1043  	m := testMetaBackend(t, nil)
  1044  
  1045  	// Get the backend
  1046  	b, err := m.Backend(&BackendOpts{Init: true})
  1047  	if err != nil {
  1048  		t.Fatalf("bad: %s", err)
  1049  	}
  1050  
  1051  	// Check the state
  1052  	s, err := b.State()
  1053  	if err != nil {
  1054  		t.Fatalf("bad: %s", err)
  1055  	}
  1056  	if err := s.RefreshState(); err != nil {
  1057  		t.Fatalf("bad: %s", err)
  1058  	}
  1059  	state := s.State()
  1060  	if state == nil {
  1061  		t.Fatal("state is nil")
  1062  	}
  1063  	if state.Lineage != "configuredUnset" {
  1064  		t.Fatalf("bad: %#v", state)
  1065  	}
  1066  
  1067  	// Verify a backup doesn't exist
  1068  	if !isEmptyState(DefaultStateFilename + DefaultBackupExtension) {
  1069  		t.Fatalf("backup state should be empty")
  1070  	}
  1071  
  1072  	// Verify we have no configured backend/legacy
  1073  	path := filepath.Join(m.DataDir(), DefaultStateFilename)
  1074  	if _, err := os.Stat(path); err == nil {
  1075  		f, err := os.Open(path)
  1076  		if err != nil {
  1077  			t.Fatalf("err: %s", err)
  1078  		}
  1079  		actual, err := terraform.ReadState(f)
  1080  		f.Close()
  1081  		if err != nil {
  1082  			t.Fatalf("err: %s", err)
  1083  		}
  1084  
  1085  		if !actual.Remote.Empty() {
  1086  			t.Fatalf("bad: %#v", actual)
  1087  		}
  1088  		if !actual.Backend.Empty() {
  1089  			t.Fatalf("bad: %#v", actual)
  1090  		}
  1091  	}
  1092  
  1093  	// Write some state
  1094  	s.WriteState(testState())
  1095  	if err := s.PersistState(); err != nil {
  1096  		t.Fatalf("bad: %s", err)
  1097  	}
  1098  
  1099  	// Verify it exists where we expect it to
  1100  	if _, err := os.Stat(DefaultStateFilename); err != nil {
  1101  		t.Fatalf("err: %s", err)
  1102  	}
  1103  
  1104  	// Verify a backup since it wasn't empty to start
  1105  	if isEmptyState(DefaultStateFilename + DefaultBackupExtension) {
  1106  		t.Fatal("backup is empty")
  1107  	}
  1108  }
  1109  
  1110  // Saved backend state matching config, with legacy
  1111  func TestMetaBackend_configuredUnchangedLegacy(t *testing.T) {
  1112  	// Create a temporary working directory that is empty
  1113  	td := tempDir(t)
  1114  	copy.CopyDir(testFixturePath("backend-unchanged-with-legacy"), td)
  1115  	defer os.RemoveAll(td)
  1116  	defer testChdir(t, td)()
  1117  
  1118  	// Ask input
  1119  	defer testInteractiveInput(t, []string{"no"})()
  1120  
  1121  	// Setup the meta
  1122  	m := testMetaBackend(t, nil)
  1123  
  1124  	// Get the backend
  1125  	b, err := m.Backend(&BackendOpts{Init: true})
  1126  	if err != nil {
  1127  		t.Fatalf("bad: %s", err)
  1128  	}
  1129  
  1130  	// Check the state
  1131  	s, err := b.State()
  1132  	if err != nil {
  1133  		t.Fatalf("bad: %s", err)
  1134  	}
  1135  	if err := s.RefreshState(); err != nil {
  1136  		t.Fatalf("bad: %s", err)
  1137  	}
  1138  	state := s.State()
  1139  	if state == nil {
  1140  		t.Fatal("state is nil")
  1141  	}
  1142  	if state.Lineage != "configured" {
  1143  		t.Fatalf("bad: %#v", state)
  1144  	}
  1145  
  1146  	// Verify the default paths don't exist
  1147  	if _, err := os.Stat(DefaultStateFilename); err == nil {
  1148  		t.Fatalf("err: %s", err)
  1149  	}
  1150  
  1151  	// Verify a backup doesn't exist
  1152  	if _, err := os.Stat(DefaultStateFilename + DefaultBackupExtension); err == nil {
  1153  		t.Fatal("file should not exist")
  1154  	}
  1155  
  1156  	// Verify we have no configured legacy
  1157  	{
  1158  		path := filepath.Join(m.DataDir(), DefaultStateFilename)
  1159  		f, err := os.Open(path)
  1160  		if err != nil {
  1161  			t.Fatalf("err: %s", err)
  1162  		}
  1163  		actual, err := terraform.ReadState(f)
  1164  		f.Close()
  1165  		if err != nil {
  1166  			t.Fatalf("err: %s", err)
  1167  		}
  1168  
  1169  		if !actual.Remote.Empty() {
  1170  			t.Fatalf("bad: %#v", actual)
  1171  		}
  1172  		if actual.Backend.Empty() {
  1173  			t.Fatalf("bad: %#v", actual)
  1174  		}
  1175  	}
  1176  
  1177  	// Write some state
  1178  	state = terraform.NewState()
  1179  	state.Lineage = "changing"
  1180  	s.WriteState(state)
  1181  	if err := s.PersistState(); err != nil {
  1182  		t.Fatalf("bad: %s", err)
  1183  	}
  1184  
  1185  	// Verify the state is where we expect
  1186  	{
  1187  		f, err := os.Open("local-state.tfstate")
  1188  		if err != nil {
  1189  			t.Fatalf("err: %s", err)
  1190  		}
  1191  		actual, err := terraform.ReadState(f)
  1192  		f.Close()
  1193  		if err != nil {
  1194  			t.Fatalf("err: %s", err)
  1195  		}
  1196  
  1197  		if actual.Lineage != state.Lineage {
  1198  			t.Fatalf("bad: %#v", actual)
  1199  		}
  1200  	}
  1201  
  1202  	// Verify no local state
  1203  	if _, err := os.Stat(DefaultStateFilename); err == nil {
  1204  		t.Fatal("file should not exist")
  1205  	}
  1206  
  1207  	// Verify no local backup
  1208  	if _, err := os.Stat(DefaultStateFilename + DefaultBackupExtension); err == nil {
  1209  		t.Fatal("file should not exist")
  1210  	}
  1211  }
  1212  
  1213  // Saved backend state matching config, with legacy
  1214  func TestMetaBackend_configuredUnchangedLegacyCopy(t *testing.T) {
  1215  	// Create a temporary working directory that is empty
  1216  	td := tempDir(t)
  1217  	copy.CopyDir(testFixturePath("backend-unchanged-with-legacy"), td)
  1218  	defer os.RemoveAll(td)
  1219  	defer testChdir(t, td)()
  1220  
  1221  	// Ask input
  1222  	defer testInteractiveInput(t, []string{"yes", "yes"})()
  1223  
  1224  	// Setup the meta
  1225  	m := testMetaBackend(t, nil)
  1226  
  1227  	// Get the backend
  1228  	b, err := m.Backend(&BackendOpts{Init: true})
  1229  	if err != nil {
  1230  		t.Fatalf("bad: %s", err)
  1231  	}
  1232  
  1233  	// Check the state
  1234  	s, err := b.State()
  1235  	if err != nil {
  1236  		t.Fatalf("bad: %s", err)
  1237  	}
  1238  	if err := s.RefreshState(); err != nil {
  1239  		t.Fatalf("bad: %s", err)
  1240  	}
  1241  	state := s.State()
  1242  	if state == nil {
  1243  		t.Fatal("state is nil")
  1244  	}
  1245  	if state.Lineage != "backend-unchanged-with-legacy" {
  1246  		t.Fatalf("bad: %#v", state)
  1247  	}
  1248  
  1249  	// Verify the default paths don't exist
  1250  	if _, err := os.Stat(DefaultStateFilename); err == nil {
  1251  		t.Fatal("file should not exist")
  1252  	}
  1253  
  1254  	// Verify a backup doesn't exist
  1255  	if _, err := os.Stat(DefaultStateFilename + DefaultBackupExtension); err == nil {
  1256  		t.Fatal("file should not exist")
  1257  	}
  1258  
  1259  	// Verify we have no configured legacy
  1260  	{
  1261  		path := filepath.Join(m.DataDir(), DefaultStateFilename)
  1262  		f, err := os.Open(path)
  1263  		if err != nil {
  1264  			t.Fatalf("err: %s", err)
  1265  		}
  1266  		actual, err := terraform.ReadState(f)
  1267  		f.Close()
  1268  		if err != nil {
  1269  			t.Fatalf("err: %s", err)
  1270  		}
  1271  
  1272  		if !actual.Remote.Empty() {
  1273  			t.Fatalf("bad: %#v", actual)
  1274  		}
  1275  		if actual.Backend.Empty() {
  1276  			t.Fatalf("bad: %#v", actual)
  1277  		}
  1278  	}
  1279  
  1280  	// Write some state
  1281  	state = terraform.NewState()
  1282  	state.Lineage = "changing"
  1283  	s.WriteState(state)
  1284  	if err := s.PersistState(); err != nil {
  1285  		t.Fatalf("bad: %s", err)
  1286  	}
  1287  
  1288  	// Verify the state is where we expect
  1289  	{
  1290  		f, err := os.Open("local-state.tfstate")
  1291  		if err != nil {
  1292  			t.Fatalf("err: %s", err)
  1293  		}
  1294  		actual, err := terraform.ReadState(f)
  1295  		f.Close()
  1296  		if err != nil {
  1297  			t.Fatalf("err: %s", err)
  1298  		}
  1299  
  1300  		if actual.Lineage != state.Lineage {
  1301  			t.Fatalf("bad: %#v", actual)
  1302  		}
  1303  	}
  1304  
  1305  	// Verify no local state
  1306  	if _, err := os.Stat(DefaultStateFilename); err == nil {
  1307  		t.Fatal("file should not exist")
  1308  	}
  1309  
  1310  	// Verify no local backup
  1311  	if _, err := os.Stat(DefaultStateFilename + DefaultBackupExtension); err == nil {
  1312  		t.Fatal("file should not exist")
  1313  	}
  1314  }
  1315  
  1316  // Saved backend state, new config, legacy remote state
  1317  func TestMetaBackend_configuredChangedLegacy(t *testing.T) {
  1318  	// Create a temporary working directory that is empty
  1319  	td := tempDir(t)
  1320  	copy.CopyDir(testFixturePath("backend-changed-with-legacy"), td)
  1321  	defer os.RemoveAll(td)
  1322  	defer testChdir(t, td)()
  1323  
  1324  	// Ask input
  1325  	defer testInteractiveInput(t, []string{"no", "no"})()
  1326  
  1327  	// Setup the meta
  1328  	m := testMetaBackend(t, nil)
  1329  
  1330  	// Get the backend
  1331  	b, err := m.Backend(&BackendOpts{Init: true})
  1332  	if err != nil {
  1333  		t.Fatalf("bad: %s", err)
  1334  	}
  1335  
  1336  	// Check the state
  1337  	s, err := b.State()
  1338  	if err != nil {
  1339  		t.Fatalf("bad: %s", err)
  1340  	}
  1341  	if err := s.RefreshState(); err != nil {
  1342  		t.Fatalf("bad: %s", err)
  1343  	}
  1344  	state := s.State()
  1345  	if state != nil {
  1346  		t.Fatal("state should be nil")
  1347  	}
  1348  
  1349  	// Verify the default paths don't exist
  1350  	if _, err := os.Stat(DefaultStateFilename); err == nil {
  1351  		t.Fatal("file should not exist")
  1352  	}
  1353  
  1354  	// Verify a backup doesn't exist
  1355  	if _, err := os.Stat(DefaultStateFilename + DefaultBackupExtension); err == nil {
  1356  		t.Fatal("file should not exist")
  1357  	}
  1358  
  1359  	// Verify we have no configured legacy
  1360  	{
  1361  		path := filepath.Join(m.DataDir(), DefaultStateFilename)
  1362  		f, err := os.Open(path)
  1363  		if err != nil {
  1364  			t.Fatalf("err: %s", err)
  1365  		}
  1366  		actual, err := terraform.ReadState(f)
  1367  		f.Close()
  1368  		if err != nil {
  1369  			t.Fatalf("err: %s", err)
  1370  		}
  1371  
  1372  		if !actual.Remote.Empty() {
  1373  			t.Fatalf("bad: %#v", actual)
  1374  		}
  1375  		if actual.Backend.Empty() {
  1376  			t.Fatalf("bad: %#v", actual)
  1377  		}
  1378  	}
  1379  
  1380  	// Write some state
  1381  	state = terraform.NewState()
  1382  	state.Lineage = "changing"
  1383  	s.WriteState(state)
  1384  	if err := s.PersistState(); err != nil {
  1385  		t.Fatalf("bad: %s", err)
  1386  	}
  1387  
  1388  	// Verify the state is where we expect
  1389  	{
  1390  		f, err := os.Open("local-state-2.tfstate")
  1391  		if err != nil {
  1392  			t.Fatalf("err: %s", err)
  1393  		}
  1394  		actual, err := terraform.ReadState(f)
  1395  		f.Close()
  1396  		if err != nil {
  1397  			t.Fatalf("err: %s", err)
  1398  		}
  1399  
  1400  		if actual.Lineage != state.Lineage {
  1401  			t.Fatalf("bad: %#v", actual)
  1402  		}
  1403  	}
  1404  
  1405  	// Verify no local state
  1406  	if _, err := os.Stat(DefaultStateFilename); err == nil {
  1407  		t.Fatal("file should not exist")
  1408  	}
  1409  
  1410  	// Verify no local backup
  1411  	if _, err := os.Stat(DefaultStateFilename + DefaultBackupExtension); err == nil {
  1412  		t.Fatal("file should not exist")
  1413  	}
  1414  }
  1415  
  1416  // Saved backend state, new config, legacy remote state
  1417  func TestMetaBackend_configuredChangedLegacyCopyBackend(t *testing.T) {
  1418  	// Create a temporary working directory that is empty
  1419  	td := tempDir(t)
  1420  	copy.CopyDir(testFixturePath("backend-changed-with-legacy"), td)
  1421  	defer os.RemoveAll(td)
  1422  	defer testChdir(t, td)()
  1423  
  1424  	// Ask input
  1425  	defer testInteractiveInput(t, []string{"yes", "yes", "no"})()
  1426  
  1427  	// Setup the meta
  1428  	m := testMetaBackend(t, nil)
  1429  
  1430  	// Get the backend
  1431  	b, err := m.Backend(&BackendOpts{Init: true})
  1432  	if err != nil {
  1433  		t.Fatalf("bad: %s", err)
  1434  	}
  1435  
  1436  	// Check the state
  1437  	s, err := b.State()
  1438  	if err != nil {
  1439  		t.Fatalf("bad: %s", err)
  1440  	}
  1441  	if err := s.RefreshState(); err != nil {
  1442  		t.Fatalf("bad: %s", err)
  1443  	}
  1444  	state := s.State()
  1445  	if state == nil {
  1446  		t.Fatal("state is nil")
  1447  	}
  1448  	if state.Lineage != "configured" {
  1449  		t.Fatalf("bad: %#v", state)
  1450  	}
  1451  
  1452  	// Verify the default paths don't exist
  1453  	if _, err := os.Stat(DefaultStateFilename); err == nil {
  1454  		t.Fatal("file should not exist")
  1455  	}
  1456  
  1457  	// Verify a backup doesn't exist
  1458  	if _, err := os.Stat(DefaultStateFilename + DefaultBackupExtension); err == nil {
  1459  		t.Fatal("file should not exist")
  1460  	}
  1461  
  1462  	// Verify we have no configured legacy
  1463  	{
  1464  		path := filepath.Join(m.DataDir(), DefaultStateFilename)
  1465  		f, err := os.Open(path)
  1466  		if err != nil {
  1467  			t.Fatalf("err: %s", err)
  1468  		}
  1469  		actual, err := terraform.ReadState(f)
  1470  		f.Close()
  1471  		if err != nil {
  1472  			t.Fatalf("err: %s", err)
  1473  		}
  1474  
  1475  		if !actual.Remote.Empty() {
  1476  			t.Fatalf("bad: %#v", actual)
  1477  		}
  1478  		if actual.Backend.Empty() {
  1479  			t.Fatalf("bad: %#v", actual)
  1480  		}
  1481  	}
  1482  
  1483  	// Write some state
  1484  	state = terraform.NewState()
  1485  	state.Lineage = "changing"
  1486  	s.WriteState(state)
  1487  	if err := s.PersistState(); err != nil {
  1488  		t.Fatalf("bad: %s", err)
  1489  	}
  1490  
  1491  	// Verify the state is where we expect
  1492  	{
  1493  		f, err := os.Open("local-state-2.tfstate")
  1494  		if err != nil {
  1495  			t.Fatalf("err: %s", err)
  1496  		}
  1497  		actual, err := terraform.ReadState(f)
  1498  		f.Close()
  1499  		if err != nil {
  1500  			t.Fatalf("err: %s", err)
  1501  		}
  1502  
  1503  		if actual.Lineage != state.Lineage {
  1504  			t.Fatalf("bad: %#v", actual)
  1505  		}
  1506  	}
  1507  
  1508  	// Verify no local state
  1509  	if _, err := os.Stat(DefaultStateFilename); err == nil {
  1510  		t.Fatal("file should not exist")
  1511  	}
  1512  
  1513  	// Verify no local backup
  1514  	if _, err := os.Stat(DefaultStateFilename + DefaultBackupExtension); err == nil {
  1515  		t.Fatal("file should not exist")
  1516  	}
  1517  }
  1518  
  1519  // Saved backend state, new config, legacy remote state
  1520  func TestMetaBackend_configuredChangedLegacyCopyLegacy(t *testing.T) {
  1521  	// Create a temporary working directory that is empty
  1522  	td := tempDir(t)
  1523  	copy.CopyDir(testFixturePath("backend-changed-with-legacy"), td)
  1524  	defer os.RemoveAll(td)
  1525  	defer testChdir(t, td)()
  1526  
  1527  	// Ask input
  1528  	defer testInteractiveInput(t, []string{"no", "yes", "yes"})()
  1529  
  1530  	// Setup the meta
  1531  	m := testMetaBackend(t, nil)
  1532  
  1533  	// Get the backend
  1534  	b, err := m.Backend(&BackendOpts{Init: true})
  1535  	if err != nil {
  1536  		t.Fatalf("bad: %s", err)
  1537  	}
  1538  
  1539  	// Check the state
  1540  	s, err := b.State()
  1541  	if err != nil {
  1542  		t.Fatalf("bad: %s", err)
  1543  	}
  1544  	if err := s.RefreshState(); err != nil {
  1545  		t.Fatalf("bad: %s", err)
  1546  	}
  1547  	state := s.State()
  1548  	if state == nil {
  1549  		t.Fatal("state is nil")
  1550  	}
  1551  	if state.Lineage != "legacy" {
  1552  		t.Fatalf("bad: %#v", state)
  1553  	}
  1554  
  1555  	// Verify the default paths don't exist
  1556  	if _, err := os.Stat(DefaultStateFilename); err == nil {
  1557  		t.Fatal("file should not exist")
  1558  	}
  1559  
  1560  	// Verify a backup doesn't exist
  1561  	if _, err := os.Stat(DefaultStateFilename + DefaultBackupExtension); err == nil {
  1562  		t.Fatal("file should not exist")
  1563  	}
  1564  
  1565  	// Verify we have no configured legacy
  1566  	{
  1567  		path := filepath.Join(m.DataDir(), DefaultStateFilename)
  1568  		f, err := os.Open(path)
  1569  		if err != nil {
  1570  			t.Fatalf("err: %s", err)
  1571  		}
  1572  		actual, err := terraform.ReadState(f)
  1573  		f.Close()
  1574  		if err != nil {
  1575  			t.Fatalf("err: %s", err)
  1576  		}
  1577  
  1578  		if !actual.Remote.Empty() {
  1579  			t.Fatalf("bad: %#v", actual)
  1580  		}
  1581  		if actual.Backend.Empty() {
  1582  			t.Fatalf("bad: %#v", actual)
  1583  		}
  1584  	}
  1585  
  1586  	// Write some state
  1587  	state = terraform.NewState()
  1588  	state.Lineage = "changing"
  1589  	s.WriteState(state)
  1590  	if err := s.PersistState(); err != nil {
  1591  		t.Fatalf("bad: %s", err)
  1592  	}
  1593  
  1594  	// Verify the state is where we expect
  1595  	{
  1596  		f, err := os.Open("local-state-2.tfstate")
  1597  		if err != nil {
  1598  			t.Fatalf("err: %s", err)
  1599  		}
  1600  		actual, err := terraform.ReadState(f)
  1601  		f.Close()
  1602  		if err != nil {
  1603  			t.Fatalf("err: %s", err)
  1604  		}
  1605  
  1606  		if actual.Lineage != state.Lineage {
  1607  			t.Fatalf("bad: %#v", actual)
  1608  		}
  1609  	}
  1610  
  1611  	// Verify no local state
  1612  	if _, err := os.Stat(DefaultStateFilename); err == nil {
  1613  		t.Fatal("file should not exist")
  1614  	}
  1615  
  1616  	// Verify no local backup
  1617  	if _, err := os.Stat(DefaultStateFilename + DefaultBackupExtension); err == nil {
  1618  		t.Fatal("file should not exist")
  1619  	}
  1620  }
  1621  
  1622  // Saved backend state, new config, legacy remote state
  1623  func TestMetaBackend_configuredChangedLegacyCopyBoth(t *testing.T) {
  1624  	// Create a temporary working directory that is empty
  1625  	td := tempDir(t)
  1626  	copy.CopyDir(testFixturePath("backend-changed-with-legacy"), td)
  1627  	defer os.RemoveAll(td)
  1628  	defer testChdir(t, td)()
  1629  
  1630  	// Ask input
  1631  	defer testInteractiveInput(t, []string{"yes", "yes", "yes", "yes"})()
  1632  
  1633  	// Setup the meta
  1634  	m := testMetaBackend(t, nil)
  1635  
  1636  	// Get the backend
  1637  	b, err := m.Backend(&BackendOpts{Init: true})
  1638  	if err != nil {
  1639  		t.Fatalf("bad: %s", err)
  1640  	}
  1641  
  1642  	// Check the state
  1643  	s, err := b.State()
  1644  	if err != nil {
  1645  		t.Fatalf("bad: %s", err)
  1646  	}
  1647  	if err := s.RefreshState(); err != nil {
  1648  		t.Fatalf("bad: %s", err)
  1649  	}
  1650  	state := s.State()
  1651  	if state == nil {
  1652  		t.Fatal("state is nil")
  1653  	}
  1654  	if state.Lineage != "legacy" {
  1655  		t.Fatalf("bad: %#v", state)
  1656  	}
  1657  
  1658  	// Verify the default paths don't exist
  1659  	if _, err := os.Stat(DefaultStateFilename); err == nil {
  1660  		t.Fatal("file should not exist")
  1661  	}
  1662  
  1663  	// Verify a backup doesn't exist
  1664  	if _, err := os.Stat(DefaultStateFilename + DefaultBackupExtension); err == nil {
  1665  		t.Fatal("file should not exist")
  1666  	}
  1667  
  1668  	// Verify we have no configured legacy
  1669  	{
  1670  		path := filepath.Join(m.DataDir(), DefaultStateFilename)
  1671  		f, err := os.Open(path)
  1672  		if err != nil {
  1673  			t.Fatalf("err: %s", err)
  1674  		}
  1675  		actual, err := terraform.ReadState(f)
  1676  		f.Close()
  1677  		if err != nil {
  1678  			t.Fatalf("err: %s", err)
  1679  		}
  1680  
  1681  		if !actual.Remote.Empty() {
  1682  			t.Fatalf("bad: %#v", actual)
  1683  		}
  1684  		if actual.Backend.Empty() {
  1685  			t.Fatalf("bad: %#v", actual)
  1686  		}
  1687  	}
  1688  
  1689  	// Write some state
  1690  	state = terraform.NewState()
  1691  	state.Lineage = "changing"
  1692  	s.WriteState(state)
  1693  	if err := s.PersistState(); err != nil {
  1694  		t.Fatalf("bad: %s", err)
  1695  	}
  1696  
  1697  	// Verify the state is where we expect
  1698  	{
  1699  		f, err := os.Open("local-state-2.tfstate")
  1700  		if err != nil {
  1701  			t.Fatalf("err: %s", err)
  1702  		}
  1703  		actual, err := terraform.ReadState(f)
  1704  		f.Close()
  1705  		if err != nil {
  1706  			t.Fatalf("err: %s", err)
  1707  		}
  1708  
  1709  		if actual.Lineage != state.Lineage {
  1710  			t.Fatalf("bad: %#v", actual)
  1711  		}
  1712  	}
  1713  
  1714  	// Verify no local state
  1715  	if _, err := os.Stat(DefaultStateFilename); err == nil {
  1716  		t.Fatal("file should not exist")
  1717  	}
  1718  
  1719  	// Verify no local backup
  1720  	if _, err := os.Stat(DefaultStateFilename + DefaultBackupExtension); err == nil {
  1721  		t.Fatal("file should not exist")
  1722  	}
  1723  }
  1724  
  1725  // Saved backend state, unset config, legacy remote state
  1726  func TestMetaBackend_configuredUnsetWithLegacyNoCopy(t *testing.T) {
  1727  	// Create a temporary working directory that is empty
  1728  	td := tempDir(t)
  1729  	copy.CopyDir(testFixturePath("backend-unset-with-legacy"), td)
  1730  	defer os.RemoveAll(td)
  1731  	defer testChdir(t, td)()
  1732  
  1733  	// Ask input
  1734  	defer testInteractiveInput(t, []string{"no", "no"})()
  1735  
  1736  	// Setup the meta
  1737  	m := testMetaBackend(t, nil)
  1738  
  1739  	// Get the backend
  1740  	b, err := m.Backend(&BackendOpts{Init: true})
  1741  	if err != nil {
  1742  		t.Fatalf("bad: %s", err)
  1743  	}
  1744  
  1745  	// Check the state
  1746  	s, err := b.State()
  1747  	if err != nil {
  1748  		t.Fatalf("bad: %s", err)
  1749  	}
  1750  	if err := s.RefreshState(); err != nil {
  1751  		t.Fatalf("bad: %s", err)
  1752  	}
  1753  	state := s.State()
  1754  	if state != nil {
  1755  		t.Fatal("state should be nil")
  1756  	}
  1757  
  1758  	// Verify the default paths dont exist since we had no state
  1759  	if !isEmptyState(DefaultStateFilename) {
  1760  		t.Fatal("state should be empty")
  1761  	}
  1762  
  1763  	// Verify a backup doesn't exist
  1764  	if !isEmptyState(DefaultStateFilename + DefaultBackupExtension) {
  1765  		t.Fatal("backup should be empty")
  1766  	}
  1767  
  1768  	// Verify we have no configured backend/legacy
  1769  	path := filepath.Join(m.DataDir(), DefaultStateFilename)
  1770  	if _, err := os.Stat(path); err == nil {
  1771  		f, err := os.Open(path)
  1772  		if err != nil {
  1773  			t.Fatalf("err: %s", err)
  1774  		}
  1775  		actual, err := terraform.ReadState(f)
  1776  		f.Close()
  1777  		if err != nil {
  1778  			t.Fatalf("err: %s", err)
  1779  		}
  1780  
  1781  		if !actual.Remote.Empty() {
  1782  			t.Fatalf("bad: %#v", actual)
  1783  		}
  1784  		if !actual.Backend.Empty() {
  1785  			t.Fatalf("bad: %#v", actual)
  1786  		}
  1787  	}
  1788  
  1789  	// Write some state
  1790  	state = terraform.NewState()
  1791  	state.Lineage = "changing"
  1792  	s.WriteState(state)
  1793  	if err := s.PersistState(); err != nil {
  1794  		t.Fatalf("bad: %s", err)
  1795  	}
  1796  
  1797  	// Verify the state is where we expect
  1798  	{
  1799  		f, err := os.Open(DefaultStateFilename)
  1800  		if err != nil {
  1801  			t.Fatalf("err: %s", err)
  1802  		}
  1803  		actual, err := terraform.ReadState(f)
  1804  		f.Close()
  1805  		if err != nil {
  1806  			t.Fatalf("err: %s", err)
  1807  		}
  1808  
  1809  		if actual.Lineage != state.Lineage {
  1810  			t.Fatalf("bad: %#v", actual)
  1811  		}
  1812  	}
  1813  }
  1814  
  1815  // Saved backend state, unset config, legacy remote state
  1816  func TestMetaBackend_configuredUnsetWithLegacyCopyBackend(t *testing.T) {
  1817  	// Create a temporary working directory that is empty
  1818  	td := tempDir(t)
  1819  	copy.CopyDir(testFixturePath("backend-unset-with-legacy"), td)
  1820  	defer os.RemoveAll(td)
  1821  	defer testChdir(t, td)()
  1822  
  1823  	// Ask input
  1824  	defer testInteractiveInput(t, []string{"yes", "yes", "no"})()
  1825  
  1826  	// Setup the meta
  1827  	m := testMetaBackend(t, nil)
  1828  
  1829  	// Get the backend
  1830  	b, err := m.Backend(&BackendOpts{Init: true})
  1831  	if err != nil {
  1832  		t.Fatalf("bad: %s", err)
  1833  	}
  1834  
  1835  	// Check the state
  1836  	s, err := b.State()
  1837  	if err != nil {
  1838  		t.Fatalf("bad: %s", err)
  1839  	}
  1840  	if err := s.RefreshState(); err != nil {
  1841  		t.Fatalf("bad: %s", err)
  1842  	}
  1843  	state := s.State()
  1844  	if state == nil {
  1845  		t.Fatal("state is nil")
  1846  	}
  1847  	if state.Lineage != "backend" {
  1848  		t.Fatalf("bad: %#v", state)
  1849  	}
  1850  
  1851  	// Verify the default paths exist
  1852  	if isEmptyState(DefaultStateFilename) {
  1853  		t.Fatalf("default state was empty")
  1854  	}
  1855  
  1856  	// Verify a backup doesn't exist
  1857  	if !isEmptyState(DefaultStateFilename + DefaultBackupExtension) {
  1858  		t.Fatal("backupstate should be empty")
  1859  	}
  1860  
  1861  	// Verify we have no configured backend/legacy
  1862  	path := filepath.Join(m.DataDir(), DefaultStateFilename)
  1863  	if _, err := os.Stat(path); err == nil {
  1864  		f, err := os.Open(path)
  1865  		if err != nil {
  1866  			t.Fatalf("err: %s", err)
  1867  		}
  1868  		actual, err := terraform.ReadState(f)
  1869  		f.Close()
  1870  		if err != nil {
  1871  			t.Fatalf("err: %s", err)
  1872  		}
  1873  
  1874  		if !actual.Remote.Empty() {
  1875  			t.Fatalf("bad: %#v", actual)
  1876  		}
  1877  		if !actual.Backend.Empty() {
  1878  			t.Fatalf("bad: %#v", actual)
  1879  		}
  1880  	}
  1881  
  1882  	// Write some state
  1883  	state = terraform.NewState()
  1884  	state.Lineage = "changing"
  1885  	s.WriteState(state)
  1886  	if err := s.PersistState(); err != nil {
  1887  		t.Fatalf("bad: %s", err)
  1888  	}
  1889  
  1890  	// Verify the state is where we expect
  1891  	{
  1892  		f, err := os.Open(DefaultStateFilename)
  1893  		if err != nil {
  1894  			t.Fatalf("err: %s", err)
  1895  		}
  1896  		actual, err := terraform.ReadState(f)
  1897  		f.Close()
  1898  		if err != nil {
  1899  			t.Fatalf("err: %s", err)
  1900  		}
  1901  
  1902  		if actual.Lineage != state.Lineage {
  1903  			t.Fatalf("bad: %#v", actual)
  1904  		}
  1905  	}
  1906  
  1907  	// Verify a local backup
  1908  	if isEmptyState(DefaultStateFilename + DefaultBackupExtension) {
  1909  		t.Fatal("backup is empty")
  1910  	}
  1911  }
  1912  
  1913  // Saved backend state, unset config, legacy remote state
  1914  func TestMetaBackend_configuredUnsetWithLegacyCopyLegacy(t *testing.T) {
  1915  	// Create a temporary working directory that is empty
  1916  	td := tempDir(t)
  1917  	copy.CopyDir(testFixturePath("backend-unset-with-legacy"), td)
  1918  	defer os.RemoveAll(td)
  1919  	defer testChdir(t, td)()
  1920  
  1921  	// Ask input
  1922  	defer testInteractiveInput(t, []string{"no", "yes", "yes"})()
  1923  
  1924  	// Setup the meta
  1925  	m := testMetaBackend(t, nil)
  1926  
  1927  	// Get the backend
  1928  	b, err := m.Backend(&BackendOpts{Init: true})
  1929  	if err != nil {
  1930  		t.Fatalf("bad: %s", err)
  1931  	}
  1932  
  1933  	// Check the state
  1934  	s, err := b.State()
  1935  	if err != nil {
  1936  		t.Fatalf("bad: %s", err)
  1937  	}
  1938  	if err := s.RefreshState(); err != nil {
  1939  		t.Fatalf("bad: %s", err)
  1940  	}
  1941  	state := s.State()
  1942  	if state == nil {
  1943  		t.Fatal("state is nil")
  1944  	}
  1945  	if state.Lineage != "legacy" {
  1946  		t.Fatalf("bad: %#v", state)
  1947  	}
  1948  
  1949  	// Verify the default paths exist
  1950  	if isEmptyState(DefaultStateFilename) {
  1951  		t.Fatalf("default state was empty")
  1952  	}
  1953  
  1954  	// Verify a backup doesn't exist
  1955  	if !isEmptyState(DefaultStateFilename + DefaultBackupExtension) {
  1956  		t.Fatal("backupstate should be empty")
  1957  	}
  1958  
  1959  	// Verify we have no configured backend/legacy
  1960  	path := filepath.Join(m.DataDir(), DefaultStateFilename)
  1961  	if _, err := os.Stat(path); err == nil {
  1962  		f, err := os.Open(path)
  1963  		if err != nil {
  1964  			t.Fatalf("err: %s", err)
  1965  		}
  1966  		actual, err := terraform.ReadState(f)
  1967  		f.Close()
  1968  		if err != nil {
  1969  			t.Fatalf("err: %s", err)
  1970  		}
  1971  
  1972  		if !actual.Remote.Empty() {
  1973  			t.Fatalf("bad: %#v", actual)
  1974  		}
  1975  		if !actual.Backend.Empty() {
  1976  			t.Fatalf("bad: %#v", actual)
  1977  		}
  1978  	}
  1979  
  1980  	// Write some state
  1981  	state = terraform.NewState()
  1982  	state.Lineage = "changing"
  1983  	s.WriteState(state)
  1984  	if err := s.PersistState(); err != nil {
  1985  		t.Fatalf("bad: %s", err)
  1986  	}
  1987  
  1988  	// Verify the state is where we expect
  1989  	{
  1990  		f, err := os.Open(DefaultStateFilename)
  1991  		if err != nil {
  1992  			t.Fatalf("err: %s", err)
  1993  		}
  1994  		actual, err := terraform.ReadState(f)
  1995  		f.Close()
  1996  		if err != nil {
  1997  			t.Fatalf("err: %s", err)
  1998  		}
  1999  
  2000  		if actual.Lineage != state.Lineage {
  2001  			t.Fatalf("bad: %#v", actual)
  2002  		}
  2003  	}
  2004  
  2005  	// Verify a local backup
  2006  	if isEmptyState(DefaultStateFilename + DefaultBackupExtension) {
  2007  		t.Fatal("backup is empty")
  2008  	}
  2009  }
  2010  
  2011  // Saved backend state, unset config, legacy remote state
  2012  func TestMetaBackend_configuredUnsetWithLegacyCopyBoth(t *testing.T) {
  2013  	// Create a temporary working directory that is empty
  2014  	td := tempDir(t)
  2015  	copy.CopyDir(testFixturePath("backend-unset-with-legacy"), td)
  2016  	defer os.RemoveAll(td)
  2017  	defer testChdir(t, td)()
  2018  
  2019  	// Ask input
  2020  	defer testInteractiveInput(t, []string{"yes", "yes", "yes", "yes"})()
  2021  
  2022  	// Setup the meta
  2023  	m := testMetaBackend(t, nil)
  2024  
  2025  	// Get the backend
  2026  	b, err := m.Backend(&BackendOpts{Init: true})
  2027  	if err != nil {
  2028  		t.Fatalf("bad: %s", err)
  2029  	}
  2030  
  2031  	// Check the state
  2032  	s, err := b.State()
  2033  	if err != nil {
  2034  		t.Fatalf("bad: %s", err)
  2035  	}
  2036  	if err := s.RefreshState(); err != nil {
  2037  		t.Fatalf("bad: %s", err)
  2038  	}
  2039  	state := s.State()
  2040  	if state == nil {
  2041  		t.Fatal("state is nil")
  2042  	}
  2043  	if state.Lineage != "legacy" {
  2044  		t.Fatalf("bad: %#v", state)
  2045  	}
  2046  
  2047  	// Verify the default paths exist
  2048  	if isEmptyState(DefaultStateFilename) {
  2049  		t.Fatal("state is empty")
  2050  	}
  2051  
  2052  	// Verify a backup exists
  2053  	if isEmptyState(DefaultStateFilename + DefaultBackupExtension) {
  2054  		t.Fatal("backup is empty")
  2055  	}
  2056  
  2057  	// Verify we have no configured backend/legacy
  2058  	path := filepath.Join(m.DataDir(), DefaultStateFilename)
  2059  	if _, err := os.Stat(path); err == nil {
  2060  		f, err := os.Open(path)
  2061  		if err != nil {
  2062  			t.Fatalf("err: %s", err)
  2063  		}
  2064  		actual, err := terraform.ReadState(f)
  2065  		f.Close()
  2066  		if err != nil {
  2067  			t.Fatalf("err: %s", err)
  2068  		}
  2069  
  2070  		if !actual.Remote.Empty() {
  2071  			t.Fatalf("bad: %#v", actual)
  2072  		}
  2073  		if !actual.Backend.Empty() {
  2074  			t.Fatalf("bad: %#v", actual)
  2075  		}
  2076  	}
  2077  
  2078  	// Write some state
  2079  	state = terraform.NewState()
  2080  	state.Lineage = "changing"
  2081  	s.WriteState(state)
  2082  	if err := s.PersistState(); err != nil {
  2083  		t.Fatalf("bad: %s", err)
  2084  	}
  2085  
  2086  	// Verify the state is where we expect
  2087  	{
  2088  		f, err := os.Open(DefaultStateFilename)
  2089  		if err != nil {
  2090  			t.Fatalf("err: %s", err)
  2091  		}
  2092  		actual, err := terraform.ReadState(f)
  2093  		f.Close()
  2094  		if err != nil {
  2095  			t.Fatalf("err: %s", err)
  2096  		}
  2097  
  2098  		if actual.Lineage != state.Lineage {
  2099  			t.Fatalf("bad: %#v", actual)
  2100  		}
  2101  	}
  2102  
  2103  	// Verify a local backup
  2104  	if isEmptyState(DefaultStateFilename + DefaultBackupExtension) {
  2105  		t.Fatal("backup is empty")
  2106  	}
  2107  }
  2108  
  2109  // A plan that has no backend config
  2110  func TestMetaBackend_planLocal(t *testing.T) {
  2111  	// Create a temporary working directory that is empty
  2112  	td := tempDir(t)
  2113  	copy.CopyDir(testFixturePath("backend-plan-local"), td)
  2114  	defer os.RemoveAll(td)
  2115  	defer testChdir(t, td)()
  2116  
  2117  	// Create the plan
  2118  	plan := &terraform.Plan{
  2119  		Module: testModule(t, "backend-plan-local"),
  2120  		State:  nil,
  2121  	}
  2122  
  2123  	// Setup the meta
  2124  	m := testMetaBackend(t, nil)
  2125  
  2126  	// Get the backend
  2127  	b, err := m.Backend(&BackendOpts{Plan: plan})
  2128  	if err != nil {
  2129  		t.Fatalf("bad: %s", err)
  2130  	}
  2131  
  2132  	// Check the state
  2133  	s, err := b.State()
  2134  	if err != nil {
  2135  		t.Fatalf("bad: %s", err)
  2136  	}
  2137  	if err := s.RefreshState(); err != nil {
  2138  		t.Fatalf("bad: %s", err)
  2139  	}
  2140  	state := s.State()
  2141  	if state != nil {
  2142  		t.Fatalf("state should be nil: %#v", state)
  2143  	}
  2144  
  2145  	// Verify the default path doens't exist
  2146  	if !isEmptyState(DefaultStateFilename) {
  2147  		t.Fatal("expected empty state")
  2148  	}
  2149  
  2150  	// Verify a backup doesn't exists
  2151  	if !isEmptyState(DefaultStateFilename + DefaultBackupExtension) {
  2152  		t.Fatal("expected empty backup")
  2153  	}
  2154  
  2155  	// Verify we have no configured backend/legacy
  2156  	path := filepath.Join(m.DataDir(), DefaultStateFilename)
  2157  	if _, err := os.Stat(path); err == nil {
  2158  		t.Fatalf("should not have backend configured")
  2159  	}
  2160  
  2161  	// Write some state
  2162  	state = terraform.NewState()
  2163  	state.Lineage = "changing"
  2164  	s.WriteState(state)
  2165  	if err := s.PersistState(); err != nil {
  2166  		t.Fatalf("bad: %s", err)
  2167  	}
  2168  
  2169  	// Verify the state is where we expect
  2170  	{
  2171  		f, err := os.Open(DefaultStateFilename)
  2172  		if err != nil {
  2173  			t.Fatalf("err: %s", err)
  2174  		}
  2175  		actual, err := terraform.ReadState(f)
  2176  		f.Close()
  2177  		if err != nil {
  2178  			t.Fatalf("err: %s", err)
  2179  		}
  2180  
  2181  		if actual.Lineage != state.Lineage {
  2182  			t.Fatalf("bad: %#v", actual)
  2183  		}
  2184  	}
  2185  
  2186  	// Verify no local backup
  2187  	if !isEmptyState(DefaultStateFilename + DefaultBackupExtension) {
  2188  		t.Fatalf("backup state should be empty")
  2189  	}
  2190  }
  2191  
  2192  // A plan with a custom state save path
  2193  func TestMetaBackend_planLocalStatePath(t *testing.T) {
  2194  	// Create a temporary working directory that is empty
  2195  	td := tempDir(t)
  2196  	copy.CopyDir(testFixturePath("backend-plan-local"), td)
  2197  	defer os.RemoveAll(td)
  2198  	defer testChdir(t, td)()
  2199  
  2200  	// Create our state
  2201  	original := testState()
  2202  	original.Lineage = "hello"
  2203  
  2204  	// Create the plan
  2205  	plan := &terraform.Plan{
  2206  		Module: testModule(t, "backend-plan-local"),
  2207  		State:  original,
  2208  	}
  2209  
  2210  	// Create an alternate output path
  2211  	statePath := "foo.tfstate"
  2212  
  2213  	// put a initial state there that needs to be backed up
  2214  	err := (&state.LocalState{Path: statePath}).WriteState(original)
  2215  	if err != nil {
  2216  		t.Fatal(err)
  2217  	}
  2218  
  2219  	// Setup the meta
  2220  	m := testMetaBackend(t, nil)
  2221  	m.stateOutPath = statePath
  2222  
  2223  	// Get the backend
  2224  	b, err := m.Backend(&BackendOpts{Plan: plan})
  2225  	if err != nil {
  2226  		t.Fatalf("bad: %s", err)
  2227  	}
  2228  
  2229  	// Check the state
  2230  	s, err := b.State()
  2231  	if err != nil {
  2232  		t.Fatalf("bad: %s", err)
  2233  	}
  2234  	if err := s.RefreshState(); err != nil {
  2235  		t.Fatalf("bad: %s", err)
  2236  	}
  2237  	state := s.State()
  2238  	if state == nil {
  2239  		t.Fatal("state is nil")
  2240  	}
  2241  	if state.Lineage != "hello" {
  2242  		t.Fatalf("bad: %#v", state)
  2243  	}
  2244  
  2245  	// Verify the default path doesn't exist
  2246  	if _, err := os.Stat(DefaultStateFilename); err == nil {
  2247  		t.Fatalf("err: %s", err)
  2248  	}
  2249  
  2250  	// Verify a backup doesn't exists
  2251  	if _, err := os.Stat(DefaultStateFilename + DefaultBackupExtension); err == nil {
  2252  		t.Fatal("file should not exist")
  2253  	}
  2254  
  2255  	// Verify we have no configured backend/legacy
  2256  	path := filepath.Join(m.DataDir(), DefaultStateFilename)
  2257  	if _, err := os.Stat(path); err == nil {
  2258  		t.Fatalf("should not have backend configured")
  2259  	}
  2260  
  2261  	// Write some state
  2262  	state = terraform.NewState()
  2263  	state.Lineage = "changing"
  2264  	s.WriteState(state)
  2265  	if err := s.PersistState(); err != nil {
  2266  		t.Fatalf("bad: %s", err)
  2267  	}
  2268  
  2269  	// Verify the state is where we expect
  2270  	{
  2271  		f, err := os.Open(statePath)
  2272  		if err != nil {
  2273  			t.Fatalf("err: %s", err)
  2274  		}
  2275  		actual, err := terraform.ReadState(f)
  2276  		f.Close()
  2277  		if err != nil {
  2278  			t.Fatalf("err: %s", err)
  2279  		}
  2280  
  2281  		if actual.Lineage != state.Lineage {
  2282  			t.Fatalf("bad: %#v", actual)
  2283  		}
  2284  	}
  2285  
  2286  	// Verify we have a backup
  2287  	if isEmptyState(statePath + DefaultBackupExtension) {
  2288  		t.Fatal("backup is empty")
  2289  	}
  2290  }
  2291  
  2292  // A plan that has no backend config, matching local state
  2293  func TestMetaBackend_planLocalMatch(t *testing.T) {
  2294  	// Create a temporary working directory that is empty
  2295  	td := tempDir(t)
  2296  	copy.CopyDir(testFixturePath("backend-plan-local-match"), td)
  2297  	defer os.RemoveAll(td)
  2298  	defer testChdir(t, td)()
  2299  
  2300  	// Create the plan
  2301  	plan := &terraform.Plan{
  2302  		Module: testModule(t, "backend-plan-local-match"),
  2303  		State:  testStateRead(t, DefaultStateFilename),
  2304  	}
  2305  
  2306  	// Setup the meta
  2307  	m := testMetaBackend(t, nil)
  2308  
  2309  	// Get the backend
  2310  	b, err := m.Backend(&BackendOpts{Plan: plan})
  2311  	if err != nil {
  2312  		t.Fatalf("bad: %s", err)
  2313  	}
  2314  
  2315  	// Check the state
  2316  	s, err := b.State()
  2317  	if err != nil {
  2318  		t.Fatalf("bad: %s", err)
  2319  	}
  2320  	if err := s.RefreshState(); err != nil {
  2321  		t.Fatalf("bad: %s", err)
  2322  	}
  2323  	state := s.State()
  2324  	if state == nil {
  2325  		t.Fatal("should is nil")
  2326  	}
  2327  	if state.Lineage != "hello" {
  2328  		t.Fatalf("bad: %#v", state)
  2329  	}
  2330  
  2331  	// Verify the default path
  2332  	if isEmptyState(DefaultStateFilename) {
  2333  		t.Fatal("state is empty")
  2334  	}
  2335  
  2336  	// Verify a backup exists
  2337  	if _, err := os.Stat(DefaultStateFilename + DefaultBackupExtension); err != nil {
  2338  		t.Fatalf("err: %s", err)
  2339  	}
  2340  
  2341  	// Verify we have no configured backend/legacy
  2342  	path := filepath.Join(m.DataDir(), DefaultStateFilename)
  2343  	if _, err := os.Stat(path); err == nil {
  2344  		t.Fatalf("should not have backend configured")
  2345  	}
  2346  
  2347  	// Write some state
  2348  	state = terraform.NewState()
  2349  	state.Lineage = "changing"
  2350  	s.WriteState(state)
  2351  	if err := s.PersistState(); err != nil {
  2352  		t.Fatalf("bad: %s", err)
  2353  	}
  2354  
  2355  	// Verify the state is where we expect
  2356  	{
  2357  		f, err := os.Open(DefaultStateFilename)
  2358  		if err != nil {
  2359  			t.Fatalf("err: %s", err)
  2360  		}
  2361  		actual, err := terraform.ReadState(f)
  2362  		f.Close()
  2363  		if err != nil {
  2364  			t.Fatalf("err: %s", err)
  2365  		}
  2366  
  2367  		if actual.Lineage != state.Lineage {
  2368  			t.Fatalf("bad: %#v", actual)
  2369  		}
  2370  	}
  2371  
  2372  	// Verify local backup
  2373  	if isEmptyState(DefaultStateFilename + DefaultBackupExtension) {
  2374  		t.Fatal("backup is empty")
  2375  	}
  2376  }
  2377  
  2378  // A plan that has no backend config, mismatched lineage
  2379  func TestMetaBackend_planLocalMismatchLineage(t *testing.T) {
  2380  	// Create a temporary working directory that is empty
  2381  	td := tempDir(t)
  2382  	copy.CopyDir(testFixturePath("backend-plan-local-mismatch-lineage"), td)
  2383  	defer os.RemoveAll(td)
  2384  	defer testChdir(t, td)()
  2385  
  2386  	// Save the original
  2387  	original := testStateRead(t, DefaultStateFilename)
  2388  
  2389  	// Change the lineage
  2390  	planState := testStateRead(t, DefaultStateFilename)
  2391  	planState.Lineage = "bad"
  2392  
  2393  	// Create the plan
  2394  	plan := &terraform.Plan{
  2395  		Module: testModule(t, "backend-plan-local-mismatch-lineage"),
  2396  		State:  planState,
  2397  	}
  2398  
  2399  	// Setup the meta
  2400  	m := testMetaBackend(t, nil)
  2401  
  2402  	// Get the backend
  2403  	_, err := m.Backend(&BackendOpts{Plan: plan})
  2404  	if err == nil {
  2405  		t.Fatal("should have error")
  2406  	}
  2407  	if !strings.Contains(err.Error(), "lineage") {
  2408  		t.Fatalf("bad: %s", err)
  2409  	}
  2410  
  2411  	// Verify our local state didn't change
  2412  	actual := testStateRead(t, DefaultStateFilename)
  2413  	if !actual.Equal(original) {
  2414  		t.Fatalf("bad: %#v", actual)
  2415  	}
  2416  
  2417  	// Verify a backup doesn't exists
  2418  	if _, err := os.Stat(DefaultStateFilename + DefaultBackupExtension); err == nil {
  2419  		t.Fatal("file should not exist")
  2420  	}
  2421  
  2422  	// Verify we have no configured backend/legacy
  2423  	path := filepath.Join(m.DataDir(), DefaultStateFilename)
  2424  	if _, err := os.Stat(path); err == nil {
  2425  		t.Fatalf("should not have backend configured")
  2426  	}
  2427  }
  2428  
  2429  // A plan that has no backend config, newer local
  2430  func TestMetaBackend_planLocalNewer(t *testing.T) {
  2431  	// Create a temporary working directory that is empty
  2432  	td := tempDir(t)
  2433  	copy.CopyDir(testFixturePath("backend-plan-local-newer"), td)
  2434  	defer os.RemoveAll(td)
  2435  	defer testChdir(t, td)()
  2436  
  2437  	// Save the original
  2438  	original := testStateRead(t, DefaultStateFilename)
  2439  
  2440  	// Change the serial
  2441  	planState := testStateRead(t, DefaultStateFilename)
  2442  	planState.Serial = 7
  2443  	planState.RootModule().Dependencies = []string{"foo"}
  2444  
  2445  	// Create the plan
  2446  	plan := &terraform.Plan{
  2447  		Module: testModule(t, "backend-plan-local-newer"),
  2448  		State:  planState,
  2449  	}
  2450  
  2451  	// Setup the meta
  2452  	m := testMetaBackend(t, nil)
  2453  
  2454  	// Get the backend
  2455  	_, err := m.Backend(&BackendOpts{Plan: plan})
  2456  	if err == nil {
  2457  		t.Fatal("should have error")
  2458  	}
  2459  	if !strings.Contains(err.Error(), "older") {
  2460  		t.Fatalf("bad: %s", err)
  2461  	}
  2462  
  2463  	// Verify our local state didn't change
  2464  	actual := testStateRead(t, DefaultStateFilename)
  2465  	if !actual.Equal(original) {
  2466  		t.Fatalf("bad: %#v", actual)
  2467  	}
  2468  
  2469  	// Verify a backup doesn't exists
  2470  	if _, err := os.Stat(DefaultStateFilename + DefaultBackupExtension); err == nil {
  2471  		t.Fatal("file should not exist")
  2472  	}
  2473  
  2474  	// Verify we have no configured backend/legacy
  2475  	path := filepath.Join(m.DataDir(), DefaultStateFilename)
  2476  	if _, err := os.Stat(path); err == nil {
  2477  		t.Fatalf("should not have backend configured")
  2478  	}
  2479  }
  2480  
  2481  // A plan that has a backend in an empty dir
  2482  func TestMetaBackend_planBackendEmptyDir(t *testing.T) {
  2483  	// Create a temporary working directory that is empty
  2484  	td := tempDir(t)
  2485  	copy.CopyDir(testFixturePath("backend-plan-backend-empty"), td)
  2486  	defer os.RemoveAll(td)
  2487  	defer testChdir(t, td)()
  2488  
  2489  	// Get the state for the plan by getting the real state and
  2490  	// adding the backend config to it.
  2491  	original := testStateRead(t, filepath.Join(
  2492  		testFixturePath("backend-plan-backend-empty-config"),
  2493  		"local-state.tfstate"))
  2494  	backendState := testStateRead(t, filepath.Join(
  2495  		testFixturePath("backend-plan-backend-empty-config"),
  2496  		DefaultDataDir, DefaultStateFilename))
  2497  	planState := original.DeepCopy()
  2498  	planState.Backend = backendState.Backend
  2499  
  2500  	// Create the plan
  2501  	plan := &terraform.Plan{
  2502  		Module: testModule(t, "backend-plan-backend-empty-config"),
  2503  		State:  planState,
  2504  	}
  2505  
  2506  	// Setup the meta
  2507  	m := testMetaBackend(t, nil)
  2508  
  2509  	// Get the backend
  2510  	b, err := m.Backend(&BackendOpts{Plan: plan})
  2511  	if err != nil {
  2512  		t.Fatalf("bad: %s", err)
  2513  	}
  2514  
  2515  	// Check the state
  2516  	s, err := b.State()
  2517  	if err != nil {
  2518  		t.Fatalf("bad: %s", err)
  2519  	}
  2520  	if err := s.RefreshState(); err != nil {
  2521  		t.Fatalf("bad: %s", err)
  2522  	}
  2523  	state := s.State()
  2524  	if state == nil {
  2525  		t.Fatal("should is nil")
  2526  	}
  2527  	if state.Lineage != "hello" {
  2528  		t.Fatalf("bad: %#v", state)
  2529  	}
  2530  
  2531  	// Verify the default path doesn't exist
  2532  	if !isEmptyState(DefaultStateFilename) {
  2533  		t.Fatal("state is not empty")
  2534  	}
  2535  
  2536  	// Verify a backup doesn't exist
  2537  	if !isEmptyState(DefaultStateFilename + DefaultBackupExtension) {
  2538  		t.Fatal("backup is not empty")
  2539  	}
  2540  
  2541  	// Verify we have no configured backend/legacy
  2542  	path := filepath.Join(m.DataDir(), DefaultStateFilename)
  2543  	if _, err := os.Stat(path); err == nil {
  2544  		t.Fatalf("should not have backend configured")
  2545  	}
  2546  
  2547  	// Write some state
  2548  	state = terraform.NewState()
  2549  	state.Lineage = "changing"
  2550  	s.WriteState(state)
  2551  	if err := s.PersistState(); err != nil {
  2552  		t.Fatalf("bad: %s", err)
  2553  	}
  2554  
  2555  	// Verify the state is where we expect
  2556  	{
  2557  		f, err := os.Open("local-state.tfstate")
  2558  		if err != nil {
  2559  			t.Fatalf("err: %s", err)
  2560  		}
  2561  		actual, err := terraform.ReadState(f)
  2562  		f.Close()
  2563  		if err != nil {
  2564  			t.Fatalf("err: %s", err)
  2565  		}
  2566  
  2567  		if actual.Lineage != state.Lineage {
  2568  			t.Fatalf("bad: %#v", actual)
  2569  		}
  2570  	}
  2571  
  2572  	// Verify no default path
  2573  	if _, err := os.Stat(DefaultStateFilename); err == nil {
  2574  		t.Fatal("file should not exist")
  2575  	}
  2576  
  2577  	// Verify no local backup
  2578  	if _, err := os.Stat(DefaultStateFilename + DefaultBackupExtension); err == nil {
  2579  		t.Fatal("file should not exist")
  2580  	}
  2581  }
  2582  
  2583  // A plan that has a backend with matching state
  2584  func TestMetaBackend_planBackendMatch(t *testing.T) {
  2585  	// Create a temporary working directory that is empty
  2586  	td := tempDir(t)
  2587  	copy.CopyDir(testFixturePath("backend-plan-backend-match"), td)
  2588  	defer os.RemoveAll(td)
  2589  	defer testChdir(t, td)()
  2590  
  2591  	// Get the state for the plan by getting the real state and
  2592  	// adding the backend config to it.
  2593  	original := testStateRead(t, filepath.Join(
  2594  		testFixturePath("backend-plan-backend-empty-config"),
  2595  		"local-state.tfstate"))
  2596  	backendState := testStateRead(t, filepath.Join(
  2597  		testFixturePath("backend-plan-backend-empty-config"),
  2598  		DefaultDataDir, DefaultStateFilename))
  2599  	planState := original.DeepCopy()
  2600  	planState.Backend = backendState.Backend
  2601  
  2602  	// Create the plan
  2603  	plan := &terraform.Plan{
  2604  		Module: testModule(t, "backend-plan-backend-empty-config"),
  2605  		State:  planState,
  2606  	}
  2607  
  2608  	// Setup the meta
  2609  	m := testMetaBackend(t, nil)
  2610  
  2611  	// Get the backend
  2612  	b, err := m.Backend(&BackendOpts{Plan: plan})
  2613  	if err != nil {
  2614  		t.Fatalf("bad: %s", err)
  2615  	}
  2616  
  2617  	// Check the state
  2618  	s, err := b.State()
  2619  	if err != nil {
  2620  		t.Fatalf("bad: %s", err)
  2621  	}
  2622  	if err := s.RefreshState(); err != nil {
  2623  		t.Fatalf("bad: %s", err)
  2624  	}
  2625  	state := s.State()
  2626  	if state == nil {
  2627  		t.Fatal("should is nil")
  2628  	}
  2629  	if state.Lineage != "hello" {
  2630  		t.Fatalf("bad: %#v", state)
  2631  	}
  2632  
  2633  	// Verify the default path exists
  2634  	if _, err := os.Stat(DefaultStateFilename); err == nil {
  2635  		t.Fatal("file should not exist")
  2636  	}
  2637  
  2638  	// Verify a backup doesn't exist
  2639  	if _, err := os.Stat(DefaultStateFilename + DefaultBackupExtension); err == nil {
  2640  		t.Fatal("file should not exist")
  2641  	}
  2642  
  2643  	// Verify we have no configured backend/legacy
  2644  	path := filepath.Join(m.DataDir(), DefaultStateFilename)
  2645  	if _, err := os.Stat(path); err == nil {
  2646  		t.Fatalf("should not have backend configured")
  2647  	}
  2648  
  2649  	// Write some state
  2650  	state = terraform.NewState()
  2651  	state.Lineage = "changing"
  2652  	s.WriteState(state)
  2653  	if err := s.PersistState(); err != nil {
  2654  		t.Fatalf("bad: %s", err)
  2655  	}
  2656  
  2657  	// Verify the state is where we expect
  2658  	{
  2659  		f, err := os.Open("local-state.tfstate")
  2660  		if err != nil {
  2661  			t.Fatalf("err: %s", err)
  2662  		}
  2663  		actual, err := terraform.ReadState(f)
  2664  		f.Close()
  2665  		if err != nil {
  2666  			t.Fatalf("err: %s", err)
  2667  		}
  2668  
  2669  		if actual.Lineage != state.Lineage {
  2670  			t.Fatalf("bad: %#v", actual)
  2671  		}
  2672  	}
  2673  
  2674  	// Verify no default path
  2675  	if _, err := os.Stat(DefaultStateFilename); err == nil {
  2676  		t.Fatal("file should not exist")
  2677  	}
  2678  
  2679  	// Verify no local backup
  2680  	if _, err := os.Stat(DefaultStateFilename + DefaultBackupExtension); err == nil {
  2681  		t.Fatal("file should not exist")
  2682  	}
  2683  }
  2684  
  2685  // A plan that has a backend with mismatching lineage
  2686  func TestMetaBackend_planBackendMismatchLineage(t *testing.T) {
  2687  	// Create a temporary working directory that is empty
  2688  	td := tempDir(t)
  2689  	copy.CopyDir(testFixturePath("backend-plan-backend-mismatch"), td)
  2690  	defer os.RemoveAll(td)
  2691  	defer testChdir(t, td)()
  2692  
  2693  	// Get the state for the plan by getting the real state and
  2694  	// adding the backend config to it.
  2695  	original := testStateRead(t, filepath.Join(
  2696  		testFixturePath("backend-plan-backend-empty-config"),
  2697  		"local-state.tfstate"))
  2698  	backendState := testStateRead(t, filepath.Join(
  2699  		testFixturePath("backend-plan-backend-empty-config"),
  2700  		DefaultDataDir, DefaultStateFilename))
  2701  	planState := original.DeepCopy()
  2702  	planState.Backend = backendState.Backend
  2703  
  2704  	// Get the real original
  2705  	original = testStateRead(t, "local-state.tfstate")
  2706  
  2707  	// Create the plan
  2708  	plan := &terraform.Plan{
  2709  		Module: testModule(t, "backend-plan-backend-empty-config"),
  2710  		State:  planState,
  2711  	}
  2712  
  2713  	// Setup the meta
  2714  	m := testMetaBackend(t, nil)
  2715  
  2716  	// Get the backend
  2717  	_, err := m.Backend(&BackendOpts{Plan: plan})
  2718  	if err == nil {
  2719  		t.Fatal("should have error")
  2720  	}
  2721  	if !strings.Contains(err.Error(), "lineage") {
  2722  		t.Fatalf("bad: %s", err)
  2723  	}
  2724  
  2725  	// Verify our local state didn't change
  2726  	actual := testStateRead(t, "local-state.tfstate")
  2727  	if !actual.Equal(original) {
  2728  		t.Fatalf("bad: %#v", actual)
  2729  	}
  2730  
  2731  	// Verify a backup doesn't exist
  2732  	if _, err := os.Stat(DefaultStateFilename + DefaultBackupExtension); err == nil {
  2733  		t.Fatal("file should not exist")
  2734  	}
  2735  
  2736  	// Verify we have no configured backend/legacy
  2737  	path := filepath.Join(m.DataDir(), DefaultStateFilename)
  2738  	if _, err := os.Stat(path); err == nil {
  2739  		t.Fatalf("should not have backend configured")
  2740  	}
  2741  
  2742  	// Verify we have no default state
  2743  	if _, err := os.Stat(DefaultStateFilename); err == nil {
  2744  		t.Fatal("file should not exist")
  2745  	}
  2746  }
  2747  
  2748  // A plan that has a legacy remote state
  2749  func TestMetaBackend_planLegacy(t *testing.T) {
  2750  	// Create a temporary working directory that is empty
  2751  	td := tempDir(t)
  2752  	copy.CopyDir(testFixturePath("backend-plan-legacy"), td)
  2753  	defer os.RemoveAll(td)
  2754  	defer testChdir(t, td)()
  2755  
  2756  	// Get the state for the plan by getting the real state and
  2757  	// adding the backend config to it.
  2758  	original := testStateRead(t, filepath.Join(
  2759  		testFixturePath("backend-plan-legacy-data"), "local-state.tfstate"))
  2760  	dataState := testStateRead(t, filepath.Join(
  2761  		testFixturePath("backend-plan-legacy-data"), "state.tfstate"))
  2762  	planState := original.DeepCopy()
  2763  	planState.Remote = dataState.Remote
  2764  
  2765  	// Create the plan
  2766  	plan := &terraform.Plan{
  2767  		Module: testModule(t, "backend-plan-legacy-data"),
  2768  		State:  planState,
  2769  	}
  2770  
  2771  	// Setup the meta
  2772  	m := testMetaBackend(t, nil)
  2773  
  2774  	// Get the backend
  2775  	b, err := m.Backend(&BackendOpts{Plan: plan})
  2776  	if err != nil {
  2777  		t.Fatalf("err: %s", err)
  2778  	}
  2779  
  2780  	// Check the state
  2781  	s, err := b.State()
  2782  	if err != nil {
  2783  		t.Fatalf("bad: %s", err)
  2784  	}
  2785  	if err := s.RefreshState(); err != nil {
  2786  		t.Fatalf("bad: %s", err)
  2787  	}
  2788  	state := s.State()
  2789  	if state == nil {
  2790  		t.Fatal("should is nil")
  2791  	}
  2792  	if state.Lineage != "hello" {
  2793  		t.Fatalf("bad: %#v", state)
  2794  	}
  2795  
  2796  	// Verify the default path
  2797  	if _, err := os.Stat(DefaultStateFilename); err == nil {
  2798  		t.Fatal("file should not exist")
  2799  	}
  2800  
  2801  	// Verify a backup doesn't exist
  2802  	if _, err := os.Stat(DefaultStateFilename + DefaultBackupExtension); err == nil {
  2803  		t.Fatal("file should not exist")
  2804  	}
  2805  
  2806  	// Verify we have no configured backend/legacy
  2807  	path := filepath.Join(m.DataDir(), DefaultStateFilename)
  2808  	if _, err := os.Stat(path); err == nil {
  2809  		t.Fatalf("should not have backend configured")
  2810  	}
  2811  
  2812  	// Write some state
  2813  	state = terraform.NewState()
  2814  	state.Lineage = "changing"
  2815  	s.WriteState(state)
  2816  	if err := s.PersistState(); err != nil {
  2817  		t.Fatalf("bad: %s", err)
  2818  	}
  2819  
  2820  	// Verify the state is where we expect
  2821  	{
  2822  		f, err := os.Open("local-state.tfstate")
  2823  		if err != nil {
  2824  			t.Fatalf("err: %s", err)
  2825  		}
  2826  		actual, err := terraform.ReadState(f)
  2827  		f.Close()
  2828  		if err != nil {
  2829  			t.Fatalf("err: %s", err)
  2830  		}
  2831  
  2832  		if actual.Lineage != state.Lineage {
  2833  			t.Fatalf("bad: %#v", actual)
  2834  		}
  2835  	}
  2836  
  2837  	// Verify no default path
  2838  	if _, err := os.Stat(DefaultStateFilename); err == nil {
  2839  		t.Fatal("file should not exist")
  2840  	}
  2841  
  2842  	// Verify no local backup
  2843  	if _, err := os.Stat(DefaultStateFilename + DefaultBackupExtension); err == nil {
  2844  		t.Fatal("file should not exist")
  2845  	}
  2846  }
  2847  
  2848  func testMetaBackend(t *testing.T, args []string) *Meta {
  2849  	var m Meta
  2850  	m.Ui = new(cli.MockUi)
  2851  	m.process(args, true)
  2852  	f := m.flagSet("test")
  2853  	if err := f.Parse(args); err != nil {
  2854  		t.Fatalf("bad: %s", err)
  2855  	}
  2856  
  2857  	return &m
  2858  }