github.com/julesgoullee/go-ethereum@v1.9.7/p2p/simulations/http_test.go (about)

     1  // Copyright 2017 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package simulations
    18  
    19  import (
    20  	"context"
    21  	"flag"
    22  	"fmt"
    23  	"math/rand"
    24  	"net/http/httptest"
    25  	"os"
    26  	"reflect"
    27  	"sync"
    28  	"sync/atomic"
    29  	"testing"
    30  	"time"
    31  
    32  	"github.com/ethereum/go-ethereum/event"
    33  	"github.com/ethereum/go-ethereum/log"
    34  	"github.com/ethereum/go-ethereum/node"
    35  	"github.com/ethereum/go-ethereum/p2p"
    36  	"github.com/ethereum/go-ethereum/p2p/enode"
    37  	"github.com/ethereum/go-ethereum/p2p/simulations/adapters"
    38  	"github.com/ethereum/go-ethereum/rpc"
    39  	"github.com/mattn/go-colorable"
    40  )
    41  
    42  func TestMain(m *testing.M) {
    43  	loglevel := flag.Int("loglevel", 2, "verbosity of logs")
    44  
    45  	flag.Parse()
    46  	log.PrintOrigins(true)
    47  	log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(*loglevel), log.StreamHandler(colorable.NewColorableStderr(), log.TerminalFormat(true))))
    48  	os.Exit(m.Run())
    49  }
    50  
    51  // testService implements the node.Service interface and provides protocols
    52  // and APIs which are useful for testing nodes in a simulation network
    53  type testService struct {
    54  	id enode.ID
    55  
    56  	// peerCount is incremented once a peer handshake has been performed
    57  	peerCount int64
    58  
    59  	peers    map[enode.ID]*testPeer
    60  	peersMtx sync.Mutex
    61  
    62  	// state stores []byte which is used to test creating and loading
    63  	// snapshots
    64  	state atomic.Value
    65  }
    66  
    67  func newTestService(ctx *adapters.ServiceContext) (node.Service, error) {
    68  	svc := &testService{
    69  		id:    ctx.Config.ID,
    70  		peers: make(map[enode.ID]*testPeer),
    71  	}
    72  	svc.state.Store(ctx.Snapshot)
    73  	return svc, nil
    74  }
    75  
    76  type testPeer struct {
    77  	testReady chan struct{}
    78  	dumReady  chan struct{}
    79  }
    80  
    81  func (t *testService) peer(id enode.ID) *testPeer {
    82  	t.peersMtx.Lock()
    83  	defer t.peersMtx.Unlock()
    84  	if peer, ok := t.peers[id]; ok {
    85  		return peer
    86  	}
    87  	peer := &testPeer{
    88  		testReady: make(chan struct{}),
    89  		dumReady:  make(chan struct{}),
    90  	}
    91  	t.peers[id] = peer
    92  	return peer
    93  }
    94  
    95  func (t *testService) Protocols() []p2p.Protocol {
    96  	return []p2p.Protocol{
    97  		{
    98  			Name:    "test",
    99  			Version: 1,
   100  			Length:  3,
   101  			Run:     t.RunTest,
   102  		},
   103  		{
   104  			Name:    "dum",
   105  			Version: 1,
   106  			Length:  1,
   107  			Run:     t.RunDum,
   108  		},
   109  		{
   110  			Name:    "prb",
   111  			Version: 1,
   112  			Length:  1,
   113  			Run:     t.RunPrb,
   114  		},
   115  	}
   116  }
   117  
   118  func (t *testService) APIs() []rpc.API {
   119  	return []rpc.API{{
   120  		Namespace: "test",
   121  		Version:   "1.0",
   122  		Service: &TestAPI{
   123  			state:     &t.state,
   124  			peerCount: &t.peerCount,
   125  		},
   126  	}}
   127  }
   128  
   129  func (t *testService) Start(server *p2p.Server) error {
   130  	return nil
   131  }
   132  
   133  func (t *testService) Stop() error {
   134  	return nil
   135  }
   136  
   137  // handshake performs a peer handshake by sending and expecting an empty
   138  // message with the given code
   139  func (t *testService) handshake(rw p2p.MsgReadWriter, code uint64) error {
   140  	errc := make(chan error, 2)
   141  	go func() { errc <- p2p.Send(rw, code, struct{}{}) }()
   142  	go func() { errc <- p2p.ExpectMsg(rw, code, struct{}{}) }()
   143  	for i := 0; i < 2; i++ {
   144  		if err := <-errc; err != nil {
   145  			return err
   146  		}
   147  	}
   148  	return nil
   149  }
   150  
   151  func (t *testService) RunTest(p *p2p.Peer, rw p2p.MsgReadWriter) error {
   152  	peer := t.peer(p.ID())
   153  
   154  	// perform three handshakes with three different message codes,
   155  	// used to test message sending and filtering
   156  	if err := t.handshake(rw, 2); err != nil {
   157  		return err
   158  	}
   159  	if err := t.handshake(rw, 1); err != nil {
   160  		return err
   161  	}
   162  	if err := t.handshake(rw, 0); err != nil {
   163  		return err
   164  	}
   165  
   166  	// close the testReady channel so that other protocols can run
   167  	close(peer.testReady)
   168  
   169  	// track the peer
   170  	atomic.AddInt64(&t.peerCount, 1)
   171  	defer atomic.AddInt64(&t.peerCount, -1)
   172  
   173  	// block until the peer is dropped
   174  	for {
   175  		_, err := rw.ReadMsg()
   176  		if err != nil {
   177  			return err
   178  		}
   179  	}
   180  }
   181  
   182  func (t *testService) RunDum(p *p2p.Peer, rw p2p.MsgReadWriter) error {
   183  	peer := t.peer(p.ID())
   184  
   185  	// wait for the test protocol to perform its handshake
   186  	<-peer.testReady
   187  
   188  	// perform a handshake
   189  	if err := t.handshake(rw, 0); err != nil {
   190  		return err
   191  	}
   192  
   193  	// close the dumReady channel so that other protocols can run
   194  	close(peer.dumReady)
   195  
   196  	// block until the peer is dropped
   197  	for {
   198  		_, err := rw.ReadMsg()
   199  		if err != nil {
   200  			return err
   201  		}
   202  	}
   203  }
   204  func (t *testService) RunPrb(p *p2p.Peer, rw p2p.MsgReadWriter) error {
   205  	peer := t.peer(p.ID())
   206  
   207  	// wait for the dum protocol to perform its handshake
   208  	<-peer.dumReady
   209  
   210  	// perform a handshake
   211  	if err := t.handshake(rw, 0); err != nil {
   212  		return err
   213  	}
   214  
   215  	// block until the peer is dropped
   216  	for {
   217  		_, err := rw.ReadMsg()
   218  		if err != nil {
   219  			return err
   220  		}
   221  	}
   222  }
   223  
   224  func (t *testService) Snapshot() ([]byte, error) {
   225  	return t.state.Load().([]byte), nil
   226  }
   227  
   228  // TestAPI provides a test API to:
   229  // * get the peer count
   230  // * get and set an arbitrary state byte slice
   231  // * get and increment a counter
   232  // * subscribe to counter increment events
   233  type TestAPI struct {
   234  	state     *atomic.Value
   235  	peerCount *int64
   236  	counter   int64
   237  	feed      event.Feed
   238  }
   239  
   240  func (t *TestAPI) PeerCount() int64 {
   241  	return atomic.LoadInt64(t.peerCount)
   242  }
   243  
   244  func (t *TestAPI) Get() int64 {
   245  	return atomic.LoadInt64(&t.counter)
   246  }
   247  
   248  func (t *TestAPI) Add(delta int64) {
   249  	atomic.AddInt64(&t.counter, delta)
   250  	t.feed.Send(delta)
   251  }
   252  
   253  func (t *TestAPI) GetState() []byte {
   254  	return t.state.Load().([]byte)
   255  }
   256  
   257  func (t *TestAPI) SetState(state []byte) {
   258  	t.state.Store(state)
   259  }
   260  
   261  func (t *TestAPI) Events(ctx context.Context) (*rpc.Subscription, error) {
   262  	notifier, supported := rpc.NotifierFromContext(ctx)
   263  	if !supported {
   264  		return nil, rpc.ErrNotificationsUnsupported
   265  	}
   266  
   267  	rpcSub := notifier.CreateSubscription()
   268  
   269  	go func() {
   270  		events := make(chan int64)
   271  		sub := t.feed.Subscribe(events)
   272  		defer sub.Unsubscribe()
   273  
   274  		for {
   275  			select {
   276  			case event := <-events:
   277  				notifier.Notify(rpcSub.ID, event)
   278  			case <-sub.Err():
   279  				return
   280  			case <-rpcSub.Err():
   281  				return
   282  			case <-notifier.Closed():
   283  				return
   284  			}
   285  		}
   286  	}()
   287  
   288  	return rpcSub, nil
   289  }
   290  
   291  var testServices = adapters.Services{
   292  	"test": newTestService,
   293  }
   294  
   295  func testHTTPServer(t *testing.T) (*Network, *httptest.Server) {
   296  	t.Helper()
   297  	adapter := adapters.NewSimAdapter(testServices)
   298  	network := NewNetwork(adapter, &NetworkConfig{
   299  		DefaultService: "test",
   300  	})
   301  	return network, httptest.NewServer(NewServer(network))
   302  }
   303  
   304  // TestHTTPNetwork tests interacting with a simulation network using the HTTP
   305  // API
   306  func TestHTTPNetwork(t *testing.T) {
   307  	// start the server
   308  	network, s := testHTTPServer(t)
   309  	defer s.Close()
   310  
   311  	// subscribe to events so we can check them later
   312  	client := NewClient(s.URL)
   313  	events := make(chan *Event, 100)
   314  	var opts SubscribeOpts
   315  	sub, err := client.SubscribeNetwork(events, opts)
   316  	if err != nil {
   317  		t.Fatalf("error subscribing to network events: %s", err)
   318  	}
   319  	defer sub.Unsubscribe()
   320  
   321  	// check we can retrieve details about the network
   322  	gotNetwork, err := client.GetNetwork()
   323  	if err != nil {
   324  		t.Fatalf("error getting network: %s", err)
   325  	}
   326  	if gotNetwork.ID != network.ID {
   327  		t.Fatalf("expected network to have ID %q, got %q", network.ID, gotNetwork.ID)
   328  	}
   329  
   330  	// start a simulation network
   331  	nodeIDs := startTestNetwork(t, client)
   332  
   333  	// check we got all the events
   334  	x := &expectEvents{t, events, sub}
   335  	x.expect(
   336  		x.nodeEvent(nodeIDs[0], false),
   337  		x.nodeEvent(nodeIDs[1], false),
   338  		x.nodeEvent(nodeIDs[0], true),
   339  		x.nodeEvent(nodeIDs[1], true),
   340  		x.connEvent(nodeIDs[0], nodeIDs[1], false),
   341  		x.connEvent(nodeIDs[0], nodeIDs[1], true),
   342  	)
   343  
   344  	// reconnect the stream and check we get the current nodes and conns
   345  	events = make(chan *Event, 100)
   346  	opts.Current = true
   347  	sub, err = client.SubscribeNetwork(events, opts)
   348  	if err != nil {
   349  		t.Fatalf("error subscribing to network events: %s", err)
   350  	}
   351  	defer sub.Unsubscribe()
   352  	x = &expectEvents{t, events, sub}
   353  	x.expect(
   354  		x.nodeEvent(nodeIDs[0], true),
   355  		x.nodeEvent(nodeIDs[1], true),
   356  		x.connEvent(nodeIDs[0], nodeIDs[1], true),
   357  	)
   358  }
   359  
   360  func startTestNetwork(t *testing.T, client *Client) []string {
   361  	// create two nodes
   362  	nodeCount := 2
   363  	nodeIDs := make([]string, nodeCount)
   364  	for i := 0; i < nodeCount; i++ {
   365  		config := adapters.RandomNodeConfig()
   366  		node, err := client.CreateNode(config)
   367  		if err != nil {
   368  			t.Fatalf("error creating node: %s", err)
   369  		}
   370  		nodeIDs[i] = node.ID
   371  	}
   372  
   373  	// check both nodes exist
   374  	nodes, err := client.GetNodes()
   375  	if err != nil {
   376  		t.Fatalf("error getting nodes: %s", err)
   377  	}
   378  	if len(nodes) != nodeCount {
   379  		t.Fatalf("expected %d nodes, got %d", nodeCount, len(nodes))
   380  	}
   381  	for i, nodeID := range nodeIDs {
   382  		if nodes[i].ID != nodeID {
   383  			t.Fatalf("expected node %d to have ID %q, got %q", i, nodeID, nodes[i].ID)
   384  		}
   385  		node, err := client.GetNode(nodeID)
   386  		if err != nil {
   387  			t.Fatalf("error getting node %d: %s", i, err)
   388  		}
   389  		if node.ID != nodeID {
   390  			t.Fatalf("expected node %d to have ID %q, got %q", i, nodeID, node.ID)
   391  		}
   392  	}
   393  
   394  	// start both nodes
   395  	for _, nodeID := range nodeIDs {
   396  		if err := client.StartNode(nodeID); err != nil {
   397  			t.Fatalf("error starting node %q: %s", nodeID, err)
   398  		}
   399  	}
   400  
   401  	// connect the nodes
   402  	for i := 0; i < nodeCount-1; i++ {
   403  		peerId := i + 1
   404  		if i == nodeCount-1 {
   405  			peerId = 0
   406  		}
   407  		if err := client.ConnectNode(nodeIDs[i], nodeIDs[peerId]); err != nil {
   408  			t.Fatalf("error connecting nodes: %s", err)
   409  		}
   410  	}
   411  
   412  	return nodeIDs
   413  }
   414  
   415  type expectEvents struct {
   416  	*testing.T
   417  
   418  	events chan *Event
   419  	sub    event.Subscription
   420  }
   421  
   422  func (t *expectEvents) nodeEvent(id string, up bool) *Event {
   423  	node := Node{
   424  		Config: &adapters.NodeConfig{
   425  			ID: enode.HexID(id),
   426  		},
   427  		up: up,
   428  	}
   429  	return &Event{
   430  		Type: EventTypeNode,
   431  		Node: &node,
   432  	}
   433  }
   434  
   435  func (t *expectEvents) connEvent(one, other string, up bool) *Event {
   436  	return &Event{
   437  		Type: EventTypeConn,
   438  		Conn: &Conn{
   439  			One:   enode.HexID(one),
   440  			Other: enode.HexID(other),
   441  			Up:    up,
   442  		},
   443  	}
   444  }
   445  
   446  func (t *expectEvents) expectMsgs(expected map[MsgFilter]int) {
   447  	actual := make(map[MsgFilter]int)
   448  	timeout := time.After(10 * time.Second)
   449  loop:
   450  	for {
   451  		select {
   452  		case event := <-t.events:
   453  			t.Logf("received %s event: %s", event.Type, event)
   454  
   455  			if event.Type != EventTypeMsg || event.Msg.Received {
   456  				continue loop
   457  			}
   458  			if event.Msg == nil {
   459  				t.Fatal("expected event.Msg to be set")
   460  			}
   461  			filter := MsgFilter{
   462  				Proto: event.Msg.Protocol,
   463  				Code:  int64(event.Msg.Code),
   464  			}
   465  			actual[filter]++
   466  			if actual[filter] > expected[filter] {
   467  				t.Fatalf("received too many msgs for filter: %v", filter)
   468  			}
   469  			if reflect.DeepEqual(actual, expected) {
   470  				return
   471  			}
   472  
   473  		case err := <-t.sub.Err():
   474  			t.Fatalf("network stream closed unexpectedly: %s", err)
   475  
   476  		case <-timeout:
   477  			t.Fatal("timed out waiting for expected events")
   478  		}
   479  	}
   480  }
   481  
   482  func (t *expectEvents) expect(events ...*Event) {
   483  	t.Helper()
   484  	timeout := time.After(10 * time.Second)
   485  	i := 0
   486  	for {
   487  		select {
   488  		case event := <-t.events:
   489  			t.Logf("received %s event: %s", event.Type, event)
   490  
   491  			expected := events[i]
   492  			if event.Type != expected.Type {
   493  				t.Fatalf("expected event %d to have type %q, got %q", i, expected.Type, event.Type)
   494  			}
   495  
   496  			switch expected.Type {
   497  
   498  			case EventTypeNode:
   499  				if event.Node == nil {
   500  					t.Fatal("expected event.Node to be set")
   501  				}
   502  				if event.Node.ID() != expected.Node.ID() {
   503  					t.Fatalf("expected node event %d to have id %q, got %q", i, expected.Node.ID().TerminalString(), event.Node.ID().TerminalString())
   504  				}
   505  				if event.Node.Up() != expected.Node.Up() {
   506  					t.Fatalf("expected node event %d to have up=%t, got up=%t", i, expected.Node.Up(), event.Node.Up())
   507  				}
   508  
   509  			case EventTypeConn:
   510  				if event.Conn == nil {
   511  					t.Fatal("expected event.Conn to be set")
   512  				}
   513  				if event.Conn.One != expected.Conn.One {
   514  					t.Fatalf("expected conn event %d to have one=%q, got one=%q", i, expected.Conn.One.TerminalString(), event.Conn.One.TerminalString())
   515  				}
   516  				if event.Conn.Other != expected.Conn.Other {
   517  					t.Fatalf("expected conn event %d to have other=%q, got other=%q", i, expected.Conn.Other.TerminalString(), event.Conn.Other.TerminalString())
   518  				}
   519  				if event.Conn.Up != expected.Conn.Up {
   520  					t.Fatalf("expected conn event %d to have up=%t, got up=%t", i, expected.Conn.Up, event.Conn.Up)
   521  				}
   522  
   523  			}
   524  
   525  			i++
   526  			if i == len(events) {
   527  				return
   528  			}
   529  
   530  		case err := <-t.sub.Err():
   531  			t.Fatalf("network stream closed unexpectedly: %s", err)
   532  
   533  		case <-timeout:
   534  			t.Fatal("timed out waiting for expected events")
   535  		}
   536  	}
   537  }
   538  
   539  // TestHTTPNodeRPC tests calling RPC methods on nodes via the HTTP API
   540  func TestHTTPNodeRPC(t *testing.T) {
   541  	// start the server
   542  	_, s := testHTTPServer(t)
   543  	defer s.Close()
   544  
   545  	// start a node in the network
   546  	client := NewClient(s.URL)
   547  
   548  	config := adapters.RandomNodeConfig()
   549  	node, err := client.CreateNode(config)
   550  	if err != nil {
   551  		t.Fatalf("error creating node: %s", err)
   552  	}
   553  	if err := client.StartNode(node.ID); err != nil {
   554  		t.Fatalf("error starting node: %s", err)
   555  	}
   556  
   557  	// create two RPC clients
   558  	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
   559  	defer cancel()
   560  	rpcClient1, err := client.RPCClient(ctx, node.ID)
   561  	if err != nil {
   562  		t.Fatalf("error getting node RPC client: %s", err)
   563  	}
   564  	rpcClient2, err := client.RPCClient(ctx, node.ID)
   565  	if err != nil {
   566  		t.Fatalf("error getting node RPC client: %s", err)
   567  	}
   568  
   569  	// subscribe to events using client 1
   570  	events := make(chan int64, 1)
   571  	sub, err := rpcClient1.Subscribe(ctx, "test", events, "events")
   572  	if err != nil {
   573  		t.Fatalf("error subscribing to events: %s", err)
   574  	}
   575  	defer sub.Unsubscribe()
   576  
   577  	// call some RPC methods using client 2
   578  	if err := rpcClient2.CallContext(ctx, nil, "test_add", 10); err != nil {
   579  		t.Fatalf("error calling RPC method: %s", err)
   580  	}
   581  	var result int64
   582  	if err := rpcClient2.CallContext(ctx, &result, "test_get"); err != nil {
   583  		t.Fatalf("error calling RPC method: %s", err)
   584  	}
   585  	if result != 10 {
   586  		t.Fatalf("expected result to be 10, got %d", result)
   587  	}
   588  
   589  	// check we got an event from client 1
   590  	select {
   591  	case event := <-events:
   592  		if event != 10 {
   593  			t.Fatalf("expected event to be 10, got %d", event)
   594  		}
   595  	case <-ctx.Done():
   596  		t.Fatal(ctx.Err())
   597  	}
   598  }
   599  
   600  // TestHTTPSnapshot tests creating and loading network snapshots
   601  func TestHTTPSnapshot(t *testing.T) {
   602  	// start the server
   603  	network, s := testHTTPServer(t)
   604  	defer s.Close()
   605  
   606  	var eventsDone = make(chan struct{})
   607  	count := 1
   608  	eventsDoneChan := make(chan *Event)
   609  	eventSub := network.Events().Subscribe(eventsDoneChan)
   610  	go func() {
   611  		defer eventSub.Unsubscribe()
   612  		for event := range eventsDoneChan {
   613  			if event.Type == EventTypeConn && !event.Control {
   614  				count--
   615  				if count == 0 {
   616  					eventsDone <- struct{}{}
   617  					return
   618  				}
   619  			}
   620  		}
   621  	}()
   622  
   623  	// create a two-node network
   624  	client := NewClient(s.URL)
   625  	nodeCount := 2
   626  	nodes := make([]*p2p.NodeInfo, nodeCount)
   627  	for i := 0; i < nodeCount; i++ {
   628  		config := adapters.RandomNodeConfig()
   629  		node, err := client.CreateNode(config)
   630  		if err != nil {
   631  			t.Fatalf("error creating node: %s", err)
   632  		}
   633  		if err := client.StartNode(node.ID); err != nil {
   634  			t.Fatalf("error starting node: %s", err)
   635  		}
   636  		nodes[i] = node
   637  	}
   638  	if err := client.ConnectNode(nodes[0].ID, nodes[1].ID); err != nil {
   639  		t.Fatalf("error connecting nodes: %s", err)
   640  	}
   641  
   642  	// store some state in the test services
   643  	states := make([]string, nodeCount)
   644  	for i, node := range nodes {
   645  		rpc, err := client.RPCClient(context.Background(), node.ID)
   646  		if err != nil {
   647  			t.Fatalf("error getting RPC client: %s", err)
   648  		}
   649  		defer rpc.Close()
   650  		state := fmt.Sprintf("%x", rand.Int())
   651  		if err := rpc.Call(nil, "test_setState", []byte(state)); err != nil {
   652  			t.Fatalf("error setting service state: %s", err)
   653  		}
   654  		states[i] = state
   655  	}
   656  	<-eventsDone
   657  	// create a snapshot
   658  	snap, err := client.CreateSnapshot()
   659  	if err != nil {
   660  		t.Fatalf("error creating snapshot: %s", err)
   661  	}
   662  	for i, state := range states {
   663  		gotState := snap.Nodes[i].Snapshots["test"]
   664  		if string(gotState) != state {
   665  			t.Fatalf("expected snapshot state %q, got %q", state, gotState)
   666  		}
   667  	}
   668  
   669  	// create another network
   670  	network2, s := testHTTPServer(t)
   671  	defer s.Close()
   672  	client = NewClient(s.URL)
   673  	count = 1
   674  	eventSub = network2.Events().Subscribe(eventsDoneChan)
   675  	go func() {
   676  		defer eventSub.Unsubscribe()
   677  		for event := range eventsDoneChan {
   678  			if event.Type == EventTypeConn && !event.Control {
   679  				count--
   680  				if count == 0 {
   681  					eventsDone <- struct{}{}
   682  					return
   683  				}
   684  			}
   685  		}
   686  	}()
   687  
   688  	// subscribe to events so we can check them later
   689  	events := make(chan *Event, 100)
   690  	var opts SubscribeOpts
   691  	sub, err := client.SubscribeNetwork(events, opts)
   692  	if err != nil {
   693  		t.Fatalf("error subscribing to network events: %s", err)
   694  	}
   695  	defer sub.Unsubscribe()
   696  
   697  	// load the snapshot
   698  	if err := client.LoadSnapshot(snap); err != nil {
   699  		t.Fatalf("error loading snapshot: %s", err)
   700  	}
   701  	<-eventsDone
   702  
   703  	// check the nodes and connection exists
   704  	net, err := client.GetNetwork()
   705  	if err != nil {
   706  		t.Fatalf("error getting network: %s", err)
   707  	}
   708  	if len(net.Nodes) != nodeCount {
   709  		t.Fatalf("expected network to have %d nodes, got %d", nodeCount, len(net.Nodes))
   710  	}
   711  	for i, node := range nodes {
   712  		id := net.Nodes[i].ID().String()
   713  		if id != node.ID {
   714  			t.Fatalf("expected node %d to have ID %s, got %s", i, node.ID, id)
   715  		}
   716  	}
   717  	if len(net.Conns) != 1 {
   718  		t.Fatalf("expected network to have 1 connection, got %d", len(net.Conns))
   719  	}
   720  	conn := net.Conns[0]
   721  	if conn.One.String() != nodes[0].ID {
   722  		t.Fatalf("expected connection to have one=%q, got one=%q", nodes[0].ID, conn.One)
   723  	}
   724  	if conn.Other.String() != nodes[1].ID {
   725  		t.Fatalf("expected connection to have other=%q, got other=%q", nodes[1].ID, conn.Other)
   726  	}
   727  	if !conn.Up {
   728  		t.Fatal("should be up")
   729  	}
   730  
   731  	// check the node states were restored
   732  	for i, node := range nodes {
   733  		rpc, err := client.RPCClient(context.Background(), node.ID)
   734  		if err != nil {
   735  			t.Fatalf("error getting RPC client: %s", err)
   736  		}
   737  		defer rpc.Close()
   738  		var state []byte
   739  		if err := rpc.Call(&state, "test_getState"); err != nil {
   740  			t.Fatalf("error getting service state: %s", err)
   741  		}
   742  		if string(state) != states[i] {
   743  			t.Fatalf("expected snapshot state %q, got %q", states[i], state)
   744  		}
   745  	}
   746  
   747  	// check we got all the events
   748  	x := &expectEvents{t, events, sub}
   749  	x.expect(
   750  		x.nodeEvent(nodes[0].ID, false),
   751  		x.nodeEvent(nodes[0].ID, true),
   752  		x.nodeEvent(nodes[1].ID, false),
   753  		x.nodeEvent(nodes[1].ID, true),
   754  		x.connEvent(nodes[0].ID, nodes[1].ID, false),
   755  		x.connEvent(nodes[0].ID, nodes[1].ID, true),
   756  	)
   757  }
   758  
   759  // TestMsgFilterPassMultiple tests streaming message events using a filter
   760  // with multiple protocols
   761  func TestMsgFilterPassMultiple(t *testing.T) {
   762  	// start the server
   763  	_, s := testHTTPServer(t)
   764  	defer s.Close()
   765  
   766  	// subscribe to events with a message filter
   767  	client := NewClient(s.URL)
   768  	events := make(chan *Event, 10)
   769  	opts := SubscribeOpts{
   770  		Filter: "prb:0-test:0",
   771  	}
   772  	sub, err := client.SubscribeNetwork(events, opts)
   773  	if err != nil {
   774  		t.Fatalf("error subscribing to network events: %s", err)
   775  	}
   776  	defer sub.Unsubscribe()
   777  
   778  	// start a simulation network
   779  	startTestNetwork(t, client)
   780  
   781  	// check we got the expected events
   782  	x := &expectEvents{t, events, sub}
   783  	x.expectMsgs(map[MsgFilter]int{
   784  		{"test", 0}: 2,
   785  		{"prb", 0}:  2,
   786  	})
   787  }
   788  
   789  // TestMsgFilterPassWildcard tests streaming message events using a filter
   790  // with a code wildcard
   791  func TestMsgFilterPassWildcard(t *testing.T) {
   792  	// start the server
   793  	_, s := testHTTPServer(t)
   794  	defer s.Close()
   795  
   796  	// subscribe to events with a message filter
   797  	client := NewClient(s.URL)
   798  	events := make(chan *Event, 10)
   799  	opts := SubscribeOpts{
   800  		Filter: "prb:0,2-test:*",
   801  	}
   802  	sub, err := client.SubscribeNetwork(events, opts)
   803  	if err != nil {
   804  		t.Fatalf("error subscribing to network events: %s", err)
   805  	}
   806  	defer sub.Unsubscribe()
   807  
   808  	// start a simulation network
   809  	startTestNetwork(t, client)
   810  
   811  	// check we got the expected events
   812  	x := &expectEvents{t, events, sub}
   813  	x.expectMsgs(map[MsgFilter]int{
   814  		{"test", 2}: 2,
   815  		{"test", 1}: 2,
   816  		{"test", 0}: 2,
   817  		{"prb", 0}:  2,
   818  	})
   819  }
   820  
   821  // TestMsgFilterPassSingle tests streaming message events using a filter
   822  // with a single protocol and code
   823  func TestMsgFilterPassSingle(t *testing.T) {
   824  	// start the server
   825  	_, s := testHTTPServer(t)
   826  	defer s.Close()
   827  
   828  	// subscribe to events with a message filter
   829  	client := NewClient(s.URL)
   830  	events := make(chan *Event, 10)
   831  	opts := SubscribeOpts{
   832  		Filter: "dum:0",
   833  	}
   834  	sub, err := client.SubscribeNetwork(events, opts)
   835  	if err != nil {
   836  		t.Fatalf("error subscribing to network events: %s", err)
   837  	}
   838  	defer sub.Unsubscribe()
   839  
   840  	// start a simulation network
   841  	startTestNetwork(t, client)
   842  
   843  	// check we got the expected events
   844  	x := &expectEvents{t, events, sub}
   845  	x.expectMsgs(map[MsgFilter]int{
   846  		{"dum", 0}: 2,
   847  	})
   848  }
   849  
   850  // TestMsgFilterPassSingle tests streaming message events using an invalid
   851  // filter
   852  func TestMsgFilterFailBadParams(t *testing.T) {
   853  	// start the server
   854  	_, s := testHTTPServer(t)
   855  	defer s.Close()
   856  
   857  	client := NewClient(s.URL)
   858  	events := make(chan *Event, 10)
   859  	opts := SubscribeOpts{
   860  		Filter: "foo:",
   861  	}
   862  	_, err := client.SubscribeNetwork(events, opts)
   863  	if err == nil {
   864  		t.Fatalf("expected event subscription to fail but succeeded!")
   865  	}
   866  
   867  	opts.Filter = "bzz:aa"
   868  	_, err = client.SubscribeNetwork(events, opts)
   869  	if err == nil {
   870  		t.Fatalf("expected event subscription to fail but succeeded!")
   871  	}
   872  
   873  	opts.Filter = "invalid"
   874  	_, err = client.SubscribeNetwork(events, opts)
   875  	if err == nil {
   876  		t.Fatalf("expected event subscription to fail but succeeded!")
   877  	}
   878  }