github.com/annwntech/go-micro/v2@v2.9.5/network/node_test.go (about) 1 package network 2 3 import ( 4 "testing" 5 "time" 6 7 pb "github.com/annwntech/go-micro/v2/network/service/proto" 8 ) 9 10 var ( 11 testNodeId = "testNode" 12 testNodeAddress = "testAddress" 13 testNodeNetName = "testNetwork" 14 testNodePeerIds = []string{"peer1", "peer2", "peer3"} 15 testPeerOfPeerIds = []string{"peer11", "peer12"} 16 ) 17 18 func testSetup() *node { 19 testNode := &node{ 20 id: testNodeId, 21 address: testNodeAddress, 22 peers: make(map[string]*node), 23 network: newNetwork(Name(testNodeNetName)), 24 status: newStatus(), 25 } 26 27 // add some peers to the node 28 for _, id := range testNodePeerIds { 29 testNode.peers[id] = &node{ 30 id: id, 31 address: testNode.address + "-" + id, 32 peers: make(map[string]*node), 33 network: testNode.network, 34 status: newStatus(), 35 } 36 } 37 38 // add peers to peer1 39 // NOTE: these are peers of peers! 40 for _, id := range testPeerOfPeerIds { 41 testNode.peers["peer1"].peers[id] = &node{ 42 id: id, 43 address: testNode.address + "-" + id, 44 peers: make(map[string]*node), 45 network: testNode.network, 46 status: newStatus(), 47 } 48 } 49 50 // connect peer1 with peer2 51 testNode.peers["peer1"].peers["peer2"] = testNode.peers["peer2"] 52 // connect peer2 with peer3 53 testNode.peers["peer2"].peers["peer3"] = testNode.peers["peer3"] 54 55 return testNode 56 } 57 58 func TestNodeId(t *testing.T) { 59 node := testSetup() 60 if node.Id() != testNodeId { 61 t.Errorf("Expected id: %s, found: %s", testNodeId, node.Id()) 62 } 63 } 64 65 func TestNodeAddress(t *testing.T) { 66 node := testSetup() 67 if node.Address() != testNodeAddress { 68 t.Errorf("Expected address: %s, found: %s", testNodeAddress, node.Address()) 69 } 70 } 71 func TestNodeNetwork(t *testing.T) { 72 node := testSetup() 73 if node.Network().Name() != testNodeNetName { 74 t.Errorf("Expected network: %s, found: %s", testNodeNetName, node.Network().Name()) 75 } 76 } 77 78 func TestNodes(t *testing.T) { 79 // single node 80 single := &node{ 81 id: testNodeId, 82 address: testNodeAddress, 83 peers: make(map[string]*node), 84 network: newNetwork(Name(testNodeNetName)), 85 } 86 // get all the nodes including yourself 87 nodes := single.Nodes() 88 nodeCount := 1 89 90 if len(nodes) != nodeCount { 91 t.Errorf("Expected to find %d nodes, found: %d", nodeCount, len(nodes)) 92 } 93 94 // complicated node graph 95 node := testSetup() 96 // get all the nodes including yourself 97 nodes = node.Nodes() 98 99 // compile a list of ids of all nodes in the network into map for easy indexing 100 nodeIds := make(map[string]bool) 101 // add yourself 102 nodeIds[node.id] = true 103 // add peer Ids 104 for _, id := range testNodePeerIds { 105 nodeIds[id] = true 106 } 107 // add peer1 peers i.e. peers of peer 108 for _, id := range testPeerOfPeerIds { 109 nodeIds[id] = true 110 } 111 112 // we should return the correct number of nodes 113 if len(nodes) != len(nodeIds) { 114 t.Errorf("Expected %d nodes, found: %d", len(nodeIds), len(nodes)) 115 } 116 117 // iterate through the list of nodes and makes sure all have been returned 118 for _, node := range nodes { 119 if _, ok := nodeIds[node.Id()]; !ok { 120 t.Errorf("Expected to find %s node", node.Id()) 121 } 122 } 123 124 // this is a leaf node 125 id := "peer11" 126 if nodePeer := node.GetPeerNode(id); nodePeer == nil { 127 t.Errorf("Expected to find %s node", id) 128 } 129 } 130 131 func collectPeerIds(peer Node, ids map[string]bool) map[string]bool { 132 if len(peer.Peers()) == 0 { 133 return ids 134 } 135 136 // iterate through the whole graph 137 for _, peer := range peer.Peers() { 138 ids = collectPeerIds(peer, ids) 139 if _, ok := ids[peer.Id()]; !ok { 140 ids[peer.Id()] = true 141 } 142 } 143 144 return ids 145 } 146 147 func TestPeers(t *testing.T) { 148 // single node 149 single := &node{ 150 id: testNodeId, 151 address: testNodeAddress, 152 peers: make(map[string]*node), 153 network: newNetwork(Name(testNodeNetName)), 154 } 155 // get node peers 156 peers := single.Peers() 157 // there should be no peers 158 peerCount := 0 159 160 if len(peers) != peerCount { 161 t.Errorf("Expected to find %d nodes, found: %d", peerCount, len(peers)) 162 } 163 164 // complicated node graph 165 node := testSetup() 166 // list of ids of nodes of MaxDepth 167 peerIds := make(map[string]bool) 168 // add peer Ids 169 for _, id := range testNodePeerIds { 170 peerIds[id] = true 171 } 172 // add peers of peers to peerIds 173 for _, id := range testPeerOfPeerIds { 174 peerIds[id] = true 175 } 176 // get node peers 177 peers = node.Peers() 178 179 // we will collect all returned Peer Ids into this map 180 resPeerIds := make(map[string]bool) 181 for _, peer := range peers { 182 resPeerIds[peer.Id()] = true 183 resPeerIds = collectPeerIds(peer, resPeerIds) 184 } 185 186 // if correct, we must collect all peerIds 187 if len(resPeerIds) != len(peerIds) { 188 t.Errorf("Expected to find %d peers, found: %d", len(peerIds), len(resPeerIds)) 189 } 190 191 for id := range resPeerIds { 192 if _, ok := peerIds[id]; !ok { 193 t.Errorf("Expected to find %s peer", id) 194 } 195 } 196 } 197 198 func TestDeletePeerNode(t *testing.T) { 199 // complicated node graph 200 node := testSetup() 201 202 nodeCount := len(node.Nodes()) 203 204 // should not find non-existent peer node 205 if err := node.DeletePeerNode("foobar"); err != ErrPeerNotFound { 206 t.Errorf("Expected: %v, got: %v", ErrPeerNotFound, err) 207 } 208 209 // lets pick one of the peer1 peers 210 if err := node.DeletePeerNode(testPeerOfPeerIds[0]); err != nil { 211 t.Errorf("Error deleting peer node: %v", err) 212 } 213 214 nodeDelCount := len(node.Nodes()) 215 216 if nodeDelCount != nodeCount-1 { 217 t.Errorf("Expected node count: %d, got: %d", nodeCount-1, nodeDelCount) 218 } 219 } 220 221 func TestPrunePeer(t *testing.T) { 222 // complicated node graph 223 node := testSetup() 224 225 before := node.Nodes() 226 227 node.PrunePeer("peer3") 228 229 now := node.Nodes() 230 231 if len(now) != len(before)-1 { 232 t.Errorf("Expected pruned node count: %d, got: %d", len(before)-1, len(now)) 233 } 234 } 235 236 func TestPruneStalePeers(t *testing.T) { 237 // complicated node graph 238 node := testSetup() 239 nodes := node.Nodes() 240 // this will delete all nodes besides the root node 241 pruneTime := 10 * time.Millisecond 242 time.Sleep(pruneTime) 243 244 // should delete all nodes besides (root) node 245 pruned := node.PruneStalePeers(pruneTime) 246 247 if len(pruned) != len(nodes)-1 { 248 t.Errorf("Expected pruned node count: %d, got: %d", len(nodes)-1, len(pruned)) 249 } 250 251 // complicated node graph 252 node = testSetup() 253 nodes = node.Nodes() 254 255 // set prune time to 100ms and wait for half of it 256 pruneTime = 100 * time.Millisecond 257 time.Sleep(pruneTime) 258 259 // update the time of peer1 260 node.peers["peer1"].lastSeen = time.Now() 261 262 // should prune all but the root nodes and peer1 263 pruned = node.PruneStalePeers(pruneTime) 264 265 if len(pruned) != len(nodes)-2 { 266 t.Errorf("Expected pruned node count: %d, got: %d", len(nodes)-2, len(pruned)) 267 } 268 } 269 270 func TestUnpackPeerTopology(t *testing.T) { 271 pbPeer := &pb.Peer{ 272 Node: &pb.Node{ 273 Id: "newPeer", 274 Address: "newPeerAddress", 275 Status: &pb.Status{ 276 Error: &pb.Error{}, 277 }, 278 }, 279 Peers: make([]*pb.Peer, 0), 280 } 281 // it should add pbPeer to the single node peers 282 peer := UnpackPeerTopology(pbPeer, time.Now(), 5) 283 if peer.id != pbPeer.Node.Id { 284 t.Errorf("Expected peer id %s, found: %s", pbPeer.Node.Id, peer.id) 285 } 286 287 node := testSetup() 288 // build a simple topology to update node peer1 289 peer1 := node.peers["peer1"] 290 pbPeer1Node := &pb.Node{ 291 Id: peer1.id, 292 Address: peer1.address, 293 Status: &pb.Status{ 294 Error: &pb.Error{}, 295 }, 296 } 297 298 pbPeer111 := &pb.Peer{ 299 Node: &pb.Node{ 300 Id: "peer111", 301 Address: "peer111Address", 302 Status: &pb.Status{ 303 Error: &pb.Error{}, 304 }, 305 }, 306 Peers: make([]*pb.Peer, 0), 307 } 308 309 pbPeer121 := &pb.Peer{ 310 Node: &pb.Node{ 311 Id: "peer121", 312 Address: "peer121Address", 313 Status: &pb.Status{ 314 Error: &pb.Error{}, 315 }, 316 }, 317 Peers: make([]*pb.Peer, 0), 318 } 319 // topology to update 320 pbPeer1 := &pb.Peer{ 321 Node: pbPeer1Node, 322 Peers: []*pb.Peer{pbPeer111, pbPeer121}, 323 } 324 // unpack peer1 topology 325 peer = UnpackPeerTopology(pbPeer1, time.Now(), 5) 326 // make sure peer1 topology has been correctly updated 327 newPeerIds := []string{pbPeer111.Node.Id, pbPeer121.Node.Id} 328 for _, id := range newPeerIds { 329 if _, ok := peer.peers[id]; !ok { 330 t.Errorf("Expected %s to be a peer of %s", id, "peer1") 331 } 332 } 333 } 334 335 func TestPeersToProto(t *testing.T) { 336 // single node 337 single := &node{ 338 id: testNodeId, 339 address: testNodeAddress, 340 peers: make(map[string]*node), 341 network: newNetwork(Name(testNodeNetName)), 342 status: newStatus(), 343 } 344 topCount := 0 345 346 protoPeers := PeersToProto(single, 0) 347 348 if len(protoPeers.Peers) != topCount { 349 t.Errorf("Expected to find %d nodes, found: %d", topCount, len(protoPeers.Peers)) 350 } 351 352 // complicated node graph 353 node := testSetup() 354 topCount = 3 355 // list of ids of nodes of depth 1 i.e. node peers 356 peerIds := make(map[string]bool) 357 // add peer Ids 358 for _, id := range testNodePeerIds { 359 peerIds[id] = true 360 } 361 // depth 1 should give us immmediate neighbours only 362 protoPeers = PeersToProto(node, 1) 363 364 if len(protoPeers.Peers) != topCount { 365 t.Errorf("Expected to find %d nodes, found: %d", topCount, len(protoPeers.Peers)) 366 } 367 }