github.com/elfadel/cilium@v1.6.12/pkg/health/server/prober_test.go (about) 1 // Copyright 2019 Authors of Cilium 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // +build !privileged_tests 16 17 package server 18 19 import ( 20 "bytes" 21 "fmt" 22 "net" 23 "sort" 24 "testing" 25 26 "github.com/cilium/cilium/api/v1/models" 27 "github.com/cilium/cilium/pkg/checker" 28 29 "gopkg.in/check.v1" 30 ) 31 32 func Test(t *testing.T) { check.TestingT(t) } 33 34 type HealthServerTestSuite struct{} 35 36 var _ = check.Suite(&HealthServerTestSuite{}) 37 38 func makeHealthNode(nodeIdx, healthIdx int) (healthNode, net.IP, net.IP) { 39 nodeIP := fmt.Sprintf("192.0.2.%d", nodeIdx) 40 healthIP := fmt.Sprintf("10.0.2.%d", healthIdx) 41 return healthNode{ 42 NodeElement: &models.NodeElement{ 43 Name: fmt.Sprintf("node-%d", nodeIdx), 44 PrimaryAddress: &models.NodeAddressing{ 45 IPV4: &models.NodeAddressingElement{ 46 IP: nodeIP, 47 Enabled: true, 48 }, 49 IPV6: &models.NodeAddressingElement{ 50 Enabled: false, 51 }, 52 }, 53 HealthEndpointAddress: &models.NodeAddressing{ 54 IPV4: &models.NodeAddressingElement{ 55 IP: healthIP, 56 Enabled: true, 57 }, 58 IPV6: &models.NodeAddressingElement{ 59 Enabled: false, 60 }, 61 }, 62 }, 63 }, net.ParseIP(nodeIP), net.ParseIP(healthIP) 64 } 65 66 func sortNodes(nodes map[string][]*net.IPAddr) map[string][]*net.IPAddr { 67 for _, slice := range nodes { 68 sort.Slice(slice, func(i, j int) bool { 69 iLength := len(slice[i].IP) 70 jLength := len(slice[j].IP) 71 if iLength == jLength { 72 return bytes.Compare(slice[i].IP, slice[j].IP) < 0 73 } 74 return iLength < jLength 75 }) 76 } 77 return nodes 78 } 79 80 func (s *HealthServerTestSuite) TestProbersetNodes(c *check.C) { 81 node1, node1IP, node1HealthIP := makeHealthNode(1, 1) 82 newNodes := nodeMap{ 83 ipString(node1.Name): node1, 84 } 85 86 // First up: Just create a prober with some nodes. 87 prober := newProber(&Server{}, newNodes) 88 nodes := prober.getIPsByNode() 89 expected := map[string][]*net.IPAddr{ 90 node1.Name: {{ 91 IP: node1IP, 92 }, { 93 IP: node1HealthIP, 94 }}, 95 } 96 c.Assert(sortNodes(nodes), checker.DeepEquals, sortNodes(expected)) 97 98 // Update the health IP and observe that it is updated. 99 // Note that update consists of delete and add in setNodes(). 100 node1, node1IP, node1HealthIP = makeHealthNode(1, 2) 101 modifiedNodes := nodeMap{ 102 ipString(node1.Name): node1, 103 } 104 prober.setNodes(modifiedNodes, newNodes) 105 nodes = prober.getIPsByNode() 106 expected = map[string][]*net.IPAddr{ 107 node1.Name: {{ 108 IP: node1IP, 109 }, { 110 IP: node1HealthIP, 111 }}, 112 } 113 c.Assert(sortNodes(nodes), checker.DeepEquals, sortNodes(expected)) 114 115 // Remove the nodes; they shouldn't be there any more 116 prober.setNodes(nil, modifiedNodes) 117 nodes = prober.getIPsByNode() 118 expected = map[string][]*net.IPAddr{} 119 c.Assert(sortNodes(nodes), checker.DeepEquals, sortNodes(expected)) 120 121 // Add back two nodes 122 node2, node2IP, node2HealthIP := makeHealthNode(2, 20) 123 updatedNodes := nodeMap{ 124 ipString(node1.Name): node1, 125 ipString(node2.Name): node2, 126 } 127 prober.setNodes(updatedNodes, nil) 128 nodes = prober.getIPsByNode() 129 expected = map[string][]*net.IPAddr{ 130 node1.Name: {{ 131 IP: node1IP, 132 }, { 133 IP: node1HealthIP, 134 }}, 135 node2.Name: {{ 136 IP: node2IP, 137 }, { 138 IP: node2HealthIP, 139 }}, 140 } 141 c.Assert(sortNodes(nodes), checker.DeepEquals, sortNodes(expected)) 142 143 // Update node 1. Node 2 should remain unaffected. 144 modifiedNodesOld := nodeMap{ 145 ipString(node1.Name): node1, 146 } 147 node1, node1IP, node1HealthIP = makeHealthNode(1, 5) 148 modifiedNodesNew := nodeMap{ 149 ipString(node1.Name): node1, 150 } 151 prober.setNodes(modifiedNodesNew, modifiedNodesOld) 152 nodes = prober.getIPsByNode() 153 expected[node1.Name] = []*net.IPAddr{{ 154 IP: node1IP, 155 }, { 156 IP: node1HealthIP, 157 }} 158 c.Assert(sortNodes(nodes), checker.DeepEquals, sortNodes(expected)) 159 160 // Remove node 1. Again, Node 2 should remain. 161 removedNodes := nodeMap{ 162 ipString(node1.Name): node1, 163 } 164 prober.setNodes(nil, removedNodes) 165 nodes = prober.getIPsByNode() 166 expected = map[string][]*net.IPAddr{ 167 node2.Name: {{ 168 IP: node2IP, 169 }, { 170 IP: node2HealthIP, 171 }}, 172 } 173 c.Assert(sortNodes(nodes), checker.DeepEquals, sortNodes(expected)) 174 }