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