github.com/alexissmirnov/terraform@v0.4.3-0.20150423153700-1ef9731a2f14/command/refresh_test.go (about)

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