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