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