github.com/paultyng/terraform@v0.6.11-0.20180227224804-66ff8f8bed40/command/taint_test.go (about)

     1  package command
     2  
     3  import (
     4  	"os"
     5  	"strings"
     6  	"testing"
     7  
     8  	"github.com/hashicorp/terraform/terraform"
     9  	"github.com/mitchellh/cli"
    10  )
    11  
    12  func TestTaint(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  						},
    23  					},
    24  				},
    25  			},
    26  		},
    27  	}
    28  	statePath := testStateFile(t, state)
    29  
    30  	ui := new(cli.MockUi)
    31  	c := &TaintCommand{
    32  		Meta: Meta{
    33  			Ui: ui,
    34  		},
    35  	}
    36  
    37  	args := []string{
    38  		"-state", statePath,
    39  		"test_instance.foo",
    40  	}
    41  	if code := c.Run(args); code != 0 {
    42  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
    43  	}
    44  
    45  	testStateOutput(t, statePath, testTaintStr)
    46  }
    47  
    48  func TestTaint_lockedState(t *testing.T) {
    49  	state := &terraform.State{
    50  		Modules: []*terraform.ModuleState{
    51  			&terraform.ModuleState{
    52  				Path: []string{"root"},
    53  				Resources: map[string]*terraform.ResourceState{
    54  					"test_instance.foo": &terraform.ResourceState{
    55  						Type: "test_instance",
    56  						Primary: &terraform.InstanceState{
    57  							ID: "bar",
    58  						},
    59  					},
    60  				},
    61  			},
    62  		},
    63  	}
    64  	statePath := testStateFile(t, state)
    65  
    66  	unlock, err := testLockState("./testdata", statePath)
    67  	if err != nil {
    68  		t.Fatal(err)
    69  	}
    70  	defer unlock()
    71  	ui := new(cli.MockUi)
    72  	c := &TaintCommand{
    73  		Meta: Meta{
    74  			Ui: ui,
    75  		},
    76  	}
    77  
    78  	args := []string{
    79  		"-state", statePath,
    80  		"test_instance.foo",
    81  	}
    82  	if code := c.Run(args); code == 0 {
    83  		t.Fatal("expected error")
    84  	}
    85  
    86  	output := ui.ErrorWriter.String()
    87  	if !strings.Contains(output, "lock") {
    88  		t.Fatal("command output does not look like a lock error:", output)
    89  	}
    90  }
    91  
    92  func TestTaint_backup(t *testing.T) {
    93  	// Get a temp cwd
    94  	tmp, cwd := testCwd(t)
    95  	defer testFixCwd(t, tmp, cwd)
    96  
    97  	// Write the temp state
    98  	state := &terraform.State{
    99  		Modules: []*terraform.ModuleState{
   100  			&terraform.ModuleState{
   101  				Path: []string{"root"},
   102  				Resources: map[string]*terraform.ResourceState{
   103  					"test_instance.foo": &terraform.ResourceState{
   104  						Type: "test_instance",
   105  						Primary: &terraform.InstanceState{
   106  							ID: "bar",
   107  						},
   108  					},
   109  				},
   110  			},
   111  		},
   112  	}
   113  	path := testStateFileDefault(t, state)
   114  
   115  	ui := new(cli.MockUi)
   116  	c := &TaintCommand{
   117  		Meta: Meta{
   118  			Ui: ui,
   119  		},
   120  	}
   121  
   122  	args := []string{
   123  		"test_instance.foo",
   124  	}
   125  	if code := c.Run(args); code != 0 {
   126  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
   127  	}
   128  
   129  	testStateOutput(t, path+".backup", testTaintDefaultStr)
   130  	testStateOutput(t, path, testTaintStr)
   131  }
   132  
   133  func TestTaint_backupDisable(t *testing.T) {
   134  	// Get a temp cwd
   135  	tmp, cwd := testCwd(t)
   136  	defer testFixCwd(t, tmp, cwd)
   137  
   138  	// Write the temp state
   139  	state := &terraform.State{
   140  		Modules: []*terraform.ModuleState{
   141  			&terraform.ModuleState{
   142  				Path: []string{"root"},
   143  				Resources: map[string]*terraform.ResourceState{
   144  					"test_instance.foo": &terraform.ResourceState{
   145  						Type: "test_instance",
   146  						Primary: &terraform.InstanceState{
   147  							ID: "bar",
   148  						},
   149  					},
   150  				},
   151  			},
   152  		},
   153  	}
   154  	path := testStateFileDefault(t, state)
   155  
   156  	ui := new(cli.MockUi)
   157  	c := &TaintCommand{
   158  		Meta: Meta{
   159  			Ui: ui,
   160  		},
   161  	}
   162  
   163  	args := []string{
   164  		"-backup", "-",
   165  		"test_instance.foo",
   166  	}
   167  	if code := c.Run(args); code != 0 {
   168  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
   169  	}
   170  
   171  	if _, err := os.Stat(path + ".backup"); err == nil {
   172  		t.Fatal("backup path should not exist")
   173  	}
   174  
   175  	testStateOutput(t, path, testTaintStr)
   176  }
   177  
   178  func TestTaint_badState(t *testing.T) {
   179  	ui := new(cli.MockUi)
   180  	c := &TaintCommand{
   181  		Meta: Meta{
   182  			Ui: ui,
   183  		},
   184  	}
   185  
   186  	args := []string{
   187  		"-state", "i-should-not-exist-ever",
   188  		"foo",
   189  	}
   190  	if code := c.Run(args); code != 1 {
   191  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
   192  	}
   193  }
   194  
   195  func TestTaint_defaultState(t *testing.T) {
   196  	// Get a temp cwd
   197  	tmp, cwd := testCwd(t)
   198  	defer testFixCwd(t, tmp, cwd)
   199  
   200  	// Write the temp state
   201  	state := &terraform.State{
   202  		Modules: []*terraform.ModuleState{
   203  			&terraform.ModuleState{
   204  				Path: []string{"root"},
   205  				Resources: map[string]*terraform.ResourceState{
   206  					"test_instance.foo": &terraform.ResourceState{
   207  						Type: "test_instance",
   208  						Primary: &terraform.InstanceState{
   209  							ID: "bar",
   210  						},
   211  					},
   212  				},
   213  			},
   214  		},
   215  	}
   216  	path := testStateFileDefault(t, state)
   217  
   218  	ui := new(cli.MockUi)
   219  	c := &TaintCommand{
   220  		Meta: Meta{
   221  			Ui: ui,
   222  		},
   223  	}
   224  
   225  	args := []string{
   226  		"test_instance.foo",
   227  	}
   228  	if code := c.Run(args); code != 0 {
   229  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
   230  	}
   231  
   232  	testStateOutput(t, path, testTaintStr)
   233  }
   234  
   235  func TestTaint_missing(t *testing.T) {
   236  	state := &terraform.State{
   237  		Modules: []*terraform.ModuleState{
   238  			&terraform.ModuleState{
   239  				Path: []string{"root"},
   240  				Resources: map[string]*terraform.ResourceState{
   241  					"test_instance.foo": &terraform.ResourceState{
   242  						Type: "test_instance",
   243  						Primary: &terraform.InstanceState{
   244  							ID: "bar",
   245  						},
   246  					},
   247  				},
   248  			},
   249  		},
   250  	}
   251  	statePath := testStateFile(t, state)
   252  
   253  	ui := new(cli.MockUi)
   254  	c := &TaintCommand{
   255  		Meta: Meta{
   256  			Ui: ui,
   257  		},
   258  	}
   259  
   260  	args := []string{
   261  		"-state", statePath,
   262  		"test_instance.bar",
   263  	}
   264  	if code := c.Run(args); code == 0 {
   265  		t.Fatalf("bad: %d\n\n%s", code, ui.OutputWriter.String())
   266  	}
   267  }
   268  
   269  func TestTaint_missingAllow(t *testing.T) {
   270  	state := &terraform.State{
   271  		Modules: []*terraform.ModuleState{
   272  			&terraform.ModuleState{
   273  				Path: []string{"root"},
   274  				Resources: map[string]*terraform.ResourceState{
   275  					"test_instance.foo": &terraform.ResourceState{
   276  						Type: "test_instance",
   277  						Primary: &terraform.InstanceState{
   278  							ID: "bar",
   279  						},
   280  					},
   281  				},
   282  			},
   283  		},
   284  	}
   285  	statePath := testStateFile(t, state)
   286  
   287  	ui := new(cli.MockUi)
   288  	c := &TaintCommand{
   289  		Meta: Meta{
   290  			Ui: ui,
   291  		},
   292  	}
   293  
   294  	args := []string{
   295  		"-allow-missing",
   296  		"-state", statePath,
   297  		"test_instance.bar",
   298  	}
   299  	if code := c.Run(args); code != 0 {
   300  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
   301  	}
   302  }
   303  
   304  func TestTaint_stateOut(t *testing.T) {
   305  	// Get a temp cwd
   306  	tmp, cwd := testCwd(t)
   307  	defer testFixCwd(t, tmp, cwd)
   308  
   309  	// Write the temp state
   310  	state := &terraform.State{
   311  		Modules: []*terraform.ModuleState{
   312  			&terraform.ModuleState{
   313  				Path: []string{"root"},
   314  				Resources: map[string]*terraform.ResourceState{
   315  					"test_instance.foo": &terraform.ResourceState{
   316  						Type: "test_instance",
   317  						Primary: &terraform.InstanceState{
   318  							ID: "bar",
   319  						},
   320  					},
   321  				},
   322  			},
   323  		},
   324  	}
   325  	path := testStateFileDefault(t, state)
   326  
   327  	ui := new(cli.MockUi)
   328  	c := &TaintCommand{
   329  		Meta: Meta{
   330  			Ui: ui,
   331  		},
   332  	}
   333  
   334  	args := []string{
   335  		"-state-out", "foo",
   336  		"test_instance.foo",
   337  	}
   338  	if code := c.Run(args); code != 0 {
   339  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
   340  	}
   341  
   342  	testStateOutput(t, path, testTaintDefaultStr)
   343  	testStateOutput(t, "foo", testTaintStr)
   344  }
   345  
   346  func TestTaint_module(t *testing.T) {
   347  	state := &terraform.State{
   348  		Modules: []*terraform.ModuleState{
   349  			&terraform.ModuleState{
   350  				Path: []string{"root"},
   351  				Resources: map[string]*terraform.ResourceState{
   352  					"test_instance.foo": &terraform.ResourceState{
   353  						Type: "test_instance",
   354  						Primary: &terraform.InstanceState{
   355  							ID: "bar",
   356  						},
   357  					},
   358  				},
   359  			},
   360  			&terraform.ModuleState{
   361  				Path: []string{"root", "child"},
   362  				Resources: map[string]*terraform.ResourceState{
   363  					"test_instance.blah": &terraform.ResourceState{
   364  						Type: "test_instance",
   365  						Primary: &terraform.InstanceState{
   366  							ID: "blah",
   367  						},
   368  					},
   369  				},
   370  			},
   371  		},
   372  	}
   373  	statePath := testStateFile(t, state)
   374  
   375  	ui := new(cli.MockUi)
   376  	c := &TaintCommand{
   377  		Meta: Meta{
   378  			Ui: ui,
   379  		},
   380  	}
   381  
   382  	args := []string{
   383  		"-module=child",
   384  		"-state", statePath,
   385  		"test_instance.blah",
   386  	}
   387  	if code := c.Run(args); code != 0 {
   388  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
   389  	}
   390  
   391  	testStateOutput(t, statePath, testTaintModuleStr)
   392  }
   393  
   394  const testTaintStr = `
   395  test_instance.foo: (tainted)
   396    ID = bar
   397  `
   398  
   399  const testTaintDefaultStr = `
   400  test_instance.foo:
   401    ID = bar
   402  `
   403  
   404  const testTaintModuleStr = `
   405  test_instance.foo:
   406    ID = bar
   407  
   408  module.child:
   409    test_instance.blah: (tainted)
   410      ID = blah
   411  `