github.com/zhyoulun/cilium@v1.6.12/pkg/node/manager/manager_test.go (about) 1 // Copyright 2018-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 manager 18 19 import ( 20 "fmt" 21 "sync" 22 "testing" 23 "time" 24 25 "github.com/cilium/cilium/pkg/checker" 26 "github.com/cilium/cilium/pkg/datapath" 27 "github.com/cilium/cilium/pkg/datapath/fake" 28 "github.com/cilium/cilium/pkg/node" 29 "github.com/cilium/cilium/pkg/source" 30 31 "gopkg.in/check.v1" 32 ) 33 34 func Test(t *testing.T) { 35 check.TestingT(t) 36 } 37 38 type managerTestSuite struct{} 39 40 var _ = check.Suite(&managerTestSuite{}) 41 42 type signalNodeHandler struct { 43 EnableNodeAddEvent bool 44 NodeAddEvent chan node.Node 45 NodeUpdateEvent chan node.Node 46 EnableNodeUpdateEvent bool 47 NodeDeleteEvent chan node.Node 48 EnableNodeDeleteEvent bool 49 NodeValidateImplementationEvent chan node.Node 50 EnableNodeValidateImplementationEvent bool 51 } 52 53 func newSignalNodeHandler() *signalNodeHandler { 54 return &signalNodeHandler{ 55 NodeAddEvent: make(chan node.Node, 10), 56 NodeUpdateEvent: make(chan node.Node, 10), 57 NodeDeleteEvent: make(chan node.Node, 10), 58 NodeValidateImplementationEvent: make(chan node.Node, 4096), 59 } 60 } 61 62 func (n *signalNodeHandler) NodeAdd(newNode node.Node) error { 63 if n.EnableNodeAddEvent { 64 n.NodeAddEvent <- newNode 65 } 66 return nil 67 } 68 69 func (n *signalNodeHandler) NodeUpdate(oldNode, newNode node.Node) error { 70 if n.EnableNodeUpdateEvent { 71 n.NodeUpdateEvent <- newNode 72 } 73 return nil 74 } 75 76 func (n *signalNodeHandler) NodeDelete(node node.Node) error { 77 if n.EnableNodeDeleteEvent { 78 n.NodeDeleteEvent <- node 79 } 80 return nil 81 } 82 83 func (n *signalNodeHandler) NodeValidateImplementation(node node.Node) error { 84 if n.EnableNodeValidateImplementationEvent { 85 n.NodeValidateImplementationEvent <- node 86 } 87 return nil 88 } 89 90 func (n *signalNodeHandler) NodeConfigurationChanged(config datapath.LocalNodeConfiguration) error { 91 return nil 92 } 93 94 func (s *managerTestSuite) TestNodeLifecycle(c *check.C) { 95 dp := newSignalNodeHandler() 96 dp.EnableNodeAddEvent = true 97 dp.EnableNodeUpdateEvent = true 98 dp.EnableNodeDeleteEvent = true 99 mngr, err := NewManager("test", dp) 100 c.Assert(err, check.IsNil) 101 102 n1 := node.Node{Name: "node1", Cluster: "c1"} 103 mngr.NodeUpdated(n1) 104 105 select { 106 case nodeEvent := <-dp.NodeAddEvent: 107 c.Assert(nodeEvent, checker.DeepEquals, n1) 108 case nodeEvent := <-dp.NodeUpdateEvent: 109 c.Errorf("Unexpected NodeUpdate() event %#v", nodeEvent) 110 case nodeEvent := <-dp.NodeDeleteEvent: 111 c.Errorf("Unexpected NodeDelete() event %#v", nodeEvent) 112 case <-time.After(3 * time.Second): 113 c.Errorf("timeout while waiting for NodeAdd() event for node1") 114 } 115 116 n2 := node.Node{Name: "node2", Cluster: "c1"} 117 mngr.NodeUpdated(n2) 118 119 select { 120 case nodeEvent := <-dp.NodeAddEvent: 121 c.Assert(nodeEvent, checker.DeepEquals, n2) 122 case nodeEvent := <-dp.NodeUpdateEvent: 123 c.Errorf("Unexpected NodeUpdate() event %#v", nodeEvent) 124 case nodeEvent := <-dp.NodeDeleteEvent: 125 c.Errorf("Unexpected NodeDelete() event %#v", nodeEvent) 126 case <-time.After(3 * time.Second): 127 c.Errorf("timeout while waiting for NodeUpdate() event for node2") 128 } 129 130 nodes := mngr.GetNodes() 131 n, ok := nodes[n1.Identity()] 132 c.Assert(ok, check.Equals, true) 133 c.Assert(n, checker.DeepEquals, n1) 134 135 mngr.NodeDeleted(n1) 136 select { 137 case nodeEvent := <-dp.NodeDeleteEvent: 138 c.Assert(nodeEvent, checker.DeepEquals, n1) 139 case nodeEvent := <-dp.NodeAddEvent: 140 c.Errorf("Unexpected NodeAdd() event %#v", nodeEvent) 141 case nodeEvent := <-dp.NodeUpdateEvent: 142 c.Errorf("Unexpected NodeUpdate() event %#v", nodeEvent) 143 case <-time.After(3 * time.Second): 144 c.Errorf("timeout while waiting for NodeDelete() event for node1") 145 } 146 nodes = mngr.GetNodes() 147 _, ok = nodes[n1.Identity()] 148 c.Assert(ok, check.Equals, false) 149 150 mngr.Close() 151 select { 152 case nodeEvent := <-dp.NodeDeleteEvent: 153 c.Assert(nodeEvent, checker.DeepEquals, n2) 154 case nodeEvent := <-dp.NodeAddEvent: 155 c.Errorf("Unexpected NodeAdd() event %#v", nodeEvent) 156 case nodeEvent := <-dp.NodeUpdateEvent: 157 c.Errorf("Unexpected NodeUpdate() event %#v", nodeEvent) 158 case <-time.After(3 * time.Second): 159 c.Errorf("timeout while waiting for NodeDelete() event for node2") 160 } 161 } 162 163 func (s *managerTestSuite) TestMultipleSources(c *check.C) { 164 dp := newSignalNodeHandler() 165 dp.EnableNodeAddEvent = true 166 dp.EnableNodeUpdateEvent = true 167 dp.EnableNodeDeleteEvent = true 168 mngr, err := NewManager("test", dp) 169 c.Assert(err, check.IsNil) 170 defer mngr.Close() 171 172 n1k8s := node.Node{Name: "node1", Cluster: "c1", Source: source.Kubernetes} 173 mngr.NodeUpdated(n1k8s) 174 select { 175 case nodeEvent := <-dp.NodeAddEvent: 176 c.Assert(nodeEvent, checker.DeepEquals, n1k8s) 177 case nodeEvent := <-dp.NodeUpdateEvent: 178 c.Errorf("Unexpected NodeUpdate() event %#v", nodeEvent) 179 case nodeEvent := <-dp.NodeDeleteEvent: 180 c.Errorf("Unexpected NodeDelete() event %#v", nodeEvent) 181 case <-time.After(3 * time.Second): 182 c.Errorf("timeout while waiting for NodeAdd() event for node1") 183 } 184 185 // agent can overwrite kubernetes 186 n1agent := node.Node{Name: "node1", Cluster: "c1", Source: source.Local} 187 mngr.NodeUpdated(n1agent) 188 select { 189 case nodeEvent := <-dp.NodeUpdateEvent: 190 c.Assert(nodeEvent, checker.DeepEquals, n1agent) 191 case nodeEvent := <-dp.NodeAddEvent: 192 c.Errorf("Unexpected NodeAdd() event %#v", nodeEvent) 193 case nodeEvent := <-dp.NodeDeleteEvent: 194 c.Errorf("Unexpected NodeDelete() event %#v", nodeEvent) 195 case <-time.After(3 * time.Second): 196 c.Errorf("timeout while waiting for NodeUpdate() event for node1") 197 } 198 199 // kubernetes cannot overwrite local node 200 mngr.NodeUpdated(n1k8s) 201 select { 202 case nodeEvent := <-dp.NodeAddEvent: 203 c.Errorf("Unexpected NodeAdd() event %#v", nodeEvent) 204 case nodeEvent := <-dp.NodeUpdateEvent: 205 c.Errorf("Unexpected NodeUpdate() event %#v", nodeEvent) 206 case nodeEvent := <-dp.NodeDeleteEvent: 207 c.Errorf("Unexpected NodeDelete() event %#v", nodeEvent) 208 case <-time.After(100 * time.Millisecond): 209 } 210 211 // delete from kubernetes, should not remove local node 212 mngr.NodeDeleted(n1k8s) 213 select { 214 case nodeEvent := <-dp.NodeAddEvent: 215 c.Errorf("Unexpected NodeAdd() event %#v", nodeEvent) 216 case nodeEvent := <-dp.NodeUpdateEvent: 217 c.Errorf("Unexpected NodeUpdate() event %#v", nodeEvent) 218 case nodeEvent := <-dp.NodeDeleteEvent: 219 c.Errorf("Unexpected NodeDelete() event %#v", nodeEvent) 220 case <-time.After(100 * time.Millisecond): 221 } 222 223 mngr.NodeDeleted(n1agent) 224 select { 225 case nodeEvent := <-dp.NodeAddEvent: 226 c.Errorf("Unexpected NodeAdd() event %#v", nodeEvent) 227 case nodeEvent := <-dp.NodeUpdateEvent: 228 c.Errorf("Unexpected NodeUpdate() event %#v", nodeEvent) 229 case nodeEvent := <-dp.NodeDeleteEvent: 230 c.Assert(nodeEvent, checker.DeepEquals, n1agent) 231 case <-time.After(3 * time.Second): 232 c.Errorf("timeout while waiting for NodeDelete() event for node1") 233 } 234 } 235 236 func (s *managerTestSuite) BenchmarkUpdateAndDeleteCycle(c *check.C) { 237 mngr, err := NewManager("test", fake.NewNodeHandler()) 238 c.Assert(err, check.IsNil) 239 defer mngr.Close() 240 241 c.ResetTimer() 242 for i := 0; i < c.N; i++ { 243 n := node.Node{Name: fmt.Sprintf("%d", i), Source: source.Local} 244 mngr.NodeUpdated(n) 245 } 246 247 for i := 0; i < c.N; i++ { 248 n := node.Node{Name: fmt.Sprintf("%d", i), Source: source.Local} 249 mngr.NodeDeleted(n) 250 } 251 c.StopTimer() 252 } 253 254 func (s *managerTestSuite) TestClusterSizeDependantInterval(c *check.C) { 255 mngr, err := NewManager("test", fake.NewNodeHandler()) 256 c.Assert(err, check.IsNil) 257 defer mngr.Close() 258 259 prevInterval := time.Nanosecond 260 261 for i := 0; i < 1000; i++ { 262 n := node.Node{Name: fmt.Sprintf("%d", i), Source: source.Local} 263 mngr.NodeUpdated(n) 264 newInterval := mngr.ClusterSizeDependantInterval(time.Minute) 265 c.Assert(newInterval > prevInterval, check.Equals, true) 266 } 267 } 268 269 func (s *managerTestSuite) TestBackgroundSync(c *check.C) { 270 c.Skip("GH-6751 Test is disabled due to being unstable") 271 272 // set the base background sync interval to a very low value so the 273 // background sync runs aggressively 274 baseBackgroundSyncIntervalBackup := baseBackgroundSyncInterval 275 baseBackgroundSyncInterval = 10 * time.Millisecond 276 defer func() { baseBackgroundSyncInterval = baseBackgroundSyncIntervalBackup }() 277 278 signalNodeHandler := newSignalNodeHandler() 279 signalNodeHandler.EnableNodeValidateImplementationEvent = true 280 mngr, err := NewManager("test", signalNodeHandler) 281 c.Assert(err, check.IsNil) 282 defer mngr.Close() 283 284 numNodes := 4096 285 286 allNodeValidateCallsReceived := &sync.WaitGroup{} 287 allNodeValidateCallsReceived.Add(1) 288 289 go func() { 290 nodeValidationsReceived := 0 291 for { 292 select { 293 case <-signalNodeHandler.NodeValidateImplementationEvent: 294 nodeValidationsReceived++ 295 if nodeValidationsReceived >= numNodes { 296 allNodeValidateCallsReceived.Done() 297 return 298 } 299 case <-time.After(time.Second * 5): 300 c.Errorf("Timeout while waiting for NodeValidateImplementation() to be called") 301 } 302 } 303 }() 304 305 for i := 0; i < numNodes; i++ { 306 n := node.Node{Name: fmt.Sprintf("%d", i), Source: source.Kubernetes} 307 mngr.NodeUpdated(n) 308 } 309 310 allNodeValidateCallsReceived.Wait() 311 }