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