github.com/wzbox/go-ethereum@v1.9.2/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 }