github.com/okex/exchain@v1.8.0/libs/tendermint/p2p/conn/connection_test.go (about) 1 package conn 2 3 import ( 4 "bytes" 5 "fmt" 6 "math" 7 "math/big" 8 "math/rand" 9 "net" 10 "os" 11 "testing" 12 "time" 13 14 ethcmn "github.com/ethereum/go-ethereum/common" 15 16 "github.com/fortytw2/leaktest" 17 "github.com/stretchr/testify/assert" 18 "github.com/stretchr/testify/require" 19 20 amino "github.com/tendermint/go-amino" 21 22 "github.com/okex/exchain/libs/tendermint/libs/log" 23 ) 24 25 const maxPingPongPacketSize = 1024 // bytes 26 27 func createTestMConnection(conn net.Conn) *MConnection { 28 onReceive := func(chID byte, msgBytes []byte) { 29 } 30 onError := func(r interface{}) { 31 } 32 c := createMConnectionWithCallbacks(conn, onReceive, onError) 33 c.SetLogger(log.TestingLogger()) 34 return c 35 } 36 37 func createMConnectionWithCallbacks( 38 conn net.Conn, 39 onReceive func(chID byte, msgBytes []byte), 40 onError func(r interface{}), 41 ) *MConnection { 42 cfg := DefaultMConnConfig() 43 cfg.PingInterval = 90 * time.Millisecond 44 cfg.PongTimeout = 45 * time.Millisecond 45 chDescs := []*ChannelDescriptor{{ID: 0x01, Priority: 1, SendQueueCapacity: 1}} 46 c := NewMConnectionWithConfig(conn, chDescs, onReceive, onError, cfg) 47 c.SetLogger(log.TestingLogger()) 48 return c 49 } 50 51 func TestMConnectionSendFlushStop(t *testing.T) { 52 server, client := NetPipe() 53 defer server.Close() // nolint: errcheck 54 defer client.Close() // nolint: errcheck 55 56 clientConn := createTestMConnection(client) 57 err := clientConn.Start() 58 require.Nil(t, err) 59 defer clientConn.Stop() 60 61 msg := []byte("abc") 62 assert.True(t, clientConn.Send(0x01, msg)) 63 64 aminoMsgLength := 14 65 66 // start the reader in a new routine, so we can flush 67 errCh := make(chan error) 68 go func() { 69 msgB := make([]byte, aminoMsgLength) 70 _, err := server.Read(msgB) 71 if err != nil { 72 t.Error(err) 73 return 74 } 75 errCh <- err 76 }() 77 78 // stop the conn - it should flush all conns 79 clientConn.FlushStop() 80 81 timer := time.NewTimer(3 * time.Second) 82 select { 83 case <-errCh: 84 case <-timer.C: 85 t.Error("timed out waiting for msgs to be read") 86 } 87 } 88 89 func TestMConnectionSend(t *testing.T) { 90 server, client := NetPipe() 91 defer server.Close() // nolint: errcheck 92 defer client.Close() // nolint: errcheck 93 94 mconn := createTestMConnection(client) 95 err := mconn.Start() 96 require.Nil(t, err) 97 defer mconn.Stop() 98 99 msg := []byte("Ant-Man") 100 assert.True(t, mconn.Send(0x01, msg)) 101 // Note: subsequent Send/TrySend calls could pass because we are reading from 102 // the send queue in a separate goroutine. 103 _, err = server.Read(make([]byte, len(msg))) 104 if err != nil { 105 t.Error(err) 106 } 107 assert.True(t, mconn.CanSend(0x01)) 108 109 msg = []byte("Spider-Man") 110 assert.True(t, mconn.TrySend(0x01, msg)) 111 _, err = server.Read(make([]byte, len(msg))) 112 if err != nil { 113 t.Error(err) 114 } 115 116 assert.False(t, mconn.CanSend(0x05), "CanSend should return false because channel is unknown") 117 assert.False(t, mconn.Send(0x05, []byte("Absorbing Man")), "Send should return false because channel is unknown") 118 } 119 120 func TestMConnectionReceive(t *testing.T) { 121 server, client := NetPipe() 122 defer server.Close() // nolint: errcheck 123 defer client.Close() // nolint: errcheck 124 125 receivedCh := make(chan []byte) 126 errorsCh := make(chan interface{}) 127 onReceive := func(chID byte, msgBytes []byte) { 128 receivedCh <- msgBytes 129 } 130 onError := func(r interface{}) { 131 errorsCh <- r 132 } 133 mconn1 := createMConnectionWithCallbacks(client, onReceive, onError) 134 err := mconn1.Start() 135 require.Nil(t, err) 136 defer mconn1.Stop() 137 138 mconn2 := createTestMConnection(server) 139 err = mconn2.Start() 140 require.Nil(t, err) 141 defer mconn2.Stop() 142 143 msg := []byte("Cyclops") 144 assert.True(t, mconn2.Send(0x01, msg)) 145 146 select { 147 case receivedBytes := <-receivedCh: 148 assert.Equal(t, msg, receivedBytes) 149 case err := <-errorsCh: 150 t.Fatalf("Expected %s, got %+v", msg, err) 151 case <-time.After(500 * time.Millisecond): 152 t.Fatalf("Did not receive %s message in 500ms", msg) 153 } 154 } 155 156 func TestMConnectionStatus(t *testing.T) { 157 server, client := NetPipe() 158 defer server.Close() // nolint: errcheck 159 defer client.Close() // nolint: errcheck 160 161 mconn := createTestMConnection(client) 162 err := mconn.Start() 163 require.Nil(t, err) 164 defer mconn.Stop() 165 166 status := mconn.Status() 167 assert.NotNil(t, status) 168 assert.Zero(t, status.Channels[0].SendQueueSize) 169 } 170 171 func TestMConnectionPongTimeoutResultsInError(t *testing.T) { 172 server, client := net.Pipe() 173 defer server.Close() 174 defer client.Close() 175 176 receivedCh := make(chan []byte) 177 errorsCh := make(chan interface{}) 178 onReceive := func(chID byte, msgBytes []byte) { 179 receivedCh <- msgBytes 180 } 181 onError := func(r interface{}) { 182 errorsCh <- r 183 } 184 mconn := createMConnectionWithCallbacks(client, onReceive, onError) 185 err := mconn.Start() 186 require.Nil(t, err) 187 defer mconn.Stop() 188 189 serverGotPing := make(chan struct{}) 190 go func() { 191 // read ping 192 var pkt PacketPing 193 _, err = cdc.UnmarshalBinaryLengthPrefixedReader(server, &pkt, maxPingPongPacketSize) 194 assert.Nil(t, err) 195 serverGotPing <- struct{}{} 196 }() 197 <-serverGotPing 198 199 pongTimerExpired := mconn.config.PongTimeout + 20*time.Millisecond 200 select { 201 case msgBytes := <-receivedCh: 202 t.Fatalf("Expected error, but got %v", msgBytes) 203 case err := <-errorsCh: 204 assert.NotNil(t, err) 205 case <-time.After(pongTimerExpired): 206 t.Fatalf("Expected to receive error after %v", pongTimerExpired) 207 } 208 } 209 210 func TestMConnectionMultiplePongsInTheBeginning(t *testing.T) { 211 server, client := net.Pipe() 212 defer server.Close() 213 defer client.Close() 214 215 receivedCh := make(chan []byte) 216 errorsCh := make(chan interface{}) 217 onReceive := func(chID byte, msgBytes []byte) { 218 receivedCh <- msgBytes 219 } 220 onError := func(r interface{}) { 221 errorsCh <- r 222 } 223 mconn := createMConnectionWithCallbacks(client, onReceive, onError) 224 err := mconn.Start() 225 require.Nil(t, err) 226 defer mconn.Stop() 227 228 // sending 3 pongs in a row (abuse) 229 _, err = server.Write(cdc.MustMarshalBinaryLengthPrefixed(PacketPong{})) 230 require.Nil(t, err) 231 _, err = server.Write(cdc.MustMarshalBinaryLengthPrefixed(PacketPong{})) 232 require.Nil(t, err) 233 _, err = server.Write(cdc.MustMarshalBinaryLengthPrefixed(PacketPong{})) 234 require.Nil(t, err) 235 236 serverGotPing := make(chan struct{}) 237 go func() { 238 // read ping (one byte) 239 var ( 240 packet Packet 241 err error 242 ) 243 _, err = cdc.UnmarshalBinaryLengthPrefixedReader(server, &packet, maxPingPongPacketSize) 244 require.Nil(t, err) 245 serverGotPing <- struct{}{} 246 // respond with pong 247 _, err = server.Write(cdc.MustMarshalBinaryLengthPrefixed(PacketPong{})) 248 require.Nil(t, err) 249 }() 250 <-serverGotPing 251 252 pongTimerExpired := mconn.config.PongTimeout + 20*time.Millisecond 253 select { 254 case msgBytes := <-receivedCh: 255 t.Fatalf("Expected no data, but got %v", msgBytes) 256 case err := <-errorsCh: 257 t.Fatalf("Expected no error, but got %v", err) 258 case <-time.After(pongTimerExpired): 259 assert.True(t, mconn.IsRunning()) 260 } 261 } 262 263 func TestMConnectionMultiplePings(t *testing.T) { 264 server, client := net.Pipe() 265 defer server.Close() 266 defer client.Close() 267 268 receivedCh := make(chan []byte) 269 errorsCh := make(chan interface{}) 270 onReceive := func(chID byte, msgBytes []byte) { 271 receivedCh <- msgBytes 272 } 273 onError := func(r interface{}) { 274 errorsCh <- r 275 } 276 mconn := createMConnectionWithCallbacks(client, onReceive, onError) 277 err := mconn.Start() 278 require.Nil(t, err) 279 defer mconn.Stop() 280 281 // sending 3 pings in a row (abuse) 282 // see https://github.com/tendermint/tendermint/issues/1190 283 _, err = server.Write(cdc.MustMarshalBinaryLengthPrefixed(PacketPing{})) 284 require.Nil(t, err) 285 var pkt PacketPong 286 _, err = cdc.UnmarshalBinaryLengthPrefixedReader(server, &pkt, maxPingPongPacketSize) 287 require.Nil(t, err) 288 _, err = server.Write(cdc.MustMarshalBinaryLengthPrefixed(PacketPing{})) 289 require.Nil(t, err) 290 _, err = cdc.UnmarshalBinaryLengthPrefixedReader(server, &pkt, maxPingPongPacketSize) 291 require.Nil(t, err) 292 _, err = server.Write(cdc.MustMarshalBinaryLengthPrefixed(PacketPing{})) 293 require.Nil(t, err) 294 _, err = cdc.UnmarshalBinaryLengthPrefixedReader(server, &pkt, maxPingPongPacketSize) 295 require.Nil(t, err) 296 297 assert.True(t, mconn.IsRunning()) 298 } 299 300 func TestMConnectionPingPongs(t *testing.T) { 301 // check that we are not leaking any go-routines 302 defer leaktest.CheckTimeout(t, 10*time.Second)() 303 304 server, client := net.Pipe() 305 306 defer server.Close() 307 defer client.Close() 308 309 receivedCh := make(chan []byte) 310 errorsCh := make(chan interface{}) 311 onReceive := func(chID byte, msgBytes []byte) { 312 receivedCh <- msgBytes 313 } 314 onError := func(r interface{}) { 315 errorsCh <- r 316 } 317 mconn := createMConnectionWithCallbacks(client, onReceive, onError) 318 err := mconn.Start() 319 require.Nil(t, err) 320 defer mconn.Stop() 321 322 serverGotPing := make(chan struct{}) 323 go func() { 324 // read ping 325 var pkt PacketPing 326 _, err = cdc.UnmarshalBinaryLengthPrefixedReader(server, &pkt, maxPingPongPacketSize) 327 require.Nil(t, err) 328 serverGotPing <- struct{}{} 329 // respond with pong 330 _, err = server.Write(cdc.MustMarshalBinaryLengthPrefixed(PacketPong{})) 331 require.Nil(t, err) 332 333 time.Sleep(mconn.config.PingInterval) 334 335 // read ping 336 _, err = cdc.UnmarshalBinaryLengthPrefixedReader(server, &pkt, maxPingPongPacketSize) 337 require.Nil(t, err) 338 // respond with pong 339 _, err = server.Write(cdc.MustMarshalBinaryLengthPrefixed(PacketPong{})) 340 require.Nil(t, err) 341 }() 342 <-serverGotPing 343 344 pongTimerExpired := (mconn.config.PongTimeout + 20*time.Millisecond) * 2 345 select { 346 case msgBytes := <-receivedCh: 347 t.Fatalf("Expected no data, but got %v", msgBytes) 348 case err := <-errorsCh: 349 t.Fatalf("Expected no error, but got %v", err) 350 case <-time.After(2 * pongTimerExpired): 351 assert.True(t, mconn.IsRunning()) 352 } 353 } 354 355 func TestMConnectionStopsAndReturnsError(t *testing.T) { 356 server, client := NetPipe() 357 defer server.Close() // nolint: errcheck 358 defer client.Close() // nolint: errcheck 359 360 receivedCh := make(chan []byte) 361 errorsCh := make(chan interface{}) 362 onReceive := func(chID byte, msgBytes []byte) { 363 receivedCh <- msgBytes 364 } 365 onError := func(r interface{}) { 366 errorsCh <- r 367 } 368 mconn := createMConnectionWithCallbacks(client, onReceive, onError) 369 err := mconn.Start() 370 require.Nil(t, err) 371 defer mconn.Stop() 372 373 if err := client.Close(); err != nil { 374 t.Error(err) 375 } 376 377 select { 378 case receivedBytes := <-receivedCh: 379 t.Fatalf("Expected error, got %v", receivedBytes) 380 case err := <-errorsCh: 381 assert.NotNil(t, err) 382 assert.False(t, mconn.IsRunning()) 383 case <-time.After(500 * time.Millisecond): 384 t.Fatal("Did not receive error in 500ms") 385 } 386 } 387 388 func newClientAndServerConnsForReadErrors(t *testing.T, chOnErr chan struct{}) (*MConnection, *MConnection) { 389 server, client := NetPipe() 390 391 onReceive := func(chID byte, msgBytes []byte) {} 392 onError := func(r interface{}) {} 393 394 // create client conn with two channels 395 chDescs := []*ChannelDescriptor{ 396 {ID: 0x01, Priority: 1, SendQueueCapacity: 1}, 397 {ID: 0x02, Priority: 1, SendQueueCapacity: 1}, 398 } 399 mconnClient := NewMConnection(client, chDescs, onReceive, onError) 400 mconnClient.SetLogger(log.TestingLogger().With("module", "client")) 401 err := mconnClient.Start() 402 require.Nil(t, err) 403 404 // create server conn with 1 channel 405 // it fires on chOnErr when there's an error 406 serverLogger := log.TestingLogger().With("module", "server") 407 onError = func(r interface{}) { 408 chOnErr <- struct{}{} 409 } 410 mconnServer := createMConnectionWithCallbacks(server, onReceive, onError) 411 mconnServer.SetLogger(serverLogger) 412 err = mconnServer.Start() 413 require.Nil(t, err) 414 return mconnClient, mconnServer 415 } 416 417 func expectSend(ch chan struct{}) bool { 418 after := time.After(time.Second * 5) 419 select { 420 case <-ch: 421 return true 422 case <-after: 423 return false 424 } 425 } 426 427 func TestMConnectionReadErrorBadEncoding(t *testing.T) { 428 chOnErr := make(chan struct{}) 429 mconnClient, mconnServer := newClientAndServerConnsForReadErrors(t, chOnErr) 430 defer mconnClient.Stop() 431 defer mconnServer.Stop() 432 433 client := mconnClient.conn 434 435 // send badly encoded msgPacket 436 bz := cdc.MustMarshalBinaryLengthPrefixed(PacketMsg{}) 437 bz[4] += 0x01 // Invalid prefix bytes. 438 439 // Write it. 440 _, err := client.Write(bz) 441 assert.Nil(t, err) 442 assert.True(t, expectSend(chOnErr), "badly encoded msgPacket") 443 } 444 445 func TestMConnectionReadErrorUnknownChannel(t *testing.T) { 446 chOnErr := make(chan struct{}) 447 mconnClient, mconnServer := newClientAndServerConnsForReadErrors(t, chOnErr) 448 defer mconnClient.Stop() 449 defer mconnServer.Stop() 450 451 msg := []byte("Ant-Man") 452 453 // fail to send msg on channel unknown by client 454 assert.False(t, mconnClient.Send(0x03, msg)) 455 456 // send msg on channel unknown by the server. 457 // should cause an error 458 assert.True(t, mconnClient.Send(0x02, msg)) 459 assert.True(t, expectSend(chOnErr), "unknown channel") 460 } 461 462 func TestMConnectionReadErrorLongMessage(t *testing.T) { 463 chOnErr := make(chan struct{}) 464 chOnRcv := make(chan struct{}) 465 466 mconnClient, mconnServer := newClientAndServerConnsForReadErrors(t, chOnErr) 467 defer mconnClient.Stop() 468 defer mconnServer.Stop() 469 470 mconnServer.onReceive = func(chID byte, msgBytes []byte) { 471 chOnRcv <- struct{}{} 472 } 473 474 client := mconnClient.conn 475 476 // send msg thats just right 477 var err error 478 var buf = new(bytes.Buffer) 479 var packet = PacketMsg{ 480 ChannelID: 0x01, 481 EOF: 1, 482 Bytes: make([]byte, mconnClient.config.MaxPacketMsgPayloadSize), 483 } 484 _, err = cdc.MarshalBinaryLengthPrefixedWriter(buf, packet) 485 assert.Nil(t, err) 486 _, err = client.Write(buf.Bytes()) 487 assert.Nil(t, err) 488 assert.True(t, expectSend(chOnRcv), "msg just right") 489 490 // send msg thats too long 491 buf = new(bytes.Buffer) 492 packet = PacketMsg{ 493 ChannelID: 0x01, 494 EOF: 1, 495 Bytes: make([]byte, mconnClient.config.MaxPacketMsgPayloadSize+100), 496 } 497 _, err = cdc.MarshalBinaryLengthPrefixedWriter(buf, packet) 498 assert.Nil(t, err) 499 _, err = client.Write(buf.Bytes()) 500 assert.NotNil(t, err) 501 assert.True(t, expectSend(chOnErr), "msg too long") 502 } 503 504 func TestMConnectionReadErrorUnknownMsgType(t *testing.T) { 505 chOnErr := make(chan struct{}) 506 mconnClient, mconnServer := newClientAndServerConnsForReadErrors(t, chOnErr) 507 defer mconnClient.Stop() 508 defer mconnServer.Stop() 509 510 // send msg with unknown msg type 511 err := amino.EncodeUvarint(mconnClient.conn, 4) 512 assert.Nil(t, err) 513 _, err = mconnClient.conn.Write([]byte{0xFF, 0xFF, 0xFF, 0xFF}) 514 assert.Nil(t, err) 515 assert.True(t, expectSend(chOnErr), "unknown msg type") 516 } 517 518 func TestMConnectionTrySend(t *testing.T) { 519 server, client := NetPipe() 520 defer server.Close() 521 defer client.Close() 522 523 mconn := createTestMConnection(client) 524 err := mconn.Start() 525 require.Nil(t, err) 526 defer mconn.Stop() 527 528 msg := []byte("Semicolon-Woman") 529 resultCh := make(chan string, 2) 530 assert.True(t, mconn.TrySend(0x01, msg)) 531 server.Read(make([]byte, len(msg))) 532 assert.True(t, mconn.CanSend(0x01)) 533 assert.True(t, mconn.TrySend(0x01, msg)) 534 assert.False(t, mconn.CanSend(0x01)) 535 go func() { 536 mconn.TrySend(0x01, msg) 537 resultCh <- "TrySend" 538 }() 539 assert.False(t, mconn.CanSend(0x01)) 540 assert.False(t, mconn.TrySend(0x01, msg)) 541 assert.Equal(t, "TrySend", <-resultCh) 542 } 543 544 func TestPacketAmino(t *testing.T) { 545 546 packets := []Packet{ 547 PacketPing{}, 548 PacketPong{}, 549 PacketMsg{}, 550 PacketMsg{0, 0, nil}, 551 PacketMsg{0, 0, []byte{}}, 552 PacketMsg{225, 225, []byte{}}, 553 PacketMsg{0x7f, 45, []byte{0x12, 0x34, 0x56, 0x78}}, 554 PacketMsg{math.MaxUint8, math.MaxUint8, []byte{0x12, 0x34, 0x56, 0x78}}, 555 } 556 557 for _, packet := range packets { 558 bz, err := cdc.MarshalBinaryLengthPrefixed(packet) 559 require.Nil(t, err) 560 561 nbz, err := cdc.MarshalBinaryLengthPrefixedWithRegisteredMarshaller(packet) 562 require.NoError(t, err) 563 require.EqualValues(t, bz, nbz) 564 565 packet = nil 566 err = cdc.UnmarshalBinaryLengthPrefixed(bz, &packet) 567 require.NoError(t, err) 568 569 v, err := cdc.UnmarshalBinaryLengthPrefixedWithRegisteredUbmarshaller(bz, &packet) 570 require.NoError(t, err) 571 newPacket, ok := v.(Packet) 572 require.True(t, ok) 573 574 var buf bytes.Buffer 575 buf.Write(bz) 576 newPacket2, n, err := unmarshalPacketFromAminoReader(&buf, int64(buf.Len()), nil) 577 require.NoError(t, err) 578 require.EqualValues(t, len(bz), n) 579 580 require.EqualValues(t, packet, newPacket) 581 require.EqualValues(t, packet, newPacket2) 582 } 583 } 584 585 func BenchmarkPacketAmino(b *testing.B) { 586 hash := ethcmn.BigToHash(big.NewInt(0x12345678)) 587 buf := bytes.Buffer{} 588 for i := 0; i < 10; i++ { 589 buf.Write(hash.Bytes()) 590 } 591 msg := PacketMsg{0x7f, 45, buf.Bytes()} 592 bz, err := cdc.MarshalBinaryLengthPrefixed(msg) 593 require.NoError(b, err) 594 b.ResetTimer() 595 596 b.Run("ping-amino-marshal", func(b *testing.B) { 597 b.ReportAllocs() 598 for i := 0; i < b.N; i++ { 599 var packet Packet 600 packet = PacketPing{} 601 _, _ = cdc.MarshalBinaryLengthPrefixed(packet) 602 } 603 }) 604 b.Run("ping-amino-marshaller", func(b *testing.B) { 605 b.ReportAllocs() 606 for i := 0; i < b.N; i++ { 607 var packet Packet 608 packet = PacketPing{} 609 _, _ = cdc.MarshalBinaryLengthPrefixedWithRegisteredMarshaller(packet) 610 } 611 }) 612 b.Run("msg-amino-marshal", func(b *testing.B) { 613 b.ReportAllocs() 614 for i := 0; i < b.N; i++ { 615 var packet Packet 616 packet = PacketMsg{32, 45, []byte{0x12, 0x34, 0x56, 0x78}} 617 _, _ = cdc.MarshalBinaryLengthPrefixed(packet) 618 } 619 }) 620 b.Run("msg-amino-marshaller", func(b *testing.B) { 621 b.ReportAllocs() 622 for i := 0; i < b.N; i++ { 623 var packet Packet 624 packet = PacketMsg{32, 45, []byte{0x12, 0x34, 0x56, 0x78}} 625 _, _ = cdc.MarshalBinaryLengthPrefixedWithRegisteredMarshaller(packet) 626 } 627 }) 628 b.Run("msg-amino-unmarshal", func(b *testing.B) { 629 b.ReportAllocs() 630 for i := 0; i < b.N; i++ { 631 var packet Packet 632 var buf = bytes.NewBuffer(bz) 633 _, err = cdc.UnmarshalBinaryLengthPrefixedReader(buf, &packet, int64(buf.Len())) 634 if err != nil { 635 b.Fatal(err) 636 } 637 } 638 }) 639 b.Run("msg-amino-unmarshaler", func(b *testing.B) { 640 b.ReportAllocs() 641 for i := 0; i < b.N; i++ { 642 var packet Packet 643 var buf = bytes.NewBuffer(bz) 644 packet, _, err = unmarshalPacketFromAminoReader(buf, int64(buf.Len()), nil) 645 if err != nil { 646 b.Fatal(err) 647 } 648 _ = packet 649 } 650 }) 651 } 652 653 func TestBytesStringer(t *testing.T) { 654 var testData = []byte("test data !!!") 655 expect := fmt.Sprintf("%X", testData) 656 var testStringer = bytesHexStringer(testData) 657 actual := testStringer.String() 658 require.EqualValues(t, expect, actual) 659 actual = fmt.Sprintf("%s", testStringer) 660 require.EqualValues(t, expect, actual) 661 } 662 663 func TestPacketMsgAmino(t *testing.T) { 664 var longBytes = make([]byte, 1024) 665 rand.Read(longBytes) 666 667 testCases := []PacketMsg{ 668 {}, 669 { 670 ChannelID: 12, 671 EOF: 25, 672 }, 673 { 674 ChannelID: math.MaxInt8, 675 EOF: math.MaxInt8, 676 Bytes: []byte("Bytes"), 677 }, 678 { 679 Bytes: []byte{}, 680 }, 681 { 682 Bytes: longBytes, 683 }, 684 } 685 for _, msg := range testCases { 686 expectData, err := cdc.MarshalBinaryBare(msg) 687 require.NoError(t, err) 688 689 actualData, err := cdc.MarshalBinaryBareWithRegisteredMarshaller(msg) 690 require.NoError(t, err) 691 692 require.EqualValues(t, expectData, actualData) 693 actualData, err = msg.MarshalToAmino(cdc) 694 if actualData == nil { 695 actualData = []byte{} 696 } 697 require.EqualValues(t, expectData[4:], actualData) 698 699 require.Equal(t, len(actualData), msg.AminoSize(cdc)) 700 701 actualData, err = cdc.MarshalBinaryWithSizer(msg, false) 702 require.EqualValues(t, expectData, actualData) 703 require.Equal(t, getPacketMsgAminoTypePrefix(), actualData[0:4]) 704 705 expectLenPrefixData, err := cdc.MarshalBinaryLengthPrefixed(msg) 706 require.NoError(t, err) 707 actualLenPrefixData, err := cdc.MarshalBinaryWithSizer(msg, true) 708 require.EqualValues(t, expectLenPrefixData, actualLenPrefixData) 709 710 var expectValue PacketMsg 711 err = cdc.UnmarshalBinaryBare(expectData, &expectValue) 712 require.NoError(t, err) 713 714 var actulaValue = &PacketMsg{} 715 tmp, err := cdc.UnmarshalBinaryBareWithRegisteredUnmarshaller(expectData, actulaValue) 716 require.NoError(t, err) 717 _, ok := tmp.(*PacketMsg) 718 require.True(t, ok) 719 actulaValue = tmp.(*PacketMsg) 720 721 require.EqualValues(t, expectValue, *actulaValue) 722 err = actulaValue.UnmarshalFromAmino(cdc, expectData[4:]) 723 require.NoError(t, err) 724 require.EqualValues(t, expectValue, *actulaValue) 725 726 actulaValue = &PacketMsg{} 727 err = cdc.UnmarshalBinaryLengthPrefixed(actualLenPrefixData, actulaValue) 728 require.NoError(t, err) 729 require.EqualValues(t, expectValue, *actulaValue) 730 } 731 } 732 733 func Benchmark(b *testing.B) { 734 var longBytes = make([]byte, 1024) 735 rand.Read(longBytes) 736 737 testCases := []PacketMsg{ 738 {}, 739 { 740 ChannelID: 12, 741 EOF: 25, 742 }, 743 { 744 ChannelID: math.MaxInt8, 745 EOF: math.MaxInt8, 746 Bytes: []byte("Bytes"), 747 }, 748 { 749 Bytes: []byte{}, 750 }, 751 { 752 Bytes: longBytes, 753 }, 754 } 755 756 b.Run("amino", func(b *testing.B) { 757 b.ReportAllocs() 758 for i := 0; i < b.N; i++ { 759 for _, msg := range testCases { 760 _, err := cdc.MarshalBinaryLengthPrefixedWithRegisteredMarshaller(&msg) 761 if err != nil { 762 b.Fatal(err) 763 } 764 } 765 } 766 }) 767 b.Run("sizer", func(b *testing.B) { 768 b.ReportAllocs() 769 for i := 0; i < b.N; i++ { 770 for _, msg := range testCases { 771 _, err := cdc.MarshalBinaryWithSizer(&msg, true) 772 if err != nil { 773 b.Fatal(err) 774 } 775 } 776 } 777 }) 778 } 779 780 func BenchmarkMConnectionLogSendData(b *testing.B) { 781 c := new(MConnection) 782 chID := byte(10) 783 msgBytes := []byte("Hello World!") 784 785 logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "benchmark") 786 var options []log.Option 787 options = append(options, log.AllowInfoWith("module", "benchmark")) 788 logger = log.NewFilter(logger, options...) 789 790 c.Logger = logger 791 b.ResetTimer() 792 793 b.Run("pool", func(b *testing.B) { 794 b.ReportAllocs() 795 for i := 0; i < b.N; i++ { 796 c.logSendData("Send", chID, msgBytes) 797 } 798 }) 799 800 b.Run("logger", func(b *testing.B) { 801 b.ReportAllocs() 802 for i := 0; i < b.N; i++ { 803 logger.Debug("Send", "channel", chID, "conn", c, "msgBytes", bytesHexStringer(msgBytes)) 804 } 805 }) 806 } 807 808 func BenchmarkMConnectionLogReceiveMsg(b *testing.B) { 809 c := new(MConnection) 810 chID := byte(10) 811 msgBytes := []byte("Hello World!") 812 813 logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "benchmark") 814 var options []log.Option 815 options = append(options, log.AllowInfoWith("module", "benchmark")) 816 logger = log.NewFilter(logger, options...) 817 818 c.Logger = logger 819 b.ResetTimer() 820 821 b.Run("pool", func(b *testing.B) { 822 b.ReportAllocs() 823 for i := 0; i < b.N; i++ { 824 c.logReceiveMsg(chID, msgBytes) 825 } 826 }) 827 828 b.Run("logger", func(b *testing.B) { 829 b.ReportAllocs() 830 for i := 0; i < b.N; i++ { 831 logger.Debug("Received bytes", "chID", chID, "msgBytes", bytesHexStringer(msgBytes)) 832 } 833 }) 834 } 835 836 func BenchmarkChannelLogRecvPacketMsg(b *testing.B) { 837 conn := new(MConnection) 838 c := new(Channel) 839 chID := byte(10) 840 msgBytes := []byte("Hello World!") 841 pk := PacketMsg{ 842 ChannelID: chID, 843 EOF: 25, 844 Bytes: msgBytes, 845 } 846 847 logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "benchmark") 848 var options []log.Option 849 options = append(options, log.AllowInfoWith("module", "benchmark")) 850 logger = log.NewFilter(logger, options...) 851 852 c.Logger = logger 853 c.conn = conn 854 b.ResetTimer() 855 856 b.Run("pool", func(b *testing.B) { 857 b.ReportAllocs() 858 for i := 0; i < b.N; i++ { 859 c.logRecvPacketMsg(pk) 860 } 861 }) 862 863 b.Run("logger", func(b *testing.B) { 864 b.ReportAllocs() 865 for i := 0; i < b.N; i++ { 866 c.Logger.Debug("Read PacketMsg", "conn", c.conn, "packet", pk) 867 } 868 }) 869 } 870 871 func TestTimer(t *testing.T) { 872 timer := time.NewTimer(1 * time.Second) 873 stoped := timer.Stop() 874 require.True(t, stoped) 875 876 var timerChHashData bool 877 select { 878 case <-timer.C: 879 timerChHashData = true 880 default: 881 timerChHashData = false 882 } 883 require.False(t, timerChHashData) 884 885 timer.Reset(1 * time.Second) 886 887 time.Sleep(2 * time.Second) 888 889 stoped = timer.Stop() 890 require.False(t, stoped) 891 892 if !stoped { 893 select { 894 case <-timer.C: 895 timerChHashData = true 896 default: 897 timerChHashData = false 898 } 899 } 900 require.True(t, timerChHashData) 901 902 timer.Reset(1 * time.Second) 903 now := time.Now() 904 <-timer.C 905 since := time.Since(now) 906 require.True(t, since > 500*time.Millisecond) 907 908 stoped = timer.Stop() 909 require.False(t, stoped) 910 if !stoped { 911 //_, ok := <-timer.C 912 //t.Log("ok:", ok) 913 select { 914 case <-timer.C: 915 timerChHashData = true 916 default: 917 timerChHashData = false 918 } 919 } 920 require.False(t, timerChHashData) 921 }