github.com/micro/go-micro/v2@v2.9.1/network/node_test.go (about)

     1  package network
     2  
     3  import (
     4  	"testing"
     5  	"time"
     6  
     7  	pb "github.com/micro/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  }