github.com/manicqin/nomad@v0.9.5/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: "Dispatched", 156 Old: "false", 157 New: "", 158 }, 159 { 160 Type: DiffTypeDeleted, 161 Name: "Meta[foo]", 162 Old: "bar", 163 New: "", 164 }, 165 { 166 Type: DiffTypeDeleted, 167 Name: "Name", 168 Old: "foo", 169 New: "", 170 }, 171 { 172 Type: DiffTypeDeleted, 173 Name: "Priority", 174 Old: "10", 175 New: "", 176 }, 177 { 178 Type: DiffTypeDeleted, 179 Name: "Region", 180 Old: "foo", 181 New: "", 182 }, 183 { 184 Type: DiffTypeDeleted, 185 Name: "Stop", 186 Old: "false", 187 New: "", 188 }, 189 { 190 Type: DiffTypeDeleted, 191 Name: "Type", 192 Old: "batch", 193 New: "", 194 }, 195 }, 196 }, 197 }, 198 { 199 // Primitive only added job 200 Old: nil, 201 New: &Job{ 202 Region: "foo", 203 ID: "foo", 204 Name: "foo", 205 Type: "batch", 206 Priority: 10, 207 AllAtOnce: true, 208 Meta: map[string]string{ 209 "foo": "bar", 210 }, 211 }, 212 Expected: &JobDiff{ 213 Type: DiffTypeAdded, 214 ID: "foo", 215 Fields: []*FieldDiff{ 216 { 217 Type: DiffTypeAdded, 218 Name: "AllAtOnce", 219 Old: "", 220 New: "true", 221 }, 222 { 223 Type: DiffTypeAdded, 224 Name: "Dispatched", 225 Old: "", 226 New: "false", 227 }, 228 { 229 Type: DiffTypeAdded, 230 Name: "Meta[foo]", 231 Old: "", 232 New: "bar", 233 }, 234 { 235 Type: DiffTypeAdded, 236 Name: "Name", 237 Old: "", 238 New: "foo", 239 }, 240 { 241 Type: DiffTypeAdded, 242 Name: "Priority", 243 Old: "", 244 New: "10", 245 }, 246 { 247 Type: DiffTypeAdded, 248 Name: "Region", 249 Old: "", 250 New: "foo", 251 }, 252 { 253 Type: DiffTypeAdded, 254 Name: "Stop", 255 Old: "", 256 New: "false", 257 }, 258 { 259 Type: DiffTypeAdded, 260 Name: "Type", 261 Old: "", 262 New: "batch", 263 }, 264 }, 265 }, 266 }, 267 { 268 // Map diff 269 Old: &Job{ 270 Meta: map[string]string{ 271 "foo": "foo", 272 "bar": "bar", 273 }, 274 }, 275 New: &Job{ 276 Meta: map[string]string{ 277 "bar": "bar", 278 "baz": "baz", 279 }, 280 }, 281 Expected: &JobDiff{ 282 Type: DiffTypeEdited, 283 Fields: []*FieldDiff{ 284 { 285 Type: DiffTypeAdded, 286 Name: "Meta[baz]", 287 Old: "", 288 New: "baz", 289 }, 290 { 291 Type: DiffTypeDeleted, 292 Name: "Meta[foo]", 293 Old: "foo", 294 New: "", 295 }, 296 }, 297 }, 298 }, 299 { 300 // Datacenter diff both added and removed 301 Old: &Job{ 302 Datacenters: []string{"foo", "bar"}, 303 }, 304 New: &Job{ 305 Datacenters: []string{"baz", "bar"}, 306 }, 307 Expected: &JobDiff{ 308 Type: DiffTypeEdited, 309 Objects: []*ObjectDiff{ 310 { 311 Type: DiffTypeEdited, 312 Name: "Datacenters", 313 Fields: []*FieldDiff{ 314 { 315 Type: DiffTypeAdded, 316 Name: "Datacenters", 317 Old: "", 318 New: "baz", 319 }, 320 { 321 Type: DiffTypeDeleted, 322 Name: "Datacenters", 323 Old: "foo", 324 New: "", 325 }, 326 }, 327 }, 328 }, 329 }, 330 }, 331 { 332 // Datacenter diff just added 333 Old: &Job{ 334 Datacenters: []string{"foo", "bar"}, 335 }, 336 New: &Job{ 337 Datacenters: []string{"foo", "bar", "baz"}, 338 }, 339 Expected: &JobDiff{ 340 Type: DiffTypeEdited, 341 Objects: []*ObjectDiff{ 342 { 343 Type: DiffTypeAdded, 344 Name: "Datacenters", 345 Fields: []*FieldDiff{ 346 { 347 Type: DiffTypeAdded, 348 Name: "Datacenters", 349 Old: "", 350 New: "baz", 351 }, 352 }, 353 }, 354 }, 355 }, 356 }, 357 { 358 // Datacenter diff just deleted 359 Old: &Job{ 360 Datacenters: []string{"foo", "bar"}, 361 }, 362 New: &Job{ 363 Datacenters: []string{"foo"}, 364 }, 365 Expected: &JobDiff{ 366 Type: DiffTypeEdited, 367 Objects: []*ObjectDiff{ 368 { 369 Type: DiffTypeDeleted, 370 Name: "Datacenters", 371 Fields: []*FieldDiff{ 372 { 373 Type: DiffTypeDeleted, 374 Name: "Datacenters", 375 Old: "bar", 376 New: "", 377 }, 378 }, 379 }, 380 }, 381 }, 382 }, 383 { 384 // Datacenter contextual no change 385 Contextual: true, 386 Old: &Job{ 387 Datacenters: []string{"foo", "bar"}, 388 }, 389 New: &Job{ 390 Datacenters: []string{"foo", "bar"}, 391 }, 392 Expected: &JobDiff{ 393 Type: DiffTypeNone, 394 }, 395 }, 396 { 397 // Datacenter contextual 398 Contextual: true, 399 Old: &Job{ 400 Datacenters: []string{"foo", "bar"}, 401 }, 402 New: &Job{ 403 Datacenters: []string{"foo", "bar", "baz"}, 404 }, 405 Expected: &JobDiff{ 406 Type: DiffTypeEdited, 407 Objects: []*ObjectDiff{ 408 { 409 Type: DiffTypeAdded, 410 Name: "Datacenters", 411 Fields: []*FieldDiff{ 412 { 413 Type: DiffTypeAdded, 414 Name: "Datacenters", 415 Old: "", 416 New: "baz", 417 }, 418 { 419 Type: DiffTypeNone, 420 Name: "Datacenters", 421 Old: "bar", 422 New: "bar", 423 }, 424 { 425 Type: DiffTypeNone, 426 Name: "Datacenters", 427 Old: "foo", 428 New: "foo", 429 }, 430 }, 431 }, 432 }, 433 }, 434 }, 435 { 436 // Periodic added 437 Old: &Job{}, 438 New: &Job{ 439 Periodic: &PeriodicConfig{ 440 Enabled: false, 441 Spec: "*/15 * * * * *", 442 SpecType: "foo", 443 ProhibitOverlap: false, 444 TimeZone: "Europe/Minsk", 445 }, 446 }, 447 Expected: &JobDiff{ 448 Type: DiffTypeEdited, 449 Objects: []*ObjectDiff{ 450 { 451 Type: DiffTypeAdded, 452 Name: "Periodic", 453 Fields: []*FieldDiff{ 454 { 455 Type: DiffTypeAdded, 456 Name: "Enabled", 457 Old: "", 458 New: "false", 459 }, 460 { 461 Type: DiffTypeAdded, 462 Name: "ProhibitOverlap", 463 Old: "", 464 New: "false", 465 }, 466 { 467 Type: DiffTypeAdded, 468 Name: "Spec", 469 Old: "", 470 New: "*/15 * * * * *", 471 }, 472 { 473 Type: DiffTypeAdded, 474 Name: "SpecType", 475 Old: "", 476 New: "foo", 477 }, 478 { 479 Type: DiffTypeAdded, 480 Name: "TimeZone", 481 Old: "", 482 New: "Europe/Minsk", 483 }, 484 }, 485 }, 486 }, 487 }, 488 }, 489 { 490 // Periodic deleted 491 Old: &Job{ 492 Periodic: &PeriodicConfig{ 493 Enabled: false, 494 Spec: "*/15 * * * * *", 495 SpecType: "foo", 496 ProhibitOverlap: false, 497 TimeZone: "Europe/Minsk", 498 }, 499 }, 500 New: &Job{}, 501 Expected: &JobDiff{ 502 Type: DiffTypeEdited, 503 Objects: []*ObjectDiff{ 504 { 505 Type: DiffTypeDeleted, 506 Name: "Periodic", 507 Fields: []*FieldDiff{ 508 { 509 Type: DiffTypeDeleted, 510 Name: "Enabled", 511 Old: "false", 512 New: "", 513 }, 514 { 515 Type: DiffTypeDeleted, 516 Name: "ProhibitOverlap", 517 Old: "false", 518 New: "", 519 }, 520 { 521 Type: DiffTypeDeleted, 522 Name: "Spec", 523 Old: "*/15 * * * * *", 524 New: "", 525 }, 526 { 527 Type: DiffTypeDeleted, 528 Name: "SpecType", 529 Old: "foo", 530 New: "", 531 }, 532 { 533 Type: DiffTypeDeleted, 534 Name: "TimeZone", 535 Old: "Europe/Minsk", 536 New: "", 537 }, 538 }, 539 }, 540 }, 541 }, 542 }, 543 { 544 // Periodic edited 545 Old: &Job{ 546 Periodic: &PeriodicConfig{ 547 Enabled: false, 548 Spec: "*/15 * * * * *", 549 SpecType: "foo", 550 ProhibitOverlap: false, 551 TimeZone: "Europe/Minsk", 552 }, 553 }, 554 New: &Job{ 555 Periodic: &PeriodicConfig{ 556 Enabled: true, 557 Spec: "* * * * * *", 558 SpecType: "cron", 559 ProhibitOverlap: true, 560 TimeZone: "America/Los_Angeles", 561 }, 562 }, 563 Expected: &JobDiff{ 564 Type: DiffTypeEdited, 565 Objects: []*ObjectDiff{ 566 { 567 Type: DiffTypeEdited, 568 Name: "Periodic", 569 Fields: []*FieldDiff{ 570 { 571 Type: DiffTypeEdited, 572 Name: "Enabled", 573 Old: "false", 574 New: "true", 575 }, 576 { 577 Type: DiffTypeEdited, 578 Name: "ProhibitOverlap", 579 Old: "false", 580 New: "true", 581 }, 582 { 583 Type: DiffTypeEdited, 584 Name: "Spec", 585 Old: "*/15 * * * * *", 586 New: "* * * * * *", 587 }, 588 { 589 Type: DiffTypeEdited, 590 Name: "SpecType", 591 Old: "foo", 592 New: "cron", 593 }, 594 { 595 Type: DiffTypeEdited, 596 Name: "TimeZone", 597 Old: "Europe/Minsk", 598 New: "America/Los_Angeles", 599 }, 600 }, 601 }, 602 }, 603 }, 604 }, 605 { 606 // Periodic edited with context 607 Contextual: true, 608 Old: &Job{ 609 Periodic: &PeriodicConfig{ 610 Enabled: false, 611 Spec: "*/15 * * * * *", 612 SpecType: "foo", 613 ProhibitOverlap: false, 614 TimeZone: "Europe/Minsk", 615 }, 616 }, 617 New: &Job{ 618 Periodic: &PeriodicConfig{ 619 Enabled: true, 620 Spec: "* * * * * *", 621 SpecType: "foo", 622 ProhibitOverlap: false, 623 TimeZone: "Europe/Minsk", 624 }, 625 }, 626 Expected: &JobDiff{ 627 Type: DiffTypeEdited, 628 Objects: []*ObjectDiff{ 629 { 630 Type: DiffTypeEdited, 631 Name: "Periodic", 632 Fields: []*FieldDiff{ 633 { 634 Type: DiffTypeEdited, 635 Name: "Enabled", 636 Old: "false", 637 New: "true", 638 }, 639 { 640 Type: DiffTypeNone, 641 Name: "ProhibitOverlap", 642 Old: "false", 643 New: "false", 644 }, 645 { 646 Type: DiffTypeEdited, 647 Name: "Spec", 648 Old: "*/15 * * * * *", 649 New: "* * * * * *", 650 }, 651 { 652 Type: DiffTypeNone, 653 Name: "SpecType", 654 Old: "foo", 655 New: "foo", 656 }, 657 { 658 Type: DiffTypeNone, 659 Name: "TimeZone", 660 Old: "Europe/Minsk", 661 New: "Europe/Minsk", 662 }, 663 }, 664 }, 665 }, 666 }, 667 }, 668 { 669 // Constraints edited 670 Old: &Job{ 671 Constraints: []*Constraint{ 672 { 673 LTarget: "foo", 674 RTarget: "foo", 675 Operand: "foo", 676 str: "foo", 677 }, 678 { 679 LTarget: "bar", 680 RTarget: "bar", 681 Operand: "bar", 682 str: "bar", 683 }, 684 }, 685 }, 686 New: &Job{ 687 Constraints: []*Constraint{ 688 { 689 LTarget: "foo", 690 RTarget: "foo", 691 Operand: "foo", 692 str: "foo", 693 }, 694 { 695 LTarget: "baz", 696 RTarget: "baz", 697 Operand: "baz", 698 str: "baz", 699 }, 700 }, 701 }, 702 Expected: &JobDiff{ 703 Type: DiffTypeEdited, 704 Objects: []*ObjectDiff{ 705 { 706 Type: DiffTypeAdded, 707 Name: "Constraint", 708 Fields: []*FieldDiff{ 709 { 710 Type: DiffTypeAdded, 711 Name: "LTarget", 712 Old: "", 713 New: "baz", 714 }, 715 { 716 Type: DiffTypeAdded, 717 Name: "Operand", 718 Old: "", 719 New: "baz", 720 }, 721 { 722 Type: DiffTypeAdded, 723 Name: "RTarget", 724 Old: "", 725 New: "baz", 726 }, 727 }, 728 }, 729 { 730 Type: DiffTypeDeleted, 731 Name: "Constraint", 732 Fields: []*FieldDiff{ 733 { 734 Type: DiffTypeDeleted, 735 Name: "LTarget", 736 Old: "bar", 737 New: "", 738 }, 739 { 740 Type: DiffTypeDeleted, 741 Name: "Operand", 742 Old: "bar", 743 New: "", 744 }, 745 { 746 Type: DiffTypeDeleted, 747 Name: "RTarget", 748 Old: "bar", 749 New: "", 750 }, 751 }, 752 }, 753 }, 754 }, 755 }, 756 { 757 // Affinities edited 758 Old: &Job{ 759 Affinities: []*Affinity{ 760 { 761 LTarget: "foo", 762 RTarget: "foo", 763 Operand: "foo", 764 Weight: 20, 765 str: "foo", 766 }, 767 { 768 LTarget: "bar", 769 RTarget: "bar", 770 Operand: "bar", 771 Weight: 20, 772 str: "bar", 773 }, 774 }, 775 }, 776 New: &Job{ 777 Affinities: []*Affinity{ 778 { 779 LTarget: "foo", 780 RTarget: "foo", 781 Operand: "foo", 782 Weight: 20, 783 str: "foo", 784 }, 785 { 786 LTarget: "baz", 787 RTarget: "baz", 788 Operand: "baz", 789 Weight: 20, 790 str: "baz", 791 }, 792 }, 793 }, 794 Expected: &JobDiff{ 795 Type: DiffTypeEdited, 796 Objects: []*ObjectDiff{ 797 { 798 Type: DiffTypeAdded, 799 Name: "Affinity", 800 Fields: []*FieldDiff{ 801 { 802 Type: DiffTypeAdded, 803 Name: "LTarget", 804 Old: "", 805 New: "baz", 806 }, 807 { 808 Type: DiffTypeAdded, 809 Name: "Operand", 810 Old: "", 811 New: "baz", 812 }, 813 { 814 Type: DiffTypeAdded, 815 Name: "RTarget", 816 Old: "", 817 New: "baz", 818 }, 819 { 820 Type: DiffTypeAdded, 821 Name: "Weight", 822 Old: "", 823 New: "20", 824 }, 825 }, 826 }, 827 { 828 Type: DiffTypeDeleted, 829 Name: "Affinity", 830 Fields: []*FieldDiff{ 831 { 832 Type: DiffTypeDeleted, 833 Name: "LTarget", 834 Old: "bar", 835 New: "", 836 }, 837 { 838 Type: DiffTypeDeleted, 839 Name: "Operand", 840 Old: "bar", 841 New: "", 842 }, 843 { 844 Type: DiffTypeDeleted, 845 Name: "RTarget", 846 Old: "bar", 847 New: "", 848 }, 849 { 850 Type: DiffTypeDeleted, 851 Name: "Weight", 852 Old: "20", 853 New: "", 854 }, 855 }, 856 }, 857 }, 858 }, 859 }, 860 { 861 // Task groups edited 862 Old: &Job{ 863 TaskGroups: []*TaskGroup{ 864 { 865 Name: "foo", 866 Count: 1, 867 }, 868 { 869 Name: "bar", 870 Count: 1, 871 }, 872 { 873 Name: "baz", 874 Count: 1, 875 }, 876 }, 877 }, 878 New: &Job{ 879 TaskGroups: []*TaskGroup{ 880 { 881 Name: "bar", 882 Count: 1, 883 }, 884 { 885 Name: "baz", 886 Count: 2, 887 }, 888 { 889 Name: "bam", 890 Count: 1, 891 }, 892 }, 893 }, 894 Expected: &JobDiff{ 895 Type: DiffTypeEdited, 896 TaskGroups: []*TaskGroupDiff{ 897 { 898 Type: DiffTypeAdded, 899 Name: "bam", 900 Fields: []*FieldDiff{ 901 { 902 Type: DiffTypeAdded, 903 Name: "Count", 904 Old: "", 905 New: "1", 906 }, 907 }, 908 }, 909 { 910 Type: DiffTypeNone, 911 Name: "bar", 912 }, 913 { 914 Type: DiffTypeEdited, 915 Name: "baz", 916 Fields: []*FieldDiff{ 917 { 918 Type: DiffTypeEdited, 919 Name: "Count", 920 Old: "1", 921 New: "2", 922 }, 923 }, 924 }, 925 { 926 Type: DiffTypeDeleted, 927 Name: "foo", 928 Fields: []*FieldDiff{ 929 { 930 Type: DiffTypeDeleted, 931 Name: "Count", 932 Old: "1", 933 New: "", 934 }, 935 }, 936 }, 937 }, 938 }, 939 }, 940 { 941 // Parameterized Job added 942 Old: &Job{}, 943 New: &Job{ 944 ParameterizedJob: &ParameterizedJobConfig{ 945 Payload: DispatchPayloadRequired, 946 MetaOptional: []string{"foo"}, 947 MetaRequired: []string{"bar"}, 948 }, 949 }, 950 Expected: &JobDiff{ 951 Type: DiffTypeEdited, 952 Objects: []*ObjectDiff{ 953 { 954 Type: DiffTypeAdded, 955 Name: "ParameterizedJob", 956 Fields: []*FieldDiff{ 957 { 958 Type: DiffTypeAdded, 959 Name: "Payload", 960 Old: "", 961 New: DispatchPayloadRequired, 962 }, 963 }, 964 Objects: []*ObjectDiff{ 965 { 966 Type: DiffTypeAdded, 967 Name: "MetaOptional", 968 Fields: []*FieldDiff{ 969 { 970 Type: DiffTypeAdded, 971 Name: "MetaOptional", 972 Old: "", 973 New: "foo", 974 }, 975 }, 976 }, 977 { 978 Type: DiffTypeAdded, 979 Name: "MetaRequired", 980 Fields: []*FieldDiff{ 981 { 982 Type: DiffTypeAdded, 983 Name: "MetaRequired", 984 Old: "", 985 New: "bar", 986 }, 987 }, 988 }, 989 }, 990 }, 991 }, 992 }, 993 }, 994 { 995 // Parameterized Job deleted 996 Old: &Job{ 997 ParameterizedJob: &ParameterizedJobConfig{ 998 Payload: DispatchPayloadRequired, 999 MetaOptional: []string{"foo"}, 1000 MetaRequired: []string{"bar"}, 1001 }, 1002 }, 1003 New: &Job{}, 1004 Expected: &JobDiff{ 1005 Type: DiffTypeEdited, 1006 Objects: []*ObjectDiff{ 1007 { 1008 Type: DiffTypeDeleted, 1009 Name: "ParameterizedJob", 1010 Fields: []*FieldDiff{ 1011 { 1012 Type: DiffTypeDeleted, 1013 Name: "Payload", 1014 Old: DispatchPayloadRequired, 1015 New: "", 1016 }, 1017 }, 1018 Objects: []*ObjectDiff{ 1019 { 1020 Type: DiffTypeDeleted, 1021 Name: "MetaOptional", 1022 Fields: []*FieldDiff{ 1023 { 1024 Type: DiffTypeDeleted, 1025 Name: "MetaOptional", 1026 Old: "foo", 1027 New: "", 1028 }, 1029 }, 1030 }, 1031 { 1032 Type: DiffTypeDeleted, 1033 Name: "MetaRequired", 1034 Fields: []*FieldDiff{ 1035 { 1036 Type: DiffTypeDeleted, 1037 Name: "MetaRequired", 1038 Old: "bar", 1039 New: "", 1040 }, 1041 }, 1042 }, 1043 }, 1044 }, 1045 }, 1046 }, 1047 }, 1048 { 1049 // Parameterized Job edited 1050 Old: &Job{ 1051 ParameterizedJob: &ParameterizedJobConfig{ 1052 Payload: DispatchPayloadRequired, 1053 MetaOptional: []string{"foo"}, 1054 MetaRequired: []string{"bar"}, 1055 }, 1056 }, 1057 New: &Job{ 1058 ParameterizedJob: &ParameterizedJobConfig{ 1059 Payload: DispatchPayloadOptional, 1060 MetaOptional: []string{"bam"}, 1061 MetaRequired: []string{"bang"}, 1062 }, 1063 }, 1064 Expected: &JobDiff{ 1065 Type: DiffTypeEdited, 1066 Objects: []*ObjectDiff{ 1067 { 1068 Type: DiffTypeEdited, 1069 Name: "ParameterizedJob", 1070 Fields: []*FieldDiff{ 1071 { 1072 Type: DiffTypeEdited, 1073 Name: "Payload", 1074 Old: DispatchPayloadRequired, 1075 New: DispatchPayloadOptional, 1076 }, 1077 }, 1078 Objects: []*ObjectDiff{ 1079 { 1080 Type: DiffTypeEdited, 1081 Name: "MetaOptional", 1082 Fields: []*FieldDiff{ 1083 { 1084 Type: DiffTypeAdded, 1085 Name: "MetaOptional", 1086 Old: "", 1087 New: "bam", 1088 }, 1089 { 1090 Type: DiffTypeDeleted, 1091 Name: "MetaOptional", 1092 Old: "foo", 1093 New: "", 1094 }, 1095 }, 1096 }, 1097 { 1098 Type: DiffTypeEdited, 1099 Name: "MetaRequired", 1100 Fields: []*FieldDiff{ 1101 { 1102 Type: DiffTypeAdded, 1103 Name: "MetaRequired", 1104 Old: "", 1105 New: "bang", 1106 }, 1107 { 1108 Type: DiffTypeDeleted, 1109 Name: "MetaRequired", 1110 Old: "bar", 1111 New: "", 1112 }, 1113 }, 1114 }, 1115 }, 1116 }, 1117 }, 1118 }, 1119 }, 1120 { 1121 // Parameterized Job edited with context 1122 Contextual: true, 1123 Old: &Job{ 1124 ParameterizedJob: &ParameterizedJobConfig{ 1125 Payload: DispatchPayloadRequired, 1126 MetaOptional: []string{"foo"}, 1127 MetaRequired: []string{"bar"}, 1128 }, 1129 }, 1130 New: &Job{ 1131 ParameterizedJob: &ParameterizedJobConfig{ 1132 Payload: DispatchPayloadOptional, 1133 MetaOptional: []string{"foo"}, 1134 MetaRequired: []string{"bar"}, 1135 }, 1136 }, 1137 Expected: &JobDiff{ 1138 Type: DiffTypeEdited, 1139 Objects: []*ObjectDiff{ 1140 { 1141 Type: DiffTypeEdited, 1142 Name: "ParameterizedJob", 1143 Fields: []*FieldDiff{ 1144 { 1145 Type: DiffTypeEdited, 1146 Name: "Payload", 1147 Old: DispatchPayloadRequired, 1148 New: DispatchPayloadOptional, 1149 }, 1150 }, 1151 Objects: []*ObjectDiff{ 1152 { 1153 Type: DiffTypeNone, 1154 Name: "MetaOptional", 1155 Fields: []*FieldDiff{ 1156 { 1157 Type: DiffTypeNone, 1158 Name: "MetaOptional", 1159 Old: "foo", 1160 New: "foo", 1161 }, 1162 }, 1163 }, 1164 { 1165 Type: DiffTypeNone, 1166 Name: "MetaRequired", 1167 Fields: []*FieldDiff{ 1168 { 1169 Type: DiffTypeNone, 1170 Name: "MetaRequired", 1171 Old: "bar", 1172 New: "bar", 1173 }, 1174 }, 1175 }, 1176 }, 1177 }, 1178 }, 1179 }, 1180 }, 1181 } 1182 1183 for i, c := range cases { 1184 actual, err := c.Old.Diff(c.New, c.Contextual) 1185 if c.Error && err == nil { 1186 t.Fatalf("case %d: expected errored", i+1) 1187 } else if err != nil { 1188 if !c.Error { 1189 t.Fatalf("case %d: errored %#v", i+1, err) 1190 } else { 1191 continue 1192 } 1193 } 1194 1195 if !reflect.DeepEqual(actual, c.Expected) { 1196 t.Fatalf("case %d: got:\n%#v\n want:\n%#v\n", 1197 i+1, actual, c.Expected) 1198 } 1199 } 1200 } 1201 1202 func TestTaskGroupDiff(t *testing.T) { 1203 cases := []struct { 1204 Old, New *TaskGroup 1205 Expected *TaskGroupDiff 1206 Error bool 1207 Contextual bool 1208 }{ 1209 { 1210 Old: nil, 1211 New: nil, 1212 Expected: &TaskGroupDiff{ 1213 Type: DiffTypeNone, 1214 }, 1215 }, 1216 { 1217 // Primitive only that has different names 1218 Old: &TaskGroup{ 1219 Name: "foo", 1220 Count: 10, 1221 Meta: map[string]string{ 1222 "foo": "bar", 1223 }, 1224 }, 1225 New: &TaskGroup{ 1226 Name: "bar", 1227 Count: 10, 1228 Meta: map[string]string{ 1229 "foo": "bar", 1230 }, 1231 }, 1232 Error: true, 1233 }, 1234 { 1235 // Primitive only that is the same 1236 Old: &TaskGroup{ 1237 Name: "foo", 1238 Count: 10, 1239 Meta: map[string]string{ 1240 "foo": "bar", 1241 }, 1242 }, 1243 New: &TaskGroup{ 1244 Name: "foo", 1245 Count: 10, 1246 Meta: map[string]string{ 1247 "foo": "bar", 1248 }, 1249 }, 1250 Expected: &TaskGroupDiff{ 1251 Type: DiffTypeNone, 1252 Name: "foo", 1253 }, 1254 }, 1255 { 1256 // Primitive only that has diffs 1257 Old: &TaskGroup{ 1258 Name: "foo", 1259 Count: 10, 1260 Meta: map[string]string{ 1261 "foo": "bar", 1262 }, 1263 }, 1264 New: &TaskGroup{ 1265 Name: "foo", 1266 Count: 100, 1267 Meta: map[string]string{ 1268 "foo": "baz", 1269 }, 1270 }, 1271 Expected: &TaskGroupDiff{ 1272 Type: DiffTypeEdited, 1273 Name: "foo", 1274 Fields: []*FieldDiff{ 1275 { 1276 Type: DiffTypeEdited, 1277 Name: "Count", 1278 Old: "10", 1279 New: "100", 1280 }, 1281 { 1282 Type: DiffTypeEdited, 1283 Name: "Meta[foo]", 1284 Old: "bar", 1285 New: "baz", 1286 }, 1287 }, 1288 }, 1289 }, 1290 { 1291 // Map diff 1292 Old: &TaskGroup{ 1293 Meta: map[string]string{ 1294 "foo": "foo", 1295 "bar": "bar", 1296 }, 1297 }, 1298 New: &TaskGroup{ 1299 Meta: map[string]string{ 1300 "bar": "bar", 1301 "baz": "baz", 1302 }, 1303 }, 1304 Expected: &TaskGroupDiff{ 1305 Type: DiffTypeEdited, 1306 Fields: []*FieldDiff{ 1307 { 1308 Type: DiffTypeAdded, 1309 Name: "Meta[baz]", 1310 Old: "", 1311 New: "baz", 1312 }, 1313 { 1314 Type: DiffTypeDeleted, 1315 Name: "Meta[foo]", 1316 Old: "foo", 1317 New: "", 1318 }, 1319 }, 1320 }, 1321 }, 1322 { 1323 // Constraints edited 1324 Old: &TaskGroup{ 1325 Constraints: []*Constraint{ 1326 { 1327 LTarget: "foo", 1328 RTarget: "foo", 1329 Operand: "foo", 1330 str: "foo", 1331 }, 1332 { 1333 LTarget: "bar", 1334 RTarget: "bar", 1335 Operand: "bar", 1336 str: "bar", 1337 }, 1338 }, 1339 }, 1340 New: &TaskGroup{ 1341 Constraints: []*Constraint{ 1342 { 1343 LTarget: "foo", 1344 RTarget: "foo", 1345 Operand: "foo", 1346 str: "foo", 1347 }, 1348 { 1349 LTarget: "baz", 1350 RTarget: "baz", 1351 Operand: "baz", 1352 str: "baz", 1353 }, 1354 }, 1355 }, 1356 Expected: &TaskGroupDiff{ 1357 Type: DiffTypeEdited, 1358 Objects: []*ObjectDiff{ 1359 { 1360 Type: DiffTypeAdded, 1361 Name: "Constraint", 1362 Fields: []*FieldDiff{ 1363 { 1364 Type: DiffTypeAdded, 1365 Name: "LTarget", 1366 Old: "", 1367 New: "baz", 1368 }, 1369 { 1370 Type: DiffTypeAdded, 1371 Name: "Operand", 1372 Old: "", 1373 New: "baz", 1374 }, 1375 { 1376 Type: DiffTypeAdded, 1377 Name: "RTarget", 1378 Old: "", 1379 New: "baz", 1380 }, 1381 }, 1382 }, 1383 { 1384 Type: DiffTypeDeleted, 1385 Name: "Constraint", 1386 Fields: []*FieldDiff{ 1387 { 1388 Type: DiffTypeDeleted, 1389 Name: "LTarget", 1390 Old: "bar", 1391 New: "", 1392 }, 1393 { 1394 Type: DiffTypeDeleted, 1395 Name: "Operand", 1396 Old: "bar", 1397 New: "", 1398 }, 1399 { 1400 Type: DiffTypeDeleted, 1401 Name: "RTarget", 1402 Old: "bar", 1403 New: "", 1404 }, 1405 }, 1406 }, 1407 }, 1408 }, 1409 }, 1410 { 1411 // Affinities edited 1412 Old: &TaskGroup{ 1413 Affinities: []*Affinity{ 1414 { 1415 LTarget: "foo", 1416 RTarget: "foo", 1417 Operand: "foo", 1418 Weight: 20, 1419 str: "foo", 1420 }, 1421 { 1422 LTarget: "bar", 1423 RTarget: "bar", 1424 Operand: "bar", 1425 Weight: 20, 1426 str: "bar", 1427 }, 1428 }, 1429 }, 1430 New: &TaskGroup{ 1431 Affinities: []*Affinity{ 1432 { 1433 LTarget: "foo", 1434 RTarget: "foo", 1435 Operand: "foo", 1436 Weight: 20, 1437 str: "foo", 1438 }, 1439 { 1440 LTarget: "baz", 1441 RTarget: "baz", 1442 Operand: "baz", 1443 Weight: 20, 1444 str: "baz", 1445 }, 1446 }, 1447 }, 1448 Expected: &TaskGroupDiff{ 1449 Type: DiffTypeEdited, 1450 Objects: []*ObjectDiff{ 1451 { 1452 Type: DiffTypeAdded, 1453 Name: "Affinity", 1454 Fields: []*FieldDiff{ 1455 { 1456 Type: DiffTypeAdded, 1457 Name: "LTarget", 1458 Old: "", 1459 New: "baz", 1460 }, 1461 { 1462 Type: DiffTypeAdded, 1463 Name: "Operand", 1464 Old: "", 1465 New: "baz", 1466 }, 1467 { 1468 Type: DiffTypeAdded, 1469 Name: "RTarget", 1470 Old: "", 1471 New: "baz", 1472 }, 1473 { 1474 Type: DiffTypeAdded, 1475 Name: "Weight", 1476 Old: "", 1477 New: "20", 1478 }, 1479 }, 1480 }, 1481 { 1482 Type: DiffTypeDeleted, 1483 Name: "Affinity", 1484 Fields: []*FieldDiff{ 1485 { 1486 Type: DiffTypeDeleted, 1487 Name: "LTarget", 1488 Old: "bar", 1489 New: "", 1490 }, 1491 { 1492 Type: DiffTypeDeleted, 1493 Name: "Operand", 1494 Old: "bar", 1495 New: "", 1496 }, 1497 { 1498 Type: DiffTypeDeleted, 1499 Name: "RTarget", 1500 Old: "bar", 1501 New: "", 1502 }, 1503 { 1504 Type: DiffTypeDeleted, 1505 Name: "Weight", 1506 Old: "20", 1507 New: "", 1508 }, 1509 }, 1510 }, 1511 }, 1512 }, 1513 }, 1514 { 1515 // RestartPolicy added 1516 Old: &TaskGroup{}, 1517 New: &TaskGroup{ 1518 RestartPolicy: &RestartPolicy{ 1519 Attempts: 1, 1520 Interval: 1 * time.Second, 1521 Delay: 1 * time.Second, 1522 Mode: "fail", 1523 }, 1524 }, 1525 Expected: &TaskGroupDiff{ 1526 Type: DiffTypeEdited, 1527 Objects: []*ObjectDiff{ 1528 { 1529 Type: DiffTypeAdded, 1530 Name: "RestartPolicy", 1531 Fields: []*FieldDiff{ 1532 { 1533 Type: DiffTypeAdded, 1534 Name: "Attempts", 1535 Old: "", 1536 New: "1", 1537 }, 1538 { 1539 Type: DiffTypeAdded, 1540 Name: "Delay", 1541 Old: "", 1542 New: "1000000000", 1543 }, 1544 { 1545 Type: DiffTypeAdded, 1546 Name: "Interval", 1547 Old: "", 1548 New: "1000000000", 1549 }, 1550 { 1551 Type: DiffTypeAdded, 1552 Name: "Mode", 1553 Old: "", 1554 New: "fail", 1555 }, 1556 }, 1557 }, 1558 }, 1559 }, 1560 }, 1561 { 1562 // RestartPolicy deleted 1563 Old: &TaskGroup{ 1564 RestartPolicy: &RestartPolicy{ 1565 Attempts: 1, 1566 Interval: 1 * time.Second, 1567 Delay: 1 * time.Second, 1568 Mode: "fail", 1569 }, 1570 }, 1571 New: &TaskGroup{}, 1572 Expected: &TaskGroupDiff{ 1573 Type: DiffTypeEdited, 1574 Objects: []*ObjectDiff{ 1575 { 1576 Type: DiffTypeDeleted, 1577 Name: "RestartPolicy", 1578 Fields: []*FieldDiff{ 1579 { 1580 Type: DiffTypeDeleted, 1581 Name: "Attempts", 1582 Old: "1", 1583 New: "", 1584 }, 1585 { 1586 Type: DiffTypeDeleted, 1587 Name: "Delay", 1588 Old: "1000000000", 1589 New: "", 1590 }, 1591 { 1592 Type: DiffTypeDeleted, 1593 Name: "Interval", 1594 Old: "1000000000", 1595 New: "", 1596 }, 1597 { 1598 Type: DiffTypeDeleted, 1599 Name: "Mode", 1600 Old: "fail", 1601 New: "", 1602 }, 1603 }, 1604 }, 1605 }, 1606 }, 1607 }, 1608 { 1609 // RestartPolicy edited 1610 Old: &TaskGroup{ 1611 RestartPolicy: &RestartPolicy{ 1612 Attempts: 1, 1613 Interval: 1 * time.Second, 1614 Delay: 1 * time.Second, 1615 Mode: "fail", 1616 }, 1617 }, 1618 New: &TaskGroup{ 1619 RestartPolicy: &RestartPolicy{ 1620 Attempts: 2, 1621 Interval: 2 * time.Second, 1622 Delay: 2 * time.Second, 1623 Mode: "delay", 1624 }, 1625 }, 1626 Expected: &TaskGroupDiff{ 1627 Type: DiffTypeEdited, 1628 Objects: []*ObjectDiff{ 1629 { 1630 Type: DiffTypeEdited, 1631 Name: "RestartPolicy", 1632 Fields: []*FieldDiff{ 1633 { 1634 Type: DiffTypeEdited, 1635 Name: "Attempts", 1636 Old: "1", 1637 New: "2", 1638 }, 1639 { 1640 Type: DiffTypeEdited, 1641 Name: "Delay", 1642 Old: "1000000000", 1643 New: "2000000000", 1644 }, 1645 { 1646 Type: DiffTypeEdited, 1647 Name: "Interval", 1648 Old: "1000000000", 1649 New: "2000000000", 1650 }, 1651 { 1652 Type: DiffTypeEdited, 1653 Name: "Mode", 1654 Old: "fail", 1655 New: "delay", 1656 }, 1657 }, 1658 }, 1659 }, 1660 }, 1661 }, 1662 { 1663 // RestartPolicy edited with context 1664 Contextual: true, 1665 Old: &TaskGroup{ 1666 RestartPolicy: &RestartPolicy{ 1667 Attempts: 1, 1668 Interval: 1 * time.Second, 1669 Delay: 1 * time.Second, 1670 Mode: "fail", 1671 }, 1672 }, 1673 New: &TaskGroup{ 1674 RestartPolicy: &RestartPolicy{ 1675 Attempts: 2, 1676 Interval: 2 * time.Second, 1677 Delay: 1 * time.Second, 1678 Mode: "fail", 1679 }, 1680 }, 1681 Expected: &TaskGroupDiff{ 1682 Type: DiffTypeEdited, 1683 Objects: []*ObjectDiff{ 1684 { 1685 Type: DiffTypeEdited, 1686 Name: "RestartPolicy", 1687 Fields: []*FieldDiff{ 1688 { 1689 Type: DiffTypeEdited, 1690 Name: "Attempts", 1691 Old: "1", 1692 New: "2", 1693 }, 1694 { 1695 Type: DiffTypeNone, 1696 Name: "Delay", 1697 Old: "1000000000", 1698 New: "1000000000", 1699 }, 1700 { 1701 Type: DiffTypeEdited, 1702 Name: "Interval", 1703 Old: "1000000000", 1704 New: "2000000000", 1705 }, 1706 { 1707 Type: DiffTypeNone, 1708 Name: "Mode", 1709 Old: "fail", 1710 New: "fail", 1711 }, 1712 }, 1713 }, 1714 }, 1715 }, 1716 }, 1717 { 1718 // ReschedulePolicy added 1719 Old: &TaskGroup{}, 1720 New: &TaskGroup{ 1721 ReschedulePolicy: &ReschedulePolicy{ 1722 Attempts: 1, 1723 Interval: 15 * time.Second, 1724 Delay: 5 * time.Second, 1725 MaxDelay: 20 * time.Second, 1726 DelayFunction: "exponential", 1727 Unlimited: false, 1728 }, 1729 }, 1730 Expected: &TaskGroupDiff{ 1731 Type: DiffTypeEdited, 1732 Objects: []*ObjectDiff{ 1733 { 1734 Type: DiffTypeAdded, 1735 Name: "ReschedulePolicy", 1736 Fields: []*FieldDiff{ 1737 { 1738 Type: DiffTypeAdded, 1739 Name: "Attempts", 1740 Old: "", 1741 New: "1", 1742 }, 1743 { 1744 Type: DiffTypeAdded, 1745 Name: "Delay", 1746 Old: "", 1747 New: "5000000000", 1748 }, 1749 { 1750 Type: DiffTypeAdded, 1751 Name: "DelayFunction", 1752 Old: "", 1753 New: "exponential", 1754 }, 1755 { 1756 Type: DiffTypeAdded, 1757 Name: "Interval", 1758 Old: "", 1759 New: "15000000000", 1760 }, 1761 { 1762 Type: DiffTypeAdded, 1763 Name: "MaxDelay", 1764 Old: "", 1765 New: "20000000000", 1766 }, 1767 { 1768 Type: DiffTypeAdded, 1769 Name: "Unlimited", 1770 Old: "", 1771 New: "false", 1772 }, 1773 }, 1774 }, 1775 }, 1776 }, 1777 }, 1778 { 1779 // ReschedulePolicy deleted 1780 Old: &TaskGroup{ 1781 ReschedulePolicy: &ReschedulePolicy{ 1782 Attempts: 1, 1783 Interval: 15 * time.Second, 1784 Delay: 5 * time.Second, 1785 MaxDelay: 20 * time.Second, 1786 DelayFunction: "exponential", 1787 Unlimited: false, 1788 }, 1789 }, 1790 New: &TaskGroup{}, 1791 Expected: &TaskGroupDiff{ 1792 Type: DiffTypeEdited, 1793 Objects: []*ObjectDiff{ 1794 { 1795 Type: DiffTypeDeleted, 1796 Name: "ReschedulePolicy", 1797 Fields: []*FieldDiff{ 1798 { 1799 Type: DiffTypeDeleted, 1800 Name: "Attempts", 1801 Old: "1", 1802 New: "", 1803 }, 1804 { 1805 Type: DiffTypeDeleted, 1806 Name: "Delay", 1807 Old: "5000000000", 1808 New: "", 1809 }, 1810 { 1811 Type: DiffTypeDeleted, 1812 Name: "DelayFunction", 1813 Old: "exponential", 1814 New: "", 1815 }, 1816 { 1817 Type: DiffTypeDeleted, 1818 Name: "Interval", 1819 Old: "15000000000", 1820 New: "", 1821 }, 1822 { 1823 Type: DiffTypeDeleted, 1824 Name: "MaxDelay", 1825 Old: "20000000000", 1826 New: "", 1827 }, 1828 { 1829 Type: DiffTypeDeleted, 1830 Name: "Unlimited", 1831 Old: "false", 1832 New: "", 1833 }, 1834 }, 1835 }, 1836 }, 1837 }, 1838 }, 1839 { 1840 // ReschedulePolicy edited 1841 Old: &TaskGroup{ 1842 ReschedulePolicy: &ReschedulePolicy{ 1843 Attempts: 1, 1844 Interval: 1 * time.Second, 1845 DelayFunction: "exponential", 1846 Delay: 20 * time.Second, 1847 MaxDelay: 1 * time.Minute, 1848 Unlimited: false, 1849 }, 1850 }, 1851 New: &TaskGroup{ 1852 ReschedulePolicy: &ReschedulePolicy{ 1853 Attempts: 2, 1854 Interval: 2 * time.Second, 1855 DelayFunction: "constant", 1856 Delay: 30 * time.Second, 1857 MaxDelay: 1 * time.Minute, 1858 Unlimited: true, 1859 }, 1860 }, 1861 Expected: &TaskGroupDiff{ 1862 Type: DiffTypeEdited, 1863 Objects: []*ObjectDiff{ 1864 { 1865 Type: DiffTypeEdited, 1866 Name: "ReschedulePolicy", 1867 Fields: []*FieldDiff{ 1868 { 1869 Type: DiffTypeEdited, 1870 Name: "Attempts", 1871 Old: "1", 1872 New: "2", 1873 }, 1874 { 1875 Type: DiffTypeEdited, 1876 Name: "Delay", 1877 Old: "20000000000", 1878 New: "30000000000", 1879 }, 1880 { 1881 Type: DiffTypeEdited, 1882 Name: "DelayFunction", 1883 Old: "exponential", 1884 New: "constant", 1885 }, 1886 { 1887 Type: DiffTypeEdited, 1888 Name: "Interval", 1889 Old: "1000000000", 1890 New: "2000000000", 1891 }, 1892 { 1893 Type: DiffTypeEdited, 1894 Name: "Unlimited", 1895 Old: "false", 1896 New: "true", 1897 }, 1898 }, 1899 }, 1900 }, 1901 }, 1902 }, { 1903 // ReschedulePolicy edited with context 1904 Contextual: true, 1905 Old: &TaskGroup{ 1906 ReschedulePolicy: &ReschedulePolicy{ 1907 Attempts: 1, 1908 Interval: 1 * time.Second, 1909 }, 1910 }, 1911 New: &TaskGroup{ 1912 ReschedulePolicy: &ReschedulePolicy{ 1913 Attempts: 1, 1914 Interval: 2 * time.Second, 1915 }, 1916 }, 1917 Expected: &TaskGroupDiff{ 1918 Type: DiffTypeEdited, 1919 Objects: []*ObjectDiff{ 1920 { 1921 Type: DiffTypeEdited, 1922 Name: "ReschedulePolicy", 1923 Fields: []*FieldDiff{ 1924 { 1925 Type: DiffTypeNone, 1926 Name: "Attempts", 1927 Old: "1", 1928 New: "1", 1929 }, 1930 { 1931 Type: DiffTypeNone, 1932 Name: "Delay", 1933 Old: "0", 1934 New: "0", 1935 }, 1936 { 1937 Type: DiffTypeNone, 1938 Name: "DelayFunction", 1939 Old: "", 1940 New: "", 1941 }, 1942 { 1943 Type: DiffTypeEdited, 1944 Name: "Interval", 1945 Old: "1000000000", 1946 New: "2000000000", 1947 }, 1948 { 1949 Type: DiffTypeNone, 1950 Name: "MaxDelay", 1951 Old: "0", 1952 New: "0", 1953 }, 1954 { 1955 Type: DiffTypeNone, 1956 Name: "Unlimited", 1957 Old: "false", 1958 New: "false", 1959 }, 1960 }, 1961 }, 1962 }, 1963 }, 1964 }, 1965 { 1966 // Update strategy deleted 1967 Old: &TaskGroup{ 1968 Update: &UpdateStrategy{ 1969 AutoRevert: true, 1970 }, 1971 }, 1972 New: &TaskGroup{}, 1973 Expected: &TaskGroupDiff{ 1974 Type: DiffTypeEdited, 1975 Objects: []*ObjectDiff{ 1976 { 1977 Type: DiffTypeDeleted, 1978 Name: "Update", 1979 Fields: []*FieldDiff{ 1980 { 1981 Type: DiffTypeDeleted, 1982 Name: "AutoPromote", 1983 Old: "false", 1984 New: "", 1985 }, 1986 { 1987 Type: DiffTypeDeleted, 1988 Name: "AutoRevert", 1989 Old: "true", 1990 New: "", 1991 }, 1992 { 1993 Type: DiffTypeDeleted, 1994 Name: "Canary", 1995 Old: "0", 1996 New: "", 1997 }, 1998 { 1999 Type: DiffTypeDeleted, 2000 Name: "HealthyDeadline", 2001 Old: "0", 2002 New: "", 2003 }, 2004 { 2005 Type: DiffTypeDeleted, 2006 Name: "MaxParallel", 2007 Old: "0", 2008 New: "", 2009 }, 2010 { 2011 Type: DiffTypeDeleted, 2012 Name: "MinHealthyTime", 2013 Old: "0", 2014 New: "", 2015 }, 2016 { 2017 Type: DiffTypeDeleted, 2018 Name: "ProgressDeadline", 2019 Old: "0", 2020 New: "", 2021 }, 2022 }, 2023 }, 2024 }, 2025 }, 2026 }, 2027 { 2028 // Update strategy added 2029 Old: &TaskGroup{}, 2030 New: &TaskGroup{ 2031 Update: &UpdateStrategy{ 2032 AutoRevert: true, 2033 }, 2034 }, 2035 Expected: &TaskGroupDiff{ 2036 Type: DiffTypeEdited, 2037 Objects: []*ObjectDiff{ 2038 { 2039 Type: DiffTypeAdded, 2040 Name: "Update", 2041 Fields: []*FieldDiff{ 2042 { 2043 Type: DiffTypeAdded, 2044 Name: "AutoPromote", 2045 Old: "", 2046 New: "false", 2047 }, 2048 { 2049 Type: DiffTypeAdded, 2050 Name: "AutoRevert", 2051 Old: "", 2052 New: "true", 2053 }, 2054 { 2055 Type: DiffTypeAdded, 2056 Name: "Canary", 2057 Old: "", 2058 New: "0", 2059 }, 2060 { 2061 Type: DiffTypeAdded, 2062 Name: "HealthyDeadline", 2063 Old: "", 2064 New: "0", 2065 }, 2066 { 2067 Type: DiffTypeAdded, 2068 Name: "MaxParallel", 2069 Old: "", 2070 New: "0", 2071 }, 2072 { 2073 Type: DiffTypeAdded, 2074 Name: "MinHealthyTime", 2075 Old: "", 2076 New: "0", 2077 }, 2078 { 2079 Type: DiffTypeAdded, 2080 Name: "ProgressDeadline", 2081 Old: "", 2082 New: "0", 2083 }, 2084 }, 2085 }, 2086 }, 2087 }, 2088 }, 2089 { 2090 // Update strategy edited 2091 Old: &TaskGroup{ 2092 Update: &UpdateStrategy{ 2093 MaxParallel: 5, 2094 HealthCheck: "foo", 2095 MinHealthyTime: 1 * time.Second, 2096 HealthyDeadline: 30 * time.Second, 2097 ProgressDeadline: 29 * time.Second, 2098 AutoRevert: true, 2099 AutoPromote: true, 2100 Canary: 2, 2101 }, 2102 }, 2103 New: &TaskGroup{ 2104 Update: &UpdateStrategy{ 2105 MaxParallel: 7, 2106 HealthCheck: "bar", 2107 MinHealthyTime: 2 * time.Second, 2108 HealthyDeadline: 31 * time.Second, 2109 ProgressDeadline: 32 * time.Second, 2110 AutoRevert: false, 2111 AutoPromote: false, 2112 Canary: 1, 2113 }, 2114 }, 2115 Expected: &TaskGroupDiff{ 2116 Type: DiffTypeEdited, 2117 Objects: []*ObjectDiff{ 2118 { 2119 Type: DiffTypeEdited, 2120 Name: "Update", 2121 Fields: []*FieldDiff{ 2122 { 2123 Type: DiffTypeEdited, 2124 Name: "AutoPromote", 2125 Old: "true", 2126 New: "false", 2127 }, 2128 { 2129 Type: DiffTypeEdited, 2130 Name: "AutoRevert", 2131 Old: "true", 2132 New: "false", 2133 }, 2134 { 2135 Type: DiffTypeEdited, 2136 Name: "Canary", 2137 Old: "2", 2138 New: "1", 2139 }, 2140 { 2141 Type: DiffTypeEdited, 2142 Name: "HealthCheck", 2143 Old: "foo", 2144 New: "bar", 2145 }, 2146 { 2147 Type: DiffTypeEdited, 2148 Name: "HealthyDeadline", 2149 Old: "30000000000", 2150 New: "31000000000", 2151 }, 2152 { 2153 Type: DiffTypeEdited, 2154 Name: "MaxParallel", 2155 Old: "5", 2156 New: "7", 2157 }, 2158 { 2159 Type: DiffTypeEdited, 2160 Name: "MinHealthyTime", 2161 Old: "1000000000", 2162 New: "2000000000", 2163 }, 2164 { 2165 Type: DiffTypeEdited, 2166 Name: "ProgressDeadline", 2167 Old: "29000000000", 2168 New: "32000000000", 2169 }, 2170 }, 2171 }, 2172 }, 2173 }, 2174 }, 2175 { 2176 // Update strategy edited with context 2177 Contextual: true, 2178 Old: &TaskGroup{ 2179 Update: &UpdateStrategy{ 2180 MaxParallel: 5, 2181 HealthCheck: "foo", 2182 MinHealthyTime: 1 * time.Second, 2183 HealthyDeadline: 30 * time.Second, 2184 ProgressDeadline: 30 * time.Second, 2185 AutoRevert: true, 2186 AutoPromote: true, 2187 Canary: 2, 2188 }, 2189 }, 2190 New: &TaskGroup{ 2191 Update: &UpdateStrategy{ 2192 MaxParallel: 7, 2193 HealthCheck: "foo", 2194 MinHealthyTime: 1 * time.Second, 2195 HealthyDeadline: 30 * time.Second, 2196 ProgressDeadline: 30 * time.Second, 2197 AutoRevert: true, 2198 AutoPromote: true, 2199 Canary: 2, 2200 }, 2201 }, 2202 Expected: &TaskGroupDiff{ 2203 Type: DiffTypeEdited, 2204 Objects: []*ObjectDiff{ 2205 { 2206 Type: DiffTypeEdited, 2207 Name: "Update", 2208 Fields: []*FieldDiff{ 2209 { 2210 Type: DiffTypeNone, 2211 Name: "AutoPromote", 2212 Old: "true", 2213 New: "true", 2214 }, 2215 { 2216 Type: DiffTypeNone, 2217 Name: "AutoRevert", 2218 Old: "true", 2219 New: "true", 2220 }, 2221 { 2222 Type: DiffTypeNone, 2223 Name: "Canary", 2224 Old: "2", 2225 New: "2", 2226 }, 2227 { 2228 Type: DiffTypeNone, 2229 Name: "HealthCheck", 2230 Old: "foo", 2231 New: "foo", 2232 }, 2233 { 2234 Type: DiffTypeNone, 2235 Name: "HealthyDeadline", 2236 Old: "30000000000", 2237 New: "30000000000", 2238 }, 2239 { 2240 Type: DiffTypeEdited, 2241 Name: "MaxParallel", 2242 Old: "5", 2243 New: "7", 2244 }, 2245 { 2246 Type: DiffTypeNone, 2247 Name: "MinHealthyTime", 2248 Old: "1000000000", 2249 New: "1000000000", 2250 }, 2251 { 2252 Type: DiffTypeNone, 2253 Name: "ProgressDeadline", 2254 Old: "30000000000", 2255 New: "30000000000", 2256 }, 2257 }, 2258 }, 2259 }, 2260 }, 2261 }, 2262 { 2263 // EphemeralDisk added 2264 Old: &TaskGroup{}, 2265 New: &TaskGroup{ 2266 EphemeralDisk: &EphemeralDisk{ 2267 Migrate: true, 2268 Sticky: true, 2269 SizeMB: 100, 2270 }, 2271 }, 2272 Expected: &TaskGroupDiff{ 2273 Type: DiffTypeEdited, 2274 Objects: []*ObjectDiff{ 2275 { 2276 Type: DiffTypeAdded, 2277 Name: "EphemeralDisk", 2278 Fields: []*FieldDiff{ 2279 { 2280 Type: DiffTypeAdded, 2281 Name: "Migrate", 2282 Old: "", 2283 New: "true", 2284 }, 2285 { 2286 Type: DiffTypeAdded, 2287 Name: "SizeMB", 2288 Old: "", 2289 New: "100", 2290 }, 2291 { 2292 Type: DiffTypeAdded, 2293 Name: "Sticky", 2294 Old: "", 2295 New: "true", 2296 }, 2297 }, 2298 }, 2299 }, 2300 }, 2301 }, 2302 { 2303 // EphemeralDisk deleted 2304 Old: &TaskGroup{ 2305 EphemeralDisk: &EphemeralDisk{ 2306 Migrate: true, 2307 Sticky: true, 2308 SizeMB: 100, 2309 }, 2310 }, 2311 New: &TaskGroup{}, 2312 Expected: &TaskGroupDiff{ 2313 Type: DiffTypeEdited, 2314 Objects: []*ObjectDiff{ 2315 { 2316 Type: DiffTypeDeleted, 2317 Name: "EphemeralDisk", 2318 Fields: []*FieldDiff{ 2319 { 2320 Type: DiffTypeDeleted, 2321 Name: "Migrate", 2322 Old: "true", 2323 New: "", 2324 }, 2325 { 2326 Type: DiffTypeDeleted, 2327 Name: "SizeMB", 2328 Old: "100", 2329 New: "", 2330 }, 2331 { 2332 Type: DiffTypeDeleted, 2333 Name: "Sticky", 2334 Old: "true", 2335 New: "", 2336 }, 2337 }, 2338 }, 2339 }, 2340 }, 2341 }, 2342 { 2343 // EphemeralDisk edited 2344 Old: &TaskGroup{ 2345 EphemeralDisk: &EphemeralDisk{ 2346 Migrate: true, 2347 Sticky: true, 2348 SizeMB: 150, 2349 }, 2350 }, 2351 New: &TaskGroup{ 2352 EphemeralDisk: &EphemeralDisk{ 2353 Migrate: false, 2354 Sticky: false, 2355 SizeMB: 90, 2356 }, 2357 }, 2358 Expected: &TaskGroupDiff{ 2359 Type: DiffTypeEdited, 2360 Objects: []*ObjectDiff{ 2361 { 2362 Type: DiffTypeEdited, 2363 Name: "EphemeralDisk", 2364 Fields: []*FieldDiff{ 2365 { 2366 Type: DiffTypeEdited, 2367 Name: "Migrate", 2368 Old: "true", 2369 New: "false", 2370 }, 2371 { 2372 Type: DiffTypeEdited, 2373 Name: "SizeMB", 2374 Old: "150", 2375 New: "90", 2376 }, 2377 2378 { 2379 Type: DiffTypeEdited, 2380 Name: "Sticky", 2381 Old: "true", 2382 New: "false", 2383 }, 2384 }, 2385 }, 2386 }, 2387 }, 2388 }, 2389 { 2390 // EphemeralDisk edited with context 2391 Contextual: true, 2392 Old: &TaskGroup{ 2393 EphemeralDisk: &EphemeralDisk{ 2394 Migrate: false, 2395 Sticky: false, 2396 SizeMB: 100, 2397 }, 2398 }, 2399 New: &TaskGroup{ 2400 EphemeralDisk: &EphemeralDisk{ 2401 Migrate: true, 2402 Sticky: true, 2403 SizeMB: 90, 2404 }, 2405 }, 2406 Expected: &TaskGroupDiff{ 2407 Type: DiffTypeEdited, 2408 Objects: []*ObjectDiff{ 2409 { 2410 Type: DiffTypeEdited, 2411 Name: "EphemeralDisk", 2412 Fields: []*FieldDiff{ 2413 { 2414 Type: DiffTypeEdited, 2415 Name: "Migrate", 2416 Old: "false", 2417 New: "true", 2418 }, 2419 { 2420 Type: DiffTypeEdited, 2421 Name: "SizeMB", 2422 Old: "100", 2423 New: "90", 2424 }, 2425 { 2426 Type: DiffTypeEdited, 2427 Name: "Sticky", 2428 Old: "false", 2429 New: "true", 2430 }, 2431 }, 2432 }, 2433 }, 2434 }, 2435 }, 2436 2437 { 2438 // TaskGroup Services edited 2439 Contextual: true, 2440 Old: &TaskGroup{ 2441 Services: []*Service{ 2442 { 2443 Name: "foo", 2444 Checks: []*ServiceCheck{ 2445 { 2446 Name: "foo", 2447 Type: "http", 2448 Command: "foo", 2449 Args: []string{"foo"}, 2450 Path: "foo", 2451 Protocol: "http", 2452 Interval: 1 * time.Second, 2453 Timeout: 1 * time.Second, 2454 }, 2455 }, 2456 Connect: &ConsulConnect{ 2457 SidecarTask: &SidecarTask{ 2458 Name: "sidecar", 2459 Driver: "docker", 2460 Env: map[string]string{ 2461 "FOO": "BAR", 2462 }, 2463 Config: map[string]interface{}{ 2464 "foo": "baz", 2465 }, 2466 }, 2467 }, 2468 }, 2469 }, 2470 }, 2471 2472 New: &TaskGroup{ 2473 Services: []*Service{ 2474 { 2475 Name: "foo", 2476 Checks: []*ServiceCheck{ 2477 { 2478 Name: "foo", 2479 Type: "tcp", 2480 Command: "bar", 2481 Path: "bar", 2482 Protocol: "tcp", 2483 Interval: 2 * time.Second, 2484 Timeout: 2 * time.Second, 2485 Header: map[string][]string{ 2486 "Foo": {"baz"}, 2487 }, 2488 }, 2489 }, 2490 Connect: &ConsulConnect{ 2491 SidecarService: &ConsulSidecarService{ 2492 Port: "http", 2493 Proxy: &ConsulProxy{ 2494 LocalServiceAddress: "127.0.0.1", 2495 LocalServicePort: 8080, 2496 Upstreams: []ConsulUpstream{ 2497 { 2498 DestinationName: "foo", 2499 LocalBindPort: 8000, 2500 }, 2501 }, 2502 Config: map[string]interface{}{ 2503 "foo": "qux", 2504 }, 2505 }, 2506 }, 2507 }, 2508 }, 2509 }, 2510 }, 2511 2512 Expected: &TaskGroupDiff{ 2513 Type: DiffTypeEdited, 2514 Objects: []*ObjectDiff{ 2515 { 2516 Type: DiffTypeEdited, 2517 Name: "Service", 2518 Fields: []*FieldDiff{ 2519 { 2520 Type: DiffTypeNone, 2521 Name: "AddressMode", 2522 Old: "", 2523 New: "", 2524 }, 2525 { 2526 Type: DiffTypeNone, 2527 Name: "Name", 2528 Old: "foo", 2529 New: "foo", 2530 }, 2531 { 2532 Type: DiffTypeNone, 2533 Name: "PortLabel", 2534 Old: "", 2535 New: "", 2536 }, 2537 }, 2538 Objects: []*ObjectDiff{ 2539 2540 { 2541 Type: DiffTypeEdited, 2542 Name: "Check", 2543 Fields: []*FieldDiff{ 2544 { 2545 Type: DiffTypeNone, 2546 Name: "AddressMode", 2547 Old: "", 2548 New: "", 2549 }, 2550 { 2551 Type: DiffTypeEdited, 2552 Name: "Command", 2553 Old: "foo", 2554 New: "bar", 2555 }, 2556 { 2557 Type: DiffTypeNone, 2558 Name: "GRPCService", 2559 Old: "", 2560 New: "", 2561 }, 2562 { 2563 Type: DiffTypeNone, 2564 Name: "GRPCUseTLS", 2565 Old: "false", 2566 New: "false", 2567 }, 2568 { 2569 Type: DiffTypeNone, 2570 Name: "InitialStatus", 2571 Old: "", 2572 New: "", 2573 }, 2574 { 2575 Type: DiffTypeEdited, 2576 Name: "Interval", 2577 Old: "1000000000", 2578 New: "2000000000", 2579 }, 2580 { 2581 Type: DiffTypeNone, 2582 Name: "Method", 2583 Old: "", 2584 New: "", 2585 }, 2586 { 2587 Type: DiffTypeNone, 2588 Name: "Name", 2589 Old: "foo", 2590 New: "foo", 2591 }, 2592 { 2593 Type: DiffTypeEdited, 2594 Name: "Path", 2595 Old: "foo", 2596 New: "bar", 2597 }, 2598 { 2599 Type: DiffTypeNone, 2600 Name: "PortLabel", 2601 Old: "", 2602 New: "", 2603 }, 2604 { 2605 Type: DiffTypeEdited, 2606 Name: "Protocol", 2607 Old: "http", 2608 New: "tcp", 2609 }, 2610 { 2611 Type: DiffTypeNone, 2612 Name: "TLSSkipVerify", 2613 Old: "false", 2614 New: "false", 2615 }, 2616 { 2617 Type: DiffTypeNone, 2618 Name: "TaskName", 2619 Old: "", 2620 New: "", 2621 }, 2622 { 2623 Type: DiffTypeEdited, 2624 Name: "Timeout", 2625 Old: "1000000000", 2626 New: "2000000000", 2627 }, 2628 { 2629 Type: DiffTypeEdited, 2630 Name: "Type", 2631 Old: "http", 2632 New: "tcp", 2633 }, 2634 }, 2635 Objects: []*ObjectDiff{ 2636 { 2637 Type: DiffTypeAdded, 2638 Name: "Header", 2639 Fields: []*FieldDiff{ 2640 { 2641 Type: DiffTypeAdded, 2642 Name: "Foo[0]", 2643 Old: "", 2644 New: "baz", 2645 }, 2646 }, 2647 }, 2648 }, 2649 }, 2650 2651 { 2652 Type: DiffTypeEdited, 2653 Name: "ConsulConnect", 2654 Fields: []*FieldDiff{ 2655 { 2656 Type: DiffTypeNone, 2657 Name: "Native", 2658 Old: "false", 2659 New: "false", 2660 }, 2661 }, 2662 Objects: []*ObjectDiff{ 2663 2664 { 2665 Type: DiffTypeAdded, 2666 Name: "SidecarService", 2667 Fields: []*FieldDiff{ 2668 { 2669 Type: DiffTypeAdded, 2670 Name: "Port", 2671 Old: "", 2672 New: "http", 2673 }, 2674 }, 2675 Objects: []*ObjectDiff{ 2676 { 2677 Type: DiffTypeAdded, 2678 Name: "ConsulProxy", 2679 Fields: []*FieldDiff{ 2680 { 2681 Type: DiffTypeAdded, 2682 Name: "LocalServiceAddress", 2683 Old: "", 2684 New: "127.0.0.1", 2685 }, { 2686 Type: DiffTypeAdded, 2687 Name: "LocalServicePort", 2688 Old: "", 2689 New: "8080", 2690 }, 2691 }, 2692 Objects: []*ObjectDiff{ 2693 { 2694 Type: DiffTypeAdded, 2695 Name: "ConsulUpstreams", 2696 Fields: []*FieldDiff{ 2697 { 2698 Type: DiffTypeAdded, 2699 Name: "DestinationName", 2700 Old: "", 2701 New: "foo", 2702 }, 2703 { 2704 Type: DiffTypeAdded, 2705 Name: "LocalBindPort", 2706 Old: "", 2707 New: "8000", 2708 }, 2709 }, 2710 }, 2711 { 2712 Type: DiffTypeAdded, 2713 Name: "Config", 2714 Fields: []*FieldDiff{ 2715 { 2716 Type: DiffTypeAdded, 2717 Name: "foo", 2718 Old: "", 2719 New: "qux", 2720 }, 2721 }, 2722 }, 2723 }, 2724 }, 2725 }, 2726 }, 2727 2728 { 2729 Type: DiffTypeDeleted, 2730 Name: "SidecarTask", 2731 Fields: []*FieldDiff{ 2732 { 2733 Type: DiffTypeDeleted, 2734 Name: "Driver", 2735 Old: "docker", 2736 New: "", 2737 }, 2738 { 2739 Type: DiffTypeDeleted, 2740 Name: "Env[FOO]", 2741 Old: "BAR", 2742 New: "", 2743 }, 2744 { 2745 Type: DiffTypeDeleted, 2746 Name: "Name", 2747 Old: "sidecar", 2748 New: "", 2749 }, 2750 }, 2751 Objects: []*ObjectDiff{ 2752 { 2753 Type: DiffTypeDeleted, 2754 Name: "Config", 2755 Fields: []*FieldDiff{ 2756 { 2757 Type: DiffTypeDeleted, 2758 Name: "foo", 2759 Old: "baz", 2760 New: "", 2761 }, 2762 }, 2763 }, 2764 }, 2765 }, 2766 }, 2767 }, 2768 }, 2769 }, 2770 }, 2771 }, 2772 }, 2773 { 2774 // TaskGroup Networks edited 2775 Contextual: true, 2776 Old: &TaskGroup{ 2777 Networks: Networks{ 2778 { 2779 Device: "foo", 2780 CIDR: "foo", 2781 IP: "foo", 2782 MBits: 100, 2783 ReservedPorts: []Port{ 2784 { 2785 Label: "foo", 2786 Value: 80, 2787 }, 2788 }, 2789 }, 2790 }, 2791 }, 2792 New: &TaskGroup{ 2793 Networks: Networks{ 2794 { 2795 Device: "bar", 2796 CIDR: "bar", 2797 IP: "bar", 2798 MBits: 200, 2799 DynamicPorts: []Port{ 2800 { 2801 Label: "bar", 2802 To: 8081, 2803 }, 2804 }, 2805 }, 2806 }, 2807 }, 2808 Expected: &TaskGroupDiff{ 2809 Type: DiffTypeEdited, 2810 Objects: []*ObjectDiff{ 2811 { 2812 Type: DiffTypeAdded, 2813 Name: "Network", 2814 Fields: []*FieldDiff{ 2815 { 2816 Type: DiffTypeAdded, 2817 Name: "MBits", 2818 Old: "", 2819 New: "200", 2820 }, 2821 { 2822 Type: DiffTypeNone, 2823 Name: "Mode", 2824 Old: "", 2825 New: "", 2826 }, 2827 }, 2828 Objects: []*ObjectDiff{ 2829 { 2830 Type: DiffTypeAdded, 2831 Name: "Dynamic Port", 2832 Fields: []*FieldDiff{ 2833 { 2834 Type: DiffTypeAdded, 2835 Name: "Label", 2836 Old: "", 2837 New: "bar", 2838 }, 2839 { 2840 Type: DiffTypeAdded, 2841 Name: "To", 2842 Old: "", 2843 New: "8081", 2844 }, 2845 }, 2846 }, 2847 }, 2848 }, 2849 { 2850 Type: DiffTypeDeleted, 2851 Name: "Network", 2852 Fields: []*FieldDiff{ 2853 { 2854 Type: DiffTypeDeleted, 2855 Name: "MBits", 2856 Old: "100", 2857 New: "", 2858 }, 2859 { 2860 Type: DiffTypeNone, 2861 Name: "Mode", 2862 Old: "", 2863 New: "", 2864 }, 2865 }, 2866 Objects: []*ObjectDiff{ 2867 { 2868 Type: DiffTypeDeleted, 2869 Name: "Static Port", 2870 Fields: []*FieldDiff{ 2871 { 2872 Type: DiffTypeDeleted, 2873 Name: "Label", 2874 Old: "foo", 2875 New: "", 2876 }, 2877 { 2878 Type: DiffTypeDeleted, 2879 Name: "To", 2880 Old: "0", 2881 New: "", 2882 }, 2883 { 2884 Type: DiffTypeDeleted, 2885 Name: "Value", 2886 Old: "80", 2887 New: "", 2888 }, 2889 }, 2890 }, 2891 }, 2892 }, 2893 }, 2894 }, 2895 }, 2896 { 2897 // Tasks edited 2898 Old: &TaskGroup{ 2899 Tasks: []*Task{ 2900 { 2901 Name: "foo", 2902 Driver: "docker", 2903 }, 2904 { 2905 Name: "bar", 2906 Driver: "docker", 2907 }, 2908 { 2909 Name: "baz", 2910 ShutdownDelay: 1 * time.Second, 2911 }, 2912 }, 2913 }, 2914 New: &TaskGroup{ 2915 Tasks: []*Task{ 2916 { 2917 Name: "bar", 2918 Driver: "docker", 2919 }, 2920 { 2921 Name: "bam", 2922 Driver: "docker", 2923 }, 2924 { 2925 Name: "baz", 2926 ShutdownDelay: 2 * time.Second, 2927 }, 2928 }, 2929 }, 2930 Expected: &TaskGroupDiff{ 2931 Type: DiffTypeEdited, 2932 Tasks: []*TaskDiff{ 2933 { 2934 Type: DiffTypeAdded, 2935 Name: "bam", 2936 Fields: []*FieldDiff{ 2937 { 2938 Type: DiffTypeAdded, 2939 Name: "Driver", 2940 Old: "", 2941 New: "docker", 2942 }, 2943 { 2944 Type: DiffTypeAdded, 2945 Name: "KillTimeout", 2946 Old: "", 2947 New: "0", 2948 }, 2949 { 2950 Type: DiffTypeAdded, 2951 Name: "Leader", 2952 Old: "", 2953 New: "false", 2954 }, 2955 { 2956 Type: DiffTypeAdded, 2957 Name: "ShutdownDelay", 2958 Old: "", 2959 New: "0", 2960 }, 2961 }, 2962 }, 2963 { 2964 Type: DiffTypeNone, 2965 Name: "bar", 2966 }, 2967 { 2968 Type: DiffTypeEdited, 2969 Name: "baz", 2970 Fields: []*FieldDiff{ 2971 { 2972 Type: DiffTypeEdited, 2973 Name: "ShutdownDelay", 2974 Old: "1000000000", 2975 New: "2000000000", 2976 }, 2977 }, 2978 }, 2979 { 2980 Type: DiffTypeDeleted, 2981 Name: "foo", 2982 Fields: []*FieldDiff{ 2983 { 2984 Type: DiffTypeDeleted, 2985 Name: "Driver", 2986 Old: "docker", 2987 New: "", 2988 }, 2989 { 2990 Type: DiffTypeDeleted, 2991 Name: "KillTimeout", 2992 Old: "0", 2993 New: "", 2994 }, 2995 { 2996 Type: DiffTypeDeleted, 2997 Name: "Leader", 2998 Old: "false", 2999 New: "", 3000 }, 3001 { 3002 Type: DiffTypeDeleted, 3003 Name: "ShutdownDelay", 3004 Old: "0", 3005 New: "", 3006 }, 3007 }, 3008 }, 3009 }, 3010 }, 3011 }, 3012 } 3013 3014 for i, c := range cases { 3015 actual, err := c.Old.Diff(c.New, c.Contextual) 3016 if c.Error && err == nil { 3017 t.Fatalf("case %d: expected errored", i+1) 3018 } else if err != nil { 3019 if !c.Error { 3020 t.Fatalf("case %d: errored %#v", i+1, err) 3021 } else { 3022 continue 3023 } 3024 } 3025 3026 if !reflect.DeepEqual(actual, c.Expected) { 3027 t.Fatalf("case %d: got:\n%#v\n want:\n%#v\n", 3028 i+1, actual, c.Expected) 3029 } 3030 } 3031 } 3032 3033 func TestTaskDiff(t *testing.T) { 3034 cases := []struct { 3035 Name string 3036 Old, New *Task 3037 Expected *TaskDiff 3038 Error bool 3039 Contextual bool 3040 }{ 3041 { 3042 Name: "Empty", 3043 Old: nil, 3044 New: nil, 3045 Expected: &TaskDiff{ 3046 Type: DiffTypeNone, 3047 }, 3048 }, 3049 { 3050 Name: "Primitive only that has different names", 3051 Old: &Task{ 3052 Name: "foo", 3053 Meta: map[string]string{ 3054 "foo": "bar", 3055 }, 3056 }, 3057 New: &Task{ 3058 Name: "bar", 3059 Meta: map[string]string{ 3060 "foo": "bar", 3061 }, 3062 }, 3063 Error: true, 3064 }, 3065 { 3066 Name: "Primitive only that is the same", 3067 Old: &Task{ 3068 Name: "foo", 3069 Driver: "exec", 3070 User: "foo", 3071 Env: map[string]string{ 3072 "FOO": "bar", 3073 }, 3074 Meta: map[string]string{ 3075 "foo": "bar", 3076 }, 3077 KillTimeout: 1 * time.Second, 3078 Leader: true, 3079 }, 3080 New: &Task{ 3081 Name: "foo", 3082 Driver: "exec", 3083 User: "foo", 3084 Env: map[string]string{ 3085 "FOO": "bar", 3086 }, 3087 Meta: map[string]string{ 3088 "foo": "bar", 3089 }, 3090 KillTimeout: 1 * time.Second, 3091 Leader: true, 3092 }, 3093 Expected: &TaskDiff{ 3094 Type: DiffTypeNone, 3095 Name: "foo", 3096 }, 3097 }, 3098 { 3099 Name: "Primitive only that has diffs", 3100 Old: &Task{ 3101 Name: "foo", 3102 Driver: "exec", 3103 User: "foo", 3104 Env: map[string]string{ 3105 "FOO": "bar", 3106 }, 3107 Meta: map[string]string{ 3108 "foo": "bar", 3109 }, 3110 KillTimeout: 1 * time.Second, 3111 Leader: true, 3112 }, 3113 New: &Task{ 3114 Name: "foo", 3115 Driver: "docker", 3116 User: "bar", 3117 Env: map[string]string{ 3118 "FOO": "baz", 3119 }, 3120 Meta: map[string]string{ 3121 "foo": "baz", 3122 }, 3123 KillTimeout: 2 * time.Second, 3124 Leader: false, 3125 }, 3126 Expected: &TaskDiff{ 3127 Type: DiffTypeEdited, 3128 Name: "foo", 3129 Fields: []*FieldDiff{ 3130 { 3131 Type: DiffTypeEdited, 3132 Name: "Driver", 3133 Old: "exec", 3134 New: "docker", 3135 }, 3136 { 3137 Type: DiffTypeEdited, 3138 Name: "Env[FOO]", 3139 Old: "bar", 3140 New: "baz", 3141 }, 3142 { 3143 Type: DiffTypeEdited, 3144 Name: "KillTimeout", 3145 Old: "1000000000", 3146 New: "2000000000", 3147 }, 3148 { 3149 Type: DiffTypeEdited, 3150 Name: "Leader", 3151 Old: "true", 3152 New: "false", 3153 }, 3154 { 3155 Type: DiffTypeEdited, 3156 Name: "Meta[foo]", 3157 Old: "bar", 3158 New: "baz", 3159 }, 3160 { 3161 Type: DiffTypeEdited, 3162 Name: "User", 3163 Old: "foo", 3164 New: "bar", 3165 }, 3166 }, 3167 }, 3168 }, 3169 { 3170 Name: "Map diff", 3171 Old: &Task{ 3172 Meta: map[string]string{ 3173 "foo": "foo", 3174 "bar": "bar", 3175 }, 3176 Env: map[string]string{ 3177 "foo": "foo", 3178 "bar": "bar", 3179 }, 3180 }, 3181 New: &Task{ 3182 Meta: map[string]string{ 3183 "bar": "bar", 3184 "baz": "baz", 3185 }, 3186 Env: map[string]string{ 3187 "bar": "bar", 3188 "baz": "baz", 3189 }, 3190 }, 3191 Expected: &TaskDiff{ 3192 Type: DiffTypeEdited, 3193 Fields: []*FieldDiff{ 3194 { 3195 Type: DiffTypeAdded, 3196 Name: "Env[baz]", 3197 Old: "", 3198 New: "baz", 3199 }, 3200 { 3201 Type: DiffTypeDeleted, 3202 Name: "Env[foo]", 3203 Old: "foo", 3204 New: "", 3205 }, 3206 { 3207 Type: DiffTypeAdded, 3208 Name: "Meta[baz]", 3209 Old: "", 3210 New: "baz", 3211 }, 3212 { 3213 Type: DiffTypeDeleted, 3214 Name: "Meta[foo]", 3215 Old: "foo", 3216 New: "", 3217 }, 3218 }, 3219 }, 3220 }, 3221 { 3222 Name: "Constraints edited", 3223 Old: &Task{ 3224 Constraints: []*Constraint{ 3225 { 3226 LTarget: "foo", 3227 RTarget: "foo", 3228 Operand: "foo", 3229 str: "foo", 3230 }, 3231 { 3232 LTarget: "bar", 3233 RTarget: "bar", 3234 Operand: "bar", 3235 str: "bar", 3236 }, 3237 }, 3238 }, 3239 New: &Task{ 3240 Constraints: []*Constraint{ 3241 { 3242 LTarget: "foo", 3243 RTarget: "foo", 3244 Operand: "foo", 3245 str: "foo", 3246 }, 3247 { 3248 LTarget: "baz", 3249 RTarget: "baz", 3250 Operand: "baz", 3251 str: "baz", 3252 }, 3253 }, 3254 }, 3255 Expected: &TaskDiff{ 3256 Type: DiffTypeEdited, 3257 Objects: []*ObjectDiff{ 3258 { 3259 Type: DiffTypeAdded, 3260 Name: "Constraint", 3261 Fields: []*FieldDiff{ 3262 { 3263 Type: DiffTypeAdded, 3264 Name: "LTarget", 3265 Old: "", 3266 New: "baz", 3267 }, 3268 { 3269 Type: DiffTypeAdded, 3270 Name: "Operand", 3271 Old: "", 3272 New: "baz", 3273 }, 3274 { 3275 Type: DiffTypeAdded, 3276 Name: "RTarget", 3277 Old: "", 3278 New: "baz", 3279 }, 3280 }, 3281 }, 3282 { 3283 Type: DiffTypeDeleted, 3284 Name: "Constraint", 3285 Fields: []*FieldDiff{ 3286 { 3287 Type: DiffTypeDeleted, 3288 Name: "LTarget", 3289 Old: "bar", 3290 New: "", 3291 }, 3292 { 3293 Type: DiffTypeDeleted, 3294 Name: "Operand", 3295 Old: "bar", 3296 New: "", 3297 }, 3298 { 3299 Type: DiffTypeDeleted, 3300 Name: "RTarget", 3301 Old: "bar", 3302 New: "", 3303 }, 3304 }, 3305 }, 3306 }, 3307 }, 3308 }, 3309 { 3310 Name: "Affinities edited", 3311 Old: &Task{ 3312 Affinities: []*Affinity{ 3313 { 3314 LTarget: "foo", 3315 RTarget: "foo", 3316 Operand: "foo", 3317 Weight: 20, 3318 str: "foo", 3319 }, 3320 { 3321 LTarget: "bar", 3322 RTarget: "bar", 3323 Operand: "bar", 3324 Weight: 20, 3325 str: "bar", 3326 }, 3327 }, 3328 }, 3329 New: &Task{ 3330 Affinities: []*Affinity{ 3331 { 3332 LTarget: "foo", 3333 RTarget: "foo", 3334 Operand: "foo", 3335 Weight: 20, 3336 str: "foo", 3337 }, 3338 { 3339 LTarget: "baz", 3340 RTarget: "baz", 3341 Operand: "baz", 3342 Weight: 20, 3343 str: "baz", 3344 }, 3345 }, 3346 }, 3347 Expected: &TaskDiff{ 3348 Type: DiffTypeEdited, 3349 Objects: []*ObjectDiff{ 3350 { 3351 Type: DiffTypeAdded, 3352 Name: "Affinity", 3353 Fields: []*FieldDiff{ 3354 { 3355 Type: DiffTypeAdded, 3356 Name: "LTarget", 3357 Old: "", 3358 New: "baz", 3359 }, 3360 { 3361 Type: DiffTypeAdded, 3362 Name: "Operand", 3363 Old: "", 3364 New: "baz", 3365 }, 3366 { 3367 Type: DiffTypeAdded, 3368 Name: "RTarget", 3369 Old: "", 3370 New: "baz", 3371 }, 3372 { 3373 Type: DiffTypeAdded, 3374 Name: "Weight", 3375 Old: "", 3376 New: "20", 3377 }, 3378 }, 3379 }, 3380 { 3381 Type: DiffTypeDeleted, 3382 Name: "Affinity", 3383 Fields: []*FieldDiff{ 3384 { 3385 Type: DiffTypeDeleted, 3386 Name: "LTarget", 3387 Old: "bar", 3388 New: "", 3389 }, 3390 { 3391 Type: DiffTypeDeleted, 3392 Name: "Operand", 3393 Old: "bar", 3394 New: "", 3395 }, 3396 { 3397 Type: DiffTypeDeleted, 3398 Name: "RTarget", 3399 Old: "bar", 3400 New: "", 3401 }, 3402 { 3403 Type: DiffTypeDeleted, 3404 Name: "Weight", 3405 Old: "20", 3406 New: "", 3407 }, 3408 }, 3409 }, 3410 }, 3411 }, 3412 }, 3413 { 3414 Name: "LogConfig added", 3415 Old: &Task{}, 3416 New: &Task{ 3417 LogConfig: &LogConfig{ 3418 MaxFiles: 1, 3419 MaxFileSizeMB: 10, 3420 FileExtension: "txt", 3421 }, 3422 }, 3423 Expected: &TaskDiff{ 3424 Type: DiffTypeEdited, 3425 Objects: []*ObjectDiff{ 3426 { 3427 Type: DiffTypeAdded, 3428 Name: "LogConfig", 3429 Fields: []*FieldDiff{ 3430 { 3431 Type: DiffTypeAdded, 3432 Name: "FileExtension", 3433 Old: "", 3434 New: "txt", 3435 }, 3436 { 3437 Type: DiffTypeAdded, 3438 Name: "MaxFileSizeMB", 3439 Old: "", 3440 New: "10", 3441 }, 3442 { 3443 Type: DiffTypeAdded, 3444 Name: "MaxFiles", 3445 Old: "", 3446 New: "1", 3447 }, 3448 }, 3449 }, 3450 }, 3451 }, 3452 }, 3453 { 3454 Name: "LogConfig deleted", 3455 Old: &Task{ 3456 LogConfig: &LogConfig{ 3457 MaxFiles: 1, 3458 MaxFileSizeMB: 10, 3459 FileExtension: "txt", 3460 }, 3461 }, 3462 New: &Task{}, 3463 Expected: &TaskDiff{ 3464 Type: DiffTypeEdited, 3465 Objects: []*ObjectDiff{ 3466 { 3467 Type: DiffTypeDeleted, 3468 Name: "LogConfig", 3469 Fields: []*FieldDiff{ 3470 { 3471 Type: DiffTypeDeleted, 3472 Name: "FileExtension", 3473 Old: "txt", 3474 New: "", 3475 }, 3476 { 3477 Type: DiffTypeDeleted, 3478 Name: "MaxFileSizeMB", 3479 Old: "10", 3480 New: "", 3481 }, 3482 { 3483 Type: DiffTypeDeleted, 3484 Name: "MaxFiles", 3485 Old: "1", 3486 New: "", 3487 }, 3488 }, 3489 }, 3490 }, 3491 }, 3492 }, 3493 { 3494 Name: "LogConfig edited", 3495 Old: &Task{ 3496 LogConfig: &LogConfig{ 3497 MaxFiles: 1, 3498 MaxFileSizeMB: 10, 3499 FileExtension: "log", 3500 }, 3501 }, 3502 New: &Task{ 3503 LogConfig: &LogConfig{ 3504 MaxFiles: 2, 3505 MaxFileSizeMB: 20, 3506 FileExtension: "txt", 3507 }, 3508 }, 3509 Expected: &TaskDiff{ 3510 Type: DiffTypeEdited, 3511 Objects: []*ObjectDiff{ 3512 { 3513 Type: DiffTypeEdited, 3514 Name: "LogConfig", 3515 Fields: []*FieldDiff{ 3516 { 3517 Type: DiffTypeEdited, 3518 Name: "FileExtension", 3519 Old: "log", 3520 New: "txt", 3521 }, 3522 { 3523 Type: DiffTypeEdited, 3524 Name: "MaxFileSizeMB", 3525 Old: "10", 3526 New: "20", 3527 }, 3528 { 3529 Type: DiffTypeEdited, 3530 Name: "MaxFiles", 3531 Old: "1", 3532 New: "2", 3533 }, 3534 }, 3535 }, 3536 }, 3537 }, 3538 }, 3539 { 3540 Name: "LogConfig edited with context", 3541 Contextual: true, 3542 Old: &Task{ 3543 LogConfig: &LogConfig{ 3544 MaxFiles: 1, 3545 MaxFileSizeMB: 10, 3546 FileExtension: "txt", 3547 }, 3548 }, 3549 New: &Task{ 3550 LogConfig: &LogConfig{ 3551 MaxFiles: 1, 3552 MaxFileSizeMB: 20, 3553 FileExtension: "txt", 3554 }, 3555 }, 3556 Expected: &TaskDiff{ 3557 Type: DiffTypeEdited, 3558 Objects: []*ObjectDiff{ 3559 { 3560 Type: DiffTypeEdited, 3561 Name: "LogConfig", 3562 Fields: []*FieldDiff{ 3563 { 3564 Type: DiffTypeNone, 3565 Name: "FileExtension", 3566 Old: "txt", 3567 New: "txt", 3568 }, 3569 { 3570 Type: DiffTypeEdited, 3571 Name: "MaxFileSizeMB", 3572 Old: "10", 3573 New: "20", 3574 }, 3575 { 3576 Type: DiffTypeNone, 3577 Name: "MaxFiles", 3578 Old: "1", 3579 New: "1", 3580 }, 3581 }, 3582 }, 3583 }, 3584 }, 3585 }, 3586 { 3587 Name: "Artifacts edited", 3588 Old: &Task{ 3589 Artifacts: []*TaskArtifact{ 3590 { 3591 GetterSource: "foo", 3592 GetterOptions: map[string]string{ 3593 "foo": "bar", 3594 }, 3595 RelativeDest: "foo", 3596 }, 3597 { 3598 GetterSource: "bar", 3599 GetterOptions: map[string]string{ 3600 "bar": "baz", 3601 }, 3602 GetterMode: "dir", 3603 RelativeDest: "bar", 3604 }, 3605 }, 3606 }, 3607 New: &Task{ 3608 Artifacts: []*TaskArtifact{ 3609 { 3610 GetterSource: "foo", 3611 GetterOptions: map[string]string{ 3612 "foo": "bar", 3613 }, 3614 RelativeDest: "foo", 3615 }, 3616 { 3617 GetterSource: "bam", 3618 GetterOptions: map[string]string{ 3619 "bam": "baz", 3620 }, 3621 GetterMode: "file", 3622 RelativeDest: "bam", 3623 }, 3624 }, 3625 }, 3626 Expected: &TaskDiff{ 3627 Type: DiffTypeEdited, 3628 Objects: []*ObjectDiff{ 3629 { 3630 Type: DiffTypeAdded, 3631 Name: "Artifact", 3632 Fields: []*FieldDiff{ 3633 { 3634 Type: DiffTypeAdded, 3635 Name: "GetterMode", 3636 Old: "", 3637 New: "file", 3638 }, 3639 { 3640 Type: DiffTypeAdded, 3641 Name: "GetterOptions[bam]", 3642 Old: "", 3643 New: "baz", 3644 }, 3645 { 3646 Type: DiffTypeAdded, 3647 Name: "GetterSource", 3648 Old: "", 3649 New: "bam", 3650 }, 3651 { 3652 Type: DiffTypeAdded, 3653 Name: "RelativeDest", 3654 Old: "", 3655 New: "bam", 3656 }, 3657 }, 3658 }, 3659 { 3660 Type: DiffTypeDeleted, 3661 Name: "Artifact", 3662 Fields: []*FieldDiff{ 3663 { 3664 Type: DiffTypeDeleted, 3665 Name: "GetterMode", 3666 Old: "dir", 3667 New: "", 3668 }, 3669 { 3670 Type: DiffTypeDeleted, 3671 Name: "GetterOptions[bar]", 3672 Old: "baz", 3673 New: "", 3674 }, 3675 { 3676 Type: DiffTypeDeleted, 3677 Name: "GetterSource", 3678 Old: "bar", 3679 New: "", 3680 }, 3681 { 3682 Type: DiffTypeDeleted, 3683 Name: "RelativeDest", 3684 Old: "bar", 3685 New: "", 3686 }, 3687 }, 3688 }, 3689 }, 3690 }, 3691 }, 3692 { 3693 Name: "Resources edited (no networks)", 3694 Old: &Task{ 3695 Resources: &Resources{ 3696 CPU: 100, 3697 MemoryMB: 100, 3698 DiskMB: 100, 3699 }, 3700 }, 3701 New: &Task{ 3702 Resources: &Resources{ 3703 CPU: 200, 3704 MemoryMB: 200, 3705 DiskMB: 200, 3706 }, 3707 }, 3708 Expected: &TaskDiff{ 3709 Type: DiffTypeEdited, 3710 Objects: []*ObjectDiff{ 3711 { 3712 Type: DiffTypeEdited, 3713 Name: "Resources", 3714 Fields: []*FieldDiff{ 3715 { 3716 Type: DiffTypeEdited, 3717 Name: "CPU", 3718 Old: "100", 3719 New: "200", 3720 }, 3721 { 3722 Type: DiffTypeEdited, 3723 Name: "DiskMB", 3724 Old: "100", 3725 New: "200", 3726 }, 3727 { 3728 Type: DiffTypeEdited, 3729 Name: "MemoryMB", 3730 Old: "100", 3731 New: "200", 3732 }, 3733 }, 3734 }, 3735 }, 3736 }, 3737 }, 3738 { 3739 Name: "Resources edited (no networks) with context", 3740 Contextual: true, 3741 Old: &Task{ 3742 Resources: &Resources{ 3743 CPU: 100, 3744 MemoryMB: 100, 3745 DiskMB: 100, 3746 }, 3747 }, 3748 New: &Task{ 3749 Resources: &Resources{ 3750 CPU: 200, 3751 MemoryMB: 100, 3752 DiskMB: 200, 3753 }, 3754 }, 3755 Expected: &TaskDiff{ 3756 Type: DiffTypeEdited, 3757 Objects: []*ObjectDiff{ 3758 { 3759 Type: DiffTypeEdited, 3760 Name: "Resources", 3761 Fields: []*FieldDiff{ 3762 { 3763 Type: DiffTypeEdited, 3764 Name: "CPU", 3765 Old: "100", 3766 New: "200", 3767 }, 3768 { 3769 Type: DiffTypeEdited, 3770 Name: "DiskMB", 3771 Old: "100", 3772 New: "200", 3773 }, 3774 { 3775 Type: DiffTypeNone, 3776 Name: "IOPS", 3777 Old: "0", 3778 New: "0", 3779 }, 3780 { 3781 Type: DiffTypeNone, 3782 Name: "MemoryMB", 3783 Old: "100", 3784 New: "100", 3785 }, 3786 }, 3787 }, 3788 }, 3789 }, 3790 }, 3791 { 3792 Name: "Network Resources edited", 3793 Old: &Task{ 3794 Resources: &Resources{ 3795 Networks: []*NetworkResource{ 3796 { 3797 Device: "foo", 3798 CIDR: "foo", 3799 IP: "foo", 3800 MBits: 100, 3801 ReservedPorts: []Port{ 3802 { 3803 Label: "foo", 3804 Value: 80, 3805 }, 3806 }, 3807 DynamicPorts: []Port{ 3808 { 3809 Label: "bar", 3810 To: 8080, 3811 }, 3812 }, 3813 }, 3814 }, 3815 }, 3816 }, 3817 New: &Task{ 3818 Resources: &Resources{ 3819 Networks: []*NetworkResource{ 3820 { 3821 Device: "bar", 3822 CIDR: "bar", 3823 IP: "bar", 3824 MBits: 200, 3825 ReservedPorts: []Port{ 3826 { 3827 Label: "foo", 3828 Value: 81, 3829 }, 3830 }, 3831 DynamicPorts: []Port{ 3832 { 3833 Label: "baz", 3834 To: 8081, 3835 }, 3836 }, 3837 }, 3838 }, 3839 }, 3840 }, 3841 Expected: &TaskDiff{ 3842 Type: DiffTypeEdited, 3843 Objects: []*ObjectDiff{ 3844 { 3845 Type: DiffTypeEdited, 3846 Name: "Resources", 3847 Objects: []*ObjectDiff{ 3848 { 3849 Type: DiffTypeAdded, 3850 Name: "Network", 3851 Fields: []*FieldDiff{ 3852 { 3853 Type: DiffTypeAdded, 3854 Name: "MBits", 3855 Old: "", 3856 New: "200", 3857 }, 3858 }, 3859 Objects: []*ObjectDiff{ 3860 { 3861 Type: DiffTypeAdded, 3862 Name: "Static Port", 3863 Fields: []*FieldDiff{ 3864 { 3865 Type: DiffTypeAdded, 3866 Name: "Label", 3867 Old: "", 3868 New: "foo", 3869 }, 3870 { 3871 Type: DiffTypeAdded, 3872 Name: "To", 3873 Old: "", 3874 New: "0", 3875 }, 3876 { 3877 Type: DiffTypeAdded, 3878 Name: "Value", 3879 Old: "", 3880 New: "81", 3881 }, 3882 }, 3883 }, 3884 { 3885 Type: DiffTypeAdded, 3886 Name: "Dynamic Port", 3887 Fields: []*FieldDiff{ 3888 { 3889 Type: DiffTypeAdded, 3890 Name: "Label", 3891 Old: "", 3892 New: "baz", 3893 }, 3894 { 3895 Type: DiffTypeAdded, 3896 Name: "To", 3897 Old: "", 3898 New: "8081", 3899 }, 3900 }, 3901 }, 3902 }, 3903 }, 3904 { 3905 Type: DiffTypeDeleted, 3906 Name: "Network", 3907 Fields: []*FieldDiff{ 3908 { 3909 Type: DiffTypeDeleted, 3910 Name: "MBits", 3911 Old: "100", 3912 New: "", 3913 }, 3914 }, 3915 Objects: []*ObjectDiff{ 3916 { 3917 Type: DiffTypeDeleted, 3918 Name: "Static Port", 3919 Fields: []*FieldDiff{ 3920 { 3921 Type: DiffTypeDeleted, 3922 Name: "Label", 3923 Old: "foo", 3924 New: "", 3925 }, 3926 { 3927 Type: DiffTypeDeleted, 3928 Name: "To", 3929 Old: "0", 3930 New: "", 3931 }, 3932 { 3933 Type: DiffTypeDeleted, 3934 Name: "Value", 3935 Old: "80", 3936 New: "", 3937 }, 3938 }, 3939 }, 3940 { 3941 Type: DiffTypeDeleted, 3942 Name: "Dynamic Port", 3943 Fields: []*FieldDiff{ 3944 { 3945 Type: DiffTypeDeleted, 3946 Name: "Label", 3947 Old: "bar", 3948 New: "", 3949 }, 3950 { 3951 Type: DiffTypeDeleted, 3952 Name: "To", 3953 Old: "8080", 3954 New: "", 3955 }, 3956 }, 3957 }, 3958 }, 3959 }, 3960 }, 3961 }, 3962 }, 3963 }, 3964 }, 3965 { 3966 Name: "Device Resources edited", 3967 Old: &Task{ 3968 Resources: &Resources{ 3969 Devices: []*RequestedDevice{ 3970 { 3971 Name: "foo", 3972 Count: 2, 3973 }, 3974 { 3975 Name: "bar", 3976 Count: 2, 3977 }, 3978 { 3979 Name: "baz", 3980 Count: 2, 3981 }, 3982 }, 3983 }, 3984 }, 3985 New: &Task{ 3986 Resources: &Resources{ 3987 Devices: []*RequestedDevice{ 3988 { 3989 Name: "foo", 3990 Count: 2, 3991 }, 3992 { 3993 Name: "bar", 3994 Count: 3, 3995 }, 3996 { 3997 Name: "bam", 3998 Count: 2, 3999 }, 4000 }, 4001 }, 4002 }, 4003 Expected: &TaskDiff{ 4004 Type: DiffTypeEdited, 4005 Objects: []*ObjectDiff{ 4006 { 4007 Type: DiffTypeEdited, 4008 Name: "Resources", 4009 Objects: []*ObjectDiff{ 4010 { 4011 Type: DiffTypeEdited, 4012 Name: "Device", 4013 Fields: []*FieldDiff{ 4014 { 4015 Type: DiffTypeEdited, 4016 Name: "Count", 4017 Old: "2", 4018 New: "3", 4019 }, 4020 }, 4021 }, 4022 { 4023 Type: DiffTypeAdded, 4024 Name: "Device", 4025 Fields: []*FieldDiff{ 4026 { 4027 Type: DiffTypeAdded, 4028 Name: "Count", 4029 Old: "", 4030 New: "2", 4031 }, 4032 { 4033 Type: DiffTypeAdded, 4034 Name: "Name", 4035 Old: "", 4036 New: "bam", 4037 }, 4038 }, 4039 }, 4040 { 4041 Type: DiffTypeDeleted, 4042 Name: "Device", 4043 Fields: []*FieldDiff{ 4044 { 4045 Type: DiffTypeDeleted, 4046 Name: "Count", 4047 Old: "2", 4048 New: "", 4049 }, 4050 { 4051 Type: DiffTypeDeleted, 4052 Name: "Name", 4053 Old: "baz", 4054 New: "", 4055 }, 4056 }, 4057 }, 4058 }, 4059 }, 4060 }, 4061 }, 4062 }, 4063 { 4064 Name: "Device Resources edited with context", 4065 Contextual: true, 4066 Old: &Task{ 4067 Resources: &Resources{ 4068 CPU: 100, 4069 MemoryMB: 100, 4070 DiskMB: 100, 4071 Devices: []*RequestedDevice{ 4072 { 4073 Name: "foo", 4074 Count: 2, 4075 }, 4076 { 4077 Name: "bar", 4078 Count: 2, 4079 }, 4080 { 4081 Name: "baz", 4082 Count: 2, 4083 }, 4084 }, 4085 }, 4086 }, 4087 New: &Task{ 4088 Resources: &Resources{ 4089 CPU: 100, 4090 MemoryMB: 100, 4091 DiskMB: 100, 4092 Devices: []*RequestedDevice{ 4093 { 4094 Name: "foo", 4095 Count: 2, 4096 }, 4097 { 4098 Name: "bar", 4099 Count: 3, 4100 }, 4101 { 4102 Name: "bam", 4103 Count: 2, 4104 }, 4105 }, 4106 }, 4107 }, 4108 Expected: &TaskDiff{ 4109 Type: DiffTypeEdited, 4110 Objects: []*ObjectDiff{ 4111 { 4112 Type: DiffTypeEdited, 4113 Name: "Resources", 4114 Fields: []*FieldDiff{ 4115 { 4116 Type: DiffTypeNone, 4117 Name: "CPU", 4118 Old: "100", 4119 New: "100", 4120 }, 4121 { 4122 Type: DiffTypeNone, 4123 Name: "DiskMB", 4124 Old: "100", 4125 New: "100", 4126 }, 4127 { 4128 Type: DiffTypeNone, 4129 Name: "IOPS", 4130 Old: "0", 4131 New: "0", 4132 }, 4133 { 4134 Type: DiffTypeNone, 4135 Name: "MemoryMB", 4136 Old: "100", 4137 New: "100", 4138 }, 4139 }, 4140 Objects: []*ObjectDiff{ 4141 { 4142 Type: DiffTypeEdited, 4143 Name: "Device", 4144 Fields: []*FieldDiff{ 4145 { 4146 Type: DiffTypeEdited, 4147 Name: "Count", 4148 Old: "2", 4149 New: "3", 4150 }, 4151 { 4152 Type: DiffTypeNone, 4153 Name: "Name", 4154 Old: "bar", 4155 New: "bar", 4156 }, 4157 }, 4158 }, 4159 { 4160 Type: DiffTypeAdded, 4161 Name: "Device", 4162 Fields: []*FieldDiff{ 4163 { 4164 Type: DiffTypeAdded, 4165 Name: "Count", 4166 Old: "", 4167 New: "2", 4168 }, 4169 { 4170 Type: DiffTypeAdded, 4171 Name: "Name", 4172 Old: "", 4173 New: "bam", 4174 }, 4175 }, 4176 }, 4177 { 4178 Type: DiffTypeDeleted, 4179 Name: "Device", 4180 Fields: []*FieldDiff{ 4181 { 4182 Type: DiffTypeDeleted, 4183 Name: "Count", 4184 Old: "2", 4185 New: "", 4186 }, 4187 { 4188 Type: DiffTypeDeleted, 4189 Name: "Name", 4190 Old: "baz", 4191 New: "", 4192 }, 4193 }, 4194 }, 4195 }, 4196 }, 4197 }, 4198 }, 4199 }, 4200 { 4201 Name: "Config same", 4202 Old: &Task{ 4203 Config: map[string]interface{}{ 4204 "foo": 1, 4205 "bar": "bar", 4206 "bam": []string{"a", "b"}, 4207 "baz": map[string]int{ 4208 "a": 1, 4209 "b": 2, 4210 }, 4211 "boom": &Port{ 4212 Label: "boom_port", 4213 }, 4214 }, 4215 }, 4216 New: &Task{ 4217 Config: map[string]interface{}{ 4218 "foo": 1, 4219 "bar": "bar", 4220 "bam": []string{"a", "b"}, 4221 "baz": map[string]int{ 4222 "a": 1, 4223 "b": 2, 4224 }, 4225 "boom": &Port{ 4226 Label: "boom_port", 4227 }, 4228 }, 4229 }, 4230 Expected: &TaskDiff{ 4231 Type: DiffTypeNone, 4232 }, 4233 }, 4234 { 4235 Name: "Config edited", 4236 Old: &Task{ 4237 Config: map[string]interface{}{ 4238 "foo": 1, 4239 "bar": "baz", 4240 "bam": []string{"a", "b"}, 4241 "baz": map[string]int{ 4242 "a": 1, 4243 "b": 2, 4244 }, 4245 "boom": &Port{ 4246 Label: "boom_port", 4247 }, 4248 }, 4249 }, 4250 New: &Task{ 4251 Config: map[string]interface{}{ 4252 "foo": 2, 4253 "bar": "baz", 4254 "bam": []string{"a", "c", "d"}, 4255 "baz": map[string]int{ 4256 "b": 3, 4257 "c": 4, 4258 }, 4259 "boom": &Port{ 4260 Label: "boom_port2", 4261 }, 4262 }, 4263 }, 4264 Expected: &TaskDiff{ 4265 Type: DiffTypeEdited, 4266 Objects: []*ObjectDiff{ 4267 { 4268 Type: DiffTypeEdited, 4269 Name: "Config", 4270 Fields: []*FieldDiff{ 4271 { 4272 Type: DiffTypeEdited, 4273 Name: "bam[1]", 4274 Old: "b", 4275 New: "c", 4276 }, 4277 { 4278 Type: DiffTypeAdded, 4279 Name: "bam[2]", 4280 Old: "", 4281 New: "d", 4282 }, 4283 { 4284 Type: DiffTypeDeleted, 4285 Name: "baz[a]", 4286 Old: "1", 4287 New: "", 4288 }, 4289 { 4290 Type: DiffTypeEdited, 4291 Name: "baz[b]", 4292 Old: "2", 4293 New: "3", 4294 }, 4295 { 4296 Type: DiffTypeAdded, 4297 Name: "baz[c]", 4298 Old: "", 4299 New: "4", 4300 }, 4301 { 4302 Type: DiffTypeEdited, 4303 Name: "boom.Label", 4304 Old: "boom_port", 4305 New: "boom_port2", 4306 }, 4307 { 4308 Type: DiffTypeEdited, 4309 Name: "foo", 4310 Old: "1", 4311 New: "2", 4312 }, 4313 }, 4314 }, 4315 }, 4316 }, 4317 }, 4318 { 4319 Name: "Config edited with context", 4320 Contextual: true, 4321 Old: &Task{ 4322 Config: map[string]interface{}{ 4323 "foo": 1, 4324 "bar": "baz", 4325 "bam": []string{"a", "b"}, 4326 "baz": map[string]int{ 4327 "a": 1, 4328 "b": 2, 4329 }, 4330 "boom": &Port{ 4331 Label: "boom_port", 4332 }, 4333 }, 4334 }, 4335 New: &Task{ 4336 Config: map[string]interface{}{ 4337 "foo": 2, 4338 "bar": "baz", 4339 "bam": []string{"a", "c", "d"}, 4340 "baz": map[string]int{ 4341 "a": 1, 4342 "b": 2, 4343 }, 4344 "boom": &Port{ 4345 Label: "boom_port", 4346 }, 4347 }, 4348 }, 4349 Expected: &TaskDiff{ 4350 Type: DiffTypeEdited, 4351 Objects: []*ObjectDiff{ 4352 { 4353 Type: DiffTypeEdited, 4354 Name: "Config", 4355 Fields: []*FieldDiff{ 4356 { 4357 Type: DiffTypeNone, 4358 Name: "bam[0]", 4359 Old: "a", 4360 New: "a", 4361 }, 4362 { 4363 Type: DiffTypeEdited, 4364 Name: "bam[1]", 4365 Old: "b", 4366 New: "c", 4367 }, 4368 { 4369 Type: DiffTypeAdded, 4370 Name: "bam[2]", 4371 Old: "", 4372 New: "d", 4373 }, 4374 { 4375 Type: DiffTypeNone, 4376 Name: "bar", 4377 Old: "baz", 4378 New: "baz", 4379 }, 4380 { 4381 Type: DiffTypeNone, 4382 Name: "baz[a]", 4383 Old: "1", 4384 New: "1", 4385 }, 4386 { 4387 Type: DiffTypeNone, 4388 Name: "baz[b]", 4389 Old: "2", 4390 New: "2", 4391 }, 4392 { 4393 Type: DiffTypeNone, 4394 Name: "boom.Label", 4395 Old: "boom_port", 4396 New: "boom_port", 4397 }, 4398 { 4399 Type: DiffTypeNone, 4400 Name: "boom.To", 4401 Old: "0", 4402 New: "0", 4403 }, 4404 { 4405 Type: DiffTypeNone, 4406 Name: "boom.Value", 4407 Old: "0", 4408 New: "0", 4409 }, 4410 { 4411 Type: DiffTypeEdited, 4412 Name: "foo", 4413 Old: "1", 4414 New: "2", 4415 }, 4416 }, 4417 }, 4418 }, 4419 }, 4420 }, 4421 { 4422 Name: "Services edited (no checks)", 4423 Old: &Task{ 4424 Services: []*Service{ 4425 { 4426 Name: "foo", 4427 PortLabel: "foo", 4428 }, 4429 { 4430 Name: "bar", 4431 PortLabel: "bar", 4432 }, 4433 { 4434 Name: "baz", 4435 PortLabel: "baz", 4436 }, 4437 }, 4438 }, 4439 New: &Task{ 4440 Services: []*Service{ 4441 { 4442 Name: "bar", 4443 PortLabel: "bar", 4444 }, 4445 { 4446 Name: "baz", 4447 PortLabel: "baz2", 4448 }, 4449 { 4450 Name: "bam", 4451 PortLabel: "bam", 4452 }, 4453 }, 4454 }, 4455 Expected: &TaskDiff{ 4456 Type: DiffTypeEdited, 4457 Objects: []*ObjectDiff{ 4458 { 4459 Type: DiffTypeEdited, 4460 Name: "Service", 4461 Fields: []*FieldDiff{ 4462 { 4463 Type: DiffTypeEdited, 4464 Name: "PortLabel", 4465 Old: "baz", 4466 New: "baz2", 4467 }, 4468 }, 4469 }, 4470 { 4471 Type: DiffTypeAdded, 4472 Name: "Service", 4473 Fields: []*FieldDiff{ 4474 { 4475 Type: DiffTypeAdded, 4476 Name: "Name", 4477 Old: "", 4478 New: "bam", 4479 }, 4480 { 4481 Type: DiffTypeAdded, 4482 Name: "PortLabel", 4483 Old: "", 4484 New: "bam", 4485 }, 4486 }, 4487 }, 4488 { 4489 Type: DiffTypeDeleted, 4490 Name: "Service", 4491 Fields: []*FieldDiff{ 4492 { 4493 Type: DiffTypeDeleted, 4494 Name: "Name", 4495 Old: "foo", 4496 New: "", 4497 }, 4498 { 4499 Type: DiffTypeDeleted, 4500 Name: "PortLabel", 4501 Old: "foo", 4502 New: "", 4503 }, 4504 }, 4505 }, 4506 }, 4507 }, 4508 }, 4509 { 4510 Name: "Services edited (no checks) with context", 4511 Contextual: true, 4512 Old: &Task{ 4513 Services: []*Service{ 4514 { 4515 Name: "foo", 4516 PortLabel: "foo", 4517 }, 4518 }, 4519 }, 4520 New: &Task{ 4521 Services: []*Service{ 4522 { 4523 Name: "foo", 4524 PortLabel: "bar", 4525 AddressMode: "driver", 4526 }, 4527 }, 4528 }, 4529 Expected: &TaskDiff{ 4530 Type: DiffTypeEdited, 4531 Objects: []*ObjectDiff{ 4532 { 4533 Type: DiffTypeEdited, 4534 Name: "Service", 4535 Fields: []*FieldDiff{ 4536 { 4537 Type: DiffTypeAdded, 4538 Name: "AddressMode", 4539 New: "driver", 4540 }, 4541 { 4542 Type: DiffTypeNone, 4543 Name: "Name", 4544 Old: "foo", 4545 New: "foo", 4546 }, 4547 { 4548 Type: DiffTypeEdited, 4549 Name: "PortLabel", 4550 Old: "foo", 4551 New: "bar", 4552 }, 4553 }, 4554 }, 4555 }, 4556 }, 4557 }, 4558 { 4559 Name: "Services tags edited (no checks) with context", 4560 Contextual: true, 4561 Old: &Task{ 4562 Services: []*Service{ 4563 { 4564 Tags: []string{"foo", "bar"}, 4565 CanaryTags: []string{"foo", "bar"}, 4566 }, 4567 }, 4568 }, 4569 New: &Task{ 4570 Services: []*Service{ 4571 { 4572 Tags: []string{"bar", "bam"}, 4573 CanaryTags: []string{"bar", "bam"}, 4574 }, 4575 }, 4576 }, 4577 Expected: &TaskDiff{ 4578 Type: DiffTypeEdited, 4579 Objects: []*ObjectDiff{ 4580 { 4581 Type: DiffTypeEdited, 4582 Name: "Service", 4583 Objects: []*ObjectDiff{ 4584 { 4585 Type: DiffTypeEdited, 4586 Name: "CanaryTags", 4587 Fields: []*FieldDiff{ 4588 { 4589 Type: DiffTypeAdded, 4590 Name: "CanaryTags", 4591 Old: "", 4592 New: "bam", 4593 }, 4594 { 4595 Type: DiffTypeNone, 4596 Name: "CanaryTags", 4597 Old: "bar", 4598 New: "bar", 4599 }, 4600 { 4601 Type: DiffTypeDeleted, 4602 Name: "CanaryTags", 4603 Old: "foo", 4604 New: "", 4605 }, 4606 }, 4607 }, 4608 { 4609 Type: DiffTypeEdited, 4610 Name: "Tags", 4611 Fields: []*FieldDiff{ 4612 { 4613 Type: DiffTypeAdded, 4614 Name: "Tags", 4615 Old: "", 4616 New: "bam", 4617 }, 4618 { 4619 Type: DiffTypeNone, 4620 Name: "Tags", 4621 Old: "bar", 4622 New: "bar", 4623 }, 4624 { 4625 Type: DiffTypeDeleted, 4626 Name: "Tags", 4627 Old: "foo", 4628 New: "", 4629 }, 4630 }, 4631 }, 4632 }, 4633 Fields: []*FieldDiff{ 4634 { 4635 Type: DiffTypeNone, 4636 Name: "AddressMode", 4637 }, 4638 { 4639 Type: DiffTypeNone, 4640 Name: "Name", 4641 }, 4642 { 4643 Type: DiffTypeNone, 4644 Name: "PortLabel", 4645 }, 4646 }, 4647 }, 4648 }, 4649 }, 4650 }, 4651 4652 { 4653 Name: "Service with Connect", 4654 Old: &Task{ 4655 Services: []*Service{ 4656 { 4657 Name: "foo", 4658 }, 4659 }, 4660 }, 4661 New: &Task{ 4662 Services: []*Service{ 4663 { 4664 Name: "foo", 4665 Connect: &ConsulConnect{ 4666 SidecarService: &ConsulSidecarService{}, 4667 }, 4668 }, 4669 }, 4670 }, 4671 Expected: &TaskDiff{ 4672 Type: DiffTypeEdited, 4673 Objects: []*ObjectDiff{ 4674 { 4675 Type: DiffTypeEdited, 4676 Name: "Service", 4677 Objects: []*ObjectDiff{ 4678 { 4679 Type: DiffTypeAdded, 4680 Name: "ConsulConnect", 4681 Fields: []*FieldDiff{ 4682 { 4683 Type: DiffTypeAdded, 4684 Name: "Native", 4685 Old: "", 4686 New: "false", 4687 }, 4688 }, 4689 Objects: []*ObjectDiff{ 4690 { 4691 Type: DiffTypeAdded, 4692 Name: "SidecarService", 4693 }, 4694 }, 4695 }, 4696 }, 4697 }, 4698 }, 4699 }, 4700 }, 4701 4702 { 4703 Name: "Service Checks edited", 4704 Old: &Task{ 4705 Services: []*Service{ 4706 { 4707 Name: "foo", 4708 Checks: []*ServiceCheck{ 4709 { 4710 Name: "foo", 4711 Type: "http", 4712 Command: "foo", 4713 Args: []string{"foo"}, 4714 Path: "foo", 4715 Protocol: "http", 4716 Interval: 1 * time.Second, 4717 Timeout: 1 * time.Second, 4718 Header: map[string][]string{ 4719 "Foo": {"bar"}, 4720 }, 4721 }, 4722 { 4723 Name: "bar", 4724 Type: "http", 4725 Command: "foo", 4726 Args: []string{"foo"}, 4727 Path: "foo", 4728 Protocol: "http", 4729 Interval: 1 * time.Second, 4730 Timeout: 1 * time.Second, 4731 }, 4732 { 4733 Name: "baz", 4734 Type: "http", 4735 Command: "foo", 4736 Args: []string{"foo"}, 4737 Path: "foo", 4738 Protocol: "http", 4739 Interval: 1 * time.Second, 4740 Timeout: 1 * time.Second, 4741 }, 4742 }, 4743 }, 4744 }, 4745 }, 4746 New: &Task{ 4747 Services: []*Service{ 4748 { 4749 Name: "foo", 4750 Checks: []*ServiceCheck{ 4751 { 4752 Name: "bar", 4753 Type: "http", 4754 Command: "foo", 4755 Args: []string{"foo"}, 4756 Path: "foo", 4757 Protocol: "http", 4758 Interval: 1 * time.Second, 4759 Timeout: 1 * time.Second, 4760 }, 4761 { 4762 Name: "baz", 4763 Type: "tcp", 4764 Command: "foo", 4765 Args: []string{"foo"}, 4766 Path: "foo", 4767 Protocol: "http", 4768 Interval: 1 * time.Second, 4769 Timeout: 1 * time.Second, 4770 Header: map[string][]string{ 4771 "Eggs": {"spam"}, 4772 }, 4773 }, 4774 { 4775 Name: "bam", 4776 Type: "http", 4777 Command: "foo", 4778 Args: []string{"foo"}, 4779 Path: "foo", 4780 Protocol: "http", 4781 Interval: 1 * time.Second, 4782 Timeout: 1 * time.Second, 4783 }, 4784 }, 4785 }, 4786 }, 4787 }, 4788 Expected: &TaskDiff{ 4789 Type: DiffTypeEdited, 4790 Objects: []*ObjectDiff{ 4791 { 4792 Type: DiffTypeEdited, 4793 Name: "Service", 4794 Objects: []*ObjectDiff{ 4795 { 4796 Type: DiffTypeEdited, 4797 Name: "Check", 4798 Fields: []*FieldDiff{ 4799 { 4800 Type: DiffTypeEdited, 4801 Name: "Type", 4802 Old: "http", 4803 New: "tcp", 4804 }, 4805 }, 4806 Objects: []*ObjectDiff{ 4807 { 4808 Type: DiffTypeAdded, 4809 Name: "Header", 4810 Fields: []*FieldDiff{ 4811 { 4812 Type: DiffTypeAdded, 4813 Name: "Eggs[0]", 4814 Old: "", 4815 New: "spam", 4816 }, 4817 }, 4818 }, 4819 }, 4820 }, 4821 { 4822 Type: DiffTypeAdded, 4823 Name: "Check", 4824 Fields: []*FieldDiff{ 4825 { 4826 Type: DiffTypeAdded, 4827 Name: "Command", 4828 Old: "", 4829 New: "foo", 4830 }, 4831 { 4832 Type: DiffTypeAdded, 4833 Name: "GRPCUseTLS", 4834 Old: "", 4835 New: "false", 4836 }, 4837 { 4838 Type: DiffTypeAdded, 4839 Name: "Interval", 4840 Old: "", 4841 New: "1000000000", 4842 }, 4843 { 4844 Type: DiffTypeAdded, 4845 Name: "Name", 4846 Old: "", 4847 New: "bam", 4848 }, 4849 { 4850 Type: DiffTypeAdded, 4851 Name: "Path", 4852 Old: "", 4853 New: "foo", 4854 }, 4855 { 4856 Type: DiffTypeAdded, 4857 Name: "Protocol", 4858 Old: "", 4859 New: "http", 4860 }, 4861 { 4862 Type: DiffTypeAdded, 4863 Name: "TLSSkipVerify", 4864 Old: "", 4865 New: "false", 4866 }, 4867 { 4868 Type: DiffTypeAdded, 4869 Name: "Timeout", 4870 Old: "", 4871 New: "1000000000", 4872 }, 4873 { 4874 Type: DiffTypeAdded, 4875 Name: "Type", 4876 Old: "", 4877 New: "http", 4878 }, 4879 }, 4880 }, 4881 { 4882 Type: DiffTypeDeleted, 4883 Name: "Check", 4884 Fields: []*FieldDiff{ 4885 { 4886 Type: DiffTypeDeleted, 4887 Name: "Command", 4888 Old: "foo", 4889 New: "", 4890 }, 4891 { 4892 Type: DiffTypeDeleted, 4893 Name: "GRPCUseTLS", 4894 Old: "false", 4895 New: "", 4896 }, 4897 { 4898 Type: DiffTypeDeleted, 4899 Name: "Interval", 4900 Old: "1000000000", 4901 New: "", 4902 }, 4903 { 4904 Type: DiffTypeDeleted, 4905 Name: "Name", 4906 Old: "foo", 4907 New: "", 4908 }, 4909 { 4910 Type: DiffTypeDeleted, 4911 Name: "Path", 4912 Old: "foo", 4913 New: "", 4914 }, 4915 { 4916 Type: DiffTypeDeleted, 4917 Name: "Protocol", 4918 Old: "http", 4919 New: "", 4920 }, 4921 { 4922 Type: DiffTypeDeleted, 4923 Name: "TLSSkipVerify", 4924 Old: "false", 4925 New: "", 4926 }, 4927 { 4928 Type: DiffTypeDeleted, 4929 Name: "Timeout", 4930 Old: "1000000000", 4931 New: "", 4932 }, 4933 { 4934 Type: DiffTypeDeleted, 4935 Name: "Type", 4936 Old: "http", 4937 New: "", 4938 }, 4939 }, 4940 Objects: []*ObjectDiff{ 4941 { 4942 Type: DiffTypeDeleted, 4943 Name: "Header", 4944 Fields: []*FieldDiff{ 4945 { 4946 Type: DiffTypeDeleted, 4947 Name: "Foo[0]", 4948 Old: "bar", 4949 }, 4950 }, 4951 }, 4952 }, 4953 }, 4954 }, 4955 }, 4956 }, 4957 }, 4958 }, 4959 { 4960 Name: "Service Checks edited with context", 4961 Contextual: true, 4962 Old: &Task{ 4963 Services: []*Service{ 4964 { 4965 Name: "foo", 4966 Checks: []*ServiceCheck{ 4967 { 4968 Name: "foo", 4969 Type: "http", 4970 Command: "foo", 4971 Args: []string{"foo"}, 4972 Path: "foo", 4973 Protocol: "http", 4974 Interval: 1 * time.Second, 4975 Timeout: 1 * time.Second, 4976 InitialStatus: "critical", 4977 Header: map[string][]string{ 4978 "Foo": {"bar"}, 4979 }, 4980 }, 4981 }, 4982 }, 4983 }, 4984 }, 4985 New: &Task{ 4986 Services: []*Service{ 4987 { 4988 Name: "foo", 4989 Checks: []*ServiceCheck{ 4990 { 4991 Name: "foo", 4992 Type: "tcp", 4993 Command: "foo", 4994 Args: []string{"foo"}, 4995 Path: "foo", 4996 Protocol: "http", 4997 Interval: 1 * time.Second, 4998 Timeout: 1 * time.Second, 4999 InitialStatus: "passing", 5000 Method: "POST", 5001 Header: map[string][]string{ 5002 "Foo": {"bar", "baz"}, 5003 "Eggs": {"spam"}, 5004 }, 5005 }, 5006 }, 5007 }, 5008 }, 5009 }, 5010 Expected: &TaskDiff{ 5011 Type: DiffTypeEdited, 5012 Objects: []*ObjectDiff{ 5013 { 5014 Type: DiffTypeEdited, 5015 Name: "Service", 5016 Fields: []*FieldDiff{ 5017 { 5018 Type: DiffTypeNone, 5019 Name: "AddressMode", 5020 Old: "", 5021 New: "", 5022 }, 5023 { 5024 Type: DiffTypeNone, 5025 Name: "Name", 5026 Old: "foo", 5027 New: "foo", 5028 }, 5029 { 5030 Type: DiffTypeNone, 5031 Name: "PortLabel", 5032 Old: "", 5033 New: "", 5034 }, 5035 }, 5036 Objects: []*ObjectDiff{ 5037 { 5038 Type: DiffTypeEdited, 5039 Name: "Check", 5040 Fields: []*FieldDiff{ 5041 { 5042 Type: DiffTypeNone, 5043 Name: "AddressMode", 5044 Old: "", 5045 New: "", 5046 }, 5047 { 5048 Type: DiffTypeNone, 5049 Name: "Command", 5050 Old: "foo", 5051 New: "foo", 5052 }, 5053 { 5054 Type: DiffTypeNone, 5055 Name: "GRPCService", 5056 Old: "", 5057 New: "", 5058 }, 5059 { 5060 Type: DiffTypeNone, 5061 Name: "GRPCUseTLS", 5062 Old: "false", 5063 New: "false", 5064 }, 5065 { 5066 Type: DiffTypeEdited, 5067 Name: "InitialStatus", 5068 Old: "critical", 5069 New: "passing", 5070 }, 5071 { 5072 Type: DiffTypeNone, 5073 Name: "Interval", 5074 Old: "1000000000", 5075 New: "1000000000", 5076 }, 5077 { 5078 Type: DiffTypeAdded, 5079 Name: "Method", 5080 Old: "", 5081 New: "POST", 5082 }, 5083 { 5084 Type: DiffTypeNone, 5085 Name: "Name", 5086 Old: "foo", 5087 New: "foo", 5088 }, 5089 { 5090 Type: DiffTypeNone, 5091 Name: "Path", 5092 Old: "foo", 5093 New: "foo", 5094 }, 5095 { 5096 Type: DiffTypeNone, 5097 Name: "PortLabel", 5098 Old: "", 5099 New: "", 5100 }, 5101 { 5102 Type: DiffTypeNone, 5103 Name: "Protocol", 5104 Old: "http", 5105 New: "http", 5106 }, 5107 { 5108 Type: DiffTypeNone, 5109 Name: "TLSSkipVerify", 5110 Old: "false", 5111 New: "false", 5112 }, 5113 { 5114 Type: DiffTypeNone, 5115 Name: "TaskName", 5116 Old: "", 5117 New: "", 5118 }, 5119 { 5120 Type: DiffTypeNone, 5121 Name: "Timeout", 5122 Old: "1000000000", 5123 New: "1000000000", 5124 }, 5125 { 5126 Type: DiffTypeEdited, 5127 Name: "Type", 5128 Old: "http", 5129 New: "tcp", 5130 }, 5131 }, 5132 Objects: []*ObjectDiff{ 5133 { 5134 Type: DiffTypeEdited, 5135 Name: "Header", 5136 Fields: []*FieldDiff{ 5137 { 5138 Type: DiffTypeAdded, 5139 Name: "Eggs[0]", 5140 Old: "", 5141 New: "spam", 5142 }, 5143 { 5144 Type: DiffTypeNone, 5145 Name: "Foo[0]", 5146 Old: "bar", 5147 New: "bar", 5148 }, 5149 { 5150 Type: DiffTypeAdded, 5151 Name: "Foo[1]", 5152 Old: "", 5153 New: "baz", 5154 }, 5155 }, 5156 }, 5157 }, 5158 }, 5159 }, 5160 }, 5161 }, 5162 }, 5163 }, 5164 { 5165 Name: "CheckRestart edited", 5166 Old: &Task{ 5167 Services: []*Service{ 5168 { 5169 Name: "foo", 5170 Checks: []*ServiceCheck{ 5171 { 5172 Name: "foo", 5173 Type: "http", 5174 Command: "foo", 5175 Args: []string{"foo"}, 5176 Path: "foo", 5177 Protocol: "http", 5178 Interval: 1 * time.Second, 5179 Timeout: 1 * time.Second, 5180 }, 5181 { 5182 Name: "bar", 5183 Type: "http", 5184 Command: "foo", 5185 Args: []string{"foo"}, 5186 Path: "foo", 5187 Protocol: "http", 5188 Interval: 1 * time.Second, 5189 Timeout: 1 * time.Second, 5190 CheckRestart: &CheckRestart{ 5191 Limit: 2, 5192 Grace: 2 * time.Second, 5193 }, 5194 }, 5195 { 5196 Name: "baz", 5197 Type: "http", 5198 Command: "foo", 5199 Args: []string{"foo"}, 5200 Path: "foo", 5201 Protocol: "http", 5202 Interval: 1 * time.Second, 5203 Timeout: 1 * time.Second, 5204 CheckRestart: &CheckRestart{ 5205 Limit: 3, 5206 Grace: 3 * time.Second, 5207 }, 5208 }, 5209 }, 5210 }, 5211 }, 5212 }, 5213 New: &Task{ 5214 Services: []*Service{ 5215 { 5216 Name: "foo", 5217 Checks: []*ServiceCheck{ 5218 { 5219 Name: "foo", 5220 Type: "http", 5221 Command: "foo", 5222 Args: []string{"foo"}, 5223 Path: "foo", 5224 Protocol: "http", 5225 Interval: 1 * time.Second, 5226 Timeout: 1 * time.Second, 5227 CheckRestart: &CheckRestart{ 5228 Limit: 1, 5229 Grace: 1 * time.Second, 5230 }, 5231 }, 5232 { 5233 Name: "bar", 5234 Type: "http", 5235 Command: "foo", 5236 Args: []string{"foo"}, 5237 Path: "foo", 5238 Protocol: "http", 5239 Interval: 1 * time.Second, 5240 Timeout: 1 * time.Second, 5241 }, 5242 { 5243 Name: "baz", 5244 Type: "http", 5245 Command: "foo", 5246 Args: []string{"foo"}, 5247 Path: "foo", 5248 Protocol: "http", 5249 Interval: 1 * time.Second, 5250 Timeout: 1 * time.Second, 5251 CheckRestart: &CheckRestart{ 5252 Limit: 4, 5253 Grace: 4 * time.Second, 5254 }, 5255 }, 5256 }, 5257 }, 5258 }, 5259 }, 5260 Expected: &TaskDiff{ 5261 Type: DiffTypeEdited, 5262 Objects: []*ObjectDiff{ 5263 { 5264 Type: DiffTypeEdited, 5265 Name: "Service", 5266 Objects: []*ObjectDiff{ 5267 { 5268 Type: DiffTypeEdited, 5269 Name: "Check", 5270 Objects: []*ObjectDiff{ 5271 { 5272 Type: DiffTypeEdited, 5273 Name: "CheckRestart", 5274 Fields: []*FieldDiff{ 5275 { 5276 Type: DiffTypeEdited, 5277 Name: "Grace", 5278 Old: "3000000000", 5279 New: "4000000000", 5280 }, 5281 { 5282 Type: DiffTypeEdited, 5283 Name: "Limit", 5284 Old: "3", 5285 New: "4", 5286 }, 5287 }, 5288 }, 5289 }, 5290 }, 5291 { 5292 Type: DiffTypeEdited, 5293 Name: "Check", 5294 Objects: []*ObjectDiff{ 5295 { 5296 Type: DiffTypeAdded, 5297 Name: "CheckRestart", 5298 Fields: []*FieldDiff{ 5299 { 5300 Type: DiffTypeAdded, 5301 Name: "Grace", 5302 New: "1000000000", 5303 }, 5304 { 5305 Type: DiffTypeAdded, 5306 Name: "IgnoreWarnings", 5307 New: "false", 5308 }, 5309 { 5310 Type: DiffTypeAdded, 5311 Name: "Limit", 5312 New: "1", 5313 }, 5314 }, 5315 }, 5316 }, 5317 }, 5318 { 5319 Type: DiffTypeEdited, 5320 Name: "Check", 5321 Objects: []*ObjectDiff{ 5322 { 5323 Type: DiffTypeDeleted, 5324 Name: "CheckRestart", 5325 Fields: []*FieldDiff{ 5326 { 5327 Type: DiffTypeDeleted, 5328 Name: "Grace", 5329 Old: "2000000000", 5330 }, 5331 { 5332 Type: DiffTypeDeleted, 5333 Name: "IgnoreWarnings", 5334 Old: "false", 5335 }, 5336 { 5337 Type: DiffTypeDeleted, 5338 Name: "Limit", 5339 Old: "2", 5340 }, 5341 }, 5342 }, 5343 }, 5344 }, 5345 }, 5346 }, 5347 }, 5348 }, 5349 }, 5350 { 5351 Name: "Vault added", 5352 Old: &Task{}, 5353 New: &Task{ 5354 Vault: &Vault{ 5355 Policies: []string{"foo", "bar"}, 5356 Env: true, 5357 ChangeMode: "signal", 5358 ChangeSignal: "SIGUSR1", 5359 }, 5360 }, 5361 Expected: &TaskDiff{ 5362 Type: DiffTypeEdited, 5363 Objects: []*ObjectDiff{ 5364 { 5365 Type: DiffTypeAdded, 5366 Name: "Vault", 5367 Fields: []*FieldDiff{ 5368 { 5369 Type: DiffTypeAdded, 5370 Name: "ChangeMode", 5371 Old: "", 5372 New: "signal", 5373 }, 5374 { 5375 Type: DiffTypeAdded, 5376 Name: "ChangeSignal", 5377 Old: "", 5378 New: "SIGUSR1", 5379 }, 5380 { 5381 Type: DiffTypeAdded, 5382 Name: "Env", 5383 Old: "", 5384 New: "true", 5385 }, 5386 }, 5387 Objects: []*ObjectDiff{ 5388 { 5389 Type: DiffTypeAdded, 5390 Name: "Policies", 5391 Fields: []*FieldDiff{ 5392 { 5393 Type: DiffTypeAdded, 5394 Name: "Policies", 5395 Old: "", 5396 New: "bar", 5397 }, 5398 { 5399 Type: DiffTypeAdded, 5400 Name: "Policies", 5401 Old: "", 5402 New: "foo", 5403 }, 5404 }, 5405 }, 5406 }, 5407 }, 5408 }, 5409 }, 5410 }, 5411 { 5412 Name: "Vault deleted", 5413 Old: &Task{ 5414 Vault: &Vault{ 5415 Policies: []string{"foo", "bar"}, 5416 Env: true, 5417 ChangeMode: "signal", 5418 ChangeSignal: "SIGUSR1", 5419 }, 5420 }, 5421 New: &Task{}, 5422 Expected: &TaskDiff{ 5423 Type: DiffTypeEdited, 5424 Objects: []*ObjectDiff{ 5425 { 5426 Type: DiffTypeDeleted, 5427 Name: "Vault", 5428 Fields: []*FieldDiff{ 5429 { 5430 Type: DiffTypeDeleted, 5431 Name: "ChangeMode", 5432 Old: "signal", 5433 New: "", 5434 }, 5435 { 5436 Type: DiffTypeDeleted, 5437 Name: "ChangeSignal", 5438 Old: "SIGUSR1", 5439 New: "", 5440 }, 5441 { 5442 Type: DiffTypeDeleted, 5443 Name: "Env", 5444 Old: "true", 5445 New: "", 5446 }, 5447 }, 5448 Objects: []*ObjectDiff{ 5449 { 5450 Type: DiffTypeDeleted, 5451 Name: "Policies", 5452 Fields: []*FieldDiff{ 5453 { 5454 Type: DiffTypeDeleted, 5455 Name: "Policies", 5456 Old: "bar", 5457 New: "", 5458 }, 5459 { 5460 Type: DiffTypeDeleted, 5461 Name: "Policies", 5462 Old: "foo", 5463 New: "", 5464 }, 5465 }, 5466 }, 5467 }, 5468 }, 5469 }, 5470 }, 5471 }, 5472 { 5473 Name: "Vault edited", 5474 Old: &Task{ 5475 Vault: &Vault{ 5476 Policies: []string{"foo", "bar"}, 5477 Env: true, 5478 ChangeMode: "signal", 5479 ChangeSignal: "SIGUSR1", 5480 }, 5481 }, 5482 New: &Task{ 5483 Vault: &Vault{ 5484 Policies: []string{"bar", "baz"}, 5485 Env: false, 5486 ChangeMode: "restart", 5487 ChangeSignal: "foo", 5488 }, 5489 }, 5490 Expected: &TaskDiff{ 5491 Type: DiffTypeEdited, 5492 Objects: []*ObjectDiff{ 5493 { 5494 Type: DiffTypeEdited, 5495 Name: "Vault", 5496 Fields: []*FieldDiff{ 5497 { 5498 Type: DiffTypeEdited, 5499 Name: "ChangeMode", 5500 Old: "signal", 5501 New: "restart", 5502 }, 5503 { 5504 Type: DiffTypeEdited, 5505 Name: "ChangeSignal", 5506 Old: "SIGUSR1", 5507 New: "foo", 5508 }, 5509 { 5510 Type: DiffTypeEdited, 5511 Name: "Env", 5512 Old: "true", 5513 New: "false", 5514 }, 5515 }, 5516 Objects: []*ObjectDiff{ 5517 { 5518 Type: DiffTypeEdited, 5519 Name: "Policies", 5520 Fields: []*FieldDiff{ 5521 { 5522 Type: DiffTypeAdded, 5523 Name: "Policies", 5524 Old: "", 5525 New: "baz", 5526 }, 5527 { 5528 Type: DiffTypeDeleted, 5529 Name: "Policies", 5530 Old: "foo", 5531 New: "", 5532 }, 5533 }, 5534 }, 5535 }, 5536 }, 5537 }, 5538 }, 5539 }, 5540 { 5541 Name: "Vault edited with context", 5542 Contextual: true, 5543 Old: &Task{ 5544 Vault: &Vault{ 5545 Policies: []string{"foo", "bar"}, 5546 Env: true, 5547 ChangeMode: "signal", 5548 ChangeSignal: "SIGUSR1", 5549 }, 5550 }, 5551 New: &Task{ 5552 Vault: &Vault{ 5553 Policies: []string{"bar", "baz"}, 5554 Env: true, 5555 ChangeMode: "signal", 5556 ChangeSignal: "SIGUSR1", 5557 }, 5558 }, 5559 Expected: &TaskDiff{ 5560 Type: DiffTypeEdited, 5561 Objects: []*ObjectDiff{ 5562 { 5563 Type: DiffTypeEdited, 5564 Name: "Vault", 5565 Fields: []*FieldDiff{ 5566 { 5567 Type: DiffTypeNone, 5568 Name: "ChangeMode", 5569 Old: "signal", 5570 New: "signal", 5571 }, 5572 { 5573 Type: DiffTypeNone, 5574 Name: "ChangeSignal", 5575 Old: "SIGUSR1", 5576 New: "SIGUSR1", 5577 }, 5578 { 5579 Type: DiffTypeNone, 5580 Name: "Env", 5581 Old: "true", 5582 New: "true", 5583 }, 5584 }, 5585 Objects: []*ObjectDiff{ 5586 { 5587 Type: DiffTypeEdited, 5588 Name: "Policies", 5589 Fields: []*FieldDiff{ 5590 { 5591 Type: DiffTypeAdded, 5592 Name: "Policies", 5593 Old: "", 5594 New: "baz", 5595 }, 5596 { 5597 Type: DiffTypeNone, 5598 Name: "Policies", 5599 Old: "bar", 5600 New: "bar", 5601 }, 5602 { 5603 Type: DiffTypeDeleted, 5604 Name: "Policies", 5605 Old: "foo", 5606 New: "", 5607 }, 5608 }, 5609 }, 5610 }, 5611 }, 5612 }, 5613 }, 5614 }, 5615 { 5616 Name: "Template edited", 5617 Old: &Task{ 5618 Templates: []*Template{ 5619 { 5620 SourcePath: "foo", 5621 DestPath: "bar", 5622 EmbeddedTmpl: "baz", 5623 ChangeMode: "bam", 5624 ChangeSignal: "SIGHUP", 5625 Splay: 1, 5626 Perms: "0644", 5627 VaultGrace: 3 * time.Second, 5628 }, 5629 { 5630 SourcePath: "foo2", 5631 DestPath: "bar2", 5632 EmbeddedTmpl: "baz2", 5633 ChangeMode: "bam2", 5634 ChangeSignal: "SIGHUP2", 5635 Splay: 2, 5636 Perms: "0666", 5637 Envvars: true, 5638 VaultGrace: 5 * time.Second, 5639 }, 5640 }, 5641 }, 5642 New: &Task{ 5643 Templates: []*Template{ 5644 { 5645 SourcePath: "foo", 5646 DestPath: "bar", 5647 EmbeddedTmpl: "baz", 5648 ChangeMode: "bam", 5649 ChangeSignal: "SIGHUP", 5650 Splay: 1, 5651 Perms: "0644", 5652 VaultGrace: 3 * time.Second, 5653 }, 5654 { 5655 SourcePath: "foo3", 5656 DestPath: "bar3", 5657 EmbeddedTmpl: "baz3", 5658 ChangeMode: "bam3", 5659 ChangeSignal: "SIGHUP3", 5660 Splay: 3, 5661 Perms: "0776", 5662 VaultGrace: 10 * time.Second, 5663 }, 5664 }, 5665 }, 5666 Expected: &TaskDiff{ 5667 Type: DiffTypeEdited, 5668 Objects: []*ObjectDiff{ 5669 { 5670 Type: DiffTypeAdded, 5671 Name: "Template", 5672 Fields: []*FieldDiff{ 5673 { 5674 Type: DiffTypeAdded, 5675 Name: "ChangeMode", 5676 Old: "", 5677 New: "bam3", 5678 }, 5679 { 5680 Type: DiffTypeAdded, 5681 Name: "ChangeSignal", 5682 Old: "", 5683 New: "SIGHUP3", 5684 }, 5685 { 5686 Type: DiffTypeAdded, 5687 Name: "DestPath", 5688 Old: "", 5689 New: "bar3", 5690 }, 5691 { 5692 Type: DiffTypeAdded, 5693 Name: "EmbeddedTmpl", 5694 Old: "", 5695 New: "baz3", 5696 }, 5697 { 5698 Type: DiffTypeAdded, 5699 Name: "Envvars", 5700 Old: "", 5701 New: "false", 5702 }, 5703 { 5704 Type: DiffTypeAdded, 5705 Name: "Perms", 5706 Old: "", 5707 New: "0776", 5708 }, 5709 { 5710 Type: DiffTypeAdded, 5711 Name: "SourcePath", 5712 Old: "", 5713 New: "foo3", 5714 }, 5715 { 5716 Type: DiffTypeAdded, 5717 Name: "Splay", 5718 Old: "", 5719 New: "3", 5720 }, 5721 { 5722 Type: DiffTypeAdded, 5723 Name: "VaultGrace", 5724 Old: "", 5725 New: "10000000000", 5726 }, 5727 }, 5728 }, 5729 { 5730 Type: DiffTypeDeleted, 5731 Name: "Template", 5732 Fields: []*FieldDiff{ 5733 { 5734 Type: DiffTypeDeleted, 5735 Name: "ChangeMode", 5736 Old: "bam2", 5737 New: "", 5738 }, 5739 { 5740 Type: DiffTypeDeleted, 5741 Name: "ChangeSignal", 5742 Old: "SIGHUP2", 5743 New: "", 5744 }, 5745 { 5746 Type: DiffTypeDeleted, 5747 Name: "DestPath", 5748 Old: "bar2", 5749 New: "", 5750 }, 5751 { 5752 Type: DiffTypeDeleted, 5753 Name: "EmbeddedTmpl", 5754 Old: "baz2", 5755 New: "", 5756 }, 5757 { 5758 Type: DiffTypeDeleted, 5759 Name: "Envvars", 5760 Old: "true", 5761 New: "", 5762 }, 5763 { 5764 Type: DiffTypeDeleted, 5765 Name: "Perms", 5766 Old: "0666", 5767 New: "", 5768 }, 5769 { 5770 Type: DiffTypeDeleted, 5771 Name: "SourcePath", 5772 Old: "foo2", 5773 New: "", 5774 }, 5775 { 5776 Type: DiffTypeDeleted, 5777 Name: "Splay", 5778 Old: "2", 5779 New: "", 5780 }, 5781 { 5782 Type: DiffTypeDeleted, 5783 Name: "VaultGrace", 5784 Old: "5000000000", 5785 New: "", 5786 }, 5787 }, 5788 }, 5789 }, 5790 }, 5791 }, 5792 { 5793 Name: "DispatchPayload added", 5794 Old: &Task{}, 5795 New: &Task{ 5796 DispatchPayload: &DispatchPayloadConfig{ 5797 File: "foo", 5798 }, 5799 }, 5800 Expected: &TaskDiff{ 5801 Type: DiffTypeEdited, 5802 Objects: []*ObjectDiff{ 5803 { 5804 Type: DiffTypeAdded, 5805 Name: "DispatchPayload", 5806 Fields: []*FieldDiff{ 5807 { 5808 Type: DiffTypeAdded, 5809 Name: "File", 5810 Old: "", 5811 New: "foo", 5812 }, 5813 }, 5814 }, 5815 }, 5816 }, 5817 }, 5818 { 5819 Name: "DispatchPayload deleted", 5820 Old: &Task{ 5821 DispatchPayload: &DispatchPayloadConfig{ 5822 File: "foo", 5823 }, 5824 }, 5825 New: &Task{}, 5826 Expected: &TaskDiff{ 5827 Type: DiffTypeEdited, 5828 Objects: []*ObjectDiff{ 5829 { 5830 Type: DiffTypeDeleted, 5831 Name: "DispatchPayload", 5832 Fields: []*FieldDiff{ 5833 { 5834 Type: DiffTypeDeleted, 5835 Name: "File", 5836 Old: "foo", 5837 New: "", 5838 }, 5839 }, 5840 }, 5841 }, 5842 }, 5843 }, 5844 { 5845 Name: "Dispatch payload edited", 5846 Old: &Task{ 5847 DispatchPayload: &DispatchPayloadConfig{ 5848 File: "foo", 5849 }, 5850 }, 5851 New: &Task{ 5852 DispatchPayload: &DispatchPayloadConfig{ 5853 File: "bar", 5854 }, 5855 }, 5856 Expected: &TaskDiff{ 5857 Type: DiffTypeEdited, 5858 Objects: []*ObjectDiff{ 5859 { 5860 Type: DiffTypeEdited, 5861 Name: "DispatchPayload", 5862 Fields: []*FieldDiff{ 5863 { 5864 Type: DiffTypeEdited, 5865 Name: "File", 5866 Old: "foo", 5867 New: "bar", 5868 }, 5869 }, 5870 }, 5871 }, 5872 }, 5873 }, 5874 { 5875 // Place holder for if more fields are added 5876 Name: "DispatchPayload edited with context", 5877 Contextual: true, 5878 Old: &Task{ 5879 DispatchPayload: &DispatchPayloadConfig{ 5880 File: "foo", 5881 }, 5882 }, 5883 New: &Task{ 5884 DispatchPayload: &DispatchPayloadConfig{ 5885 File: "bar", 5886 }, 5887 }, 5888 Expected: &TaskDiff{ 5889 Type: DiffTypeEdited, 5890 Objects: []*ObjectDiff{ 5891 { 5892 Type: DiffTypeEdited, 5893 Name: "DispatchPayload", 5894 Fields: []*FieldDiff{ 5895 { 5896 Type: DiffTypeEdited, 5897 Name: "File", 5898 Old: "foo", 5899 New: "bar", 5900 }, 5901 }, 5902 }, 5903 }, 5904 }, 5905 }, 5906 } 5907 5908 for i, c := range cases { 5909 t.Run(c.Name, func(t *testing.T) { 5910 actual, err := c.Old.Diff(c.New, c.Contextual) 5911 if c.Error && err == nil { 5912 t.Fatalf("case %d: expected errored", i+1) 5913 } else if err != nil { 5914 if !c.Error { 5915 t.Fatalf("case %d: errored %#v", i+1, err) 5916 } else { 5917 return 5918 } 5919 } 5920 5921 if !reflect.DeepEqual(actual, c.Expected) { 5922 t.Errorf("case %d: got:\n%#v\n want:\n%#v\n", 5923 i+1, actual, c.Expected) 5924 } 5925 }) 5926 } 5927 }