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