github.com/ibm-cloud/terraform@v0.6.4-0.20170726051544-8872b87621df/command/init_test.go (about)

     1  package command
     2  
     3  import (
     4  	"io/ioutil"
     5  	"os"
     6  	"path/filepath"
     7  	"strings"
     8  	"testing"
     9  
    10  	"github.com/hashicorp/terraform/helper/copy"
    11  	"github.com/mitchellh/cli"
    12  )
    13  
    14  func TestInit(t *testing.T) {
    15  	dir := tempDir(t)
    16  
    17  	ui := new(cli.MockUi)
    18  	c := &InitCommand{
    19  		Meta: Meta{
    20  			ContextOpts: testCtxConfig(testProvider()),
    21  			Ui:          ui,
    22  		},
    23  	}
    24  
    25  	args := []string{
    26  		testFixturePath("init"),
    27  		dir,
    28  	}
    29  	if code := c.Run(args); code != 0 {
    30  		t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
    31  	}
    32  
    33  	if _, err := os.Stat(filepath.Join(dir, "hello.tf")); err != nil {
    34  		t.Fatalf("err: %s", err)
    35  	}
    36  }
    37  
    38  func TestInit_cwd(t *testing.T) {
    39  	dir := tempDir(t)
    40  	if err := os.MkdirAll(dir, 0755); err != nil {
    41  		t.Fatalf("err: %s", err)
    42  	}
    43  
    44  	// Change to the temporary directory
    45  	cwd, err := os.Getwd()
    46  	if err != nil {
    47  		t.Fatalf("err: %s", err)
    48  	}
    49  	if err := os.Chdir(dir); err != nil {
    50  		t.Fatalf("err: %s", err)
    51  	}
    52  	defer os.Chdir(cwd)
    53  
    54  	ui := new(cli.MockUi)
    55  	c := &InitCommand{
    56  		Meta: Meta{
    57  			ContextOpts: testCtxConfig(testProvider()),
    58  			Ui:          ui,
    59  		},
    60  	}
    61  
    62  	args := []string{
    63  		testFixturePath("init"),
    64  	}
    65  	if code := c.Run(args); code != 0 {
    66  		t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
    67  	}
    68  
    69  	if _, err := os.Stat("hello.tf"); err != nil {
    70  		t.Fatalf("err: %s", err)
    71  	}
    72  }
    73  
    74  func TestInit_empty(t *testing.T) {
    75  	// Create a temporary working directory that is empty
    76  	td := tempDir(t)
    77  	os.MkdirAll(td, 0755)
    78  	defer os.RemoveAll(td)
    79  	defer testChdir(t, td)()
    80  
    81  	ui := new(cli.MockUi)
    82  	c := &InitCommand{
    83  		Meta: Meta{
    84  			ContextOpts: testCtxConfig(testProvider()),
    85  			Ui:          ui,
    86  		},
    87  	}
    88  
    89  	args := []string{}
    90  	if code := c.Run(args); code != 0 {
    91  		t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
    92  	}
    93  }
    94  
    95  func TestInit_multipleArgs(t *testing.T) {
    96  	ui := new(cli.MockUi)
    97  	c := &InitCommand{
    98  		Meta: Meta{
    99  			ContextOpts: testCtxConfig(testProvider()),
   100  			Ui:          ui,
   101  		},
   102  	}
   103  
   104  	args := []string{
   105  		"bad",
   106  		"bad",
   107  	}
   108  	if code := c.Run(args); code != 1 {
   109  		t.Fatalf("bad: \n%s", ui.OutputWriter.String())
   110  	}
   111  }
   112  
   113  // https://github.com/hashicorp/terraform/issues/518
   114  func TestInit_dstInSrc(t *testing.T) {
   115  	dir := tempDir(t)
   116  	if err := os.MkdirAll(dir, 0755); err != nil {
   117  		t.Fatalf("err: %s", err)
   118  	}
   119  
   120  	// Change to the temporary directory
   121  	cwd, err := os.Getwd()
   122  	if err != nil {
   123  		t.Fatalf("err: %s", err)
   124  	}
   125  	if err := os.Chdir(dir); err != nil {
   126  		t.Fatalf("err: %s", err)
   127  	}
   128  	defer os.Chdir(cwd)
   129  
   130  	if _, err := os.Create("issue518.tf"); err != nil {
   131  		t.Fatalf("err: %s", err)
   132  	}
   133  
   134  	ui := new(cli.MockUi)
   135  	c := &InitCommand{
   136  		Meta: Meta{
   137  			ContextOpts: testCtxConfig(testProvider()),
   138  			Ui:          ui,
   139  		},
   140  	}
   141  
   142  	args := []string{
   143  		".",
   144  		"foo",
   145  	}
   146  	if code := c.Run(args); code != 0 {
   147  		t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
   148  	}
   149  
   150  	if _, err := os.Stat(filepath.Join(dir, "foo", "issue518.tf")); err != nil {
   151  		t.Fatalf("err: %s", err)
   152  	}
   153  }
   154  
   155  func TestInit_get(t *testing.T) {
   156  	// Create a temporary working directory that is empty
   157  	td := tempDir(t)
   158  	copy.CopyDir(testFixturePath("init-get"), td)
   159  	defer os.RemoveAll(td)
   160  	defer testChdir(t, td)()
   161  
   162  	ui := new(cli.MockUi)
   163  	c := &InitCommand{
   164  		Meta: Meta{
   165  			ContextOpts: testCtxConfig(testProvider()),
   166  			Ui:          ui,
   167  		},
   168  	}
   169  
   170  	args := []string{}
   171  	if code := c.Run(args); code != 0 {
   172  		t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
   173  	}
   174  
   175  	// Check output
   176  	output := ui.OutputWriter.String()
   177  	if !strings.Contains(output, "Get: file://") {
   178  		t.Fatalf("doesn't look like get: %s", output)
   179  	}
   180  }
   181  
   182  func TestInit_copyGet(t *testing.T) {
   183  	// Create a temporary working directory that is empty
   184  	td := tempDir(t)
   185  	os.MkdirAll(td, 0755)
   186  	defer os.RemoveAll(td)
   187  	defer testChdir(t, td)()
   188  
   189  	ui := new(cli.MockUi)
   190  	c := &InitCommand{
   191  		Meta: Meta{
   192  			ContextOpts: testCtxConfig(testProvider()),
   193  			Ui:          ui,
   194  		},
   195  	}
   196  
   197  	args := []string{
   198  		testFixturePath("init-get"),
   199  	}
   200  	if code := c.Run(args); code != 0 {
   201  		t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
   202  	}
   203  
   204  	// Check copy
   205  	if _, err := os.Stat("main.tf"); err != nil {
   206  		t.Fatalf("err: %s", err)
   207  	}
   208  
   209  	output := ui.OutputWriter.String()
   210  	if !strings.Contains(output, "Get: file://") {
   211  		t.Fatalf("doesn't look like get: %s", output)
   212  	}
   213  }
   214  
   215  func TestInit_backend(t *testing.T) {
   216  	// Create a temporary working directory that is empty
   217  	td := tempDir(t)
   218  	copy.CopyDir(testFixturePath("init-backend"), td)
   219  	defer os.RemoveAll(td)
   220  	defer testChdir(t, td)()
   221  
   222  	ui := new(cli.MockUi)
   223  	c := &InitCommand{
   224  		Meta: Meta{
   225  			ContextOpts: testCtxConfig(testProvider()),
   226  			Ui:          ui,
   227  		},
   228  	}
   229  
   230  	args := []string{}
   231  	if code := c.Run(args); code != 0 {
   232  		t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
   233  	}
   234  
   235  	if _, err := os.Stat(filepath.Join(DefaultDataDir, DefaultStateFilename)); err != nil {
   236  		t.Fatalf("err: %s", err)
   237  	}
   238  }
   239  
   240  func TestInit_backendUnset(t *testing.T) {
   241  	// Create a temporary working directory that is empty
   242  	td := tempDir(t)
   243  	copy.CopyDir(testFixturePath("init-backend"), td)
   244  	defer os.RemoveAll(td)
   245  	defer testChdir(t, td)()
   246  
   247  	{
   248  		ui := new(cli.MockUi)
   249  		c := &InitCommand{
   250  			Meta: Meta{
   251  				ContextOpts: testCtxConfig(testProvider()),
   252  				Ui:          ui,
   253  			},
   254  		}
   255  
   256  		// Init
   257  		args := []string{}
   258  		if code := c.Run(args); code != 0 {
   259  			t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
   260  		}
   261  
   262  		if _, err := os.Stat(filepath.Join(DefaultDataDir, DefaultStateFilename)); err != nil {
   263  			t.Fatalf("err: %s", err)
   264  		}
   265  	}
   266  
   267  	{
   268  		// Unset
   269  		if err := ioutil.WriteFile("main.tf", []byte(""), 0644); err != nil {
   270  			t.Fatalf("err: %s", err)
   271  		}
   272  
   273  		ui := new(cli.MockUi)
   274  		c := &InitCommand{
   275  			Meta: Meta{
   276  				ContextOpts: testCtxConfig(testProvider()),
   277  				Ui:          ui,
   278  			},
   279  		}
   280  
   281  		args := []string{"-force-copy"}
   282  		if code := c.Run(args); code != 0 {
   283  			t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
   284  		}
   285  
   286  		s := testStateRead(t, filepath.Join(
   287  			DefaultDataDir, DefaultStateFilename))
   288  		if !s.Backend.Empty() {
   289  			t.Fatal("should not have backend config")
   290  		}
   291  	}
   292  }
   293  
   294  func TestInit_backendConfigFile(t *testing.T) {
   295  	// Create a temporary working directory that is empty
   296  	td := tempDir(t)
   297  	copy.CopyDir(testFixturePath("init-backend-config-file"), td)
   298  	defer os.RemoveAll(td)
   299  	defer testChdir(t, td)()
   300  
   301  	ui := new(cli.MockUi)
   302  	c := &InitCommand{
   303  		Meta: Meta{
   304  			ContextOpts: testCtxConfig(testProvider()),
   305  			Ui:          ui,
   306  		},
   307  	}
   308  
   309  	args := []string{"-backend-config", "input.config"}
   310  	if code := c.Run(args); code != 0 {
   311  		t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
   312  	}
   313  
   314  	// Read our saved backend config and verify we have our settings
   315  	state := testStateRead(t, filepath.Join(DefaultDataDir, DefaultStateFilename))
   316  	if v := state.Backend.Config["path"]; v != "hello" {
   317  		t.Fatalf("bad: %#v", v)
   318  	}
   319  }
   320  
   321  func TestInit_backendConfigFileChange(t *testing.T) {
   322  	// Create a temporary working directory that is empty
   323  	td := tempDir(t)
   324  	copy.CopyDir(testFixturePath("init-backend-config-file-change"), td)
   325  	defer os.RemoveAll(td)
   326  	defer testChdir(t, td)()
   327  
   328  	// Ask input
   329  	defer testInputMap(t, map[string]string{
   330  		"backend-migrate-to-new": "no",
   331  	})()
   332  
   333  	ui := new(cli.MockUi)
   334  	c := &InitCommand{
   335  		Meta: Meta{
   336  			ContextOpts: testCtxConfig(testProvider()),
   337  			Ui:          ui,
   338  		},
   339  	}
   340  
   341  	args := []string{"-backend-config", "input.config"}
   342  	if code := c.Run(args); code != 0 {
   343  		t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
   344  	}
   345  
   346  	// Read our saved backend config and verify we have our settings
   347  	state := testStateRead(t, filepath.Join(DefaultDataDir, DefaultStateFilename))
   348  	if v := state.Backend.Config["path"]; v != "hello" {
   349  		t.Fatalf("bad: %#v", v)
   350  	}
   351  }
   352  
   353  func TestInit_backendConfigKV(t *testing.T) {
   354  	// Create a temporary working directory that is empty
   355  	td := tempDir(t)
   356  	copy.CopyDir(testFixturePath("init-backend-config-kv"), td)
   357  	defer os.RemoveAll(td)
   358  	defer testChdir(t, td)()
   359  
   360  	ui := new(cli.MockUi)
   361  	c := &InitCommand{
   362  		Meta: Meta{
   363  			ContextOpts: testCtxConfig(testProvider()),
   364  			Ui:          ui,
   365  		},
   366  	}
   367  
   368  	args := []string{"-backend-config", "path=hello"}
   369  	if code := c.Run(args); code != 0 {
   370  		t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
   371  	}
   372  
   373  	// Read our saved backend config and verify we have our settings
   374  	state := testStateRead(t, filepath.Join(DefaultDataDir, DefaultStateFilename))
   375  	if v := state.Backend.Config["path"]; v != "hello" {
   376  		t.Fatalf("bad: %#v", v)
   377  	}
   378  }
   379  
   380  func TestInit_copyBackendDst(t *testing.T) {
   381  	// Create a temporary working directory that is empty
   382  	td := tempDir(t)
   383  	os.MkdirAll(td, 0755)
   384  	defer os.RemoveAll(td)
   385  	defer testChdir(t, td)()
   386  
   387  	ui := new(cli.MockUi)
   388  	c := &InitCommand{
   389  		Meta: Meta{
   390  			ContextOpts: testCtxConfig(testProvider()),
   391  			Ui:          ui,
   392  		},
   393  	}
   394  
   395  	args := []string{
   396  		testFixturePath("init-backend"),
   397  		"dst",
   398  	}
   399  	if code := c.Run(args); code != 0 {
   400  		t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
   401  	}
   402  
   403  	if _, err := os.Stat(filepath.Join(
   404  		"dst", DefaultDataDir, DefaultStateFilename)); err != nil {
   405  		t.Fatalf("err: %s", err)
   406  	}
   407  }
   408  
   409  func TestInit_backendReinitWithExtra(t *testing.T) {
   410  	td := tempDir(t)
   411  	copy.CopyDir(testFixturePath("init-backend-empty"), td)
   412  	defer os.RemoveAll(td)
   413  	defer testChdir(t, td)()
   414  
   415  	m := testMetaBackend(t, nil)
   416  	opts := &BackendOpts{
   417  		ConfigExtra: map[string]interface{}{"path": "hello"},
   418  		Init:        true,
   419  	}
   420  
   421  	b, err := m.backendConfig(opts)
   422  	if err != nil {
   423  		t.Fatal(err)
   424  	}
   425  
   426  	ui := new(cli.MockUi)
   427  	c := &InitCommand{
   428  		Meta: Meta{
   429  			ContextOpts: testCtxConfig(testProvider()),
   430  			Ui:          ui,
   431  		},
   432  	}
   433  
   434  	args := []string{"-backend-config", "path=hello"}
   435  	if code := c.Run(args); code != 0 {
   436  		t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
   437  	}
   438  
   439  	// Read our saved backend config and verify we have our settings
   440  	state := testStateRead(t, filepath.Join(DefaultDataDir, DefaultStateFilename))
   441  	if v := state.Backend.Config["path"]; v != "hello" {
   442  		t.Fatalf("bad: %#v", v)
   443  	}
   444  
   445  	if state.Backend.Hash != b.Hash {
   446  		t.Fatal("mismatched state and config backend hashes")
   447  	}
   448  
   449  	if state.Backend.Rehash() != b.Rehash() {
   450  		t.Fatal("mismatched state and config re-hashes")
   451  	}
   452  
   453  	// init again and make sure nothing changes
   454  	if code := c.Run(args); code != 0 {
   455  		t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
   456  	}
   457  	state = testStateRead(t, filepath.Join(DefaultDataDir, DefaultStateFilename))
   458  	if v := state.Backend.Config["path"]; v != "hello" {
   459  		t.Fatalf("bad: %#v", v)
   460  	}
   461  
   462  	if state.Backend.Hash != b.Hash {
   463  		t.Fatal("mismatched state and config backend hashes")
   464  	}
   465  }
   466  
   467  // move option from config to -backend-config args
   468  func TestInit_backendReinitConfigToExtra(t *testing.T) {
   469  	td := tempDir(t)
   470  	copy.CopyDir(testFixturePath("init-backend"), td)
   471  	defer os.RemoveAll(td)
   472  	defer testChdir(t, td)()
   473  
   474  	ui := new(cli.MockUi)
   475  	c := &InitCommand{
   476  		Meta: Meta{
   477  			ContextOpts: testCtxConfig(testProvider()),
   478  			Ui:          ui,
   479  		},
   480  	}
   481  
   482  	if code := c.Run([]string{"-input=false"}); code != 0 {
   483  		t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
   484  	}
   485  
   486  	// Read our saved backend config and verify we have our settings
   487  	state := testStateRead(t, filepath.Join(DefaultDataDir, DefaultStateFilename))
   488  	if v := state.Backend.Config["path"]; v != "foo" {
   489  		t.Fatalf("bad: %#v", v)
   490  	}
   491  
   492  	backendHash := state.Backend.Hash
   493  
   494  	// init again but remove the path option from the config
   495  	cfg := "terraform {\n  backend \"local\" {}\n}\n"
   496  	if err := ioutil.WriteFile("main.tf", []byte(cfg), 0644); err != nil {
   497  		t.Fatal(err)
   498  	}
   499  
   500  	args := []string{"-input=false", "-backend-config=path=foo"}
   501  	if code := c.Run(args); code != 0 {
   502  		t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
   503  	}
   504  	state = testStateRead(t, filepath.Join(DefaultDataDir, DefaultStateFilename))
   505  
   506  	if state.Backend.Hash == backendHash {
   507  		t.Fatal("state.Backend.Hash was not updated")
   508  	}
   509  }
   510  
   511  // make sure inputFalse stops execution on migrate
   512  func TestInit_inputFalse(t *testing.T) {
   513  	td := tempDir(t)
   514  	copy.CopyDir(testFixturePath("init-backend"), td)
   515  	defer os.RemoveAll(td)
   516  	defer testChdir(t, td)()
   517  
   518  	ui := new(cli.MockUi)
   519  	c := &InitCommand{
   520  		Meta: Meta{
   521  			ContextOpts: testCtxConfig(testProvider()),
   522  			Ui:          ui,
   523  		},
   524  	}
   525  
   526  	args := []string{"-input=false", "-backend-config=path=foo"}
   527  	if code := c.Run([]string{"-input=false"}); code != 0 {
   528  		t.Fatalf("bad: \n%s", ui.ErrorWriter)
   529  	}
   530  
   531  	args = []string{"-input=false", "-backend-config=path=bar"}
   532  	if code := c.Run(args); code == 0 {
   533  		t.Fatal("init should have failed", ui.OutputWriter)
   534  	}
   535  }
   536  
   537  /*
   538  func TestInit_remoteState(t *testing.T) {
   539  	tmp, cwd := testCwd(t)
   540  	defer testFixCwd(t, tmp, cwd)
   541  
   542  	s := terraform.NewState()
   543  	conf, srv := testRemoteState(t, s, 200)
   544  	defer srv.Close()
   545  
   546  	ui := new(cli.MockUi)
   547  	c := &InitCommand{
   548  		Meta: Meta{
   549  			ContextOpts: testCtxConfig(testProvider()),
   550  			Ui:          ui,
   551  		},
   552  	}
   553  
   554  	args := []string{
   555  		"-backend", "HTTP",
   556  		"-backend-config", "address=" + conf.Config["address"],
   557  		testFixturePath("init"),
   558  		tmp,
   559  	}
   560  	if code := c.Run(args); code != 0 {
   561  		t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
   562  	}
   563  
   564  	if _, err := os.Stat(filepath.Join(tmp, "hello.tf")); err != nil {
   565  		t.Fatalf("err: %s", err)
   566  	}
   567  
   568  	if _, err := os.Stat(filepath.Join(tmp, DefaultDataDir, DefaultStateFilename)); err != nil {
   569  		t.Fatalf("missing state: %s", err)
   570  	}
   571  }
   572  
   573  func TestInit_remoteStateSubdir(t *testing.T) {
   574  	tmp, cwd := testCwd(t)
   575  	defer testFixCwd(t, tmp, cwd)
   576  	subdir := filepath.Join(tmp, "subdir")
   577  
   578  	s := terraform.NewState()
   579  	conf, srv := testRemoteState(t, s, 200)
   580  	defer srv.Close()
   581  
   582  	ui := new(cli.MockUi)
   583  	c := &InitCommand{
   584  		Meta: Meta{
   585  			ContextOpts: testCtxConfig(testProvider()),
   586  			Ui:          ui,
   587  		},
   588  	}
   589  
   590  	args := []string{
   591  		"-backend", "http",
   592  		"-backend-config", "address=" + conf.Config["address"],
   593  		testFixturePath("init"),
   594  		subdir,
   595  	}
   596  	if code := c.Run(args); code != 0 {
   597  		t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
   598  	}
   599  
   600  	if _, err := os.Stat(filepath.Join(subdir, "hello.tf")); err != nil {
   601  		t.Fatalf("err: %s", err)
   602  	}
   603  
   604  	if _, err := os.Stat(filepath.Join(subdir, DefaultDataDir, DefaultStateFilename)); err != nil {
   605  		t.Fatalf("missing state: %s", err)
   606  	}
   607  }
   608  
   609  func TestInit_remoteStateWithLocal(t *testing.T) {
   610  	tmp, cwd := testCwd(t)
   611  	defer testFixCwd(t, tmp, cwd)
   612  
   613  	statePath := filepath.Join(tmp, DefaultStateFilename)
   614  
   615  	// Write some state
   616  	f, err := os.Create(statePath)
   617  	if err != nil {
   618  		t.Fatalf("err: %s", err)
   619  	}
   620  	err = terraform.WriteState(testState(), f)
   621  	f.Close()
   622  	if err != nil {
   623  		t.Fatalf("err: %s", err)
   624  	}
   625  
   626  	ui := new(cli.MockUi)
   627  	c := &InitCommand{
   628  		Meta: Meta{
   629  			ContextOpts: testCtxConfig(testProvider()),
   630  			Ui:          ui,
   631  		},
   632  	}
   633  
   634  	args := []string{
   635  		"-backend", "http",
   636  		"-backend-config", "address=http://google.com",
   637  		testFixturePath("init"),
   638  	}
   639  	if code := c.Run(args); code == 0 {
   640  		t.Fatalf("should have failed: \n%s", ui.OutputWriter.String())
   641  	}
   642  }
   643  
   644  func TestInit_remoteStateWithRemote(t *testing.T) {
   645  	tmp, cwd := testCwd(t)
   646  	defer testFixCwd(t, tmp, cwd)
   647  
   648  	statePath := filepath.Join(tmp, DefaultDataDir, DefaultStateFilename)
   649  	if err := os.MkdirAll(filepath.Dir(statePath), 0755); err != nil {
   650  		t.Fatalf("err: %s", err)
   651  	}
   652  
   653  	// Write some state
   654  	f, err := os.Create(statePath)
   655  	if err != nil {
   656  		t.Fatalf("err: %s", err)
   657  	}
   658  	err = terraform.WriteState(testState(), f)
   659  	f.Close()
   660  	if err != nil {
   661  		t.Fatalf("err: %s", err)
   662  	}
   663  
   664  	ui := new(cli.MockUi)
   665  	c := &InitCommand{
   666  		Meta: Meta{
   667  			ContextOpts: testCtxConfig(testProvider()),
   668  			Ui:          ui,
   669  		},
   670  	}
   671  
   672  	args := []string{
   673  		"-backend", "http",
   674  		"-backend-config", "address=http://google.com",
   675  		testFixturePath("init"),
   676  	}
   677  	if code := c.Run(args); code == 0 {
   678  		t.Fatalf("should have failed: \n%s", ui.OutputWriter.String())
   679  	}
   680  }
   681  */