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

     1  package command
     2  
     3  import (
     4  	"os"
     5  	"path/filepath"
     6  	"testing"
     7  
     8  	"github.com/hashicorp/terraform/terraform"
     9  	"github.com/mitchellh/cli"
    10  )
    11  
    12  func TestStateMv(t *testing.T) {
    13  	state := &terraform.State{
    14  		Modules: []*terraform.ModuleState{
    15  			&terraform.ModuleState{
    16  				Path: []string{"root"},
    17  				Resources: map[string]*terraform.ResourceState{
    18  					"test_instance.foo": &terraform.ResourceState{
    19  						Type: "test_instance",
    20  						Primary: &terraform.InstanceState{
    21  							ID: "bar",
    22  							Attributes: map[string]string{
    23  								"foo": "value",
    24  								"bar": "value",
    25  							},
    26  						},
    27  					},
    28  
    29  					"test_instance.baz": &terraform.ResourceState{
    30  						Type: "test_instance",
    31  						Primary: &terraform.InstanceState{
    32  							ID: "foo",
    33  							Attributes: map[string]string{
    34  								"foo": "value",
    35  								"bar": "value",
    36  							},
    37  						},
    38  					},
    39  				},
    40  			},
    41  		},
    42  	}
    43  
    44  	statePath := testStateFile(t, state)
    45  
    46  	p := testProvider()
    47  	ui := new(cli.MockUi)
    48  	c := &StateMvCommand{
    49  		Meta: Meta{
    50  			ContextOpts: testCtxConfig(p),
    51  			Ui:          ui,
    52  		},
    53  	}
    54  
    55  	args := []string{
    56  		"-state", statePath,
    57  		"test_instance.foo",
    58  		"test_instance.bar",
    59  	}
    60  	if code := c.Run(args); code != 0 {
    61  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
    62  	}
    63  
    64  	// Test it is correct
    65  	testStateOutput(t, statePath, testStateMvOutput)
    66  
    67  	// Test we have backups
    68  	backups := testStateBackups(t, filepath.Dir(statePath))
    69  	if len(backups) != 1 {
    70  		t.Fatalf("bad: %#v", backups)
    71  	}
    72  	testStateOutput(t, backups[0], testStateMvOutputOriginal)
    73  }
    74  
    75  func TestStateMv_backupExplicit(t *testing.T) {
    76  	td := tempDir(t)
    77  	defer os.RemoveAll(td)
    78  	backupPath := filepath.Join(td, "backup")
    79  
    80  	state := &terraform.State{
    81  		Modules: []*terraform.ModuleState{
    82  			&terraform.ModuleState{
    83  				Path: []string{"root"},
    84  				Resources: map[string]*terraform.ResourceState{
    85  					"test_instance.foo": &terraform.ResourceState{
    86  						Type: "test_instance",
    87  						Primary: &terraform.InstanceState{
    88  							ID: "bar",
    89  							Attributes: map[string]string{
    90  								"foo": "value",
    91  								"bar": "value",
    92  							},
    93  						},
    94  					},
    95  
    96  					"test_instance.baz": &terraform.ResourceState{
    97  						Type: "test_instance",
    98  						Primary: &terraform.InstanceState{
    99  							ID: "foo",
   100  							Attributes: map[string]string{
   101  								"foo": "value",
   102  								"bar": "value",
   103  							},
   104  						},
   105  					},
   106  				},
   107  			},
   108  		},
   109  	}
   110  
   111  	statePath := testStateFile(t, state)
   112  
   113  	p := testProvider()
   114  	ui := new(cli.MockUi)
   115  	c := &StateMvCommand{
   116  		Meta: Meta{
   117  			ContextOpts: testCtxConfig(p),
   118  			Ui:          ui,
   119  		},
   120  	}
   121  
   122  	args := []string{
   123  		"-backup", backupPath,
   124  		"-state", statePath,
   125  		"test_instance.foo",
   126  		"test_instance.bar",
   127  	}
   128  	if code := c.Run(args); code != 0 {
   129  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
   130  	}
   131  
   132  	// Test it is correct
   133  	testStateOutput(t, statePath, testStateMvOutput)
   134  
   135  	// Test we have backups
   136  	backups := testStateBackups(t, filepath.Dir(statePath))
   137  	if len(backups) != 1 {
   138  		t.Fatalf("bad: %#v", backups)
   139  	}
   140  	testStateOutput(t, backups[0], testStateMvOutputOriginal)
   141  	testStateOutput(t, backupPath, testStateMvOutputOriginal)
   142  }
   143  
   144  func TestStateMv_stateOutNew(t *testing.T) {
   145  	state := &terraform.State{
   146  		Modules: []*terraform.ModuleState{
   147  			&terraform.ModuleState{
   148  				Path: []string{"root"},
   149  				Resources: map[string]*terraform.ResourceState{
   150  					"test_instance.foo": &terraform.ResourceState{
   151  						Type: "test_instance",
   152  						Primary: &terraform.InstanceState{
   153  							ID: "bar",
   154  							Attributes: map[string]string{
   155  								"foo": "value",
   156  								"bar": "value",
   157  							},
   158  						},
   159  					},
   160  				},
   161  			},
   162  		},
   163  	}
   164  
   165  	statePath := testStateFile(t, state)
   166  	stateOutPath := statePath + ".out"
   167  
   168  	p := testProvider()
   169  	ui := new(cli.MockUi)
   170  	c := &StateMvCommand{
   171  		Meta: Meta{
   172  			ContextOpts: testCtxConfig(p),
   173  			Ui:          ui,
   174  		},
   175  	}
   176  
   177  	args := []string{
   178  		"-state", statePath,
   179  		"-state-out", stateOutPath,
   180  		"test_instance.foo",
   181  		"test_instance.bar",
   182  	}
   183  	if code := c.Run(args); code != 0 {
   184  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
   185  	}
   186  
   187  	// Test it is correct
   188  	testStateOutput(t, stateOutPath, testStateMvOutput_stateOut)
   189  	testStateOutput(t, statePath, testStateMvOutput_stateOutSrc)
   190  
   191  	// Test we have backups
   192  	backups := testStateBackups(t, filepath.Dir(statePath))
   193  	if len(backups) != 1 {
   194  		t.Fatalf("bad: %#v", backups)
   195  	}
   196  	testStateOutput(t, backups[0], testStateMvOutput_stateOutOriginal)
   197  }
   198  
   199  func TestStateMv_stateOutExisting(t *testing.T) {
   200  	stateSrc := &terraform.State{
   201  		Modules: []*terraform.ModuleState{
   202  			&terraform.ModuleState{
   203  				Path: []string{"root"},
   204  				Resources: map[string]*terraform.ResourceState{
   205  					"test_instance.foo": &terraform.ResourceState{
   206  						Type: "test_instance",
   207  						Primary: &terraform.InstanceState{
   208  							ID: "bar",
   209  							Attributes: map[string]string{
   210  								"foo": "value",
   211  								"bar": "value",
   212  							},
   213  						},
   214  					},
   215  				},
   216  			},
   217  		},
   218  	}
   219  
   220  	statePath := testStateFile(t, stateSrc)
   221  
   222  	stateDst := &terraform.State{
   223  		Modules: []*terraform.ModuleState{
   224  			&terraform.ModuleState{
   225  				Path: []string{"root"},
   226  				Resources: map[string]*terraform.ResourceState{
   227  					"test_instance.qux": &terraform.ResourceState{
   228  						Type: "test_instance",
   229  						Primary: &terraform.InstanceState{
   230  							ID: "bar",
   231  						},
   232  					},
   233  				},
   234  			},
   235  		},
   236  	}
   237  
   238  	stateOutPath := testStateFile(t, stateDst)
   239  
   240  	p := testProvider()
   241  	ui := new(cli.MockUi)
   242  	c := &StateMvCommand{
   243  		Meta: Meta{
   244  			ContextOpts: testCtxConfig(p),
   245  			Ui:          ui,
   246  		},
   247  	}
   248  
   249  	args := []string{
   250  		"-state", statePath,
   251  		"-state-out", stateOutPath,
   252  		"test_instance.foo",
   253  		"test_instance.bar",
   254  	}
   255  	if code := c.Run(args); code != 0 {
   256  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
   257  	}
   258  
   259  	// Test it is correct
   260  	testStateOutput(t, stateOutPath, testStateMvExisting_stateDst)
   261  	testStateOutput(t, statePath, testStateMvExisting_stateSrc)
   262  
   263  	// Test we have backups
   264  	backups := testStateBackups(t, filepath.Dir(statePath))
   265  	if len(backups) != 1 {
   266  		t.Fatalf("bad: %#v", backups)
   267  	}
   268  	testStateOutput(t, backups[0], testStateMvExisting_stateSrcOriginal)
   269  
   270  	backups = testStateBackups(t, filepath.Dir(stateOutPath))
   271  	if len(backups) != 1 {
   272  		t.Fatalf("bad: %#v", backups)
   273  	}
   274  	testStateOutput(t, backups[0], testStateMvExisting_stateDstOriginal)
   275  }
   276  
   277  func TestStateMv_noState(t *testing.T) {
   278  	tmp, cwd := testCwd(t)
   279  	defer testFixCwd(t, tmp, cwd)
   280  
   281  	p := testProvider()
   282  	ui := new(cli.MockUi)
   283  	c := &StateMvCommand{
   284  		Meta: Meta{
   285  			ContextOpts: testCtxConfig(p),
   286  			Ui:          ui,
   287  		},
   288  	}
   289  
   290  	args := []string{"from", "to"}
   291  	if code := c.Run(args); code != 1 {
   292  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
   293  	}
   294  }
   295  
   296  func TestStateMv_stateOutNew_count(t *testing.T) {
   297  	state := &terraform.State{
   298  		Modules: []*terraform.ModuleState{
   299  			&terraform.ModuleState{
   300  				Path: []string{"root"},
   301  				Resources: map[string]*terraform.ResourceState{
   302  					"test_instance.foo.0": &terraform.ResourceState{
   303  						Type: "test_instance",
   304  						Primary: &terraform.InstanceState{
   305  							ID: "foo",
   306  							Attributes: map[string]string{
   307  								"foo": "value",
   308  								"bar": "value",
   309  							},
   310  						},
   311  					},
   312  
   313  					"test_instance.foo.1": &terraform.ResourceState{
   314  						Type: "test_instance",
   315  						Primary: &terraform.InstanceState{
   316  							ID: "bar",
   317  							Attributes: map[string]string{
   318  								"foo": "value",
   319  								"bar": "value",
   320  							},
   321  						},
   322  					},
   323  
   324  					"test_instance.bar": &terraform.ResourceState{
   325  						Type: "test_instance",
   326  						Primary: &terraform.InstanceState{
   327  							ID: "bar",
   328  							Attributes: map[string]string{
   329  								"foo": "value",
   330  								"bar": "value",
   331  							},
   332  						},
   333  					},
   334  				},
   335  			},
   336  		},
   337  	}
   338  
   339  	statePath := testStateFile(t, state)
   340  	stateOutPath := statePath + ".out"
   341  
   342  	p := testProvider()
   343  	ui := new(cli.MockUi)
   344  	c := &StateMvCommand{
   345  		Meta: Meta{
   346  			ContextOpts: testCtxConfig(p),
   347  			Ui:          ui,
   348  		},
   349  	}
   350  
   351  	args := []string{
   352  		"-state", statePath,
   353  		"-state-out", stateOutPath,
   354  		"test_instance.foo",
   355  		"test_instance.bar",
   356  	}
   357  	if code := c.Run(args); code != 0 {
   358  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
   359  	}
   360  
   361  	// Test it is correct
   362  	testStateOutput(t, stateOutPath, testStateMvCount_stateOut)
   363  	testStateOutput(t, statePath, testStateMvCount_stateOutSrc)
   364  
   365  	// Test we have backups
   366  	backups := testStateBackups(t, filepath.Dir(statePath))
   367  	if len(backups) != 1 {
   368  		t.Fatalf("bad: %#v", backups)
   369  	}
   370  	testStateOutput(t, backups[0], testStateMvCount_stateOutOriginal)
   371  }
   372  
   373  func TestStateMv_stateOutNew_nestedModule(t *testing.T) {
   374  	state := &terraform.State{
   375  		Modules: []*terraform.ModuleState{
   376  			&terraform.ModuleState{
   377  				Path:      []string{"root"},
   378  				Resources: map[string]*terraform.ResourceState{},
   379  			},
   380  
   381  			&terraform.ModuleState{
   382  				Path:      []string{"root", "foo"},
   383  				Resources: map[string]*terraform.ResourceState{},
   384  			},
   385  
   386  			&terraform.ModuleState{
   387  				Path: []string{"root", "foo", "child1"},
   388  				Resources: map[string]*terraform.ResourceState{
   389  					"test_instance.foo": &terraform.ResourceState{
   390  						Type: "test_instance",
   391  						Primary: &terraform.InstanceState{
   392  							ID: "bar",
   393  							Attributes: map[string]string{
   394  								"foo": "value",
   395  								"bar": "value",
   396  							},
   397  						},
   398  					},
   399  				},
   400  			},
   401  
   402  			&terraform.ModuleState{
   403  				Path: []string{"root", "foo", "child2"},
   404  				Resources: map[string]*terraform.ResourceState{
   405  					"test_instance.foo": &terraform.ResourceState{
   406  						Type: "test_instance",
   407  						Primary: &terraform.InstanceState{
   408  							ID: "bar",
   409  							Attributes: map[string]string{
   410  								"foo": "value",
   411  								"bar": "value",
   412  							},
   413  						},
   414  					},
   415  				},
   416  			},
   417  		},
   418  	}
   419  
   420  	statePath := testStateFile(t, state)
   421  	stateOutPath := statePath + ".out"
   422  
   423  	p := testProvider()
   424  	ui := new(cli.MockUi)
   425  	c := &StateMvCommand{
   426  		Meta: Meta{
   427  			ContextOpts: testCtxConfig(p),
   428  			Ui:          ui,
   429  		},
   430  	}
   431  
   432  	args := []string{
   433  		"-state", statePath,
   434  		"-state-out", stateOutPath,
   435  		"module.foo",
   436  		"module.bar",
   437  	}
   438  	if code := c.Run(args); code != 0 {
   439  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
   440  	}
   441  
   442  	// Test it is correct
   443  	testStateOutput(t, stateOutPath, testStateMvNestedModule_stateOut)
   444  	testStateOutput(t, statePath, testStateMvNestedModule_stateOutSrc)
   445  
   446  	// Test we have backups
   447  	backups := testStateBackups(t, filepath.Dir(statePath))
   448  	if len(backups) != 1 {
   449  		t.Fatalf("bad: %#v", backups)
   450  	}
   451  	testStateOutput(t, backups[0], testStateMvNestedModule_stateOutOriginal)
   452  }
   453  
   454  const testStateMvOutputOriginal = `
   455  test_instance.baz:
   456    ID = foo
   457    bar = value
   458    foo = value
   459  test_instance.foo:
   460    ID = bar
   461    bar = value
   462    foo = value
   463  `
   464  
   465  const testStateMvOutput = `
   466  test_instance.bar:
   467    ID = bar
   468    bar = value
   469    foo = value
   470  test_instance.baz:
   471    ID = foo
   472    bar = value
   473    foo = value
   474  `
   475  
   476  const testStateMvCount_stateOut = `
   477  test_instance.bar.0:
   478    ID = foo
   479    bar = value
   480    foo = value
   481  test_instance.bar.1:
   482    ID = bar
   483    bar = value
   484    foo = value
   485  `
   486  
   487  const testStateMvCount_stateOutSrc = `
   488  test_instance.bar:
   489    ID = bar
   490    bar = value
   491    foo = value
   492  `
   493  
   494  const testStateMvCount_stateOutOriginal = `
   495  test_instance.bar:
   496    ID = bar
   497    bar = value
   498    foo = value
   499  test_instance.foo.0:
   500    ID = foo
   501    bar = value
   502    foo = value
   503  test_instance.foo.1:
   504    ID = bar
   505    bar = value
   506    foo = value
   507  `
   508  
   509  const testStateMvNestedModule_stateOut = `
   510  <no state>
   511  module.bar:
   512    <no state>
   513  module.bar.child1:
   514    test_instance.foo:
   515      ID = bar
   516      bar = value
   517      foo = value
   518  module.bar.child2:
   519    test_instance.foo:
   520      ID = bar
   521      bar = value
   522      foo = value
   523  `
   524  
   525  const testStateMvNestedModule_stateOutSrc = `
   526  <no state>
   527  `
   528  
   529  const testStateMvNestedModule_stateOutOriginal = `
   530  <no state>
   531  module.foo:
   532    <no state>
   533  module.foo.child1:
   534    test_instance.foo:
   535      ID = bar
   536      bar = value
   537      foo = value
   538  module.foo.child2:
   539    test_instance.foo:
   540      ID = bar
   541      bar = value
   542      foo = value
   543  `
   544  
   545  const testStateMvOutput_stateOut = `
   546  test_instance.bar:
   547    ID = bar
   548    bar = value
   549    foo = value
   550  `
   551  
   552  const testStateMvOutput_stateOutSrc = `
   553  <no state>
   554  `
   555  
   556  const testStateMvOutput_stateOutOriginal = `
   557  test_instance.foo:
   558    ID = bar
   559    bar = value
   560    foo = value
   561  `
   562  
   563  const testStateMvExisting_stateSrc = `
   564  <no state>
   565  `
   566  
   567  const testStateMvExisting_stateDst = `
   568  test_instance.bar:
   569    ID = bar
   570    bar = value
   571    foo = value
   572  test_instance.qux:
   573    ID = bar
   574  `
   575  
   576  const testStateMvExisting_stateSrcOriginal = `
   577  test_instance.foo:
   578    ID = bar
   579    bar = value
   580    foo = value
   581  `
   582  
   583  const testStateMvExisting_stateDstOriginal = `
   584  test_instance.qux:
   585    ID = bar
   586  `