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.

147 lines
3.0 KiB

8 years ago
8 years ago
8 years ago
10 years ago
8 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. package blockchain
  2. import (
  3. "testing"
  4. "time"
  5. cmn "github.com/tendermint/tendermint/libs/common"
  6. "github.com/tendermint/tendermint/libs/log"
  7. "github.com/tendermint/tendermint/p2p"
  8. "github.com/tendermint/tendermint/types"
  9. )
  10. func init() {
  11. peerTimeout = 2 * time.Second
  12. }
  13. type testPeer struct {
  14. id p2p.ID
  15. height int64
  16. }
  17. func makePeers(numPeers int, minHeight, maxHeight int64) map[p2p.ID]testPeer {
  18. peers := make(map[p2p.ID]testPeer, numPeers)
  19. for i := 0; i < numPeers; i++ {
  20. peerID := p2p.ID(cmn.RandStr(12))
  21. height := minHeight + cmn.RandInt63n(maxHeight-minHeight)
  22. peers[peerID] = testPeer{peerID, height}
  23. }
  24. return peers
  25. }
  26. func TestBasic(t *testing.T) {
  27. start := int64(42)
  28. peers := makePeers(10, start+1, 1000)
  29. errorsCh := make(chan peerError, 1000)
  30. requestsCh := make(chan BlockRequest, 1000)
  31. pool := NewBlockPool(start, requestsCh, errorsCh)
  32. pool.SetLogger(log.TestingLogger())
  33. err := pool.Start()
  34. if err != nil {
  35. t.Error(err)
  36. }
  37. defer pool.Stop()
  38. // Introduce each peer.
  39. go func() {
  40. for _, peer := range peers {
  41. pool.SetPeerHeight(peer.id, peer.height)
  42. }
  43. }()
  44. // Start a goroutine to pull blocks
  45. go func() {
  46. for {
  47. if !pool.IsRunning() {
  48. return
  49. }
  50. first, second := pool.PeekTwoBlocks()
  51. if first != nil && second != nil {
  52. pool.PopRequest()
  53. } else {
  54. time.Sleep(1 * time.Second)
  55. }
  56. }
  57. }()
  58. // Pull from channels
  59. for {
  60. select {
  61. case err := <-errorsCh:
  62. t.Error(err)
  63. case request := <-requestsCh:
  64. t.Logf("Pulled new BlockRequest %v", request)
  65. if request.Height == 300 {
  66. return // Done!
  67. }
  68. // Request desired, pretend like we got the block immediately.
  69. go func() {
  70. block := &types.Block{Header: types.Header{Height: request.Height}}
  71. pool.AddBlock(request.PeerID, block, 123)
  72. t.Logf("Added block from peer %v (height: %v)", request.PeerID, request.Height)
  73. }()
  74. }
  75. }
  76. }
  77. func TestTimeout(t *testing.T) {
  78. start := int64(42)
  79. peers := makePeers(10, start+1, 1000)
  80. errorsCh := make(chan peerError, 1000)
  81. requestsCh := make(chan BlockRequest, 1000)
  82. pool := NewBlockPool(start, requestsCh, errorsCh)
  83. pool.SetLogger(log.TestingLogger())
  84. err := pool.Start()
  85. if err != nil {
  86. t.Error(err)
  87. }
  88. defer pool.Stop()
  89. for _, peer := range peers {
  90. t.Logf("Peer %v", peer.id)
  91. }
  92. // Introduce each peer.
  93. go func() {
  94. for _, peer := range peers {
  95. pool.SetPeerHeight(peer.id, peer.height)
  96. }
  97. }()
  98. // Start a goroutine to pull blocks
  99. go func() {
  100. for {
  101. if !pool.IsRunning() {
  102. return
  103. }
  104. first, second := pool.PeekTwoBlocks()
  105. if first != nil && second != nil {
  106. pool.PopRequest()
  107. } else {
  108. time.Sleep(1 * time.Second)
  109. }
  110. }
  111. }()
  112. // Pull from channels
  113. counter := 0
  114. timedOut := map[p2p.ID]struct{}{}
  115. for {
  116. select {
  117. case err := <-errorsCh:
  118. t.Log(err)
  119. // consider error to be always timeout here
  120. if _, ok := timedOut[err.peerID]; !ok {
  121. counter++
  122. if counter == len(peers) {
  123. return // Done!
  124. }
  125. }
  126. case request := <-requestsCh:
  127. t.Logf("Pulled new BlockRequest %+v", request)
  128. }
  129. }
  130. }