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.

307 lines
8.1 KiB

8 years ago
8 years ago
8 years ago
  1. package p2p
  2. import (
  3. "net"
  4. "testing"
  5. "time"
  6. "github.com/stretchr/testify/assert"
  7. "github.com/stretchr/testify/require"
  8. wire "github.com/tendermint/go-wire"
  9. "github.com/tendermint/tmlibs/log"
  10. )
  11. func createTestMConnection(conn net.Conn) *MConnection {
  12. onReceive := func(chID byte, msgBytes []byte) {
  13. }
  14. onError := func(r interface{}) {
  15. }
  16. c := createMConnectionWithCallbacks(conn, onReceive, onError)
  17. c.SetLogger(log.TestingLogger())
  18. return c
  19. }
  20. func createMConnectionWithCallbacks(conn net.Conn, onReceive func(chID byte, msgBytes []byte), onError func(r interface{})) *MConnection {
  21. chDescs := []*ChannelDescriptor{&ChannelDescriptor{ID: 0x01, Priority: 1, SendQueueCapacity: 1}}
  22. c := NewMConnection(conn, chDescs, onReceive, onError)
  23. c.SetLogger(log.TestingLogger())
  24. return c
  25. }
  26. func TestMConnectionSend(t *testing.T) {
  27. assert, require := assert.New(t), require.New(t)
  28. server, client := netPipe()
  29. defer server.Close()
  30. defer client.Close()
  31. mconn := createTestMConnection(client)
  32. _, err := mconn.Start()
  33. require.Nil(err)
  34. defer mconn.Stop()
  35. msg := "Ant-Man"
  36. assert.True(mconn.Send(0x01, msg))
  37. // Note: subsequent Send/TrySend calls could pass because we are reading from
  38. // the send queue in a separate goroutine.
  39. server.Read(make([]byte, len(msg)))
  40. assert.True(mconn.CanSend(0x01))
  41. msg = "Spider-Man"
  42. assert.True(mconn.TrySend(0x01, msg))
  43. server.Read(make([]byte, len(msg)))
  44. assert.False(mconn.CanSend(0x05), "CanSend should return false because channel is unknown")
  45. assert.False(mconn.Send(0x05, "Absorbing Man"), "Send should return false because channel is unknown")
  46. }
  47. func TestMConnectionReceive(t *testing.T) {
  48. assert, require := assert.New(t), require.New(t)
  49. server, client := netPipe()
  50. defer server.Close()
  51. defer client.Close()
  52. receivedCh := make(chan []byte)
  53. errorsCh := make(chan interface{})
  54. onReceive := func(chID byte, msgBytes []byte) {
  55. receivedCh <- msgBytes
  56. }
  57. onError := func(r interface{}) {
  58. errorsCh <- r
  59. }
  60. mconn1 := createMConnectionWithCallbacks(client, onReceive, onError)
  61. _, err := mconn1.Start()
  62. require.Nil(err)
  63. defer mconn1.Stop()
  64. mconn2 := createTestMConnection(server)
  65. _, err = mconn2.Start()
  66. require.Nil(err)
  67. defer mconn2.Stop()
  68. msg := "Cyclops"
  69. assert.True(mconn2.Send(0x01, msg))
  70. select {
  71. case receivedBytes := <-receivedCh:
  72. assert.Equal([]byte(msg), receivedBytes[2:]) // first 3 bytes are internal
  73. case err := <-errorsCh:
  74. t.Fatalf("Expected %s, got %+v", msg, err)
  75. case <-time.After(500 * time.Millisecond):
  76. t.Fatalf("Did not receive %s message in 500ms", msg)
  77. }
  78. }
  79. func TestMConnectionStatus(t *testing.T) {
  80. assert, require := assert.New(t), require.New(t)
  81. server, client := netPipe()
  82. defer server.Close()
  83. defer client.Close()
  84. mconn := createTestMConnection(client)
  85. _, err := mconn.Start()
  86. require.Nil(err)
  87. defer mconn.Stop()
  88. status := mconn.Status()
  89. assert.NotNil(status)
  90. assert.Zero(status.Channels[0].SendQueueSize)
  91. }
  92. func TestMConnectionStopsAndReturnsError(t *testing.T) {
  93. assert, require := assert.New(t), require.New(t)
  94. server, client := netPipe()
  95. defer server.Close()
  96. defer client.Close()
  97. receivedCh := make(chan []byte)
  98. errorsCh := make(chan interface{})
  99. onReceive := func(chID byte, msgBytes []byte) {
  100. receivedCh <- msgBytes
  101. }
  102. onError := func(r interface{}) {
  103. errorsCh <- r
  104. }
  105. mconn := createMConnectionWithCallbacks(client, onReceive, onError)
  106. _, err := mconn.Start()
  107. require.Nil(err)
  108. defer mconn.Stop()
  109. client.Close()
  110. select {
  111. case receivedBytes := <-receivedCh:
  112. t.Fatalf("Expected error, got %v", receivedBytes)
  113. case err := <-errorsCh:
  114. assert.NotNil(err)
  115. assert.False(mconn.IsRunning())
  116. case <-time.After(500 * time.Millisecond):
  117. t.Fatal("Did not receive error in 500ms")
  118. }
  119. }
  120. func newClientAndServerConnsForReadErrors(require *require.Assertions, chOnErr chan struct{}) (*MConnection, *MConnection) {
  121. server, client := netPipe()
  122. onReceive := func(chID byte, msgBytes []byte) {}
  123. onError := func(r interface{}) {}
  124. // create client conn with two channels
  125. chDescs := []*ChannelDescriptor{
  126. {ID: 0x01, Priority: 1, SendQueueCapacity: 1},
  127. {ID: 0x02, Priority: 1, SendQueueCapacity: 1},
  128. }
  129. mconnClient := NewMConnection(client, chDescs, onReceive, onError)
  130. mconnClient.SetLogger(log.TestingLogger().With("module", "client"))
  131. _, err := mconnClient.Start()
  132. require.Nil(err)
  133. // create server conn with 1 channel
  134. // it fires on chOnErr when there's an error
  135. serverLogger := log.TestingLogger().With("module", "server")
  136. onError = func(r interface{}) {
  137. chOnErr <- struct{}{}
  138. }
  139. mconnServer := createMConnectionWithCallbacks(server, onReceive, onError)
  140. mconnServer.SetLogger(serverLogger)
  141. _, err = mconnServer.Start()
  142. require.Nil(err)
  143. return mconnClient, mconnServer
  144. }
  145. func expectSend(ch chan struct{}) bool {
  146. after := time.After(time.Second * 5)
  147. select {
  148. case <-ch:
  149. return true
  150. case <-after:
  151. return false
  152. }
  153. }
  154. func TestMConnectionReadErrorBadEncoding(t *testing.T) {
  155. assert, require := assert.New(t), require.New(t)
  156. chOnErr := make(chan struct{})
  157. mconnClient, mconnServer := newClientAndServerConnsForReadErrors(require, chOnErr)
  158. defer mconnClient.Stop()
  159. defer mconnServer.Stop()
  160. client := mconnClient.conn
  161. msg := "Ant-Man"
  162. // send badly encoded msgPacket
  163. var n int
  164. var err error
  165. wire.WriteByte(packetTypeMsg, client, &n, &err)
  166. wire.WriteByteSlice([]byte(msg), client, &n, &err)
  167. assert.True(expectSend(chOnErr), "badly encoded msgPacket")
  168. }
  169. func TestMConnectionReadErrorUnknownChannel(t *testing.T) {
  170. assert, require := assert.New(t), require.New(t)
  171. chOnErr := make(chan struct{})
  172. mconnClient, mconnServer := newClientAndServerConnsForReadErrors(require, chOnErr)
  173. defer mconnClient.Stop()
  174. defer mconnServer.Stop()
  175. msg := "Ant-Man"
  176. // fail to send msg on channel unknown by client
  177. assert.False(mconnClient.Send(0x03, msg))
  178. // send msg on channel unknown by the server.
  179. // should cause an error
  180. assert.True(mconnClient.Send(0x02, msg))
  181. assert.True(expectSend(chOnErr), "unknown channel")
  182. }
  183. func TestMConnectionReadErrorLongMessage(t *testing.T) {
  184. assert, require := assert.New(t), require.New(t)
  185. chOnErr := make(chan struct{})
  186. chOnRcv := make(chan struct{})
  187. mconnClient, mconnServer := newClientAndServerConnsForReadErrors(require, chOnErr)
  188. defer mconnClient.Stop()
  189. defer mconnServer.Stop()
  190. mconnServer.onReceive = func(chID byte, msgBytes []byte) {
  191. chOnRcv <- struct{}{}
  192. }
  193. client := mconnClient.conn
  194. // send msg thats just right
  195. var n int
  196. var err error
  197. packet := msgPacket{
  198. ChannelID: 0x01,
  199. Bytes: make([]byte, mconnClient.config.maxMsgPacketTotalSize()-5),
  200. EOF: 1,
  201. }
  202. writeMsgPacketTo(packet, client, &n, &err)
  203. assert.True(expectSend(chOnRcv), "msg just right")
  204. // send msg thats too long
  205. packet = msgPacket{
  206. ChannelID: 0x01,
  207. Bytes: make([]byte, mconnClient.config.maxMsgPacketTotalSize()-4),
  208. EOF: 1,
  209. }
  210. writeMsgPacketTo(packet, client, &n, &err)
  211. assert.True(expectSend(chOnErr), "msg too long")
  212. }
  213. func TestMConnectionReadErrorUnknownMsgType(t *testing.T) {
  214. assert, require := assert.New(t), require.New(t)
  215. chOnErr := make(chan struct{})
  216. mconnClient, mconnServer := newClientAndServerConnsForReadErrors(require, chOnErr)
  217. defer mconnClient.Stop()
  218. defer mconnServer.Stop()
  219. // send msg with unknown msg type
  220. var n int
  221. var err error
  222. wire.WriteByte(0x04, mconnClient.conn, &n, &err)
  223. assert.True(expectSend(chOnErr), "unknown msg type")
  224. }
  225. func TestMConnectionTrySend(t *testing.T) {
  226. assert, require := assert.New(t), require.New(t)
  227. server, client := netPipe()
  228. defer server.Close()
  229. defer client.Close()
  230. mconn := createTestMConnection(client)
  231. _, err := mconn.Start()
  232. require.Nil(err)
  233. defer mconn.Stop()
  234. msg := "Semicolon-Woman"
  235. resultCh := make(chan string, 2)
  236. assert.True(mconn.TrySend(0x01, msg))
  237. server.Read(make([]byte, len(msg)))
  238. assert.True(mconn.CanSend(0x01))
  239. assert.True(mconn.TrySend(0x01, msg))
  240. assert.False(mconn.CanSend(0x01))
  241. go func() {
  242. mconn.TrySend(0x01, msg)
  243. resultCh <- "TrySend"
  244. }()
  245. go func() {
  246. mconn.Send(0x01, msg)
  247. resultCh <- "Send"
  248. }()
  249. assert.False(mconn.CanSend(0x01))
  250. assert.False(mconn.TrySend(0x01, msg))
  251. assert.Equal("TrySend", <-resultCh)
  252. server.Read(make([]byte, len(msg)))
  253. assert.Equal("Send", <-resultCh) // Order constrained by parallel blocking above
  254. }