consensus: test reactor
This commit is contained in:
parent
fd128c7180
commit
f837252ff1
|
@ -6,7 +6,7 @@ import (
|
||||||
|
|
||||||
// NOTE: this is blocking
|
// NOTE: this is blocking
|
||||||
func subscribeToEvent(evsw types.EventSwitch, receiver, eventID string, chanCap int) chan interface{} {
|
func subscribeToEvent(evsw types.EventSwitch, receiver, eventID string, chanCap int) chan interface{} {
|
||||||
// listen for new round
|
// listen for event
|
||||||
ch := make(chan interface{}, chanCap)
|
ch := make(chan interface{}, chanCap)
|
||||||
types.AddListenerForEvent(evsw, receiver, eventID, func(data types.TMEventData) {
|
types.AddListenerForEvent(evsw, receiver, eventID, func(data types.TMEventData) {
|
||||||
ch <- data
|
ch <- data
|
||||||
|
|
|
@ -246,6 +246,18 @@ func randConsensusState(nValidators int) (*ConsensusState, []*validatorStub) {
|
||||||
return cs, vss
|
return cs, vss
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func randConsensusNet(nValidators int) []*ConsensusState {
|
||||||
|
genDoc, privVals := randGenesisDoc(nValidators, false, 10)
|
||||||
|
css := make([]*ConsensusState, nValidators)
|
||||||
|
for i := 0; i < nValidators; i++ {
|
||||||
|
db := dbm.NewMemDB() // each state needs its own db
|
||||||
|
state := sm.MakeGenesisState(db, genDoc)
|
||||||
|
state.Save()
|
||||||
|
css[i] = newConsensusState(state, privVals[i], counter.NewCounterApplication(true))
|
||||||
|
}
|
||||||
|
return css
|
||||||
|
}
|
||||||
|
|
||||||
func subscribeToVoter(cs *ConsensusState, addr []byte) chan interface{} {
|
func subscribeToVoter(cs *ConsensusState, addr []byte) chan interface{} {
|
||||||
voteCh0 := subscribeToEvent(cs.evsw, "tester", types.EventStringVote(), 1)
|
voteCh0 := subscribeToEvent(cs.evsw, "tester", types.EventStringVote(), 1)
|
||||||
voteCh := make(chan interface{})
|
voteCh := make(chan interface{})
|
||||||
|
@ -274,8 +286,8 @@ func readVotes(ch chan interface{}, reads int) chan struct{} {
|
||||||
}
|
}
|
||||||
|
|
||||||
func randGenesisState(numValidators int, randPower bool, minPower int64) (*sm.State, []*types.PrivValidator) {
|
func randGenesisState(numValidators int, randPower bool, minPower int64) (*sm.State, []*types.PrivValidator) {
|
||||||
db := dbm.NewMemDB()
|
|
||||||
genDoc, privValidators := randGenesisDoc(numValidators, randPower, minPower)
|
genDoc, privValidators := randGenesisDoc(numValidators, randPower, minPower)
|
||||||
|
db := dbm.NewMemDB()
|
||||||
s0 := sm.MakeGenesisState(db, genDoc)
|
s0 := sm.MakeGenesisState(db, genDoc)
|
||||||
s0.Save()
|
s0.Save()
|
||||||
return s0, privValidators
|
return s0, privValidators
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
package consensus
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"sync"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/tendermint/tendermint/config/tendermint_test"
|
||||||
|
|
||||||
|
. "github.com/tendermint/go-common"
|
||||||
|
dbm "github.com/tendermint/go-db"
|
||||||
|
"github.com/tendermint/go-events"
|
||||||
|
"github.com/tendermint/go-p2p"
|
||||||
|
bc "github.com/tendermint/tendermint/blockchain"
|
||||||
|
"github.com/tendermint/tendermint/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
config = tendermint_test.ResetConfig("consensus_reactor_test")
|
||||||
|
}
|
||||||
|
|
||||||
|
func resetConfigTimeouts() {
|
||||||
|
config.Set("log_level", "notice")
|
||||||
|
config.Set("timeout_propose", 2000)
|
||||||
|
// config.Set("timeout_propose_delta", 500)
|
||||||
|
// config.Set("timeout_prevote", 1000)
|
||||||
|
// config.Set("timeout_prevote_delta", 500)
|
||||||
|
// config.Set("timeout_precommit", 1000)
|
||||||
|
// config.Set("timeout_precommit_delta", 500)
|
||||||
|
// config.Set("timeout_commit", 1000)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestReactor(t *testing.T) {
|
||||||
|
resetConfigTimeouts()
|
||||||
|
N := 4
|
||||||
|
css := randConsensusNet(N)
|
||||||
|
reactors := make([]*ConsensusReactor, N)
|
||||||
|
eventChans := make([]chan interface{}, N)
|
||||||
|
for i := 0; i < N; i++ {
|
||||||
|
blockStoreDB := dbm.NewDB(Fmt("blockstore%d", i), config.GetString("db_backend"), config.GetString("db_dir"))
|
||||||
|
blockStore := bc.NewBlockStore(blockStoreDB)
|
||||||
|
reactors[i] = NewConsensusReactor(css[i], blockStore, false)
|
||||||
|
reactors[i].SetPrivValidator(css[i].privValidator)
|
||||||
|
|
||||||
|
eventSwitch := events.NewEventSwitch()
|
||||||
|
_, err := eventSwitch.Start()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Failed to start switch: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
reactors[i].SetEventSwitch(eventSwitch)
|
||||||
|
eventChans[i] = subscribeToEvent(eventSwitch, "tester", types.EventStringNewBlock(), 1)
|
||||||
|
}
|
||||||
|
p2p.MakeConnectedSwitches(N, func(i int, s *p2p.Switch) *p2p.Switch {
|
||||||
|
s.AddReactor("CONSENSUS", reactors[i])
|
||||||
|
return s
|
||||||
|
}, net.Pipe)
|
||||||
|
|
||||||
|
// wait till everyone makes the first new block
|
||||||
|
wg := new(sync.WaitGroup)
|
||||||
|
wg.Add(N)
|
||||||
|
for i := 0; i < N; i++ {
|
||||||
|
go func(j int) {
|
||||||
|
<-eventChans[j]
|
||||||
|
wg.Done()
|
||||||
|
}(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
done := make(chan struct{})
|
||||||
|
go func() {
|
||||||
|
wg.Wait()
|
||||||
|
close(done)
|
||||||
|
}()
|
||||||
|
|
||||||
|
tick := time.NewTicker(time.Second * 3)
|
||||||
|
select {
|
||||||
|
case <-done:
|
||||||
|
case <-tick.C:
|
||||||
|
t.Fatalf("Timed out waiting for all validators to commit first block")
|
||||||
|
}
|
||||||
|
}
|
|
@ -30,7 +30,7 @@ x * TestBadProposal - 2 vals, bad proposal (bad block state hash), should prevot
|
||||||
FullRoundSuite
|
FullRoundSuite
|
||||||
x * TestFullRound1 - 1 val, full successful round
|
x * TestFullRound1 - 1 val, full successful round
|
||||||
x * TestFullRoundNil - 1 val, full round of nil
|
x * TestFullRoundNil - 1 val, full round of nil
|
||||||
x * TestFullRound2 - 2 vals, both required for fuill round
|
x * TestFullRound2 - 2 vals, both required for full round
|
||||||
LockSuite
|
LockSuite
|
||||||
x * TestLockNoPOL - 2 vals, 4 rounds. one val locked, precommits nil every round except first.
|
x * TestLockNoPOL - 2 vals, 4 rounds. one val locked, precommits nil every round except first.
|
||||||
x * TestLockPOLRelock - 4 vals, one precommits, other 3 polka at next round, so we unlock and precomit the polka
|
x * TestLockPOLRelock - 4 vals, one precommits, other 3 polka at next round, so we unlock and precomit the polka
|
||||||
|
|
Loading…
Reference in New Issue