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.

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