github.com/simonswine/terraform@v0.9.0-beta2/command/meta_backend_test.go (about)

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