github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/p2p/simulations/http_test.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 19:16:41</date> 10 //</624450106967461888> 11 12 13 package simulations 14 15 import ( 16 "context" 17 "flag" 18 "fmt" 19 "math/rand" 20 "net/http/httptest" 21 "reflect" 22 "sync" 23 "sync/atomic" 24 "testing" 25 "time" 26 27 "github.com/ethereum/go-ethereum/event" 28 "github.com/ethereum/go-ethereum/log" 29 "github.com/ethereum/go-ethereum/node" 30 "github.com/ethereum/go-ethereum/p2p" 31 "github.com/ethereum/go-ethereum/p2p/enode" 32 "github.com/ethereum/go-ethereum/p2p/simulations/adapters" 33 "github.com/ethereum/go-ethereum/rpc" 34 "github.com/mattn/go-colorable" 35 ) 36 37 var ( 38 loglevel = flag.Int("loglevel", 2, "verbosity of logs") 39 ) 40 41 func init() { 42 flag.Parse() 43 44 log.PrintOrigins(true) 45 log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(*loglevel), log.StreamHandler(colorable.NewColorableStderr(), log.TerminalFormat(true)))) 46 } 47 48 //testservice实现node.service接口并提供协议 49 //以及用于测试模拟网络中节点的API 50 type testService struct { 51 id enode.ID 52 53 //一旦执行了对等握手,对等方计数就会增加。 54 peerCount int64 55 56 peers map[enode.ID]*testPeer 57 peersMtx sync.Mutex 58 59 //状态存储用于测试创建和加载的[]字节 60 //快照 61 state atomic.Value 62 } 63 64 func newTestService(ctx *adapters.ServiceContext) (node.Service, error) { 65 svc := &testService{ 66 id: ctx.Config.ID, 67 peers: make(map[enode.ID]*testPeer), 68 } 69 svc.state.Store(ctx.Snapshot) 70 return svc, nil 71 } 72 73 type testPeer struct { 74 testReady chan struct{} 75 dumReady chan struct{} 76 } 77 78 func (t *testService) peer(id enode.ID) *testPeer { 79 t.peersMtx.Lock() 80 defer t.peersMtx.Unlock() 81 if peer, ok := t.peers[id]; ok { 82 return peer 83 } 84 peer := &testPeer{ 85 testReady: make(chan struct{}), 86 dumReady: make(chan struct{}), 87 } 88 t.peers[id] = peer 89 return peer 90 } 91 92 func (t *testService) Protocols() []p2p.Protocol { 93 return []p2p.Protocol{ 94 { 95 Name: "test", 96 Version: 1, 97 Length: 3, 98 Run: t.RunTest, 99 }, 100 { 101 Name: "dum", 102 Version: 1, 103 Length: 1, 104 Run: t.RunDum, 105 }, 106 { 107 Name: "prb", 108 Version: 1, 109 Length: 1, 110 Run: t.RunPrb, 111 }, 112 } 113 } 114 115 func (t *testService) APIs() []rpc.API { 116 return []rpc.API{{ 117 Namespace: "test", 118 Version: "1.0", 119 Service: &TestAPI{ 120 state: &t.state, 121 peerCount: &t.peerCount, 122 }, 123 }} 124 } 125 126 func (t *testService) Start(server *p2p.Server) error { 127 return nil 128 } 129 130 func (t *testService) Stop() error { 131 return nil 132 } 133 134 //握手通过发送和期望空的 135 //带有给定代码的消息 136 func (t *testService) handshake(rw p2p.MsgReadWriter, code uint64) error { 137 errc := make(chan error, 2) 138 go func() { errc <- p2p.Send(rw, code, struct{}{}) }() 139 go func() { errc <- p2p.ExpectMsg(rw, code, struct{}{}) }() 140 for i := 0; i < 2; i++ { 141 if err := <-errc; err != nil { 142 return err 143 } 144 } 145 return nil 146 } 147 148 func (t *testService) RunTest(p *p2p.Peer, rw p2p.MsgReadWriter) error { 149 peer := t.peer(p.ID()) 150 151 //用三个不同的信息码进行三次握手, 152 //用于测试消息发送和筛选 153 if err := t.handshake(rw, 2); err != nil { 154 return err 155 } 156 if err := t.handshake(rw, 1); err != nil { 157 return err 158 } 159 if err := t.handshake(rw, 0); err != nil { 160 return err 161 } 162 163 //关闭TestReady通道,以便其他协议可以运行 164 close(peer.testReady) 165 166 //追踪同行 167 atomic.AddInt64(&t.peerCount, 1) 168 defer atomic.AddInt64(&t.peerCount, -1) 169 170 //阻止,直到删除对等机 171 for { 172 _, err := rw.ReadMsg() 173 if err != nil { 174 return err 175 } 176 } 177 } 178 179 func (t *testService) RunDum(p *p2p.Peer, rw p2p.MsgReadWriter) error { 180 peer := t.peer(p.ID()) 181 182 //等待测试协议执行其握手 183 <-peer.testReady 184 185 //握手 186 if err := t.handshake(rw, 0); err != nil { 187 return err 188 } 189 190 //关闭DumReady通道,以便其他协议可以运行 191 close(peer.dumReady) 192 193 //阻止,直到删除对等机 194 for { 195 _, err := rw.ReadMsg() 196 if err != nil { 197 return err 198 } 199 } 200 } 201 func (t *testService) RunPrb(p *p2p.Peer, rw p2p.MsgReadWriter) error { 202 peer := t.peer(p.ID()) 203 204 //等待dum协议执行握手 205 <-peer.dumReady 206 207 //握手 208 if err := t.handshake(rw, 0); err != nil { 209 return err 210 } 211 212 //阻止,直到删除对等机 213 for { 214 _, err := rw.ReadMsg() 215 if err != nil { 216 return err 217 } 218 } 219 } 220 221 func (t *testService) Snapshot() ([]byte, error) { 222 return t.state.Load().([]byte), nil 223 } 224 225 //test api提供了一个测试API,用于: 226 //*获取对等计数 227 //*获取并设置任意状态字节片 228 //*获取并递增一个计数器 229 //*订阅计数器增量事件 230 type TestAPI struct { 231 state *atomic.Value 232 peerCount *int64 233 counter int64 234 feed event.Feed 235 } 236 237 func (t *TestAPI) PeerCount() int64 { 238 return atomic.LoadInt64(t.peerCount) 239 } 240 241 func (t *TestAPI) Get() int64 { 242 return atomic.LoadInt64(&t.counter) 243 } 244 245 func (t *TestAPI) Add(delta int64) { 246 atomic.AddInt64(&t.counter, delta) 247 t.feed.Send(delta) 248 } 249 250 func (t *TestAPI) GetState() []byte { 251 return t.state.Load().([]byte) 252 } 253 254 func (t *TestAPI) SetState(state []byte) { 255 t.state.Store(state) 256 } 257 258 func (t *TestAPI) Events(ctx context.Context) (*rpc.Subscription, error) { 259 notifier, supported := rpc.NotifierFromContext(ctx) 260 if !supported { 261 return nil, rpc.ErrNotificationsUnsupported 262 } 263 264 rpcSub := notifier.CreateSubscription() 265 266 go func() { 267 events := make(chan int64) 268 sub := t.feed.Subscribe(events) 269 defer sub.Unsubscribe() 270 271 for { 272 select { 273 case event := <-events: 274 notifier.Notify(rpcSub.ID, event) 275 case <-sub.Err(): 276 return 277 case <-rpcSub.Err(): 278 return 279 case <-notifier.Closed(): 280 return 281 } 282 } 283 }() 284 285 return rpcSub, nil 286 } 287 288 var testServices = adapters.Services{ 289 "test": newTestService, 290 } 291 292 func testHTTPServer(t *testing.T) (*Network, *httptest.Server) { 293 t.Helper() 294 adapter := adapters.NewSimAdapter(testServices) 295 network := NewNetwork(adapter, &NetworkConfig{ 296 DefaultService: "test", 297 }) 298 return network, httptest.NewServer(NewServer(network)) 299 } 300 301 //testhttpnetwork使用http与仿真网络交互的测试 302 //美国石油学会 303 func TestHTTPNetwork(t *testing.T) { 304 //启动服务器 305 network, s := testHTTPServer(t) 306 defer s.Close() 307 308 //订阅活动,以便稍后检查 309 client := NewClient(s.URL) 310 events := make(chan *Event, 100) 311 var opts SubscribeOpts 312 sub, err := client.SubscribeNetwork(events, opts) 313 if err != nil { 314 t.Fatalf("error subscribing to network events: %s", err) 315 } 316 defer sub.Unsubscribe() 317 318 //检查我们是否可以检索网络的详细信息 319 gotNetwork, err := client.GetNetwork() 320 if err != nil { 321 t.Fatalf("error getting network: %s", err) 322 } 323 if gotNetwork.ID != network.ID { 324 t.Fatalf("expected network to have ID %q, got %q", network.ID, gotNetwork.ID) 325 } 326 327 //启动模拟网络 328 nodeIDs := startTestNetwork(t, client) 329 330 //检查我们有所有的活动 331 x := &expectEvents{t, events, sub} 332 x.expect( 333 x.nodeEvent(nodeIDs[0], false), 334 x.nodeEvent(nodeIDs[1], false), 335 x.nodeEvent(nodeIDs[0], true), 336 x.nodeEvent(nodeIDs[1], true), 337 x.connEvent(nodeIDs[0], nodeIDs[1], false), 338 x.connEvent(nodeIDs[0], nodeIDs[1], true), 339 ) 340 341 //重新连接流并检查当前节点和conn 342 events = make(chan *Event, 100) 343 opts.Current = true 344 sub, err = client.SubscribeNetwork(events, opts) 345 if err != nil { 346 t.Fatalf("error subscribing to network events: %s", err) 347 } 348 defer sub.Unsubscribe() 349 x = &expectEvents{t, events, sub} 350 x.expect( 351 x.nodeEvent(nodeIDs[0], true), 352 x.nodeEvent(nodeIDs[1], true), 353 x.connEvent(nodeIDs[0], nodeIDs[1], true), 354 ) 355 } 356 357 func startTestNetwork(t *testing.T, client *Client) []string { 358 //创建两个节点 359 nodeCount := 2 360 nodeIDs := make([]string, nodeCount) 361 for i := 0; i < nodeCount; i++ { 362 config := adapters.RandomNodeConfig() 363 node, err := client.CreateNode(config) 364 if err != nil { 365 t.Fatalf("error creating node: %s", err) 366 } 367 nodeIDs[i] = node.ID 368 } 369 370 //检查两个节点是否存在 371 nodes, err := client.GetNodes() 372 if err != nil { 373 t.Fatalf("error getting nodes: %s", err) 374 } 375 if len(nodes) != nodeCount { 376 t.Fatalf("expected %d nodes, got %d", nodeCount, len(nodes)) 377 } 378 for i, nodeID := range nodeIDs { 379 if nodes[i].ID != nodeID { 380 t.Fatalf("expected node %d to have ID %q, got %q", i, nodeID, nodes[i].ID) 381 } 382 node, err := client.GetNode(nodeID) 383 if err != nil { 384 t.Fatalf("error getting node %d: %s", i, err) 385 } 386 if node.ID != nodeID { 387 t.Fatalf("expected node %d to have ID %q, got %q", i, nodeID, node.ID) 388 } 389 } 390 391 //启动两个节点 392 for _, nodeID := range nodeIDs { 393 if err := client.StartNode(nodeID); err != nil { 394 t.Fatalf("error starting node %q: %s", nodeID, err) 395 } 396 } 397 398 //连接节点 399 for i := 0; i < nodeCount-1; i++ { 400 peerId := i + 1 401 if i == nodeCount-1 { 402 peerId = 0 403 } 404 if err := client.ConnectNode(nodeIDs[i], nodeIDs[peerId]); err != nil { 405 t.Fatalf("error connecting nodes: %s", err) 406 } 407 } 408 409 return nodeIDs 410 } 411 412 type expectEvents struct { 413 *testing.T 414 415 events chan *Event 416 sub event.Subscription 417 } 418 419 func (t *expectEvents) nodeEvent(id string, up bool) *Event { 420 return &Event{ 421 Type: EventTypeNode, 422 Node: &Node{ 423 Config: &adapters.NodeConfig{ 424 ID: enode.HexID(id), 425 }, 426 Up: up, 427 }, 428 } 429 } 430 431 func (t *expectEvents) connEvent(one, other string, up bool) *Event { 432 return &Event{ 433 Type: EventTypeConn, 434 Conn: &Conn{ 435 One: enode.HexID(one), 436 Other: enode.HexID(other), 437 Up: up, 438 }, 439 } 440 } 441 442 func (t *expectEvents) expectMsgs(expected map[MsgFilter]int) { 443 actual := make(map[MsgFilter]int) 444 timeout := time.After(10 * time.Second) 445 loop: 446 for { 447 select { 448 case event := <-t.events: 449 t.Logf("received %s event: %s", event.Type, event) 450 451 if event.Type != EventTypeMsg || event.Msg.Received { 452 continue loop 453 } 454 if event.Msg == nil { 455 t.Fatal("expected event.Msg to be set") 456 } 457 filter := MsgFilter{ 458 Proto: event.Msg.Protocol, 459 Code: int64(event.Msg.Code), 460 } 461 actual[filter]++ 462 if actual[filter] > expected[filter] { 463 t.Fatalf("received too many msgs for filter: %v", filter) 464 } 465 if reflect.DeepEqual(actual, expected) { 466 return 467 } 468 469 case err := <-t.sub.Err(): 470 t.Fatalf("network stream closed unexpectedly: %s", err) 471 472 case <-timeout: 473 t.Fatal("timed out waiting for expected events") 474 } 475 } 476 } 477 478 func (t *expectEvents) expect(events ...*Event) { 479 timeout := time.After(10 * time.Second) 480 i := 0 481 for { 482 select { 483 case event := <-t.events: 484 t.Logf("received %s event: %s", event.Type, event) 485 486 expected := events[i] 487 if event.Type != expected.Type { 488 t.Fatalf("expected event %d to have type %q, got %q", i, expected.Type, event.Type) 489 } 490 491 switch expected.Type { 492 493 case EventTypeNode: 494 if event.Node == nil { 495 t.Fatal("expected event.Node to be set") 496 } 497 if event.Node.ID() != expected.Node.ID() { 498 t.Fatalf("expected node event %d to have id %q, got %q", i, expected.Node.ID().TerminalString(), event.Node.ID().TerminalString()) 499 } 500 if event.Node.Up != expected.Node.Up { 501 t.Fatalf("expected node event %d to have up=%t, got up=%t", i, expected.Node.Up, event.Node.Up) 502 } 503 504 case EventTypeConn: 505 if event.Conn == nil { 506 t.Fatal("expected event.Conn to be set") 507 } 508 if event.Conn.One != expected.Conn.One { 509 t.Fatalf("expected conn event %d to have one=%q, got one=%q", i, expected.Conn.One.TerminalString(), event.Conn.One.TerminalString()) 510 } 511 if event.Conn.Other != expected.Conn.Other { 512 t.Fatalf("expected conn event %d to have other=%q, got other=%q", i, expected.Conn.Other.TerminalString(), event.Conn.Other.TerminalString()) 513 } 514 if event.Conn.Up != expected.Conn.Up { 515 t.Fatalf("expected conn event %d to have up=%t, got up=%t", i, expected.Conn.Up, event.Conn.Up) 516 } 517 518 } 519 520 i++ 521 if i == len(events) { 522 return 523 } 524 525 case err := <-t.sub.Err(): 526 t.Fatalf("network stream closed unexpectedly: %s", err) 527 528 case <-timeout: 529 t.Fatal("timed out waiting for expected events") 530 } 531 } 532 } 533 534 //testhttpnoderpc测试通过HTTP API在节点上调用RPC方法 535 func TestHTTPNodeRPC(t *testing.T) { 536 //启动服务器 537 _, s := testHTTPServer(t) 538 defer s.Close() 539 540 //启动网络中的节点 541 client := NewClient(s.URL) 542 543 config := adapters.RandomNodeConfig() 544 node, err := client.CreateNode(config) 545 if err != nil { 546 t.Fatalf("error creating node: %s", err) 547 } 548 if err := client.StartNode(node.ID); err != nil { 549 t.Fatalf("error starting node: %s", err) 550 } 551 552 //创建两个RPC客户端 553 ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) 554 defer cancel() 555 rpcClient1, err := client.RPCClient(ctx, node.ID) 556 if err != nil { 557 t.Fatalf("error getting node RPC client: %s", err) 558 } 559 rpcClient2, err := client.RPCClient(ctx, node.ID) 560 if err != nil { 561 t.Fatalf("error getting node RPC client: %s", err) 562 } 563 564 //使用客户端1订阅事件 565 events := make(chan int64, 1) 566 sub, err := rpcClient1.Subscribe(ctx, "test", events, "events") 567 if err != nil { 568 t.Fatalf("error subscribing to events: %s", err) 569 } 570 defer sub.Unsubscribe() 571 572 //使用客户端2调用某些RPC方法 573 if err := rpcClient2.CallContext(ctx, nil, "test_add", 10); err != nil { 574 t.Fatalf("error calling RPC method: %s", err) 575 } 576 var result int64 577 if err := rpcClient2.CallContext(ctx, &result, "test_get"); err != nil { 578 t.Fatalf("error calling RPC method: %s", err) 579 } 580 if result != 10 { 581 t.Fatalf("expected result to be 10, got %d", result) 582 } 583 584 //检查我们从客户机1收到一个事件 585 select { 586 case event := <-events: 587 if event != 10 { 588 t.Fatalf("expected event to be 10, got %d", event) 589 } 590 case <-ctx.Done(): 591 t.Fatal(ctx.Err()) 592 } 593 } 594 595 //testhttpsnapshot测试创建和加载网络快照 596 func TestHTTPSnapshot(t *testing.T) { 597 //启动服务器 598 network, s := testHTTPServer(t) 599 defer s.Close() 600 601 var eventsDone = make(chan struct{}) 602 count := 1 603 eventsDoneChan := make(chan *Event) 604 eventSub := network.Events().Subscribe(eventsDoneChan) 605 go func() { 606 defer eventSub.Unsubscribe() 607 for event := range eventsDoneChan { 608 if event.Type == EventTypeConn && !event.Control { 609 count-- 610 if count == 0 { 611 eventsDone <- struct{}{} 612 return 613 } 614 } 615 } 616 }() 617 618 //创建两节点网络 619 client := NewClient(s.URL) 620 nodeCount := 2 621 nodes := make([]*p2p.NodeInfo, nodeCount) 622 for i := 0; i < nodeCount; i++ { 623 config := adapters.RandomNodeConfig() 624 node, err := client.CreateNode(config) 625 if err != nil { 626 t.Fatalf("error creating node: %s", err) 627 } 628 if err := client.StartNode(node.ID); err != nil { 629 t.Fatalf("error starting node: %s", err) 630 } 631 nodes[i] = node 632 } 633 if err := client.ConnectNode(nodes[0].ID, nodes[1].ID); err != nil { 634 t.Fatalf("error connecting nodes: %s", err) 635 } 636 637 //在测试服务中存储一些状态 638 states := make([]string, nodeCount) 639 for i, node := range nodes { 640 rpc, err := client.RPCClient(context.Background(), node.ID) 641 if err != nil { 642 t.Fatalf("error getting RPC client: %s", err) 643 } 644 defer rpc.Close() 645 state := fmt.Sprintf("%x", rand.Int()) 646 if err := rpc.Call(nil, "test_setState", []byte(state)); err != nil { 647 t.Fatalf("error setting service state: %s", err) 648 } 649 states[i] = state 650 } 651 <-eventsDone 652 //创建快照 653 snap, err := client.CreateSnapshot() 654 if err != nil { 655 t.Fatalf("error creating snapshot: %s", err) 656 } 657 for i, state := range states { 658 gotState := snap.Nodes[i].Snapshots["test"] 659 if string(gotState) != state { 660 t.Fatalf("expected snapshot state %q, got %q", state, gotState) 661 } 662 } 663 664 //创建另一个网络 665 network2, s := testHTTPServer(t) 666 defer s.Close() 667 client = NewClient(s.URL) 668 count = 1 669 eventSub = network2.Events().Subscribe(eventsDoneChan) 670 go func() { 671 defer eventSub.Unsubscribe() 672 for event := range eventsDoneChan { 673 if event.Type == EventTypeConn && !event.Control { 674 count-- 675 if count == 0 { 676 eventsDone <- struct{}{} 677 return 678 } 679 } 680 } 681 }() 682 683 //订阅活动,以便稍后检查 684 events := make(chan *Event, 100) 685 var opts SubscribeOpts 686 sub, err := client.SubscribeNetwork(events, opts) 687 if err != nil { 688 t.Fatalf("error subscribing to network events: %s", err) 689 } 690 defer sub.Unsubscribe() 691 692 //加载快照 693 if err := client.LoadSnapshot(snap); err != nil { 694 t.Fatalf("error loading snapshot: %s", err) 695 } 696 <-eventsDone 697 698 //检查节点和连接是否存在 699 net, err := client.GetNetwork() 700 if err != nil { 701 t.Fatalf("error getting network: %s", err) 702 } 703 if len(net.Nodes) != nodeCount { 704 t.Fatalf("expected network to have %d nodes, got %d", nodeCount, len(net.Nodes)) 705 } 706 for i, node := range nodes { 707 id := net.Nodes[i].ID().String() 708 if id != node.ID { 709 t.Fatalf("expected node %d to have ID %s, got %s", i, node.ID, id) 710 } 711 } 712 if len(net.Conns) != 1 { 713 t.Fatalf("expected network to have 1 connection, got %d", len(net.Conns)) 714 } 715 conn := net.Conns[0] 716 if conn.One.String() != nodes[0].ID { 717 t.Fatalf("expected connection to have one=%q, got one=%q", nodes[0].ID, conn.One) 718 } 719 if conn.Other.String() != nodes[1].ID { 720 t.Fatalf("expected connection to have other=%q, got other=%q", nodes[1].ID, conn.Other) 721 } 722 if !conn.Up { 723 t.Fatal("should be up") 724 } 725 726 //检查节点状态是否已还原 727 for i, node := range nodes { 728 rpc, err := client.RPCClient(context.Background(), node.ID) 729 if err != nil { 730 t.Fatalf("error getting RPC client: %s", err) 731 } 732 defer rpc.Close() 733 var state []byte 734 if err := rpc.Call(&state, "test_getState"); err != nil { 735 t.Fatalf("error getting service state: %s", err) 736 } 737 if string(state) != states[i] { 738 t.Fatalf("expected snapshot state %q, got %q", states[i], state) 739 } 740 } 741 742 //检查我们有所有的活动 743 x := &expectEvents{t, events, sub} 744 x.expect( 745 x.nodeEvent(nodes[0].ID, false), 746 x.nodeEvent(nodes[0].ID, true), 747 x.nodeEvent(nodes[1].ID, false), 748 x.nodeEvent(nodes[1].ID, true), 749 x.connEvent(nodes[0].ID, nodes[1].ID, false), 750 x.connEvent(nodes[0].ID, nodes[1].ID, true), 751 ) 752 } 753 754 //testmsgfilterpassmultiple使用筛选器测试流式消息事件 755 //有多种协议 756 func TestMsgFilterPassMultiple(t *testing.T) { 757 //启动服务器 758 _, s := testHTTPServer(t) 759 defer s.Close() 760 761 //使用消息筛选器订阅事件 762 client := NewClient(s.URL) 763 events := make(chan *Event, 10) 764 opts := SubscribeOpts{ 765 Filter: "prb:0-test:0", 766 } 767 sub, err := client.SubscribeNetwork(events, opts) 768 if err != nil { 769 t.Fatalf("error subscribing to network events: %s", err) 770 } 771 defer sub.Unsubscribe() 772 773 //启动模拟网络 774 startTestNetwork(t, client) 775 776 //检查我们得到了预期的事件 777 x := &expectEvents{t, events, sub} 778 x.expectMsgs(map[MsgFilter]int{ 779 {"test", 0}: 2, 780 {"prb", 0}: 2, 781 }) 782 } 783 784 //testmsgfilterpasswildcard使用筛选器测试流式消息事件 785 //使用代码通配符 786 func TestMsgFilterPassWildcard(t *testing.T) { 787 //启动服务器 788 _, s := testHTTPServer(t) 789 defer s.Close() 790 791 //使用消息筛选器订阅事件 792 client := NewClient(s.URL) 793 events := make(chan *Event, 10) 794 opts := SubscribeOpts{ 795 Filter: "prb:0,2-test:*", 796 } 797 sub, err := client.SubscribeNetwork(events, opts) 798 if err != nil { 799 t.Fatalf("error subscribing to network events: %s", err) 800 } 801 defer sub.Unsubscribe() 802 803 //启动模拟网络 804 startTestNetwork(t, client) 805 806 //检查我们得到了预期的事件 807 x := &expectEvents{t, events, sub} 808 x.expectMsgs(map[MsgFilter]int{ 809 {"test", 2}: 2, 810 {"test", 1}: 2, 811 {"test", 0}: 2, 812 {"prb", 0}: 2, 813 }) 814 } 815 816 //testmsgfilterpasssingle使用筛选器测试流式消息事件 817 //只有一个协议和代码 818 func TestMsgFilterPassSingle(t *testing.T) { 819 //启动服务器 820 _, s := testHTTPServer(t) 821 defer s.Close() 822 823 //使用消息筛选器订阅事件 824 client := NewClient(s.URL) 825 events := make(chan *Event, 10) 826 opts := SubscribeOpts{ 827 Filter: "dum:0", 828 } 829 sub, err := client.SubscribeNetwork(events, opts) 830 if err != nil { 831 t.Fatalf("error subscribing to network events: %s", err) 832 } 833 defer sub.Unsubscribe() 834 835 //启动模拟网络 836 startTestNetwork(t, client) 837 838 //检查我们得到了预期的事件 839 x := &expectEvents{t, events, sub} 840 x.expectMsgs(map[MsgFilter]int{ 841 {"dum", 0}: 2, 842 }) 843 } 844 845 //testmsgfilterpasssingle使用无效的 846 //滤波器 847 func TestMsgFilterFailBadParams(t *testing.T) { 848 //启动服务器 849 _, s := testHTTPServer(t) 850 defer s.Close() 851 852 client := NewClient(s.URL) 853 events := make(chan *Event, 10) 854 opts := SubscribeOpts{ 855 Filter: "foo:", 856 } 857 _, err := client.SubscribeNetwork(events, opts) 858 if err == nil { 859 t.Fatalf("expected event subscription to fail but succeeded!") 860 } 861 862 opts.Filter = "bzz:aa" 863 _, err = client.SubscribeNetwork(events, opts) 864 if err == nil { 865 t.Fatalf("expected event subscription to fail but succeeded!") 866 } 867 868 opts.Filter = "invalid" 869 _, err = client.SubscribeNetwork(events, opts) 870 if err == nil { 871 t.Fatalf("expected event subscription to fail but succeeded!") 872 } 873 } 874