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