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