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.

137 lines
2.8 KiB

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