github.com/scottwinkler/terraform@v0.11.6-0.20180329211809-05143987aea8/helper/resource/testing_test.go (about) 1 package resource 2 3 import ( 4 "errors" 5 "flag" 6 "fmt" 7 "os" 8 "reflect" 9 "regexp" 10 "sort" 11 "strings" 12 "sync" 13 "sync/atomic" 14 "testing" 15 16 "github.com/hashicorp/go-multierror" 17 "github.com/hashicorp/terraform/terraform" 18 ) 19 20 func init() { 21 testTesting = true 22 23 // TODO: Remove when we remove the guard on id checks 24 if err := os.Setenv("TF_ACC_IDONLY", "1"); err != nil { 25 panic(err) 26 } 27 28 if err := os.Setenv(TestEnvVar, "1"); err != nil { 29 panic(err) 30 } 31 } 32 33 // wrap the mock provider to implement TestProvider 34 type resetProvider struct { 35 *terraform.MockResourceProvider 36 mu sync.Mutex 37 TestResetCalled bool 38 TestResetError error 39 } 40 41 func (p *resetProvider) TestReset() error { 42 p.mu.Lock() 43 defer p.mu.Unlock() 44 p.TestResetCalled = true 45 return p.TestResetError 46 } 47 48 func TestTest(t *testing.T) { 49 mp := &resetProvider{ 50 MockResourceProvider: testProvider(), 51 } 52 53 mp.DiffReturn = nil 54 55 mp.ApplyFn = func( 56 info *terraform.InstanceInfo, 57 state *terraform.InstanceState, 58 diff *terraform.InstanceDiff) (*terraform.InstanceState, error) { 59 if !diff.Destroy { 60 return &terraform.InstanceState{ 61 ID: "foo", 62 }, nil 63 } 64 65 return nil, nil 66 } 67 68 var refreshCount int32 69 mp.RefreshFn = func(*terraform.InstanceInfo, *terraform.InstanceState) (*terraform.InstanceState, error) { 70 atomic.AddInt32(&refreshCount, 1) 71 return &terraform.InstanceState{ID: "foo"}, nil 72 } 73 74 checkDestroy := false 75 checkStep := false 76 77 checkDestroyFn := func(*terraform.State) error { 78 checkDestroy = true 79 return nil 80 } 81 82 checkStepFn := func(s *terraform.State) error { 83 checkStep = true 84 85 rs, ok := s.RootModule().Resources["test_instance.foo"] 86 if !ok { 87 t.Error("test_instance.foo is not present") 88 return nil 89 } 90 is := rs.Primary 91 if is.ID != "foo" { 92 t.Errorf("bad check ID: %s", is.ID) 93 } 94 95 return nil 96 } 97 98 mt := new(mockT) 99 Test(mt, TestCase{ 100 Providers: map[string]terraform.ResourceProvider{ 101 "test": mp, 102 }, 103 CheckDestroy: checkDestroyFn, 104 Steps: []TestStep{ 105 TestStep{ 106 Config: testConfigStr, 107 Check: checkStepFn, 108 }, 109 }, 110 }) 111 112 if mt.failed() { 113 t.Fatalf("test failed: %s", mt.failMessage()) 114 } 115 if !checkStep { 116 t.Fatal("didn't call check for step") 117 } 118 if !checkDestroy { 119 t.Fatal("didn't call check for destroy") 120 } 121 if !mp.TestResetCalled { 122 t.Fatal("didn't call TestReset") 123 } 124 } 125 126 func TestTest_plan_only(t *testing.T) { 127 mp := testProvider() 128 mp.ApplyReturn = &terraform.InstanceState{ 129 ID: "foo", 130 } 131 132 checkDestroy := false 133 134 checkDestroyFn := func(*terraform.State) error { 135 checkDestroy = true 136 return nil 137 } 138 139 mt := new(mockT) 140 Test(mt, TestCase{ 141 Providers: map[string]terraform.ResourceProvider{ 142 "test": mp, 143 }, 144 CheckDestroy: checkDestroyFn, 145 Steps: []TestStep{ 146 TestStep{ 147 Config: testConfigStr, 148 PlanOnly: true, 149 ExpectNonEmptyPlan: false, 150 }, 151 }, 152 }) 153 154 if !mt.failed() { 155 t.Fatal("test should've failed") 156 } 157 158 expected := `Step 0 error: After applying this step, the plan was not empty: 159 160 DIFF: 161 162 CREATE: test_instance.foo 163 foo: "" => "bar" 164 165 STATE: 166 167 <no state>` 168 169 if mt.failMessage() != expected { 170 t.Fatalf("Expected message: %s\n\ngot:\n\n%s", expected, mt.failMessage()) 171 } 172 173 if !checkDestroy { 174 t.Fatal("didn't call check for destroy") 175 } 176 } 177 178 func TestTest_idRefresh(t *testing.T) { 179 // Refresh count should be 3: 180 // 1.) initial Ref/Plan/Apply 181 // 2.) post Ref/Plan/Apply for plan-check 182 // 3.) id refresh check 183 var expectedRefresh int32 = 3 184 185 mp := testProvider() 186 mp.DiffReturn = nil 187 188 mp.ApplyFn = func( 189 info *terraform.InstanceInfo, 190 state *terraform.InstanceState, 191 diff *terraform.InstanceDiff) (*terraform.InstanceState, error) { 192 if !diff.Destroy { 193 return &terraform.InstanceState{ 194 ID: "foo", 195 }, nil 196 } 197 198 return nil, nil 199 } 200 201 var refreshCount int32 202 mp.RefreshFn = func(*terraform.InstanceInfo, *terraform.InstanceState) (*terraform.InstanceState, error) { 203 atomic.AddInt32(&refreshCount, 1) 204 return &terraform.InstanceState{ID: "foo"}, nil 205 } 206 207 mt := new(mockT) 208 Test(mt, TestCase{ 209 IDRefreshName: "test_instance.foo", 210 Providers: map[string]terraform.ResourceProvider{ 211 "test": mp, 212 }, 213 Steps: []TestStep{ 214 TestStep{ 215 Config: testConfigStr, 216 }, 217 }, 218 }) 219 220 if mt.failed() { 221 t.Fatalf("test failed: %s", mt.failMessage()) 222 } 223 224 // See declaration of expectedRefresh for why that number 225 if refreshCount != expectedRefresh { 226 t.Fatalf("bad refresh count: %d", refreshCount) 227 } 228 } 229 230 func TestTest_idRefreshCustomName(t *testing.T) { 231 // Refresh count should be 3: 232 // 1.) initial Ref/Plan/Apply 233 // 2.) post Ref/Plan/Apply for plan-check 234 // 3.) id refresh check 235 var expectedRefresh int32 = 3 236 237 mp := testProvider() 238 mp.DiffReturn = nil 239 240 mp.ApplyFn = func( 241 info *terraform.InstanceInfo, 242 state *terraform.InstanceState, 243 diff *terraform.InstanceDiff) (*terraform.InstanceState, error) { 244 if !diff.Destroy { 245 return &terraform.InstanceState{ 246 ID: "foo", 247 }, nil 248 } 249 250 return nil, nil 251 } 252 253 var refreshCount int32 254 mp.RefreshFn = func(*terraform.InstanceInfo, *terraform.InstanceState) (*terraform.InstanceState, error) { 255 atomic.AddInt32(&refreshCount, 1) 256 return &terraform.InstanceState{ID: "foo"}, nil 257 } 258 259 mt := new(mockT) 260 Test(mt, TestCase{ 261 IDRefreshName: "test_instance.foo", 262 Providers: map[string]terraform.ResourceProvider{ 263 "test": mp, 264 }, 265 Steps: []TestStep{ 266 TestStep{ 267 Config: testConfigStr, 268 }, 269 }, 270 }) 271 272 if mt.failed() { 273 t.Fatalf("test failed: %s", mt.failMessage()) 274 } 275 276 // See declaration of expectedRefresh for why that number 277 if refreshCount != expectedRefresh { 278 t.Fatalf("bad refresh count: %d", refreshCount) 279 } 280 } 281 282 func TestTest_idRefreshFail(t *testing.T) { 283 // Refresh count should be 3: 284 // 1.) initial Ref/Plan/Apply 285 // 2.) post Ref/Plan/Apply for plan-check 286 // 3.) id refresh check 287 var expectedRefresh int32 = 3 288 289 mp := testProvider() 290 mp.DiffReturn = nil 291 292 mp.ApplyFn = func( 293 info *terraform.InstanceInfo, 294 state *terraform.InstanceState, 295 diff *terraform.InstanceDiff) (*terraform.InstanceState, error) { 296 if !diff.Destroy { 297 return &terraform.InstanceState{ 298 ID: "foo", 299 }, nil 300 } 301 302 return nil, nil 303 } 304 305 var refreshCount int32 306 mp.RefreshFn = func(*terraform.InstanceInfo, *terraform.InstanceState) (*terraform.InstanceState, error) { 307 atomic.AddInt32(&refreshCount, 1) 308 if atomic.LoadInt32(&refreshCount) == expectedRefresh-1 { 309 return &terraform.InstanceState{ 310 ID: "foo", 311 Attributes: map[string]string{"foo": "bar"}, 312 }, nil 313 } else if atomic.LoadInt32(&refreshCount) < expectedRefresh { 314 return &terraform.InstanceState{ID: "foo"}, nil 315 } else { 316 return nil, nil 317 } 318 } 319 320 mt := new(mockT) 321 Test(mt, TestCase{ 322 IDRefreshName: "test_instance.foo", 323 Providers: map[string]terraform.ResourceProvider{ 324 "test": mp, 325 }, 326 Steps: []TestStep{ 327 TestStep{ 328 Config: testConfigStr, 329 }, 330 }, 331 }) 332 333 if !mt.failed() { 334 t.Fatal("test didn't fail") 335 } 336 t.Logf("failure reason: %s", mt.failMessage()) 337 338 // See declaration of expectedRefresh for why that number 339 if refreshCount != expectedRefresh { 340 t.Fatalf("bad refresh count: %d", refreshCount) 341 } 342 } 343 344 func TestTest_empty(t *testing.T) { 345 destroyCalled := false 346 checkDestroyFn := func(*terraform.State) error { 347 destroyCalled = true 348 return nil 349 } 350 351 mt := new(mockT) 352 Test(mt, TestCase{ 353 CheckDestroy: checkDestroyFn, 354 }) 355 356 if mt.failed() { 357 t.Fatal("test failed") 358 } 359 if destroyCalled { 360 t.Fatal("should not call check destroy if there is no steps") 361 } 362 } 363 364 func TestTest_noEnv(t *testing.T) { 365 // Unset the variable 366 if err := os.Setenv(TestEnvVar, ""); err != nil { 367 t.Fatalf("err: %s", err) 368 } 369 defer os.Setenv(TestEnvVar, "1") 370 371 mt := new(mockT) 372 Test(mt, TestCase{}) 373 374 if !mt.SkipCalled { 375 t.Fatal("skip not called") 376 } 377 } 378 379 func TestTest_preCheck(t *testing.T) { 380 called := false 381 382 mt := new(mockT) 383 Test(mt, TestCase{ 384 PreCheck: func() { called = true }, 385 }) 386 387 if !called { 388 t.Fatal("precheck should be called") 389 } 390 } 391 392 func TestTest_skipFunc(t *testing.T) { 393 preCheckCalled := false 394 skipped := false 395 396 mp := testProvider() 397 mp.ApplyReturn = &terraform.InstanceState{ 398 ID: "foo", 399 } 400 401 checkStepFn := func(*terraform.State) error { 402 return fmt.Errorf("error") 403 } 404 405 mt := new(mockT) 406 Test(mt, TestCase{ 407 Providers: map[string]terraform.ResourceProvider{ 408 "test": mp, 409 }, 410 PreCheck: func() { preCheckCalled = true }, 411 Steps: []TestStep{ 412 { 413 Config: testConfigStr, 414 Check: checkStepFn, 415 SkipFunc: func() (bool, error) { skipped = true; return true, nil }, 416 }, 417 }, 418 }) 419 420 if mt.failed() { 421 t.Fatal("Expected check to be skipped") 422 } 423 424 if !preCheckCalled { 425 t.Fatal("precheck should be called") 426 } 427 if !skipped { 428 t.Fatal("SkipFunc should be called") 429 } 430 } 431 432 func TestTest_stepError(t *testing.T) { 433 mp := testProvider() 434 mp.ApplyReturn = &terraform.InstanceState{ 435 ID: "foo", 436 } 437 438 checkDestroy := false 439 440 checkDestroyFn := func(*terraform.State) error { 441 checkDestroy = true 442 return nil 443 } 444 445 checkStepFn := func(*terraform.State) error { 446 return fmt.Errorf("error") 447 } 448 449 mt := new(mockT) 450 Test(mt, TestCase{ 451 Providers: map[string]terraform.ResourceProvider{ 452 "test": mp, 453 }, 454 CheckDestroy: checkDestroyFn, 455 Steps: []TestStep{ 456 TestStep{ 457 Config: testConfigStr, 458 Check: checkStepFn, 459 }, 460 }, 461 }) 462 463 if !mt.failed() { 464 t.Fatal("test should've failed") 465 } 466 expected := "Step 0 error: Check failed: error" 467 if mt.failMessage() != expected { 468 t.Fatalf("Expected message: %s\n\ngot:\n\n%s", expected, mt.failMessage()) 469 } 470 471 if !checkDestroy { 472 t.Fatal("didn't call check for destroy") 473 } 474 } 475 476 func TestTest_factoryError(t *testing.T) { 477 resourceFactoryError := fmt.Errorf("resource factory error") 478 479 factory := func() (terraform.ResourceProvider, error) { 480 return nil, resourceFactoryError 481 } 482 483 mt := new(mockT) 484 Test(mt, TestCase{ 485 ProviderFactories: map[string]terraform.ResourceProviderFactory{ 486 "test": factory, 487 }, 488 Steps: []TestStep{ 489 TestStep{ 490 ExpectError: regexp.MustCompile("resource factory error"), 491 }, 492 }, 493 }) 494 495 if !mt.failed() { 496 t.Fatal("test should've failed") 497 } 498 } 499 500 func TestTest_resetError(t *testing.T) { 501 mp := &resetProvider{ 502 MockResourceProvider: testProvider(), 503 TestResetError: fmt.Errorf("provider reset error"), 504 } 505 506 mt := new(mockT) 507 Test(mt, TestCase{ 508 Providers: map[string]terraform.ResourceProvider{ 509 "test": mp, 510 }, 511 Steps: []TestStep{ 512 TestStep{ 513 ExpectError: regexp.MustCompile("provider reset error"), 514 }, 515 }, 516 }) 517 518 if !mt.failed() { 519 t.Fatal("test should've failed") 520 } 521 } 522 523 func TestTest_expectError(t *testing.T) { 524 cases := []struct { 525 name string 526 planErr bool 527 applyErr bool 528 badErr bool 529 }{ 530 { 531 name: "successful apply", 532 planErr: false, 533 applyErr: false, 534 }, 535 { 536 name: "bad plan", 537 planErr: true, 538 applyErr: false, 539 }, 540 { 541 name: "bad apply", 542 planErr: false, 543 applyErr: true, 544 }, 545 { 546 name: "bad plan, bad err", 547 planErr: true, 548 applyErr: false, 549 badErr: true, 550 }, 551 { 552 name: "bad apply, bad err", 553 planErr: false, 554 applyErr: true, 555 badErr: true, 556 }, 557 } 558 559 for _, tc := range cases { 560 t.Run(tc.name, func(t *testing.T) { 561 mp := testProvider() 562 expectedText := "test provider error" 563 var errText string 564 if tc.badErr { 565 errText = "wrong provider error" 566 } else { 567 errText = expectedText 568 } 569 noErrText := "no error received, but expected a match to" 570 if tc.planErr { 571 mp.DiffReturnError = errors.New(errText) 572 } 573 if tc.applyErr { 574 mp.ApplyReturnError = errors.New(errText) 575 } 576 mt := new(mockT) 577 Test(mt, TestCase{ 578 Providers: map[string]terraform.ResourceProvider{ 579 "test": mp, 580 }, 581 Steps: []TestStep{ 582 TestStep{ 583 Config: testConfigStr, 584 ExpectError: regexp.MustCompile(expectedText), 585 Check: func(*terraform.State) error { return nil }, 586 ExpectNonEmptyPlan: true, 587 }, 588 }, 589 }, 590 ) 591 if mt.FatalCalled { 592 t.Fatalf("fatal: %+v", mt.FatalArgs) 593 } 594 switch { 595 case len(mt.ErrorArgs) < 1 && !tc.planErr && !tc.applyErr: 596 t.Fatalf("expected error, got none") 597 case !tc.planErr && !tc.applyErr: 598 for _, e := range mt.ErrorArgs { 599 if regexp.MustCompile(noErrText).MatchString(fmt.Sprintf("%v", e)) { 600 return 601 } 602 } 603 t.Fatalf("expected error to match %s, got %+v", noErrText, mt.ErrorArgs) 604 case tc.badErr: 605 for _, e := range mt.ErrorArgs { 606 if regexp.MustCompile(expectedText).MatchString(fmt.Sprintf("%v", e)) { 607 return 608 } 609 } 610 t.Fatalf("expected error to match %s, got %+v", expectedText, mt.ErrorArgs) 611 } 612 }) 613 } 614 } 615 616 func TestComposeAggregateTestCheckFunc(t *testing.T) { 617 check1 := func(s *terraform.State) error { 618 return errors.New("Error 1") 619 } 620 621 check2 := func(s *terraform.State) error { 622 return errors.New("Error 2") 623 } 624 625 f := ComposeAggregateTestCheckFunc(check1, check2) 626 err := f(nil) 627 if err == nil { 628 t.Fatalf("Expected errors") 629 } 630 631 multi := err.(*multierror.Error) 632 if !strings.Contains(multi.Errors[0].Error(), "Error 1") { 633 t.Fatalf("Expected Error 1, Got %s", multi.Errors[0]) 634 } 635 if !strings.Contains(multi.Errors[1].Error(), "Error 2") { 636 t.Fatalf("Expected Error 2, Got %s", multi.Errors[1]) 637 } 638 } 639 640 func TestComposeTestCheckFunc(t *testing.T) { 641 cases := []struct { 642 F []TestCheckFunc 643 Result string 644 }{ 645 { 646 F: []TestCheckFunc{ 647 func(*terraform.State) error { return nil }, 648 }, 649 Result: "", 650 }, 651 652 { 653 F: []TestCheckFunc{ 654 func(*terraform.State) error { 655 return fmt.Errorf("error") 656 }, 657 func(*terraform.State) error { return nil }, 658 }, 659 Result: "Check 1/2 error: error", 660 }, 661 662 { 663 F: []TestCheckFunc{ 664 func(*terraform.State) error { return nil }, 665 func(*terraform.State) error { 666 return fmt.Errorf("error") 667 }, 668 }, 669 Result: "Check 2/2 error: error", 670 }, 671 672 { 673 F: []TestCheckFunc{ 674 func(*terraform.State) error { return nil }, 675 func(*terraform.State) error { return nil }, 676 }, 677 Result: "", 678 }, 679 } 680 681 for i, tc := range cases { 682 f := ComposeTestCheckFunc(tc.F...) 683 err := f(nil) 684 if err == nil { 685 err = fmt.Errorf("") 686 } 687 if tc.Result != err.Error() { 688 t.Fatalf("Case %d bad: %s", i, err) 689 } 690 } 691 } 692 693 // mockT implements TestT for testing 694 type mockT struct { 695 ErrorCalled bool 696 ErrorArgs []interface{} 697 FatalCalled bool 698 FatalArgs []interface{} 699 SkipCalled bool 700 SkipArgs []interface{} 701 702 f bool 703 } 704 705 func (t *mockT) Error(args ...interface{}) { 706 t.ErrorCalled = true 707 t.ErrorArgs = args 708 t.f = true 709 } 710 711 func (t *mockT) Fatal(args ...interface{}) { 712 t.FatalCalled = true 713 t.FatalArgs = args 714 t.f = true 715 } 716 717 func (t *mockT) Skip(args ...interface{}) { 718 t.SkipCalled = true 719 t.SkipArgs = args 720 t.f = true 721 } 722 723 func (t *mockT) Name() string { 724 return "MockedName" 725 } 726 727 func (t *mockT) failed() bool { 728 return t.f 729 } 730 731 func (t *mockT) failMessage() string { 732 if t.FatalCalled { 733 return t.FatalArgs[0].(string) 734 } else if t.ErrorCalled { 735 return t.ErrorArgs[0].(string) 736 } else if t.SkipCalled { 737 return t.SkipArgs[0].(string) 738 } 739 740 return "unknown" 741 } 742 743 func testProvider() *terraform.MockResourceProvider { 744 mp := new(terraform.MockResourceProvider) 745 mp.DiffReturn = &terraform.InstanceDiff{ 746 Attributes: map[string]*terraform.ResourceAttrDiff{ 747 "foo": &terraform.ResourceAttrDiff{ 748 New: "bar", 749 }, 750 }, 751 } 752 mp.ResourcesReturn = []terraform.ResourceType{ 753 terraform.ResourceType{Name: "test_instance"}, 754 } 755 756 return mp 757 } 758 759 func TestTest_Main(t *testing.T) { 760 flag.Parse() 761 if *flagSweep == "" { 762 // Tests for the TestMain method used for Sweepers will panic without the -sweep 763 // flag specified. Mock the value for now 764 *flagSweep = "us-east-1" 765 } 766 767 cases := []struct { 768 Name string 769 Sweepers map[string]*Sweeper 770 ExpectedRunList []string 771 SweepRun string 772 }{ 773 { 774 Name: "normal", 775 Sweepers: map[string]*Sweeper{ 776 "aws_dummy": &Sweeper{ 777 Name: "aws_dummy", 778 F: mockSweeperFunc, 779 }, 780 }, 781 ExpectedRunList: []string{"aws_dummy"}, 782 }, 783 { 784 Name: "with dep", 785 Sweepers: map[string]*Sweeper{ 786 "aws_dummy": &Sweeper{ 787 Name: "aws_dummy", 788 F: mockSweeperFunc, 789 }, 790 "aws_top": &Sweeper{ 791 Name: "aws_top", 792 Dependencies: []string{"aws_sub"}, 793 F: mockSweeperFunc, 794 }, 795 "aws_sub": &Sweeper{ 796 Name: "aws_sub", 797 F: mockSweeperFunc, 798 }, 799 }, 800 ExpectedRunList: []string{"aws_dummy", "aws_sub", "aws_top"}, 801 }, 802 { 803 Name: "with filter", 804 Sweepers: map[string]*Sweeper{ 805 "aws_dummy": &Sweeper{ 806 Name: "aws_dummy", 807 F: mockSweeperFunc, 808 }, 809 "aws_top": &Sweeper{ 810 Name: "aws_top", 811 Dependencies: []string{"aws_sub"}, 812 F: mockSweeperFunc, 813 }, 814 "aws_sub": &Sweeper{ 815 Name: "aws_sub", 816 F: mockSweeperFunc, 817 }, 818 }, 819 ExpectedRunList: []string{"aws_dummy"}, 820 SweepRun: "aws_dummy", 821 }, 822 { 823 Name: "with two filters", 824 Sweepers: map[string]*Sweeper{ 825 "aws_dummy": &Sweeper{ 826 Name: "aws_dummy", 827 F: mockSweeperFunc, 828 }, 829 "aws_top": &Sweeper{ 830 Name: "aws_top", 831 Dependencies: []string{"aws_sub"}, 832 F: mockSweeperFunc, 833 }, 834 "aws_sub": &Sweeper{ 835 Name: "aws_sub", 836 F: mockSweeperFunc, 837 }, 838 }, 839 ExpectedRunList: []string{"aws_dummy", "aws_sub"}, 840 SweepRun: "aws_dummy,aws_sub", 841 }, 842 { 843 Name: "with dep and filter", 844 Sweepers: map[string]*Sweeper{ 845 "aws_dummy": &Sweeper{ 846 Name: "aws_dummy", 847 F: mockSweeperFunc, 848 }, 849 "aws_top": &Sweeper{ 850 Name: "aws_top", 851 Dependencies: []string{"aws_sub"}, 852 F: mockSweeperFunc, 853 }, 854 "aws_sub": &Sweeper{ 855 Name: "aws_sub", 856 F: mockSweeperFunc, 857 }, 858 }, 859 ExpectedRunList: []string{"aws_top", "aws_sub"}, 860 SweepRun: "aws_top", 861 }, 862 { 863 Name: "filter and none", 864 Sweepers: map[string]*Sweeper{ 865 "aws_dummy": &Sweeper{ 866 Name: "aws_dummy", 867 F: mockSweeperFunc, 868 }, 869 "aws_top": &Sweeper{ 870 Name: "aws_top", 871 Dependencies: []string{"aws_sub"}, 872 F: mockSweeperFunc, 873 }, 874 "aws_sub": &Sweeper{ 875 Name: "aws_sub", 876 F: mockSweeperFunc, 877 }, 878 }, 879 SweepRun: "none", 880 }, 881 } 882 883 for _, tc := range cases { 884 // reset sweepers 885 sweeperFuncs = map[string]*Sweeper{} 886 887 t.Run(tc.Name, func(t *testing.T) { 888 for n, s := range tc.Sweepers { 889 AddTestSweepers(n, s) 890 } 891 *flagSweepRun = tc.SweepRun 892 893 TestMain(&testing.M{}) 894 895 // get list of tests ran from sweeperRunList keys 896 var keys []string 897 for k, _ := range sweeperRunList { 898 keys = append(keys, k) 899 } 900 901 sort.Strings(keys) 902 sort.Strings(tc.ExpectedRunList) 903 if !reflect.DeepEqual(keys, tc.ExpectedRunList) { 904 t.Fatalf("Expected keys mismatch, expected:\n%#v\ngot:\n%#v\n", tc.ExpectedRunList, keys) 905 } 906 }) 907 } 908 } 909 910 func mockSweeperFunc(s string) error { 911 return nil 912 } 913 914 const testConfigStr = ` 915 resource "test_instance" "foo" {} 916 ` 917 918 const testConfigStrProvider = ` 919 provider "test" {} 920 `