github.com/rhenning/terraform@v0.8.0-beta2/command/import_test.go (about) 1 package command 2 3 import ( 4 "fmt" 5 "testing" 6 7 "github.com/hashicorp/terraform/terraform" 8 "github.com/mitchellh/cli" 9 ) 10 11 func TestImport(t *testing.T) { 12 statePath := testTempFile(t) 13 14 p := testProvider() 15 ui := new(cli.MockUi) 16 c := &ImportCommand{ 17 Meta: Meta{ 18 ContextOpts: testCtxConfig(p), 19 Ui: ui, 20 }, 21 } 22 23 p.ImportStateFn = nil 24 p.ImportStateReturn = []*terraform.InstanceState{ 25 &terraform.InstanceState{ 26 ID: "yay", 27 Ephemeral: terraform.EphemeralState{ 28 Type: "test_instance", 29 }, 30 }, 31 } 32 33 args := []string{ 34 "-state", statePath, 35 "test_instance.foo", 36 "bar", 37 } 38 if code := c.Run(args); code != 0 { 39 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) 40 } 41 42 if !p.ImportStateCalled { 43 t.Fatal("ImportState should be called") 44 } 45 46 testStateOutput(t, statePath, testImportStr) 47 } 48 49 func TestImport_providerConfig(t *testing.T) { 50 defer testChdir(t, testFixturePath("import-provider"))() 51 52 statePath := testTempFile(t) 53 54 p := testProvider() 55 ui := new(cli.MockUi) 56 c := &ImportCommand{ 57 Meta: Meta{ 58 ContextOpts: testCtxConfig(p), 59 Ui: ui, 60 }, 61 } 62 63 p.ImportStateFn = nil 64 p.ImportStateReturn = []*terraform.InstanceState{ 65 &terraform.InstanceState{ 66 ID: "yay", 67 Ephemeral: terraform.EphemeralState{ 68 Type: "test_instance", 69 }, 70 }, 71 } 72 73 configured := false 74 p.ConfigureFn = func(c *terraform.ResourceConfig) error { 75 configured = true 76 77 if v, ok := c.Get("foo"); !ok || v.(string) != "bar" { 78 return fmt.Errorf("bad value: %#v", v) 79 } 80 81 return nil 82 } 83 84 args := []string{ 85 "-state", statePath, 86 "test_instance.foo", 87 "bar", 88 } 89 if code := c.Run(args); code != 0 { 90 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) 91 } 92 93 // Verify that we were called 94 if !configured { 95 t.Fatal("Configure should be called") 96 } 97 98 if !p.ImportStateCalled { 99 t.Fatal("ImportState should be called") 100 } 101 102 testStateOutput(t, statePath, testImportStr) 103 } 104 105 func TestImport_providerConfigDisable(t *testing.T) { 106 defer testChdir(t, testFixturePath("import-provider"))() 107 108 statePath := testTempFile(t) 109 110 p := testProvider() 111 ui := new(cli.MockUi) 112 c := &ImportCommand{ 113 Meta: Meta{ 114 ContextOpts: testCtxConfig(p), 115 Ui: ui, 116 }, 117 } 118 119 p.ImportStateFn = nil 120 p.ImportStateReturn = []*terraform.InstanceState{ 121 &terraform.InstanceState{ 122 ID: "yay", 123 Ephemeral: terraform.EphemeralState{ 124 Type: "test_instance", 125 }, 126 }, 127 } 128 129 configured := false 130 p.ConfigureFn = func(c *terraform.ResourceConfig) error { 131 configured = true 132 133 if v, ok := c.Get("foo"); ok { 134 return fmt.Errorf("bad value: %#v", v) 135 } 136 137 return nil 138 } 139 140 args := []string{ 141 "-state", statePath, 142 "-config", "", 143 "test_instance.foo", 144 "bar", 145 } 146 if code := c.Run(args); code != 0 { 147 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) 148 } 149 150 // Verify that we were called 151 if !configured { 152 t.Fatal("Configure should be called") 153 } 154 155 if !p.ImportStateCalled { 156 t.Fatal("ImportState should be called") 157 } 158 159 testStateOutput(t, statePath, testImportStr) 160 } 161 162 /* 163 func TestRefresh_badState(t *testing.T) { 164 p := testProvider() 165 ui := new(cli.MockUi) 166 c := &RefreshCommand{ 167 Meta: Meta{ 168 ContextOpts: testCtxConfig(p), 169 Ui: ui, 170 }, 171 } 172 173 args := []string{ 174 "-state", "i-should-not-exist-ever", 175 testFixturePath("refresh"), 176 } 177 if code := c.Run(args); code != 1 { 178 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) 179 } 180 } 181 182 func TestRefresh_cwd(t *testing.T) { 183 cwd, err := os.Getwd() 184 if err != nil { 185 t.Fatalf("err: %s", err) 186 } 187 if err := os.Chdir(testFixturePath("refresh")); err != nil { 188 t.Fatalf("err: %s", err) 189 } 190 defer os.Chdir(cwd) 191 192 state := testState() 193 statePath := testStateFile(t, state) 194 195 p := testProvider() 196 ui := new(cli.MockUi) 197 c := &RefreshCommand{ 198 Meta: Meta{ 199 ContextOpts: testCtxConfig(p), 200 Ui: ui, 201 }, 202 } 203 204 p.RefreshFn = nil 205 p.RefreshReturn = &terraform.InstanceState{ID: "yes"} 206 207 args := []string{ 208 "-state", statePath, 209 } 210 if code := c.Run(args); code != 0 { 211 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) 212 } 213 214 if !p.RefreshCalled { 215 t.Fatal("refresh should be called") 216 } 217 218 f, err := os.Open(statePath) 219 if err != nil { 220 t.Fatalf("err: %s", err) 221 } 222 223 newState, err := terraform.ReadState(f) 224 f.Close() 225 if err != nil { 226 t.Fatalf("err: %s", err) 227 } 228 229 actual := strings.TrimSpace(newState.String()) 230 expected := strings.TrimSpace(testRefreshCwdStr) 231 if actual != expected { 232 t.Fatalf("bad:\n\n%s", actual) 233 } 234 } 235 236 func TestRefresh_defaultState(t *testing.T) { 237 originalState := testState() 238 239 // Write the state file in a temporary directory with the 240 // default filename. 241 td, err := ioutil.TempDir("", "tf") 242 if err != nil { 243 t.Fatalf("err: %s", err) 244 } 245 statePath := filepath.Join(td, DefaultStateFilename) 246 247 f, err := os.Create(statePath) 248 if err != nil { 249 t.Fatalf("err: %s", err) 250 } 251 err = terraform.WriteState(originalState, f) 252 f.Close() 253 if err != nil { 254 t.Fatalf("err: %s", err) 255 } 256 257 // Change to that directory 258 cwd, err := os.Getwd() 259 if err != nil { 260 t.Fatalf("err: %s", err) 261 } 262 if err := os.Chdir(filepath.Dir(statePath)); err != nil { 263 t.Fatalf("err: %s", err) 264 } 265 defer os.Chdir(cwd) 266 267 p := testProvider() 268 ui := new(cli.MockUi) 269 c := &RefreshCommand{ 270 Meta: Meta{ 271 ContextOpts: testCtxConfig(p), 272 Ui: ui, 273 }, 274 } 275 276 p.RefreshFn = nil 277 p.RefreshReturn = &terraform.InstanceState{ID: "yes"} 278 279 args := []string{ 280 testFixturePath("refresh"), 281 } 282 if code := c.Run(args); code != 0 { 283 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) 284 } 285 286 if !p.RefreshCalled { 287 t.Fatal("refresh should be called") 288 } 289 290 f, err = os.Open(statePath) 291 if err != nil { 292 t.Fatalf("err: %s", err) 293 } 294 295 newState, err := terraform.ReadState(f) 296 f.Close() 297 if err != nil { 298 t.Fatalf("err: %s", err) 299 } 300 301 actual := newState.RootModule().Resources["test_instance.foo"].Primary 302 expected := p.RefreshReturn 303 if !reflect.DeepEqual(actual, expected) { 304 t.Fatalf("bad: %#v", actual) 305 } 306 307 f, err = os.Open(statePath + DefaultBackupExtension) 308 if err != nil { 309 t.Fatalf("err: %s", err) 310 } 311 312 backupState, err := terraform.ReadState(f) 313 f.Close() 314 if err != nil { 315 t.Fatalf("err: %s", err) 316 } 317 318 actual = backupState.RootModule().Resources["test_instance.foo"].Primary 319 expected = originalState.RootModule().Resources["test_instance.foo"].Primary 320 if !reflect.DeepEqual(actual, expected) { 321 t.Fatalf("bad: %#v", actual) 322 } 323 } 324 325 func TestRefresh_futureState(t *testing.T) { 326 cwd, err := os.Getwd() 327 if err != nil { 328 t.Fatalf("err: %s", err) 329 } 330 if err := os.Chdir(testFixturePath("refresh")); err != nil { 331 t.Fatalf("err: %s", err) 332 } 333 defer os.Chdir(cwd) 334 335 state := testState() 336 state.TFVersion = "99.99.99" 337 statePath := testStateFile(t, state) 338 339 p := testProvider() 340 ui := new(cli.MockUi) 341 c := &RefreshCommand{ 342 Meta: Meta{ 343 ContextOpts: testCtxConfig(p), 344 Ui: ui, 345 }, 346 } 347 348 args := []string{ 349 "-state", statePath, 350 } 351 if code := c.Run(args); code == 0 { 352 t.Fatal("should fail") 353 } 354 355 if p.RefreshCalled { 356 t.Fatal("refresh should not be called") 357 } 358 359 f, err := os.Open(statePath) 360 if err != nil { 361 t.Fatalf("err: %s", err) 362 } 363 364 newState, err := terraform.ReadState(f) 365 f.Close() 366 if err != nil { 367 t.Fatalf("err: %s", err) 368 } 369 370 actual := strings.TrimSpace(newState.String()) 371 expected := strings.TrimSpace(state.String()) 372 if actual != expected { 373 t.Fatalf("bad:\n\n%s", actual) 374 } 375 } 376 377 func TestRefresh_pastState(t *testing.T) { 378 state := testState() 379 state.TFVersion = "0.1.0" 380 statePath := testStateFile(t, state) 381 382 p := testProvider() 383 ui := new(cli.MockUi) 384 c := &RefreshCommand{ 385 Meta: Meta{ 386 ContextOpts: testCtxConfig(p), 387 Ui: ui, 388 }, 389 } 390 391 p.RefreshFn = nil 392 p.RefreshReturn = &terraform.InstanceState{ID: "yes"} 393 394 args := []string{ 395 "-state", statePath, 396 testFixturePath("refresh"), 397 } 398 if code := c.Run(args); code != 0 { 399 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) 400 } 401 402 if !p.RefreshCalled { 403 t.Fatal("refresh should be called") 404 } 405 406 f, err := os.Open(statePath) 407 if err != nil { 408 t.Fatalf("err: %s", err) 409 } 410 411 newState, err := terraform.ReadState(f) 412 f.Close() 413 if err != nil { 414 t.Fatalf("err: %s", err) 415 } 416 417 actual := strings.TrimSpace(newState.String()) 418 expected := strings.TrimSpace(testRefreshStr) 419 if actual != expected { 420 t.Fatalf("bad:\n\n%s", actual) 421 } 422 423 if newState.TFVersion != terraform.Version { 424 t.Fatalf("bad:\n\n%s", newState.TFVersion) 425 } 426 } 427 428 func TestRefresh_outPath(t *testing.T) { 429 state := testState() 430 statePath := testStateFile(t, state) 431 432 // Output path 433 outf, err := ioutil.TempFile("", "tf") 434 if err != nil { 435 t.Fatalf("err: %s", err) 436 } 437 outPath := outf.Name() 438 outf.Close() 439 os.Remove(outPath) 440 441 p := testProvider() 442 ui := new(cli.MockUi) 443 c := &RefreshCommand{ 444 Meta: Meta{ 445 ContextOpts: testCtxConfig(p), 446 Ui: ui, 447 }, 448 } 449 450 p.RefreshFn = nil 451 p.RefreshReturn = &terraform.InstanceState{ID: "yes"} 452 453 args := []string{ 454 "-state", statePath, 455 "-state-out", outPath, 456 testFixturePath("refresh"), 457 } 458 if code := c.Run(args); code != 0 { 459 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) 460 } 461 462 f, err := os.Open(statePath) 463 if err != nil { 464 t.Fatalf("err: %s", err) 465 } 466 467 newState, err := terraform.ReadState(f) 468 f.Close() 469 if err != nil { 470 t.Fatalf("err: %s", err) 471 } 472 473 if !reflect.DeepEqual(newState, state) { 474 t.Fatalf("bad: %#v", newState) 475 } 476 477 f, err = os.Open(outPath) 478 if err != nil { 479 t.Fatalf("err: %s", err) 480 } 481 482 newState, err = terraform.ReadState(f) 483 f.Close() 484 if err != nil { 485 t.Fatalf("err: %s", err) 486 } 487 488 actual := newState.RootModule().Resources["test_instance.foo"].Primary 489 expected := p.RefreshReturn 490 if !reflect.DeepEqual(actual, expected) { 491 t.Fatalf("bad: %#v", actual) 492 } 493 494 f, err = os.Open(outPath + DefaultBackupExtension) 495 if err != nil { 496 t.Fatalf("err: %s", err) 497 } 498 499 backupState, err := terraform.ReadState(f) 500 f.Close() 501 if err != nil { 502 t.Fatalf("err: %s", err) 503 } 504 505 actualStr := strings.TrimSpace(backupState.String()) 506 expectedStr := strings.TrimSpace(state.String()) 507 if actualStr != expectedStr { 508 t.Fatalf("bad:\n\n%s\n\n%s", actualStr, expectedStr) 509 } 510 } 511 512 func TestRefresh_var(t *testing.T) { 513 state := testState() 514 statePath := testStateFile(t, state) 515 516 p := testProvider() 517 ui := new(cli.MockUi) 518 c := &RefreshCommand{ 519 Meta: Meta{ 520 ContextOpts: testCtxConfig(p), 521 Ui: ui, 522 }, 523 } 524 525 args := []string{ 526 "-var", "foo=bar", 527 "-state", statePath, 528 testFixturePath("refresh-var"), 529 } 530 if code := c.Run(args); code != 0 { 531 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) 532 } 533 534 if !p.ConfigureCalled { 535 t.Fatal("configure should be called") 536 } 537 if p.ConfigureConfig.Config["value"].(string) != "bar" { 538 t.Fatalf("bad: %#v", p.ConfigureConfig.Config) 539 } 540 } 541 542 func TestRefresh_varFile(t *testing.T) { 543 state := testState() 544 statePath := testStateFile(t, state) 545 546 p := testProvider() 547 ui := new(cli.MockUi) 548 c := &RefreshCommand{ 549 Meta: Meta{ 550 ContextOpts: testCtxConfig(p), 551 Ui: ui, 552 }, 553 } 554 555 varFilePath := testTempFile(t) 556 if err := ioutil.WriteFile(varFilePath, []byte(refreshVarFile), 0644); err != nil { 557 t.Fatalf("err: %s", err) 558 } 559 560 args := []string{ 561 "-var-file", varFilePath, 562 "-state", statePath, 563 testFixturePath("refresh-var"), 564 } 565 if code := c.Run(args); code != 0 { 566 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) 567 } 568 569 if !p.ConfigureCalled { 570 t.Fatal("configure should be called") 571 } 572 if p.ConfigureConfig.Config["value"].(string) != "bar" { 573 t.Fatalf("bad: %#v", p.ConfigureConfig.Config) 574 } 575 } 576 577 func TestRefresh_varFileDefault(t *testing.T) { 578 state := testState() 579 statePath := testStateFile(t, state) 580 581 p := testProvider() 582 ui := new(cli.MockUi) 583 c := &RefreshCommand{ 584 Meta: Meta{ 585 ContextOpts: testCtxConfig(p), 586 Ui: ui, 587 }, 588 } 589 590 varFileDir := testTempDir(t) 591 varFilePath := filepath.Join(varFileDir, "terraform.tfvars") 592 if err := ioutil.WriteFile(varFilePath, []byte(refreshVarFile), 0644); err != nil { 593 t.Fatalf("err: %s", err) 594 } 595 596 cwd, err := os.Getwd() 597 if err != nil { 598 t.Fatalf("err: %s", err) 599 } 600 if err := os.Chdir(varFileDir); err != nil { 601 t.Fatalf("err: %s", err) 602 } 603 defer os.Chdir(cwd) 604 605 args := []string{ 606 "-state", statePath, 607 testFixturePath("refresh-var"), 608 } 609 if code := c.Run(args); code != 0 { 610 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) 611 } 612 613 if !p.ConfigureCalled { 614 t.Fatal("configure should be called") 615 } 616 if p.ConfigureConfig.Config["value"].(string) != "bar" { 617 t.Fatalf("bad: %#v", p.ConfigureConfig.Config) 618 } 619 } 620 621 func TestRefresh_varsUnset(t *testing.T) { 622 // Disable test mode so input would be asked 623 test = false 624 defer func() { test = true }() 625 626 defaultInputReader = bytes.NewBufferString("bar\n") 627 628 state := testState() 629 statePath := testStateFile(t, state) 630 631 p := testProvider() 632 ui := new(cli.MockUi) 633 c := &RefreshCommand{ 634 Meta: Meta{ 635 ContextOpts: testCtxConfig(p), 636 Ui: ui, 637 }, 638 } 639 640 args := []string{ 641 "-state", statePath, 642 testFixturePath("refresh-unset-var"), 643 } 644 if code := c.Run(args); code != 0 { 645 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) 646 } 647 } 648 649 func TestRefresh_backup(t *testing.T) { 650 state := testState() 651 statePath := testStateFile(t, state) 652 653 // Output path 654 outf, err := ioutil.TempFile("", "tf") 655 if err != nil { 656 t.Fatalf("err: %s", err) 657 } 658 outPath := outf.Name() 659 outf.Close() 660 os.Remove(outPath) 661 662 // Backup path 663 backupf, err := ioutil.TempFile("", "tf") 664 if err != nil { 665 t.Fatalf("err: %s", err) 666 } 667 backupPath := backupf.Name() 668 backupf.Close() 669 os.Remove(backupPath) 670 671 p := testProvider() 672 ui := new(cli.MockUi) 673 c := &RefreshCommand{ 674 Meta: Meta{ 675 ContextOpts: testCtxConfig(p), 676 Ui: ui, 677 }, 678 } 679 680 p.RefreshFn = nil 681 p.RefreshReturn = &terraform.InstanceState{ID: "yes"} 682 683 args := []string{ 684 "-state", statePath, 685 "-state-out", outPath, 686 "-backup", backupPath, 687 testFixturePath("refresh"), 688 } 689 if code := c.Run(args); code != 0 { 690 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) 691 } 692 693 f, err := os.Open(statePath) 694 if err != nil { 695 t.Fatalf("err: %s", err) 696 } 697 698 newState, err := terraform.ReadState(f) 699 f.Close() 700 if err != nil { 701 t.Fatalf("err: %s", err) 702 } 703 704 if !reflect.DeepEqual(newState, state) { 705 t.Fatalf("bad: %#v", newState) 706 } 707 708 f, err = os.Open(outPath) 709 if err != nil { 710 t.Fatalf("err: %s", err) 711 } 712 713 newState, err = terraform.ReadState(f) 714 f.Close() 715 if err != nil { 716 t.Fatalf("err: %s", err) 717 } 718 719 actual := newState.RootModule().Resources["test_instance.foo"].Primary 720 expected := p.RefreshReturn 721 if !reflect.DeepEqual(actual, expected) { 722 t.Fatalf("bad: %#v", actual) 723 } 724 725 f, err = os.Open(backupPath) 726 if err != nil { 727 t.Fatalf("err: %s", err) 728 } 729 730 backupState, err := terraform.ReadState(f) 731 f.Close() 732 if err != nil { 733 t.Fatalf("err: %s", err) 734 } 735 736 actualStr := strings.TrimSpace(backupState.String()) 737 expectedStr := strings.TrimSpace(state.String()) 738 if actualStr != expectedStr { 739 t.Fatalf("bad:\n\n%s\n\n%s", actualStr, expectedStr) 740 } 741 } 742 743 func TestRefresh_disableBackup(t *testing.T) { 744 state := testState() 745 statePath := testStateFile(t, state) 746 747 // Output path 748 outf, err := ioutil.TempFile("", "tf") 749 if err != nil { 750 t.Fatalf("err: %s", err) 751 } 752 outPath := outf.Name() 753 outf.Close() 754 os.Remove(outPath) 755 756 p := testProvider() 757 ui := new(cli.MockUi) 758 c := &RefreshCommand{ 759 Meta: Meta{ 760 ContextOpts: testCtxConfig(p), 761 Ui: ui, 762 }, 763 } 764 765 p.RefreshFn = nil 766 p.RefreshReturn = &terraform.InstanceState{ID: "yes"} 767 768 args := []string{ 769 "-state", statePath, 770 "-state-out", outPath, 771 "-backup", "-", 772 testFixturePath("refresh"), 773 } 774 if code := c.Run(args); code != 0 { 775 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) 776 } 777 778 f, err := os.Open(statePath) 779 if err != nil { 780 t.Fatalf("err: %s", err) 781 } 782 783 newState, err := terraform.ReadState(f) 784 f.Close() 785 if err != nil { 786 t.Fatalf("err: %s", err) 787 } 788 789 if !reflect.DeepEqual(newState, state) { 790 t.Fatalf("bad: %#v", newState) 791 } 792 793 f, err = os.Open(outPath) 794 if err != nil { 795 t.Fatalf("err: %s", err) 796 } 797 798 newState, err = terraform.ReadState(f) 799 f.Close() 800 if err != nil { 801 t.Fatalf("err: %s", err) 802 } 803 804 actual := newState.RootModule().Resources["test_instance.foo"].Primary 805 expected := p.RefreshReturn 806 if !reflect.DeepEqual(actual, expected) { 807 t.Fatalf("bad: %#v", actual) 808 } 809 810 // Ensure there is no backup 811 _, err = os.Stat(outPath + DefaultBackupExtension) 812 if err == nil || !os.IsNotExist(err) { 813 t.Fatalf("backup should not exist") 814 } 815 } 816 817 func TestRefresh_displaysOutputs(t *testing.T) { 818 state := testState() 819 statePath := testStateFile(t, state) 820 821 p := testProvider() 822 ui := new(cli.MockUi) 823 c := &RefreshCommand{ 824 Meta: Meta{ 825 ContextOpts: testCtxConfig(p), 826 Ui: ui, 827 }, 828 } 829 830 args := []string{ 831 "-state", statePath, 832 testFixturePath("refresh-output"), 833 } 834 if code := c.Run(args); code != 0 { 835 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) 836 } 837 838 // Test that outputs were displayed 839 outputValue := "foo.example.com" 840 actual := ui.OutputWriter.String() 841 if !strings.Contains(actual, outputValue) { 842 t.Fatalf("Expected:\n%s\n\nTo include: %q", actual, outputValue) 843 } 844 } 845 */ 846 847 const testImportStr = ` 848 test_instance.foo: 849 ID = yay 850 provider = test 851 `