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