Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Baseapp: Adding more tests #1075

Merged
merged 3 commits into from
Jun 5, 2018
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
158 changes: 128 additions & 30 deletions baseapp/baseapp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,18 +83,36 @@ func TestLoadVersion(t *testing.T) {
header := abci.Header{Height: 1}
app.BeginBlock(abci.RequestBeginBlock{Header: header})
res := app.Commit()
commitID := sdk.CommitID{1, res.Data}
commitID1 := sdk.CommitID{1, res.Data}
header = abci.Header{Height: 2}
app.BeginBlock(abci.RequestBeginBlock{Header: header})
res = app.Commit()
commitID2 := sdk.CommitID{2, res.Data}

// reload
// reload with LoadLatestVersion
app = NewBaseApp(name, nil, logger, db)
app.MountStoresIAVL(capKey)
err = app.LoadLatestVersion(capKey) // needed to make stores non-nil
err = app.LoadLatestVersion(capKey)
assert.Nil(t, err)
testLoadVersionHelper(t, app, int64(2), commitID2)

// reload with LoadVersion, see if you can commit the same block and get
// the same result
app = NewBaseApp(name, nil, logger, db)
app.MountStoresIAVL(capKey)
err = app.LoadVersion(1, capKey)
assert.Nil(t, err)
testLoadVersionHelper(t, app, int64(1), commitID1)
app.BeginBlock(abci.RequestBeginBlock{Header: header})
app.Commit()
testLoadVersionHelper(t, app, int64(2), commitID2)
}

lastHeight = app.LastBlockHeight()
lastID = app.LastCommitID()
assert.Equal(t, int64(1), lastHeight)
assert.Equal(t, commitID, lastID)
func testLoadVersionHelper(t *testing.T, app *BaseApp, expectedHeight int64, expectedID sdk.CommitID) {
lastHeight := app.LastBlockHeight()
lastID := app.LastCommitID()
assert.Equal(t, expectedHeight, lastHeight)
assert.Equal(t, expectedID, lastID)
}

// Test that the app hash is static
Expand Down Expand Up @@ -206,11 +224,91 @@ func TestInitChainer(t *testing.T) {
assert.Equal(t, value, res.Value)
}

func getStateCheckingHandler(t *testing.T, capKey *sdk.KVStoreKey, txPerHeight int, checkHeader bool) func(ctx sdk.Context, msg sdk.Msg) sdk.Result {
counter := 0
return func(ctx sdk.Context, msg sdk.Msg) sdk.Result {
store := ctx.KVStore(capKey)
// Checking state gets updated between checkTx's / DeliverTx's
// on the store within a block.
if counter > 0 {
// check previous value in store
counterBytes := []byte{byte(counter - 1)}
prevBytes := store.Get(counterBytes)
assert.Equal(t, counterBytes, prevBytes)
}

// set the current counter in the store
counterBytes := []byte{byte(counter)}
store.Set(counterBytes, counterBytes)

// check that we can see the current header
// wrapped in an if, so it can be reused between CheckTx and DeliverTx tests.
if checkHeader {
thisHeader := ctx.BlockHeader()
height := int64((counter / txPerHeight) + 1)
assert.Equal(t, height, thisHeader.Height)
}

counter++
return sdk.Result{}
}
}

// A mock transaction that has a validation which can fail.
type testTx struct {
positiveNum int64
}

const msgType2 = "testTx"

func (tx testTx) Type() string { return msgType2 }
func (tx testTx) GetMsg() sdk.Msg { return tx }
func (tx testTx) GetSignBytes() []byte { return nil }
func (tx testTx) GetSigners() []sdk.Address { return nil }
func (tx testTx) GetSignatures() []auth.StdSignature { return nil }
func (tx testTx) ValidateBasic() sdk.Error {
if tx.positiveNum >= 0 {
return nil
}
return sdk.ErrTxDecode("positiveNum should be a non-negative integer.")
}

