tendermint/blockchain/pool_test.go

183 lines
3.6 KiB
Go
Raw Permalink Normal View History

package blockchain
2015-03-22 12:46:53 -07:00
import (
"testing"
2015-03-22 19:20:54 -07:00
"time"
2015-03-22 12:46:53 -07:00
2018-07-01 22:36:49 -04:00
cmn "github.com/tendermint/tendermint/libs/common"
"github.com/tendermint/tendermint/libs/log"
2018-01-03 11:29:19 +01:00
"github.com/tendermint/tendermint/p2p"
"github.com/tendermint/tendermint/types"
2015-03-22 12:46:53 -07:00
)
func init() {
peerTimeout = 2 * time.Second
}
2015-03-22 12:46:53 -07:00
type testPeer struct {
id p2p.ID
height int64
inputChan chan inputData //make sure each peer's data is sequential
2015-03-22 12:46:53 -07:00
}
type inputData struct {
t *testing.T
pool *BlockPool
request BlockRequest
}
func (p testPeer) runInputRoutine() {
go func() {
for input := range p.inputChan {
p.simulateInput(input)
}
}()
}
// Request desired, pretend like we got the block immediately.
func (p testPeer) simulateInput(input inputData) {
block := &types.Block{Header: types.Header{Height: input.request.Height}}
input.pool.AddBlock(input.request.PeerID, block, 123)
input.t.Logf("Added block from peer %v (height: %v)", input.request.PeerID, input.request.Height)
}
type testPeers map[p2p.ID]testPeer
func (ps testPeers) start() {
for _, v := range ps {
v.runInputRoutine()
}
}
func (ps testPeers) stop() {
for _, v := range ps {
close(v.inputChan)
}
}
func makePeers(numPeers int, minHeight, maxHeight int64) testPeers {
peers := make(testPeers, numPeers)
2015-03-22 12:46:53 -07:00
for i := 0; i < numPeers; i++ {
2018-01-01 21:27:38 -05:00
peerID := p2p.ID(cmn.RandStr(12))
height := minHeight + cmn.RandInt63n(maxHeight-minHeight)
peers[peerID] = testPeer{peerID, height, make(chan inputData, 10)}
2015-03-22 12:46:53 -07:00
}
return peers
}
func TestBasic(t *testing.T) {
start := int64(42)
2015-09-09 21:44:48 -07:00
peers := makePeers(10, start+1, 1000)
2018-03-04 13:42:26 +04:00
errorsCh := make(chan peerError, 1000)
requestsCh := make(chan BlockRequest, 1000)
pool := NewBlockPool(start, requestsCh, errorsCh)
2017-05-02 11:53:32 +04:00
pool.SetLogger(log.TestingLogger())
2017-09-06 11:50:43 -04:00
err := pool.Start()
2017-09-06 11:50:43 -04:00
if err != nil {
t.Error(err)
}
defer pool.Stop()
2015-03-22 12:46:53 -07:00
peers.start()
defer peers.stop()
2015-03-22 12:46:53 -07:00
// Introduce each peer.
go func() {
for _, peer := range peers {
2015-03-24 11:02:30 -07:00
pool.SetPeerHeight(peer.id, peer.height)
2015-03-22 12:46:53 -07:00
}
}()
2015-03-24 11:02:30 -07:00
// Start a goroutine to pull blocks
go func() {
for {
if !pool.IsRunning() {
return
}
first, second := pool.PeekTwoBlocks()
if first != nil && second != nil {
pool.PopRequest()
} else {
time.Sleep(1 * time.Second)
}
}
}()
2015-03-22 12:46:53 -07:00
// Pull from channels
for {
select {
case err := <-errorsCh:
t.Error(err)
2015-03-22 12:46:53 -07:00
case request := <-requestsCh:
2017-05-02 11:53:32 +04:00
t.Logf("Pulled new BlockRequest %v", request)
2015-03-24 11:02:30 -07:00
if request.Height == 300 {
return // Done!
}
peers[request.PeerID].inputChan <- inputData{t, pool, request}
2015-03-22 12:46:53 -07:00
}
}
2015-03-22 16:23:24 -07:00
}
func TestTimeout(t *testing.T) {
start := int64(42)
2015-09-09 21:44:48 -07:00
peers := makePeers(10, start+1, 1000)
2018-03-04 13:42:26 +04:00
errorsCh := make(chan peerError, 1000)
requestsCh := make(chan BlockRequest, 1000)
pool := NewBlockPool(start, requestsCh, errorsCh)
2017-05-02 11:53:32 +04:00
pool.SetLogger(log.TestingLogger())
err := pool.Start()
2017-09-06 11:50:43 -04:00
if err != nil {
t.Error(err)
}
defer pool.Stop()
2015-03-22 16:23:24 -07:00
2015-09-09 21:44:48 -07:00
for _, peer := range peers {
2017-05-12 17:40:57 +02:00
t.Logf("Peer %v", peer.id)
2015-09-09 21:44:48 -07:00
}
2015-03-22 16:23:24 -07:00
// Introduce each peer.
go func() {
for _, peer := range peers {
2015-03-24 11:02:30 -07:00
pool.SetPeerHeight(peer.id, peer.height)
}
}()
// Start a goroutine to pull blocks
go func() {
for {
if !pool.IsRunning() {
return
}
first, second := pool.PeekTwoBlocks()
if first != nil && second != nil {
pool.PopRequest()
} else {
time.Sleep(1 * time.Second)
}
2015-03-22 16:23:24 -07:00
}
}()
// Pull from channels
2015-03-24 11:02:30 -07:00
counter := 0
2018-01-01 21:27:38 -05:00
timedOut := map[p2p.ID]struct{}{}
2015-03-22 16:23:24 -07:00
for {
select {
case err := <-errorsCh:
t.Log(err)
// consider error to be always timeout here
if _, ok := timedOut[err.peerID]; !ok {
2015-03-24 11:02:30 -07:00
counter++
if counter == len(peers) {
return // Done!
}
2015-03-22 16:23:24 -07:00
}
2015-03-24 11:02:30 -07:00
case request := <-requestsCh:
2017-05-12 17:40:57 +02:00
t.Logf("Pulled new BlockRequest %+v", request)
2015-03-22 16:23:24 -07:00
}
}
2015-03-22 12:46:53 -07:00
}