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 `