github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/swarm/network/protocol_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 19:16:43</date>
    10  //</624450114131333120>
    11  
    12  
    13  package network
    14  
    15  import (
    16  	"flag"
    17  	"fmt"
    18  	"os"
    19  	"testing"
    20  	"time"
    21  
    22  	"github.com/ethereum/go-ethereum/log"
    23  	"github.com/ethereum/go-ethereum/p2p"
    24  	"github.com/ethereum/go-ethereum/p2p/enode"
    25  	"github.com/ethereum/go-ethereum/p2p/protocols"
    26  	p2ptest "github.com/ethereum/go-ethereum/p2p/testing"
    27  )
    28  
    29  const (
    30  	TestProtocolVersion   = 8
    31  	TestProtocolNetworkID = 3
    32  )
    33  
    34  var (
    35  	loglevel = flag.Int("loglevel", 2, "verbosity of logs")
    36  )
    37  
    38  func init() {
    39  	flag.Parse()
    40  	log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(*loglevel), log.StreamHandler(os.Stderr, log.TerminalFormat(true))))
    41  }
    42  
    43  func HandshakeMsgExchange(lhs, rhs *HandshakeMsg, id enode.ID) []p2ptest.Exchange {
    44  	return []p2ptest.Exchange{
    45  		{
    46  			Expects: []p2ptest.Expect{
    47  				{
    48  					Code: 0,
    49  					Msg:  lhs,
    50  					Peer: id,
    51  				},
    52  			},
    53  		},
    54  		{
    55  			Triggers: []p2ptest.Trigger{
    56  				{
    57  					Code: 0,
    58  					Msg:  rhs,
    59  					Peer: id,
    60  				},
    61  			},
    62  		},
    63  	}
    64  }
    65  
    66  func newBzzBaseTester(t *testing.T, n int, addr *BzzAddr, spec *protocols.Spec, run func(*BzzPeer) error) *bzzTester {
    67  	cs := make(map[string]chan bool)
    68  
    69  	srv := func(p *BzzPeer) error {
    70  		defer func() {
    71  			if cs[p.ID().String()] != nil {
    72  				close(cs[p.ID().String()])
    73  			}
    74  		}()
    75  		return run(p)
    76  	}
    77  
    78  	protocol := func(p *p2p.Peer, rw p2p.MsgReadWriter) error {
    79  		return srv(&BzzPeer{Peer: protocols.NewPeer(p, rw, spec), BzzAddr: NewAddr(p.Node())})
    80  	}
    81  
    82  	s := p2ptest.NewProtocolTester(t, addr.ID(), n, protocol)
    83  
    84  	for _, node := range s.Nodes {
    85  		cs[node.ID().String()] = make(chan bool)
    86  	}
    87  
    88  	return &bzzTester{
    89  		addr:           addr,
    90  		ProtocolTester: s,
    91  		cs:             cs,
    92  	}
    93  }
    94  
    95  type bzzTester struct {
    96  	*p2ptest.ProtocolTester
    97  	addr *BzzAddr
    98  	cs   map[string]chan bool
    99  	bzz  *Bzz
   100  }
   101  
   102  func newBzz(addr *BzzAddr, lightNode bool) *Bzz {
   103  	config := &BzzConfig{
   104  		OverlayAddr:  addr.Over(),
   105  		UnderlayAddr: addr.Under(),
   106  		HiveParams:   NewHiveParams(),
   107  		NetworkID:    DefaultNetworkID,
   108  		LightNode:    lightNode,
   109  	}
   110  	kad := NewKademlia(addr.OAddr, NewKadParams())
   111  	bzz := NewBzz(config, kad, nil, nil, nil)
   112  	return bzz
   113  }
   114  
   115  func newBzzHandshakeTester(t *testing.T, n int, addr *BzzAddr, lightNode bool) *bzzTester {
   116  	bzz := newBzz(addr, lightNode)
   117  	pt := p2ptest.NewProtocolTester(t, addr.ID(), n, bzz.runBzz)
   118  
   119  	return &bzzTester{
   120  		addr:           addr,
   121  		ProtocolTester: pt,
   122  		bzz:            bzz,
   123  	}
   124  }
   125  
   126  //应该在一次交换中测试握手吗?并行化
   127  func (s *bzzTester) testHandshake(lhs, rhs *HandshakeMsg, disconnects ...*p2ptest.Disconnect) error {
   128  	if err := s.TestExchanges(HandshakeMsgExchange(lhs, rhs, rhs.Addr.ID())...); err != nil {
   129  		return err
   130  	}
   131  
   132  	if len(disconnects) > 0 {
   133  		return s.TestDisconnected(disconnects...)
   134  	}
   135  
   136  //如果我们不期望断开连接,请确保对等端保持连接
   137  	err := s.TestDisconnected(&p2ptest.Disconnect{
   138  		Peer:  s.Nodes[0].ID(),
   139  		Error: nil,
   140  	})
   141  
   142  	if err == nil {
   143  		return fmt.Errorf("Unexpected peer disconnect")
   144  	}
   145  
   146  	if err.Error() != "timed out waiting for peers to disconnect" {
   147  		return err
   148  	}
   149  
   150  	return nil
   151  }
   152  
   153  func correctBzzHandshake(addr *BzzAddr, lightNode bool) *HandshakeMsg {
   154  	return &HandshakeMsg{
   155  		Version:   TestProtocolVersion,
   156  		NetworkID: TestProtocolNetworkID,
   157  		Addr:      addr,
   158  		LightNode: lightNode,
   159  	}
   160  }
   161  
   162  func TestBzzHandshakeNetworkIDMismatch(t *testing.T) {
   163  	lightNode := false
   164  	addr := RandomAddr()
   165  	s := newBzzHandshakeTester(t, 1, addr, lightNode)
   166  	node := s.Nodes[0]
   167  
   168  	err := s.testHandshake(
   169  		correctBzzHandshake(addr, lightNode),
   170  		&HandshakeMsg{Version: TestProtocolVersion, NetworkID: 321, Addr: NewAddr(node)},
   171  		&p2ptest.Disconnect{Peer: node.ID(), Error: fmt.Errorf("Handshake error: Message handler error: (msg code 0): network id mismatch 321 (!= 3)")},
   172  	)
   173  
   174  	if err != nil {
   175  		t.Fatal(err)
   176  	}
   177  }
   178  
   179  func TestBzzHandshakeVersionMismatch(t *testing.T) {
   180  	lightNode := false
   181  	addr := RandomAddr()
   182  	s := newBzzHandshakeTester(t, 1, addr, lightNode)
   183  	node := s.Nodes[0]
   184  
   185  	err := s.testHandshake(
   186  		correctBzzHandshake(addr, lightNode),
   187  		&HandshakeMsg{Version: 0, NetworkID: TestProtocolNetworkID, Addr: NewAddr(node)},
   188  		&p2ptest.Disconnect{Peer: node.ID(), Error: fmt.Errorf("Handshake error: Message handler error: (msg code 0): version mismatch 0 (!= %d)", TestProtocolVersion)},
   189  	)
   190  
   191  	if err != nil {
   192  		t.Fatal(err)
   193  	}
   194  }
   195  
   196  func TestBzzHandshakeSuccess(t *testing.T) {
   197  	lightNode := false
   198  	addr := RandomAddr()
   199  	s := newBzzHandshakeTester(t, 1, addr, lightNode)
   200  	node := s.Nodes[0]
   201  
   202  	err := s.testHandshake(
   203  		correctBzzHandshake(addr, lightNode),
   204  		&HandshakeMsg{Version: TestProtocolVersion, NetworkID: TestProtocolNetworkID, Addr: NewAddr(node)},
   205  	)
   206  
   207  	if err != nil {
   208  		t.Fatal(err)
   209  	}
   210  }
   211  
   212  func TestBzzHandshakeLightNode(t *testing.T) {
   213  	var lightNodeTests = []struct {
   214  		name      string
   215  		lightNode bool
   216  	}{
   217  		{"on", true},
   218  		{"off", false},
   219  	}
   220  
   221  	for _, test := range lightNodeTests {
   222  		t.Run(test.name, func(t *testing.T) {
   223  			randomAddr := RandomAddr()
   224  pt := newBzzHandshakeTester(nil, 1, randomAddr, false) //TODO更改签名-t未在任何位置使用
   225  			node := pt.Nodes[0]
   226  			addr := NewAddr(node)
   227  
   228  			err := pt.testHandshake(
   229  				correctBzzHandshake(randomAddr, false),
   230  				&HandshakeMsg{Version: TestProtocolVersion, NetworkID: TestProtocolNetworkID, Addr: addr, LightNode: test.lightNode},
   231  			)
   232  
   233  			if err != nil {
   234  				t.Fatal(err)
   235  			}
   236  
   237  			select {
   238  
   239  			case <-pt.bzz.handshakes[node.ID()].done:
   240  				if pt.bzz.handshakes[node.ID()].LightNode != test.lightNode {
   241  					t.Fatalf("peer LightNode flag is %v, should be %v", pt.bzz.handshakes[node.ID()].LightNode, test.lightNode)
   242  				}
   243  			case <-time.After(10 * time.Second):
   244  				t.Fatal("test timeout")
   245  			}
   246  		})
   247  	}
   248  }
   249