github.com/paultyng/terraform@v0.6.11-0.20180227224804-66ff8f8bed40/command/apply_destroy_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 TestApply_destroy(t *testing.T) {
    13  	originalState := &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  
    29  	statePath := testStateFile(t, originalState)
    30  
    31  	p := testProvider()
    32  	ui := new(cli.MockUi)
    33  	c := &ApplyCommand{
    34  		Destroy: true,
    35  		Meta: Meta{
    36  			testingOverrides: metaOverridesForProvider(p),
    37  			Ui:               ui,
    38  		},
    39  	}
    40  
    41  	// Run the apply command pointing to our existing state
    42  	args := []string{
    43  		"-force",
    44  		"-state", statePath,
    45  		testFixturePath("apply"),
    46  	}
    47  	if code := c.Run(args); code != 0 {
    48  		t.Log(ui.OutputWriter.String())
    49  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
    50  	}
    51  
    52  	// Verify a new state exists
    53  	if _, err := os.Stat(statePath); err != nil {
    54  		t.Fatalf("err: %s", err)
    55  	}
    56  
    57  	f, err := os.Open(statePath)
    58  	if err != nil {
    59  		t.Fatalf("err: %s", err)
    60  	}
    61  	defer f.Close()
    62  
    63  	state, err := terraform.ReadState(f)
    64  	if err != nil {
    65  		t.Fatalf("err: %s", err)
    66  	}
    67  	if state == nil {
    68  		t.Fatal("state should not be nil")
    69  	}
    70  
    71  	actualStr := strings.TrimSpace(state.String())
    72  	expectedStr := strings.TrimSpace(testApplyDestroyStr)
    73  	if actualStr != expectedStr {
    74  		t.Fatalf("bad:\n\n%s\n\n%s", actualStr, expectedStr)
    75  	}
    76  
    77  	// Should have a backup file
    78  	f, err = os.Open(statePath + DefaultBackupExtension)
    79  	if err != nil {
    80  		t.Fatalf("err: %s", err)
    81  	}
    82  
    83  	backupState, err := terraform.ReadState(f)
    84  	f.Close()
    85  	if err != nil {
    86  		t.Fatalf("err: %s", err)
    87  	}
    88  
    89  	actualStr = strings.TrimSpace(backupState.String())
    90  	expectedStr = strings.TrimSpace(originalState.String())
    91  	if actualStr != expectedStr {
    92  		t.Fatalf("bad:\n\n%s\n\n%s", actualStr, expectedStr)
    93  	}
    94  }
    95  
    96  func TestApply_destroyLockedState(t *testing.T) {
    97  	originalState := &terraform.State{
    98  		Modules: []*terraform.ModuleState{
    99  			&terraform.ModuleState{
   100  				Path: []string{"root"},
   101  				Resources: map[string]*terraform.ResourceState{
   102  					"test_instance.foo": &terraform.ResourceState{
   103  						Type: "test_instance",
   104  						Primary: &terraform.InstanceState{
   105  							ID: "bar",
   106  						},
   107  					},
   108  				},
   109  			},
   110  		},
   111  	}
   112  
   113  	statePath := testStateFile(t, originalState)
   114  
   115  	unlock, err := testLockState("./testdata", statePath)
   116  	if err != nil {
   117  		t.Fatal(err)
   118  	}
   119  	defer unlock()
   120  
   121  	p := testProvider()
   122  	ui := new(cli.MockUi)
   123  	c := &ApplyCommand{
   124  		Destroy: true,
   125  		Meta: Meta{
   126  			testingOverrides: metaOverridesForProvider(p),
   127  			Ui:               ui,
   128  		},
   129  	}
   130  
   131  	// Run the apply command pointing to our existing state
   132  	args := []string{
   133  		"-force",
   134  		"-state", statePath,
   135  		testFixturePath("apply"),
   136  	}
   137  
   138  	if code := c.Run(args); code == 0 {
   139  		t.Fatal("expected error")
   140  	}
   141  
   142  	output := ui.ErrorWriter.String()
   143  	if !strings.Contains(output, "lock") {
   144  		t.Fatal("command output does not look like a lock error:", output)
   145  	}
   146  }
   147  
   148  func TestApply_destroyPlan(t *testing.T) {
   149  	planPath := testPlanFile(t, &terraform.Plan{
   150  		Module: testModule(t, "apply"),
   151  	})
   152  
   153  	p := testProvider()
   154  	ui := new(cli.MockUi)
   155  	c := &ApplyCommand{
   156  		Destroy: true,
   157  		Meta: Meta{
   158  			testingOverrides: metaOverridesForProvider(p),
   159  			Ui:               ui,
   160  		},
   161  	}
   162  
   163  	// Run the apply command pointing to our existing state
   164  	args := []string{
   165  		planPath,
   166  	}
   167  	if code := c.Run(args); code != 1 {
   168  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
   169  	}
   170  }
   171  
   172  func TestApply_destroyTargeted(t *testing.T) {
   173  	originalState := &terraform.State{
   174  		Modules: []*terraform.ModuleState{
   175  			&terraform.ModuleState{
   176  				Path: []string{"root"},
   177  				Resources: map[string]*terraform.ResourceState{
   178  					"test_instance.foo": &terraform.ResourceState{
   179  						Type: "test_instance",
   180  						Primary: &terraform.InstanceState{
   181  							ID: "i-ab123",
   182  						},
   183  					},
   184  					"test_load_balancer.foo": &terraform.ResourceState{
   185  						Type: "test_load_balancer",
   186  						Primary: &terraform.InstanceState{
   187  							ID: "lb-abc123",
   188  						},
   189  					},
   190  				},
   191  			},
   192  		},
   193  	}
   194  
   195  	statePath := testStateFile(t, originalState)
   196  
   197  	p := testProvider()
   198  	ui := new(cli.MockUi)
   199  	c := &ApplyCommand{
   200  		Destroy: true,
   201  		Meta: Meta{
   202  			testingOverrides: metaOverridesForProvider(p),
   203  			Ui:               ui,
   204  		},
   205  	}
   206  
   207  	// Run the apply command pointing to our existing state
   208  	args := []string{
   209  		"-force",
   210  		"-target", "test_instance.foo",
   211  		"-state", statePath,
   212  		testFixturePath("apply-destroy-targeted"),
   213  	}
   214  	if code := c.Run(args); code != 0 {
   215  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
   216  	}
   217  
   218  	// Verify a new state exists
   219  	if _, err := os.Stat(statePath); err != nil {
   220  		t.Fatalf("err: %s", err)
   221  	}
   222  
   223  	f, err := os.Open(statePath)
   224  	if err != nil {
   225  		t.Fatalf("err: %s", err)
   226  	}
   227  	defer f.Close()
   228  
   229  	state, err := terraform.ReadState(f)
   230  	if err != nil {
   231  		t.Fatalf("err: %s", err)
   232  	}
   233  	if state == nil {
   234  		t.Fatal("state should not be nil")
   235  	}
   236  
   237  	actualStr := strings.TrimSpace(state.String())
   238  	expectedStr := strings.TrimSpace(testApplyDestroyStr)
   239  	if actualStr != expectedStr {
   240  		t.Fatalf("bad:\n\n%s\n\nexpected:\n\n%s", actualStr, expectedStr)
   241  	}
   242  
   243  	// Should have a backup file
   244  	f, err = os.Open(statePath + DefaultBackupExtension)
   245  	if err != nil {
   246  		t.Fatalf("err: %s", err)
   247  	}
   248  
   249  	backupState, err := terraform.ReadState(f)
   250  	f.Close()
   251  	if err != nil {
   252  		t.Fatalf("err: %s", err)
   253  	}
   254  
   255  	actualStr = strings.TrimSpace(backupState.String())
   256  	expectedStr = strings.TrimSpace(originalState.String())
   257  	if actualStr != expectedStr {
   258  		t.Fatalf("bad:\n\nactual:\n%s\n\nexpected:\nb%s", actualStr, expectedStr)
   259  	}
   260  }
   261  
   262  const testApplyDestroyStr = `
   263  <no state>
   264  `