udp_test.go 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. package discover
  2. import (
  3. "fmt"
  4. logpkg "log"
  5. "net"
  6. "os"
  7. "testing"
  8. "time"
  9. "github.com/ethereum/go-ethereum/logger"
  10. )
  11. func init() {
  12. logger.AddLogSystem(logger.NewStdLogSystem(os.Stdout, logpkg.LstdFlags, logger.ErrorLevel))
  13. }
  14. func TestUDP_ping(t *testing.T) {
  15. t.Parallel()
  16. n1, _ := ListenUDP(newkey(), "127.0.0.1:0", nil)
  17. n2, _ := ListenUDP(newkey(), "127.0.0.1:0", nil)
  18. defer n1.Close()
  19. defer n2.Close()
  20. if err := n1.net.ping(n2.self); err != nil {
  21. t.Fatalf("ping error: %v", err)
  22. }
  23. if find(n2, n1.self.ID) == nil {
  24. t.Errorf("node 2 does not contain id of node 1")
  25. }
  26. if e := find(n1, n2.self.ID); e != nil {
  27. t.Errorf("node 1 does contains id of node 2: %v", e)
  28. }
  29. }
  30. func find(tab *Table, id NodeID) *Node {
  31. for _, b := range tab.buckets {
  32. for _, e := range b.entries {
  33. if e.ID == id {
  34. return e
  35. }
  36. }
  37. }
  38. return nil
  39. }
  40. func TestUDP_findnode(t *testing.T) {
  41. t.Parallel()
  42. n1, _ := ListenUDP(newkey(), "127.0.0.1:0", nil)
  43. n2, _ := ListenUDP(newkey(), "127.0.0.1:0", nil)
  44. defer n1.Close()
  45. defer n2.Close()
  46. // put a few nodes into n2. the exact distribution shouldn't
  47. // matter much, altough we need to take care not to overflow
  48. // any bucket.
  49. target := randomID(n1.self.ID, 100)
  50. nodes := &nodesByDistance{target: target}
  51. for i := 0; i < bucketSize; i++ {
  52. n2.add([]*Node{&Node{
  53. IP: net.IP{1, 2, 3, byte(i)},
  54. DiscPort: i + 2,
  55. TCPPort: i + 2,
  56. ID: randomID(n2.self.ID, i+2),
  57. }})
  58. }
  59. n2.add(nodes.entries)
  60. n2.bumpOrAdd(n1.self.ID, &net.UDPAddr{IP: n1.self.IP, Port: n1.self.DiscPort})
  61. expected := n2.closest(target, bucketSize)
  62. err := runUDP(10, func() error {
  63. result, _ := n1.net.findnode(n2.self, target)
  64. if len(result) != bucketSize {
  65. return fmt.Errorf("wrong number of results: got %d, want %d", len(result), bucketSize)
  66. }
  67. for i := range result {
  68. if result[i].ID != expected.entries[i].ID {
  69. return fmt.Errorf("result mismatch at %d:\n got: %v\n want: %v", i, result[i], expected.entries[i])
  70. }
  71. }
  72. return nil
  73. })
  74. if err != nil {
  75. t.Error(err)
  76. }
  77. }
  78. func TestUDP_replytimeout(t *testing.T) {
  79. t.Parallel()
  80. // reserve a port so we don't talk to an existing service by accident
  81. addr, _ := net.ResolveUDPAddr("udp", "127.0.0.1:0")
  82. fd, err := net.ListenUDP("udp", addr)
  83. if err != nil {
  84. t.Fatal(err)
  85. }
  86. defer fd.Close()
  87. n1, _ := ListenUDP(newkey(), "127.0.0.1:0", nil)
  88. defer n1.Close()
  89. n2 := n1.bumpOrAdd(randomID(n1.self.ID, 10), fd.LocalAddr().(*net.UDPAddr))
  90. if err := n1.net.ping(n2); err != errTimeout {
  91. t.Error("expected timeout error, got", err)
  92. }
  93. if result, err := n1.net.findnode(n2, n1.self.ID); err != errTimeout {
  94. t.Error("expected timeout error, got", err)
  95. } else if len(result) > 0 {
  96. t.Error("expected empty result, got", result)
  97. }
  98. }
  99. func TestUDP_findnodeMultiReply(t *testing.T) {
  100. t.Parallel()
  101. n1, _ := ListenUDP(newkey(), "127.0.0.1:0", nil)
  102. n2, _ := ListenUDP(newkey(), "127.0.0.1:0", nil)
  103. udp2 := n2.net.(*udp)
  104. defer n1.Close()
  105. defer n2.Close()
  106. err := runUDP(10, func() error {
  107. nodes := make([]*Node, bucketSize)
  108. for i := range nodes {
  109. nodes[i] = &Node{
  110. IP: net.IP{1, 2, 3, 4},
  111. DiscPort: i + 1,
  112. TCPPort: i + 1,
  113. ID: randomID(n2.self.ID, i+1),
  114. }
  115. }
  116. // ask N2 for neighbors. it will send an empty reply back.
  117. // the request will wait for up to bucketSize replies.
  118. resultc := make(chan []*Node)
  119. errc := make(chan error)
  120. go func() {
  121. ns, err := n1.net.findnode(n2.self, n1.self.ID)
  122. if err != nil {
  123. errc <- err
  124. } else {
  125. resultc <- ns
  126. }
  127. }()
  128. // send a few more neighbors packets to N1.
  129. // it should collect those.
  130. for end := 0; end < len(nodes); {
  131. off := end
  132. if end = end + 5; end > len(nodes) {
  133. end = len(nodes)
  134. }
  135. udp2.send(n1.self, neighborsPacket, neighbors{
  136. Nodes: nodes[off:end],
  137. Expiration: uint64(time.Now().Add(10 * time.Second).Unix()),
  138. })
  139. }
  140. // check that they are all returned. we cannot just check for
  141. // equality because they might not be returned in the order they
  142. // were sent.
  143. var result []*Node
  144. select {
  145. case result = <-resultc:
  146. case err := <-errc:
  147. return err
  148. }
  149. if hasDuplicates(result) {
  150. return fmt.Errorf("result slice contains duplicates")
  151. }
  152. if len(result) != len(nodes) {
  153. return fmt.Errorf("wrong number of nodes returned: got %d, want %d", len(result), len(nodes))
  154. }
  155. matched := make(map[NodeID]bool)
  156. for _, n := range result {
  157. for _, expn := range nodes {
  158. if n.ID == expn.ID { // && bytes.Equal(n.Addr.IP, expn.Addr.IP) && n.Addr.Port == expn.Addr.Port {
  159. matched[n.ID] = true
  160. }
  161. }
  162. }
  163. if len(matched) != len(nodes) {
  164. return fmt.Errorf("wrong number of matching nodes: got %d, want %d", len(matched), len(nodes))
  165. }
  166. return nil
  167. })
  168. if err != nil {
  169. t.Error(err)
  170. }
  171. }
  172. // runUDP runs a test n times and returns an error if the test failed
  173. // in all n runs. This is necessary because UDP is unreliable even for
  174. // connections on the local machine, causing test failures.
  175. func runUDP(n int, test func() error) error {
  176. errcount := 0
  177. errors := ""
  178. for i := 0; i < n; i++ {
  179. if err := test(); err != nil {
  180. errors += fmt.Sprintf("\n#%d: %v", i, err)
  181. errcount++
  182. }
  183. }
  184. if errcount == n {
  185. return fmt.Errorf("failed on all %d iterations:%s", n, errors)
  186. }
  187. return nil
  188. }