github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/p2p/simulations/mocker_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:44</date>
    10  //</624342661561585664>
    11  
    12  
    13  //包模拟模拟P2P网络。
    14  //MOKCER模拟网络中真实节点的启动和停止。
    15  package simulations
    16  
    17  import (
    18  	"encoding/json"
    19  	"net/http"
    20  	"net/url"
    21  	"strconv"
    22  	"sync"
    23  	"testing"
    24  	"time"
    25  
    26  	"github.com/ethereum/go-ethereum/p2p/discover"
    27  )
    28  
    29  func TestMocker(t *testing.T) {
    30  //启动模拟HTTP服务器
    31  	_, s := testHTTPServer(t)
    32  	defer s.Close()
    33  
    34  //创建客户端
    35  	client := NewClient(s.URL)
    36  
    37  //启动网络
    38  	err := client.StartNetwork()
    39  	if err != nil {
    40  		t.Fatalf("Could not start test network: %s", err)
    41  	}
    42  //停止网络以终止
    43  	defer func() {
    44  		err = client.StopNetwork()
    45  		if err != nil {
    46  			t.Fatalf("Could not stop test network: %s", err)
    47  		}
    48  	}()
    49  
    50  //获取可用的mocker类型列表
    51  	resp, err := http.Get(s.URL + "/mocker")
    52  	if err != nil {
    53  		t.Fatalf("Could not get mocker list: %s", err)
    54  	}
    55  	defer resp.Body.Close()
    56  
    57  	if resp.StatusCode != 200 {
    58  		t.Fatalf("Invalid Status Code received, expected 200, got %d", resp.StatusCode)
    59  	}
    60  
    61  //检查列表的大小是否至少为1
    62  	var mockerlist []string
    63  	err = json.NewDecoder(resp.Body).Decode(&mockerlist)
    64  	if err != nil {
    65  		t.Fatalf("Error decoding JSON mockerlist: %s", err)
    66  	}
    67  
    68  	if len(mockerlist) < 1 {
    69  		t.Fatalf("No mockers available")
    70  	}
    71  
    72  	nodeCount := 10
    73  	var wg sync.WaitGroup
    74  
    75  	events := make(chan *Event, 10)
    76  	var opts SubscribeOpts
    77  	sub, err := client.SubscribeNetwork(events, opts)
    78  	defer sub.Unsubscribe()
    79  //等待所有节点启动并连接
    80  //将每个节点向上事件存储在映射中(值不相关,模拟集数据类型)
    81  	nodemap := make(map[discover.NodeID]bool)
    82  	wg.Add(1)
    83  	nodesComplete := false
    84  	connCount := 0
    85  	go func() {
    86  		for {
    87  			select {
    88  			case event := <-events:
    89  //如果事件仅为节点向上事件
    90  				if event.Node != nil && event.Node.Up {
    91  //将相应的节点ID添加到映射中
    92  					nodemap[event.Node.Config.ID] = true
    93  //这意味着所有节点都有一个nodeup事件,因此我们可以继续测试
    94  					if len(nodemap) == nodeCount {
    95  						nodesComplete = true
    96  //等待3秒,因为模拟机需要时间连接节点
    97  //时间。睡眠(3*时间。秒)
    98  					}
    99  				} else if event.Conn != nil && nodesComplete {
   100  					connCount += 1
   101  					if connCount == (nodeCount-1)*2 {
   102  						wg.Done()
   103  						return
   104  					}
   105  				}
   106  			case <-time.After(30 * time.Second):
   107  				wg.Done()
   108  				t.Fatalf("Timeout waiting for nodes being started up!")
   109  			}
   110  		}
   111  	}()
   112  
   113  //将mokerlist的最后一个元素作为默认mocker类型,以确保启用了mocker类型。
   114  	mockertype := mockerlist[len(mockerlist)-1]
   115  //不过,如果有的话,使用硬编码的“概率”一个;()
   116  	for _, m := range mockerlist {
   117  		if m == "probabilistic" {
   118  			mockertype = m
   119  			break
   120  		}
   121  	}
   122  //用节点数启动mocker
   123  	resp, err = http.PostForm(s.URL+"/mocker/start", url.Values{"mocker-type": {mockertype}, "node-count": {strconv.Itoa(nodeCount)}})
   124  	if err != nil {
   125  		t.Fatalf("Could not start mocker: %s", err)
   126  	}
   127  	if resp.StatusCode != 200 {
   128  		t.Fatalf("Invalid Status Code received for starting mocker, expected 200, got %d", resp.StatusCode)
   129  	}
   130  
   131  	wg.Wait()
   132  
   133  //检查网络中是否有节点计数
   134  	nodes_info, err := client.GetNodes()
   135  	if err != nil {
   136  		t.Fatalf("Could not get nodes list: %s", err)
   137  	}
   138  
   139  	if len(nodes_info) != nodeCount {
   140  		t.Fatalf("Expected %d number of nodes, got: %d", nodeCount, len(nodes_info))
   141  	}
   142  
   143  //停止嘲笑者
   144  	resp, err = http.Post(s.URL+"/mocker/stop", "", nil)
   145  	if err != nil {
   146  		t.Fatalf("Could not stop mocker: %s", err)
   147  	}
   148  	if resp.StatusCode != 200 {
   149  		t.Fatalf("Invalid Status Code received for stopping mocker, expected 200, got %d", resp.StatusCode)
   150  	}
   151  
   152  //重置网络
   153  	_, err = http.Post(s.URL+"/reset", "", nil)
   154  	if err != nil {
   155  		t.Fatalf("Could not reset network: %s", err)
   156  	}
   157  
   158  //现在网络中的节点数应该为零
   159  	nodes_info, err = client.GetNodes()
   160  	if err != nil {
   161  		t.Fatalf("Could not get nodes list: %s", err)
   162  	}
   163  
   164  	if len(nodes_info) != 0 {
   165  		t.Fatalf("Expected empty list of nodes, got: %d", len(nodes_info))
   166  	}
   167  }
   168