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