You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

161 lines
4.0 KiB

10 years ago
11 years ago
11 years ago
10 years ago
10 years ago
  1. package p2p
  2. import (
  3. "bytes"
  4. "encoding/hex"
  5. "io"
  6. "testing"
  7. "time"
  8. . "github.com/tendermint/tendermint/binary"
  9. )
  10. type String string
  11. func (s String) WriteTo(w io.Writer) (n int64, err error) {
  12. WriteString(w, string(s), &n, &err)
  13. return
  14. }
  15. // convenience method for creating two switches connected to each other.
  16. func makeSwitchPair(t testing.TB, numChannels int, sendQueueCapacity int, recvBufferSize int, recvQueueCapacity int) (*Switch, *Switch, []*ChannelDescriptor) {
  17. // Make numChannels channels starting at byte(0x00)
  18. chIds := []byte{}
  19. for i := 0; i < numChannels; i++ {
  20. chIds = append(chIds, byte(i))
  21. }
  22. // Make some channel descriptors.
  23. chDescs := []*ChannelDescriptor{}
  24. for _, chId := range chIds {
  25. chDescs = append(chDescs, &ChannelDescriptor{
  26. Id: chId,
  27. SendQueueCapacity: sendQueueCapacity,
  28. RecvBufferSize: recvBufferSize,
  29. RecvQueueCapacity: recvQueueCapacity,
  30. DefaultPriority: 1,
  31. })
  32. }
  33. // Create two switches that will be interconnected.
  34. s1 := NewSwitch(chDescs)
  35. s2 := NewSwitch(chDescs)
  36. // Create a listener for s1
  37. l := NewDefaultListener("tcp", ":8001")
  38. // Dial the listener & add the connection to s2.
  39. lAddr := l.ExternalAddress()
  40. connOut, err := lAddr.Dial()
  41. if err != nil {
  42. t.Fatalf("Could not connect to listener address %v", lAddr)
  43. } else {
  44. t.Logf("Created a connection to listener address %v", lAddr)
  45. }
  46. connIn, ok := <-l.Connections()
  47. if !ok {
  48. t.Fatalf("Could not get inbound connection from listener")
  49. }
  50. s1.AddPeerWithConnection(connIn, false)
  51. s2.AddPeerWithConnection(connOut, true)
  52. // Wait for things to happen, peers to get added...
  53. time.Sleep(100 * time.Millisecond)
  54. // Close the server, no longer needed.
  55. l.Stop()
  56. return s1, s2, chDescs
  57. }
  58. func TestSwitches(t *testing.T) {
  59. s1, s2, _ := makeSwitchPair(t, 10, 10, 1024, 10)
  60. defer s1.Stop()
  61. defer s2.Stop()
  62. // Lets send a message from s1 to s2.
  63. if s1.Peers().Size() != 1 {
  64. t.Errorf("Expected exactly 1 peer in s1, got %v", s1.Peers().Size())
  65. }
  66. if s2.Peers().Size() != 1 {
  67. t.Errorf("Expected exactly 1 peer in s2, got %v", s2.Peers().Size())
  68. }
  69. // Broadcast a message on ch0
  70. s1.Broadcast(byte(0x00), String("channel zero"))
  71. // Broadcast a message on ch1
  72. s1.Broadcast(byte(0x01), String("channel one"))
  73. // Broadcast a message on ch2
  74. s1.Broadcast(byte(0x02), String("channel two"))
  75. // Wait for things to settle...
  76. time.Sleep(100 * time.Millisecond)
  77. // Receive message from channel 1 and check
  78. inMsg, ok := s2.Receive(byte(0x01))
  79. var n int64
  80. var err error
  81. if !ok {
  82. t.Errorf("Failed to receive from channel one")
  83. }
  84. if ReadString(bytes.NewBuffer(inMsg.Bytes), &n, &err) != "channel one" {
  85. t.Errorf("Unexpected received message bytes:\n%v", hex.Dump(inMsg.Bytes))
  86. }
  87. // Receive message from channel 0 and check
  88. inMsg, ok = s2.Receive(byte(0x00))
  89. if !ok {
  90. t.Errorf("Failed to receive from channel zero")
  91. }
  92. if ReadString(bytes.NewBuffer(inMsg.Bytes), &n, &err) != "channel zero" {
  93. t.Errorf("Unexpected received message bytes:\n%v", hex.Dump(inMsg.Bytes))
  94. }
  95. }
  96. func BenchmarkSwitches(b *testing.B) {
  97. b.StopTimer()
  98. s1, s2, chDescs := makeSwitchPair(b, 10, 10, 1024, 10)
  99. defer s1.Stop()
  100. defer s2.Stop()
  101. // Create a sink on either channel to just pop off messages.
  102. recvRoutine := func(c *Switch, chId byte) {
  103. for {
  104. _, ok := c.Receive(chId)
  105. if !ok {
  106. break
  107. }
  108. }
  109. }
  110. // Create routines to consume from recvQueues.
  111. for _, chDesc := range chDescs {
  112. go recvRoutine(s1, chDesc.Id)
  113. go recvRoutine(s2, chDesc.Id)
  114. }
  115. // Allow time for goroutines to boot up
  116. time.Sleep(1000 * time.Millisecond)
  117. b.StartTimer()
  118. numSuccess, numFailure := 0, 0
  119. // Send random message from one channel to another
  120. for i := 0; i < b.N; i++ {
  121. chId := chDescs[i%len(chDescs)].Id
  122. nS, nF := s1.Broadcast(chId, String("test data"))
  123. numSuccess += nS
  124. numFailure += nF
  125. }
  126. log.Warning("success: %v, failure: %v", numSuccess, numFailure)
  127. // Allow everything to flush before stopping switches & closing connections.
  128. b.StopTimer()
  129. time.Sleep(1000 * time.Millisecond)
  130. }