github.com/diptanu/nomad@v0.5.7-0.20170516172507-d72e86cbe3d9/nomad/structs/diff_test.go (about) 1 package structs 2 3 import ( 4 "reflect" 5 "testing" 6 "time" 7 ) 8 9 func TestJobDiff(t *testing.T) { 10 cases := []struct { 11 Old, New *Job 12 Expected *JobDiff 13 Error bool 14 Contextual bool 15 }{ 16 { 17 Old: nil, 18 New: nil, 19 Expected: &JobDiff{ 20 Type: DiffTypeNone, 21 }, 22 }, 23 { 24 // Different IDs 25 Old: &Job{ 26 ID: "foo", 27 }, 28 New: &Job{ 29 ID: "bar", 30 }, 31 Error: true, 32 }, 33 { 34 // Primitive only that is the same 35 Old: &Job{ 36 Region: "foo", 37 ID: "foo", 38 Name: "foo", 39 Type: "batch", 40 Priority: 10, 41 AllAtOnce: true, 42 Meta: map[string]string{ 43 "foo": "bar", 44 }, 45 }, 46 New: &Job{ 47 Region: "foo", 48 ID: "foo", 49 Name: "foo", 50 Type: "batch", 51 Priority: 10, 52 AllAtOnce: true, 53 Meta: map[string]string{ 54 "foo": "bar", 55 }, 56 }, 57 Expected: &JobDiff{ 58 Type: DiffTypeNone, 59 ID: "foo", 60 }, 61 }, 62 { 63 // Primitive only that is has diffs 64 Old: &Job{ 65 Region: "foo", 66 ID: "foo", 67 Name: "foo", 68 Type: "batch", 69 Priority: 10, 70 AllAtOnce: true, 71 Meta: map[string]string{ 72 "foo": "bar", 73 }, 74 }, 75 New: &Job{ 76 Region: "bar", 77 ID: "foo", 78 Name: "bar", 79 Type: "system", 80 Priority: 100, 81 AllAtOnce: false, 82 Meta: map[string]string{ 83 "foo": "baz", 84 }, 85 }, 86 Expected: &JobDiff{ 87 Type: DiffTypeEdited, 88 ID: "foo", 89 Fields: []*FieldDiff{ 90 { 91 Type: DiffTypeEdited, 92 Name: "AllAtOnce", 93 Old: "true", 94 New: "false", 95 }, 96 { 97 Type: DiffTypeEdited, 98 Name: "Meta[foo]", 99 Old: "bar", 100 New: "baz", 101 }, 102 { 103 Type: DiffTypeEdited, 104 Name: "Name", 105 Old: "foo", 106 New: "bar", 107 }, 108 { 109 Type: DiffTypeEdited, 110 Name: "Priority", 111 Old: "10", 112 New: "100", 113 }, 114 { 115 Type: DiffTypeEdited, 116 Name: "Region", 117 Old: "foo", 118 New: "bar", 119 }, 120 { 121 Type: DiffTypeEdited, 122 Name: "Type", 123 Old: "batch", 124 New: "system", 125 }, 126 }, 127 }, 128 }, 129 { 130 // Primitive only deleted job 131 Old: &Job{ 132 Region: "foo", 133 ID: "foo", 134 Name: "foo", 135 Type: "batch", 136 Priority: 10, 137 AllAtOnce: true, 138 Meta: map[string]string{ 139 "foo": "bar", 140 }, 141 }, 142 New: nil, 143 Expected: &JobDiff{ 144 Type: DiffTypeDeleted, 145 ID: "foo", 146 Fields: []*FieldDiff{ 147 { 148 Type: DiffTypeDeleted, 149 Name: "AllAtOnce", 150 Old: "true", 151 New: "", 152 }, 153 { 154 Type: DiffTypeDeleted, 155 Name: "Meta[foo]", 156 Old: "bar", 157 New: "", 158 }, 159 { 160 Type: DiffTypeDeleted, 161 Name: "Name", 162 Old: "foo", 163 New: "", 164 }, 165 { 166 Type: DiffTypeDeleted, 167 Name: "Priority", 168 Old: "10", 169 New: "", 170 }, 171 { 172 Type: DiffTypeDeleted, 173 Name: "Region", 174 Old: "foo", 175 New: "", 176 }, 177 { 178 Type: DiffTypeDeleted, 179 Name: "Stop", 180 Old: "false", 181 New: "", 182 }, 183 { 184 Type: DiffTypeDeleted, 185 Name: "Type", 186 Old: "batch", 187 New: "", 188 }, 189 }, 190 Objects: []*ObjectDiff{ 191 { 192 Type: DiffTypeDeleted, 193 Name: "Update", 194 Fields: []*FieldDiff{ 195 { 196 Type: DiffTypeDeleted, 197 Name: "MaxParallel", 198 Old: "0", 199 New: "", 200 }, 201 { 202 Type: DiffTypeDeleted, 203 Name: "Stagger", 204 Old: "0", 205 New: "", 206 }, 207 }, 208 }, 209 }, 210 }, 211 }, 212 { 213 // Primitive only added job 214 Old: nil, 215 New: &Job{ 216 Region: "foo", 217 ID: "foo", 218 Name: "foo", 219 Type: "batch", 220 Priority: 10, 221 AllAtOnce: true, 222 Meta: map[string]string{ 223 "foo": "bar", 224 }, 225 }, 226 Expected: &JobDiff{ 227 Type: DiffTypeAdded, 228 ID: "foo", 229 Fields: []*FieldDiff{ 230 { 231 Type: DiffTypeAdded, 232 Name: "AllAtOnce", 233 Old: "", 234 New: "true", 235 }, 236 { 237 Type: DiffTypeAdded, 238 Name: "Meta[foo]", 239 Old: "", 240 New: "bar", 241 }, 242 { 243 Type: DiffTypeAdded, 244 Name: "Name", 245 Old: "", 246 New: "foo", 247 }, 248 { 249 Type: DiffTypeAdded, 250 Name: "Priority", 251 Old: "", 252 New: "10", 253 }, 254 { 255 Type: DiffTypeAdded, 256 Name: "Region", 257 Old: "", 258 New: "foo", 259 }, 260 { 261 Type: DiffTypeAdded, 262 Name: "Stop", 263 Old: "", 264 New: "false", 265 }, 266 { 267 Type: DiffTypeAdded, 268 Name: "Type", 269 Old: "", 270 New: "batch", 271 }, 272 }, 273 Objects: []*ObjectDiff{ 274 { 275 Type: DiffTypeAdded, 276 Name: "Update", 277 Fields: []*FieldDiff{ 278 { 279 Type: DiffTypeAdded, 280 Name: "MaxParallel", 281 Old: "", 282 New: "0", 283 }, 284 { 285 Type: DiffTypeAdded, 286 Name: "Stagger", 287 Old: "", 288 New: "0", 289 }, 290 }, 291 }, 292 }, 293 }, 294 }, 295 { 296 // Map diff 297 Old: &Job{ 298 Meta: map[string]string{ 299 "foo": "foo", 300 "bar": "bar", 301 }, 302 }, 303 New: &Job{ 304 Meta: map[string]string{ 305 "bar": "bar", 306 "baz": "baz", 307 }, 308 }, 309 Expected: &JobDiff{ 310 Type: DiffTypeEdited, 311 Fields: []*FieldDiff{ 312 { 313 Type: DiffTypeAdded, 314 Name: "Meta[baz]", 315 Old: "", 316 New: "baz", 317 }, 318 { 319 Type: DiffTypeDeleted, 320 Name: "Meta[foo]", 321 Old: "foo", 322 New: "", 323 }, 324 }, 325 }, 326 }, 327 { 328 // Datacenter diff both added and removed 329 Old: &Job{ 330 Datacenters: []string{"foo", "bar"}, 331 }, 332 New: &Job{ 333 Datacenters: []string{"baz", "bar"}, 334 }, 335 Expected: &JobDiff{ 336 Type: DiffTypeEdited, 337 Objects: []*ObjectDiff{ 338 { 339 Type: DiffTypeEdited, 340 Name: "Datacenters", 341 Fields: []*FieldDiff{ 342 { 343 Type: DiffTypeAdded, 344 Name: "Datacenters", 345 Old: "", 346 New: "baz", 347 }, 348 { 349 Type: DiffTypeDeleted, 350 Name: "Datacenters", 351 Old: "foo", 352 New: "", 353 }, 354 }, 355 }, 356 }, 357 }, 358 }, 359 { 360 // Datacenter diff just added 361 Old: &Job{ 362 Datacenters: []string{"foo", "bar"}, 363 }, 364 New: &Job{ 365 Datacenters: []string{"foo", "bar", "baz"}, 366 }, 367 Expected: &JobDiff{ 368 Type: DiffTypeEdited, 369 Objects: []*ObjectDiff{ 370 { 371 Type: DiffTypeAdded, 372 Name: "Datacenters", 373 Fields: []*FieldDiff{ 374 { 375 Type: DiffTypeAdded, 376 Name: "Datacenters", 377 Old: "", 378 New: "baz", 379 }, 380 }, 381 }, 382 }, 383 }, 384 }, 385 { 386 // Datacenter diff just deleted 387 Old: &Job{ 388 Datacenters: []string{"foo", "bar"}, 389 }, 390 New: &Job{ 391 Datacenters: []string{"foo"}, 392 }, 393 Expected: &JobDiff{ 394 Type: DiffTypeEdited, 395 Objects: []*ObjectDiff{ 396 { 397 Type: DiffTypeDeleted, 398 Name: "Datacenters", 399 Fields: []*FieldDiff{ 400 { 401 Type: DiffTypeDeleted, 402 Name: "Datacenters", 403 Old: "bar", 404 New: "", 405 }, 406 }, 407 }, 408 }, 409 }, 410 }, 411 { 412 // Datacenter contextual no change 413 Contextual: true, 414 Old: &Job{ 415 Datacenters: []string{"foo", "bar"}, 416 }, 417 New: &Job{ 418 Datacenters: []string{"foo", "bar"}, 419 }, 420 Expected: &JobDiff{ 421 Type: DiffTypeNone, 422 }, 423 }, 424 { 425 // Datacenter contextual 426 Contextual: true, 427 Old: &Job{ 428 Datacenters: []string{"foo", "bar"}, 429 }, 430 New: &Job{ 431 Datacenters: []string{"foo", "bar", "baz"}, 432 }, 433 Expected: &JobDiff{ 434 Type: DiffTypeEdited, 435 Objects: []*ObjectDiff{ 436 { 437 Type: DiffTypeAdded, 438 Name: "Datacenters", 439 Fields: []*FieldDiff{ 440 { 441 Type: DiffTypeAdded, 442 Name: "Datacenters", 443 Old: "", 444 New: "baz", 445 }, 446 { 447 Type: DiffTypeNone, 448 Name: "Datacenters", 449 Old: "bar", 450 New: "bar", 451 }, 452 { 453 Type: DiffTypeNone, 454 Name: "Datacenters", 455 Old: "foo", 456 New: "foo", 457 }, 458 }, 459 }, 460 }, 461 }, 462 }, 463 { 464 // Update strategy edited 465 Old: &Job{ 466 Update: UpdateStrategy{ 467 Stagger: 10 * time.Second, 468 MaxParallel: 5, 469 }, 470 }, 471 New: &Job{ 472 Update: UpdateStrategy{ 473 Stagger: 60 * time.Second, 474 MaxParallel: 10, 475 }, 476 }, 477 Expected: &JobDiff{ 478 Type: DiffTypeEdited, 479 Objects: []*ObjectDiff{ 480 { 481 Type: DiffTypeEdited, 482 Name: "Update", 483 Fields: []*FieldDiff{ 484 { 485 Type: DiffTypeEdited, 486 Name: "MaxParallel", 487 Old: "5", 488 New: "10", 489 }, 490 { 491 Type: DiffTypeEdited, 492 Name: "Stagger", 493 Old: "10000000000", 494 New: "60000000000", 495 }, 496 }, 497 }, 498 }, 499 }, 500 }, 501 { 502 // Update strategy edited with context 503 Contextual: true, 504 Old: &Job{ 505 Update: UpdateStrategy{ 506 Stagger: 10 * time.Second, 507 MaxParallel: 5, 508 }, 509 }, 510 New: &Job{ 511 Update: UpdateStrategy{ 512 Stagger: 60 * time.Second, 513 MaxParallel: 5, 514 }, 515 }, 516 Expected: &JobDiff{ 517 Type: DiffTypeEdited, 518 Objects: []*ObjectDiff{ 519 { 520 Type: DiffTypeEdited, 521 Name: "Update", 522 Fields: []*FieldDiff{ 523 { 524 Type: DiffTypeNone, 525 Name: "MaxParallel", 526 Old: "5", 527 New: "5", 528 }, 529 { 530 Type: DiffTypeEdited, 531 Name: "Stagger", 532 Old: "10000000000", 533 New: "60000000000", 534 }, 535 }, 536 }, 537 }, 538 }, 539 }, 540 { 541 // Periodic added 542 Old: &Job{}, 543 New: &Job{ 544 Periodic: &PeriodicConfig{ 545 Enabled: false, 546 Spec: "*/15 * * * * *", 547 SpecType: "foo", 548 ProhibitOverlap: false, 549 TimeZone: "Europe/Minsk", 550 }, 551 }, 552 Expected: &JobDiff{ 553 Type: DiffTypeEdited, 554 Objects: []*ObjectDiff{ 555 { 556 Type: DiffTypeAdded, 557 Name: "Periodic", 558 Fields: []*FieldDiff{ 559 { 560 Type: DiffTypeAdded, 561 Name: "Enabled", 562 Old: "", 563 New: "false", 564 }, 565 { 566 Type: DiffTypeAdded, 567 Name: "ProhibitOverlap", 568 Old: "", 569 New: "false", 570 }, 571 { 572 Type: DiffTypeAdded, 573 Name: "Spec", 574 Old: "", 575 New: "*/15 * * * * *", 576 }, 577 { 578 Type: DiffTypeAdded, 579 Name: "SpecType", 580 Old: "", 581 New: "foo", 582 }, 583 { 584 Type: DiffTypeAdded, 585 Name: "TimeZone", 586 Old: "", 587 New: "Europe/Minsk", 588 }, 589 }, 590 }, 591 }, 592 }, 593 }, 594 { 595 // Periodic deleted 596 Old: &Job{ 597 Periodic: &PeriodicConfig{ 598 Enabled: false, 599 Spec: "*/15 * * * * *", 600 SpecType: "foo", 601 ProhibitOverlap: false, 602 TimeZone: "Europe/Minsk", 603 }, 604 }, 605 New: &Job{}, 606 Expected: &JobDiff{ 607 Type: DiffTypeEdited, 608 Objects: []*ObjectDiff{ 609 { 610 Type: DiffTypeDeleted, 611 Name: "Periodic", 612 Fields: []*FieldDiff{ 613 { 614 Type: DiffTypeDeleted, 615 Name: "Enabled", 616 Old: "false", 617 New: "", 618 }, 619 { 620 Type: DiffTypeDeleted, 621 Name: "ProhibitOverlap", 622 Old: "false", 623 New: "", 624 }, 625 { 626 Type: DiffTypeDeleted, 627 Name: "Spec", 628 Old: "*/15 * * * * *", 629 New: "", 630 }, 631 { 632 Type: DiffTypeDeleted, 633 Name: "SpecType", 634 Old: "foo", 635 New: "", 636 }, 637 { 638 Type: DiffTypeDeleted, 639 Name: "TimeZone", 640 Old: "Europe/Minsk", 641 New: "", 642 }, 643 }, 644 }, 645 }, 646 }, 647 }, 648 { 649 // Periodic edited 650 Old: &Job{ 651 Periodic: &PeriodicConfig{ 652 Enabled: false, 653 Spec: "*/15 * * * * *", 654 SpecType: "foo", 655 ProhibitOverlap: false, 656 TimeZone: "Europe/Minsk", 657 }, 658 }, 659 New: &Job{ 660 Periodic: &PeriodicConfig{ 661 Enabled: true, 662 Spec: "* * * * * *", 663 SpecType: "cron", 664 ProhibitOverlap: true, 665 TimeZone: "America/Los_Angeles", 666 }, 667 }, 668 Expected: &JobDiff{ 669 Type: DiffTypeEdited, 670 Objects: []*ObjectDiff{ 671 { 672 Type: DiffTypeEdited, 673 Name: "Periodic", 674 Fields: []*FieldDiff{ 675 { 676 Type: DiffTypeEdited, 677 Name: "Enabled", 678 Old: "false", 679 New: "true", 680 }, 681 { 682 Type: DiffTypeEdited, 683 Name: "ProhibitOverlap", 684 Old: "false", 685 New: "true", 686 }, 687 { 688 Type: DiffTypeEdited, 689 Name: "Spec", 690 Old: "*/15 * * * * *", 691 New: "* * * * * *", 692 }, 693 { 694 Type: DiffTypeEdited, 695 Name: "SpecType", 696 Old: "foo", 697 New: "cron", 698 }, 699 { 700 Type: DiffTypeEdited, 701 Name: "TimeZone", 702 Old: "Europe/Minsk", 703 New: "America/Los_Angeles", 704 }, 705 }, 706 }, 707 }, 708 }, 709 }, 710 { 711 // Periodic edited with context 712 Contextual: true, 713 Old: &Job{ 714 Periodic: &PeriodicConfig{ 715 Enabled: false, 716 Spec: "*/15 * * * * *", 717 SpecType: "foo", 718 ProhibitOverlap: false, 719 TimeZone: "Europe/Minsk", 720 }, 721 }, 722 New: &Job{ 723 Periodic: &PeriodicConfig{ 724 Enabled: true, 725 Spec: "* * * * * *", 726 SpecType: "foo", 727 ProhibitOverlap: false, 728 TimeZone: "Europe/Minsk", 729 }, 730 }, 731 Expected: &JobDiff{ 732 Type: DiffTypeEdited, 733 Objects: []*ObjectDiff{ 734 { 735 Type: DiffTypeEdited, 736 Name: "Periodic", 737 Fields: []*FieldDiff{ 738 { 739 Type: DiffTypeEdited, 740 Name: "Enabled", 741 Old: "false", 742 New: "true", 743 }, 744 { 745 Type: DiffTypeNone, 746 Name: "ProhibitOverlap", 747 Old: "false", 748 New: "false", 749 }, 750 { 751 Type: DiffTypeEdited, 752 Name: "Spec", 753 Old: "*/15 * * * * *", 754 New: "* * * * * *", 755 }, 756 { 757 Type: DiffTypeNone, 758 Name: "SpecType", 759 Old: "foo", 760 New: "foo", 761 }, 762 { 763 Type: DiffTypeNone, 764 Name: "TimeZone", 765 Old: "Europe/Minsk", 766 New: "Europe/Minsk", 767 }, 768 }, 769 }, 770 }, 771 }, 772 }, 773 { 774 // Constraints edited 775 Old: &Job{ 776 Constraints: []*Constraint{ 777 { 778 LTarget: "foo", 779 RTarget: "foo", 780 Operand: "foo", 781 str: "foo", 782 }, 783 { 784 LTarget: "bar", 785 RTarget: "bar", 786 Operand: "bar", 787 str: "bar", 788 }, 789 }, 790 }, 791 New: &Job{ 792 Constraints: []*Constraint{ 793 { 794 LTarget: "foo", 795 RTarget: "foo", 796 Operand: "foo", 797 str: "foo", 798 }, 799 { 800 LTarget: "baz", 801 RTarget: "baz", 802 Operand: "baz", 803 str: "baz", 804 }, 805 }, 806 }, 807 Expected: &JobDiff{ 808 Type: DiffTypeEdited, 809 Objects: []*ObjectDiff{ 810 { 811 Type: DiffTypeAdded, 812 Name: "Constraint", 813 Fields: []*FieldDiff{ 814 { 815 Type: DiffTypeAdded, 816 Name: "LTarget", 817 Old: "", 818 New: "baz", 819 }, 820 { 821 Type: DiffTypeAdded, 822 Name: "Operand", 823 Old: "", 824 New: "baz", 825 }, 826 { 827 Type: DiffTypeAdded, 828 Name: "RTarget", 829 Old: "", 830 New: "baz", 831 }, 832 }, 833 }, 834 { 835 Type: DiffTypeDeleted, 836 Name: "Constraint", 837 Fields: []*FieldDiff{ 838 { 839 Type: DiffTypeDeleted, 840 Name: "LTarget", 841 Old: "bar", 842 New: "", 843 }, 844 { 845 Type: DiffTypeDeleted, 846 Name: "Operand", 847 Old: "bar", 848 New: "", 849 }, 850 { 851 Type: DiffTypeDeleted, 852 Name: "RTarget", 853 Old: "bar", 854 New: "", 855 }, 856 }, 857 }, 858 }, 859 }, 860 }, 861 { 862 // Task groups edited 863 Old: &Job{ 864 TaskGroups: []*TaskGroup{ 865 { 866 Name: "foo", 867 Count: 1, 868 }, 869 { 870 Name: "bar", 871 Count: 1, 872 }, 873 { 874 Name: "baz", 875 Count: 1, 876 }, 877 }, 878 }, 879 New: &Job{ 880 TaskGroups: []*TaskGroup{ 881 { 882 Name: "bar", 883 Count: 1, 884 }, 885 { 886 Name: "baz", 887 Count: 2, 888 }, 889 { 890 Name: "bam", 891 Count: 1, 892 }, 893 }, 894 }, 895 Expected: &JobDiff{ 896 Type: DiffTypeEdited, 897 TaskGroups: []*TaskGroupDiff{ 898 { 899 Type: DiffTypeAdded, 900 Name: "bam", 901 Fields: []*FieldDiff{ 902 { 903 Type: DiffTypeAdded, 904 Name: "Count", 905 Old: "", 906 New: "1", 907 }, 908 }, 909 }, 910 { 911 Type: DiffTypeNone, 912 Name: "bar", 913 }, 914 { 915 Type: DiffTypeEdited, 916 Name: "baz", 917 Fields: []*FieldDiff{ 918 { 919 Type: DiffTypeEdited, 920 Name: "Count", 921 Old: "1", 922 New: "2", 923 }, 924 }, 925 }, 926 { 927 Type: DiffTypeDeleted, 928 Name: "foo", 929 Fields: []*FieldDiff{ 930 { 931 Type: DiffTypeDeleted, 932 Name: "Count", 933 Old: "1", 934 New: "", 935 }, 936 }, 937 }, 938 }, 939 }, 940 }, 941 { 942 // Parameterized Job added 943 Old: &Job{}, 944 New: &Job{ 945 ParameterizedJob: &ParameterizedJobConfig{ 946 Payload: DispatchPayloadRequired, 947 MetaOptional: []string{"foo"}, 948 MetaRequired: []string{"bar"}, 949 }, 950 }, 951 Expected: &JobDiff{ 952 Type: DiffTypeEdited, 953 Objects: []*ObjectDiff{ 954 { 955 Type: DiffTypeAdded, 956 Name: "ParameterizedJob", 957 Fields: []*FieldDiff{ 958 { 959 Type: DiffTypeAdded, 960 Name: "Payload", 961 Old: "", 962 New: DispatchPayloadRequired, 963 }, 964 }, 965 Objects: []*ObjectDiff{ 966 { 967 Type: DiffTypeAdded, 968 Name: "MetaOptional", 969 Fields: []*FieldDiff{ 970 { 971 Type: DiffTypeAdded, 972 Name: "MetaOptional", 973 Old: "", 974 New: "foo", 975 }, 976 }, 977 }, 978 { 979 Type: DiffTypeAdded, 980 Name: "MetaRequired", 981 Fields: []*FieldDiff{ 982 { 983 Type: DiffTypeAdded, 984 Name: "MetaRequired", 985 Old: "", 986 New: "bar", 987 }, 988 }, 989 }, 990 }, 991 }, 992 }, 993 }, 994 }, 995 { 996 // Parameterized Job deleted 997 Old: &Job{ 998 ParameterizedJob: &ParameterizedJobConfig{ 999 Payload: DispatchPayloadRequired, 1000 MetaOptional: []string{"foo"}, 1001 MetaRequired: []string{"bar"}, 1002 }, 1003 }, 1004 New: &Job{}, 1005 Expected: &JobDiff{ 1006 Type: DiffTypeEdited, 1007 Objects: []*ObjectDiff{ 1008 { 1009 Type: DiffTypeDeleted, 1010 Name: "ParameterizedJob", 1011 Fields: []*FieldDiff{ 1012 { 1013 Type: DiffTypeDeleted, 1014 Name: "Payload", 1015 Old: DispatchPayloadRequired, 1016 New: "", 1017 }, 1018 }, 1019 Objects: []*ObjectDiff{ 1020 { 1021 Type: DiffTypeDeleted, 1022 Name: "MetaOptional", 1023 Fields: []*FieldDiff{ 1024 { 1025 Type: DiffTypeDeleted, 1026 Name: "MetaOptional", 1027 Old: "foo", 1028 New: "", 1029 }, 1030 }, 1031 }, 1032 { 1033 Type: DiffTypeDeleted, 1034 Name: "MetaRequired", 1035 Fields: []*FieldDiff{ 1036 { 1037 Type: DiffTypeDeleted, 1038 Name: "MetaRequired", 1039 Old: "bar", 1040 New: "", 1041 }, 1042 }, 1043 }, 1044 }, 1045 }, 1046 }, 1047 }, 1048 }, 1049 { 1050 // Parameterized Job edited 1051 Old: &Job{ 1052 ParameterizedJob: &ParameterizedJobConfig{ 1053 Payload: DispatchPayloadRequired, 1054 MetaOptional: []string{"foo"}, 1055 MetaRequired: []string{"bar"}, 1056 }, 1057 }, 1058 New: &Job{ 1059 ParameterizedJob: &ParameterizedJobConfig{ 1060 Payload: DispatchPayloadOptional, 1061 MetaOptional: []string{"bam"}, 1062 MetaRequired: []string{"bang"}, 1063 }, 1064 }, 1065 Expected: &JobDiff{ 1066 Type: DiffTypeEdited, 1067 Objects: []*ObjectDiff{ 1068 { 1069 Type: DiffTypeEdited, 1070 Name: "ParameterizedJob", 1071 Fields: []*FieldDiff{ 1072 { 1073 Type: DiffTypeEdited, 1074 Name: "Payload", 1075 Old: DispatchPayloadRequired, 1076 New: DispatchPayloadOptional, 1077 }, 1078 }, 1079 Objects: []*ObjectDiff{ 1080 { 1081 Type: DiffTypeEdited, 1082 Name: "MetaOptional", 1083 Fields: []*FieldDiff{ 1084 { 1085 Type: DiffTypeAdded, 1086 Name: "MetaOptional", 1087 Old: "", 1088 New: "bam", 1089 }, 1090 { 1091 Type: DiffTypeDeleted, 1092 Name: "MetaOptional", 1093 Old: "foo", 1094 New: "", 1095 }, 1096 }, 1097 }, 1098 { 1099 Type: DiffTypeEdited, 1100 Name: "MetaRequired", 1101 Fields: []*FieldDiff{ 1102 { 1103 Type: DiffTypeAdded, 1104 Name: "MetaRequired", 1105 Old: "", 1106 New: "bang", 1107 }, 1108 { 1109 Type: DiffTypeDeleted, 1110 Name: "MetaRequired", 1111 Old: "bar", 1112 New: "", 1113 }, 1114 }, 1115 }, 1116 }, 1117 }, 1118 }, 1119 }, 1120 }, 1121 { 1122 // Parameterized Job edited with context 1123 Contextual: true, 1124 Old: &Job{ 1125 ParameterizedJob: &ParameterizedJobConfig{ 1126 Payload: DispatchPayloadRequired, 1127 MetaOptional: []string{"foo"}, 1128 MetaRequired: []string{"bar"}, 1129 }, 1130 }, 1131 New: &Job{ 1132 ParameterizedJob: &ParameterizedJobConfig{ 1133 Payload: DispatchPayloadOptional, 1134 MetaOptional: []string{"foo"}, 1135 MetaRequired: []string{"bar"}, 1136 }, 1137 }, 1138 Expected: &JobDiff{ 1139 Type: DiffTypeEdited, 1140 Objects: []*ObjectDiff{ 1141 { 1142 Type: DiffTypeEdited, 1143 Name: "ParameterizedJob", 1144 Fields: []*FieldDiff{ 1145 { 1146 Type: DiffTypeEdited, 1147 Name: "Payload", 1148 Old: DispatchPayloadRequired, 1149 New: DispatchPayloadOptional, 1150 }, 1151 }, 1152 Objects: []*ObjectDiff{ 1153 { 1154 Type: DiffTypeNone, 1155 Name: "MetaOptional", 1156 Fields: []*FieldDiff{ 1157 { 1158 Type: DiffTypeNone, 1159 Name: "MetaOptional", 1160 Old: "foo", 1161 New: "foo", 1162 }, 1163 }, 1164 }, 1165 { 1166 Type: DiffTypeNone, 1167 Name: "MetaRequired", 1168 Fields: []*FieldDiff{ 1169 { 1170 Type: DiffTypeNone, 1171 Name: "MetaRequired", 1172 Old: "bar", 1173 New: "bar", 1174 }, 1175 }, 1176 }, 1177 }, 1178 }, 1179 }, 1180 }, 1181 }, 1182 } 1183 1184 for i, c := range cases { 1185 actual, err := c.Old.Diff(c.New, c.Contextual) 1186 if c.Error && err == nil { 1187 t.Fatalf("case %d: expected errored", i+1) 1188 } else if err != nil { 1189 if !c.Error { 1190 t.Fatalf("case %d: errored %#v", i+1, err) 1191 } else { 1192 continue 1193 } 1194 } 1195 1196 if !reflect.DeepEqual(actual, c.Expected) { 1197 t.Fatalf("case %d: got:\n%#v\n want:\n%#v\n", 1198 i+1, actual, c.Expected) 1199 } 1200 } 1201 } 1202 1203 func TestTaskGroupDiff(t *testing.T) { 1204 cases := []struct { 1205 Old, New *TaskGroup 1206 Expected *TaskGroupDiff 1207 Error bool 1208 Contextual bool 1209 }{ 1210 { 1211 Old: nil, 1212 New: nil, 1213 Expected: &TaskGroupDiff{ 1214 Type: DiffTypeNone, 1215 }, 1216 }, 1217 { 1218 // Primitive only that has different names 1219 Old: &TaskGroup{ 1220 Name: "foo", 1221 Count: 10, 1222 Meta: map[string]string{ 1223 "foo": "bar", 1224 }, 1225 }, 1226 New: &TaskGroup{ 1227 Name: "bar", 1228 Count: 10, 1229 Meta: map[string]string{ 1230 "foo": "bar", 1231 }, 1232 }, 1233 Error: true, 1234 }, 1235 { 1236 // Primitive only that is the same 1237 Old: &TaskGroup{ 1238 Name: "foo", 1239 Count: 10, 1240 Meta: map[string]string{ 1241 "foo": "bar", 1242 }, 1243 }, 1244 New: &TaskGroup{ 1245 Name: "foo", 1246 Count: 10, 1247 Meta: map[string]string{ 1248 "foo": "bar", 1249 }, 1250 }, 1251 Expected: &TaskGroupDiff{ 1252 Type: DiffTypeNone, 1253 Name: "foo", 1254 }, 1255 }, 1256 { 1257 // Primitive only that has diffs 1258 Old: &TaskGroup{ 1259 Name: "foo", 1260 Count: 10, 1261 Meta: map[string]string{ 1262 "foo": "bar", 1263 }, 1264 }, 1265 New: &TaskGroup{ 1266 Name: "foo", 1267 Count: 100, 1268 Meta: map[string]string{ 1269 "foo": "baz", 1270 }, 1271 }, 1272 Expected: &TaskGroupDiff{ 1273 Type: DiffTypeEdited, 1274 Name: "foo", 1275 Fields: []*FieldDiff{ 1276 { 1277 Type: DiffTypeEdited, 1278 Name: "Count", 1279 Old: "10", 1280 New: "100", 1281 }, 1282 { 1283 Type: DiffTypeEdited, 1284 Name: "Meta[foo]", 1285 Old: "bar", 1286 New: "baz", 1287 }, 1288 }, 1289 }, 1290 }, 1291 { 1292 // Map diff 1293 Old: &TaskGroup{ 1294 Meta: map[string]string{ 1295 "foo": "foo", 1296 "bar": "bar", 1297 }, 1298 }, 1299 New: &TaskGroup{ 1300 Meta: map[string]string{ 1301 "bar": "bar", 1302 "baz": "baz", 1303 }, 1304 }, 1305 Expected: &TaskGroupDiff{ 1306 Type: DiffTypeEdited, 1307 Fields: []*FieldDiff{ 1308 { 1309 Type: DiffTypeAdded, 1310 Name: "Meta[baz]", 1311 Old: "", 1312 New: "baz", 1313 }, 1314 { 1315 Type: DiffTypeDeleted, 1316 Name: "Meta[foo]", 1317 Old: "foo", 1318 New: "", 1319 }, 1320 }, 1321 }, 1322 }, 1323 { 1324 // Constraints edited 1325 Old: &TaskGroup{ 1326 Constraints: []*Constraint{ 1327 { 1328 LTarget: "foo", 1329 RTarget: "foo", 1330 Operand: "foo", 1331 str: "foo", 1332 }, 1333 { 1334 LTarget: "bar", 1335 RTarget: "bar", 1336 Operand: "bar", 1337 str: "bar", 1338 }, 1339 }, 1340 }, 1341 New: &TaskGroup{ 1342 Constraints: []*Constraint{ 1343 { 1344 LTarget: "foo", 1345 RTarget: "foo", 1346 Operand: "foo", 1347 str: "foo", 1348 }, 1349 { 1350 LTarget: "baz", 1351 RTarget: "baz", 1352 Operand: "baz", 1353 str: "baz", 1354 }, 1355 }, 1356 }, 1357 Expected: &TaskGroupDiff{ 1358 Type: DiffTypeEdited, 1359 Objects: []*ObjectDiff{ 1360 { 1361 Type: DiffTypeAdded, 1362 Name: "Constraint", 1363 Fields: []*FieldDiff{ 1364 { 1365 Type: DiffTypeAdded, 1366 Name: "LTarget", 1367 Old: "", 1368 New: "baz", 1369 }, 1370 { 1371 Type: DiffTypeAdded, 1372 Name: "Operand", 1373 Old: "", 1374 New: "baz", 1375 }, 1376 { 1377 Type: DiffTypeAdded, 1378 Name: "RTarget", 1379 Old: "", 1380 New: "baz", 1381 }, 1382 }, 1383 }, 1384 { 1385 Type: DiffTypeDeleted, 1386 Name: "Constraint", 1387 Fields: []*FieldDiff{ 1388 { 1389 Type: DiffTypeDeleted, 1390 Name: "LTarget", 1391 Old: "bar", 1392 New: "", 1393 }, 1394 { 1395 Type: DiffTypeDeleted, 1396 Name: "Operand", 1397 Old: "bar", 1398 New: "", 1399 }, 1400 { 1401 Type: DiffTypeDeleted, 1402 Name: "RTarget", 1403 Old: "bar", 1404 New: "", 1405 }, 1406 }, 1407 }, 1408 }, 1409 }, 1410 }, 1411 { 1412 // RestartPolicy added 1413 Old: &TaskGroup{}, 1414 New: &TaskGroup{ 1415 RestartPolicy: &RestartPolicy{ 1416 Attempts: 1, 1417 Interval: 1 * time.Second, 1418 Delay: 1 * time.Second, 1419 Mode: "fail", 1420 }, 1421 }, 1422 Expected: &TaskGroupDiff{ 1423 Type: DiffTypeEdited, 1424 Objects: []*ObjectDiff{ 1425 { 1426 Type: DiffTypeAdded, 1427 Name: "RestartPolicy", 1428 Fields: []*FieldDiff{ 1429 { 1430 Type: DiffTypeAdded, 1431 Name: "Attempts", 1432 Old: "", 1433 New: "1", 1434 }, 1435 { 1436 Type: DiffTypeAdded, 1437 Name: "Delay", 1438 Old: "", 1439 New: "1000000000", 1440 }, 1441 { 1442 Type: DiffTypeAdded, 1443 Name: "Interval", 1444 Old: "", 1445 New: "1000000000", 1446 }, 1447 { 1448 Type: DiffTypeAdded, 1449 Name: "Mode", 1450 Old: "", 1451 New: "fail", 1452 }, 1453 }, 1454 }, 1455 }, 1456 }, 1457 }, 1458 { 1459 // RestartPolicy deleted 1460 Old: &TaskGroup{ 1461 RestartPolicy: &RestartPolicy{ 1462 Attempts: 1, 1463 Interval: 1 * time.Second, 1464 Delay: 1 * time.Second, 1465 Mode: "fail", 1466 }, 1467 }, 1468 New: &TaskGroup{}, 1469 Expected: &TaskGroupDiff{ 1470 Type: DiffTypeEdited, 1471 Objects: []*ObjectDiff{ 1472 { 1473 Type: DiffTypeDeleted, 1474 Name: "RestartPolicy", 1475 Fields: []*FieldDiff{ 1476 { 1477 Type: DiffTypeDeleted, 1478 Name: "Attempts", 1479 Old: "1", 1480 New: "", 1481 }, 1482 { 1483 Type: DiffTypeDeleted, 1484 Name: "Delay", 1485 Old: "1000000000", 1486 New: "", 1487 }, 1488 { 1489 Type: DiffTypeDeleted, 1490 Name: "Interval", 1491 Old: "1000000000", 1492 New: "", 1493 }, 1494 { 1495 Type: DiffTypeDeleted, 1496 Name: "Mode", 1497 Old: "fail", 1498 New: "", 1499 }, 1500 }, 1501 }, 1502 }, 1503 }, 1504 }, 1505 { 1506 // RestartPolicy edited 1507 Old: &TaskGroup{ 1508 RestartPolicy: &RestartPolicy{ 1509 Attempts: 1, 1510 Interval: 1 * time.Second, 1511 Delay: 1 * time.Second, 1512 Mode: "fail", 1513 }, 1514 }, 1515 New: &TaskGroup{ 1516 RestartPolicy: &RestartPolicy{ 1517 Attempts: 2, 1518 Interval: 2 * time.Second, 1519 Delay: 2 * time.Second, 1520 Mode: "delay", 1521 }, 1522 }, 1523 Expected: &TaskGroupDiff{ 1524 Type: DiffTypeEdited, 1525 Objects: []*ObjectDiff{ 1526 { 1527 Type: DiffTypeEdited, 1528 Name: "RestartPolicy", 1529 Fields: []*FieldDiff{ 1530 { 1531 Type: DiffTypeEdited, 1532 Name: "Attempts", 1533 Old: "1", 1534 New: "2", 1535 }, 1536 { 1537 Type: DiffTypeEdited, 1538 Name: "Delay", 1539 Old: "1000000000", 1540 New: "2000000000", 1541 }, 1542 { 1543 Type: DiffTypeEdited, 1544 Name: "Interval", 1545 Old: "1000000000", 1546 New: "2000000000", 1547 }, 1548 { 1549 Type: DiffTypeEdited, 1550 Name: "Mode", 1551 Old: "fail", 1552 New: "delay", 1553 }, 1554 }, 1555 }, 1556 }, 1557 }, 1558 }, 1559 { 1560 // RestartPolicy edited with context 1561 Contextual: true, 1562 Old: &TaskGroup{ 1563 RestartPolicy: &RestartPolicy{ 1564 Attempts: 1, 1565 Interval: 1 * time.Second, 1566 Delay: 1 * time.Second, 1567 Mode: "fail", 1568 }, 1569 }, 1570 New: &TaskGroup{ 1571 RestartPolicy: &RestartPolicy{ 1572 Attempts: 2, 1573 Interval: 2 * time.Second, 1574 Delay: 1 * time.Second, 1575 Mode: "fail", 1576 }, 1577 }, 1578 Expected: &TaskGroupDiff{ 1579 Type: DiffTypeEdited, 1580 Objects: []*ObjectDiff{ 1581 { 1582 Type: DiffTypeEdited, 1583 Name: "RestartPolicy", 1584 Fields: []*FieldDiff{ 1585 { 1586 Type: DiffTypeEdited, 1587 Name: "Attempts", 1588 Old: "1", 1589 New: "2", 1590 }, 1591 { 1592 Type: DiffTypeNone, 1593 Name: "Delay", 1594 Old: "1000000000", 1595 New: "1000000000", 1596 }, 1597 { 1598 Type: DiffTypeEdited, 1599 Name: "Interval", 1600 Old: "1000000000", 1601 New: "2000000000", 1602 }, 1603 { 1604 Type: DiffTypeNone, 1605 Name: "Mode", 1606 Old: "fail", 1607 New: "fail", 1608 }, 1609 }, 1610 }, 1611 }, 1612 }, 1613 }, 1614 { 1615 // EphemeralDisk added 1616 Old: &TaskGroup{}, 1617 New: &TaskGroup{ 1618 EphemeralDisk: &EphemeralDisk{ 1619 Migrate: true, 1620 Sticky: true, 1621 SizeMB: 100, 1622 }, 1623 }, 1624 Expected: &TaskGroupDiff{ 1625 Type: DiffTypeEdited, 1626 Objects: []*ObjectDiff{ 1627 { 1628 Type: DiffTypeAdded, 1629 Name: "EphemeralDisk", 1630 Fields: []*FieldDiff{ 1631 { 1632 Type: DiffTypeAdded, 1633 Name: "Migrate", 1634 Old: "", 1635 New: "true", 1636 }, 1637 { 1638 Type: DiffTypeAdded, 1639 Name: "SizeMB", 1640 Old: "", 1641 New: "100", 1642 }, 1643 { 1644 Type: DiffTypeAdded, 1645 Name: "Sticky", 1646 Old: "", 1647 New: "true", 1648 }, 1649 }, 1650 }, 1651 }, 1652 }, 1653 }, 1654 { 1655 // EphemeralDisk deleted 1656 Old: &TaskGroup{ 1657 EphemeralDisk: &EphemeralDisk{ 1658 Migrate: true, 1659 Sticky: true, 1660 SizeMB: 100, 1661 }, 1662 }, 1663 New: &TaskGroup{}, 1664 Expected: &TaskGroupDiff{ 1665 Type: DiffTypeEdited, 1666 Objects: []*ObjectDiff{ 1667 { 1668 Type: DiffTypeDeleted, 1669 Name: "EphemeralDisk", 1670 Fields: []*FieldDiff{ 1671 { 1672 Type: DiffTypeDeleted, 1673 Name: "Migrate", 1674 Old: "true", 1675 New: "", 1676 }, 1677 { 1678 Type: DiffTypeDeleted, 1679 Name: "SizeMB", 1680 Old: "100", 1681 New: "", 1682 }, 1683 { 1684 Type: DiffTypeDeleted, 1685 Name: "Sticky", 1686 Old: "true", 1687 New: "", 1688 }, 1689 }, 1690 }, 1691 }, 1692 }, 1693 }, 1694 { 1695 // EphemeralDisk edited 1696 Old: &TaskGroup{ 1697 EphemeralDisk: &EphemeralDisk{ 1698 Migrate: true, 1699 Sticky: true, 1700 SizeMB: 150, 1701 }, 1702 }, 1703 New: &TaskGroup{ 1704 EphemeralDisk: &EphemeralDisk{ 1705 Migrate: false, 1706 Sticky: false, 1707 SizeMB: 90, 1708 }, 1709 }, 1710 Expected: &TaskGroupDiff{ 1711 Type: DiffTypeEdited, 1712 Objects: []*ObjectDiff{ 1713 { 1714 Type: DiffTypeEdited, 1715 Name: "EphemeralDisk", 1716 Fields: []*FieldDiff{ 1717 { 1718 Type: DiffTypeEdited, 1719 Name: "Migrate", 1720 Old: "true", 1721 New: "false", 1722 }, 1723 { 1724 Type: DiffTypeEdited, 1725 Name: "SizeMB", 1726 Old: "150", 1727 New: "90", 1728 }, 1729 1730 { 1731 Type: DiffTypeEdited, 1732 Name: "Sticky", 1733 Old: "true", 1734 New: "false", 1735 }, 1736 }, 1737 }, 1738 }, 1739 }, 1740 }, 1741 { 1742 // EphemeralDisk edited with context 1743 Contextual: true, 1744 Old: &TaskGroup{ 1745 EphemeralDisk: &EphemeralDisk{ 1746 Migrate: false, 1747 Sticky: false, 1748 SizeMB: 100, 1749 }, 1750 }, 1751 New: &TaskGroup{ 1752 EphemeralDisk: &EphemeralDisk{ 1753 Migrate: true, 1754 Sticky: true, 1755 SizeMB: 90, 1756 }, 1757 }, 1758 Expected: &TaskGroupDiff{ 1759 Type: DiffTypeEdited, 1760 Objects: []*ObjectDiff{ 1761 { 1762 Type: DiffTypeEdited, 1763 Name: "EphemeralDisk", 1764 Fields: []*FieldDiff{ 1765 { 1766 Type: DiffTypeEdited, 1767 Name: "Migrate", 1768 Old: "false", 1769 New: "true", 1770 }, 1771 { 1772 Type: DiffTypeEdited, 1773 Name: "SizeMB", 1774 Old: "100", 1775 New: "90", 1776 }, 1777 { 1778 Type: DiffTypeEdited, 1779 Name: "Sticky", 1780 Old: "false", 1781 New: "true", 1782 }, 1783 }, 1784 }, 1785 }, 1786 }, 1787 }, 1788 { 1789 // Tasks edited 1790 Old: &TaskGroup{ 1791 Tasks: []*Task{ 1792 { 1793 Name: "foo", 1794 Driver: "docker", 1795 }, 1796 { 1797 Name: "bar", 1798 Driver: "docker", 1799 }, 1800 { 1801 Name: "baz", 1802 Driver: "docker", 1803 }, 1804 }, 1805 }, 1806 New: &TaskGroup{ 1807 Tasks: []*Task{ 1808 { 1809 Name: "bar", 1810 Driver: "docker", 1811 }, 1812 { 1813 Name: "baz", 1814 Driver: "exec", 1815 }, 1816 { 1817 Name: "bam", 1818 Driver: "docker", 1819 }, 1820 }, 1821 }, 1822 Expected: &TaskGroupDiff{ 1823 Type: DiffTypeEdited, 1824 Tasks: []*TaskDiff{ 1825 { 1826 Type: DiffTypeAdded, 1827 Name: "bam", 1828 Fields: []*FieldDiff{ 1829 { 1830 Type: DiffTypeAdded, 1831 Name: "Driver", 1832 Old: "", 1833 New: "docker", 1834 }, 1835 { 1836 Type: DiffTypeAdded, 1837 Name: "KillTimeout", 1838 Old: "", 1839 New: "0", 1840 }, 1841 { 1842 Type: DiffTypeAdded, 1843 Name: "Leader", 1844 Old: "", 1845 New: "false", 1846 }, 1847 }, 1848 }, 1849 { 1850 Type: DiffTypeNone, 1851 Name: "bar", 1852 }, 1853 { 1854 Type: DiffTypeEdited, 1855 Name: "baz", 1856 Fields: []*FieldDiff{ 1857 { 1858 Type: DiffTypeEdited, 1859 Name: "Driver", 1860 Old: "docker", 1861 New: "exec", 1862 }, 1863 }, 1864 }, 1865 { 1866 Type: DiffTypeDeleted, 1867 Name: "foo", 1868 Fields: []*FieldDiff{ 1869 { 1870 Type: DiffTypeDeleted, 1871 Name: "Driver", 1872 Old: "docker", 1873 New: "", 1874 }, 1875 { 1876 Type: DiffTypeDeleted, 1877 Name: "KillTimeout", 1878 Old: "0", 1879 New: "", 1880 }, 1881 { 1882 Type: DiffTypeDeleted, 1883 Name: "Leader", 1884 Old: "false", 1885 New: "", 1886 }, 1887 }, 1888 }, 1889 }, 1890 }, 1891 }, 1892 } 1893 1894 for i, c := range cases { 1895 actual, err := c.Old.Diff(c.New, c.Contextual) 1896 if c.Error && err == nil { 1897 t.Fatalf("case %d: expected errored", i+1) 1898 } else if err != nil { 1899 if !c.Error { 1900 t.Fatalf("case %d: errored %#v", i+1, err) 1901 } else { 1902 continue 1903 } 1904 } 1905 1906 if !reflect.DeepEqual(actual, c.Expected) { 1907 t.Fatalf("case %d: got:\n%#v\n want:\n%#v\n", 1908 i+1, actual, c.Expected) 1909 } 1910 } 1911 } 1912 1913 func TestTaskDiff(t *testing.T) { 1914 cases := []struct { 1915 Name string 1916 Old, New *Task 1917 Expected *TaskDiff 1918 Error bool 1919 Contextual bool 1920 }{ 1921 { 1922 Name: "Empty", 1923 Old: nil, 1924 New: nil, 1925 Expected: &TaskDiff{ 1926 Type: DiffTypeNone, 1927 }, 1928 }, 1929 { 1930 Name: "Primitive only that has different names", 1931 Old: &Task{ 1932 Name: "foo", 1933 Meta: map[string]string{ 1934 "foo": "bar", 1935 }, 1936 }, 1937 New: &Task{ 1938 Name: "bar", 1939 Meta: map[string]string{ 1940 "foo": "bar", 1941 }, 1942 }, 1943 Error: true, 1944 }, 1945 { 1946 Name: "Primitive only that is the same", 1947 Old: &Task{ 1948 Name: "foo", 1949 Driver: "exec", 1950 User: "foo", 1951 Env: map[string]string{ 1952 "FOO": "bar", 1953 }, 1954 Meta: map[string]string{ 1955 "foo": "bar", 1956 }, 1957 KillTimeout: 1 * time.Second, 1958 Leader: true, 1959 }, 1960 New: &Task{ 1961 Name: "foo", 1962 Driver: "exec", 1963 User: "foo", 1964 Env: map[string]string{ 1965 "FOO": "bar", 1966 }, 1967 Meta: map[string]string{ 1968 "foo": "bar", 1969 }, 1970 KillTimeout: 1 * time.Second, 1971 Leader: true, 1972 }, 1973 Expected: &TaskDiff{ 1974 Type: DiffTypeNone, 1975 Name: "foo", 1976 }, 1977 }, 1978 { 1979 Name: "Primitive only that has diffs", 1980 Old: &Task{ 1981 Name: "foo", 1982 Driver: "exec", 1983 User: "foo", 1984 Env: map[string]string{ 1985 "FOO": "bar", 1986 }, 1987 Meta: map[string]string{ 1988 "foo": "bar", 1989 }, 1990 KillTimeout: 1 * time.Second, 1991 Leader: true, 1992 }, 1993 New: &Task{ 1994 Name: "foo", 1995 Driver: "docker", 1996 User: "bar", 1997 Env: map[string]string{ 1998 "FOO": "baz", 1999 }, 2000 Meta: map[string]string{ 2001 "foo": "baz", 2002 }, 2003 KillTimeout: 2 * time.Second, 2004 Leader: false, 2005 }, 2006 Expected: &TaskDiff{ 2007 Type: DiffTypeEdited, 2008 Name: "foo", 2009 Fields: []*FieldDiff{ 2010 { 2011 Type: DiffTypeEdited, 2012 Name: "Driver", 2013 Old: "exec", 2014 New: "docker", 2015 }, 2016 { 2017 Type: DiffTypeEdited, 2018 Name: "Env[FOO]", 2019 Old: "bar", 2020 New: "baz", 2021 }, 2022 { 2023 Type: DiffTypeEdited, 2024 Name: "KillTimeout", 2025 Old: "1000000000", 2026 New: "2000000000", 2027 }, 2028 { 2029 Type: DiffTypeEdited, 2030 Name: "Leader", 2031 Old: "true", 2032 New: "false", 2033 }, 2034 { 2035 Type: DiffTypeEdited, 2036 Name: "Meta[foo]", 2037 Old: "bar", 2038 New: "baz", 2039 }, 2040 { 2041 Type: DiffTypeEdited, 2042 Name: "User", 2043 Old: "foo", 2044 New: "bar", 2045 }, 2046 }, 2047 }, 2048 }, 2049 { 2050 Name: "Map diff", 2051 Old: &Task{ 2052 Meta: map[string]string{ 2053 "foo": "foo", 2054 "bar": "bar", 2055 }, 2056 Env: map[string]string{ 2057 "foo": "foo", 2058 "bar": "bar", 2059 }, 2060 }, 2061 New: &Task{ 2062 Meta: map[string]string{ 2063 "bar": "bar", 2064 "baz": "baz", 2065 }, 2066 Env: map[string]string{ 2067 "bar": "bar", 2068 "baz": "baz", 2069 }, 2070 }, 2071 Expected: &TaskDiff{ 2072 Type: DiffTypeEdited, 2073 Fields: []*FieldDiff{ 2074 { 2075 Type: DiffTypeAdded, 2076 Name: "Env[baz]", 2077 Old: "", 2078 New: "baz", 2079 }, 2080 { 2081 Type: DiffTypeDeleted, 2082 Name: "Env[foo]", 2083 Old: "foo", 2084 New: "", 2085 }, 2086 { 2087 Type: DiffTypeAdded, 2088 Name: "Meta[baz]", 2089 Old: "", 2090 New: "baz", 2091 }, 2092 { 2093 Type: DiffTypeDeleted, 2094 Name: "Meta[foo]", 2095 Old: "foo", 2096 New: "", 2097 }, 2098 }, 2099 }, 2100 }, 2101 { 2102 Name: "Constraints edited", 2103 Old: &Task{ 2104 Constraints: []*Constraint{ 2105 { 2106 LTarget: "foo", 2107 RTarget: "foo", 2108 Operand: "foo", 2109 str: "foo", 2110 }, 2111 { 2112 LTarget: "bar", 2113 RTarget: "bar", 2114 Operand: "bar", 2115 str: "bar", 2116 }, 2117 }, 2118 }, 2119 New: &Task{ 2120 Constraints: []*Constraint{ 2121 { 2122 LTarget: "foo", 2123 RTarget: "foo", 2124 Operand: "foo", 2125 str: "foo", 2126 }, 2127 { 2128 LTarget: "baz", 2129 RTarget: "baz", 2130 Operand: "baz", 2131 str: "baz", 2132 }, 2133 }, 2134 }, 2135 Expected: &TaskDiff{ 2136 Type: DiffTypeEdited, 2137 Objects: []*ObjectDiff{ 2138 { 2139 Type: DiffTypeAdded, 2140 Name: "Constraint", 2141 Fields: []*FieldDiff{ 2142 { 2143 Type: DiffTypeAdded, 2144 Name: "LTarget", 2145 Old: "", 2146 New: "baz", 2147 }, 2148 { 2149 Type: DiffTypeAdded, 2150 Name: "Operand", 2151 Old: "", 2152 New: "baz", 2153 }, 2154 { 2155 Type: DiffTypeAdded, 2156 Name: "RTarget", 2157 Old: "", 2158 New: "baz", 2159 }, 2160 }, 2161 }, 2162 { 2163 Type: DiffTypeDeleted, 2164 Name: "Constraint", 2165 Fields: []*FieldDiff{ 2166 { 2167 Type: DiffTypeDeleted, 2168 Name: "LTarget", 2169 Old: "bar", 2170 New: "", 2171 }, 2172 { 2173 Type: DiffTypeDeleted, 2174 Name: "Operand", 2175 Old: "bar", 2176 New: "", 2177 }, 2178 { 2179 Type: DiffTypeDeleted, 2180 Name: "RTarget", 2181 Old: "bar", 2182 New: "", 2183 }, 2184 }, 2185 }, 2186 }, 2187 }, 2188 }, 2189 { 2190 Name: "LogConfig added", 2191 Old: &Task{}, 2192 New: &Task{ 2193 LogConfig: &LogConfig{ 2194 MaxFiles: 1, 2195 MaxFileSizeMB: 10, 2196 }, 2197 }, 2198 Expected: &TaskDiff{ 2199 Type: DiffTypeEdited, 2200 Objects: []*ObjectDiff{ 2201 { 2202 Type: DiffTypeAdded, 2203 Name: "LogConfig", 2204 Fields: []*FieldDiff{ 2205 { 2206 Type: DiffTypeAdded, 2207 Name: "MaxFileSizeMB", 2208 Old: "", 2209 New: "10", 2210 }, 2211 { 2212 Type: DiffTypeAdded, 2213 Name: "MaxFiles", 2214 Old: "", 2215 New: "1", 2216 }, 2217 }, 2218 }, 2219 }, 2220 }, 2221 }, 2222 { 2223 Name: "LogConfig deleted", 2224 Old: &Task{ 2225 LogConfig: &LogConfig{ 2226 MaxFiles: 1, 2227 MaxFileSizeMB: 10, 2228 }, 2229 }, 2230 New: &Task{}, 2231 Expected: &TaskDiff{ 2232 Type: DiffTypeEdited, 2233 Objects: []*ObjectDiff{ 2234 { 2235 Type: DiffTypeDeleted, 2236 Name: "LogConfig", 2237 Fields: []*FieldDiff{ 2238 { 2239 Type: DiffTypeDeleted, 2240 Name: "MaxFileSizeMB", 2241 Old: "10", 2242 New: "", 2243 }, 2244 { 2245 Type: DiffTypeDeleted, 2246 Name: "MaxFiles", 2247 Old: "1", 2248 New: "", 2249 }, 2250 }, 2251 }, 2252 }, 2253 }, 2254 }, 2255 { 2256 Name: "LogConfig edited", 2257 Old: &Task{ 2258 LogConfig: &LogConfig{ 2259 MaxFiles: 1, 2260 MaxFileSizeMB: 10, 2261 }, 2262 }, 2263 New: &Task{ 2264 LogConfig: &LogConfig{ 2265 MaxFiles: 2, 2266 MaxFileSizeMB: 20, 2267 }, 2268 }, 2269 Expected: &TaskDiff{ 2270 Type: DiffTypeEdited, 2271 Objects: []*ObjectDiff{ 2272 { 2273 Type: DiffTypeEdited, 2274 Name: "LogConfig", 2275 Fields: []*FieldDiff{ 2276 { 2277 Type: DiffTypeEdited, 2278 Name: "MaxFileSizeMB", 2279 Old: "10", 2280 New: "20", 2281 }, 2282 { 2283 Type: DiffTypeEdited, 2284 Name: "MaxFiles", 2285 Old: "1", 2286 New: "2", 2287 }, 2288 }, 2289 }, 2290 }, 2291 }, 2292 }, 2293 { 2294 Name: "LogConfig edited with context", 2295 Contextual: true, 2296 Old: &Task{ 2297 LogConfig: &LogConfig{ 2298 MaxFiles: 1, 2299 MaxFileSizeMB: 10, 2300 }, 2301 }, 2302 New: &Task{ 2303 LogConfig: &LogConfig{ 2304 MaxFiles: 1, 2305 MaxFileSizeMB: 20, 2306 }, 2307 }, 2308 Expected: &TaskDiff{ 2309 Type: DiffTypeEdited, 2310 Objects: []*ObjectDiff{ 2311 { 2312 Type: DiffTypeEdited, 2313 Name: "LogConfig", 2314 Fields: []*FieldDiff{ 2315 { 2316 Type: DiffTypeEdited, 2317 Name: "MaxFileSizeMB", 2318 Old: "10", 2319 New: "20", 2320 }, 2321 { 2322 Type: DiffTypeNone, 2323 Name: "MaxFiles", 2324 Old: "1", 2325 New: "1", 2326 }, 2327 }, 2328 }, 2329 }, 2330 }, 2331 }, 2332 { 2333 Name: "Artifacts edited", 2334 Old: &Task{ 2335 Artifacts: []*TaskArtifact{ 2336 { 2337 GetterSource: "foo", 2338 GetterOptions: map[string]string{ 2339 "foo": "bar", 2340 }, 2341 RelativeDest: "foo", 2342 }, 2343 { 2344 GetterSource: "bar", 2345 GetterOptions: map[string]string{ 2346 "bar": "baz", 2347 }, 2348 RelativeDest: "bar", 2349 }, 2350 }, 2351 }, 2352 New: &Task{ 2353 Artifacts: []*TaskArtifact{ 2354 { 2355 GetterSource: "foo", 2356 GetterOptions: map[string]string{ 2357 "foo": "bar", 2358 }, 2359 RelativeDest: "foo", 2360 }, 2361 { 2362 GetterSource: "bam", 2363 GetterOptions: map[string]string{ 2364 "bam": "baz", 2365 }, 2366 RelativeDest: "bam", 2367 }, 2368 }, 2369 }, 2370 Expected: &TaskDiff{ 2371 Type: DiffTypeEdited, 2372 Objects: []*ObjectDiff{ 2373 { 2374 Type: DiffTypeAdded, 2375 Name: "Artifact", 2376 Fields: []*FieldDiff{ 2377 { 2378 Type: DiffTypeAdded, 2379 Name: "GetterOptions[bam]", 2380 Old: "", 2381 New: "baz", 2382 }, 2383 { 2384 Type: DiffTypeAdded, 2385 Name: "GetterSource", 2386 Old: "", 2387 New: "bam", 2388 }, 2389 { 2390 Type: DiffTypeAdded, 2391 Name: "RelativeDest", 2392 Old: "", 2393 New: "bam", 2394 }, 2395 }, 2396 }, 2397 { 2398 Type: DiffTypeDeleted, 2399 Name: "Artifact", 2400 Fields: []*FieldDiff{ 2401 { 2402 Type: DiffTypeDeleted, 2403 Name: "GetterOptions[bar]", 2404 Old: "baz", 2405 New: "", 2406 }, 2407 { 2408 Type: DiffTypeDeleted, 2409 Name: "GetterSource", 2410 Old: "bar", 2411 New: "", 2412 }, 2413 { 2414 Type: DiffTypeDeleted, 2415 Name: "RelativeDest", 2416 Old: "bar", 2417 New: "", 2418 }, 2419 }, 2420 }, 2421 }, 2422 }, 2423 }, 2424 { 2425 Name: "Resources edited (no networks)", 2426 Old: &Task{ 2427 Resources: &Resources{ 2428 CPU: 100, 2429 MemoryMB: 100, 2430 DiskMB: 100, 2431 IOPS: 100, 2432 }, 2433 }, 2434 New: &Task{ 2435 Resources: &Resources{ 2436 CPU: 200, 2437 MemoryMB: 200, 2438 DiskMB: 200, 2439 IOPS: 200, 2440 }, 2441 }, 2442 Expected: &TaskDiff{ 2443 Type: DiffTypeEdited, 2444 Objects: []*ObjectDiff{ 2445 { 2446 Type: DiffTypeEdited, 2447 Name: "Resources", 2448 Fields: []*FieldDiff{ 2449 { 2450 Type: DiffTypeEdited, 2451 Name: "CPU", 2452 Old: "100", 2453 New: "200", 2454 }, 2455 { 2456 Type: DiffTypeEdited, 2457 Name: "DiskMB", 2458 Old: "100", 2459 New: "200", 2460 }, 2461 { 2462 Type: DiffTypeEdited, 2463 Name: "IOPS", 2464 Old: "100", 2465 New: "200", 2466 }, 2467 { 2468 Type: DiffTypeEdited, 2469 Name: "MemoryMB", 2470 Old: "100", 2471 New: "200", 2472 }, 2473 }, 2474 }, 2475 }, 2476 }, 2477 }, 2478 { 2479 Name: "Resources edited (no networks) with context", 2480 Contextual: true, 2481 Old: &Task{ 2482 Resources: &Resources{ 2483 CPU: 100, 2484 MemoryMB: 100, 2485 DiskMB: 100, 2486 IOPS: 100, 2487 }, 2488 }, 2489 New: &Task{ 2490 Resources: &Resources{ 2491 CPU: 200, 2492 MemoryMB: 100, 2493 DiskMB: 200, 2494 IOPS: 100, 2495 }, 2496 }, 2497 Expected: &TaskDiff{ 2498 Type: DiffTypeEdited, 2499 Objects: []*ObjectDiff{ 2500 { 2501 Type: DiffTypeEdited, 2502 Name: "Resources", 2503 Fields: []*FieldDiff{ 2504 { 2505 Type: DiffTypeEdited, 2506 Name: "CPU", 2507 Old: "100", 2508 New: "200", 2509 }, 2510 { 2511 Type: DiffTypeEdited, 2512 Name: "DiskMB", 2513 Old: "100", 2514 New: "200", 2515 }, 2516 { 2517 Type: DiffTypeNone, 2518 Name: "IOPS", 2519 Old: "100", 2520 New: "100", 2521 }, 2522 { 2523 Type: DiffTypeNone, 2524 Name: "MemoryMB", 2525 Old: "100", 2526 New: "100", 2527 }, 2528 }, 2529 }, 2530 }, 2531 }, 2532 }, 2533 { 2534 Name: "Network Resources edited", 2535 Old: &Task{ 2536 Resources: &Resources{ 2537 Networks: []*NetworkResource{ 2538 { 2539 Device: "foo", 2540 CIDR: "foo", 2541 IP: "foo", 2542 MBits: 100, 2543 ReservedPorts: []Port{ 2544 { 2545 Label: "foo", 2546 Value: 80, 2547 }, 2548 }, 2549 DynamicPorts: []Port{ 2550 { 2551 Label: "bar", 2552 }, 2553 }, 2554 }, 2555 }, 2556 }, 2557 }, 2558 New: &Task{ 2559 Resources: &Resources{ 2560 Networks: []*NetworkResource{ 2561 { 2562 Device: "bar", 2563 CIDR: "bar", 2564 IP: "bar", 2565 MBits: 200, 2566 ReservedPorts: []Port{ 2567 { 2568 Label: "foo", 2569 Value: 81, 2570 }, 2571 }, 2572 DynamicPorts: []Port{ 2573 { 2574 Label: "baz", 2575 }, 2576 }, 2577 }, 2578 }, 2579 }, 2580 }, 2581 Expected: &TaskDiff{ 2582 Type: DiffTypeEdited, 2583 Objects: []*ObjectDiff{ 2584 { 2585 Type: DiffTypeEdited, 2586 Name: "Resources", 2587 Objects: []*ObjectDiff{ 2588 { 2589 Type: DiffTypeAdded, 2590 Name: "Network", 2591 Fields: []*FieldDiff{ 2592 { 2593 Type: DiffTypeAdded, 2594 Name: "MBits", 2595 Old: "", 2596 New: "200", 2597 }, 2598 }, 2599 Objects: []*ObjectDiff{ 2600 { 2601 Type: DiffTypeAdded, 2602 Name: "Static Port", 2603 Fields: []*FieldDiff{ 2604 { 2605 Type: DiffTypeAdded, 2606 Name: "Label", 2607 Old: "", 2608 New: "foo", 2609 }, 2610 { 2611 Type: DiffTypeAdded, 2612 Name: "Value", 2613 Old: "", 2614 New: "81", 2615 }, 2616 }, 2617 }, 2618 { 2619 Type: DiffTypeAdded, 2620 Name: "Dynamic Port", 2621 Fields: []*FieldDiff{ 2622 { 2623 Type: DiffTypeAdded, 2624 Name: "Label", 2625 Old: "", 2626 New: "baz", 2627 }, 2628 }, 2629 }, 2630 }, 2631 }, 2632 { 2633 Type: DiffTypeDeleted, 2634 Name: "Network", 2635 Fields: []*FieldDiff{ 2636 { 2637 Type: DiffTypeDeleted, 2638 Name: "MBits", 2639 Old: "100", 2640 New: "", 2641 }, 2642 }, 2643 Objects: []*ObjectDiff{ 2644 { 2645 Type: DiffTypeDeleted, 2646 Name: "Static Port", 2647 Fields: []*FieldDiff{ 2648 { 2649 Type: DiffTypeDeleted, 2650 Name: "Label", 2651 Old: "foo", 2652 New: "", 2653 }, 2654 { 2655 Type: DiffTypeDeleted, 2656 Name: "Value", 2657 Old: "80", 2658 New: "", 2659 }, 2660 }, 2661 }, 2662 { 2663 Type: DiffTypeDeleted, 2664 Name: "Dynamic Port", 2665 Fields: []*FieldDiff{ 2666 { 2667 Type: DiffTypeDeleted, 2668 Name: "Label", 2669 Old: "bar", 2670 New: "", 2671 }, 2672 }, 2673 }, 2674 }, 2675 }, 2676 }, 2677 }, 2678 }, 2679 }, 2680 }, 2681 { 2682 Name: "Config same", 2683 Old: &Task{ 2684 Config: map[string]interface{}{ 2685 "foo": 1, 2686 "bar": "bar", 2687 "bam": []string{"a", "b"}, 2688 "baz": map[string]int{ 2689 "a": 1, 2690 "b": 2, 2691 }, 2692 "boom": &Port{ 2693 Label: "boom_port", 2694 }, 2695 }, 2696 }, 2697 New: &Task{ 2698 Config: map[string]interface{}{ 2699 "foo": 1, 2700 "bar": "bar", 2701 "bam": []string{"a", "b"}, 2702 "baz": map[string]int{ 2703 "a": 1, 2704 "b": 2, 2705 }, 2706 "boom": &Port{ 2707 Label: "boom_port", 2708 }, 2709 }, 2710 }, 2711 Expected: &TaskDiff{ 2712 Type: DiffTypeNone, 2713 }, 2714 }, 2715 { 2716 Name: "Config edited", 2717 Old: &Task{ 2718 Config: map[string]interface{}{ 2719 "foo": 1, 2720 "bar": "baz", 2721 "bam": []string{"a", "b"}, 2722 "baz": map[string]int{ 2723 "a": 1, 2724 "b": 2, 2725 }, 2726 "boom": &Port{ 2727 Label: "boom_port", 2728 }, 2729 }, 2730 }, 2731 New: &Task{ 2732 Config: map[string]interface{}{ 2733 "foo": 2, 2734 "bar": "baz", 2735 "bam": []string{"a", "c", "d"}, 2736 "baz": map[string]int{ 2737 "b": 3, 2738 "c": 4, 2739 }, 2740 "boom": &Port{ 2741 Label: "boom_port2", 2742 }, 2743 }, 2744 }, 2745 Expected: &TaskDiff{ 2746 Type: DiffTypeEdited, 2747 Objects: []*ObjectDiff{ 2748 { 2749 Type: DiffTypeEdited, 2750 Name: "Config", 2751 Fields: []*FieldDiff{ 2752 { 2753 Type: DiffTypeEdited, 2754 Name: "bam[1]", 2755 Old: "b", 2756 New: "c", 2757 }, 2758 { 2759 Type: DiffTypeAdded, 2760 Name: "bam[2]", 2761 Old: "", 2762 New: "d", 2763 }, 2764 { 2765 Type: DiffTypeDeleted, 2766 Name: "baz[a]", 2767 Old: "1", 2768 New: "", 2769 }, 2770 { 2771 Type: DiffTypeEdited, 2772 Name: "baz[b]", 2773 Old: "2", 2774 New: "3", 2775 }, 2776 { 2777 Type: DiffTypeAdded, 2778 Name: "baz[c]", 2779 Old: "", 2780 New: "4", 2781 }, 2782 { 2783 Type: DiffTypeEdited, 2784 Name: "boom.Label", 2785 Old: "boom_port", 2786 New: "boom_port2", 2787 }, 2788 { 2789 Type: DiffTypeEdited, 2790 Name: "foo", 2791 Old: "1", 2792 New: "2", 2793 }, 2794 }, 2795 }, 2796 }, 2797 }, 2798 }, 2799 { 2800 Name: "Config edited with context", 2801 Contextual: true, 2802 Old: &Task{ 2803 Config: map[string]interface{}{ 2804 "foo": 1, 2805 "bar": "baz", 2806 "bam": []string{"a", "b"}, 2807 "baz": map[string]int{ 2808 "a": 1, 2809 "b": 2, 2810 }, 2811 "boom": &Port{ 2812 Label: "boom_port", 2813 }, 2814 }, 2815 }, 2816 New: &Task{ 2817 Config: map[string]interface{}{ 2818 "foo": 2, 2819 "bar": "baz", 2820 "bam": []string{"a", "c", "d"}, 2821 "baz": map[string]int{ 2822 "a": 1, 2823 "b": 2, 2824 }, 2825 "boom": &Port{ 2826 Label: "boom_port", 2827 }, 2828 }, 2829 }, 2830 Expected: &TaskDiff{ 2831 Type: DiffTypeEdited, 2832 Objects: []*ObjectDiff{ 2833 { 2834 Type: DiffTypeEdited, 2835 Name: "Config", 2836 Fields: []*FieldDiff{ 2837 { 2838 Type: DiffTypeNone, 2839 Name: "bam[0]", 2840 Old: "a", 2841 New: "a", 2842 }, 2843 { 2844 Type: DiffTypeEdited, 2845 Name: "bam[1]", 2846 Old: "b", 2847 New: "c", 2848 }, 2849 { 2850 Type: DiffTypeAdded, 2851 Name: "bam[2]", 2852 Old: "", 2853 New: "d", 2854 }, 2855 { 2856 Type: DiffTypeNone, 2857 Name: "bar", 2858 Old: "baz", 2859 New: "baz", 2860 }, 2861 { 2862 Type: DiffTypeNone, 2863 Name: "baz[a]", 2864 Old: "1", 2865 New: "1", 2866 }, 2867 { 2868 Type: DiffTypeNone, 2869 Name: "baz[b]", 2870 Old: "2", 2871 New: "2", 2872 }, 2873 { 2874 Type: DiffTypeNone, 2875 Name: "boom.Label", 2876 Old: "boom_port", 2877 New: "boom_port", 2878 }, 2879 { 2880 Type: DiffTypeNone, 2881 Name: "boom.Value", 2882 Old: "0", 2883 New: "0", 2884 }, 2885 { 2886 Type: DiffTypeEdited, 2887 Name: "foo", 2888 Old: "1", 2889 New: "2", 2890 }, 2891 }, 2892 }, 2893 }, 2894 }, 2895 }, 2896 { 2897 Name: "Services edited (no checks)", 2898 Old: &Task{ 2899 Services: []*Service{ 2900 { 2901 Name: "foo", 2902 PortLabel: "foo", 2903 }, 2904 { 2905 Name: "bar", 2906 PortLabel: "bar", 2907 }, 2908 { 2909 Name: "baz", 2910 PortLabel: "baz", 2911 }, 2912 }, 2913 }, 2914 New: &Task{ 2915 Services: []*Service{ 2916 { 2917 Name: "bar", 2918 PortLabel: "bar", 2919 }, 2920 { 2921 Name: "baz", 2922 PortLabel: "baz2", 2923 }, 2924 { 2925 Name: "bam", 2926 PortLabel: "bam", 2927 }, 2928 }, 2929 }, 2930 Expected: &TaskDiff{ 2931 Type: DiffTypeEdited, 2932 Objects: []*ObjectDiff{ 2933 { 2934 Type: DiffTypeEdited, 2935 Name: "Service", 2936 Fields: []*FieldDiff{ 2937 { 2938 Type: DiffTypeEdited, 2939 Name: "PortLabel", 2940 Old: "baz", 2941 New: "baz2", 2942 }, 2943 }, 2944 }, 2945 { 2946 Type: DiffTypeAdded, 2947 Name: "Service", 2948 Fields: []*FieldDiff{ 2949 { 2950 Type: DiffTypeAdded, 2951 Name: "Name", 2952 Old: "", 2953 New: "bam", 2954 }, 2955 { 2956 Type: DiffTypeAdded, 2957 Name: "PortLabel", 2958 Old: "", 2959 New: "bam", 2960 }, 2961 }, 2962 }, 2963 { 2964 Type: DiffTypeDeleted, 2965 Name: "Service", 2966 Fields: []*FieldDiff{ 2967 { 2968 Type: DiffTypeDeleted, 2969 Name: "Name", 2970 Old: "foo", 2971 New: "", 2972 }, 2973 { 2974 Type: DiffTypeDeleted, 2975 Name: "PortLabel", 2976 Old: "foo", 2977 New: "", 2978 }, 2979 }, 2980 }, 2981 }, 2982 }, 2983 }, 2984 { 2985 Name: "Services edited (no checks) with context", 2986 Contextual: true, 2987 Old: &Task{ 2988 Services: []*Service{ 2989 { 2990 Name: "foo", 2991 PortLabel: "foo", 2992 }, 2993 }, 2994 }, 2995 New: &Task{ 2996 Services: []*Service{ 2997 { 2998 Name: "foo", 2999 PortLabel: "bar", 3000 }, 3001 }, 3002 }, 3003 Expected: &TaskDiff{ 3004 Type: DiffTypeEdited, 3005 Objects: []*ObjectDiff{ 3006 { 3007 Type: DiffTypeEdited, 3008 Name: "Service", 3009 Fields: []*FieldDiff{ 3010 { 3011 Type: DiffTypeNone, 3012 Name: "Name", 3013 Old: "foo", 3014 New: "foo", 3015 }, 3016 { 3017 Type: DiffTypeEdited, 3018 Name: "PortLabel", 3019 Old: "foo", 3020 New: "bar", 3021 }, 3022 }, 3023 }, 3024 }, 3025 }, 3026 }, 3027 { 3028 Name: "Service Checks edited", 3029 Old: &Task{ 3030 Services: []*Service{ 3031 { 3032 Name: "foo", 3033 Checks: []*ServiceCheck{ 3034 { 3035 Name: "foo", 3036 Type: "http", 3037 Command: "foo", 3038 Args: []string{"foo"}, 3039 Path: "foo", 3040 Protocol: "http", 3041 Interval: 1 * time.Second, 3042 Timeout: 1 * time.Second, 3043 }, 3044 { 3045 Name: "bar", 3046 Type: "http", 3047 Command: "foo", 3048 Args: []string{"foo"}, 3049 Path: "foo", 3050 Protocol: "http", 3051 Interval: 1 * time.Second, 3052 Timeout: 1 * time.Second, 3053 }, 3054 { 3055 Name: "baz", 3056 Type: "http", 3057 Command: "foo", 3058 Args: []string{"foo"}, 3059 Path: "foo", 3060 Protocol: "http", 3061 Interval: 1 * time.Second, 3062 Timeout: 1 * time.Second, 3063 }, 3064 }, 3065 }, 3066 }, 3067 }, 3068 New: &Task{ 3069 Services: []*Service{ 3070 { 3071 Name: "foo", 3072 Checks: []*ServiceCheck{ 3073 { 3074 Name: "bar", 3075 Type: "http", 3076 Command: "foo", 3077 Args: []string{"foo"}, 3078 Path: "foo", 3079 Protocol: "http", 3080 Interval: 1 * time.Second, 3081 Timeout: 1 * time.Second, 3082 }, 3083 { 3084 Name: "baz", 3085 Type: "tcp", 3086 Command: "foo", 3087 Args: []string{"foo"}, 3088 Path: "foo", 3089 Protocol: "http", 3090 Interval: 1 * time.Second, 3091 Timeout: 1 * time.Second, 3092 }, 3093 { 3094 Name: "bam", 3095 Type: "http", 3096 Command: "foo", 3097 Args: []string{"foo"}, 3098 Path: "foo", 3099 Protocol: "http", 3100 Interval: 1 * time.Second, 3101 Timeout: 1 * time.Second, 3102 }, 3103 }, 3104 }, 3105 }, 3106 }, 3107 Expected: &TaskDiff{ 3108 Type: DiffTypeEdited, 3109 Objects: []*ObjectDiff{ 3110 { 3111 Type: DiffTypeEdited, 3112 Name: "Service", 3113 Objects: []*ObjectDiff{ 3114 { 3115 Type: DiffTypeEdited, 3116 Name: "Check", 3117 Fields: []*FieldDiff{ 3118 { 3119 Type: DiffTypeEdited, 3120 Name: "Type", 3121 Old: "http", 3122 New: "tcp", 3123 }, 3124 }, 3125 }, 3126 { 3127 Type: DiffTypeAdded, 3128 Name: "Check", 3129 Fields: []*FieldDiff{ 3130 { 3131 Type: DiffTypeAdded, 3132 Name: "Command", 3133 Old: "", 3134 New: "foo", 3135 }, 3136 { 3137 Type: DiffTypeAdded, 3138 Name: "Interval", 3139 Old: "", 3140 New: "1000000000", 3141 }, 3142 { 3143 Type: DiffTypeAdded, 3144 Name: "Name", 3145 Old: "", 3146 New: "bam", 3147 }, 3148 { 3149 Type: DiffTypeAdded, 3150 Name: "Path", 3151 Old: "", 3152 New: "foo", 3153 }, 3154 { 3155 Type: DiffTypeAdded, 3156 Name: "Protocol", 3157 Old: "", 3158 New: "http", 3159 }, 3160 { 3161 Type: DiffTypeAdded, 3162 Name: "TLSSkipVerify", 3163 Old: "", 3164 New: "false", 3165 }, 3166 { 3167 Type: DiffTypeAdded, 3168 Name: "Timeout", 3169 Old: "", 3170 New: "1000000000", 3171 }, 3172 { 3173 Type: DiffTypeAdded, 3174 Name: "Type", 3175 Old: "", 3176 New: "http", 3177 }, 3178 }, 3179 }, 3180 { 3181 Type: DiffTypeDeleted, 3182 Name: "Check", 3183 Fields: []*FieldDiff{ 3184 { 3185 Type: DiffTypeDeleted, 3186 Name: "Command", 3187 Old: "foo", 3188 New: "", 3189 }, 3190 { 3191 Type: DiffTypeDeleted, 3192 Name: "Interval", 3193 Old: "1000000000", 3194 New: "", 3195 }, 3196 { 3197 Type: DiffTypeDeleted, 3198 Name: "Name", 3199 Old: "foo", 3200 New: "", 3201 }, 3202 { 3203 Type: DiffTypeDeleted, 3204 Name: "Path", 3205 Old: "foo", 3206 New: "", 3207 }, 3208 { 3209 Type: DiffTypeDeleted, 3210 Name: "Protocol", 3211 Old: "http", 3212 New: "", 3213 }, 3214 { 3215 Type: DiffTypeDeleted, 3216 Name: "TLSSkipVerify", 3217 Old: "false", 3218 New: "", 3219 }, 3220 { 3221 Type: DiffTypeDeleted, 3222 Name: "Timeout", 3223 Old: "1000000000", 3224 New: "", 3225 }, 3226 { 3227 Type: DiffTypeDeleted, 3228 Name: "Type", 3229 Old: "http", 3230 New: "", 3231 }, 3232 }, 3233 }, 3234 }, 3235 }, 3236 }, 3237 }, 3238 }, 3239 { 3240 Name: "Service Checks edited with context", 3241 Contextual: true, 3242 Old: &Task{ 3243 Services: []*Service{ 3244 { 3245 Name: "foo", 3246 Checks: []*ServiceCheck{ 3247 { 3248 Name: "foo", 3249 Type: "http", 3250 Command: "foo", 3251 Args: []string{"foo"}, 3252 Path: "foo", 3253 Protocol: "http", 3254 Interval: 1 * time.Second, 3255 Timeout: 1 * time.Second, 3256 InitialStatus: "critical", 3257 }, 3258 }, 3259 }, 3260 }, 3261 }, 3262 New: &Task{ 3263 Services: []*Service{ 3264 { 3265 Name: "foo", 3266 Checks: []*ServiceCheck{ 3267 { 3268 Name: "foo", 3269 Type: "tcp", 3270 Command: "foo", 3271 Args: []string{"foo"}, 3272 Path: "foo", 3273 Protocol: "http", 3274 Interval: 1 * time.Second, 3275 Timeout: 1 * time.Second, 3276 InitialStatus: "passing", 3277 }, 3278 }, 3279 }, 3280 }, 3281 }, 3282 Expected: &TaskDiff{ 3283 Type: DiffTypeEdited, 3284 Objects: []*ObjectDiff{ 3285 { 3286 Type: DiffTypeEdited, 3287 Name: "Service", 3288 Fields: []*FieldDiff{ 3289 { 3290 Type: DiffTypeNone, 3291 Name: "Name", 3292 Old: "foo", 3293 New: "foo", 3294 }, 3295 { 3296 Type: DiffTypeNone, 3297 Name: "PortLabel", 3298 Old: "", 3299 New: "", 3300 }, 3301 }, 3302 Objects: []*ObjectDiff{ 3303 { 3304 Type: DiffTypeEdited, 3305 Name: "Check", 3306 Fields: []*FieldDiff{ 3307 { 3308 Type: DiffTypeNone, 3309 Name: "Command", 3310 Old: "foo", 3311 New: "foo", 3312 }, 3313 { 3314 Type: DiffTypeEdited, 3315 Name: "InitialStatus", 3316 Old: "critical", 3317 New: "passing", 3318 }, 3319 { 3320 Type: DiffTypeNone, 3321 Name: "Interval", 3322 Old: "1000000000", 3323 New: "1000000000", 3324 }, 3325 { 3326 Type: DiffTypeNone, 3327 Name: "Name", 3328 Old: "foo", 3329 New: "foo", 3330 }, 3331 { 3332 Type: DiffTypeNone, 3333 Name: "Path", 3334 Old: "foo", 3335 New: "foo", 3336 }, 3337 { 3338 Type: DiffTypeNone, 3339 Name: "PortLabel", 3340 Old: "", 3341 New: "", 3342 }, 3343 { 3344 Type: DiffTypeNone, 3345 Name: "Protocol", 3346 Old: "http", 3347 New: "http", 3348 }, 3349 { 3350 Type: DiffTypeNone, 3351 Name: "TLSSkipVerify", 3352 Old: "false", 3353 New: "false", 3354 }, 3355 { 3356 Type: DiffTypeNone, 3357 Name: "Timeout", 3358 Old: "1000000000", 3359 New: "1000000000", 3360 }, 3361 { 3362 Type: DiffTypeEdited, 3363 Name: "Type", 3364 Old: "http", 3365 New: "tcp", 3366 }, 3367 }, 3368 }, 3369 }, 3370 }, 3371 }, 3372 }, 3373 }, 3374 { 3375 Name: "Vault added", 3376 Old: &Task{}, 3377 New: &Task{ 3378 Vault: &Vault{ 3379 Policies: []string{"foo", "bar"}, 3380 Env: true, 3381 ChangeMode: "signal", 3382 ChangeSignal: "SIGUSR1", 3383 }, 3384 }, 3385 Expected: &TaskDiff{ 3386 Type: DiffTypeEdited, 3387 Objects: []*ObjectDiff{ 3388 { 3389 Type: DiffTypeAdded, 3390 Name: "Vault", 3391 Fields: []*FieldDiff{ 3392 { 3393 Type: DiffTypeAdded, 3394 Name: "ChangeMode", 3395 Old: "", 3396 New: "signal", 3397 }, 3398 { 3399 Type: DiffTypeAdded, 3400 Name: "ChangeSignal", 3401 Old: "", 3402 New: "SIGUSR1", 3403 }, 3404 { 3405 Type: DiffTypeAdded, 3406 Name: "Env", 3407 Old: "", 3408 New: "true", 3409 }, 3410 }, 3411 Objects: []*ObjectDiff{ 3412 { 3413 Type: DiffTypeAdded, 3414 Name: "Policies", 3415 Fields: []*FieldDiff{ 3416 { 3417 Type: DiffTypeAdded, 3418 Name: "Policies", 3419 Old: "", 3420 New: "bar", 3421 }, 3422 { 3423 Type: DiffTypeAdded, 3424 Name: "Policies", 3425 Old: "", 3426 New: "foo", 3427 }, 3428 }, 3429 }, 3430 }, 3431 }, 3432 }, 3433 }, 3434 }, 3435 { 3436 Name: "Vault deleted", 3437 Old: &Task{ 3438 Vault: &Vault{ 3439 Policies: []string{"foo", "bar"}, 3440 Env: true, 3441 ChangeMode: "signal", 3442 ChangeSignal: "SIGUSR1", 3443 }, 3444 }, 3445 New: &Task{}, 3446 Expected: &TaskDiff{ 3447 Type: DiffTypeEdited, 3448 Objects: []*ObjectDiff{ 3449 { 3450 Type: DiffTypeDeleted, 3451 Name: "Vault", 3452 Fields: []*FieldDiff{ 3453 { 3454 Type: DiffTypeDeleted, 3455 Name: "ChangeMode", 3456 Old: "signal", 3457 New: "", 3458 }, 3459 { 3460 Type: DiffTypeDeleted, 3461 Name: "ChangeSignal", 3462 Old: "SIGUSR1", 3463 New: "", 3464 }, 3465 { 3466 Type: DiffTypeDeleted, 3467 Name: "Env", 3468 Old: "true", 3469 New: "", 3470 }, 3471 }, 3472 Objects: []*ObjectDiff{ 3473 { 3474 Type: DiffTypeDeleted, 3475 Name: "Policies", 3476 Fields: []*FieldDiff{ 3477 { 3478 Type: DiffTypeDeleted, 3479 Name: "Policies", 3480 Old: "bar", 3481 New: "", 3482 }, 3483 { 3484 Type: DiffTypeDeleted, 3485 Name: "Policies", 3486 Old: "foo", 3487 New: "", 3488 }, 3489 }, 3490 }, 3491 }, 3492 }, 3493 }, 3494 }, 3495 }, 3496 { 3497 Name: "Vault edited", 3498 Old: &Task{ 3499 Vault: &Vault{ 3500 Policies: []string{"foo", "bar"}, 3501 Env: true, 3502 ChangeMode: "signal", 3503 ChangeSignal: "SIGUSR1", 3504 }, 3505 }, 3506 New: &Task{ 3507 Vault: &Vault{ 3508 Policies: []string{"bar", "baz"}, 3509 Env: false, 3510 ChangeMode: "restart", 3511 ChangeSignal: "foo", 3512 }, 3513 }, 3514 Expected: &TaskDiff{ 3515 Type: DiffTypeEdited, 3516 Objects: []*ObjectDiff{ 3517 { 3518 Type: DiffTypeEdited, 3519 Name: "Vault", 3520 Fields: []*FieldDiff{ 3521 { 3522 Type: DiffTypeEdited, 3523 Name: "ChangeMode", 3524 Old: "signal", 3525 New: "restart", 3526 }, 3527 { 3528 Type: DiffTypeEdited, 3529 Name: "ChangeSignal", 3530 Old: "SIGUSR1", 3531 New: "foo", 3532 }, 3533 { 3534 Type: DiffTypeEdited, 3535 Name: "Env", 3536 Old: "true", 3537 New: "false", 3538 }, 3539 }, 3540 Objects: []*ObjectDiff{ 3541 { 3542 Type: DiffTypeEdited, 3543 Name: "Policies", 3544 Fields: []*FieldDiff{ 3545 { 3546 Type: DiffTypeAdded, 3547 Name: "Policies", 3548 Old: "", 3549 New: "baz", 3550 }, 3551 { 3552 Type: DiffTypeDeleted, 3553 Name: "Policies", 3554 Old: "foo", 3555 New: "", 3556 }, 3557 }, 3558 }, 3559 }, 3560 }, 3561 }, 3562 }, 3563 }, 3564 { 3565 Name: "Vault edited with context", 3566 Contextual: true, 3567 Old: &Task{ 3568 Vault: &Vault{ 3569 Policies: []string{"foo", "bar"}, 3570 Env: true, 3571 ChangeMode: "signal", 3572 ChangeSignal: "SIGUSR1", 3573 }, 3574 }, 3575 New: &Task{ 3576 Vault: &Vault{ 3577 Policies: []string{"bar", "baz"}, 3578 Env: true, 3579 ChangeMode: "signal", 3580 ChangeSignal: "SIGUSR1", 3581 }, 3582 }, 3583 Expected: &TaskDiff{ 3584 Type: DiffTypeEdited, 3585 Objects: []*ObjectDiff{ 3586 { 3587 Type: DiffTypeEdited, 3588 Name: "Vault", 3589 Fields: []*FieldDiff{ 3590 { 3591 Type: DiffTypeNone, 3592 Name: "ChangeMode", 3593 Old: "signal", 3594 New: "signal", 3595 }, 3596 { 3597 Type: DiffTypeNone, 3598 Name: "ChangeSignal", 3599 Old: "SIGUSR1", 3600 New: "SIGUSR1", 3601 }, 3602 { 3603 Type: DiffTypeNone, 3604 Name: "Env", 3605 Old: "true", 3606 New: "true", 3607 }, 3608 }, 3609 Objects: []*ObjectDiff{ 3610 { 3611 Type: DiffTypeEdited, 3612 Name: "Policies", 3613 Fields: []*FieldDiff{ 3614 { 3615 Type: DiffTypeAdded, 3616 Name: "Policies", 3617 Old: "", 3618 New: "baz", 3619 }, 3620 { 3621 Type: DiffTypeNone, 3622 Name: "Policies", 3623 Old: "bar", 3624 New: "bar", 3625 }, 3626 { 3627 Type: DiffTypeDeleted, 3628 Name: "Policies", 3629 Old: "foo", 3630 New: "", 3631 }, 3632 }, 3633 }, 3634 }, 3635 }, 3636 }, 3637 }, 3638 }, 3639 { 3640 Name: "Template edited", 3641 Old: &Task{ 3642 Templates: []*Template{ 3643 { 3644 SourcePath: "foo", 3645 DestPath: "bar", 3646 EmbeddedTmpl: "baz", 3647 ChangeMode: "bam", 3648 ChangeSignal: "SIGHUP", 3649 Splay: 1, 3650 Perms: "0644", 3651 }, 3652 { 3653 SourcePath: "foo2", 3654 DestPath: "bar2", 3655 EmbeddedTmpl: "baz2", 3656 ChangeMode: "bam2", 3657 ChangeSignal: "SIGHUP2", 3658 Splay: 2, 3659 Perms: "0666", 3660 }, 3661 }, 3662 }, 3663 New: &Task{ 3664 Templates: []*Template{ 3665 { 3666 SourcePath: "foo", 3667 DestPath: "bar", 3668 EmbeddedTmpl: "baz", 3669 ChangeMode: "bam", 3670 ChangeSignal: "SIGHUP", 3671 Splay: 1, 3672 Perms: "0644", 3673 }, 3674 { 3675 SourcePath: "foo3", 3676 DestPath: "bar3", 3677 EmbeddedTmpl: "baz3", 3678 ChangeMode: "bam3", 3679 ChangeSignal: "SIGHUP3", 3680 Splay: 3, 3681 Perms: "0776", 3682 }, 3683 }, 3684 }, 3685 Expected: &TaskDiff{ 3686 Type: DiffTypeEdited, 3687 Objects: []*ObjectDiff{ 3688 { 3689 Type: DiffTypeAdded, 3690 Name: "Template", 3691 Fields: []*FieldDiff{ 3692 { 3693 Type: DiffTypeAdded, 3694 Name: "ChangeMode", 3695 Old: "", 3696 New: "bam3", 3697 }, 3698 { 3699 Type: DiffTypeAdded, 3700 Name: "ChangeSignal", 3701 Old: "", 3702 New: "SIGHUP3", 3703 }, 3704 { 3705 Type: DiffTypeAdded, 3706 Name: "DestPath", 3707 Old: "", 3708 New: "bar3", 3709 }, 3710 { 3711 Type: DiffTypeAdded, 3712 Name: "EmbeddedTmpl", 3713 Old: "", 3714 New: "baz3", 3715 }, 3716 { 3717 Type: DiffTypeAdded, 3718 Name: "Perms", 3719 Old: "", 3720 New: "0776", 3721 }, 3722 { 3723 Type: DiffTypeAdded, 3724 Name: "SourcePath", 3725 Old: "", 3726 New: "foo3", 3727 }, 3728 { 3729 Type: DiffTypeAdded, 3730 Name: "Splay", 3731 Old: "", 3732 New: "3", 3733 }, 3734 }, 3735 }, 3736 { 3737 Type: DiffTypeDeleted, 3738 Name: "Template", 3739 Fields: []*FieldDiff{ 3740 { 3741 Type: DiffTypeDeleted, 3742 Name: "ChangeMode", 3743 Old: "bam2", 3744 New: "", 3745 }, 3746 { 3747 Type: DiffTypeDeleted, 3748 Name: "ChangeSignal", 3749 Old: "SIGHUP2", 3750 New: "", 3751 }, 3752 { 3753 Type: DiffTypeDeleted, 3754 Name: "DestPath", 3755 Old: "bar2", 3756 New: "", 3757 }, 3758 { 3759 Type: DiffTypeDeleted, 3760 Name: "EmbeddedTmpl", 3761 Old: "baz2", 3762 New: "", 3763 }, 3764 { 3765 Type: DiffTypeDeleted, 3766 Name: "Perms", 3767 Old: "0666", 3768 New: "", 3769 }, 3770 { 3771 Type: DiffTypeDeleted, 3772 Name: "SourcePath", 3773 Old: "foo2", 3774 New: "", 3775 }, 3776 { 3777 Type: DiffTypeDeleted, 3778 Name: "Splay", 3779 Old: "2", 3780 New: "", 3781 }, 3782 }, 3783 }, 3784 }, 3785 }, 3786 }, 3787 { 3788 Name: "DispatchPayload added", 3789 Old: &Task{}, 3790 New: &Task{ 3791 DispatchPayload: &DispatchPayloadConfig{ 3792 File: "foo", 3793 }, 3794 }, 3795 Expected: &TaskDiff{ 3796 Type: DiffTypeEdited, 3797 Objects: []*ObjectDiff{ 3798 { 3799 Type: DiffTypeAdded, 3800 Name: "DispatchPayload", 3801 Fields: []*FieldDiff{ 3802 { 3803 Type: DiffTypeAdded, 3804 Name: "File", 3805 Old: "", 3806 New: "foo", 3807 }, 3808 }, 3809 }, 3810 }, 3811 }, 3812 }, 3813 { 3814 Name: "DispatchPayload deleted", 3815 Old: &Task{ 3816 DispatchPayload: &DispatchPayloadConfig{ 3817 File: "foo", 3818 }, 3819 }, 3820 New: &Task{}, 3821 Expected: &TaskDiff{ 3822 Type: DiffTypeEdited, 3823 Objects: []*ObjectDiff{ 3824 { 3825 Type: DiffTypeDeleted, 3826 Name: "DispatchPayload", 3827 Fields: []*FieldDiff{ 3828 { 3829 Type: DiffTypeDeleted, 3830 Name: "File", 3831 Old: "foo", 3832 New: "", 3833 }, 3834 }, 3835 }, 3836 }, 3837 }, 3838 }, 3839 { 3840 Name: "Dispatch payload edited", 3841 Old: &Task{ 3842 DispatchPayload: &DispatchPayloadConfig{ 3843 File: "foo", 3844 }, 3845 }, 3846 New: &Task{ 3847 DispatchPayload: &DispatchPayloadConfig{ 3848 File: "bar", 3849 }, 3850 }, 3851 Expected: &TaskDiff{ 3852 Type: DiffTypeEdited, 3853 Objects: []*ObjectDiff{ 3854 { 3855 Type: DiffTypeEdited, 3856 Name: "DispatchPayload", 3857 Fields: []*FieldDiff{ 3858 { 3859 Type: DiffTypeEdited, 3860 Name: "File", 3861 Old: "foo", 3862 New: "bar", 3863 }, 3864 }, 3865 }, 3866 }, 3867 }, 3868 }, 3869 { 3870 // Place holder for if more fields are added 3871 Name: "DispatchPayload edited with context", 3872 Contextual: true, 3873 Old: &Task{ 3874 DispatchPayload: &DispatchPayloadConfig{ 3875 File: "foo", 3876 }, 3877 }, 3878 New: &Task{ 3879 DispatchPayload: &DispatchPayloadConfig{ 3880 File: "bar", 3881 }, 3882 }, 3883 Expected: &TaskDiff{ 3884 Type: DiffTypeEdited, 3885 Objects: []*ObjectDiff{ 3886 { 3887 Type: DiffTypeEdited, 3888 Name: "DispatchPayload", 3889 Fields: []*FieldDiff{ 3890 { 3891 Type: DiffTypeEdited, 3892 Name: "File", 3893 Old: "foo", 3894 New: "bar", 3895 }, 3896 }, 3897 }, 3898 }, 3899 }, 3900 }, 3901 } 3902 3903 for i, c := range cases { 3904 t.Run(c.Name, func(t *testing.T) { 3905 actual, err := c.Old.Diff(c.New, c.Contextual) 3906 if c.Error && err == nil { 3907 t.Fatalf("case %d: expected errored", i+1) 3908 } else if err != nil { 3909 if !c.Error { 3910 t.Fatalf("case %d: errored %#v", i+1, err) 3911 } else { 3912 return 3913 } 3914 } 3915 3916 if !reflect.DeepEqual(actual, c.Expected) { 3917 t.Errorf("case %d: got:\n%#v\n want:\n%#v\n", 3918 i+1, actual, c.Expected) 3919 } 3920 }) 3921 } 3922 }