github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/p2p/simulations/network_test.go (about)

     1  
     2  //<developer>
     3  //    <name>linapex 曹一峰</name>
     4  //    <email>linapex@163.com</email>
     5  //    <wx>superexc</wx>
     6  //    <qqgroup>128148617</qqgroup>
     7  //    <url>https://jsq.ink</url>
     8  //    <role>pku engineer</role>
     9  //    <date>2019-03-16 12:09:45</date>
    10  //</624342661725163520>
    11  
    12  
    13  package simulations
    14  
    15  import (
    16  	"context"
    17  	"fmt"
    18  	"testing"
    19  	"time"
    20  
    21  	"github.com/ethereum/go-ethereum/p2p/discover"
    22  	"github.com/ethereum/go-ethereum/p2p/simulations/adapters"
    23  )
    24  
    25  //TestNetworkSimulation使用每个节点创建多节点仿真网络
    26  //在环形拓扑中连接,检查所有节点是否成功握手
    27  //彼此之间,快照完全代表所需的拓扑
    28  func TestNetworkSimulation(t *testing.T) {
    29  //使用20个testservice节点创建模拟网络
    30  	adapter := adapters.NewSimAdapter(adapters.Services{
    31  		"test": newTestService,
    32  	})
    33  	network := NewNetwork(adapter, &NetworkConfig{
    34  		DefaultService: "test",
    35  	})
    36  	defer network.Shutdown()
    37  	nodeCount := 20
    38  	ids := make([]discover.NodeID, nodeCount)
    39  	for i := 0; i < nodeCount; i++ {
    40  		conf := adapters.RandomNodeConfig()
    41  		node, err := network.NewNodeWithConfig(conf)
    42  		if err != nil {
    43  			t.Fatalf("error creating node: %s", err)
    44  		}
    45  		if err := network.Start(node.ID()); err != nil {
    46  			t.Fatalf("error starting node: %s", err)
    47  		}
    48  		ids[i] = node.ID()
    49  	}
    50  
    51  //执行连接环中节点的检查(因此每个节点
    52  //然后检查所有节点
    53  //通过检查他们的对等计数进行了两次握手
    54  	action := func(_ context.Context) error {
    55  		for i, id := range ids {
    56  			peerID := ids[(i+1)%len(ids)]
    57  			if err := network.Connect(id, peerID); err != nil {
    58  				return err
    59  			}
    60  		}
    61  		return nil
    62  	}
    63  	check := func(ctx context.Context, id discover.NodeID) (bool, error) {
    64  //检查一下我们的时间没有用完
    65  		select {
    66  		case <-ctx.Done():
    67  			return false, ctx.Err()
    68  		default:
    69  		}
    70  
    71  //获取节点
    72  		node := network.GetNode(id)
    73  		if node == nil {
    74  			return false, fmt.Errorf("unknown node: %s", id)
    75  		}
    76  
    77  //检查它是否有两个同龄人
    78  		client, err := node.Client()
    79  		if err != nil {
    80  			return false, err
    81  		}
    82  		var peerCount int64
    83  		if err := client.CallContext(ctx, &peerCount, "test_peerCount"); err != nil {
    84  			return false, err
    85  		}
    86  		switch {
    87  		case peerCount < 2:
    88  			return false, nil
    89  		case peerCount == 2:
    90  			return true, nil
    91  		default:
    92  			return false, fmt.Errorf("unexpected peerCount: %d", peerCount)
    93  		}
    94  	}
    95  
    96  	timeout := 30 * time.Second
    97  	ctx, cancel := context.WithTimeout(context.Background(), timeout)
    98  	defer cancel()
    99  
   100  //每100毫秒触发一次检查
   101  	trigger := make(chan discover.NodeID)
   102  	go triggerChecks(ctx, ids, trigger, 100*time.Millisecond)
   103  
   104  	result := NewSimulation(network).Run(ctx, &Step{
   105  		Action:  action,
   106  		Trigger: trigger,
   107  		Expect: &Expectation{
   108  			Nodes: ids,
   109  			Check: check,
   110  		},
   111  	})
   112  	if result.Error != nil {
   113  		t.Fatalf("simulation failed: %s", result.Error)
   114  	}
   115  
   116  //获取网络快照并检查它是否包含正确的拓扑
   117  	snap, err := network.Snapshot()
   118  	if err != nil {
   119  		t.Fatal(err)
   120  	}
   121  	if len(snap.Nodes) != nodeCount {
   122  		t.Fatalf("expected snapshot to contain %d nodes, got %d", nodeCount, len(snap.Nodes))
   123  	}
   124  	if len(snap.Conns) != nodeCount {
   125  		t.Fatalf("expected snapshot to contain %d connections, got %d", nodeCount, len(snap.Conns))
   126  	}
   127  	for i, id := range ids {
   128  		conn := snap.Conns[i]
   129  		if conn.One != id {
   130  			t.Fatalf("expected conn[%d].One to be %s, got %s", i, id, conn.One)
   131  		}
   132  		peerID := ids[(i+1)%len(ids)]
   133  		if conn.Other != peerID {
   134  			t.Fatalf("expected conn[%d].Other to be %s, got %s", i, peerID, conn.Other)
   135  		}
   136  	}
   137  }
   138  
   139  func triggerChecks(ctx context.Context, ids []discover.NodeID, trigger chan discover.NodeID, interval time.Duration) {
   140  	tick := time.NewTicker(interval)
   141  	defer tick.Stop()
   142  	for {
   143  		select {
   144  		case <-tick.C:
   145  			for _, id := range ids {
   146  				select {
   147  				case trigger <- id:
   148  				case <-ctx.Done():
   149  					return
   150  				}
   151  			}
   152  		case <-ctx.Done():
   153  			return
   154  		}
   155  	}
   156  }
   157