// Test that successive CheckTx can see each others' effects
// on the store within a block, and that the CheckTx state
// gets reset to the latest Committed state during Commit
func TestCheckTx(t *testing.T) {
// TODO
// Initialize an app for testing
app := newBaseApp(t.Name())
// make a cap key and mount the store
capKey := sdk.NewKVStoreKey("main")
app.MountStoresIAVL(capKey)
err := app.LoadLatestVersion(capKey) // needed to make stores non-nil
assert.Nil(t, err)
app.SetAnteHandler(func(ctx sdk.Context, tx sdk.Tx) (newCtx sdk.Context, res sdk.Result, abort bool) { return })

txPerHeight := 3
app.Router().AddRoute(msgType, getStateCheckingHandler(t, capKey, txPerHeight, false)).
AddRoute(msgType2, func(ctx sdk.Context, msg sdk.Msg) (res sdk.Result) { return })
tx := testUpdatePowerTx{} // doesn't matter
for i := 0; i < txPerHeight; i++ {
app.Check(tx)
}
// If it gets to this point, then successive CheckTx's can see the effects of
// other CheckTx's on the block. The following checks that if another block
// is committed, the CheckTx State will reset.
app.BeginBlock(abci.RequestBeginBlock{})
tx2 := testTx{}
for i := 0; i < txPerHeight; i++ {
app.Deliver(tx2)
}
app.EndBlock(abci.RequestEndBlock{})
app.Commit()

checkStateStore := app.checkState.ctx.KVStore(capKey)
for i := 0; i < txPerHeight; i++ {
storedValue := checkStateStore.Get([]byte{byte(i)})
assert.Nil(t, storedValue)
}
}

// Test that successive DeliverTx can see each others' effects
Expand All @@ -224,30 +322,9 @@ func TestDeliverTx(t *testing.T) {
err := app.LoadLatestVersion(capKey) // needed to make stores non-nil
assert.Nil(t, err)

counter := 0
txPerHeight := 2
app.SetAnteHandler(func(ctx sdk.Context, tx sdk.Tx) (newCtx sdk.Context, res sdk.Result, abort bool) { return })
app.Router().AddRoute(msgType, func(ctx sdk.Context, msg sdk.Msg) sdk.Result {
store := ctx.KVStore(capKey)
if counter > 0 {
// check previous value in store
counterBytes := []byte{byte(counter - 1)}
prevBytes := store.Get(counterBytes)
assert.Equal(t, prevBytes, counterBytes)
}

// set the current counter in the store
counterBytes := []byte{byte(counter)}
store.Set(counterBytes, counterBytes)

// check we can see the current header
thisHeader := ctx.BlockHeader()
height := int64((counter / txPerHeight) + 1)
assert.Equal(t, height, thisHeader.Height)

counter++
return sdk.Result{}
})
app.Router().AddRoute(msgType, getStateCheckingHandler(t, capKey, txPerHeight, true))

tx := testUpdatePowerTx{} // doesn't matter
header := abci.Header{AppHash: []byte("apphash")}
Expand Down Expand Up @@ -325,6 +402,27 @@ func TestSimulateTx(t *testing.T) {
}
}

func TestRunInvalidTransaction(t *testing.T) {
// Initialize an app for testing
app := newBaseApp(t.Name())
// make a cap key and mount the store
capKey := sdk.NewKVStoreKey("main")
app.MountStoresIAVL(capKey)
err := app.LoadLatestVersion(capKey) // needed to make stores non-nil
assert.Nil(t, err)
app.SetAnteHandler(func(ctx sdk.Context, tx sdk.Tx) (newCtx sdk.Context, res sdk.Result, abort bool) { return })
app.Router().AddRoute(msgType2, func(ctx sdk.Context, msg sdk.Msg) (res sdk.Result) { return })
app.BeginBlock(abci.RequestBeginBlock{})
// Transaction where validate fails
invalidTx := testTx{-1}
err1 := app.Deliver(invalidTx)
assert.Equal(t, sdk.ToABCICode(sdk.CodespaceRoot, sdk.CodeTxDecode), err1.Code)
// Transaction with no known route
unknownRouteTx := testUpdatePowerTx{}
err2 := app.Deliver(unknownRouteTx)
assert.Equal(t, sdk.ToABCICode(sdk.CodespaceRoot, sdk.CodeUnknownRequest), err2.Code)
}

// Test that transactions exceeding gas limits fail
func TestTxGasLimits(t *testing.T) {
logger := defaultLogger()
Expand Down