github.com/codingfuture/orig-energi3@v0.8.4/p2p/simulations/http_test.go (about)

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