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