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.

136 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
  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. // Introduce each peer.
  33. go func() {
  34. for _, peer := range peers {
  35. pool.SetPeerHeight(peer.id, peer.height)
  36. }
  37. }()
  38. // Start a goroutine to pull blocks
  39. go func() {
  40. for {
  41. if !pool.IsRunning() {
  42. return
  43. }
  44. first, second := pool.PeekTwoBlocks()
  45. if first != nil && second != nil {
  46. pool.PopRequest()
  47. } else {
  48. time.Sleep(1 * time.Second)
  49. }
  50. }
  51. }()
  52. // Pull from channels
  53. for {
  54. select {
  55. case peerID := <-timeoutsCh:
  56. t.Errorf("timeout: %v", peerID)
  57. case request := <-requestsCh:
  58. log.Info("TEST: Pulled new BlockRequest", "request", request)
  59. if request.Height == 300 {
  60. return // Done!
  61. }
  62. // Request desired, pretend like we got the block immediately.
  63. go func() {
  64. block := &types.Block{Header: &types.Header{Height: request.Height}}
  65. pool.AddBlock(request.PeerID, block, 123)
  66. log.Info("TEST: Added block", "block", request.Height, "peer", request.PeerID)
  67. }()
  68. }
  69. }
  70. pool.Stop()
  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. for _, peer := range peers {
  80. log.Info("Peer", "id", peer.id)
  81. }
  82. // Introduce each peer.
  83. go func() {
  84. for _, peer := range peers {
  85. pool.SetPeerHeight(peer.id, peer.height)
  86. }
  87. }()
  88. // Start a goroutine to pull blocks
  89. go func() {
  90. for {
  91. if !pool.IsRunning() {
  92. return
  93. }
  94. first, second := pool.PeekTwoBlocks()
  95. if first != nil && second != nil {
  96. pool.PopRequest()
  97. } else {
  98. time.Sleep(1 * time.Second)
  99. }
  100. }
  101. }()
  102. // Pull from channels
  103. counter := 0
  104. timedOut := map[string]struct{}{}
  105. for {
  106. select {
  107. case peerID := <-timeoutsCh:
  108. log.Info("Timeout", "peerID", peerID)
  109. if _, ok := timedOut[peerID]; !ok {
  110. counter++
  111. if counter == len(peers) {
  112. return // Done!
  113. }
  114. }
  115. case request := <-requestsCh:
  116. log.Info("TEST: Pulled new BlockRequest", "request", request)
  117. }
  118. }
  119. pool.Stop()
  120. }