mock application framework compiling
This commit is contained in:
parent
3c17fa285c
commit
f58b454985
|
@ -0,0 +1,85 @@
|
||||||
|
package mock
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
abci "github.com/tendermint/abci/types"
|
||||||
|
dbm "github.com/tendermint/tmlibs/db"
|
||||||
|
"github.com/tendermint/tmlibs/log"
|
||||||
|
|
||||||
|
bam "github.com/cosmos/cosmos-sdk/baseapp"
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
"github.com/cosmos/cosmos-sdk/wire"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Extended ABCI application
|
||||||
|
type App struct {
|
||||||
|
*bam.BaseApp
|
||||||
|
Cdc *wire.Codec // public since the codec is passed into the module anyways.
|
||||||
|
KeyMain *sdk.KVStoreKey
|
||||||
|
KeyAccount *sdk.KVStoreKey
|
||||||
|
|
||||||
|
// TODO: Abstract this out from not needing to be auth specifically
|
||||||
|
AccountMapper auth.AccountMapper
|
||||||
|
FeeCollectionKeeper auth.FeeCollectionKeeper
|
||||||
|
|
||||||
|
GenesisAccounts []auth.Account
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewApp is used for testing the server. For the internal mock app stuff, it uses code in helpers.go
|
||||||
|
func NewApp() *App {
|
||||||
|
logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "sdk/app")
|
||||||
|
db := dbm.NewMemDB()
|
||||||
|
|
||||||
|
// create the cdc with some standard codecs
|
||||||
|
cdc := wire.NewCodec()
|
||||||
|
sdk.RegisterWire(cdc)
|
||||||
|
wire.RegisterCrypto(cdc)
|
||||||
|
|
||||||
|
// create your application object
|
||||||
|
app := &App{
|
||||||
|
BaseApp: bam.NewBaseApp("mock", cdc, logger, db),
|
||||||
|
Cdc: cdc,
|
||||||
|
KeyMain: sdk.NewKVStoreKey("main"),
|
||||||
|
KeyAccount: sdk.NewKVStoreKey("acc"),
|
||||||
|
}
|
||||||
|
|
||||||
|
// define the accountMapper
|
||||||
|
app.AccountMapper = auth.NewAccountMapper(
|
||||||
|
app.Cdc,
|
||||||
|
app.KeyAccount, // target store
|
||||||
|
&auth.BaseAccount{}, // prototype
|
||||||
|
)
|
||||||
|
|
||||||
|
// initialize the app, the chainers and blockers can be overwritten before calling complete setup
|
||||||
|
app.SetInitChainer(app.initChainer)
|
||||||
|
|
||||||
|
app.SetAnteHandler(auth.NewAnteHandler(app.AccountMapper, app.FeeCollectionKeeper))
|
||||||
|
|
||||||
|
return app
|
||||||
|
}
|
||||||
|
|
||||||
|
// complete the application setup after the routes have been registered
|
||||||
|
func (app App) CompleteSetup(t *testing.T, newKeys []*sdk.KVStoreKey) {
|
||||||
|
|
||||||
|
newKeys = append(newKeys, app.KeyMain)
|
||||||
|
newKeys = append(newKeys, app.KeyAccount)
|
||||||
|
app.MountStoresIAVL(newKeys...)
|
||||||
|
err := app.LoadLatestVersion(app.KeyMain)
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// custom logic for initialization
|
||||||
|
func (app App) initChainer(ctx sdk.Context, _ abci.RequestInitChain) abci.ResponseInitChain {
|
||||||
|
|
||||||
|
// load the accounts
|
||||||
|
for _, acc := range app.GenesisAccounts {
|
||||||
|
app.AccountMapper.SetAccount(ctx, acc)
|
||||||
|
}
|
||||||
|
|
||||||
|
return abci.ResponseInitChain{}
|
||||||
|
}
|
|
@ -0,0 +1,100 @@
|
||||||
|
package mock
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
crypto "github.com/tendermint/go-crypto"
|
||||||
|
|
||||||
|
abci "github.com/tendermint/abci/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
var chainID = "" // TODO
|
||||||
|
|
||||||
|
// set the mock app genesis
|
||||||
|
func SetGenesis(app *App, accs []auth.Account) {
|
||||||
|
|
||||||
|
// pass the accounts in via the application (lazy) instead of through RequestInitChain
|
||||||
|
app.GenesisAccounts = accs
|
||||||
|
|
||||||
|
app.InitChain(abci.RequestInitChain{})
|
||||||
|
app.Commit()
|
||||||
|
}
|
||||||
|
|
||||||
|
// check an account balance
|
||||||
|
func CheckBalance(t *testing.T, app *App, addr sdk.Address, exp sdk.Coins) {
|
||||||
|
ctxDeliver := app.BaseApp.NewContext(false, abci.Header{})
|
||||||
|
res := app.AccountMapper.GetAccount(ctxDeliver, addr)
|
||||||
|
assert.Equal(t, exp, res.GetCoins())
|
||||||
|
}
|
||||||
|
|
||||||
|
// generate a signed transaction
|
||||||
|
func GenTx(msg sdk.Msg, seq []int64, priv ...crypto.PrivKeyEd25519) auth.StdTx {
|
||||||
|
|
||||||
|
// make the transaction free
|
||||||
|
fee := auth.StdFee{
|
||||||
|
sdk.Coins{{"foocoin", 0}},
|
||||||
|
100000,
|
||||||
|
}
|
||||||
|
|
||||||
|
sigs := make([]auth.StdSignature, len(priv))
|
||||||
|
for i, p := range priv {
|
||||||
|
sigs[i] = auth.StdSignature{
|
||||||
|
PubKey: p.PubKey(),
|
||||||
|
Signature: p.Sign(auth.StdSignBytes(chainID, seq, fee, msg)),
|
||||||
|
Sequence: seq[i],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return auth.NewStdTx(msg, fee, sigs)
|
||||||
|
}
|
||||||
|
|
||||||
|
// simulate a block
|
||||||
|
func SignCheckDeliver(t *testing.T, app *App, msg sdk.Msg, seq []int64, expPass bool, priv ...crypto.PrivKeyEd25519) {
|
||||||
|
|
||||||
|
// Sign the tx
|
||||||
|
tx := GenTx(msg, seq, priv...)
|
||||||
|
|
||||||
|
// Run a Check
|
||||||
|
res := app.Check(tx)
|
||||||
|
if expPass {
|
||||||
|
require.Equal(t, sdk.ABCICodeOK, res.Code, res.Log)
|
||||||
|
} else {
|
||||||
|
require.NotEqual(t, sdk.ABCICodeOK, res.Code, res.Log)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Simulate a Block
|
||||||
|
app.BeginBlock(abci.RequestBeginBlock{})
|
||||||
|
res = app.Deliver(tx)
|
||||||
|
if expPass {
|
||||||
|
require.Equal(t, sdk.ABCICodeOK, res.Code, res.Log)
|
||||||
|
} else {
|
||||||
|
require.NotEqual(t, sdk.ABCICodeOK, res.Code, res.Log)
|
||||||
|
}
|
||||||
|
app.EndBlock(abci.RequestEndBlock{})
|
||||||
|
|
||||||
|
// XXX fix code or add explaination as to why using commit breaks a bunch of these tests
|
||||||
|
//app.Commit()
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX the only reason we are using Sign Deliver here is because the tests
|
||||||
|
// break on check tx the second time you use SignCheckDeliver in a test because
|
||||||
|
// the checktx state has not been updated likely because commit is not being
|
||||||
|
// called!
|
||||||
|
func SignDeliver(t *testing.T, app App, msg sdk.Msg, seq []int64, expPass bool, priv ...crypto.PrivKeyEd25519) {
|
||||||
|
|
||||||
|
// Sign the tx
|
||||||
|
tx := GenTx(msg, seq, priv...)
|
||||||
|
|
||||||
|
// Simulate a Block
|
||||||
|
app.BeginBlock(abci.RequestBeginBlock{})
|
||||||
|
res := app.Deliver(tx)
|
||||||
|
if expPass {
|
||||||
|
require.Equal(t, sdk.ABCICodeOK, res.Code, res.Log)
|
||||||
|
} else {
|
||||||
|
require.NotEqual(t, sdk.ABCICodeOK, res.Code, res.Log)
|
||||||
|
}
|
||||||
|
app.EndBlock(abci.RequestEndBlock{})
|
||||||
|
}
|
|
@ -0,0 +1,96 @@
|
||||||
|
package bank
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/tests/mock"
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||||
|
|
||||||
|
abci "github.com/tendermint/abci/types"
|
||||||
|
crypto "github.com/tendermint/go-crypto"
|
||||||
|
)
|
||||||
|
|
||||||
|
// test bank module in a mock application
|
||||||
|
var (
|
||||||
|
chainID = "" // TODO
|
||||||
|
|
||||||
|
accName = "foobart"
|
||||||
|
|
||||||
|
priv1 = crypto.GenPrivKeyEd25519()
|
||||||
|
addr1 = priv1.PubKey().Address()
|
||||||
|
priv2 = crypto.GenPrivKeyEd25519()
|
||||||
|
addr2 = priv2.PubKey().Address()
|
||||||
|
addr3 = crypto.GenPrivKeyEd25519().PubKey().Address()
|
||||||
|
priv4 = crypto.GenPrivKeyEd25519()
|
||||||
|
addr4 = priv4.PubKey().Address()
|
||||||
|
coins = sdk.Coins{{"foocoin", 10}}
|
||||||
|
halfCoins = sdk.Coins{{"foocoin", 5}}
|
||||||
|
manyCoins = sdk.Coins{{"foocoin", 1}, {"barcoin", 1}}
|
||||||
|
fee = auth.StdFee{
|
||||||
|
sdk.Coins{{"foocoin", 0}},
|
||||||
|
100000,
|
||||||
|
}
|
||||||
|
|
||||||
|
sendMsg1 = MsgSend{
|
||||||
|
Inputs: []Input{NewInput(addr1, coins)},
|
||||||
|
Outputs: []Output{NewOutput(addr2, coins)},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestMsgSendWithAccounts(t *testing.T) {
|
||||||
|
|
||||||
|
// initialize the mock application
|
||||||
|
mapp := mock.NewApp()
|
||||||
|
|
||||||
|
RegisterWire(mapp.Cdc)
|
||||||
|
coinKeeper := NewKeeper(mapp.AccountMapper)
|
||||||
|
mapp.Router().AddRoute("bank", NewHandler(coinKeeper))
|
||||||
|
|
||||||
|
mapp.CompleteSetup(t, []*sdk.KVStoreKey{})
|
||||||
|
|
||||||
|
// Add an account at genesis
|
||||||
|
coins, err := sdk.ParseCoins("77foocoin")
|
||||||
|
require.Nil(t, err)
|
||||||
|
//acc := auth.NewAccountWithAddress(addr1)
|
||||||
|
//acc.SetCoins(coins)
|
||||||
|
//accs := []auth.Account{acc}
|
||||||
|
|
||||||
|
baseAcc := &auth.BaseAccount{
|
||||||
|
Address: addr1,
|
||||||
|
Coins: coins,
|
||||||
|
}
|
||||||
|
baseAccs := []auth.Account{baseAcc}
|
||||||
|
|
||||||
|
// Construct genesis state
|
||||||
|
mock.SetGenesis(mapp, baseAccs)
|
||||||
|
|
||||||
|
// A checkTx context (true)
|
||||||
|
ctxCheck := mapp.BaseApp.NewContext(true, abci.Header{})
|
||||||
|
res1 := mapp.AccountMapper.GetAccount(ctxCheck, addr1)
|
||||||
|
require.NotNil(t, res1)
|
||||||
|
assert.Equal(t, baseAcc, res1.(*auth.BaseAccount))
|
||||||
|
|
||||||
|
// Run a CheckDeliver
|
||||||
|
mock.SignCheckDeliver(t, mapp, sendMsg1, []int64{0}, true, priv1)
|
||||||
|
|
||||||
|
// Check balances
|
||||||
|
mock.CheckBalance(t, mapp, addr1, sdk.Coins{{"foocoin", 67}})
|
||||||
|
mock.CheckBalance(t, mapp, addr2, sdk.Coins{{"foocoin", 10}})
|
||||||
|
|
||||||
|
// Delivering again should cause replay error
|
||||||
|
mock.SignCheckDeliver(t, mapp, sendMsg1, []int64{0}, false, priv1)
|
||||||
|
|
||||||
|
// bumping the txnonce number without resigning should be an auth error
|
||||||
|
tx := mock.GenTx(sendMsg1, []int64{0}, priv1)
|
||||||
|
tx.Signatures[0].Sequence = 1
|
||||||
|
res := mapp.Deliver(tx)
|
||||||
|
|
||||||
|
assert.Equal(t, sdk.ToABCICode(sdk.CodespaceRoot, sdk.CodeUnauthorized), res.Code, res.Log)
|
||||||
|
|
||||||
|
// resigning the tx with the bumped sequence should work
|
||||||
|
mock.SignCheckDeliver(t, mapp, sendMsg1, []int64{1}, true, priv1)
|
||||||
|
}
|
Loading…
Reference in New Issue