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