github.com/arvindram03/terraform@v0.3.7-0.20150212015210-408f838db36d/command/remote_test.go (about)

     1  package command
     2  
     3  import (
     4  	"bytes"
     5  	"io/ioutil"
     6  	"os"
     7  	"testing"
     8  
     9  	"github.com/hashicorp/terraform/remote"
    10  	"github.com/hashicorp/terraform/terraform"
    11  	"github.com/mitchellh/cli"
    12  )
    13  
    14  // Test disabling remote management
    15  func TestRemote_disable(t *testing.T) {
    16  	tmp, cwd := testCwd(t)
    17  	defer testFixCwd(t, tmp, cwd)
    18  
    19  	// Create remote state file, this should be pulled
    20  	s := terraform.NewState()
    21  	s.Serial = 10
    22  	conf, srv := testRemoteState(t, s, 200)
    23  	defer srv.Close()
    24  
    25  	// Persist local remote state
    26  	s = terraform.NewState()
    27  	s.Serial = 5
    28  	s.Remote = conf
    29  	if err := remote.EnsureDirectory(); err != nil {
    30  		t.Fatalf("err: %v", err)
    31  	}
    32  	if err := remote.PersistState(s); err != nil {
    33  		t.Fatalf("err: %v", err)
    34  	}
    35  
    36  	ui := new(cli.MockUi)
    37  	c := &RemoteCommand{
    38  		Meta: Meta{
    39  			ContextOpts: testCtxConfig(testProvider()),
    40  			Ui:          ui,
    41  		},
    42  	}
    43  	args := []string{"-disable"}
    44  	if code := c.Run(args); code != 0 {
    45  		t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
    46  	}
    47  
    48  	// Local state file should be removed
    49  	haveLocal, err := remote.HaveLocalState()
    50  	if err != nil {
    51  		t.Fatalf("err: %v", err)
    52  	}
    53  	if haveLocal {
    54  		t.Fatalf("should be disabled")
    55  	}
    56  
    57  	// New state file should be installed
    58  	exists, err := remote.ExistsFile(DefaultStateFilename)
    59  	if err != nil {
    60  		t.Fatalf("err: %v", err)
    61  	}
    62  	if !exists {
    63  		t.Fatalf("failed to make state file")
    64  	}
    65  
    66  	// Check that the state file was updated
    67  	raw, _ := ioutil.ReadFile(DefaultStateFilename)
    68  	newState, err := terraform.ReadState(bytes.NewReader(raw))
    69  	if err != nil {
    70  		t.Fatalf("err: %v", err)
    71  	}
    72  
    73  	// Ensure we updated
    74  	// TODO: Should be 10, but WriteState currently
    75  	// increments incorrectly
    76  	if newState.Serial != 11 {
    77  		t.Fatalf("state file not updated: %#v", newState)
    78  	}
    79  	if newState.Remote != nil {
    80  		t.Fatalf("remote configuration not removed")
    81  	}
    82  }
    83  
    84  // Test disabling remote management without pulling
    85  func TestRemote_disable_noPull(t *testing.T) {
    86  	tmp, cwd := testCwd(t)
    87  	defer testFixCwd(t, tmp, cwd)
    88  
    89  	// Create remote state file, this should be pulled
    90  	s := terraform.NewState()
    91  	s.Serial = 10
    92  	conf, srv := testRemoteState(t, s, 200)
    93  	defer srv.Close()
    94  
    95  	// Persist local remote state
    96  	s = terraform.NewState()
    97  	s.Serial = 5
    98  	s.Remote = conf
    99  	if err := remote.EnsureDirectory(); err != nil {
   100  		t.Fatalf("err: %v", err)
   101  	}
   102  	if err := remote.PersistState(s); err != nil {
   103  		t.Fatalf("err: %v", err)
   104  	}
   105  
   106  	ui := new(cli.MockUi)
   107  	c := &RemoteCommand{
   108  		Meta: Meta{
   109  			ContextOpts: testCtxConfig(testProvider()),
   110  			Ui:          ui,
   111  		},
   112  	}
   113  	args := []string{"-disable", "-pull=false"}
   114  	if code := c.Run(args); code != 0 {
   115  		t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
   116  	}
   117  
   118  	// Local state file should be removed
   119  	haveLocal, err := remote.HaveLocalState()
   120  	if err != nil {
   121  		t.Fatalf("err: %v", err)
   122  	}
   123  	if haveLocal {
   124  		t.Fatalf("should be disabled")
   125  	}
   126  
   127  	// New state file should be installed
   128  	exists, err := remote.ExistsFile(DefaultStateFilename)
   129  	if err != nil {
   130  		t.Fatalf("err: %v", err)
   131  	}
   132  	if !exists {
   133  		t.Fatalf("failed to make state file")
   134  	}
   135  
   136  	// Check that the state file was updated
   137  	raw, _ := ioutil.ReadFile(DefaultStateFilename)
   138  	newState, err := terraform.ReadState(bytes.NewReader(raw))
   139  	if err != nil {
   140  		t.Fatalf("err: %v", err)
   141  	}
   142  
   143  	// Ensure we DIDNT updated
   144  	// TODO: Should be 5, but WriteState currently increments
   145  	// this which is incorrect.
   146  	if newState.Serial != 7 {
   147  		t.Fatalf("state file updated: %#v", newState)
   148  	}
   149  	if newState.Remote != nil {
   150  		t.Fatalf("remote configuration not removed")
   151  	}
   152  }
   153  
   154  // Test disabling remote management when not enabled
   155  func TestRemote_disable_notEnabled(t *testing.T) {
   156  	tmp, cwd := testCwd(t)
   157  	defer testFixCwd(t, tmp, cwd)
   158  
   159  	ui := new(cli.MockUi)
   160  	c := &RemoteCommand{
   161  		Meta: Meta{
   162  			ContextOpts: testCtxConfig(testProvider()),
   163  			Ui:          ui,
   164  		},
   165  	}
   166  
   167  	args := []string{"-disable"}
   168  	if code := c.Run(args); code != 1 {
   169  		t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
   170  	}
   171  }
   172  
   173  // Test disabling remote management with a state file in the way
   174  func TestRemote_disable_otherState(t *testing.T) {
   175  	tmp, cwd := testCwd(t)
   176  	defer testFixCwd(t, tmp, cwd)
   177  
   178  	// Persist local remote state
   179  	s := terraform.NewState()
   180  	s.Serial = 5
   181  	if err := remote.EnsureDirectory(); err != nil {
   182  		t.Fatalf("err: %v", err)
   183  	}
   184  	if err := remote.PersistState(s); err != nil {
   185  		t.Fatalf("err: %v", err)
   186  	}
   187  
   188  	// Also put a file at the default path
   189  	fh, err := os.Create(DefaultStateFilename)
   190  	if err != nil {
   191  		t.Fatalf("err: %v", err)
   192  	}
   193  	err = terraform.WriteState(s, fh)
   194  	fh.Close()
   195  	if err != nil {
   196  		t.Fatalf("err: %v", err)
   197  	}
   198  
   199  	ui := new(cli.MockUi)
   200  	c := &RemoteCommand{
   201  		Meta: Meta{
   202  			ContextOpts: testCtxConfig(testProvider()),
   203  			Ui:          ui,
   204  		},
   205  	}
   206  
   207  	args := []string{"-disable"}
   208  	if code := c.Run(args); code != 1 {
   209  		t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
   210  	}
   211  }
   212  
   213  // Test the case where both managed and non managed state present
   214  func TestRemote_managedAndNonManaged(t *testing.T) {
   215  	tmp, cwd := testCwd(t)
   216  	defer testFixCwd(t, tmp, cwd)
   217  
   218  	// Persist local remote state
   219  	s := terraform.NewState()
   220  	s.Serial = 5
   221  	if err := remote.EnsureDirectory(); err != nil {
   222  		t.Fatalf("err: %v", err)
   223  	}
   224  	if err := remote.PersistState(s); err != nil {
   225  		t.Fatalf("err: %v", err)
   226  	}
   227  
   228  	// Also put a file at the default path
   229  	fh, err := os.Create(DefaultStateFilename)
   230  	if err != nil {
   231  		t.Fatalf("err: %v", err)
   232  	}
   233  	err = terraform.WriteState(s, fh)
   234  	fh.Close()
   235  	if err != nil {
   236  		t.Fatalf("err: %v", err)
   237  	}
   238  
   239  	ui := new(cli.MockUi)
   240  	c := &RemoteCommand{
   241  		Meta: Meta{
   242  			ContextOpts: testCtxConfig(testProvider()),
   243  			Ui:          ui,
   244  		},
   245  	}
   246  
   247  	args := []string{}
   248  	if code := c.Run(args); code != 1 {
   249  		t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
   250  	}
   251  }
   252  
   253  // Test initializing blank state
   254  func TestRemote_initBlank(t *testing.T) {
   255  	tmp, cwd := testCwd(t)
   256  	defer testFixCwd(t, tmp, cwd)
   257  
   258  	ui := new(cli.MockUi)
   259  	c := &RemoteCommand{
   260  		Meta: Meta{
   261  			ContextOpts: testCtxConfig(testProvider()),
   262  			Ui:          ui,
   263  		},
   264  	}
   265  
   266  	args := []string{
   267  		"-backend=http",
   268  		"-address", "http://example.com",
   269  		"-access-token=test",
   270  	}
   271  	if code := c.Run(args); code != 0 {
   272  		t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
   273  	}
   274  
   275  	local, _, err := remote.ReadLocalState()
   276  	if err != nil {
   277  		t.Fatalf("err: %v", err)
   278  	}
   279  
   280  	if local.Remote.Type != "http" {
   281  		t.Fatalf("Bad: %#v", local.Remote)
   282  	}
   283  	if local.Remote.Config["address"] != "http://example.com" {
   284  		t.Fatalf("Bad: %#v", local.Remote)
   285  	}
   286  	if local.Remote.Config["access_token"] != "test" {
   287  		t.Fatalf("Bad: %#v", local.Remote)
   288  	}
   289  }
   290  
   291  // Test initializing without remote settings
   292  func TestRemote_initBlank_missingRemote(t *testing.T) {
   293  	tmp, cwd := testCwd(t)
   294  	defer testFixCwd(t, tmp, cwd)
   295  
   296  	ui := new(cli.MockUi)
   297  	c := &RemoteCommand{
   298  		Meta: Meta{
   299  			ContextOpts: testCtxConfig(testProvider()),
   300  			Ui:          ui,
   301  		},
   302  	}
   303  
   304  	args := []string{}
   305  	if code := c.Run(args); code != 1 {
   306  		t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
   307  	}
   308  }
   309  
   310  // Test updating remote config
   311  func TestRemote_updateRemote(t *testing.T) {
   312  	tmp, cwd := testCwd(t)
   313  	defer testFixCwd(t, tmp, cwd)
   314  
   315  	// Persist local remote state
   316  	s := terraform.NewState()
   317  	s.Serial = 5
   318  	s.Remote = &terraform.RemoteState{
   319  		Type: "invalid",
   320  	}
   321  	if err := remote.EnsureDirectory(); err != nil {
   322  		t.Fatalf("err: %v", err)
   323  	}
   324  	if err := remote.PersistState(s); err != nil {
   325  		t.Fatalf("err: %v", err)
   326  	}
   327  
   328  	ui := new(cli.MockUi)
   329  	c := &RemoteCommand{
   330  		Meta: Meta{
   331  			ContextOpts: testCtxConfig(testProvider()),
   332  			Ui:          ui,
   333  		},
   334  	}
   335  
   336  	args := []string{
   337  		"-backend=http",
   338  		"-address",
   339  		"http://example.com",
   340  		"-access-token=test",
   341  	}
   342  	if code := c.Run(args); code != 0 {
   343  		t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
   344  	}
   345  
   346  	local, _, err := remote.ReadLocalState()
   347  	if err != nil {
   348  		t.Fatalf("err: %v", err)
   349  	}
   350  
   351  	if local.Remote.Type != "http" {
   352  		t.Fatalf("Bad: %#v", local.Remote)
   353  	}
   354  	if local.Remote.Config["address"] != "http://example.com" {
   355  		t.Fatalf("Bad: %#v", local.Remote)
   356  	}
   357  	if local.Remote.Config["access_token"] != "test" {
   358  		t.Fatalf("Bad: %#v", local.Remote)
   359  	}
   360  }
   361  
   362  // Test enabling remote state
   363  func TestRemote_enableRemote(t *testing.T) {
   364  	tmp, cwd := testCwd(t)
   365  	defer testFixCwd(t, tmp, cwd)
   366  
   367  	// Create a non-remote enabled state
   368  	s := terraform.NewState()
   369  	s.Serial = 5
   370  
   371  	// Add the state at the default path
   372  	fh, err := os.Create(DefaultStateFilename)
   373  	if err != nil {
   374  		t.Fatalf("err: %v", err)
   375  	}
   376  	err = terraform.WriteState(s, fh)
   377  	fh.Close()
   378  	if err != nil {
   379  		t.Fatalf("err: %v", err)
   380  	}
   381  
   382  	ui := new(cli.MockUi)
   383  	c := &RemoteCommand{
   384  		Meta: Meta{
   385  			ContextOpts: testCtxConfig(testProvider()),
   386  			Ui:          ui,
   387  		},
   388  	}
   389  
   390  	args := []string{
   391  		"-backend=http",
   392  		"-address",
   393  		"http://example.com",
   394  		"-access-token=test",
   395  	}
   396  	if code := c.Run(args); code != 0 {
   397  		t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
   398  	}
   399  
   400  	local, _, err := remote.ReadLocalState()
   401  	if err != nil {
   402  		t.Fatalf("err: %v", err)
   403  	}
   404  
   405  	if local.Remote.Type != "http" {
   406  		t.Fatalf("Bad: %#v", local.Remote)
   407  	}
   408  	if local.Remote.Config["address"] != "http://example.com" {
   409  		t.Fatalf("Bad: %#v", local.Remote)
   410  	}
   411  	if local.Remote.Config["access_token"] != "test" {
   412  		t.Fatalf("Bad: %#v", local.Remote)
   413  	}
   414  
   415  	// Backup file should exist
   416  	exist, err := remote.ExistsFile(DefaultStateFilename + DefaultBackupExtention)
   417  	if err != nil {
   418  		t.Fatalf("err: %v", err)
   419  	}
   420  	if !exist {
   421  		t.Fatalf("backup should exist")
   422  	}
   423  
   424  	// State file should not
   425  	exist, err = remote.ExistsFile(DefaultStateFilename)
   426  	if err != nil {
   427  		t.Fatalf("err: %v", err)
   428  	}
   429  	if exist {
   430  		t.Fatalf("state file should not exist")
   431  	}
   432  }