Browse Source

add test for mempool deadlock

pull/290/head
Ethan Buchman 8 years ago
parent
commit
a07063f119
2 changed files with 68 additions and 13 deletions
  1. +62
    -6
      consensus/mempool_test.go
  2. +6
    -7
      mempool/mempool_test.go

+ 62
- 6
consensus/mempool_test.go View File

@ -2,7 +2,6 @@ package consensus
import (
"encoding/binary"
// "math/rand"
"testing"
"time"
@ -52,6 +51,67 @@ func TestTxConcurrentWithCommit(t *testing.T) {
}
}
func TestRmBadTx(t *testing.T) {
state, privVals := randGenesisState(1, false, 10)
app := NewCounterApplication()
cs := newConsensusState(state, privVals[0], app)
// increment the counter by 1
txBytes := make([]byte, 8)
binary.BigEndian.PutUint64(txBytes, uint64(0))
app.AppendTx(txBytes)
app.Commit()
ch := make(chan struct{})
cbCh := make(chan struct{})
go func() {
// Try to send the tx through the mempool.
// CheckTx should not err, but the app should return a bad tmsp code
// and the tx should get removed from the pool
err := cs.mempool.CheckTx(txBytes, func(r *tmsp.Response) {
if r.GetCheckTx().Code != tmsp.CodeType_BadNonce {
t.Fatalf("expected checktx to return bad nonce, got %v", r)
}
cbCh <- struct{}{}
})
if err != nil {
t.Fatal("Error after CheckTx: %v", err)
}
// check for the tx
for {
time.Sleep(time.Second)
select {
case <-ch:
default:
txs := cs.mempool.Reap(1)
if len(txs) == 0 {
ch <- struct{}{}
}
}
}
}()
// Wait until the tx returns
ticker := time.After(time.Second * 5)
select {
case <-cbCh:
// success
case <-ticker:
t.Fatalf("Timed out waiting for tx to return")
}
// Wait until the tx is removed
ticker = time.After(time.Second * 5)
select {
case <-ch:
// success
case <-ticker:
t.Fatalf("Timed out waiting for tx to be removed")
}
}
// CounterApplication that maintains a mempool state and resets it upon commit
type CounterApplication struct {
txCount int
@ -84,11 +144,7 @@ func runTx(tx []byte, countPtr *int) tmsp.Result {
copy(tx8[len(tx8)-len(tx):], tx)
txValue := binary.BigEndian.Uint64(tx8)
if txValue != uint64(count) {
return tmsp.Result{
Code: tmsp.CodeType_BadNonce,
Data: nil,
Log: Fmt("Invalid nonce. Expected %v, got %v", count, txValue),
}
return tmsp.ErrBadNonce.AppendLog(Fmt("Invalid nonce. Expected %v, got %v", count, txValue))
}
*countPtr += 1
return tmsp.OK


+ 6
- 7
mempool/mempool_test.go View File

@ -2,12 +2,11 @@ package mempool
import (
"encoding/binary"
"sync"
"testing"
"github.com/tendermint/tendermint/config/tendermint_test"
"github.com/tendermint/tendermint/proxy"
"github.com/tendermint/tendermint/types"
tmspcli "github.com/tendermint/tmsp/client"
"github.com/tendermint/tmsp/example/counter"
)
@ -16,9 +15,9 @@ func TestSerialReap(t *testing.T) {
app := counter.NewCounterApplication(true)
app.SetOption("serial", "on")
mtx := new(sync.Mutex)
appConnMem := tmspcli.NewLocalClient(mtx, app)
appConnCon := tmspcli.NewLocalClient(mtx, app)
cc := proxy.NewLocalClientCreator(app)
appConnMem, _ := cc.NewTMSPClient()
appConnCon, _ := cc.NewTMSPClient()
mempool := NewMempool(config, appConnMem)
appendTxsRange := func(start, end int) {
@ -66,13 +65,13 @@ func TestSerialReap(t *testing.T) {
for i := start; i < end; i++ {
txBytes := make([]byte, 8)
binary.BigEndian.PutUint64(txBytes, uint64(i))
res := appConnCon.AppendTx(txBytes)
res := appConnCon.AppendTxSync(txBytes)
if !res.IsOK() {
t.Errorf("Error committing tx. Code:%v result:%X log:%v",
res.Code, res.Data, res.Log)
}
}
res := appConnCon.Commit()
res := appConnCon.CommitSync()
if len(res.Data) != 8 {
t.Errorf("Error committing. Hash:%X log:%v", res.Data, res.Log)
}


Loading…
Cancel
Save