github.com/acm1/terraform@v0.6.2-0.20150729164239-1f314444f45c/terraform/context_plan_test.go (about) 1 package terraform 2 3 import ( 4 "bytes" 5 "fmt" 6 "os" 7 "reflect" 8 "sort" 9 "strings" 10 "sync" 11 "testing" 12 "time" 13 ) 14 15 func TestContext2Plan(t *testing.T) { 16 m := testModule(t, "plan-good") 17 p := testProvider("aws") 18 p.DiffFn = testDiffFn 19 ctx := testContext2(t, &ContextOpts{ 20 Module: m, 21 Providers: map[string]ResourceProviderFactory{ 22 "aws": testProviderFuncFixed(p), 23 }, 24 }) 25 26 plan, err := ctx.Plan() 27 if err != nil { 28 t.Fatalf("err: %s", err) 29 } 30 31 if len(plan.Diff.RootModule().Resources) < 2 { 32 t.Fatalf("bad: %#v", plan.Diff.RootModule().Resources) 33 } 34 35 actual := strings.TrimSpace(plan.String()) 36 expected := strings.TrimSpace(testTerraformPlanStr) 37 if actual != expected { 38 t.Fatalf("bad:\n%s", actual) 39 } 40 } 41 42 func TestContext2Plan_createBefore_maintainRoot(t *testing.T) { 43 m := testModule(t, "plan-cbd-maintain-root") 44 p := testProvider("aws") 45 p.DiffFn = testDiffFn 46 ctx := testContext2(t, &ContextOpts{ 47 Module: m, 48 Providers: map[string]ResourceProviderFactory{ 49 "aws": testProviderFuncFixed(p), 50 }, 51 Variables: map[string]string{ 52 "in": "a,b,c", 53 }, 54 }) 55 56 plan, err := ctx.Plan() 57 if err != nil { 58 t.Fatalf("err: %s", err) 59 } 60 61 actual := strings.TrimSpace(plan.String()) 62 expected := strings.TrimSpace(` 63 DIFF: 64 65 CREATE: aws_instance.bar.0 66 CREATE: aws_instance.bar.1 67 CREATE: aws_instance.foo.0 68 CREATE: aws_instance.foo.1 69 70 STATE: 71 72 <no state> 73 `) 74 if actual != expected { 75 t.Fatalf("expected:\n%s, got:\n%s", expected, actual) 76 } 77 } 78 79 func TestContext2Plan_emptyDiff(t *testing.T) { 80 m := testModule(t, "plan-empty") 81 p := testProvider("aws") 82 p.DiffFn = func( 83 info *InstanceInfo, 84 s *InstanceState, 85 c *ResourceConfig) (*InstanceDiff, error) { 86 return nil, nil 87 } 88 89 ctx := testContext2(t, &ContextOpts{ 90 Module: m, 91 Providers: map[string]ResourceProviderFactory{ 92 "aws": testProviderFuncFixed(p), 93 }, 94 }) 95 96 plan, err := ctx.Plan() 97 if err != nil { 98 t.Fatalf("err: %s", err) 99 } 100 101 actual := strings.TrimSpace(plan.String()) 102 expected := strings.TrimSpace(testTerraformPlanEmptyStr) 103 if actual != expected { 104 t.Fatalf("bad:\n%s", actual) 105 } 106 } 107 108 func TestContext2Plan_minimal(t *testing.T) { 109 m := testModule(t, "plan-empty") 110 p := testProvider("aws") 111 p.DiffFn = testDiffFn 112 ctx := testContext2(t, &ContextOpts{ 113 Module: m, 114 Providers: map[string]ResourceProviderFactory{ 115 "aws": testProviderFuncFixed(p), 116 }, 117 }) 118 119 plan, err := ctx.Plan() 120 if err != nil { 121 t.Fatalf("err: %s", err) 122 } 123 124 actual := strings.TrimSpace(plan.String()) 125 expected := strings.TrimSpace(testTerraformPlanEmptyStr) 126 if actual != expected { 127 t.Fatalf("bad:\n%s", actual) 128 } 129 } 130 131 func TestContext2Plan_modules(t *testing.T) { 132 m := testModule(t, "plan-modules") 133 p := testProvider("aws") 134 p.DiffFn = testDiffFn 135 ctx := testContext2(t, &ContextOpts{ 136 Module: m, 137 Providers: map[string]ResourceProviderFactory{ 138 "aws": testProviderFuncFixed(p), 139 }, 140 }) 141 142 plan, err := ctx.Plan() 143 if err != nil { 144 t.Fatalf("err: %s", err) 145 } 146 147 actual := strings.TrimSpace(plan.String()) 148 expected := strings.TrimSpace(testTerraformPlanModulesStr) 149 if actual != expected { 150 t.Fatalf("bad:\n%s", actual) 151 } 152 } 153 154 // GH-1475 155 func TestContext2Plan_moduleCycle(t *testing.T) { 156 m := testModule(t, "plan-module-cycle") 157 p := testProvider("aws") 158 p.DiffFn = testDiffFn 159 ctx := testContext2(t, &ContextOpts{ 160 Module: m, 161 Providers: map[string]ResourceProviderFactory{ 162 "aws": testProviderFuncFixed(p), 163 }, 164 }) 165 166 plan, err := ctx.Plan() 167 if err != nil { 168 t.Fatalf("err: %s", err) 169 } 170 171 actual := strings.TrimSpace(plan.String()) 172 expected := strings.TrimSpace(testTerraformPlanModuleCycleStr) 173 if actual != expected { 174 t.Fatalf("bad:\n%s", actual) 175 } 176 } 177 178 func TestContext2Plan_moduleDeadlock(t *testing.T) { 179 m := testModule(t, "plan-module-deadlock") 180 p := testProvider("aws") 181 p.DiffFn = testDiffFn 182 timeout := make(chan bool, 1) 183 done := make(chan bool, 1) 184 go func() { 185 time.Sleep(3 * time.Second) 186 timeout <- true 187 }() 188 go func() { 189 ctx := testContext2(t, &ContextOpts{ 190 Module: m, 191 Providers: map[string]ResourceProviderFactory{ 192 "aws": testProviderFuncFixed(p), 193 }, 194 }) 195 196 plan, err := ctx.Plan() 197 done <- true 198 if err != nil { 199 t.Fatalf("err: %s", err) 200 } 201 202 actual := strings.TrimSpace(plan.String()) 203 expected := strings.TrimSpace(` 204 DIFF: 205 206 module.child: 207 CREATE: aws_instance.foo.0 208 CREATE: aws_instance.foo.1 209 CREATE: aws_instance.foo.2 210 211 STATE: 212 213 <no state> 214 `) 215 if actual != expected { 216 t.Fatalf("expected:\n%sgot:\n%s", expected, actual) 217 } 218 }() 219 220 select { 221 case <-timeout: 222 t.Fatalf("timed out! probably deadlock") 223 case <-done: 224 // ok 225 } 226 } 227 228 func TestContext2Plan_moduleInput(t *testing.T) { 229 m := testModule(t, "plan-module-input") 230 p := testProvider("aws") 231 p.DiffFn = testDiffFn 232 ctx := testContext2(t, &ContextOpts{ 233 Module: m, 234 Providers: map[string]ResourceProviderFactory{ 235 "aws": testProviderFuncFixed(p), 236 }, 237 }) 238 239 plan, err := ctx.Plan() 240 if err != nil { 241 t.Fatalf("err: %s", err) 242 } 243 244 actual := strings.TrimSpace(plan.String()) 245 expected := strings.TrimSpace(testTerraformPlanModuleInputStr) 246 if actual != expected { 247 t.Fatalf("bad:\n%s", actual) 248 } 249 } 250 251 func TestContext2Plan_moduleInputComputed(t *testing.T) { 252 m := testModule(t, "plan-module-input-computed") 253 p := testProvider("aws") 254 p.DiffFn = testDiffFn 255 ctx := testContext2(t, &ContextOpts{ 256 Module: m, 257 Providers: map[string]ResourceProviderFactory{ 258 "aws": testProviderFuncFixed(p), 259 }, 260 }) 261 262 plan, err := ctx.Plan() 263 if err != nil { 264 t.Fatalf("err: %s", err) 265 } 266 267 actual := strings.TrimSpace(plan.String()) 268 expected := strings.TrimSpace(testTerraformPlanModuleInputComputedStr) 269 if actual != expected { 270 t.Fatalf("bad:\n%s", actual) 271 } 272 } 273 274 func TestContext2Plan_moduleInputFromVar(t *testing.T) { 275 m := testModule(t, "plan-module-input-var") 276 p := testProvider("aws") 277 p.DiffFn = testDiffFn 278 ctx := testContext2(t, &ContextOpts{ 279 Module: m, 280 Providers: map[string]ResourceProviderFactory{ 281 "aws": testProviderFuncFixed(p), 282 }, 283 Variables: map[string]string{ 284 "foo": "52", 285 }, 286 }) 287 288 plan, err := ctx.Plan() 289 if err != nil { 290 t.Fatalf("err: %s", err) 291 } 292 293 actual := strings.TrimSpace(plan.String()) 294 expected := strings.TrimSpace(testTerraformPlanModuleInputVarStr) 295 if actual != expected { 296 t.Fatalf("bad:\n%s", actual) 297 } 298 } 299 300 func TestContext2Plan_moduleMultiVar(t *testing.T) { 301 m := testModule(t, "plan-module-multi-var") 302 p := testProvider("aws") 303 p.DiffFn = testDiffFn 304 ctx := testContext2(t, &ContextOpts{ 305 Module: m, 306 Providers: map[string]ResourceProviderFactory{ 307 "aws": testProviderFuncFixed(p), 308 }, 309 }) 310 311 plan, err := ctx.Plan() 312 if err != nil { 313 t.Fatalf("err: %s", err) 314 } 315 316 actual := strings.TrimSpace(plan.String()) 317 expected := strings.TrimSpace(testTerraformPlanModuleMultiVarStr) 318 if actual != expected { 319 t.Fatalf("bad:\n%s", actual) 320 } 321 } 322 323 func TestContext2Plan_moduleOrphans(t *testing.T) { 324 m := testModule(t, "plan-modules-remove") 325 p := testProvider("aws") 326 p.DiffFn = testDiffFn 327 s := &State{ 328 Modules: []*ModuleState{ 329 &ModuleState{ 330 Path: []string{"root", "child"}, 331 Resources: map[string]*ResourceState{ 332 "aws_instance.foo": &ResourceState{ 333 Type: "aws_instance", 334 Primary: &InstanceState{ 335 ID: "baz", 336 }, 337 }, 338 }, 339 }, 340 }, 341 } 342 ctx := testContext2(t, &ContextOpts{ 343 Module: m, 344 Providers: map[string]ResourceProviderFactory{ 345 "aws": testProviderFuncFixed(p), 346 }, 347 State: s, 348 }) 349 350 plan, err := ctx.Plan() 351 if err != nil { 352 t.Fatalf("err: %s", err) 353 } 354 355 actual := strings.TrimSpace(plan.String()) 356 expected := strings.TrimSpace(testTerraformPlanModuleOrphansStr) 357 if actual != expected { 358 t.Fatalf("bad:\n%s", actual) 359 } 360 } 361 362 func TestContext2Plan_moduleProviderInherit(t *testing.T) { 363 var l sync.Mutex 364 var calls []string 365 366 m := testModule(t, "plan-module-provider-inherit") 367 ctx := testContext2(t, &ContextOpts{ 368 Module: m, 369 Providers: map[string]ResourceProviderFactory{ 370 "aws": func() (ResourceProvider, error) { 371 l.Lock() 372 defer l.Unlock() 373 374 p := testProvider("aws") 375 p.ConfigureFn = func(c *ResourceConfig) error { 376 if v, ok := c.Get("from"); !ok || v.(string) != "root" { 377 return fmt.Errorf("bad") 378 } 379 380 return nil 381 } 382 p.DiffFn = func( 383 info *InstanceInfo, 384 state *InstanceState, 385 c *ResourceConfig) (*InstanceDiff, error) { 386 v, _ := c.Get("from") 387 calls = append(calls, v.(string)) 388 return testDiffFn(info, state, c) 389 } 390 return p, nil 391 }, 392 }, 393 }) 394 395 _, err := ctx.Plan() 396 if err != nil { 397 t.Fatalf("err: %s", err) 398 } 399 400 actual := calls 401 sort.Strings(actual) 402 expected := []string{"child", "root"} 403 if !reflect.DeepEqual(actual, expected) { 404 t.Fatalf("bad: %#v", actual) 405 } 406 } 407 408 func TestContext2Plan_moduleProviderDefaults(t *testing.T) { 409 var l sync.Mutex 410 var calls []string 411 toCount := 0 412 413 m := testModule(t, "plan-module-provider-defaults") 414 ctx := testContext2(t, &ContextOpts{ 415 Module: m, 416 Providers: map[string]ResourceProviderFactory{ 417 "aws": func() (ResourceProvider, error) { 418 l.Lock() 419 defer l.Unlock() 420 421 p := testProvider("aws") 422 p.ConfigureFn = func(c *ResourceConfig) error { 423 if v, ok := c.Get("from"); !ok || v.(string) != "root" { 424 return fmt.Errorf("bad") 425 } 426 if v, ok := c.Get("to"); ok && v.(string) == "child" { 427 toCount++ 428 } 429 430 return nil 431 } 432 p.DiffFn = func( 433 info *InstanceInfo, 434 state *InstanceState, 435 c *ResourceConfig) (*InstanceDiff, error) { 436 v, _ := c.Get("from") 437 calls = append(calls, v.(string)) 438 return testDiffFn(info, state, c) 439 } 440 return p, nil 441 }, 442 }, 443 }) 444 445 _, err := ctx.Plan() 446 if err != nil { 447 t.Fatalf("err: %s", err) 448 } 449 450 if toCount != 1 { 451 t.Fatalf( 452 "provider in child didn't set proper config\n\n"+ 453 "toCount: %d", toCount) 454 } 455 456 actual := calls 457 sort.Strings(actual) 458 expected := []string{"child", "root"} 459 if !reflect.DeepEqual(actual, expected) { 460 t.Fatalf("bad: %#v", actual) 461 } 462 } 463 464 func TestContext2Plan_moduleProviderDefaultsVar(t *testing.T) { 465 var l sync.Mutex 466 var calls []string 467 468 m := testModule(t, "plan-module-provider-defaults-var") 469 ctx := testContext2(t, &ContextOpts{ 470 Module: m, 471 Providers: map[string]ResourceProviderFactory{ 472 "aws": func() (ResourceProvider, error) { 473 l.Lock() 474 defer l.Unlock() 475 476 p := testProvider("aws") 477 p.ConfigureFn = func(c *ResourceConfig) error { 478 var buf bytes.Buffer 479 if v, ok := c.Get("from"); ok { 480 buf.WriteString(v.(string) + "\n") 481 } 482 if v, ok := c.Get("to"); ok { 483 buf.WriteString(v.(string) + "\n") 484 } 485 486 calls = append(calls, buf.String()) 487 return nil 488 } 489 p.DiffFn = testDiffFn 490 return p, nil 491 }, 492 }, 493 Variables: map[string]string{ 494 "foo": "root", 495 }, 496 }) 497 498 _, err := ctx.Plan() 499 if err != nil { 500 t.Fatalf("err: %s", err) 501 } 502 503 expected := []string{ 504 "root\n", 505 "root\nchild\n", 506 } 507 if !reflect.DeepEqual(calls, expected) { 508 t.Fatalf("BAD: %#v", calls) 509 } 510 } 511 512 func TestContext2Plan_moduleVar(t *testing.T) { 513 m := testModule(t, "plan-module-var") 514 p := testProvider("aws") 515 p.DiffFn = testDiffFn 516 ctx := testContext2(t, &ContextOpts{ 517 Module: m, 518 Providers: map[string]ResourceProviderFactory{ 519 "aws": testProviderFuncFixed(p), 520 }, 521 }) 522 523 plan, err := ctx.Plan() 524 if err != nil { 525 t.Fatalf("err: %s", err) 526 } 527 528 actual := strings.TrimSpace(plan.String()) 529 expected := strings.TrimSpace(testTerraformPlanModuleVarStr) 530 if actual != expected { 531 t.Fatalf("bad:\n%s", actual) 532 } 533 } 534 535 func TestContext2Plan_moduleVarComputed(t *testing.T) { 536 m := testModule(t, "plan-module-var-computed") 537 p := testProvider("aws") 538 p.DiffFn = testDiffFn 539 ctx := testContext2(t, &ContextOpts{ 540 Module: m, 541 Providers: map[string]ResourceProviderFactory{ 542 "aws": testProviderFuncFixed(p), 543 }, 544 }) 545 546 plan, err := ctx.Plan() 547 if err != nil { 548 t.Fatalf("err: %s", err) 549 } 550 551 actual := strings.TrimSpace(plan.String()) 552 expected := strings.TrimSpace(testTerraformPlanModuleVarComputedStr) 553 if actual != expected { 554 t.Fatalf("bad:\n%s", actual) 555 } 556 } 557 558 func TestContext2Plan_nil(t *testing.T) { 559 m := testModule(t, "plan-nil") 560 p := testProvider("aws") 561 p.DiffFn = testDiffFn 562 ctx := testContext2(t, &ContextOpts{ 563 Module: m, 564 Providers: map[string]ResourceProviderFactory{ 565 "aws": testProviderFuncFixed(p), 566 }, 567 State: &State{ 568 Modules: []*ModuleState{ 569 &ModuleState{ 570 Path: rootModulePath, 571 Resources: map[string]*ResourceState{ 572 "aws_instance.foo": &ResourceState{ 573 Type: "aws_instance", 574 Primary: &InstanceState{ 575 ID: "bar", 576 }, 577 }, 578 }, 579 }, 580 }, 581 }, 582 }) 583 584 plan, err := ctx.Plan() 585 if err != nil { 586 t.Fatalf("err: %s", err) 587 } 588 if len(plan.Diff.RootModule().Resources) != 0 { 589 t.Fatalf("bad: %#v", plan.Diff.RootModule().Resources) 590 } 591 } 592 593 func TestContext2Plan_preventDestroy_bad(t *testing.T) { 594 m := testModule(t, "plan-prevent-destroy-bad") 595 p := testProvider("aws") 596 p.DiffFn = testDiffFn 597 ctx := testContext2(t, &ContextOpts{ 598 Module: m, 599 Providers: map[string]ResourceProviderFactory{ 600 "aws": testProviderFuncFixed(p), 601 }, 602 State: &State{ 603 Modules: []*ModuleState{ 604 &ModuleState{ 605 Path: rootModulePath, 606 Resources: map[string]*ResourceState{ 607 "aws_instance.foo": &ResourceState{ 608 Type: "aws_instance", 609 Primary: &InstanceState{ 610 ID: "i-abc123", 611 }, 612 }, 613 }, 614 }, 615 }, 616 }, 617 }) 618 619 plan, err := ctx.Plan() 620 621 expectedErr := "aws_instance.foo: plan would destroy" 622 if !strings.Contains(fmt.Sprintf("%s", err), expectedErr) { 623 t.Fatalf("expected err would contain %q\nerr: %s\nplan: %s", 624 expectedErr, err, plan) 625 } 626 } 627 628 func TestContext2Plan_preventDestroy_good(t *testing.T) { 629 m := testModule(t, "plan-prevent-destroy-good") 630 p := testProvider("aws") 631 p.DiffFn = testDiffFn 632 ctx := testContext2(t, &ContextOpts{ 633 Module: m, 634 Providers: map[string]ResourceProviderFactory{ 635 "aws": testProviderFuncFixed(p), 636 }, 637 State: &State{ 638 Modules: []*ModuleState{ 639 &ModuleState{ 640 Path: rootModulePath, 641 Resources: map[string]*ResourceState{ 642 "aws_instance.foo": &ResourceState{ 643 Type: "aws_instance", 644 Primary: &InstanceState{ 645 ID: "i-abc123", 646 }, 647 }, 648 }, 649 }, 650 }, 651 }, 652 }) 653 654 plan, err := ctx.Plan() 655 if err != nil { 656 t.Fatalf("err: %s", err) 657 } 658 if !plan.Diff.Empty() { 659 t.Fatalf("Expected empty plan, got %s", plan.String()) 660 } 661 } 662 663 func TestContext2Plan_preventDestroy_destroyPlan(t *testing.T) { 664 m := testModule(t, "plan-prevent-destroy-good") 665 p := testProvider("aws") 666 p.DiffFn = testDiffFn 667 ctx := testContext2(t, &ContextOpts{ 668 Module: m, 669 Providers: map[string]ResourceProviderFactory{ 670 "aws": testProviderFuncFixed(p), 671 }, 672 State: &State{ 673 Modules: []*ModuleState{ 674 &ModuleState{ 675 Path: rootModulePath, 676 Resources: map[string]*ResourceState{ 677 "aws_instance.foo": &ResourceState{ 678 Type: "aws_instance", 679 Primary: &InstanceState{ 680 ID: "i-abc123", 681 }, 682 }, 683 }, 684 }, 685 }, 686 }, 687 Destroy: true, 688 }) 689 690 plan, err := ctx.Plan() 691 692 expectedErr := "aws_instance.foo: plan would destroy" 693 if !strings.Contains(fmt.Sprintf("%s", err), expectedErr) { 694 t.Fatalf("expected err would contain %q\nerr: %s\nplan: %s", 695 expectedErr, err, plan) 696 } 697 } 698 699 func TestContext2Plan_computed(t *testing.T) { 700 m := testModule(t, "plan-computed") 701 p := testProvider("aws") 702 p.DiffFn = testDiffFn 703 ctx := testContext2(t, &ContextOpts{ 704 Module: m, 705 Providers: map[string]ResourceProviderFactory{ 706 "aws": testProviderFuncFixed(p), 707 }, 708 }) 709 710 plan, err := ctx.Plan() 711 if err != nil { 712 t.Fatalf("err: %s", err) 713 } 714 715 actual := strings.TrimSpace(plan.String()) 716 expected := strings.TrimSpace(testTerraformPlanComputedStr) 717 if actual != expected { 718 t.Fatalf("bad:\n%s", actual) 719 } 720 } 721 722 func TestContext2Plan_computedList(t *testing.T) { 723 m := testModule(t, "plan-computed-list") 724 p := testProvider("aws") 725 p.DiffFn = testDiffFn 726 ctx := testContext2(t, &ContextOpts{ 727 Module: m, 728 Providers: map[string]ResourceProviderFactory{ 729 "aws": testProviderFuncFixed(p), 730 }, 731 }) 732 733 plan, err := ctx.Plan() 734 if err != nil { 735 t.Fatalf("err: %s", err) 736 } 737 738 actual := strings.TrimSpace(plan.String()) 739 expected := strings.TrimSpace(testTerraformPlanComputedListStr) 740 if actual != expected { 741 t.Fatalf("bad:\n%s", actual) 742 } 743 } 744 745 func TestContext2Plan_count(t *testing.T) { 746 m := testModule(t, "plan-count") 747 p := testProvider("aws") 748 p.DiffFn = testDiffFn 749 ctx := testContext2(t, &ContextOpts{ 750 Module: m, 751 Providers: map[string]ResourceProviderFactory{ 752 "aws": testProviderFuncFixed(p), 753 }, 754 }) 755 756 plan, err := ctx.Plan() 757 if err != nil { 758 t.Fatalf("err: %s", err) 759 } 760 761 if len(plan.Diff.RootModule().Resources) < 6 { 762 t.Fatalf("bad: %#v", plan.Diff.RootModule().Resources) 763 } 764 765 actual := strings.TrimSpace(plan.String()) 766 expected := strings.TrimSpace(testTerraformPlanCountStr) 767 if actual != expected { 768 t.Fatalf("bad:\n%s", actual) 769 } 770 } 771 772 func TestContext2Plan_countComputed(t *testing.T) { 773 m := testModule(t, "plan-count-computed") 774 p := testProvider("aws") 775 p.DiffFn = testDiffFn 776 ctx := testContext2(t, &ContextOpts{ 777 Module: m, 778 Providers: map[string]ResourceProviderFactory{ 779 "aws": testProviderFuncFixed(p), 780 }, 781 }) 782 783 _, err := ctx.Plan() 784 if err == nil { 785 t.Fatal("should error") 786 } 787 } 788 789 func TestContext2Plan_countIndex(t *testing.T) { 790 m := testModule(t, "plan-count-index") 791 p := testProvider("aws") 792 p.DiffFn = testDiffFn 793 ctx := testContext2(t, &ContextOpts{ 794 Module: m, 795 Providers: map[string]ResourceProviderFactory{ 796 "aws": testProviderFuncFixed(p), 797 }, 798 }) 799 800 plan, err := ctx.Plan() 801 if err != nil { 802 t.Fatalf("err: %s", err) 803 } 804 805 actual := strings.TrimSpace(plan.String()) 806 expected := strings.TrimSpace(testTerraformPlanCountIndexStr) 807 if actual != expected { 808 t.Fatalf("bad:\n%s", actual) 809 } 810 } 811 812 func TestContext2Plan_countIndexZero(t *testing.T) { 813 m := testModule(t, "plan-count-index-zero") 814 p := testProvider("aws") 815 p.DiffFn = testDiffFn 816 ctx := testContext2(t, &ContextOpts{ 817 Module: m, 818 Providers: map[string]ResourceProviderFactory{ 819 "aws": testProviderFuncFixed(p), 820 }, 821 }) 822 823 plan, err := ctx.Plan() 824 if err != nil { 825 t.Fatalf("err: %s", err) 826 } 827 828 actual := strings.TrimSpace(plan.String()) 829 expected := strings.TrimSpace(testTerraformPlanCountIndexZeroStr) 830 if actual != expected { 831 t.Fatalf("bad:\n%s", actual) 832 } 833 } 834 835 func TestContext2Plan_countVar(t *testing.T) { 836 m := testModule(t, "plan-count-var") 837 p := testProvider("aws") 838 p.DiffFn = testDiffFn 839 ctx := testContext2(t, &ContextOpts{ 840 Module: m, 841 Providers: map[string]ResourceProviderFactory{ 842 "aws": testProviderFuncFixed(p), 843 }, 844 Variables: map[string]string{ 845 "count": "3", 846 }, 847 }) 848 849 plan, err := ctx.Plan() 850 if err != nil { 851 t.Fatalf("err: %s", err) 852 } 853 854 actual := strings.TrimSpace(plan.String()) 855 expected := strings.TrimSpace(testTerraformPlanCountVarStr) 856 if actual != expected { 857 t.Fatalf("bad:\n%s", actual) 858 } 859 } 860 861 func TestContext2Plan_countZero(t *testing.T) { 862 m := testModule(t, "plan-count-zero") 863 p := testProvider("aws") 864 p.DiffFn = testDiffFn 865 ctx := testContext2(t, &ContextOpts{ 866 Module: m, 867 Providers: map[string]ResourceProviderFactory{ 868 "aws": testProviderFuncFixed(p), 869 }, 870 }) 871 872 plan, err := ctx.Plan() 873 if err != nil { 874 t.Fatalf("err: %s", err) 875 } 876 877 actual := strings.TrimSpace(plan.String()) 878 expected := strings.TrimSpace(testTerraformPlanCountZeroStr) 879 if actual != expected { 880 t.Fatalf("bad:\n%s", actual) 881 } 882 } 883 884 func TestContext2Plan_countOneIndex(t *testing.T) { 885 m := testModule(t, "plan-count-one-index") 886 p := testProvider("aws") 887 p.DiffFn = testDiffFn 888 ctx := testContext2(t, &ContextOpts{ 889 Module: m, 890 Providers: map[string]ResourceProviderFactory{ 891 "aws": testProviderFuncFixed(p), 892 }, 893 }) 894 895 plan, err := ctx.Plan() 896 if err != nil { 897 t.Fatalf("err: %s", err) 898 } 899 900 actual := strings.TrimSpace(plan.String()) 901 expected := strings.TrimSpace(testTerraformPlanCountOneIndexStr) 902 if actual != expected { 903 t.Fatalf("bad:\n%s", actual) 904 } 905 } 906 907 func TestContext2Plan_countDecreaseToOne(t *testing.T) { 908 m := testModule(t, "plan-count-dec") 909 p := testProvider("aws") 910 p.DiffFn = testDiffFn 911 s := &State{ 912 Modules: []*ModuleState{ 913 &ModuleState{ 914 Path: rootModulePath, 915 Resources: map[string]*ResourceState{ 916 "aws_instance.foo.0": &ResourceState{ 917 Type: "aws_instance", 918 Primary: &InstanceState{ 919 ID: "bar", 920 Attributes: map[string]string{ 921 "foo": "foo", 922 "type": "aws_instance", 923 }, 924 }, 925 }, 926 "aws_instance.foo.1": &ResourceState{ 927 Type: "aws_instance", 928 Primary: &InstanceState{ 929 ID: "bar", 930 }, 931 }, 932 "aws_instance.foo.2": &ResourceState{ 933 Type: "aws_instance", 934 Primary: &InstanceState{ 935 ID: "bar", 936 }, 937 }, 938 }, 939 }, 940 }, 941 } 942 ctx := testContext2(t, &ContextOpts{ 943 Module: m, 944 Providers: map[string]ResourceProviderFactory{ 945 "aws": testProviderFuncFixed(p), 946 }, 947 State: s, 948 }) 949 950 plan, err := ctx.Plan() 951 if err != nil { 952 t.Fatalf("err: %s", err) 953 } 954 955 actual := strings.TrimSpace(plan.String()) 956 expected := strings.TrimSpace(testTerraformPlanCountDecreaseStr) 957 if actual != expected { 958 t.Fatalf("bad:\n%s", actual) 959 } 960 } 961 962 func TestContext2Plan_countIncreaseFromNotSet(t *testing.T) { 963 m := testModule(t, "plan-count-inc") 964 p := testProvider("aws") 965 p.DiffFn = testDiffFn 966 s := &State{ 967 Modules: []*ModuleState{ 968 &ModuleState{ 969 Path: rootModulePath, 970 Resources: map[string]*ResourceState{ 971 "aws_instance.foo": &ResourceState{ 972 Type: "aws_instance", 973 Primary: &InstanceState{ 974 ID: "bar", 975 Attributes: map[string]string{ 976 "foo": "foo", 977 "type": "aws_instance", 978 }, 979 }, 980 }, 981 }, 982 }, 983 }, 984 } 985 ctx := testContext2(t, &ContextOpts{ 986 Module: m, 987 Providers: map[string]ResourceProviderFactory{ 988 "aws": testProviderFuncFixed(p), 989 }, 990 State: s, 991 }) 992 993 plan, err := ctx.Plan() 994 if err != nil { 995 t.Fatalf("err: %s", err) 996 } 997 998 actual := strings.TrimSpace(plan.String()) 999 expected := strings.TrimSpace(testTerraformPlanCountIncreaseStr) 1000 if actual != expected { 1001 t.Fatalf("bad:\n%s", actual) 1002 } 1003 } 1004 1005 func TestContext2Plan_countIncreaseFromOne(t *testing.T) { 1006 m := testModule(t, "plan-count-inc") 1007 p := testProvider("aws") 1008 p.DiffFn = testDiffFn 1009 s := &State{ 1010 Modules: []*ModuleState{ 1011 &ModuleState{ 1012 Path: rootModulePath, 1013 Resources: map[string]*ResourceState{ 1014 "aws_instance.foo.0": &ResourceState{ 1015 Type: "aws_instance", 1016 Primary: &InstanceState{ 1017 ID: "bar", 1018 Attributes: map[string]string{ 1019 "foo": "foo", 1020 "type": "aws_instance", 1021 }, 1022 }, 1023 }, 1024 }, 1025 }, 1026 }, 1027 } 1028 ctx := testContext2(t, &ContextOpts{ 1029 Module: m, 1030 Providers: map[string]ResourceProviderFactory{ 1031 "aws": testProviderFuncFixed(p), 1032 }, 1033 State: s, 1034 }) 1035 1036 plan, err := ctx.Plan() 1037 if err != nil { 1038 t.Fatalf("err: %s", err) 1039 } 1040 1041 actual := strings.TrimSpace(plan.String()) 1042 expected := strings.TrimSpace(testTerraformPlanCountIncreaseFromOneStr) 1043 if actual != expected { 1044 t.Fatalf("bad:\n%s", actual) 1045 } 1046 } 1047 1048 // https://github.com/PeoplePerHour/terraform/pull/11 1049 // 1050 // This tests a case where both a "resource" and "resource.0" are in 1051 // the state file, which apparently is a reasonable backwards compatibility 1052 // concern found in the above 3rd party repo. 1053 func TestContext2Plan_countIncreaseFromOneCorrupted(t *testing.T) { 1054 m := testModule(t, "plan-count-inc") 1055 p := testProvider("aws") 1056 p.DiffFn = testDiffFn 1057 s := &State{ 1058 Modules: []*ModuleState{ 1059 &ModuleState{ 1060 Path: rootModulePath, 1061 Resources: map[string]*ResourceState{ 1062 "aws_instance.foo": &ResourceState{ 1063 Type: "aws_instance", 1064 Primary: &InstanceState{ 1065 ID: "bar", 1066 Attributes: map[string]string{ 1067 "foo": "foo", 1068 "type": "aws_instance", 1069 }, 1070 }, 1071 }, 1072 "aws_instance.foo.0": &ResourceState{ 1073 Type: "aws_instance", 1074 Primary: &InstanceState{ 1075 ID: "bar", 1076 Attributes: map[string]string{ 1077 "foo": "foo", 1078 "type": "aws_instance", 1079 }, 1080 }, 1081 }, 1082 }, 1083 }, 1084 }, 1085 } 1086 ctx := testContext2(t, &ContextOpts{ 1087 Module: m, 1088 Providers: map[string]ResourceProviderFactory{ 1089 "aws": testProviderFuncFixed(p), 1090 }, 1091 State: s, 1092 }) 1093 1094 plan, err := ctx.Plan() 1095 if err != nil { 1096 t.Fatalf("err: %s", err) 1097 } 1098 1099 actual := strings.TrimSpace(plan.String()) 1100 expected := strings.TrimSpace(testTerraformPlanCountIncreaseFromOneCorruptedStr) 1101 if actual != expected { 1102 t.Fatalf("bad:\n%s", actual) 1103 } 1104 } 1105 1106 func TestContext2Plan_destroy(t *testing.T) { 1107 m := testModule(t, "plan-destroy") 1108 p := testProvider("aws") 1109 p.DiffFn = testDiffFn 1110 s := &State{ 1111 Modules: []*ModuleState{ 1112 &ModuleState{ 1113 Path: rootModulePath, 1114 Resources: map[string]*ResourceState{ 1115 "aws_instance.one": &ResourceState{ 1116 Type: "aws_instance", 1117 Primary: &InstanceState{ 1118 ID: "bar", 1119 }, 1120 }, 1121 "aws_instance.two": &ResourceState{ 1122 Type: "aws_instance", 1123 Primary: &InstanceState{ 1124 ID: "baz", 1125 }, 1126 }, 1127 }, 1128 }, 1129 }, 1130 } 1131 ctx := testContext2(t, &ContextOpts{ 1132 Module: m, 1133 Providers: map[string]ResourceProviderFactory{ 1134 "aws": testProviderFuncFixed(p), 1135 }, 1136 State: s, 1137 Destroy: true, 1138 }) 1139 1140 plan, err := ctx.Plan() 1141 if err != nil { 1142 t.Fatalf("err: %s", err) 1143 } 1144 1145 if len(plan.Diff.RootModule().Resources) != 2 { 1146 t.Fatalf("bad: %#v", plan.Diff.RootModule().Resources) 1147 } 1148 1149 actual := strings.TrimSpace(plan.String()) 1150 expected := strings.TrimSpace(testTerraformPlanDestroyStr) 1151 if actual != expected { 1152 t.Fatalf("bad:\n%s", actual) 1153 } 1154 } 1155 1156 func TestContext2Plan_moduleDestroy(t *testing.T) { 1157 m := testModule(t, "plan-module-destroy") 1158 p := testProvider("aws") 1159 p.DiffFn = testDiffFn 1160 s := &State{ 1161 Modules: []*ModuleState{ 1162 &ModuleState{ 1163 Path: rootModulePath, 1164 Resources: map[string]*ResourceState{ 1165 "aws_instance.foo": &ResourceState{ 1166 Type: "aws_instance", 1167 Primary: &InstanceState{ 1168 ID: "bar", 1169 }, 1170 }, 1171 }, 1172 }, 1173 &ModuleState{ 1174 Path: []string{"root", "child"}, 1175 Resources: map[string]*ResourceState{ 1176 "aws_instance.foo": &ResourceState{ 1177 Type: "aws_instance", 1178 Primary: &InstanceState{ 1179 ID: "bar", 1180 }, 1181 }, 1182 }, 1183 }, 1184 }, 1185 } 1186 ctx := testContext2(t, &ContextOpts{ 1187 Module: m, 1188 Providers: map[string]ResourceProviderFactory{ 1189 "aws": testProviderFuncFixed(p), 1190 }, 1191 State: s, 1192 Destroy: true, 1193 }) 1194 1195 plan, err := ctx.Plan() 1196 if err != nil { 1197 t.Fatalf("err: %s", err) 1198 } 1199 1200 actual := strings.TrimSpace(plan.String()) 1201 expected := strings.TrimSpace(testTerraformPlanModuleDestroyStr) 1202 if actual != expected { 1203 t.Fatalf("bad:\n%s", actual) 1204 } 1205 } 1206 1207 // GH-1835 1208 func TestContext2Plan_moduleDestroyCycle(t *testing.T) { 1209 m := testModule(t, "plan-module-destroy-gh-1835") 1210 p := testProvider("aws") 1211 p.DiffFn = testDiffFn 1212 s := &State{ 1213 Modules: []*ModuleState{ 1214 &ModuleState{ 1215 Path: []string{"root", "a_module"}, 1216 Resources: map[string]*ResourceState{ 1217 "aws_instance.a": &ResourceState{ 1218 Type: "aws_instance", 1219 Primary: &InstanceState{ 1220 ID: "a", 1221 }, 1222 }, 1223 }, 1224 }, 1225 &ModuleState{ 1226 Path: []string{"root", "b_module"}, 1227 Resources: map[string]*ResourceState{ 1228 "aws_instance.b": &ResourceState{ 1229 Type: "aws_instance", 1230 Primary: &InstanceState{ 1231 ID: "b", 1232 }, 1233 }, 1234 }, 1235 }, 1236 }, 1237 } 1238 ctx := testContext2(t, &ContextOpts{ 1239 Module: m, 1240 Providers: map[string]ResourceProviderFactory{ 1241 "aws": testProviderFuncFixed(p), 1242 }, 1243 State: s, 1244 Destroy: true, 1245 }) 1246 1247 plan, err := ctx.Plan() 1248 if err != nil { 1249 t.Fatalf("err: %s", err) 1250 } 1251 1252 actual := strings.TrimSpace(plan.String()) 1253 expected := strings.TrimSpace(testTerraformPlanModuleDestroyCycleStr) 1254 if actual != expected { 1255 t.Fatalf("bad:\n%s", actual) 1256 } 1257 } 1258 1259 func TestContext2Plan_moduleDestroyMultivar(t *testing.T) { 1260 m := testModule(t, "plan-module-destroy-multivar") 1261 p := testProvider("aws") 1262 p.DiffFn = testDiffFn 1263 s := &State{ 1264 Modules: []*ModuleState{ 1265 &ModuleState{ 1266 Path: rootModulePath, 1267 Resources: map[string]*ResourceState{}, 1268 }, 1269 &ModuleState{ 1270 Path: []string{"root", "child"}, 1271 Resources: map[string]*ResourceState{ 1272 "aws_instance.foo.0": &ResourceState{ 1273 Type: "aws_instance", 1274 Primary: &InstanceState{ 1275 ID: "bar0", 1276 }, 1277 }, 1278 "aws_instance.foo.1": &ResourceState{ 1279 Type: "aws_instance", 1280 Primary: &InstanceState{ 1281 ID: "bar1", 1282 }, 1283 }, 1284 }, 1285 }, 1286 }, 1287 } 1288 ctx := testContext2(t, &ContextOpts{ 1289 Module: m, 1290 Providers: map[string]ResourceProviderFactory{ 1291 "aws": testProviderFuncFixed(p), 1292 }, 1293 State: s, 1294 Destroy: true, 1295 }) 1296 1297 plan, err := ctx.Plan() 1298 if err != nil { 1299 t.Fatalf("err: %s", err) 1300 } 1301 1302 actual := strings.TrimSpace(plan.String()) 1303 expected := strings.TrimSpace(testTerraformPlanModuleDestroyMultivarStr) 1304 if actual != expected { 1305 t.Fatalf("bad:\n%s", actual) 1306 } 1307 } 1308 1309 func TestContext2Plan_pathVar(t *testing.T) { 1310 cwd, err := os.Getwd() 1311 if err != nil { 1312 t.Fatalf("err: %s", err) 1313 } 1314 1315 m := testModule(t, "plan-path-var") 1316 p := testProvider("aws") 1317 p.DiffFn = testDiffFn 1318 ctx := testContext2(t, &ContextOpts{ 1319 Module: m, 1320 Providers: map[string]ResourceProviderFactory{ 1321 "aws": testProviderFuncFixed(p), 1322 }, 1323 }) 1324 1325 plan, err := ctx.Plan() 1326 if err != nil { 1327 t.Fatalf("err: %s", err) 1328 } 1329 1330 actual := strings.TrimSpace(plan.String()) 1331 expected := strings.TrimSpace(testTerraformPlanPathVarStr) 1332 1333 // Warning: this ordering REALLY matters for this test. The 1334 // order is: cwd, module, root. 1335 expected = fmt.Sprintf( 1336 expected, 1337 cwd, 1338 m.Config().Dir, 1339 m.Config().Dir) 1340 1341 if actual != expected { 1342 t.Fatalf("bad:\n%s\n\nexpected:\n\n%s", actual, expected) 1343 } 1344 } 1345 1346 func TestContext2Plan_diffVar(t *testing.T) { 1347 m := testModule(t, "plan-diffvar") 1348 p := testProvider("aws") 1349 s := &State{ 1350 Modules: []*ModuleState{ 1351 &ModuleState{ 1352 Path: rootModulePath, 1353 Resources: map[string]*ResourceState{ 1354 "aws_instance.foo": &ResourceState{ 1355 Primary: &InstanceState{ 1356 ID: "bar", 1357 Attributes: map[string]string{ 1358 "num": "2", 1359 }, 1360 }, 1361 }, 1362 }, 1363 }, 1364 }, 1365 } 1366 ctx := testContext2(t, &ContextOpts{ 1367 Module: m, 1368 Providers: map[string]ResourceProviderFactory{ 1369 "aws": testProviderFuncFixed(p), 1370 }, 1371 State: s, 1372 }) 1373 1374 p.DiffFn = func( 1375 info *InstanceInfo, 1376 s *InstanceState, 1377 c *ResourceConfig) (*InstanceDiff, error) { 1378 if s.ID != "bar" { 1379 return testDiffFn(info, s, c) 1380 } 1381 1382 return &InstanceDiff{ 1383 Attributes: map[string]*ResourceAttrDiff{ 1384 "num": &ResourceAttrDiff{ 1385 Old: "2", 1386 New: "3", 1387 }, 1388 }, 1389 }, nil 1390 } 1391 1392 plan, err := ctx.Plan() 1393 if err != nil { 1394 t.Fatalf("err: %s", err) 1395 } 1396 1397 actual := strings.TrimSpace(plan.String()) 1398 expected := strings.TrimSpace(testTerraformPlanDiffVarStr) 1399 if actual != expected { 1400 t.Fatalf("actual:\n%s\n\nexpected:\n%s", actual, expected) 1401 } 1402 } 1403 1404 func TestContext2Plan_hook(t *testing.T) { 1405 m := testModule(t, "plan-good") 1406 h := new(MockHook) 1407 p := testProvider("aws") 1408 p.DiffFn = testDiffFn 1409 ctx := testContext2(t, &ContextOpts{ 1410 Module: m, 1411 Hooks: []Hook{h}, 1412 Providers: map[string]ResourceProviderFactory{ 1413 "aws": testProviderFuncFixed(p), 1414 }, 1415 }) 1416 1417 _, err := ctx.Plan() 1418 if err != nil { 1419 t.Fatalf("err: %s", err) 1420 } 1421 1422 if !h.PreDiffCalled { 1423 t.Fatal("should be called") 1424 } 1425 if !h.PostDiffCalled { 1426 t.Fatal("should be called") 1427 } 1428 } 1429 1430 func TestContext2Plan_orphan(t *testing.T) { 1431 m := testModule(t, "plan-orphan") 1432 p := testProvider("aws") 1433 p.DiffFn = testDiffFn 1434 s := &State{ 1435 Modules: []*ModuleState{ 1436 &ModuleState{ 1437 Path: rootModulePath, 1438 Resources: map[string]*ResourceState{ 1439 "aws_instance.baz": &ResourceState{ 1440 Type: "aws_instance", 1441 Primary: &InstanceState{ 1442 ID: "bar", 1443 }, 1444 }, 1445 }, 1446 }, 1447 }, 1448 } 1449 ctx := testContext2(t, &ContextOpts{ 1450 Module: m, 1451 Providers: map[string]ResourceProviderFactory{ 1452 "aws": testProviderFuncFixed(p), 1453 }, 1454 State: s, 1455 }) 1456 1457 plan, err := ctx.Plan() 1458 if err != nil { 1459 t.Fatalf("err: %s", err) 1460 } 1461 1462 actual := strings.TrimSpace(plan.String()) 1463 expected := strings.TrimSpace(testTerraformPlanOrphanStr) 1464 if actual != expected { 1465 t.Fatalf("bad:\n%s", actual) 1466 } 1467 } 1468 1469 func TestContext2Plan_state(t *testing.T) { 1470 m := testModule(t, "plan-good") 1471 p := testProvider("aws") 1472 p.DiffFn = testDiffFn 1473 s := &State{ 1474 Modules: []*ModuleState{ 1475 &ModuleState{ 1476 Path: rootModulePath, 1477 Resources: map[string]*ResourceState{ 1478 "aws_instance.foo": &ResourceState{ 1479 Primary: &InstanceState{ 1480 ID: "bar", 1481 }, 1482 }, 1483 }, 1484 }, 1485 }, 1486 } 1487 ctx := testContext2(t, &ContextOpts{ 1488 Module: m, 1489 Providers: map[string]ResourceProviderFactory{ 1490 "aws": testProviderFuncFixed(p), 1491 }, 1492 State: s, 1493 }) 1494 1495 plan, err := ctx.Plan() 1496 if err != nil { 1497 t.Fatalf("err: %s", err) 1498 } 1499 1500 if len(plan.Diff.RootModule().Resources) < 2 { 1501 t.Fatalf("bad: %#v", plan.Diff.RootModule().Resources) 1502 } 1503 1504 actual := strings.TrimSpace(plan.String()) 1505 expected := strings.TrimSpace(testTerraformPlanStateStr) 1506 if actual != expected { 1507 t.Fatalf("bad:\n%s\n\nexpected:\n\n%s", actual, expected) 1508 } 1509 } 1510 1511 func TestContext2Plan_taint(t *testing.T) { 1512 m := testModule(t, "plan-taint") 1513 p := testProvider("aws") 1514 p.DiffFn = testDiffFn 1515 s := &State{ 1516 Modules: []*ModuleState{ 1517 &ModuleState{ 1518 Path: rootModulePath, 1519 Resources: map[string]*ResourceState{ 1520 "aws_instance.foo": &ResourceState{ 1521 Type: "aws_instance", 1522 Primary: &InstanceState{ 1523 ID: "bar", 1524 Attributes: map[string]string{"num": "2"}, 1525 }, 1526 }, 1527 "aws_instance.bar": &ResourceState{ 1528 Type: "aws_instance", 1529 Tainted: []*InstanceState{ 1530 &InstanceState{ 1531 ID: "baz", 1532 }, 1533 }, 1534 }, 1535 }, 1536 }, 1537 }, 1538 } 1539 ctx := testContext2(t, &ContextOpts{ 1540 Module: m, 1541 Providers: map[string]ResourceProviderFactory{ 1542 "aws": testProviderFuncFixed(p), 1543 }, 1544 State: s, 1545 }) 1546 1547 plan, err := ctx.Plan() 1548 if err != nil { 1549 t.Fatalf("err: %s", err) 1550 } 1551 1552 actual := strings.TrimSpace(plan.String()) 1553 expected := strings.TrimSpace(testTerraformPlanTaintStr) 1554 if actual != expected { 1555 t.Fatalf("bad:\n%s", actual) 1556 } 1557 } 1558 1559 func TestContext2Plan_multiple_taint(t *testing.T) { 1560 m := testModule(t, "plan-taint") 1561 p := testProvider("aws") 1562 p.DiffFn = testDiffFn 1563 s := &State{ 1564 Modules: []*ModuleState{ 1565 &ModuleState{ 1566 Path: rootModulePath, 1567 Resources: map[string]*ResourceState{ 1568 "aws_instance.foo": &ResourceState{ 1569 Type: "aws_instance", 1570 Primary: &InstanceState{ 1571 ID: "bar", 1572 Attributes: map[string]string{"num": "2"}, 1573 }, 1574 }, 1575 "aws_instance.bar": &ResourceState{ 1576 Type: "aws_instance", 1577 Tainted: []*InstanceState{ 1578 &InstanceState{ 1579 ID: "baz", 1580 }, 1581 &InstanceState{ 1582 ID: "zip", 1583 }, 1584 }, 1585 }, 1586 }, 1587 }, 1588 }, 1589 } 1590 ctx := testContext2(t, &ContextOpts{ 1591 Module: m, 1592 Providers: map[string]ResourceProviderFactory{ 1593 "aws": testProviderFuncFixed(p), 1594 }, 1595 State: s, 1596 }) 1597 1598 plan, err := ctx.Plan() 1599 if err != nil { 1600 t.Fatalf("err: %s", err) 1601 } 1602 1603 actual := strings.TrimSpace(plan.String()) 1604 expected := strings.TrimSpace(testTerraformPlanMultipleTaintStr) 1605 if actual != expected { 1606 t.Fatalf("bad:\n%s", actual) 1607 } 1608 } 1609 1610 func TestContext2Plan_targeted(t *testing.T) { 1611 m := testModule(t, "plan-targeted") 1612 p := testProvider("aws") 1613 p.DiffFn = testDiffFn 1614 ctx := testContext2(t, &ContextOpts{ 1615 Module: m, 1616 Providers: map[string]ResourceProviderFactory{ 1617 "aws": testProviderFuncFixed(p), 1618 }, 1619 Targets: []string{"aws_instance.foo"}, 1620 }) 1621 1622 plan, err := ctx.Plan() 1623 if err != nil { 1624 t.Fatalf("err: %s", err) 1625 } 1626 1627 actual := strings.TrimSpace(plan.String()) 1628 expected := strings.TrimSpace(` 1629 DIFF: 1630 1631 CREATE: aws_instance.foo 1632 num: "" => "2" 1633 type: "" => "aws_instance" 1634 1635 STATE: 1636 1637 <no state> 1638 `) 1639 if actual != expected { 1640 t.Fatalf("expected:\n%s\n\ngot:\n%s", expected, actual) 1641 } 1642 } 1643 1644 func TestContext2Plan_provider(t *testing.T) { 1645 m := testModule(t, "plan-provider") 1646 p := testProvider("aws") 1647 p.DiffFn = testDiffFn 1648 1649 var value interface{} 1650 p.ConfigureFn = func(c *ResourceConfig) error { 1651 value, _ = c.Get("foo") 1652 return nil 1653 } 1654 1655 ctx := testContext2(t, &ContextOpts{ 1656 Module: m, 1657 Providers: map[string]ResourceProviderFactory{ 1658 "aws": testProviderFuncFixed(p), 1659 }, 1660 Variables: map[string]string{ 1661 "foo": "bar", 1662 }, 1663 }) 1664 1665 if _, err := ctx.Plan(); err != nil { 1666 t.Fatalf("err: %s", err) 1667 } 1668 1669 if value != "bar" { 1670 t.Fatalf("bad: %#v", value) 1671 } 1672 } 1673 1674 func TestContext2Plan_varListErr(t *testing.T) { 1675 m := testModule(t, "plan-var-list-err") 1676 p := testProvider("aws") 1677 ctx := testContext2(t, &ContextOpts{ 1678 Module: m, 1679 Providers: map[string]ResourceProviderFactory{ 1680 "aws": testProviderFuncFixed(p), 1681 }, 1682 }) 1683 1684 _, err := ctx.Plan() 1685 if err == nil { 1686 t.Fatal("should error") 1687 } 1688 }