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.

128 lines
2.6 KiB

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