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 }