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.

234 lines
6.1 KiB

9 years ago
  1. package p2p
  2. import (
  3. "bytes"
  4. "sync"
  5. "testing"
  6. "time"
  7. . "github.com/tendermint/go-common"
  8. "github.com/tendermint/go-crypto"
  9. "github.com/tendermint/go-wire"
  10. )
  11. type PeerMessage struct {
  12. PeerKey string
  13. Bytes []byte
  14. Counter int
  15. }
  16. type TestReactor struct {
  17. BaseReactor
  18. mtx sync.Mutex
  19. channels []*ChannelDescriptor
  20. peersAdded []*Peer
  21. peersRemoved []*Peer
  22. logMessages bool
  23. msgsCounter int
  24. msgsReceived map[byte][]PeerMessage
  25. }
  26. func NewTestReactor(channels []*ChannelDescriptor, logMessages bool) *TestReactor {
  27. tr := &TestReactor{
  28. channels: channels,
  29. logMessages: logMessages,
  30. msgsReceived: make(map[byte][]PeerMessage),
  31. }
  32. tr.BaseReactor = *NewBaseReactor(log, "TestReactor", tr)
  33. return tr
  34. }
  35. func (tr *TestReactor) GetChannels() []*ChannelDescriptor {
  36. return tr.channels
  37. }
  38. func (tr *TestReactor) AddPeer(peer *Peer) {
  39. tr.mtx.Lock()
  40. defer tr.mtx.Unlock()
  41. tr.peersAdded = append(tr.peersAdded, peer)
  42. }
  43. func (tr *TestReactor) RemovePeer(peer *Peer, reason interface{}) {
  44. tr.mtx.Lock()
  45. defer tr.mtx.Unlock()
  46. tr.peersRemoved = append(tr.peersRemoved, peer)
  47. }
  48. func (tr *TestReactor) Receive(chID byte, peer *Peer, msgBytes []byte) {
  49. if tr.logMessages {
  50. tr.mtx.Lock()
  51. defer tr.mtx.Unlock()
  52. //fmt.Printf("Received: %X, %X\n", chID, msgBytes)
  53. tr.msgsReceived[chID] = append(tr.msgsReceived[chID], PeerMessage{peer.Key, msgBytes, tr.msgsCounter})
  54. tr.msgsCounter++
  55. }
  56. }
  57. //-----------------------------------------------------------------------------
  58. // convenience method for creating two switches connected to each other.
  59. func makeSwitchPair(t testing.TB, initSwitch func(*Switch) *Switch) (*Switch, *Switch) {
  60. s1PrivKey := crypto.GenPrivKeyEd25519()
  61. s2PrivKey := crypto.GenPrivKeyEd25519()
  62. // Create two switches that will be interconnected.
  63. s1 := initSwitch(NewSwitch())
  64. s1.SetNodeInfo(&NodeInfo{
  65. PubKey: s1PrivKey.PubKey().(crypto.PubKeyEd25519),
  66. Moniker: "switch1",
  67. Network: "testing",
  68. Version: "123.123.123",
  69. })
  70. s1.SetNodePrivKey(s1PrivKey)
  71. s2 := initSwitch(NewSwitch())
  72. s2.SetNodeInfo(&NodeInfo{
  73. PubKey: s2PrivKey.PubKey().(crypto.PubKeyEd25519),
  74. Moniker: "switch2",
  75. Network: "testing",
  76. Version: "123.123.123",
  77. })
  78. s2.SetNodePrivKey(s2PrivKey)
  79. // Start switches and reactors
  80. s1.Start()
  81. s2.Start()
  82. // Create a listener for s1
  83. l := NewDefaultListener("tcp", ":8001", true)
  84. // Dial the listener & add the connection to s2.
  85. lAddr := l.ExternalAddress()
  86. connOut, err := lAddr.Dial()
  87. if err != nil {
  88. t.Fatalf("Could not connect to listener address %v", lAddr)
  89. } else {
  90. t.Logf("Created a connection to listener address %v", lAddr)
  91. }
  92. connIn, ok := <-l.Connections()
  93. if !ok {
  94. t.Fatalf("Could not get inbound connection from listener")
  95. }
  96. go s1.AddPeerWithConnection(connIn, false) // AddPeer is blocking, requires handshake.
  97. s2.AddPeerWithConnection(connOut, true)
  98. // Wait for things to happen, peers to get added...
  99. time.Sleep(100 * time.Millisecond)
  100. // Close the server, no longer needed.
  101. l.Stop()
  102. return s1, s2
  103. }
  104. func TestSwitches(t *testing.T) {
  105. s1, s2 := makeSwitchPair(t, func(sw *Switch) *Switch {
  106. // Make two reactors of two channels each
  107. sw.AddReactor("foo", NewTestReactor([]*ChannelDescriptor{
  108. &ChannelDescriptor{ID: byte(0x00), Priority: 10},
  109. &ChannelDescriptor{ID: byte(0x01), Priority: 10},
  110. }, true))
  111. sw.AddReactor("bar", NewTestReactor([]*ChannelDescriptor{
  112. &ChannelDescriptor{ID: byte(0x02), Priority: 10},
  113. &ChannelDescriptor{ID: byte(0x03), Priority: 10},
  114. }, true))
  115. return sw
  116. })
  117. defer s1.Stop()
  118. defer s2.Stop()
  119. // Lets send a message from s1 to s2.
  120. if s1.Peers().Size() != 1 {
  121. t.Errorf("Expected exactly 1 peer in s1, got %v", s1.Peers().Size())
  122. }
  123. if s2.Peers().Size() != 1 {
  124. t.Errorf("Expected exactly 1 peer in s2, got %v", s2.Peers().Size())
  125. }
  126. ch0Msg := "channel zero"
  127. ch1Msg := "channel foo"
  128. ch2Msg := "channel bar"
  129. s1.Broadcast(byte(0x00), ch0Msg)
  130. s1.Broadcast(byte(0x01), ch1Msg)
  131. s1.Broadcast(byte(0x02), ch2Msg)
  132. // Wait for things to settle...
  133. time.Sleep(5000 * time.Millisecond)
  134. // Check message on ch0
  135. ch0Msgs := s2.Reactor("foo").(*TestReactor).msgsReceived[byte(0x00)]
  136. if len(ch0Msgs) != 1 {
  137. t.Errorf("Expected to have received 1 message in ch0")
  138. }
  139. if !bytes.Equal(ch0Msgs[0].Bytes, wire.BinaryBytes(ch0Msg)) {
  140. t.Errorf("Unexpected message bytes. Wanted: %X, Got: %X", wire.BinaryBytes(ch0Msg), ch0Msgs[0].Bytes)
  141. }
  142. // Check message on ch1
  143. ch1Msgs := s2.Reactor("foo").(*TestReactor).msgsReceived[byte(0x01)]
  144. if len(ch1Msgs) != 1 {
  145. t.Errorf("Expected to have received 1 message in ch1")
  146. }
  147. if !bytes.Equal(ch1Msgs[0].Bytes, wire.BinaryBytes(ch1Msg)) {
  148. t.Errorf("Unexpected message bytes. Wanted: %X, Got: %X", wire.BinaryBytes(ch1Msg), ch1Msgs[0].Bytes)
  149. }
  150. // Check message on ch2
  151. ch2Msgs := s2.Reactor("bar").(*TestReactor).msgsReceived[byte(0x02)]
  152. if len(ch2Msgs) != 1 {
  153. t.Errorf("Expected to have received 1 message in ch2")
  154. }
  155. if !bytes.Equal(ch2Msgs[0].Bytes, wire.BinaryBytes(ch2Msg)) {
  156. t.Errorf("Unexpected message bytes. Wanted: %X, Got: %X", wire.BinaryBytes(ch2Msg), ch2Msgs[0].Bytes)
  157. }
  158. }
  159. func BenchmarkSwitches(b *testing.B) {
  160. b.StopTimer()
  161. s1, s2 := makeSwitchPair(b, func(sw *Switch) *Switch {
  162. // Make bar reactors of bar channels each
  163. sw.AddReactor("foo", NewTestReactor([]*ChannelDescriptor{
  164. &ChannelDescriptor{ID: byte(0x00), Priority: 10},
  165. &ChannelDescriptor{ID: byte(0x01), Priority: 10},
  166. }, false))
  167. sw.AddReactor("bar", NewTestReactor([]*ChannelDescriptor{
  168. &ChannelDescriptor{ID: byte(0x02), Priority: 10},
  169. &ChannelDescriptor{ID: byte(0x03), Priority: 10},
  170. }, false))
  171. return sw
  172. })
  173. defer s1.Stop()
  174. defer s2.Stop()
  175. // Allow time for goroutines to boot up
  176. time.Sleep(1000 * time.Millisecond)
  177. b.StartTimer()
  178. numSuccess, numFailure := 0, 0
  179. // Send random message from foo channel to another
  180. for i := 0; i < b.N; i++ {
  181. chID := byte(i % 4)
  182. successChan := s1.Broadcast(chID, "test data")
  183. for s := range successChan {
  184. if s {
  185. numSuccess += 1
  186. } else {
  187. numFailure += 1
  188. }
  189. }
  190. }
  191. log.Warn(Fmt("success: %v, failure: %v", numSuccess, numFailure))
  192. // Allow everything to flush before stopping switches & closing connections.
  193. b.StopTimer()
  194. time.Sleep(1000 * time.Millisecond)
  195. }