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