peer_test.go 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. package p2p
  2. import (
  3. "bufio"
  4. "bytes"
  5. "encoding/hex"
  6. "io/ioutil"
  7. "net"
  8. "reflect"
  9. "testing"
  10. "time"
  11. )
  12. var discard = Protocol{
  13. Name: "discard",
  14. Length: 1,
  15. Run: func(p *Peer, rw MsgReadWriter) error {
  16. for {
  17. msg, err := rw.ReadMsg()
  18. if err != nil {
  19. return err
  20. }
  21. if err = msg.Discard(); err != nil {
  22. return err
  23. }
  24. }
  25. },
  26. }
  27. func testPeer(protos []Protocol) (net.Conn, *Peer, <-chan error) {
  28. conn1, conn2 := net.Pipe()
  29. id := NewSimpleClientIdentity("test", "0", "0", "public key")
  30. peer := newPeer(conn1, protos, nil)
  31. peer.ourID = id
  32. peer.pubkeyHook = func(*peerAddr) error { return nil }
  33. errc := make(chan error, 1)
  34. go func() {
  35. _, err := peer.loop()
  36. errc <- err
  37. }()
  38. return conn2, peer, errc
  39. }
  40. func TestPeerProtoReadMsg(t *testing.T) {
  41. defer testlog(t).detach()
  42. done := make(chan struct{})
  43. proto := Protocol{
  44. Name: "a",
  45. Length: 5,
  46. Run: func(peer *Peer, rw MsgReadWriter) error {
  47. msg, err := rw.ReadMsg()
  48. if err != nil {
  49. t.Errorf("read error: %v", err)
  50. }
  51. if msg.Code != 2 {
  52. t.Errorf("incorrect msg code %d relayed to protocol", msg.Code)
  53. }
  54. data, err := ioutil.ReadAll(msg.Payload)
  55. if err != nil {
  56. t.Errorf("payload read error: %v", err)
  57. }
  58. expdata, _ := hex.DecodeString("0183303030")
  59. if !bytes.Equal(expdata, data) {
  60. t.Errorf("incorrect msg data %x", data)
  61. }
  62. close(done)
  63. return nil
  64. },
  65. }
  66. net, peer, errc := testPeer([]Protocol{proto})
  67. defer net.Close()
  68. peer.startSubprotocols([]Cap{proto.cap()})
  69. writeMsg(net, NewMsg(18, 1, "000"))
  70. select {
  71. case <-done:
  72. case err := <-errc:
  73. t.Errorf("peer returned: %v", err)
  74. case <-time.After(2 * time.Second):
  75. t.Errorf("receive timeout")
  76. }
  77. }
  78. func TestPeerProtoReadLargeMsg(t *testing.T) {
  79. defer testlog(t).detach()
  80. msgsize := uint32(10 * 1024 * 1024)
  81. done := make(chan struct{})
  82. proto := Protocol{
  83. Name: "a",
  84. Length: 5,
  85. Run: func(peer *Peer, rw MsgReadWriter) error {
  86. msg, err := rw.ReadMsg()
  87. if err != nil {
  88. t.Errorf("read error: %v", err)
  89. }
  90. if msg.Size != msgsize+4 {
  91. t.Errorf("incorrect msg.Size, got %d, expected %d", msg.Size, msgsize)
  92. }
  93. msg.Discard()
  94. close(done)
  95. return nil
  96. },
  97. }
  98. net, peer, errc := testPeer([]Protocol{proto})
  99. defer net.Close()
  100. peer.startSubprotocols([]Cap{proto.cap()})
  101. writeMsg(net, NewMsg(18, make([]byte, msgsize)))
  102. select {
  103. case <-done:
  104. case err := <-errc:
  105. t.Errorf("peer returned: %v", err)
  106. case <-time.After(2 * time.Second):
  107. t.Errorf("receive timeout")
  108. }
  109. }
  110. func TestPeerProtoEncodeMsg(t *testing.T) {
  111. defer testlog(t).detach()
  112. proto := Protocol{
  113. Name: "a",
  114. Length: 2,
  115. Run: func(peer *Peer, rw MsgReadWriter) error {
  116. if err := rw.EncodeMsg(2); err == nil {
  117. t.Error("expected error for out-of-range msg code, got nil")
  118. }
  119. if err := rw.EncodeMsg(1); err != nil {
  120. t.Errorf("write error: %v", err)
  121. }
  122. return nil
  123. },
  124. }
  125. net, peer, _ := testPeer([]Protocol{proto})
  126. defer net.Close()
  127. peer.startSubprotocols([]Cap{proto.cap()})
  128. bufr := bufio.NewReader(net)
  129. msg, err := readMsg(bufr)
  130. if err != nil {
  131. t.Errorf("read error: %v", err)
  132. }
  133. if msg.Code != 17 {
  134. t.Errorf("incorrect message code: got %d, expected %d", msg.Code, 17)
  135. }
  136. }
  137. func TestPeerWrite(t *testing.T) {
  138. defer testlog(t).detach()
  139. net, peer, peerErr := testPeer([]Protocol{discard})
  140. defer net.Close()
  141. peer.startSubprotocols([]Cap{discard.cap()})
  142. // test write errors
  143. if err := peer.writeProtoMsg("b", NewMsg(3)); err == nil {
  144. t.Errorf("expected error for unknown protocol, got nil")
  145. }
  146. if err := peer.writeProtoMsg("discard", NewMsg(8)); err == nil {
  147. t.Errorf("expected error for out-of-range msg code, got nil")
  148. } else if perr, ok := err.(*peerError); !ok || perr.Code != errInvalidMsgCode {
  149. t.Errorf("wrong error for out-of-range msg code, got %#v", err)
  150. }
  151. // setup for reading the message on the other end
  152. read := make(chan struct{})
  153. go func() {
  154. bufr := bufio.NewReader(net)
  155. msg, err := readMsg(bufr)
  156. if err != nil {
  157. t.Errorf("read error: %v", err)
  158. } else if msg.Code != 16 {
  159. t.Errorf("wrong code, got %d, expected %d", msg.Code, 16)
  160. }
  161. msg.Discard()
  162. close(read)
  163. }()
  164. // test succcessful write
  165. if err := peer.writeProtoMsg("discard", NewMsg(0)); err != nil {
  166. t.Errorf("expect no error for known protocol: %v", err)
  167. }
  168. select {
  169. case <-read:
  170. case err := <-peerErr:
  171. t.Fatalf("peer stopped: %v", err)
  172. }
  173. }
  174. func TestPeerActivity(t *testing.T) {
  175. // shorten inactivityTimeout while this test is running
  176. oldT := inactivityTimeout
  177. defer func() { inactivityTimeout = oldT }()
  178. inactivityTimeout = 20 * time.Millisecond
  179. net, peer, peerErr := testPeer([]Protocol{discard})
  180. defer net.Close()
  181. peer.startSubprotocols([]Cap{discard.cap()})
  182. sub := peer.activity.Subscribe(time.Time{})
  183. defer sub.Unsubscribe()
  184. for i := 0; i < 6; i++ {
  185. writeMsg(net, NewMsg(16))
  186. select {
  187. case <-sub.Chan():
  188. case <-time.After(inactivityTimeout / 2):
  189. t.Fatal("no event within ", inactivityTimeout/2)
  190. case err := <-peerErr:
  191. t.Fatal("peer error", err)
  192. }
  193. }
  194. select {
  195. case <-time.After(inactivityTimeout * 2):
  196. case <-sub.Chan():
  197. t.Fatal("got activity event while connection was inactive")
  198. case err := <-peerErr:
  199. t.Fatal("peer error", err)
  200. }
  201. }
  202. func TestNewPeer(t *testing.T) {
  203. id := NewSimpleClientIdentity("clientid", "version", "customid", "pubkey")
  204. caps := []Cap{{"foo", 2}, {"bar", 3}}
  205. p := NewPeer(id, caps)
  206. if !reflect.DeepEqual(p.Caps(), caps) {
  207. t.Errorf("Caps mismatch: got %v, expected %v", p.Caps(), caps)
  208. }
  209. if p.Identity() != id {
  210. t.Errorf("Identity mismatch: got %v, expected %v", p.Identity(), id)
  211. }
  212. // Should not hang.
  213. p.Disconnect(DiscAlreadyConnected)
  214. }