blockchain: fixing reactor tests
This commit is contained in:
parent
068f01368f
commit
659768783f
|
@ -4,13 +4,15 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
wire "github.com/tendermint/go-wire"
|
||||||
|
cmn "github.com/tendermint/tmlibs/common"
|
||||||
|
"github.com/tendermint/tmlibs/db"
|
||||||
|
"github.com/tendermint/tmlibs/log"
|
||||||
|
|
||||||
cfg "github.com/tendermint/tendermint/config"
|
cfg "github.com/tendermint/tendermint/config"
|
||||||
"github.com/tendermint/tendermint/p2p"
|
"github.com/tendermint/tendermint/p2p"
|
||||||
sm "github.com/tendermint/tendermint/state"
|
sm "github.com/tendermint/tendermint/state"
|
||||||
"github.com/tendermint/tendermint/types"
|
"github.com/tendermint/tendermint/types"
|
||||||
cmn "github.com/tendermint/tmlibs/common"
|
|
||||||
"github.com/tendermint/tmlibs/db"
|
|
||||||
"github.com/tendermint/tmlibs/log"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func newBlockchainReactor(logger log.Logger, maxBlockHeight int) *BlockchainReactor {
|
func newBlockchainReactor(logger log.Logger, maxBlockHeight int) *BlockchainReactor {
|
||||||
|
@ -23,7 +25,8 @@ func newBlockchainReactor(logger log.Logger, maxBlockHeight int) *BlockchainReac
|
||||||
|
|
||||||
// Get State
|
// Get State
|
||||||
stateDB := db.NewDB("state", config.DBBackend, config.DBDir())
|
stateDB := db.NewDB("state", config.DBBackend, config.DBDir())
|
||||||
state := sm.GetState(stateDB, config.GenesisFile())
|
state, _ := sm.GetState(stateDB, config.GenesisFile())
|
||||||
|
|
||||||
state.SetLogger(stateLogger)
|
state.SetLogger(stateLogger)
|
||||||
state.Save()
|
state.Save()
|
||||||
|
|
||||||
|
@ -39,21 +42,13 @@ func newBlockchainReactor(logger log.Logger, maxBlockHeight int) *BlockchainReac
|
||||||
for blockHeight := 1; blockHeight <= maxBlockHeight; blockHeight++ {
|
for blockHeight := 1; blockHeight <= maxBlockHeight; blockHeight++ {
|
||||||
firstBlock := makeBlock(blockHeight, state)
|
firstBlock := makeBlock(blockHeight, state)
|
||||||
secondBlock := makeBlock(blockHeight+1, state)
|
secondBlock := makeBlock(blockHeight+1, state)
|
||||||
firstParts := firstBlock.MakePartSet(types.DefaultBlockPartSize)
|
firstParts := firstBlock.MakePartSet(state.Params().BlockGossipParams.BlockPartSizeBytes)
|
||||||
blockStore.SaveBlock(firstBlock, firstParts, secondBlock.LastCommit)
|
blockStore.SaveBlock(firstBlock, firstParts, secondBlock.LastCommit)
|
||||||
}
|
}
|
||||||
|
|
||||||
return bcReactor
|
return bcReactor
|
||||||
}
|
}
|
||||||
|
|
||||||
func newbcrTestPeer(key string) *bcrTestPeer {
|
|
||||||
return &bcrTestPeer{
|
|
||||||
key: key,
|
|
||||||
kvm: make(map[byte]interface{}),
|
|
||||||
ch: make(chan *keyValue, 2),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNoBlockMessageResponse(t *testing.T) {
|
func TestNoBlockMessageResponse(t *testing.T) {
|
||||||
logBuf := new(bytes.Buffer)
|
logBuf := new(bytes.Buffer)
|
||||||
logger := log.NewTMLogger(logBuf)
|
logger := log.NewTMLogger(logBuf)
|
||||||
|
@ -68,131 +63,78 @@ func TestNoBlockMessageResponse(t *testing.T) {
|
||||||
bcr.AddPeer(peer)
|
bcr.AddPeer(peer)
|
||||||
|
|
||||||
chID := byte(0x01)
|
chID := byte(0x01)
|
||||||
|
|
||||||
tests := [...]struct {
|
tests := []struct {
|
||||||
height int
|
height int
|
||||||
existent bool
|
existent bool
|
||||||
}{
|
}{
|
||||||
0: {
|
{maxBlockHeight + 2, false},
|
||||||
height: maxBlockHeight + 2,
|
{10, true},
|
||||||
existent: false,
|
{1, true},
|
||||||
},
|
{100, false},
|
||||||
1: {
|
|
||||||
height: 10,
|
|
||||||
existent: true, // We should have this
|
|
||||||
},
|
|
||||||
2: {
|
|
||||||
height: 1,
|
|
||||||
existent: true, // We should have this
|
|
||||||
},
|
|
||||||
3: {
|
|
||||||
height: 100,
|
|
||||||
existent: false,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Currently the repsonses take asynchronous paths so
|
|
||||||
// the results are skewed. However, we can ensure that
|
|
||||||
// the (expectedHeight, expectedExistence) all tally up.
|
|
||||||
heightTally := map[int]bool{}
|
|
||||||
var results []BlockchainMessage
|
|
||||||
|
|
||||||
msgRequest := byte(0x10)
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
reqBlockBytes := []byte{msgRequest, 0x02, 0x00, byte(tt.height)}
|
reqBlockMsg := &bcBlockRequestMessage{tt.height}
|
||||||
|
reqBlockBytes := wire.BinaryBytes(struct{ BlockchainMessage }{reqBlockMsg})
|
||||||
bcr.Receive(chID, peer, reqBlockBytes)
|
bcr.Receive(chID, peer, reqBlockBytes)
|
||||||
heightTally[tt.height] = tt.existent
|
value := peer.lastValue()
|
||||||
kv := peer.lastKeyValue()
|
msg := value.(struct{ BlockchainMessage }).BlockchainMessage
|
||||||
results = append(results, kv.value.(struct{ BlockchainMessage }).BlockchainMessage)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, res := range results {
|
if tt.existent {
|
||||||
if bcRM, ok := res.(*bcBlockResponseMessage); ok {
|
if blockMsg, ok := msg.(*bcBlockResponseMessage); !ok {
|
||||||
block := bcRM.Block
|
t.Fatalf("Expected to receive a block response for height %d", tt.height)
|
||||||
if block == nil {
|
} else if blockMsg.Block.Height != tt.height {
|
||||||
t.Errorf("result: #%d: expecting a non-nil block", i)
|
t.Fatalf("Expected response to be for height %d, got %d", tt.height, blockMsg.Block.Height)
|
||||||
continue
|
|
||||||
}
|
|
||||||
mustExist, foundHeight := heightTally[block.Height]
|
|
||||||
if !foundHeight {
|
|
||||||
t.Errorf("result: #%d, missing height %d", i, block.Height)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if !mustExist {
|
|
||||||
t.Errorf("result: #%d mustExist", i)
|
|
||||||
} else {
|
|
||||||
delete(heightTally, block.Height)
|
|
||||||
}
|
|
||||||
} else if bcNBRSM, ok := res.(*bcNoBlockResponseMessage); ok {
|
|
||||||
mustExist, foundHeight := heightTally[bcNBRSM.Height]
|
|
||||||
if !foundHeight {
|
|
||||||
t.Errorf("result: #%d, missing height %d", i, bcNBRSM.Height)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if mustExist {
|
|
||||||
t.Errorf("result: #%d mustNotExist", i)
|
|
||||||
} else {
|
|
||||||
// Passes, remove this height from the tally
|
|
||||||
delete(heightTally, bcNBRSM.Height)
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
t.Errorf("result: #%d is an unexpected type: %T; data: %#v", i, res, res)
|
if noBlockMsg, ok := msg.(*bcNoBlockResponseMessage); !ok {
|
||||||
|
t.Fatalf("Expected to receive a no block response for height %d", tt.height)
|
||||||
|
} else if noBlockMsg.Height != tt.height {
|
||||||
|
t.Fatalf("Expected response to be for height %d, got %d", tt.height, noBlockMsg.Height)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(heightTally) > 0 {
|
|
||||||
t.Errorf("Untallied heights: %#v\n", heightTally)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------
|
||||||
|
// utility funcs
|
||||||
|
|
||||||
func makeTxs(blockNumber int) (txs []types.Tx) {
|
func makeTxs(blockNumber int) (txs []types.Tx) {
|
||||||
for i := 0; i < 10; i++ {
|
for i := 0; i < 10; i++ {
|
||||||
txs = append(txs, types.Tx([]byte{byte(blockNumber)}))
|
txs = append(txs, types.Tx([]byte{byte(blockNumber), byte(i)}))
|
||||||
}
|
}
|
||||||
return txs
|
return txs
|
||||||
}
|
}
|
||||||
|
|
||||||
const testPartSize = 65536
|
|
||||||
|
|
||||||
func makeBlock(blockNumber int, state *sm.State) *types.Block {
|
func makeBlock(blockNumber int, state *sm.State) *types.Block {
|
||||||
prevHash := state.LastBlockID.Hash
|
prevHash := state.LastBlockID.Hash
|
||||||
prevParts := types.PartSetHeader{}
|
prevParts := types.PartSetHeader{}
|
||||||
valHash := state.Validators.Hash()
|
valHash := state.Validators.Hash()
|
||||||
prevBlockID := types.BlockID{prevHash, prevParts}
|
prevBlockID := types.BlockID{prevHash, prevParts}
|
||||||
block, _ := types.MakeBlock(blockNumber, "test_chain", makeTxs(blockNumber),
|
block, _ := types.MakeBlock(blockNumber, "test_chain", makeTxs(blockNumber),
|
||||||
new(types.Commit), prevBlockID, valHash, state.AppHash, testPartSize)
|
new(types.Commit), prevBlockID, valHash, state.AppHash, state.Params().BlockGossipParams.BlockPartSizeBytes)
|
||||||
return block
|
return block
|
||||||
}
|
}
|
||||||
|
|
||||||
// The Test peer
|
// The Test peer
|
||||||
type bcrTestPeer struct {
|
type bcrTestPeer struct {
|
||||||
|
cmn.Service
|
||||||
key string
|
key string
|
||||||
ch chan *keyValue
|
ch chan interface{}
|
||||||
kvm map[byte]interface{}
|
|
||||||
}
|
|
||||||
|
|
||||||
type keyValue struct {
|
|
||||||
key interface{}
|
|
||||||
value interface{}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ p2p.Peer = (*bcrTestPeer)(nil)
|
var _ p2p.Peer = (*bcrTestPeer)(nil)
|
||||||
|
|
||||||
func (tp *bcrTestPeer) Key() string { return tp.key }
|
func newbcrTestPeer(key string) *bcrTestPeer {
|
||||||
func (tp *bcrTestPeer) IsOutbound() bool { return false }
|
return &bcrTestPeer{
|
||||||
func (tp *bcrTestPeer) IsPersistent() bool { return true }
|
Service: cmn.NewBaseService(nil, "bcrTestPeer", nil),
|
||||||
func (tp *bcrTestPeer) IsRunning() bool { return true }
|
key: key,
|
||||||
|
ch: make(chan interface{}, 2),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (tp *bcrTestPeer) OnStop() {}
|
func (tp *bcrTestPeer) lastValue() interface{} { return <-tp.ch }
|
||||||
|
|
||||||
func (tp *bcrTestPeer) OnReset() error { return nil }
|
|
||||||
func (tp *bcrTestPeer) Reset() (bool, error) { return false, nil }
|
|
||||||
func (tp *bcrTestPeer) OnStart() error { return nil }
|
|
||||||
func (tp *bcrTestPeer) SetLogger(l log.Logger) {}
|
|
||||||
|
|
||||||
func (tp *bcrTestPeer) Start() (bool, error) { return true, nil }
|
|
||||||
func (tp *bcrTestPeer) Stop() bool { return true }
|
|
||||||
func (tp *bcrTestPeer) String() string { return tp.key }
|
|
||||||
|
|
||||||
func (tp *bcrTestPeer) TrySend(chID byte, value interface{}) bool {
|
func (tp *bcrTestPeer) TrySend(chID byte, value interface{}) bool {
|
||||||
if _, ok := value.(struct{ BlockchainMessage }).BlockchainMessage.(*bcStatusResponseMessage); ok {
|
if _, ok := value.(struct{ BlockchainMessage }).BlockchainMessage.(*bcStatusResponseMessage); ok {
|
||||||
|
@ -201,18 +143,16 @@ func (tp *bcrTestPeer) TrySend(chID byte, value interface{}) bool {
|
||||||
// + bcBlockResponseMessage
|
// + bcBlockResponseMessage
|
||||||
// + bcNoBlockResponseMessage
|
// + bcNoBlockResponseMessage
|
||||||
} else {
|
} else {
|
||||||
tp.ch <- &keyValue{key: chID, value: value}
|
tp.ch <- value
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tp *bcrTestPeer) Send(chID byte, data interface{}) bool {
|
func (tp *bcrTestPeer) Send(chID byte, data interface{}) bool { return tp.TrySend(chID, data) }
|
||||||
return tp.TrySend(chID, data)
|
func (tp *bcrTestPeer) NodeInfo() *p2p.NodeInfo { return nil }
|
||||||
}
|
func (tp *bcrTestPeer) Status() p2p.ConnectionStatus { return p2p.ConnectionStatus{} }
|
||||||
|
func (tp *bcrTestPeer) Key() string { return tp.key }
|
||||||
func (tp *bcrTestPeer) NodeInfo() *p2p.NodeInfo { return nil }
|
func (tp *bcrTestPeer) IsOutbound() bool { return false }
|
||||||
func (tp *bcrTestPeer) Status() p2p.ConnectionStatus { return p2p.ConnectionStatus{} }
|
func (tp *bcrTestPeer) IsPersistent() bool { return true }
|
||||||
|
func (tp *bcrTestPeer) Get(s string) interface{} { return s }
|
||||||
func (tp *bcrTestPeer) Get(s string) interface{} { return s }
|
func (tp *bcrTestPeer) Set(string, interface{}) {}
|
||||||
func (tp *bcrTestPeer) Set(string, interface{}) {}
|
|
||||||
func (tp *bcrTestPeer) lastKeyValue() *keyValue { return <-tp.ch }
|
|
||||||
|
|
Loading…
Reference in New Issue