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

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/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. }