|
1 | 1 | package routingtable_test |
2 | 2 |
|
3 | 3 | import ( |
| 4 | + "encoding/json" |
4 | 5 | "fmt" |
5 | 6 |
|
6 | 7 | mfakes "code.cloudfoundry.org/diego-logging-client/testhelpers" |
@@ -650,6 +651,128 @@ var _ = Describe("RoutingTable", func() { |
650 | 651 | }) |
651 | 652 | }) |
652 | 653 |
|
| 654 | + Context("when there is an existing routing key with options", func() { |
| 655 | + var desiredLRP *models.DesiredLRP |
| 656 | + |
| 657 | + createDesiredLRPWithOptions := func(options json.RawMessage) *models.DesiredLRP { |
| 658 | + routingInfo := cfroutes.CFRoutes{ |
| 659 | + { |
| 660 | + Hostnames: []string{hostname1, hostname2}, |
| 661 | + Port: key.ContainerPort, |
| 662 | + Options: options, |
| 663 | + }, |
| 664 | + }.RoutingInfo() |
| 665 | + routes := models.Routes{} |
| 666 | + for k, v := range routingInfo { |
| 667 | + routes[k] = v |
| 668 | + } |
| 669 | + return createDesiredLRPWithRoutes(key.ProcessGUID, 3, routes, logGuid, *currentTag, runInfo) |
| 670 | + } |
| 671 | + |
| 672 | + BeforeEach(func() { |
| 673 | + tempTable := routingtable.NewRoutingTable(false, false, fakeMetronClient) |
| 674 | + desiredLRP = createDesiredLRPWithOptions(json.RawMessage(`{"loadbalancing":"hash"}`)) |
| 675 | + tempTable.SetRoutes(logger, nil, desiredLRP) |
| 676 | + lrp := createActualLRP(key, endpoint1, domain) |
| 677 | + tempTable.AddEndpoint(logger, lrp) |
| 678 | + table.Swap(logger, tempTable, domains) |
| 679 | + }) |
| 680 | + |
| 681 | + Context("when only options change in an event", func() { |
| 682 | + BeforeEach(func() { |
| 683 | + afterDesiredLRP := createDesiredLRPWithOptions(json.RawMessage(`{"loadbalancing":"round-robin"}`)) |
| 684 | + afterDesiredLRP.ModificationTag.Index++ |
| 685 | + _, messagesToEmit = table.SetRoutes(logger, desiredLRP, afterDesiredLRP) |
| 686 | + }) |
| 687 | + |
| 688 | + It("registers the updated route without unregistering the old one", func() { |
| 689 | + expected := routingtable.MessagesToEmit{ |
| 690 | + RegistrationMessages: []routingtable.RegistryMessage{ |
| 691 | + routingtable.RegistryMessageFor(endpoint1, routingtable.Route{Hostname: hostname1, LogGUID: logGuid, Options: json.RawMessage(`{"loadbalancing":"round-robin"}`)}, false), |
| 692 | + routingtable.RegistryMessageFor(endpoint1, routingtable.Route{Hostname: hostname2, LogGUID: logGuid, Options: json.RawMessage(`{"loadbalancing":"round-robin"}`)}, false), |
| 693 | + }, |
| 694 | + } |
| 695 | + Expect(messagesToEmit).To(MatchMessagesToEmit(expected)) |
| 696 | + }) |
| 697 | + }) |
| 698 | + |
| 699 | + Context("when only options change during sync", func() { |
| 700 | + BeforeEach(func() { |
| 701 | + tempTable := routingtable.NewRoutingTable(false, false, fakeMetronClient) |
| 702 | + afterDesiredLRP := createDesiredLRPWithOptions(json.RawMessage(`{"loadbalancing":"round-robin"}`)) |
| 703 | + tempTable.SetRoutes(logger, nil, afterDesiredLRP) |
| 704 | + lrp := createActualLRP(key, endpoint1, domain) |
| 705 | + tempTable.AddEndpoint(logger, lrp) |
| 706 | + _, messagesToEmit = table.Swap(logger, tempTable, domains) |
| 707 | + }) |
| 708 | + |
| 709 | + It("registers the updated route without unregistering the old one", func() { |
| 710 | + expected := routingtable.MessagesToEmit{ |
| 711 | + RegistrationMessages: []routingtable.RegistryMessage{ |
| 712 | + routingtable.RegistryMessageFor(endpoint1, routingtable.Route{Hostname: hostname1, LogGUID: logGuid, Options: json.RawMessage(`{"loadbalancing":"round-robin"}`)}, false), |
| 713 | + routingtable.RegistryMessageFor(endpoint1, routingtable.Route{Hostname: hostname2, LogGUID: logGuid, Options: json.RawMessage(`{"loadbalancing":"round-robin"}`)}, false), |
| 714 | + }, |
| 715 | + } |
| 716 | + Expect(messagesToEmit).To(MatchMessagesToEmit(expected)) |
| 717 | + }) |
| 718 | + }) |
| 719 | + |
| 720 | + Context("when options change and endpoints change simultaneously during sync", func() { |
| 721 | + BeforeEach(func() { |
| 722 | + tempTable := routingtable.NewRoutingTable(false, false, fakeMetronClient) |
| 723 | + afterDesiredLRP := createDesiredLRPWithOptions(json.RawMessage(`{"loadbalancing":"round-robin"}`)) |
| 724 | + tempTable.SetRoutes(logger, nil, afterDesiredLRP) |
| 725 | + lrp := createActualLRP(key, endpoint2, domain) |
| 726 | + tempTable.AddEndpoint(logger, lrp) |
| 727 | + _, messagesToEmit = table.Swap(logger, tempTable, domains) |
| 728 | + }) |
| 729 | + |
| 730 | + It("registers the new endpoint with new options and unregisters the old endpoint with old options", func() { |
| 731 | + expected := routingtable.MessagesToEmit{ |
| 732 | + RegistrationMessages: []routingtable.RegistryMessage{ |
| 733 | + routingtable.RegistryMessageFor(endpoint2, routingtable.Route{Hostname: hostname1, LogGUID: logGuid, Options: json.RawMessage(`{"loadbalancing":"round-robin"}`)}, false), |
| 734 | + routingtable.RegistryMessageFor(endpoint2, routingtable.Route{Hostname: hostname2, LogGUID: logGuid, Options: json.RawMessage(`{"loadbalancing":"round-robin"}`)}, false), |
| 735 | + }, |
| 736 | + UnregistrationMessages: []routingtable.RegistryMessage{ |
| 737 | + routingtable.RegistryMessageFor(endpoint1, routingtable.Route{Hostname: hostname1, LogGUID: logGuid, Options: json.RawMessage(`{"loadbalancing":"hash"}`)}, false), |
| 738 | + routingtable.RegistryMessageFor(endpoint1, routingtable.Route{Hostname: hostname2, LogGUID: logGuid, Options: json.RawMessage(`{"loadbalancing":"hash"}`)}, false), |
| 739 | + }, |
| 740 | + } |
| 741 | + Expect(messagesToEmit).To(MatchMessagesToEmit(expected)) |
| 742 | + }) |
| 743 | + }) |
| 744 | + |
| 745 | + Context("when options change and a hostname is removed in the same event", func() { |
| 746 | + BeforeEach(func() { |
| 747 | + routingInfo := cfroutes.CFRoutes{ |
| 748 | + { |
| 749 | + Hostnames: []string{hostname1}, |
| 750 | + Port: key.ContainerPort, |
| 751 | + Options: json.RawMessage(`{"loadbalancing":"round-robin"}`), |
| 752 | + }, |
| 753 | + }.RoutingInfo() |
| 754 | + routes := models.Routes{} |
| 755 | + for k, v := range routingInfo { |
| 756 | + routes[k] = v |
| 757 | + } |
| 758 | + afterDesiredLRP := createDesiredLRPWithRoutes(key.ProcessGUID, 3, routes, logGuid, *newerTag, runInfo) |
| 759 | + _, messagesToEmit = table.SetRoutes(logger, desiredLRP, afterDesiredLRP) |
| 760 | + }) |
| 761 | + |
| 762 | + It("registers hostname1 with new options and unregisters hostname2 without a gap", func() { |
| 763 | + expected := routingtable.MessagesToEmit{ |
| 764 | + RegistrationMessages: []routingtable.RegistryMessage{ |
| 765 | + routingtable.RegistryMessageFor(endpoint1, routingtable.Route{Hostname: hostname1, LogGUID: logGuid, Options: json.RawMessage(`{"loadbalancing":"round-robin"}`)}, false), |
| 766 | + }, |
| 767 | + UnregistrationMessages: []routingtable.RegistryMessage{ |
| 768 | + routingtable.RegistryMessageFor(endpoint1, routingtable.Route{Hostname: hostname2, LogGUID: logGuid, Options: json.RawMessage(`{"loadbalancing":"hash"}`)}, false), |
| 769 | + }, |
| 770 | + } |
| 771 | + Expect(messagesToEmit).To(MatchMessagesToEmit(expected)) |
| 772 | + }) |
| 773 | + }) |
| 774 | + }) |
| 775 | + |
653 | 776 | Context("when the routing key has an evacuating and instance endpoint", func() { |
654 | 777 | BeforeEach(func() { |
655 | 778 | tempTable := routingtable.NewRoutingTable(false, false, fakeMetronClient) |
|
0 commit comments