github.com/hooklift/terraform@v0.11.0-beta1.0.20171117000744-6786c1361ffe/helper/schema/resource_diff_test.go (about) 1 package schema 2 3 import ( 4 "reflect" 5 "testing" 6 7 "github.com/davecgh/go-spew/spew" 8 "github.com/hashicorp/terraform/terraform" 9 ) 10 11 // testSetFunc is a very simple function we use to test a foo/bar complex set. 12 // Both "foo" and "bar" are int values. 13 // 14 // This is not foolproof as since it performs sums, you can run into 15 // collisions. Spec tests accordingly. :P 16 func testSetFunc(v interface{}) int { 17 m := v.(map[string]interface{}) 18 return m["foo"].(int) + m["bar"].(int) 19 } 20 21 // resourceDiffTestCase provides a test case struct for SetNew and SetDiff. 22 type resourceDiffTestCase struct { 23 Name string 24 Schema map[string]*Schema 25 State *terraform.InstanceState 26 Config *terraform.ResourceConfig 27 Diff *terraform.InstanceDiff 28 Key string 29 OldValue interface{} 30 NewValue interface{} 31 Expected *terraform.InstanceDiff 32 ExpectedError bool 33 } 34 35 // testDiffCases produces a list of test cases for use with SetNew and SetDiff. 36 func testDiffCases(t *testing.T, oldPrefix string, oldOffset int, computed bool) []resourceDiffTestCase { 37 return []resourceDiffTestCase{ 38 resourceDiffTestCase{ 39 Name: "basic primitive diff", 40 Schema: map[string]*Schema{ 41 "foo": &Schema{ 42 Type: TypeString, 43 Optional: true, 44 Computed: true, 45 }, 46 }, 47 State: &terraform.InstanceState{ 48 Attributes: map[string]string{ 49 "foo": "bar", 50 }, 51 }, 52 Config: testConfig(t, map[string]interface{}{ 53 "foo": "baz", 54 }), 55 Diff: &terraform.InstanceDiff{ 56 Attributes: map[string]*terraform.ResourceAttrDiff{ 57 "foo": &terraform.ResourceAttrDiff{ 58 Old: "bar", 59 New: "baz", 60 }, 61 }, 62 }, 63 Key: "foo", 64 NewValue: "qux", 65 Expected: &terraform.InstanceDiff{ 66 Attributes: map[string]*terraform.ResourceAttrDiff{ 67 "foo": &terraform.ResourceAttrDiff{ 68 Old: "bar", 69 New: func() string { 70 if computed { 71 return "" 72 } 73 return "qux" 74 }(), 75 NewComputed: computed, 76 }, 77 }, 78 }, 79 }, 80 resourceDiffTestCase{ 81 Name: "basic set diff", 82 Schema: map[string]*Schema{ 83 "foo": &Schema{ 84 Type: TypeSet, 85 Optional: true, 86 Computed: true, 87 Elem: &Schema{Type: TypeString}, 88 Set: HashString, 89 }, 90 }, 91 State: &terraform.InstanceState{ 92 Attributes: map[string]string{ 93 "foo.#": "1", 94 "foo.1996459178": "bar", 95 }, 96 }, 97 Config: testConfig(t, map[string]interface{}{ 98 "foo": []interface{}{"baz"}, 99 }), 100 Diff: &terraform.InstanceDiff{ 101 Attributes: map[string]*terraform.ResourceAttrDiff{ 102 "foo.1996459178": &terraform.ResourceAttrDiff{ 103 Old: "bar", 104 New: "", 105 NewRemoved: true, 106 }, 107 "foo.2015626392": &terraform.ResourceAttrDiff{ 108 Old: "", 109 New: "baz", 110 }, 111 }, 112 }, 113 Key: "foo", 114 NewValue: []interface{}{"qux"}, 115 Expected: &terraform.InstanceDiff{ 116 Attributes: func() map[string]*terraform.ResourceAttrDiff { 117 result := map[string]*terraform.ResourceAttrDiff{} 118 if computed { 119 result["foo.#"] = &terraform.ResourceAttrDiff{ 120 Old: "1", 121 New: "", 122 NewComputed: true, 123 } 124 } else { 125 result["foo.2800005064"] = &terraform.ResourceAttrDiff{ 126 Old: "", 127 New: "qux", 128 } 129 result["foo.1996459178"] = &terraform.ResourceAttrDiff{ 130 Old: "bar", 131 New: "", 132 NewRemoved: true, 133 } 134 } 135 return result 136 }(), 137 }, 138 }, 139 resourceDiffTestCase{ 140 Name: "basic list diff", 141 Schema: map[string]*Schema{ 142 "foo": &Schema{ 143 Type: TypeList, 144 Optional: true, 145 Computed: true, 146 Elem: &Schema{Type: TypeString}, 147 }, 148 }, 149 State: &terraform.InstanceState{ 150 Attributes: map[string]string{ 151 "foo.#": "1", 152 "foo.0": "bar", 153 }, 154 }, 155 Config: testConfig(t, map[string]interface{}{ 156 "foo": []interface{}{"baz"}, 157 }), 158 Diff: &terraform.InstanceDiff{ 159 Attributes: map[string]*terraform.ResourceAttrDiff{ 160 "foo.0": &terraform.ResourceAttrDiff{ 161 Old: "bar", 162 New: "baz", 163 }, 164 }, 165 }, 166 Key: "foo", 167 NewValue: []interface{}{"qux"}, 168 Expected: &terraform.InstanceDiff{ 169 Attributes: func() map[string]*terraform.ResourceAttrDiff { 170 result := make(map[string]*terraform.ResourceAttrDiff) 171 if computed { 172 result["foo.#"] = &terraform.ResourceAttrDiff{ 173 Old: "1", 174 New: "", 175 NewComputed: true, 176 } 177 } else { 178 result["foo.0"] = &terraform.ResourceAttrDiff{ 179 Old: "bar", 180 New: "qux", 181 } 182 } 183 return result 184 }(), 185 }, 186 }, 187 resourceDiffTestCase{ 188 Name: "basic map diff", 189 Schema: map[string]*Schema{ 190 "foo": &Schema{ 191 Type: TypeMap, 192 Optional: true, 193 Computed: true, 194 }, 195 }, 196 State: &terraform.InstanceState{ 197 Attributes: map[string]string{ 198 "foo.%": "1", 199 "foo.bar": "baz", 200 }, 201 }, 202 Config: testConfig(t, map[string]interface{}{ 203 "foo": map[string]interface{}{"bar": "qux"}, 204 }), 205 Diff: &terraform.InstanceDiff{ 206 Attributes: map[string]*terraform.ResourceAttrDiff{ 207 "foo.bar": &terraform.ResourceAttrDiff{ 208 Old: "baz", 209 New: "qux", 210 }, 211 }, 212 }, 213 Key: "foo", 214 NewValue: map[string]interface{}{"bar": "quux"}, 215 Expected: &terraform.InstanceDiff{ 216 Attributes: func() map[string]*terraform.ResourceAttrDiff { 217 result := make(map[string]*terraform.ResourceAttrDiff) 218 if computed { 219 result["foo.%"] = &terraform.ResourceAttrDiff{ 220 Old: "", 221 New: "", 222 NewComputed: true, 223 } 224 result["foo.bar"] = &terraform.ResourceAttrDiff{ 225 Old: "baz", 226 New: "", 227 NewRemoved: true, 228 } 229 } else { 230 result["foo.bar"] = &terraform.ResourceAttrDiff{ 231 Old: "baz", 232 New: "quux", 233 } 234 } 235 return result 236 }(), 237 }, 238 }, 239 resourceDiffTestCase{ 240 Name: "additional diff with primitive", 241 Schema: map[string]*Schema{ 242 "foo": &Schema{ 243 Type: TypeString, 244 Optional: true, 245 }, 246 "one": &Schema{ 247 Type: TypeString, 248 Optional: true, 249 Computed: true, 250 }, 251 }, 252 State: &terraform.InstanceState{ 253 Attributes: map[string]string{ 254 "foo": "bar", 255 "one": "two", 256 }, 257 }, 258 Config: testConfig(t, map[string]interface{}{ 259 "foo": "baz", 260 }), 261 Diff: &terraform.InstanceDiff{ 262 Attributes: map[string]*terraform.ResourceAttrDiff{ 263 "foo": &terraform.ResourceAttrDiff{ 264 Old: "bar", 265 New: "baz", 266 }, 267 }, 268 }, 269 Key: "one", 270 NewValue: "four", 271 Expected: &terraform.InstanceDiff{ 272 Attributes: map[string]*terraform.ResourceAttrDiff{ 273 "foo": &terraform.ResourceAttrDiff{ 274 Old: "bar", 275 New: "baz", 276 }, 277 "one": &terraform.ResourceAttrDiff{ 278 Old: "two", 279 New: func() string { 280 if computed { 281 return "" 282 } 283 return "four" 284 }(), 285 NewComputed: computed, 286 }, 287 }, 288 }, 289 }, 290 resourceDiffTestCase{ 291 Name: "additional diff with primitive computed only", 292 Schema: map[string]*Schema{ 293 "foo": &Schema{ 294 Type: TypeString, 295 Optional: true, 296 }, 297 "one": &Schema{ 298 Type: TypeString, 299 Computed: true, 300 }, 301 }, 302 State: &terraform.InstanceState{ 303 Attributes: map[string]string{ 304 "foo": "bar", 305 "one": "two", 306 }, 307 }, 308 Config: testConfig(t, map[string]interface{}{ 309 "foo": "baz", 310 }), 311 Diff: &terraform.InstanceDiff{ 312 Attributes: map[string]*terraform.ResourceAttrDiff{ 313 "foo": &terraform.ResourceAttrDiff{ 314 Old: "bar", 315 New: "baz", 316 }, 317 }, 318 }, 319 Key: "one", 320 NewValue: "three", 321 Expected: &terraform.InstanceDiff{ 322 Attributes: map[string]*terraform.ResourceAttrDiff{ 323 "foo": &terraform.ResourceAttrDiff{ 324 Old: "bar", 325 New: "baz", 326 }, 327 "one": &terraform.ResourceAttrDiff{ 328 Old: "two", 329 New: func() string { 330 if computed { 331 return "" 332 } 333 return "three" 334 }(), 335 NewComputed: computed, 336 }, 337 }, 338 }, 339 }, 340 resourceDiffTestCase{ 341 Name: "complex-ish set diff", 342 Schema: map[string]*Schema{ 343 "top": &Schema{ 344 Type: TypeSet, 345 Optional: true, 346 Computed: true, 347 Elem: &Resource{ 348 Schema: map[string]*Schema{ 349 "foo": &Schema{ 350 Type: TypeInt, 351 Optional: true, 352 Computed: true, 353 }, 354 "bar": &Schema{ 355 Type: TypeInt, 356 Optional: true, 357 Computed: true, 358 }, 359 }, 360 }, 361 Set: testSetFunc, 362 }, 363 }, 364 State: &terraform.InstanceState{ 365 Attributes: map[string]string{ 366 "top.#": "2", 367 "top.3.foo": "1", 368 "top.3.bar": "2", 369 "top.23.foo": "11", 370 "top.23.bar": "12", 371 }, 372 }, 373 Config: testConfig(t, map[string]interface{}{ 374 "top": []interface{}{ 375 map[string]interface{}{ 376 "foo": 1, 377 "bar": 3, 378 }, 379 map[string]interface{}{ 380 "foo": 12, 381 "bar": 12, 382 }, 383 }, 384 }), 385 Diff: &terraform.InstanceDiff{ 386 Attributes: map[string]*terraform.ResourceAttrDiff{ 387 "top.4.foo": &terraform.ResourceAttrDiff{ 388 Old: "", 389 New: "1", 390 }, 391 "top.4.bar": &terraform.ResourceAttrDiff{ 392 Old: "", 393 New: "3", 394 }, 395 "top.24.foo": &terraform.ResourceAttrDiff{ 396 Old: "", 397 New: "12", 398 }, 399 "top.24.bar": &terraform.ResourceAttrDiff{ 400 Old: "", 401 New: "12", 402 }, 403 }, 404 }, 405 Key: "top", 406 NewValue: NewSet(testSetFunc, []interface{}{ 407 map[string]interface{}{ 408 "foo": 1, 409 "bar": 4, 410 }, 411 map[string]interface{}{ 412 "foo": 13, 413 "bar": 12, 414 }, 415 map[string]interface{}{ 416 "foo": 21, 417 "bar": 22, 418 }, 419 }), 420 Expected: &terraform.InstanceDiff{ 421 Attributes: func() map[string]*terraform.ResourceAttrDiff { 422 result := make(map[string]*terraform.ResourceAttrDiff) 423 if computed { 424 result["top.#"] = &terraform.ResourceAttrDiff{ 425 Old: "2", 426 New: "", 427 NewComputed: true, 428 } 429 } else { 430 result["top.#"] = &terraform.ResourceAttrDiff{ 431 Old: "2", 432 New: "3", 433 } 434 result["top.5.foo"] = &terraform.ResourceAttrDiff{ 435 Old: "", 436 New: "1", 437 } 438 result["top.5.bar"] = &terraform.ResourceAttrDiff{ 439 Old: "", 440 New: "4", 441 } 442 result["top.25.foo"] = &terraform.ResourceAttrDiff{ 443 Old: "", 444 New: "13", 445 } 446 result["top.25.bar"] = &terraform.ResourceAttrDiff{ 447 Old: "", 448 New: "12", 449 } 450 result["top.43.foo"] = &terraform.ResourceAttrDiff{ 451 Old: "", 452 New: "21", 453 } 454 result["top.43.bar"] = &terraform.ResourceAttrDiff{ 455 Old: "", 456 New: "22", 457 } 458 } 459 return result 460 }(), 461 }, 462 }, 463 resourceDiffTestCase{ 464 Name: "primitive, no diff, no refresh", 465 Schema: map[string]*Schema{ 466 "foo": &Schema{ 467 Type: TypeString, 468 Computed: true, 469 }, 470 }, 471 State: &terraform.InstanceState{ 472 Attributes: map[string]string{ 473 "foo": "bar", 474 }, 475 }, 476 Config: testConfig(t, map[string]interface{}{}), 477 Diff: &terraform.InstanceDiff{Attributes: map[string]*terraform.ResourceAttrDiff{}}, 478 Key: "foo", 479 NewValue: "baz", 480 Expected: &terraform.InstanceDiff{ 481 Attributes: map[string]*terraform.ResourceAttrDiff{ 482 "foo": &terraform.ResourceAttrDiff{ 483 Old: "bar", 484 New: func() string { 485 if computed { 486 return "" 487 } 488 return "baz" 489 }(), 490 NewComputed: computed, 491 }, 492 }, 493 }, 494 }, 495 resourceDiffTestCase{ 496 Name: "non-computed key, should error", 497 Schema: map[string]*Schema{ 498 "foo": &Schema{ 499 Type: TypeString, 500 Required: true, 501 }, 502 }, 503 State: &terraform.InstanceState{ 504 Attributes: map[string]string{ 505 "foo": "bar", 506 }, 507 }, 508 Config: testConfig(t, map[string]interface{}{ 509 "foo": "baz", 510 }), 511 Diff: &terraform.InstanceDiff{ 512 Attributes: map[string]*terraform.ResourceAttrDiff{ 513 "foo": &terraform.ResourceAttrDiff{ 514 Old: "bar", 515 New: "baz", 516 }, 517 }, 518 }, 519 Key: "foo", 520 NewValue: "qux", 521 ExpectedError: true, 522 }, 523 resourceDiffTestCase{ 524 Name: "bad key, should error", 525 Schema: map[string]*Schema{ 526 "foo": &Schema{ 527 Type: TypeString, 528 Required: true, 529 }, 530 }, 531 State: &terraform.InstanceState{ 532 Attributes: map[string]string{ 533 "foo": "bar", 534 }, 535 }, 536 Config: testConfig(t, map[string]interface{}{ 537 "foo": "baz", 538 }), 539 Diff: &terraform.InstanceDiff{ 540 Attributes: map[string]*terraform.ResourceAttrDiff{ 541 "foo": &terraform.ResourceAttrDiff{ 542 Old: "bar", 543 New: "baz", 544 }, 545 }, 546 }, 547 Key: "bad", 548 NewValue: "qux", 549 ExpectedError: true, 550 }, 551 } 552 } 553 554 func TestSetNew(t *testing.T) { 555 testCases := testDiffCases(t, "", 0, false) 556 for _, tc := range testCases { 557 t.Run(tc.Name, func(t *testing.T) { 558 m := schemaMap(tc.Schema) 559 d := newResourceDiff(tc.Schema, tc.Config, tc.State, tc.Diff) 560 err := d.SetNew(tc.Key, tc.NewValue) 561 switch { 562 case err != nil && !tc.ExpectedError: 563 t.Fatalf("bad: %s", err) 564 case err == nil && tc.ExpectedError: 565 t.Fatalf("Expected error, got none") 566 case err != nil && tc.ExpectedError: 567 return 568 } 569 for _, k := range d.UpdatedKeys() { 570 if err := m.diff(k, m[k], tc.Diff, d, false); err != nil { 571 t.Fatalf("bad: %s", err) 572 } 573 } 574 if !reflect.DeepEqual(tc.Expected, tc.Diff) { 575 t.Fatalf("Expected %s, got %s", spew.Sdump(tc.Expected), spew.Sdump(tc.Diff)) 576 } 577 }) 578 } 579 } 580 581 func TestSetNewComputed(t *testing.T) { 582 testCases := testDiffCases(t, "", 0, true) 583 for _, tc := range testCases { 584 t.Run(tc.Name, func(t *testing.T) { 585 m := schemaMap(tc.Schema) 586 d := newResourceDiff(tc.Schema, tc.Config, tc.State, tc.Diff) 587 err := d.SetNewComputed(tc.Key) 588 switch { 589 case err != nil && !tc.ExpectedError: 590 t.Fatalf("bad: %s", err) 591 case err == nil && tc.ExpectedError: 592 t.Fatalf("Expected error, got none") 593 case err != nil && tc.ExpectedError: 594 return 595 } 596 for _, k := range d.UpdatedKeys() { 597 if err := m.diff(k, m[k], tc.Diff, d, false); err != nil { 598 t.Fatalf("bad: %s", err) 599 } 600 } 601 if !reflect.DeepEqual(tc.Expected, tc.Diff) { 602 t.Fatalf("Expected %s, got %s", spew.Sdump(tc.Expected), spew.Sdump(tc.Diff)) 603 } 604 }) 605 } 606 } 607 608 func TestForceNew(t *testing.T) { 609 cases := []resourceDiffTestCase{ 610 resourceDiffTestCase{ 611 Name: "basic primitive diff", 612 Schema: map[string]*Schema{ 613 "foo": &Schema{ 614 Type: TypeString, 615 Optional: true, 616 Computed: true, 617 }, 618 }, 619 State: &terraform.InstanceState{ 620 Attributes: map[string]string{ 621 "foo": "bar", 622 }, 623 }, 624 Config: testConfig(t, map[string]interface{}{ 625 "foo": "baz", 626 }), 627 Diff: &terraform.InstanceDiff{ 628 Attributes: map[string]*terraform.ResourceAttrDiff{ 629 "foo": &terraform.ResourceAttrDiff{ 630 Old: "bar", 631 New: "baz", 632 }, 633 }, 634 }, 635 Key: "foo", 636 Expected: &terraform.InstanceDiff{ 637 Attributes: map[string]*terraform.ResourceAttrDiff{ 638 "foo": &terraform.ResourceAttrDiff{ 639 Old: "bar", 640 New: "baz", 641 RequiresNew: true, 642 }, 643 }, 644 }, 645 }, 646 resourceDiffTestCase{ 647 Name: "no change, should error", 648 Schema: map[string]*Schema{ 649 "foo": &Schema{ 650 Type: TypeString, 651 Optional: true, 652 Computed: true, 653 }, 654 }, 655 State: &terraform.InstanceState{ 656 Attributes: map[string]string{ 657 "foo": "bar", 658 }, 659 }, 660 Config: testConfig(t, map[string]interface{}{ 661 "foo": "bar", 662 }), 663 ExpectedError: true, 664 }, 665 resourceDiffTestCase{ 666 Name: "basic primitive, non-computed key", 667 Schema: map[string]*Schema{ 668 "foo": &Schema{ 669 Type: TypeString, 670 Required: true, 671 }, 672 }, 673 State: &terraform.InstanceState{ 674 Attributes: map[string]string{ 675 "foo": "bar", 676 }, 677 }, 678 Config: testConfig(t, map[string]interface{}{ 679 "foo": "baz", 680 }), 681 Diff: &terraform.InstanceDiff{ 682 Attributes: map[string]*terraform.ResourceAttrDiff{ 683 "foo": &terraform.ResourceAttrDiff{ 684 Old: "bar", 685 New: "baz", 686 }, 687 }, 688 }, 689 Key: "foo", 690 Expected: &terraform.InstanceDiff{ 691 Attributes: map[string]*terraform.ResourceAttrDiff{ 692 "foo": &terraform.ResourceAttrDiff{ 693 Old: "bar", 694 New: "baz", 695 RequiresNew: true, 696 }, 697 }, 698 }, 699 }, 700 } 701 for _, tc := range cases { 702 t.Run(tc.Name, func(t *testing.T) { 703 m := schemaMap(tc.Schema) 704 d := newResourceDiff(m, tc.Config, tc.State, tc.Diff) 705 err := d.ForceNew(tc.Key) 706 switch { 707 case err != nil && !tc.ExpectedError: 708 t.Fatalf("bad: %s", err) 709 case err == nil && tc.ExpectedError: 710 t.Fatalf("Expected error, got none") 711 case err != nil && tc.ExpectedError: 712 return 713 } 714 for _, k := range d.UpdatedKeys() { 715 if err := m.diff(k, m[k], tc.Diff, d, false); err != nil { 716 t.Fatalf("bad: %s", err) 717 } 718 } 719 if !reflect.DeepEqual(tc.Expected, tc.Diff) { 720 t.Fatalf("Expected %s, got %s", spew.Sdump(tc.Expected), spew.Sdump(tc.Diff)) 721 } 722 }) 723 } 724 } 725 726 func TestClear(t *testing.T) { 727 cases := []resourceDiffTestCase{ 728 resourceDiffTestCase{ 729 Name: "basic primitive diff", 730 Schema: map[string]*Schema{ 731 "foo": &Schema{ 732 Type: TypeString, 733 Optional: true, 734 Computed: true, 735 }, 736 }, 737 State: &terraform.InstanceState{ 738 Attributes: map[string]string{ 739 "foo": "bar", 740 }, 741 }, 742 Config: testConfig(t, map[string]interface{}{ 743 "foo": "baz", 744 }), 745 Diff: &terraform.InstanceDiff{ 746 Attributes: map[string]*terraform.ResourceAttrDiff{ 747 "foo": &terraform.ResourceAttrDiff{ 748 Old: "bar", 749 New: "baz", 750 }, 751 }, 752 }, 753 Key: "foo", 754 Expected: &terraform.InstanceDiff{Attributes: map[string]*terraform.ResourceAttrDiff{}}, 755 }, 756 resourceDiffTestCase{ 757 Name: "non-computed key, should error", 758 Schema: map[string]*Schema{ 759 "foo": &Schema{ 760 Type: TypeString, 761 Required: true, 762 }, 763 }, 764 State: &terraform.InstanceState{ 765 Attributes: map[string]string{ 766 "foo": "bar", 767 }, 768 }, 769 Config: testConfig(t, map[string]interface{}{ 770 "foo": "baz", 771 }), 772 Diff: &terraform.InstanceDiff{ 773 Attributes: map[string]*terraform.ResourceAttrDiff{ 774 "foo": &terraform.ResourceAttrDiff{ 775 Old: "bar", 776 New: "baz", 777 }, 778 }, 779 }, 780 Key: "foo", 781 ExpectedError: true, 782 }, 783 resourceDiffTestCase{ 784 Name: "multi-value, one removed", 785 Schema: map[string]*Schema{ 786 "foo": &Schema{ 787 Type: TypeString, 788 Optional: true, 789 Computed: true, 790 }, 791 "one": &Schema{ 792 Type: TypeString, 793 Optional: true, 794 Computed: true, 795 }, 796 }, 797 State: &terraform.InstanceState{ 798 Attributes: map[string]string{ 799 "foo": "bar", 800 "one": "two", 801 }, 802 }, 803 Config: testConfig(t, map[string]interface{}{ 804 "foo": "baz", 805 "one": "three", 806 }), 807 Diff: &terraform.InstanceDiff{ 808 Attributes: map[string]*terraform.ResourceAttrDiff{ 809 "foo": &terraform.ResourceAttrDiff{ 810 Old: "bar", 811 New: "baz", 812 }, 813 "one": &terraform.ResourceAttrDiff{ 814 Old: "two", 815 New: "three", 816 }, 817 }, 818 }, 819 Key: "one", 820 Expected: &terraform.InstanceDiff{ 821 Attributes: map[string]*terraform.ResourceAttrDiff{ 822 "foo": &terraform.ResourceAttrDiff{ 823 Old: "bar", 824 New: "baz", 825 }, 826 }, 827 }, 828 }, 829 } 830 for _, tc := range cases { 831 t.Run(tc.Name, func(t *testing.T) { 832 m := schemaMap(tc.Schema) 833 d := newResourceDiff(m, tc.Config, tc.State, tc.Diff) 834 err := d.Clear(tc.Key) 835 switch { 836 case err != nil && !tc.ExpectedError: 837 t.Fatalf("bad: %s", err) 838 case err == nil && tc.ExpectedError: 839 t.Fatalf("Expected error, got none") 840 case err != nil && tc.ExpectedError: 841 return 842 } 843 for _, k := range d.UpdatedKeys() { 844 if err := m.diff(k, m[k], tc.Diff, d, false); err != nil { 845 t.Fatalf("bad: %s", err) 846 } 847 } 848 if !reflect.DeepEqual(tc.Expected, tc.Diff) { 849 t.Fatalf("Expected %s, got %s", spew.Sdump(tc.Expected), spew.Sdump(tc.Diff)) 850 } 851 }) 852 } 853 }