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

8 years ago
10 years ago
10 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/tmlibs/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. }