From abab7c2e42eb694147879b755faae8534274f94a Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Thu, 7 Jun 2018 20:55:14 -0700 Subject: [PATCH] modules test within mock application --- cmd/gaia/app/app_test.go | 212 +--------- examples/basecoin/app/app_test.go | 473 +---------------------- examples/democoin/app/app_test.go | 368 +----------------- examples/democoin/x/cool/app_test.go | 105 +++++ examples/democoin/x/pow/app_test.go | 83 ++++ {tests => x/auth}/mock/app.go | 4 +- x/auth/mock/auth_app_test.go | 111 ++++++ {tests => x/auth}/mock/simulate_block.go | 5 +- x/bank/app_test.go | 18 +- x/ibc/app_test.go | 22 +- x/stake/app_test.go | 152 ++++++++ 11 files changed, 497 insertions(+), 1056 deletions(-) create mode 100644 examples/democoin/x/cool/app_test.go create mode 100644 examples/democoin/x/pow/app_test.go rename {tests => x/auth}/mock/app.go (95%) create mode 100644 x/auth/mock/auth_app_test.go rename {tests => x/auth}/mock/simulate_block.go (89%) create mode 100644 x/stake/app_test.go diff --git a/cmd/gaia/app/app_test.go b/cmd/gaia/app/app_test.go index 1ec24d0179..0f6bab134b 100644 --- a/cmd/gaia/app/app_test.go +++ b/cmd/gaia/app/app_test.go @@ -1,17 +1,16 @@ package app import ( - "fmt" "os" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/cosmos/cosmos-sdk/x/auth/mock" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" "github.com/cosmos/cosmos-sdk/x/auth" - "github.com/cosmos/cosmos-sdk/x/bank" "github.com/cosmos/cosmos-sdk/x/stake" abci "github.com/tendermint/abci/types" @@ -20,31 +19,13 @@ import ( "github.com/tendermint/tmlibs/log" ) -// Construct some global addrs and txs for tests. 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 = bank.MsgSend{ - Inputs: []bank.Input{bank.NewInput(addr1, coins)}, - Outputs: []bank.Output{bank.NewOutput(addr2, coins)}, - } + priv1 = crypto.GenPrivKeyEd25519() + addr1 = priv1.PubKey().Address() + priv2 = crypto.GenPrivKeyEd25519() + addr2 = priv2.PubKey().Address() ) func loggerAndDB() (log.Logger, dbm.DB) { @@ -53,11 +34,6 @@ func loggerAndDB() (log.Logger, dbm.DB) { return logger, db } -func newGaiaApp() *GaiaApp { - logger, db := loggerAndDB() - return NewGaiaApp(logger, db) -} - func setGenesis(gapp *GaiaApp, accs ...*auth.BaseAccount) error { genaccs := make([]GenesisAccount, len(accs)) for i, acc := range accs { @@ -84,22 +60,6 @@ func setGenesis(gapp *GaiaApp, accs ...*auth.BaseAccount) error { //_______________________________________________________________________ -func TestMsgs(t *testing.T) { - gapp := newGaiaApp() - require.Nil(t, setGenesis(gapp)) - - msgs := []struct { - msg sdk.Msg - }{ - {sendMsg1}, - } - - for i, m := range msgs { - // Run a CheckDeliver - SignCheckDeliver(t, gapp, m.msg, []int64{int64(i)}, false, priv1) - } -} - func TestGenesis(t *testing.T) { logger, dbs := loggerAndDB() gapp := NewGaiaApp(logger, dbs) @@ -129,96 +89,9 @@ func TestGenesis(t *testing.T) { assert.Equal(t, baseAcc, res1) } -func TestStakeMsgs(t *testing.T) { - gapp := newGaiaApp() - - genCoins, err := sdk.ParseCoins("42steak") - require.Nil(t, err) - bondCoin, err := sdk.ParseCoin("10steak") - require.Nil(t, err) - - acc1 := &auth.BaseAccount{ - Address: addr1, - Coins: genCoins, - } - acc2 := &auth.BaseAccount{ - Address: addr2, - Coins: genCoins, - } - - err = setGenesis(gapp, acc1, acc2) - require.Nil(t, err) - - // A checkTx context (true) - ctxCheck := gapp.BaseApp.NewContext(true, abci.Header{}) - res1 := gapp.accountMapper.GetAccount(ctxCheck, addr1) - res2 := gapp.accountMapper.GetAccount(ctxCheck, addr2) - require.Equal(t, acc1, res1) - require.Equal(t, acc2, res2) - - // Create Validator - - description := stake.NewDescription("foo_moniker", "", "", "") - createValidatorMsg := stake.NewMsgCreateValidator( - addr1, priv1.PubKey(), bondCoin, description, - ) - SignCheckDeliver(t, gapp, createValidatorMsg, []int64{0}, true, priv1) - - ctxDeliver := gapp.BaseApp.NewContext(false, abci.Header{}) - res1 = gapp.accountMapper.GetAccount(ctxDeliver, addr1) - require.Equal(t, genCoins.Minus(sdk.Coins{bondCoin}), res1.GetCoins()) - validator, found := gapp.stakeKeeper.GetValidator(ctxDeliver, addr1) - require.True(t, found) - require.Equal(t, addr1, validator.Owner) - require.Equal(t, sdk.Bonded, validator.Status()) - require.True(sdk.RatEq(t, sdk.NewRat(10), validator.PoolShares.Bonded())) - - // check the bond that should have been created as well - bond, found := gapp.stakeKeeper.GetDelegation(ctxDeliver, addr1, addr1) - require.True(sdk.RatEq(t, sdk.NewRat(10), bond.Shares)) - - // Edit Validator - - description = stake.NewDescription("bar_moniker", "", "", "") - editValidatorMsg := stake.NewMsgEditValidator( - addr1, description, - ) - SignDeliver(t, gapp, editValidatorMsg, []int64{1}, true, priv1) - - validator, found = gapp.stakeKeeper.GetValidator(ctxDeliver, addr1) - require.True(t, found) - require.Equal(t, description, validator.Description) - - // Delegate - - delegateMsg := stake.NewMsgDelegate( - addr2, addr1, bondCoin, - ) - SignDeliver(t, gapp, delegateMsg, []int64{0}, true, priv2) - - res2 = gapp.accountMapper.GetAccount(ctxDeliver, addr2) - require.Equal(t, genCoins.Minus(sdk.Coins{bondCoin}), res2.GetCoins()) - bond, found = gapp.stakeKeeper.GetDelegation(ctxDeliver, addr2, addr1) - require.True(t, found) - require.Equal(t, addr2, bond.DelegatorAddr) - require.Equal(t, addr1, bond.ValidatorAddr) - require.True(sdk.RatEq(t, sdk.NewRat(10), bond.Shares)) - - // Unbond - - unbondMsg := stake.NewMsgUnbond( - addr2, addr1, "MAX", - ) - SignDeliver(t, gapp, unbondMsg, []int64{1}, true, priv2) - - res2 = gapp.accountMapper.GetAccount(ctxDeliver, addr2) - require.Equal(t, genCoins, res2.GetCoins()) - _, found = gapp.stakeKeeper.GetDelegation(ctxDeliver, addr2, addr1) - require.False(t, found) -} - func TestExportValidators(t *testing.T) { - gapp := newGaiaApp() + logger, dbs := loggerAndDB() + gapp := NewGaiaApp(logger, dbs) genCoins, err := sdk.ParseCoins("42steak") require.Nil(t, err) @@ -242,7 +115,7 @@ func TestExportValidators(t *testing.T) { createValidatorMsg := stake.NewMsgCreateValidator( addr1, priv1.PubKey(), bondCoin, description, ) - SignCheckDeliver(t, gapp, createValidatorMsg, []int64{0}, true, priv1) + mock.SignCheckDeliver(t, gapp.BaseApp, createValidatorMsg, []int64{0}, true, priv1) gapp.Commit() // Export validator set @@ -252,72 +125,3 @@ func TestExportValidators(t *testing.T) { require.Equal(t, priv1.PubKey(), validators[0].PubKey) require.Equal(t, int64(10), validators[0].Power) } - -//____________________________________________________________________________________ - -func CheckBalance(t *testing.T, gapp *GaiaApp, addr sdk.Address, balExpected string) { - ctxDeliver := gapp.BaseApp.NewContext(false, abci.Header{}) - res2 := gapp.accountMapper.GetAccount(ctxDeliver, addr) - assert.Equal(t, balExpected, fmt.Sprintf("%v", res2.GetCoins())) -} - -func genTx(msg sdk.Msg, seq []int64, priv ...crypto.PrivKeyEd25519) auth.StdTx { - 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) - -} - -func SignCheckDeliver(t *testing.T, gapp *GaiaApp, msg sdk.Msg, seq []int64, expPass bool, priv ...crypto.PrivKeyEd25519) { - - // Sign the tx - tx := genTx(msg, seq, priv...) - - // Run a Check - res := gapp.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 - gapp.BeginBlock(abci.RequestBeginBlock{}) - res = gapp.Deliver(tx) - if expPass { - require.Equal(t, sdk.ABCICodeOK, res.Code, res.Log) - } else { - require.NotEqual(t, sdk.ABCICodeOK, res.Code, res.Log) - } - gapp.EndBlock(abci.RequestEndBlock{}) - - // XXX fix code or add explaination as to why using commit breaks a bunch of these tests - //gapp.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, gapp *GaiaApp, msg sdk.Msg, seq []int64, expPass bool, priv ...crypto.PrivKeyEd25519) { - - // Sign the tx - tx := genTx(msg, seq, priv...) - - // Simulate a Block - gapp.BeginBlock(abci.RequestBeginBlock{}) - res := gapp.Deliver(tx) - if expPass { - require.Equal(t, sdk.ABCICodeOK, res.Code, res.Log) - } else { - require.NotEqual(t, sdk.ABCICodeOK, res.Code, res.Log) - } - gapp.EndBlock(abci.RequestEndBlock{}) -} diff --git a/examples/basecoin/app/app_test.go b/examples/basecoin/app/app_test.go index 3027a84707..a1f7d53702 100644 --- a/examples/basecoin/app/app_test.go +++ b/examples/basecoin/app/app_test.go @@ -1,26 +1,23 @@ package app import ( - "encoding/json" - "fmt" "os" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/cosmos/cosmos-sdk/examples/basecoin/types" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/wire" - "github.com/cosmos/cosmos-sdk/x/auth" - "github.com/cosmos/cosmos-sdk/x/bank" - "github.com/cosmos/cosmos-sdk/x/ibc" - "github.com/cosmos/cosmos-sdk/x/stake" - abci "github.com/tendermint/abci/types" crypto "github.com/tendermint/go-crypto" dbm "github.com/tendermint/tmlibs/db" "github.com/tendermint/tmlibs/log" + + "github.com/cosmos/cosmos-sdk/examples/basecoin/types" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/wire" + "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/stake" ) // Construct some global addrs and txs for tests. @@ -28,66 +25,9 @@ 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 = bank.MsgSend{ - Inputs: []bank.Input{bank.NewInput(addr1, coins)}, - Outputs: []bank.Output{bank.NewOutput(addr2, coins)}, - } - - sendMsg2 = bank.MsgSend{ - Inputs: []bank.Input{bank.NewInput(addr1, coins)}, - Outputs: []bank.Output{ - bank.NewOutput(addr2, halfCoins), - bank.NewOutput(addr3, halfCoins), - }, - } - - sendMsg3 = bank.MsgSend{ - Inputs: []bank.Input{ - bank.NewInput(addr1, coins), - bank.NewInput(addr4, coins), - }, - Outputs: []bank.Output{ - bank.NewOutput(addr2, coins), - bank.NewOutput(addr3, coins), - }, - } - - sendMsg4 = bank.MsgSend{ - Inputs: []bank.Input{ - bank.NewInput(addr2, coins), - }, - Outputs: []bank.Output{ - bank.NewOutput(addr1, coins), - }, - } - - sendMsg5 = bank.MsgSend{ - Inputs: []bank.Input{ - bank.NewInput(addr1, manyCoins), - }, - Outputs: []bank.Output{ - bank.NewOutput(addr2, manyCoins), - }, - } ) -func setGenesis(bapp *BasecoinApp, accs ...auth.BaseAccount) error { +func setGenesis(t *testing.T, bapp *BasecoinApp, accs ...auth.BaseAccount) error { genaccs := make([]*types.GenesisAccount, len(accs)) for i, acc := range accs { genaccs[i] = types.NewGenesisAccount(&types.AppAccount{acc, accName}) @@ -99,9 +39,7 @@ func setGenesis(bapp *BasecoinApp, accs ...auth.BaseAccount) error { } stateBytes, err := wire.MarshalJSONIndent(bapp.cdc, genesisState) - if err != nil { - return err - } + require.NoError(t, err) // Initialize the chain vals := []abci.Validator{} @@ -111,94 +49,24 @@ func setGenesis(bapp *BasecoinApp, accs ...auth.BaseAccount) error { return nil } -func loggerAndDB() (log.Logger, dbm.DB) { - logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "sdk/app") - db := dbm.NewMemDB() - return logger, db -} - -func newBasecoinApp() *BasecoinApp { - logger, db := loggerAndDB() - return NewBasecoinApp(logger, db) -} - //_______________________________________________________________________ -func TestMsgs(t *testing.T) { - bapp := newBasecoinApp() - require.Nil(t, setGenesis(bapp)) - - msgs := []struct { - msg sdk.Msg - }{ - {sendMsg1}, - } - - for i, m := range msgs { - // Run a CheckDeliver - SignCheckDeliver(t, bapp, m.msg, []int64{int64(i)}, false, priv1) - } -} - -func TestSortGenesis(t *testing.T) { - logger, db := loggerAndDB() - bapp := NewBasecoinApp(logger, db) - - // Note the order: the coins are unsorted! - coinDenom1, coinDenom2 := "foocoin", "barcoin" - - genState := fmt.Sprintf(`{ - "accounts": [{ - "address": "%s", - "coins": [ - { - "denom": "%s", - "amount": 10 - }, - { - "denom": "%s", - "amount": 20 - } - ] - }] - }`, addr1.String(), coinDenom1, coinDenom2) - - // Initialize the chain - vals := []abci.Validator{} - bapp.InitChain(abci.RequestInitChain{Validators: vals, AppStateBytes: []byte(genState)}) - bapp.Commit() - - // Unsorted coins means invalid - err := sendMsg5.ValidateBasic() - require.Equal(t, sdk.CodeInvalidCoins, err.Code(), err.ABCILog()) - - // Sort coins, should be valid - sendMsg5.Inputs[0].Coins.Sort() - sendMsg5.Outputs[0].Coins.Sort() - err = sendMsg5.ValidateBasic() - require.Nil(t, err) - - // Ensure we can send - SignCheckDeliver(t, bapp, sendMsg5, []int64{0}, true, priv1) -} - func TestGenesis(t *testing.T) { - logger, db := loggerAndDB() + logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "sdk/app") + db := dbm.NewMemDB() bapp := NewBasecoinApp(logger, db) // Construct some genesis bytes to reflect basecoin/types/AppAccount pk := crypto.GenPrivKeyEd25519().PubKey() addr := pk.Address() - coins, err := sdk.ParseCoins("77foocoin,99barcoin") - require.Nil(t, err) + coins := sdk.Coins{{"foocoin", 77}, {"barcoin", 99}} baseAcc := auth.BaseAccount{ Address: addr, Coins: coins, } acc := &types.AppAccount{baseAcc, "foobart"} - err = setGenesis(bapp, baseAcc) - require.Nil(t, err) + setGenesis(t, bapp, baseAcc) // A checkTx context ctx := bapp.BaseApp.NewContext(true, abci.Header{}) @@ -211,318 +79,3 @@ func TestGenesis(t *testing.T) { res1 = bapp.accountMapper.GetAccount(ctx, baseAcc.Address) assert.Equal(t, acc, res1) } - -func TestMsgChangePubKey(t *testing.T) { - - bapp := newBasecoinApp() - - // Construct some genesis bytes to reflect basecoin/types/AppAccount - // Give 77 foocoin to the first key - coins, err := sdk.ParseCoins("77foocoin") - require.Nil(t, err) - baseAcc := auth.BaseAccount{ - Address: addr1, - Coins: coins, - } - - // Construct genesis state - err = setGenesis(bapp, baseAcc) - require.Nil(t, err) - - // A checkTx context (true) - ctxCheck := bapp.BaseApp.NewContext(true, abci.Header{}) - res1 := bapp.accountMapper.GetAccount(ctxCheck, addr1) - assert.Equal(t, baseAcc, res1.(*types.AppAccount).BaseAccount) - - // Run a CheckDeliver - SignCheckDeliver(t, bapp, sendMsg1, []int64{0}, true, priv1) - - // Check balances - CheckBalance(t, bapp, addr1, "67foocoin") - CheckBalance(t, bapp, addr2, "10foocoin") - - changePubKeyMsg := auth.MsgChangeKey{ - Address: addr1, - NewPubKey: priv2.PubKey(), - } - - ctxDeliver := bapp.BaseApp.NewContext(false, abci.Header{}) - acc := bapp.accountMapper.GetAccount(ctxDeliver, addr1) - - // send a MsgChangePubKey - SignCheckDeliver(t, bapp, changePubKeyMsg, []int64{1}, true, priv1) - acc = bapp.accountMapper.GetAccount(ctxDeliver, addr1) - - assert.True(t, priv2.PubKey().Equals(acc.GetPubKey())) - - // signing a SendMsg with the old privKey should be an auth error - tx := genTx(sendMsg1, []int64{2}, priv1) - res := bapp.Deliver(tx) - assert.Equal(t, sdk.ToABCICode(sdk.CodespaceRoot, sdk.CodeUnauthorized), res.Code, res.Log) - - // resigning the tx with the new correct priv key should work - SignCheckDeliver(t, bapp, sendMsg1, []int64{2}, true, priv2) - - // Check balances - CheckBalance(t, bapp, addr1, "57foocoin") - CheckBalance(t, bapp, addr2, "20foocoin") -} - -func TestMsgSendWithAccounts(t *testing.T) { - bapp := newBasecoinApp() - - // Construct some genesis bytes to reflect basecoin/types/AppAccount - // Give 77 foocoin to the first key - coins, err := sdk.ParseCoins("77foocoin") - require.Nil(t, err) - baseAcc := auth.BaseAccount{ - Address: addr1, - Coins: coins, - } - - // Construct genesis state - err = setGenesis(bapp, baseAcc) - require.Nil(t, err) - - // A checkTx context (true) - ctxCheck := bapp.BaseApp.NewContext(true, abci.Header{}) - res1 := bapp.accountMapper.GetAccount(ctxCheck, addr1) - assert.Equal(t, baseAcc, res1.(*types.AppAccount).BaseAccount) - - // Run a CheckDeliver - SignCheckDeliver(t, bapp, sendMsg1, []int64{0}, true, priv1) - - // Check balances - CheckBalance(t, bapp, addr1, "67foocoin") - CheckBalance(t, bapp, addr2, "10foocoin") - - // Delivering again should cause replay error - SignCheckDeliver(t, bapp, sendMsg1, []int64{0}, false, priv1) - - // bumping the txnonce number without resigning should be an auth error - tx := genTx(sendMsg1, []int64{0}, priv1) - tx.Signatures[0].Sequence = 1 - res := bapp.Deliver(tx) - - assert.Equal(t, sdk.ToABCICode(sdk.CodespaceRoot, sdk.CodeUnauthorized), res.Code, res.Log) - - // resigning the tx with the bumped sequence should work - SignCheckDeliver(t, bapp, sendMsg1, []int64{1}, true, priv1) -} - -func TestMsgSendMultipleOut(t *testing.T) { - bapp := newBasecoinApp() - - genCoins, err := sdk.ParseCoins("42foocoin") - require.Nil(t, err) - - acc1 := auth.BaseAccount{ - Address: addr1, - Coins: genCoins, - } - - acc2 := auth.BaseAccount{ - Address: addr2, - Coins: genCoins, - } - - // Construct genesis state - err = setGenesis(bapp, acc1, acc2) - require.Nil(t, err) - - // Simulate a Block - SignCheckDeliver(t, bapp, sendMsg2, []int64{0}, true, priv1) - - // Check balances - CheckBalance(t, bapp, addr1, "32foocoin") - CheckBalance(t, bapp, addr2, "47foocoin") - CheckBalance(t, bapp, addr3, "5foocoin") -} - -func TestSengMsgMultipleInOut(t *testing.T) { - bapp := newBasecoinApp() - - genCoins, err := sdk.ParseCoins("42foocoin") - require.Nil(t, err) - - acc1 := auth.BaseAccount{ - Address: addr1, - Coins: genCoins, - } - - acc2 := auth.BaseAccount{ - Address: addr2, - Coins: genCoins, - } - - acc4 := auth.BaseAccount{ - Address: addr4, - Coins: genCoins, - } - - err = setGenesis(bapp, acc1, acc2, acc4) - assert.Nil(t, err) - - // CheckDeliver - SignCheckDeliver(t, bapp, sendMsg3, []int64{0, 0}, true, priv1, priv4) - - // Check balances - CheckBalance(t, bapp, addr1, "32foocoin") - CheckBalance(t, bapp, addr4, "32foocoin") - CheckBalance(t, bapp, addr2, "52foocoin") - CheckBalance(t, bapp, addr3, "10foocoin") -} - -func TestMsgSendDependent(t *testing.T) { - bapp := newBasecoinApp() - - genCoins, err := sdk.ParseCoins("42foocoin") - require.Nil(t, err) - - acc1 := auth.BaseAccount{ - Address: addr1, - Coins: genCoins, - } - - // Construct genesis state - err = setGenesis(bapp, acc1) - require.Nil(t, err) - - err = setGenesis(bapp, acc1) - assert.Nil(t, err) - - // CheckDeliver - SignCheckDeliver(t, bapp, sendMsg1, []int64{0}, true, priv1) - - // Check balances - CheckBalance(t, bapp, addr1, "32foocoin") - CheckBalance(t, bapp, addr2, "10foocoin") - - // Simulate a Block - SignCheckDeliver(t, bapp, sendMsg4, []int64{0}, true, priv2) - - // Check balances - CheckBalance(t, bapp, addr1, "42foocoin") -} - -func TestMsgQuiz(t *testing.T) { - bapp := newBasecoinApp() - - // Construct genesis state - // Construct some genesis bytes to reflect basecoin/types/AppAccount - baseAcc := auth.BaseAccount{ - Address: addr1, - Coins: nil, - } - acc1 := &types.AppAccount{baseAcc, "foobart"} - - // Construct genesis state - genesisState := map[string]interface{}{ - "accounts": []*types.GenesisAccount{ - types.NewGenesisAccount(acc1), - }, - } - stateBytes, err := json.MarshalIndent(genesisState, "", "\t") - require.Nil(t, err) - - // Initialize the chain (nil) - vals := []abci.Validator{} - bapp.InitChain(abci.RequestInitChain{Validators: vals, AppStateBytes: stateBytes}) - bapp.Commit() - - // A checkTx context (true) - ctxCheck := bapp.BaseApp.NewContext(true, abci.Header{}) - res1 := bapp.accountMapper.GetAccount(ctxCheck, addr1) - assert.Equal(t, acc1, res1) - -} - -func TestIBCMsgs(t *testing.T) { - bapp := newBasecoinApp() - - sourceChain := "source-chain" - destChain := "dest-chain" - - baseAcc := auth.BaseAccount{ - Address: addr1, - Coins: coins, - } - acc1 := &types.AppAccount{baseAcc, "foobart"} - - err := setGenesis(bapp, baseAcc) - assert.Nil(t, err) - - // A checkTx context (true) - ctxCheck := bapp.BaseApp.NewContext(true, abci.Header{}) - res1 := bapp.accountMapper.GetAccount(ctxCheck, addr1) - assert.Equal(t, acc1, res1) - - packet := ibc.IBCPacket{ - SrcAddr: addr1, - DestAddr: addr1, - Coins: coins, - SrcChain: sourceChain, - DestChain: destChain, - } - - transferMsg := ibc.IBCTransferMsg{ - IBCPacket: packet, - } - - receiveMsg := ibc.IBCReceiveMsg{ - IBCPacket: packet, - Relayer: addr1, - Sequence: 0, - } - - SignCheckDeliver(t, bapp, transferMsg, []int64{0}, true, priv1) - CheckBalance(t, bapp, addr1, "") - SignCheckDeliver(t, bapp, transferMsg, []int64{1}, false, priv1) - SignCheckDeliver(t, bapp, receiveMsg, []int64{2}, true, priv1) - CheckBalance(t, bapp, addr1, "10foocoin") - SignCheckDeliver(t, bapp, receiveMsg, []int64{3}, false, priv1) -} - -func genTx(msg sdk.Msg, seq []int64, priv ...crypto.PrivKeyEd25519) auth.StdTx { - 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) - -} - -func SignCheckDeliver(t *testing.T, bapp *BasecoinApp, msg sdk.Msg, seq []int64, expPass bool, priv ...crypto.PrivKeyEd25519) { - - // Sign the tx - tx := genTx(msg, seq, priv...) - // Run a Check - res := bapp.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 - bapp.BeginBlock(abci.RequestBeginBlock{}) - res = bapp.Deliver(tx) - if expPass { - require.Equal(t, sdk.ABCICodeOK, res.Code, res.Log) - } else { - require.NotEqual(t, sdk.ABCICodeOK, res.Code, res.Log) - } - bapp.EndBlock(abci.RequestEndBlock{}) - //bapp.Commit() -} - -func CheckBalance(t *testing.T, bapp *BasecoinApp, addr sdk.Address, balExpected string) { - ctxDeliver := bapp.BaseApp.NewContext(false, abci.Header{}) - res2 := bapp.accountMapper.GetAccount(ctxDeliver, addr) - assert.Equal(t, balExpected, fmt.Sprintf("%v", res2.GetCoins())) -} diff --git a/examples/democoin/app/app_test.go b/examples/democoin/app/app_test.go index ba041bcff1..01264399ae 100644 --- a/examples/democoin/app/app_test.go +++ b/examples/democoin/app/app_test.go @@ -2,7 +2,6 @@ package app import ( "encoding/json" - "fmt" "os" "testing" @@ -10,12 +9,8 @@ import ( "github.com/stretchr/testify/require" "github.com/cosmos/cosmos-sdk/examples/democoin/types" - "github.com/cosmos/cosmos-sdk/examples/democoin/x/cool" - "github.com/cosmos/cosmos-sdk/examples/democoin/x/pow" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" - "github.com/cosmos/cosmos-sdk/x/bank" - "github.com/cosmos/cosmos-sdk/x/ibc" abci "github.com/tendermint/abci/types" crypto "github.com/tendermint/go-crypto" @@ -23,101 +18,9 @@ import ( "github.com/tendermint/tmlibs/log" ) -// Construct some global addrs and txs for tests. -var ( - chainID = "" // TODO - - priv1 = crypto.GenPrivKeyEd25519() - addr1 = priv1.PubKey().Address() - addr2 = crypto.GenPrivKeyEd25519().PubKey().Address() - coins = sdk.Coins{{"foocoin", 10}} - fee = auth.StdFee{ - sdk.Coins{{"foocoin", 0}}, - 1000000, - } - - sendMsg = bank.MsgSend{ - Inputs: []bank.Input{bank.NewInput(addr1, coins)}, - Outputs: []bank.Output{bank.NewOutput(addr2, coins)}, - } - - quizMsg1 = cool.MsgQuiz{ - Sender: addr1, - CoolAnswer: "icecold", - } - - quizMsg2 = cool.MsgQuiz{ - Sender: addr1, - CoolAnswer: "badvibesonly", - } - - setTrendMsg1 = cool.MsgSetTrend{ - Sender: addr1, - Cool: "icecold", - } - - setTrendMsg2 = cool.MsgSetTrend{ - Sender: addr1, - Cool: "badvibesonly", - } - - setTrendMsg3 = cool.MsgSetTrend{ - Sender: addr1, - Cool: "warmandkind", - } -) - -func loggerAndDB() (log.Logger, dbm.DB) { +func TestGenesis(t *testing.T) { logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "sdk/app") db := dbm.NewMemDB() - return logger, db -} - -func newDemocoinApp() *DemocoinApp { - logger, db := loggerAndDB() - return NewDemocoinApp(logger, db) -} - -//_______________________________________________________________________ - -func TestMsgs(t *testing.T) { - bapp := newDemocoinApp() - - msgs := []struct { - msg sdk.Msg - }{ - {sendMsg}, - {quizMsg1}, - {setTrendMsg1}, - } - - sequences := []int64{0} - for i, m := range msgs { - sig := priv1.Sign(auth.StdSignBytes(chainID, sequences, fee, m.msg)) - tx := auth.NewStdTx(m.msg, fee, []auth.StdSignature{{ - PubKey: priv1.PubKey(), - Signature: sig, - }}) - - // just marshal/unmarshal! - txBytes, err := bapp.cdc.MarshalBinary(tx) - require.NoError(t, err, "i: %v", i) - - // Run a Check - cres := bapp.CheckTx(txBytes) - assert.Equal(t, sdk.CodeUnknownAddress, - sdk.CodeType(cres.Code), "i: %v, log: %v", i, cres.Log) - - // Simulate a Block - bapp.BeginBlock(abci.RequestBeginBlock{}) - dres := bapp.DeliverTx(txBytes) - assert.Equal(t, sdk.CodeUnknownAddress, - sdk.CodeType(dres.Code), "i: %v, log: %v", i, dres.Log) - } -} - -func TestGenesis(t *testing.T) { - logger, db := loggerAndDB() bapp := NewDemocoinApp(logger, db) // Construct some genesis bytes to reflect democoin/types/AppAccount @@ -156,272 +59,3 @@ func TestGenesis(t *testing.T) { res1 = bapp.accountMapper.GetAccount(ctx, baseAcc.Address) assert.Equal(t, acc, res1) } - -func TestMsgSendWithAccounts(t *testing.T) { - bapp := newDemocoinApp() - - // Construct some genesis bytes to reflect democoin/types/AppAccount - // Give 77 foocoin to the first key - coins, err := sdk.ParseCoins("77foocoin") - require.Nil(t, err) - baseAcc := auth.BaseAccount{ - Address: addr1, - Coins: coins, - } - acc1 := &types.AppAccount{baseAcc, "foobart"} - - // Construct genesis state - genesisState := map[string]interface{}{ - "accounts": []*types.GenesisAccount{ - types.NewGenesisAccount(acc1), - }, - "cool": map[string]string{ - "trend": "ice-cold", - }, - } - stateBytes, err := json.MarshalIndent(genesisState, "", "\t") - require.Nil(t, err) - - // Initialize the chain - vals := []abci.Validator{} - bapp.InitChain(abci.RequestInitChain{Validators: vals, AppStateBytes: stateBytes}) - bapp.Commit() - - // A checkTx context (true) - ctxCheck := bapp.BaseApp.NewContext(true, abci.Header{}) - res1 := bapp.accountMapper.GetAccount(ctxCheck, addr1) - assert.Equal(t, acc1, res1) - - // Sign the tx - sequences := []int64{0} - sig := priv1.Sign(auth.StdSignBytes(chainID, sequences, fee, sendMsg)) - tx := auth.NewStdTx(sendMsg, fee, []auth.StdSignature{{ - PubKey: priv1.PubKey(), - Signature: sig, - }}) - - // Run a Check - res := bapp.Check(tx) - assert.Equal(t, sdk.ABCICodeOK, res.Code, res.Log) - - // Simulate a Block - bapp.BeginBlock(abci.RequestBeginBlock{}) - res = bapp.Deliver(tx) - assert.Equal(t, sdk.ABCICodeOK, res.Code, res.Log) - - // Check balances - ctxDeliver := bapp.BaseApp.NewContext(false, abci.Header{}) - res2 := bapp.accountMapper.GetAccount(ctxDeliver, addr1) - res3 := bapp.accountMapper.GetAccount(ctxDeliver, addr2) - assert.Equal(t, fmt.Sprintf("%v", res2.GetCoins()), "67foocoin") - assert.Equal(t, fmt.Sprintf("%v", res3.GetCoins()), "10foocoin") - - // Delivering again should cause replay error - res = bapp.Deliver(tx) - assert.Equal(t, sdk.ToABCICode(sdk.CodespaceRoot, sdk.CodeInvalidSequence), sdk.ABCICodeType(res.Code), res.Log) - - // bumping the txnonce number without resigning should be an auth error - tx.Signatures[0].Sequence = 1 - res = bapp.Deliver(tx) - assert.Equal(t, sdk.ToABCICode(sdk.CodespaceRoot, sdk.CodeUnauthorized), sdk.ABCICodeType(res.Code), res.Log) - - // resigning the tx with the bumped sequence should work - sequences = []int64{1} - sig = priv1.Sign(auth.StdSignBytes(chainID, sequences, fee, tx.Msg)) - tx.Signatures[0].Signature = sig - res = bapp.Deliver(tx) - assert.Equal(t, sdk.ABCICodeOK, res.Code, res.Log) -} - -func TestMsgMine(t *testing.T) { - bapp := newDemocoinApp() - - // Construct genesis state - // Construct some genesis bytes to reflect democoin/types/AppAccount - baseAcc := auth.BaseAccount{ - Address: addr1, - Coins: nil, - } - acc1 := &types.AppAccount{baseAcc, "foobart"} - - // Construct genesis state - genesisState := map[string]interface{}{ - "accounts": []*types.GenesisAccount{ - types.NewGenesisAccount(acc1), - }, - "cool": map[string]string{ - "trend": "ice-cold", - }, - "pow": map[string]uint64{ - "difficulty": 1, - "count": 0, - }, - } - stateBytes, err := json.MarshalIndent(genesisState, "", "\t") - require.Nil(t, err) - - // Initialize the chain (nil) - vals := []abci.Validator{} - bapp.InitChain(abci.RequestInitChain{Validators: vals, AppStateBytes: stateBytes}) - bapp.Commit() - - // A checkTx context (true) - ctxCheck := bapp.BaseApp.NewContext(true, abci.Header{}) - res1 := bapp.accountMapper.GetAccount(ctxCheck, addr1) - assert.Equal(t, acc1, res1) - - // Mine and check for reward - mineMsg1 := pow.GenerateMsgMine(addr1, 1, 2) - SignCheckDeliver(t, bapp, mineMsg1, 0, true) - CheckBalance(t, bapp, "1pow") - // Mine again and check for reward - mineMsg2 := pow.GenerateMsgMine(addr1, 2, 3) - SignCheckDeliver(t, bapp, mineMsg2, 1, true) - CheckBalance(t, bapp, "2pow") - // Mine again - should be invalid - SignCheckDeliver(t, bapp, mineMsg2, 1, false) - CheckBalance(t, bapp, "2pow") - -} - -func TestMsgQuiz(t *testing.T) { - bapp := newDemocoinApp() - - // Construct genesis state - // Construct some genesis bytes to reflect democoin/types/AppAccount - baseAcc := auth.BaseAccount{ - Address: addr1, - Coins: nil, - } - acc1 := &types.AppAccount{baseAcc, "foobart"} - - // Construct genesis state - genesisState := map[string]interface{}{ - "accounts": []*types.GenesisAccount{ - types.NewGenesisAccount(acc1), - }, - "cool": map[string]string{ - "trend": "ice-cold", - }, - } - stateBytes, err := json.MarshalIndent(genesisState, "", "\t") - require.Nil(t, err) - - // Initialize the chain (nil) - vals := []abci.Validator{} - bapp.InitChain(abci.RequestInitChain{Validators: vals, AppStateBytes: stateBytes}) - bapp.Commit() - - // A checkTx context (true) - ctxCheck := bapp.BaseApp.NewContext(true, abci.Header{}) - res1 := bapp.accountMapper.GetAccount(ctxCheck, addr1) - assert.Equal(t, acc1, res1) - - // Set the trend, submit a really cool quiz and check for reward - SignCheckDeliver(t, bapp, setTrendMsg1, 0, true) - SignCheckDeliver(t, bapp, quizMsg1, 1, true) - CheckBalance(t, bapp, "69icecold") - SignCheckDeliver(t, bapp, quizMsg2, 2, false) // result without reward - CheckBalance(t, bapp, "69icecold") - SignCheckDeliver(t, bapp, quizMsg1, 3, true) - CheckBalance(t, bapp, "138icecold") - SignCheckDeliver(t, bapp, setTrendMsg2, 4, true) // reset the trend - SignCheckDeliver(t, bapp, quizMsg1, 5, false) // the same answer will nolonger do! - CheckBalance(t, bapp, "138icecold") - SignCheckDeliver(t, bapp, quizMsg2, 6, true) // earlier answer now relavent again - CheckBalance(t, bapp, "69badvibesonly,138icecold") - SignCheckDeliver(t, bapp, setTrendMsg3, 7, false) // expect to fail to set the trend to something which is not cool - -} - -func TestHandler(t *testing.T) { - bapp := newDemocoinApp() - - sourceChain := "source-chain" - destChain := "dest-chain" - - vals := []abci.Validator{} - baseAcc := auth.BaseAccount{ - Address: addr1, - Coins: coins, - } - acc1 := &types.AppAccount{baseAcc, "foobart"} - genesisState := map[string]interface{}{ - "accounts": []*types.GenesisAccount{ - types.NewGenesisAccount(acc1), - }, - "cool": map[string]string{ - "trend": "ice-cold", - }, - } - stateBytes, err := json.MarshalIndent(genesisState, "", "\t") - require.Nil(t, err) - bapp.InitChain(abci.RequestInitChain{Validators: vals, AppStateBytes: stateBytes}) - bapp.Commit() - - // A checkTx context (true) - ctxCheck := bapp.BaseApp.NewContext(true, abci.Header{}) - res1 := bapp.accountMapper.GetAccount(ctxCheck, addr1) - assert.Equal(t, acc1, res1) - - packet := ibc.IBCPacket{ - SrcAddr: addr1, - DestAddr: addr1, - Coins: coins, - SrcChain: sourceChain, - DestChain: destChain, - } - - transferMsg := ibc.IBCTransferMsg{ - IBCPacket: packet, - } - - receiveMsg := ibc.IBCReceiveMsg{ - IBCPacket: packet, - Relayer: addr1, - Sequence: 0, - } - - SignCheckDeliver(t, bapp, transferMsg, 0, true) - CheckBalance(t, bapp, "") - SignCheckDeliver(t, bapp, transferMsg, 1, false) - SignCheckDeliver(t, bapp, receiveMsg, 2, true) - CheckBalance(t, bapp, "10foocoin") - SignCheckDeliver(t, bapp, receiveMsg, 3, false) -} - -// TODO describe the use of this function -func SignCheckDeliver(t *testing.T, bapp *DemocoinApp, msg sdk.Msg, seq int64, expPass bool) { - - // Sign the tx - tx := auth.NewStdTx(msg, fee, []auth.StdSignature{{ - PubKey: priv1.PubKey(), - Signature: priv1.Sign(auth.StdSignBytes(chainID, []int64{seq}, fee, msg)), - Sequence: seq, - }}) - - // Run a Check - res := bapp.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 - bapp.BeginBlock(abci.RequestBeginBlock{}) - res = bapp.Deliver(tx) - if expPass { - require.Equal(t, sdk.ABCICodeOK, res.Code, res.Log) - } else { - require.NotEqual(t, sdk.ABCICodeOK, res.Code, res.Log) - } - bapp.EndBlock(abci.RequestEndBlock{}) - //bapp.Commit() -} - -func CheckBalance(t *testing.T, bapp *DemocoinApp, balExpected string) { - ctxDeliver := bapp.BaseApp.NewContext(false, abci.Header{}) - res2 := bapp.accountMapper.GetAccount(ctxDeliver, addr1) - assert.Equal(t, balExpected, fmt.Sprintf("%v", res2.GetCoins())) -} diff --git a/examples/democoin/x/cool/app_test.go b/examples/democoin/x/cool/app_test.go new file mode 100644 index 0000000000..d41c8ea824 --- /dev/null +++ b/examples/democoin/x/cool/app_test.go @@ -0,0 +1,105 @@ +package cool + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + abci "github.com/tendermint/abci/types" + crypto "github.com/tendermint/go-crypto" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/auth/mock" + bank "github.com/cosmos/cosmos-sdk/x/bank" +) + +var ( + priv1 = crypto.GenPrivKeyEd25519() + addr1 = priv1.PubKey().Address() + + quizMsg1 = MsgQuiz{ + Sender: addr1, + CoolAnswer: "icecold", + } + + quizMsg2 = MsgQuiz{ + Sender: addr1, + CoolAnswer: "badvibesonly", + } + + setTrendMsg1 = MsgSetTrend{ + Sender: addr1, + Cool: "icecold", + } + + setTrendMsg2 = MsgSetTrend{ + Sender: addr1, + Cool: "badvibesonly", + } + + setTrendMsg3 = MsgSetTrend{ + Sender: addr1, + Cool: "warmandkind", + } +) + +// initialize the mock application for this module +func getMockApp(t *testing.T) *mock.App { + mapp := mock.NewApp() + + RegisterWire(mapp.Cdc) + keyCool := sdk.NewKVStoreKey("cool") + coinKeeper := bank.NewKeeper(mapp.AccountMapper) + keeper := NewKeeper(keyCool, coinKeeper, mapp.RegisterCodespace(DefaultCodespace)) + mapp.Router().AddRoute("cool", NewHandler(keeper)) + + mapp.SetInitChainer(getInitChainer(mapp, keeper, "ice-cold")) + + mapp.CompleteSetup(t, []*sdk.KVStoreKey{keyCool}) + return mapp +} + +// overwrite the mock init chainer +func getInitChainer(mapp *mock.App, keeper Keeper, newTrend string) sdk.InitChainer { + return func(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain { + mapp.InitChainer(ctx, req) + keeper.setTrend(ctx, newTrend) + + return abci.ResponseInitChain{} + } +} + +func TestMsgQuiz(t *testing.T) { + mapp := getMockApp(t) + + // Construct genesis state + acc1 := &auth.BaseAccount{ + Address: addr1, + Coins: nil, + } + accs := []auth.Account{acc1} + + // Initialize the chain (nil) + mock.SetGenesis(mapp, accs) + + // A checkTx context (true) + ctxCheck := mapp.BaseApp.NewContext(true, abci.Header{}) + res1 := mapp.AccountMapper.GetAccount(ctxCheck, addr1) + assert.Equal(t, acc1, res1) + + // Set the trend, submit a really cool quiz and check for reward + mock.SignCheckDeliver(t, mapp.BaseApp, setTrendMsg1, []int64{0}, true, priv1) + mock.SignCheckDeliver(t, mapp.BaseApp, quizMsg1, []int64{1}, true, priv1) + mock.CheckBalance(t, mapp, addr1, sdk.Coins{{"icecold", 69}}) + mock.SignCheckDeliver(t, mapp.BaseApp, quizMsg2, []int64{2}, false, priv1) // result without reward + mock.CheckBalance(t, mapp, addr1, sdk.Coins{{"icecold", 69}}) + mock.SignCheckDeliver(t, mapp.BaseApp, quizMsg1, []int64{3}, true, priv1) + mock.CheckBalance(t, mapp, addr1, sdk.Coins{{"icecold", 138}}) + mock.SignCheckDeliver(t, mapp.BaseApp, setTrendMsg2, []int64{4}, true, priv1) // reset the trend + mock.SignCheckDeliver(t, mapp.BaseApp, quizMsg1, []int64{5}, false, priv1) // the same answer will nolonger do! + mock.CheckBalance(t, mapp, addr1, sdk.Coins{{"icecold", 138}}) + mock.SignCheckDeliver(t, mapp.BaseApp, quizMsg2, []int64{6}, true, priv1) // earlier answer now relavent again + mock.CheckBalance(t, mapp, addr1, sdk.Coins{{"badvibesonly", 69}, {"icecold", 138}}) + mock.SignCheckDeliver(t, mapp.BaseApp, setTrendMsg3, []int64{7}, false, priv1) // expect to fail to set the trend to something which is not cool +} diff --git a/examples/democoin/x/pow/app_test.go b/examples/democoin/x/pow/app_test.go new file mode 100644 index 0000000000..0539df5560 --- /dev/null +++ b/examples/democoin/x/pow/app_test.go @@ -0,0 +1,83 @@ +package pow + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/auth/mock" + "github.com/cosmos/cosmos-sdk/x/bank" + + abci "github.com/tendermint/abci/types" + crypto "github.com/tendermint/go-crypto" +) + +var ( + priv1 = crypto.GenPrivKeyEd25519() + addr1 = priv1.PubKey().Address() +) + +// initialize the mock application for this module +func getMockApp(t *testing.T) *mock.App { + mapp := mock.NewApp() + + RegisterWire(mapp.Cdc) + keyPOW := sdk.NewKVStoreKey("pow") + coinKeeper := bank.NewKeeper(mapp.AccountMapper) + config := Config{"pow", 1} + keeper := NewKeeper(keyPOW, config, coinKeeper, mapp.RegisterCodespace(DefaultCodespace)) + mapp.Router().AddRoute("pow", keeper.Handler) + + mapp.SetInitChainer(getInitChainer(mapp, keeper)) + + mapp.CompleteSetup(t, []*sdk.KVStoreKey{keyPOW}) + return mapp +} + +// overwrite the mock init chainer +func getInitChainer(mapp *mock.App, keeper Keeper) sdk.InitChainer { + return func(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain { + mapp.InitChainer(ctx, req) + + genesis := Genesis{ + Difficulty: 1, + Count: 0, + } + InitGenesis(ctx, keeper, genesis) + + return abci.ResponseInitChain{} + } +} + +func TestMsgMine(t *testing.T) { + mapp := getMockApp(t) + + // Construct genesis state + acc1 := &auth.BaseAccount{ + Address: addr1, + Coins: nil, + } + accs := []auth.Account{acc1} + + // Initialize the chain (nil) + mock.SetGenesis(mapp, accs) + + // A checkTx context (true) + ctxCheck := mapp.BaseApp.NewContext(true, abci.Header{}) + res1 := mapp.AccountMapper.GetAccount(ctxCheck, addr1) + assert.Equal(t, acc1, res1) + + // Mine and check for reward + mineMsg1 := GenerateMsgMine(addr1, 1, 2) + mock.SignCheckDeliver(t, mapp.BaseApp, mineMsg1, []int64{0}, true, priv1) + mock.CheckBalance(t, mapp, addr1, sdk.Coins{{"pow", 1}}) + // Mine again and check for reward + mineMsg2 := GenerateMsgMine(addr1, 2, 3) + mock.SignCheckDeliver(t, mapp.BaseApp, mineMsg2, []int64{1}, true, priv1) + mock.CheckBalance(t, mapp, addr1, sdk.Coins{{"pow", 2}}) + // Mine again - should be invalid + mock.SignCheckDeliver(t, mapp.BaseApp, mineMsg2, []int64{1}, false, priv1) + mock.CheckBalance(t, mapp, addr1, sdk.Coins{{"pow", 2}}) +} diff --git a/tests/mock/app.go b/x/auth/mock/app.go similarity index 95% rename from tests/mock/app.go rename to x/auth/mock/app.go index 6a39330055..6ceff482bf 100644 --- a/tests/mock/app.go +++ b/x/auth/mock/app.go @@ -57,7 +57,7 @@ func NewApp() *App { ) // initialize the app, the chainers and blockers can be overwritten before calling complete setup - app.SetInitChainer(app.initChainer) + app.SetInitChainer(app.InitChainer) app.SetAnteHandler(auth.NewAnteHandler(app.AccountMapper, app.FeeCollectionKeeper)) @@ -75,7 +75,7 @@ func (app *App) CompleteSetup(t *testing.T, newKeys []*sdk.KVStoreKey) { } // custom logic for initialization -func (app *App) initChainer(ctx sdk.Context, _ abci.RequestInitChain) abci.ResponseInitChain { +func (app *App) InitChainer(ctx sdk.Context, _ abci.RequestInitChain) abci.ResponseInitChain { // load the accounts for _, acc := range app.GenesisAccounts { diff --git a/x/auth/mock/auth_app_test.go b/x/auth/mock/auth_app_test.go new file mode 100644 index 0000000000..a3ff6710ee --- /dev/null +++ b/x/auth/mock/auth_app_test.go @@ -0,0 +1,111 @@ +package mock + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/assert" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/bank" + + abci "github.com/tendermint/abci/types" + crypto "github.com/tendermint/go-crypto" +) + +// test auth module messages + +var ( + priv1 = crypto.GenPrivKeyEd25519() + addr1 = priv1.PubKey().Address() + priv2 = crypto.GenPrivKeyEd25519() + addr2 = priv2.PubKey().Address() + + coins = sdk.Coins{{"foocoin", 10}} + sendMsg1 = bank.MsgSend{ + Inputs: []bank.Input{bank.NewInput(addr1, coins)}, + Outputs: []bank.Output{bank.NewOutput(addr2, coins)}, + } +) + +// initialize the mock application for this module +func getMockApp(t *testing.T) *App { + mapp := NewApp() + + coinKeeper := bank.NewKeeper(mapp.AccountMapper) + mapp.Router().AddRoute("bank", bank.NewHandler(coinKeeper)) + mapp.Router().AddRoute("auth", auth.NewHandler(mapp.AccountMapper)) + + mapp.CompleteSetup(t, []*sdk.KVStoreKey{}) + return mapp +} + +func TestMsgChangePubKey(t *testing.T) { + fmt.Println("wackydebugoutput TestMsgChangePubKey 0") + mapp := getMockApp(t) + + // Construct some genesis bytes to reflect basecoin/types/AppAccount + // Give 77 foocoin to the first key + coins := sdk.Coins{{"foocoin", 77}} + fmt.Println("wackydebugoutput TestMsgChangePubKey 1") + acc1 := &auth.BaseAccount{ + Address: addr1, + Coins: coins, + } + fmt.Println("wackydebugoutput TestMsgChangePubKey 3") + accs := []auth.Account{acc1} + fmt.Println("wackydebugoutput TestMsgChangePubKey 4") + + // Construct genesis state + SetGenesis(mapp, accs) + + // A checkTx context (true) + ctxCheck := mapp.BaseApp.NewContext(true, abci.Header{}) + fmt.Println("wackydebugoutput TestMsgChangePubKey 5") + res1 := mapp.AccountMapper.GetAccount(ctxCheck, addr1) + assert.Equal(t, acc1, res1.(*auth.BaseAccount)) + + // Run a CheckDeliver + SignCheckDeliver(t, mapp.BaseApp, sendMsg1, []int64{0}, true, priv1) + fmt.Println("wackydebugoutput TestMsgChangePubKey 6") + + // Check balances + CheckBalance(t, mapp, addr1, sdk.Coins{{"foocoin", 67}}) + fmt.Println("wackydebugoutput TestMsgChangePubKey 7") + CheckBalance(t, mapp, addr2, sdk.Coins{{"foocoin", 10}}) + fmt.Println("wackydebugoutput TestMsgChangePubKey 8") + + changePubKeyMsg := auth.MsgChangeKey{ + Address: addr1, + NewPubKey: priv2.PubKey(), + } + fmt.Println("wackydebugoutput TestMsgChangePubKey 10") + + ctxDeliver := mapp.BaseApp.NewContext(false, abci.Header{}) + fmt.Println("wackydebugoutput TestMsgChangePubKey 11") + acc2 := mapp.AccountMapper.GetAccount(ctxDeliver, addr1) + + // send a MsgChangePubKey + SignCheckDeliver(t, mapp.BaseApp, changePubKeyMsg, []int64{1}, true, priv1) + fmt.Println("wackydebugoutput TestMsgChangePubKey 12") + acc2 = mapp.AccountMapper.GetAccount(ctxDeliver, addr1) + + assert.True(t, priv2.PubKey().Equals(acc2.GetPubKey())) + + // signing a SendMsg with the old privKey should be an auth error + tx := GenTx(sendMsg1, []int64{2}, priv1) + fmt.Println("wackydebugoutput TestMsgChangePubKey 13") + res := mapp.Deliver(tx) + assert.Equal(t, sdk.ToABCICode(sdk.CodespaceRoot, sdk.CodeUnauthorized), res.Code, res.Log) + + // resigning the tx with the new correct priv key should work + SignCheckDeliver(t, mapp.BaseApp, sendMsg1, []int64{2}, true, priv2) + fmt.Println("wackydebugoutput TestMsgChangePubKey 14") + + // Check balances + CheckBalance(t, mapp, addr1, sdk.Coins{{"foocoin", 57}}) + fmt.Println("wackydebugoutput TestMsgChangePubKey 15") + CheckBalance(t, mapp, addr2, sdk.Coins{{"foocoin", 20}}) + fmt.Println("wackydebugoutput TestMsgChangePubKey 16") +} diff --git a/tests/mock/simulate_block.go b/x/auth/mock/simulate_block.go similarity index 89% rename from tests/mock/simulate_block.go rename to x/auth/mock/simulate_block.go index fa1000af79..cf0c303a3f 100644 --- a/tests/mock/simulate_block.go +++ b/x/auth/mock/simulate_block.go @@ -3,6 +3,7 @@ package mock import ( "testing" + "github.com/cosmos/cosmos-sdk/baseapp" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/stretchr/testify/assert" @@ -52,7 +53,7 @@ func GenTx(msg sdk.Msg, seq []int64, priv ...crypto.PrivKeyEd25519) auth.StdTx { } // simulate a block -func SignCheckDeliver(t *testing.T, app *App, msg sdk.Msg, seq []int64, expPass bool, priv ...crypto.PrivKeyEd25519) { +func SignCheckDeliver(t *testing.T, app *baseapp.BaseApp, msg sdk.Msg, seq []int64, expPass bool, priv ...crypto.PrivKeyEd25519) { // Sign the tx tx := GenTx(msg, seq, priv...) @@ -83,7 +84,7 @@ func SignCheckDeliver(t *testing.T, app *App, msg sdk.Msg, seq []int64, expPass // 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) { +func SignDeliver(t *testing.T, app *baseapp.BaseApp, msg sdk.Msg, seq []int64, expPass bool, priv ...crypto.PrivKeyEd25519) { // Sign the tx tx := GenTx(msg, seq, priv...) diff --git a/x/bank/app_test.go b/x/bank/app_test.go index ecbb661455..507f9e3f89 100644 --- a/x/bank/app_test.go +++ b/x/bank/app_test.go @@ -6,9 +6,9 @@ import ( "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" + "github.com/cosmos/cosmos-sdk/x/auth/mock" abci "github.com/tendermint/abci/types" crypto "github.com/tendermint/go-crypto" @@ -16,8 +16,6 @@ import ( // test bank module in a mock application var ( - chainID = "" // TODO - priv1 = crypto.GenPrivKeyEd25519() addr1 = priv1.PubKey().Address() priv2 = crypto.GenPrivKeyEd25519() @@ -109,14 +107,14 @@ func TestMsgSendWithAccounts(t *testing.T) { assert.Equal(t, acc, res1.(*auth.BaseAccount)) // Run a CheckDeliver - mock.SignCheckDeliver(t, mapp, sendMsg1, []int64{0}, true, priv1) + mock.SignCheckDeliver(t, mapp.BaseApp, sendMsg1, []int64{0}, true, priv1) // Check balances mock.CheckBalance(t, mapp, addr1, sdk.Coins{{"foocoin", 57}}) mock.CheckBalance(t, mapp, addr2, sdk.Coins{{"foocoin", 10}}) // Delivering again should cause replay error - mock.SignCheckDeliver(t, mapp, sendMsg1, []int64{0}, false, priv1) + mock.SignCheckDeliver(t, mapp.BaseApp, sendMsg1, []int64{0}, false, priv1) // bumping the txnonce number without resigning should be an auth error tx := mock.GenTx(sendMsg1, []int64{0}, priv1) @@ -126,7 +124,7 @@ func TestMsgSendWithAccounts(t *testing.T) { 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) + mock.SignCheckDeliver(t, mapp.BaseApp, sendMsg1, []int64{1}, true, priv1) } func TestMsgSendMultipleOut(t *testing.T) { @@ -146,7 +144,7 @@ func TestMsgSendMultipleOut(t *testing.T) { mock.SetGenesis(mapp, accs) // Simulate a Block - mock.SignCheckDeliver(t, mapp, sendMsg2, []int64{0}, true, priv1) + mock.SignCheckDeliver(t, mapp.BaseApp, sendMsg2, []int64{0}, true, priv1) // Check balances mock.CheckBalance(t, mapp, addr1, sdk.Coins{{"foocoin", 32}}) @@ -174,7 +172,7 @@ func TestSengMsgMultipleInOut(t *testing.T) { mock.SetGenesis(mapp, accs) // CheckDeliver - mock.SignCheckDeliver(t, mapp, sendMsg3, []int64{0, 0}, true, priv1, priv4) + mock.SignCheckDeliver(t, mapp.BaseApp, sendMsg3, []int64{0, 0}, true, priv1, priv4) // Check balances mock.CheckBalance(t, mapp, addr1, sdk.Coins{{"foocoin", 32}}) @@ -195,14 +193,14 @@ func TestMsgSendDependent(t *testing.T) { mock.SetGenesis(mapp, accs) // CheckDeliver - mock.SignCheckDeliver(t, mapp, sendMsg1, []int64{0}, true, priv1) + mock.SignCheckDeliver(t, mapp.BaseApp, sendMsg1, []int64{0}, true, priv1) // Check balances mock.CheckBalance(t, mapp, addr1, sdk.Coins{{"foocoin", 32}}) mock.CheckBalance(t, mapp, addr2, sdk.Coins{{"foocoin", 10}}) // Simulate a Block - mock.SignCheckDeliver(t, mapp, sendMsg4, []int64{0}, true, priv2) + mock.SignCheckDeliver(t, mapp.BaseApp, sendMsg4, []int64{0}, true, priv2) // Check balances mock.CheckBalance(t, mapp, addr1, sdk.Coins{{"foocoin", 42}}) diff --git a/x/ibc/app_test.go b/x/ibc/app_test.go index 0124e417e5..9e4b4bf56d 100644 --- a/x/ibc/app_test.go +++ b/x/ibc/app_test.go @@ -5,7 +5,7 @@ import ( "github.com/stretchr/testify/assert" - "github.com/cosmos/cosmos-sdk/tests/mock" + "github.com/cosmos/cosmos-sdk/x/auth/mock" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/bank" @@ -29,7 +29,7 @@ func getMockApp(t *testing.T) *mock.App { } func TestIBCMsgs(t *testing.T) { - gapp := getMockApp(t) + mapp := getMockApp(t) sourceChain := "source-chain" destChain := "dest-chain" @@ -45,11 +45,11 @@ func TestIBCMsgs(t *testing.T) { } accs := []auth.Account{acc} - mock.SetGenesis(gapp, accs) + mock.SetGenesis(mapp, accs) // A checkTx context (true) - ctxCheck := gapp.BaseApp.NewContext(true, abci.Header{}) - res1 := gapp.AccountMapper.GetAccount(ctxCheck, addr1) + ctxCheck := mapp.BaseApp.NewContext(true, abci.Header{}) + res1 := mapp.AccountMapper.GetAccount(ctxCheck, addr1) assert.Equal(t, acc, res1) packet := IBCPacket{ @@ -70,10 +70,10 @@ func TestIBCMsgs(t *testing.T) { Sequence: 0, } - mock.SignCheckDeliver(t, gapp, transferMsg, []int64{0}, true, priv1) - mock.CheckBalance(t, gapp, addr1, emptyCoins) - mock.SignCheckDeliver(t, gapp, transferMsg, []int64{1}, false, priv1) - mock.SignCheckDeliver(t, gapp, receiveMsg, []int64{2}, true, priv1) - mock.CheckBalance(t, gapp, addr1, coins) - mock.SignCheckDeliver(t, gapp, receiveMsg, []int64{3}, false, priv1) + mock.SignCheckDeliver(t, mapp.BaseApp, transferMsg, []int64{0}, true, priv1) + mock.CheckBalance(t, mapp, addr1, emptyCoins) + mock.SignCheckDeliver(t, mapp.BaseApp, transferMsg, []int64{1}, false, priv1) + mock.SignCheckDeliver(t, mapp.BaseApp, receiveMsg, []int64{2}, true, priv1) + mock.CheckBalance(t, mapp, addr1, coins) + mock.SignCheckDeliver(t, mapp.BaseApp, receiveMsg, []int64{3}, false, priv1) } diff --git a/x/stake/app_test.go b/x/stake/app_test.go new file mode 100644 index 0000000000..4e3d1f422e --- /dev/null +++ b/x/stake/app_test.go @@ -0,0 +1,152 @@ +package stake + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/auth/mock" + "github.com/cosmos/cosmos-sdk/x/bank" + "github.com/stretchr/testify/require" + + abci "github.com/tendermint/abci/types" + crypto "github.com/tendermint/go-crypto" +) + +var ( + 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}} + fee = auth.StdFee{ + sdk.Coins{{"foocoin", 0}}, + 100000, + } +) + +// initialize the mock application for this module +func getMockApp(t *testing.T) (*mock.App, Keeper) { + mapp := mock.NewApp() + + RegisterWire(mapp.Cdc) + keyStake := sdk.NewKVStoreKey("stake") + coinKeeper := bank.NewKeeper(mapp.AccountMapper) + keeper := NewKeeper(mapp.Cdc, keyStake, coinKeeper, mapp.RegisterCodespace(DefaultCodespace)) + mapp.Router().AddRoute("stake", NewHandler(keeper)) + + mapp.SetEndBlocker(getEndBlocker(keeper)) + mapp.SetInitChainer(getInitChainer(mapp, keeper)) + + mapp.CompleteSetup(t, []*sdk.KVStoreKey{keyStake}) + return mapp, keeper +} + +// stake endblocker +func getEndBlocker(keeper Keeper) sdk.EndBlocker { + return func(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock { + validatorUpdates := EndBlocker(ctx, keeper) + return abci.ResponseEndBlock{ + ValidatorUpdates: validatorUpdates, + } + } +} + +// overwrite the mock init chainer +func getInitChainer(mapp *mock.App, keeper Keeper) sdk.InitChainer { + return func(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain { + mapp.InitChainer(ctx, req) + InitGenesis(ctx, keeper, DefaultGenesisState()) + + return abci.ResponseInitChain{} + } +} + +func TestStakeMsgs(t *testing.T) { + mapp, keeper := getMockApp(t) + + genCoin := sdk.Coin{"steak", 42} + bondCoin := sdk.Coin{"steak", 10} + + acc1 := &auth.BaseAccount{ + Address: addr1, + Coins: sdk.Coins{genCoin}, + } + acc2 := &auth.BaseAccount{ + Address: addr2, + Coins: sdk.Coins{genCoin}, + } + accs := []auth.Account{acc1, acc2} + + mock.SetGenesis(mapp, accs) + + // A checkTx context (true) + ctxCheck := mapp.BaseApp.NewContext(true, abci.Header{}) + res1 := mapp.AccountMapper.GetAccount(ctxCheck, addr1) + res2 := mapp.AccountMapper.GetAccount(ctxCheck, addr2) + require.Equal(t, acc1, res1) + require.Equal(t, acc2, res2) + + // Create Validator + + description := NewDescription("foo_moniker", "", "", "") + createValidatorMsg := NewMsgCreateValidator( + addr1, priv1.PubKey(), bondCoin, description, + ) + mock.SignCheckDeliver(t, mapp.BaseApp, createValidatorMsg, []int64{0}, true, priv1) + + ctxDeliver := mapp.BaseApp.NewContext(false, abci.Header{}) + res1 = mapp.AccountMapper.GetAccount(ctxDeliver, addr1) + require.Equal(t, sdk.Coins{genCoin.Minus(bondCoin)}, res1.GetCoins()) + validator, found := keeper.GetValidator(ctxDeliver, addr1) + require.True(t, found) + require.Equal(t, addr1, validator.Owner) + require.Equal(t, sdk.Bonded, validator.Status()) + require.True(sdk.RatEq(t, sdk.NewRat(10), validator.PoolShares.Bonded())) + + // check the bond that should have been created as well + bond, found := keeper.GetDelegation(ctxDeliver, addr1, addr1) + require.True(sdk.RatEq(t, sdk.NewRat(10), bond.Shares)) + + // Edit Validator + + description = NewDescription("bar_moniker", "", "", "") + editValidatorMsg := NewMsgEditValidator( + addr1, description, + ) + mock.SignDeliver(t, mapp.BaseApp, editValidatorMsg, []int64{1}, true, priv1) + + validator, found = keeper.GetValidator(ctxDeliver, addr1) + require.True(t, found) + require.Equal(t, description, validator.Description) + + // Delegate + + delegateMsg := NewMsgDelegate( + addr2, addr1, bondCoin, + ) + mock.SignDeliver(t, mapp.BaseApp, delegateMsg, []int64{0}, true, priv2) + + res2 = mapp.AccountMapper.GetAccount(ctxDeliver, addr2) + require.Equal(t, sdk.Coins{genCoin.Minus(bondCoin)}, res2.GetCoins()) + bond, found = keeper.GetDelegation(ctxDeliver, addr2, addr1) + require.True(t, found) + require.Equal(t, addr2, bond.DelegatorAddr) + require.Equal(t, addr1, bond.ValidatorAddr) + require.True(sdk.RatEq(t, sdk.NewRat(10), bond.Shares)) + + // Unbond + + unbondMsg := NewMsgUnbond( + addr2, addr1, "MAX", + ) + mock.SignDeliver(t, mapp.BaseApp, unbondMsg, []int64{1}, true, priv2) + + res2 = mapp.AccountMapper.GetAccount(ctxDeliver, addr2) + require.Equal(t, sdk.Coins{genCoin}, res2.GetCoins()) + _, found = keeper.GetDelegation(ctxDeliver, addr2, addr1) + require.False(t, found) +}