github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/p2p/simulations/mocker_test.go (about)

     1  
     2  //此源码被清华学神尹成大魔王专业翻译分析并修改
     3  //尹成QQ77025077
     4  //尹成微信18510341407
     5  //尹成所在QQ群721929980
     6  //尹成邮箱 yinc13@mails.tsinghua.edu.cn
     7  //尹成毕业于清华大学,微软区块链领域全球最有价值专家
     8  //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620
     9  //版权所有2017 Go Ethereum作者
    10  //此文件是Go以太坊库的一部分。
    11  //
    12  //Go-Ethereum库是免费软件:您可以重新分发它和/或修改
    13  //根据GNU发布的较低通用公共许可证的条款
    14  //自由软件基金会,或者许可证的第3版,或者
    15  //(由您选择)任何更高版本。
    16  //
    17  //Go以太坊图书馆的发行目的是希望它会有用,
    18  //但没有任何保证;甚至没有
    19  //适销性或特定用途的适用性。见
    20  //GNU较低的通用公共许可证,了解更多详细信息。
    21  //
    22  //你应该收到一份GNU较低级别的公共许可证副本
    23  //以及Go以太坊图书馆。如果没有,请参见<http://www.gnu.org/licenses/>。
    24  
    25  //包模拟模拟P2P网络。
    26  //MOKCER模拟网络中真实节点的启动和停止。
    27  package simulations
    28  
    29  import (
    30  	"encoding/json"
    31  	"net/http"
    32  	"net/url"
    33  	"strconv"
    34  	"sync"
    35  	"testing"
    36  	"time"
    37  
    38  	"github.com/ethereum/go-ethereum/p2p/discover"
    39  )
    40  
    41  func TestMocker(t *testing.T) {
    42  //启动模拟HTTP服务器
    43  	_, s := testHTTPServer(t)
    44  	defer s.Close()
    45  
    46  //创建客户端
    47  	client := NewClient(s.URL)
    48  
    49  //启动网络
    50  	err := client.StartNetwork()
    51  	if err != nil {
    52  		t.Fatalf("Could not start test network: %s", err)
    53  	}
    54  //停止网络以终止
    55  	defer func() {
    56  		err = client.StopNetwork()
    57  		if err != nil {
    58  			t.Fatalf("Could not stop test network: %s", err)
    59  		}
    60  	}()
    61  
    62  //获取可用的mocker类型列表
    63  	resp, err := http.Get(s.URL + "/mocker")
    64  	if err != nil {
    65  		t.Fatalf("Could not get mocker list: %s", err)
    66  	}
    67  	defer resp.Body.Close()
    68  
    69  	if resp.StatusCode != 200 {
    70  		t.Fatalf("Invalid Status Code received, expected 200, got %d", resp.StatusCode)
    71  	}
    72  
    73  //检查列表的大小是否至少为1
    74  	var mockerlist []string
    75  	err = json.NewDecoder(resp.Body).Decode(&mockerlist)
    76  	if err != nil {
    77  		t.Fatalf("Error decoding JSON mockerlist: %s", err)
    78  	}
    79  
    80  	if len(mockerlist) < 1 {
    81  		t.Fatalf("No mockers available")
    82  	}
    83  
    84  	nodeCount := 10
    85  	var wg sync.WaitGroup
    86  
    87  	events := make(chan *Event, 10)
    88  	var opts SubscribeOpts
    89  	sub, err := client.SubscribeNetwork(events, opts)
    90  	defer sub.Unsubscribe()
    91  //等待所有节点启动并连接
    92  //将每个节点向上事件存储在映射中(值不相关,模拟集数据类型)
    93  	nodemap := make(map[discover.NodeID]bool)
    94  	wg.Add(1)
    95  	nodesComplete := false
    96  	connCount := 0
    97  	go func() {
    98  		for {
    99  			select {
   100  			case event := <-events:
   101  //如果事件仅为节点向上事件
   102  				if event.Node != nil && event.Node.Up {
   103  //将相应的节点ID添加到映射中
   104  					nodemap[event.Node.Config.ID] = true
   105  //这意味着所有节点都有一个nodeup事件,因此我们可以继续测试
   106  					if len(nodemap) == nodeCount {
   107  						nodesComplete = true
   108  //等待3秒,因为模拟机需要时间连接节点
   109  //时间。睡眠(3*时间。秒)
   110  					}
   111  				} else if event.Conn != nil && nodesComplete {
   112  					connCount += 1
   113  					if connCount == (nodeCount-1)*2 {
   114  						wg.Done()
   115  						return
   116  					}
   117  				}
   118  			case <-time.After(30 * time.Second):
   119  				wg.Done()
   120  				t.Fatalf("Timeout waiting for nodes being started up!")
   121  			}
   122  		}
   123  	}()
   124  
   125  //将mokerlist的最后一个元素作为默认mocker类型,以确保启用了mocker类型。
   126  	mockertype := mockerlist[len(mockerlist)-1]
   127  //不过,如果有的话,使用硬编码的“概率”一个;()
   128  	for _, m := range mockerlist {
   129  		if m == "probabilistic" {
   130  			mockertype = m
   131  			break
   132  		}
   133  	}
   134  //用节点数启动mocker
   135  	resp, err = http.PostForm(s.URL+"/mocker/start", url.Values{"mocker-type": {mockertype}, "node-count": {strconv.Itoa(nodeCount)}})
   136  	if err != nil {
   137  		t.Fatalf("Could not start mocker: %s", err)
   138  	}
   139  	if resp.StatusCode != 200 {
   140  		t.Fatalf("Invalid Status Code received for starting mocker, expected 200, got %d", resp.StatusCode)
   141  	}
   142  
   143  	wg.Wait()
   144  
   145  //检查网络中是否有节点计数
   146  	nodes_info, err := client.GetNodes()
   147  	if err != nil {
   148  		t.Fatalf("Could not get nodes list: %s", err)
   149  	}
   150  
   151  	if len(nodes_info) != nodeCount {
   152  		t.Fatalf("Expected %d number of nodes, got: %d", nodeCount, len(nodes_info))
   153  	}
   154  
   155  //停止嘲笑者
   156  	resp, err = http.Post(s.URL+"/mocker/stop", "", nil)
   157  	if err != nil {
   158  		t.Fatalf("Could not stop mocker: %s", err)
   159  	}
   160  	if resp.StatusCode != 200 {
   161  		t.Fatalf("Invalid Status Code received for stopping mocker, expected 200, got %d", resp.StatusCode)
   162  	}
   163  
   164  //重置网络
   165  	_, err = http.Post(s.URL+"/reset", "", nil)
   166  	if err != nil {
   167  		t.Fatalf("Could not reset network: %s", err)
   168  	}
   169  
   170  //现在网络中的节点数应该为零
   171  	nodes_info, err = client.GetNodes()
   172  	if err != nil {
   173  		t.Fatalf("Could not get nodes list: %s", err)
   174  	}
   175  
   176  	if len(nodes_info) != 0 {
   177  		t.Fatalf("Expected empty list of nodes, got: %d", len(nodes_info))
   178  	}
   179  }