github.com/ggriffiths/terraform@v0.9.0-beta1.0.20170222213024-79c4935604cb/command/state_mv_test.go (about) 1 package command 2 3 import ( 4 "os" 5 "path/filepath" 6 "testing" 7 8 "github.com/hashicorp/terraform/terraform" 9 "github.com/mitchellh/cli" 10 ) 11 12 func TestStateMv(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 Attributes: map[string]string{ 23 "foo": "value", 24 "bar": "value", 25 }, 26 }, 27 }, 28 29 "test_instance.baz": &terraform.ResourceState{ 30 Type: "test_instance", 31 Primary: &terraform.InstanceState{ 32 ID: "foo", 33 Attributes: map[string]string{ 34 "foo": "value", 35 "bar": "value", 36 }, 37 }, 38 }, 39 }, 40 }, 41 }, 42 } 43 44 statePath := testStateFile(t, state) 45 46 p := testProvider() 47 ui := new(cli.MockUi) 48 c := &StateMvCommand{ 49 Meta: Meta{ 50 ContextOpts: testCtxConfig(p), 51 Ui: ui, 52 }, 53 } 54 55 args := []string{ 56 "-state", statePath, 57 "test_instance.foo", 58 "test_instance.bar", 59 } 60 if code := c.Run(args); code != 0 { 61 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) 62 } 63 64 // Test it is correct 65 testStateOutput(t, statePath, testStateMvOutput) 66 67 // Test we have backups 68 backups := testStateBackups(t, filepath.Dir(statePath)) 69 if len(backups) != 1 { 70 t.Fatalf("bad: %#v", backups) 71 } 72 testStateOutput(t, backups[0], testStateMvOutputOriginal) 73 } 74 75 func TestStateMv_backupExplicit(t *testing.T) { 76 td := tempDir(t) 77 defer os.RemoveAll(td) 78 backupPath := filepath.Join(td, "backup") 79 80 state := &terraform.State{ 81 Modules: []*terraform.ModuleState{ 82 &terraform.ModuleState{ 83 Path: []string{"root"}, 84 Resources: map[string]*terraform.ResourceState{ 85 "test_instance.foo": &terraform.ResourceState{ 86 Type: "test_instance", 87 Primary: &terraform.InstanceState{ 88 ID: "bar", 89 Attributes: map[string]string{ 90 "foo": "value", 91 "bar": "value", 92 }, 93 }, 94 }, 95 96 "test_instance.baz": &terraform.ResourceState{ 97 Type: "test_instance", 98 Primary: &terraform.InstanceState{ 99 ID: "foo", 100 Attributes: map[string]string{ 101 "foo": "value", 102 "bar": "value", 103 }, 104 }, 105 }, 106 }, 107 }, 108 }, 109 } 110 111 statePath := testStateFile(t, state) 112 113 p := testProvider() 114 ui := new(cli.MockUi) 115 c := &StateMvCommand{ 116 Meta: Meta{ 117 ContextOpts: testCtxConfig(p), 118 Ui: ui, 119 }, 120 } 121 122 args := []string{ 123 "-backup", backupPath, 124 "-state", statePath, 125 "test_instance.foo", 126 "test_instance.bar", 127 } 128 if code := c.Run(args); code != 0 { 129 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) 130 } 131 132 // Test it is correct 133 testStateOutput(t, statePath, testStateMvOutput) 134 135 // Test we have backups 136 backups := testStateBackups(t, filepath.Dir(statePath)) 137 if len(backups) != 1 { 138 t.Fatalf("bad: %#v", backups) 139 } 140 testStateOutput(t, backups[0], testStateMvOutputOriginal) 141 testStateOutput(t, backupPath, testStateMvOutputOriginal) 142 } 143 144 func TestStateMv_stateOutNew(t *testing.T) { 145 state := &terraform.State{ 146 Modules: []*terraform.ModuleState{ 147 &terraform.ModuleState{ 148 Path: []string{"root"}, 149 Resources: map[string]*terraform.ResourceState{ 150 "test_instance.foo": &terraform.ResourceState{ 151 Type: "test_instance", 152 Primary: &terraform.InstanceState{ 153 ID: "bar", 154 Attributes: map[string]string{ 155 "foo": "value", 156 "bar": "value", 157 }, 158 }, 159 }, 160 }, 161 }, 162 }, 163 } 164 165 statePath := testStateFile(t, state) 166 stateOutPath := statePath + ".out" 167 168 p := testProvider() 169 ui := new(cli.MockUi) 170 c := &StateMvCommand{ 171 Meta: Meta{ 172 ContextOpts: testCtxConfig(p), 173 Ui: ui, 174 }, 175 } 176 177 args := []string{ 178 "-state", statePath, 179 "-state-out", stateOutPath, 180 "test_instance.foo", 181 "test_instance.bar", 182 } 183 if code := c.Run(args); code != 0 { 184 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) 185 } 186 187 // Test it is correct 188 testStateOutput(t, stateOutPath, testStateMvOutput_stateOut) 189 testStateOutput(t, statePath, testStateMvOutput_stateOutSrc) 190 191 // Test we have backups 192 backups := testStateBackups(t, filepath.Dir(statePath)) 193 if len(backups) != 1 { 194 t.Fatalf("bad: %#v", backups) 195 } 196 testStateOutput(t, backups[0], testStateMvOutput_stateOutOriginal) 197 } 198 199 func TestStateMv_stateOutExisting(t *testing.T) { 200 stateSrc := &terraform.State{ 201 Modules: []*terraform.ModuleState{ 202 &terraform.ModuleState{ 203 Path: []string{"root"}, 204 Resources: map[string]*terraform.ResourceState{ 205 "test_instance.foo": &terraform.ResourceState{ 206 Type: "test_instance", 207 Primary: &terraform.InstanceState{ 208 ID: "bar", 209 Attributes: map[string]string{ 210 "foo": "value", 211 "bar": "value", 212 }, 213 }, 214 }, 215 }, 216 }, 217 }, 218 } 219 220 statePath := testStateFile(t, stateSrc) 221 222 stateDst := &terraform.State{ 223 Modules: []*terraform.ModuleState{ 224 &terraform.ModuleState{ 225 Path: []string{"root"}, 226 Resources: map[string]*terraform.ResourceState{ 227 "test_instance.qux": &terraform.ResourceState{ 228 Type: "test_instance", 229 Primary: &terraform.InstanceState{ 230 ID: "bar", 231 }, 232 }, 233 }, 234 }, 235 }, 236 } 237 238 stateOutPath := testStateFile(t, stateDst) 239 240 p := testProvider() 241 ui := new(cli.MockUi) 242 c := &StateMvCommand{ 243 Meta: Meta{ 244 ContextOpts: testCtxConfig(p), 245 Ui: ui, 246 }, 247 } 248 249 args := []string{ 250 "-state", statePath, 251 "-state-out", stateOutPath, 252 "test_instance.foo", 253 "test_instance.bar", 254 } 255 if code := c.Run(args); code != 0 { 256 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) 257 } 258 259 // Test it is correct 260 testStateOutput(t, stateOutPath, testStateMvExisting_stateDst) 261 testStateOutput(t, statePath, testStateMvExisting_stateSrc) 262 263 // Test we have backups 264 backups := testStateBackups(t, filepath.Dir(statePath)) 265 if len(backups) != 1 { 266 t.Fatalf("bad: %#v", backups) 267 } 268 testStateOutput(t, backups[0], testStateMvExisting_stateSrcOriginal) 269 270 backups = testStateBackups(t, filepath.Dir(stateOutPath)) 271 if len(backups) != 1 { 272 t.Fatalf("bad: %#v", backups) 273 } 274 testStateOutput(t, backups[0], testStateMvExisting_stateDstOriginal) 275 } 276 277 func TestStateMv_noState(t *testing.T) { 278 tmp, cwd := testCwd(t) 279 defer testFixCwd(t, tmp, cwd) 280 281 p := testProvider() 282 ui := new(cli.MockUi) 283 c := &StateMvCommand{ 284 Meta: Meta{ 285 ContextOpts: testCtxConfig(p), 286 Ui: ui, 287 }, 288 } 289 290 args := []string{"from", "to"} 291 if code := c.Run(args); code != 1 { 292 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) 293 } 294 } 295 296 func TestStateMv_stateOutNew_count(t *testing.T) { 297 state := &terraform.State{ 298 Modules: []*terraform.ModuleState{ 299 &terraform.ModuleState{ 300 Path: []string{"root"}, 301 Resources: map[string]*terraform.ResourceState{ 302 "test_instance.foo.0": &terraform.ResourceState{ 303 Type: "test_instance", 304 Primary: &terraform.InstanceState{ 305 ID: "foo", 306 Attributes: map[string]string{ 307 "foo": "value", 308 "bar": "value", 309 }, 310 }, 311 }, 312 313 "test_instance.foo.1": &terraform.ResourceState{ 314 Type: "test_instance", 315 Primary: &terraform.InstanceState{ 316 ID: "bar", 317 Attributes: map[string]string{ 318 "foo": "value", 319 "bar": "value", 320 }, 321 }, 322 }, 323 324 "test_instance.bar": &terraform.ResourceState{ 325 Type: "test_instance", 326 Primary: &terraform.InstanceState{ 327 ID: "bar", 328 Attributes: map[string]string{ 329 "foo": "value", 330 "bar": "value", 331 }, 332 }, 333 }, 334 }, 335 }, 336 }, 337 } 338 339 statePath := testStateFile(t, state) 340 stateOutPath := statePath + ".out" 341 342 p := testProvider() 343 ui := new(cli.MockUi) 344 c := &StateMvCommand{ 345 Meta: Meta{ 346 ContextOpts: testCtxConfig(p), 347 Ui: ui, 348 }, 349 } 350 351 args := []string{ 352 "-state", statePath, 353 "-state-out", stateOutPath, 354 "test_instance.foo", 355 "test_instance.bar", 356 } 357 if code := c.Run(args); code != 0 { 358 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) 359 } 360 361 // Test it is correct 362 testStateOutput(t, stateOutPath, testStateMvCount_stateOut) 363 testStateOutput(t, statePath, testStateMvCount_stateOutSrc) 364 365 // Test we have backups 366 backups := testStateBackups(t, filepath.Dir(statePath)) 367 if len(backups) != 1 { 368 t.Fatalf("bad: %#v", backups) 369 } 370 testStateOutput(t, backups[0], testStateMvCount_stateOutOriginal) 371 } 372 373 func TestStateMv_stateOutNew_nestedModule(t *testing.T) { 374 state := &terraform.State{ 375 Modules: []*terraform.ModuleState{ 376 &terraform.ModuleState{ 377 Path: []string{"root"}, 378 Resources: map[string]*terraform.ResourceState{}, 379 }, 380 381 &terraform.ModuleState{ 382 Path: []string{"root", "foo"}, 383 Resources: map[string]*terraform.ResourceState{}, 384 }, 385 386 &terraform.ModuleState{ 387 Path: []string{"root", "foo", "child1"}, 388 Resources: map[string]*terraform.ResourceState{ 389 "test_instance.foo": &terraform.ResourceState{ 390 Type: "test_instance", 391 Primary: &terraform.InstanceState{ 392 ID: "bar", 393 Attributes: map[string]string{ 394 "foo": "value", 395 "bar": "value", 396 }, 397 }, 398 }, 399 }, 400 }, 401 402 &terraform.ModuleState{ 403 Path: []string{"root", "foo", "child2"}, 404 Resources: map[string]*terraform.ResourceState{ 405 "test_instance.foo": &terraform.ResourceState{ 406 Type: "test_instance", 407 Primary: &terraform.InstanceState{ 408 ID: "bar", 409 Attributes: map[string]string{ 410 "foo": "value", 411 "bar": "value", 412 }, 413 }, 414 }, 415 }, 416 }, 417 }, 418 } 419 420 statePath := testStateFile(t, state) 421 stateOutPath := statePath + ".out" 422 423 p := testProvider() 424 ui := new(cli.MockUi) 425 c := &StateMvCommand{ 426 Meta: Meta{ 427 ContextOpts: testCtxConfig(p), 428 Ui: ui, 429 }, 430 } 431 432 args := []string{ 433 "-state", statePath, 434 "-state-out", stateOutPath, 435 "module.foo", 436 "module.bar", 437 } 438 if code := c.Run(args); code != 0 { 439 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) 440 } 441 442 // Test it is correct 443 testStateOutput(t, stateOutPath, testStateMvNestedModule_stateOut) 444 testStateOutput(t, statePath, testStateMvNestedModule_stateOutSrc) 445 446 // Test we have backups 447 backups := testStateBackups(t, filepath.Dir(statePath)) 448 if len(backups) != 1 { 449 t.Fatalf("bad: %#v", backups) 450 } 451 testStateOutput(t, backups[0], testStateMvNestedModule_stateOutOriginal) 452 } 453 454 const testStateMvOutputOriginal = ` 455 test_instance.baz: 456 ID = foo 457 bar = value 458 foo = value 459 test_instance.foo: 460 ID = bar 461 bar = value 462 foo = value 463 ` 464 465 const testStateMvOutput = ` 466 test_instance.bar: 467 ID = bar 468 bar = value 469 foo = value 470 test_instance.baz: 471 ID = foo 472 bar = value 473 foo = value 474 ` 475 476 const testStateMvCount_stateOut = ` 477 test_instance.bar.0: 478 ID = foo 479 bar = value 480 foo = value 481 test_instance.bar.1: 482 ID = bar 483 bar = value 484 foo = value 485 ` 486 487 const testStateMvCount_stateOutSrc = ` 488 test_instance.bar: 489 ID = bar 490 bar = value 491 foo = value 492 ` 493 494 const testStateMvCount_stateOutOriginal = ` 495 test_instance.bar: 496 ID = bar 497 bar = value 498 foo = value 499 test_instance.foo.0: 500 ID = foo 501 bar = value 502 foo = value 503 test_instance.foo.1: 504 ID = bar 505 bar = value 506 foo = value 507 ` 508 509 const testStateMvNestedModule_stateOut = ` 510 <no state> 511 module.bar: 512 <no state> 513 module.bar.child1: 514 test_instance.foo: 515 ID = bar 516 bar = value 517 foo = value 518 module.bar.child2: 519 test_instance.foo: 520 ID = bar 521 bar = value 522 foo = value 523 ` 524 525 const testStateMvNestedModule_stateOutSrc = ` 526 <no state> 527 ` 528 529 const testStateMvNestedModule_stateOutOriginal = ` 530 <no state> 531 module.foo: 532 <no state> 533 module.foo.child1: 534 test_instance.foo: 535 ID = bar 536 bar = value 537 foo = value 538 module.foo.child2: 539 test_instance.foo: 540 ID = bar 541 bar = value 542 foo = value 543 ` 544 545 const testStateMvOutput_stateOut = ` 546 test_instance.bar: 547 ID = bar 548 bar = value 549 foo = value 550 ` 551 552 const testStateMvOutput_stateOutSrc = ` 553 <no state> 554 ` 555 556 const testStateMvOutput_stateOutOriginal = ` 557 test_instance.foo: 558 ID = bar 559 bar = value 560 foo = value 561 ` 562 563 const testStateMvExisting_stateSrc = ` 564 <no state> 565 ` 566 567 const testStateMvExisting_stateDst = ` 568 test_instance.bar: 569 ID = bar 570 bar = value 571 foo = value 572 test_instance.qux: 573 ID = bar 574 ` 575 576 const testStateMvExisting_stateSrcOriginal = ` 577 test_instance.foo: 578 ID = bar 579 bar = value 580 foo = value 581 ` 582 583 const testStateMvExisting_stateDstOriginal = ` 584 test_instance.qux: 585 ID = bar 586 `