|
|
- package blockchain
-
- import (
- "math/rand"
- "testing"
-
- . "github.com/tendermint/tendermint/common"
- "github.com/tendermint/tendermint/types"
- )
-
- type testPeer struct {
- id string
- height uint
- }
-
- func makePeers(numPeers int, minHeight, maxHeight uint) map[string]testPeer {
- peers := make(map[string]testPeer, numPeers)
- for i := 0; i < numPeers; i++ {
- peerId := RandStr(12)
- height := minHeight + uint(rand.Intn(int(maxHeight-minHeight)))
- peers[peerId] = testPeer{peerId, height}
- }
- return peers
- }
-
- func TestBasic(t *testing.T) {
- // 100 peers anywhere at height 0 to 1000.
- peers := makePeers(100, 0, 1000)
-
- start := uint(42)
- maxHeight := uint(300)
- timeoutsCh := make(chan string, 100)
- requestsCh := make(chan BlockRequest, 100)
- blocksCh := make(chan *types.Block, 100)
-
- pool := NewBlockPool(start, timeoutsCh, requestsCh, blocksCh)
- pool.Start()
-
- // Introduce each peer.
- go func() {
- for _, peer := range peers {
- pool.SetPeerStatus(peer.id, peer.height)
- }
- }()
-
- lastSeenBlock := uint(41)
-
- // Pull from channels
- for {
- select {
- case peerId := <-timeoutsCh:
- t.Errorf("timeout: %v", peerId)
- case request := <-requestsCh:
- log.Debug("TEST: Pulled new BlockRequest", "request", request)
- // After a while, pretend like we got a block from the peer.
- go func() {
- block := &types.Block{Header: &types.Header{Height: request.Height}}
- pool.AddBlock(block, request.PeerId)
- log.Debug("TEST: Added block", "block", request.Height, "peer", request.PeerId)
- }()
- case block := <-blocksCh:
- log.Debug("TEST: Pulled new Block", "height", block.Height)
- if block.Height != lastSeenBlock+1 {
- t.Fatalf("Wrong order of blocks seen. Expected: %v Got: %v", lastSeenBlock+1, block.Height)
- }
- lastSeenBlock++
- if block.Height == maxHeight {
- return // Done!
- }
- }
- }
-
- pool.Stop()
- }
-
- func TestTimeout(t *testing.T) {
- peers := makePeers(100, 0, 1000)
- start := uint(42)
- timeoutsCh := make(chan string, 10)
- requestsCh := make(chan BlockRequest, 10)
- blocksCh := make(chan *types.Block, 100)
-
- pool := NewBlockPool(start, timeoutsCh, requestsCh, blocksCh)
- pool.Start()
-
- // Introduce each peer.
- go func() {
- for _, peer := range peers {
- pool.SetPeerStatus(peer.id, peer.height)
- }
- }()
-
- // Pull from channels
- for {
- select {
- case peerId := <-timeoutsCh:
- // Timed out. Done!
- if peers[peerId].id != peerId {
- t.Errorf("Unexpected peer from timeoutsCh")
- }
- return
- case _ = <-requestsCh:
- // Don't do anything, let it time out.
- case _ = <-blocksCh:
- t.Errorf("Got block when none expected")
- return
- }
- }
-
- pool.Stop()
-
- }
|