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

feat(tests): add simapp setup helpers #10020

Merged
merged 14 commits into from
Sep 15, 2021
44 changes: 19 additions & 25 deletions simapp/app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,15 @@ import (
func TestSimAppExportAndBlockedAddrs(t *testing.T) {
encCfg := MakeTestEncodingConfig()
db := dbm.NewMemDB()
app := NewSimApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, map[int64]bool{}, DefaultNodeHome, 0, encCfg, EmptyAppOptions{})
app := NewSimappWithCustomOptions(t, false, SetupOptions{
Logger: log.NewTMLogger(log.NewSyncWriter(os.Stdout)),
DB: db,
InvCheckPeriod: 0,
EncConfig: encCfg,
HomePath: DefaultNodeHome,
SkipUpgradeHeights: map[int64]bool{},
AppOpts: EmptyAppOptions{},
})

for acc := range maccPerms {
require.True(
Expand All @@ -49,22 +57,11 @@ func TestSimAppExportAndBlockedAddrs(t *testing.T) {
)
}

genesisState := NewDefaultGenesisState(encCfg.Codec)
stateBytes, err := json.MarshalIndent(genesisState, "", " ")
require.NoError(t, err)

// Initialize the chain
app.InitChain(
abci.RequestInitChain{
Validators: []abci.ValidatorUpdate{},
AppStateBytes: stateBytes,
},
)
app.Commit()

// Making a new app object with the db, so that initchain hasn't been called
app2 := NewSimApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, map[int64]bool{}, DefaultNodeHome, 0, encCfg, EmptyAppOptions{})
_, err = app2.ExportAppStateAndValidators(false, []string{})
_, err := app2.ExportAppStateAndValidators(false, []string{})
require.NoError(t, err, "ExportAppStateAndValidators should not have an error")
}

Expand Down Expand Up @@ -249,18 +246,15 @@ func TestInitGenesisOnMigration(t *testing.T) {
func TestUpgradeStateOnGenesis(t *testing.T) {
encCfg := MakeTestEncodingConfig()
db := dbm.NewMemDB()
app := NewSimApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, map[int64]bool{}, DefaultNodeHome, 0, encCfg, EmptyAppOptions{})
genesisState := NewDefaultGenesisState(encCfg.Codec)
stateBytes, err := json.MarshalIndent(genesisState, "", " ")
require.NoError(t, err)

// Initialize the chain
app.InitChain(
abci.RequestInitChain{
Validators: []abci.ValidatorUpdate{},
AppStateBytes: stateBytes,
},
)
app := NewSimappWithCustomOptions(t, false, SetupOptions{
Logger: log.NewTMLogger(log.NewSyncWriter(os.Stdout)),
DB: db,
InvCheckPeriod: 0,
EncConfig: encCfg,
HomePath: DefaultNodeHome,
SkipUpgradeHeights: map[int64]bool{},
AppOpts: EmptyAppOptions{},
})

// make sure the upgrade keeper has version map in state
ctx := app.NewContext(false, tmproto.Header{})
Expand Down
86 changes: 75 additions & 11 deletions simapp/test_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (

"github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types"
tmjson "github.com/tendermint/tendermint/libs/json"
"github.com/tendermint/tendermint/libs/log"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
tmtypes "github.com/tendermint/tendermint/types"
Expand All @@ -21,8 +22,12 @@ import (
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
"github.com/cosmos/cosmos-sdk/server/types"
"github.com/cosmos/cosmos-sdk/simapp/helpers"
"github.com/cosmos/cosmos-sdk/simapp/params"
"github.com/cosmos/cosmos-sdk/testutil/mock"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/errors"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
Expand Down Expand Up @@ -50,6 +55,17 @@ var DefaultConsensusParams = &abci.ConsensusParams{
},
}

// SetupOptions defines arguments that are passed into `Simapp` constructor.
type SetupOptions struct {
colin-axner marked this conversation as resolved.
Show resolved Hide resolved
Logger log.Logger
DB *dbm.MemDB
InvCheckPeriod uint
HomePath string
SkipUpgradeHeights map[int64]bool
EncConfig params.EncodingConfig
AppOpts types.AppOptions
}

func setup(withGenesis bool, invCheckPeriod uint) (*SimApp, GenesisState) {
db := dbm.NewMemDB()
encCdc := MakeTestEncodingConfig()
Expand All @@ -60,6 +76,47 @@ func setup(withGenesis bool, invCheckPeriod uint) (*SimApp, GenesisState) {
return app, GenesisState{}
}

// NewSimappWithCustomOptions initializes a new SimApp with custom options.
func NewSimappWithCustomOptions(t *testing.T, isCheckTx bool, options SetupOptions) *SimApp {
t.Helper()

privVal := mock.NewPV()
pubKey, err := privVal.GetPubKey()
require.NoError(t, err)
// create validator set with single validator
validator := tmtypes.NewValidator(pubKey, 1)
valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator})

// generate genesis account
senderPrivKey := secp256k1.GenPrivKey()
acc := authtypes.NewBaseAccount(senderPrivKey.PubKey().Address().Bytes(), senderPrivKey.PubKey(), 0, 0)
balance := banktypes.Balance{
Address: acc.GetAddress().String(),
Coins: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100000000000000))),
}

app := NewSimApp(options.Logger, options.DB, nil, true, options.SkipUpgradeHeights, options.HomePath, options.InvCheckPeriod, options.EncConfig, options.AppOpts)
genesisState := NewDefaultGenesisState(app.appCodec)
genesisState = genesisStateWithValSet(t, app, genesisState, valSet, []authtypes.GenesisAccount{acc}, balance)

if !isCheckTx {
// init chain must be called to stop deliverState from being nil
stateBytes, err := tmjson.MarshalIndent(genesisState, "", " ")
require.NoError(t, err)

// Initialize the chain
app.InitChain(
abci.RequestInitChain{
Validators: []abci.ValidatorUpdate{},
ConsensusParams: DefaultConsensusParams,
AppStateBytes: stateBytes,
},
)
}

return app
}

// Setup initializes a new SimApp. A Nop logger is set in SimApp.
func Setup(t *testing.T, isCheckTx bool) *SimApp {
t.Helper()
Expand All @@ -83,20 +140,18 @@ func Setup(t *testing.T, isCheckTx bool) *SimApp {
return app
}

// SetupWithGenesisValSet initializes a new SimApp with a validator set and genesis accounts
// that also act as delegators. For simplicity, each validator is bonded with a delegation
// of one consensus engine unit (10^6) in the default token of the simapp from first genesis
// account. A Nop logger is set in SimApp.
func SetupWithGenesisValSet(t *testing.T, valSet *tmtypes.ValidatorSet, genAccs []authtypes.GenesisAccount, balances ...banktypes.Balance) *SimApp {
app, genesisState := setup(true, 5)
func genesisStateWithValSet(t *testing.T,
app *SimApp, genesisState GenesisState,
valSet *tmtypes.ValidatorSet, genAccs []authtypes.GenesisAccount,
balances ...banktypes.Balance) GenesisState {
// set genesis accounts
authGenesis := authtypes.NewGenesisState(authtypes.DefaultParams(), genAccs)
genesisState[authtypes.ModuleName] = app.AppCodec().MustMarshalJSON(authGenesis)

validators := make([]stakingtypes.Validator, 0, len(valSet.Validators))
delegations := make([]stakingtypes.Delegation, 0, len(valSet.Validators))

bondAmt := sdk.NewInt(1000000)
bondAmt := sdk.DefaultPowerReduction

for _, val := range valSet.Validators {
pk, err := cryptocodec.FromTmPubKeyInterface(val.PubKey)
Expand Down Expand Up @@ -140,6 +195,17 @@ func SetupWithGenesisValSet(t *testing.T, valSet *tmtypes.ValidatorSet, genAccs
bankGenesis := banktypes.NewGenesisState(banktypes.DefaultGenesisState().Params, balances, totalSupply, []banktypes.Metadata{})
genesisState[banktypes.ModuleName] = app.AppCodec().MustMarshalJSON(bankGenesis)

return genesisState
}

// SetupWithGenesisValSet initializes a new SimApp with a validator set and genesis accounts
// that also act as delegators. For simplicity, each validator is bonded with a delegation
// of one consensus engine unit in the default token of the simapp from first genesis
// account. A Nop logger is set in SimApp.
func SetupWithGenesisValSet(t *testing.T, valSet *tmtypes.ValidatorSet, genAccs []authtypes.GenesisAccount, balances ...banktypes.Balance) *SimApp {
app, genesisState := setup(true, 5)
genesisState = genesisStateWithValSet(t, app, genesisState, valSet, genAccs, balances...)

stateBytes, err := json.MarshalIndent(genesisState, "", " ")
require.NoError(t, err)

Expand All @@ -166,7 +232,7 @@ func SetupWithGenesisValSet(t *testing.T, valSet *tmtypes.ValidatorSet, genAccs

// SetupWithGenesisAccounts initializes a new SimApp with the provided genesis
// accounts and possible balances.
func SetupWithGenesisAccounts(genAccs []authtypes.GenesisAccount, balances ...banktypes.Balance) *SimApp {
func SetupWithGenesisAccounts(t *testing.T, genAccs []authtypes.GenesisAccount, balances ...banktypes.Balance) *SimApp {
app, genesisState := setup(true, 0)
authGenesis := authtypes.NewGenesisState(authtypes.DefaultParams(), genAccs)
genesisState[authtypes.ModuleName] = app.AppCodec().MustMarshalJSON(authGenesis)
Expand All @@ -180,9 +246,7 @@ func SetupWithGenesisAccounts(genAccs []authtypes.GenesisAccount, balances ...ba
genesisState[banktypes.ModuleName] = app.AppCodec().MustMarshalJSON(bankGenesis)

stateBytes, err := json.MarshalIndent(genesisState, "", " ")
if err != nil {
panic(err)
}
require.NoError(t, err)

app.InitChain(
abci.RequestInitChain{
Expand Down
50 changes: 50 additions & 0 deletions testutil/mock/privval.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package mock

import (
"github.com/tendermint/tendermint/crypto"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
tmtypes "github.com/tendermint/tendermint/types"

cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
)

var _ tmtypes.PrivValidator = PV{}
aleem1314 marked this conversation as resolved.
Show resolved Hide resolved

// MockPV implements PrivValidator without any safety or persistence.
// Only use it for testing.
type PV struct {
PrivKey cryptotypes.PrivKey
}

func NewPV() PV {
return PV{ed25519.GenPrivKey()}
}

// GetPubKey implements PrivValidator interface
func (pv PV) GetPubKey() (crypto.PubKey, error) {
return cryptocodec.ToTmPubKeyInterface(pv.PrivKey.PubKey())
}

// SignVote implements PrivValidator interface
func (pv PV) SignVote(chainID string, vote *tmproto.Vote) error {
signBytes := tmtypes.VoteSignBytes(chainID, vote)
sig, err := pv.PrivKey.Sign(signBytes)
if err != nil {
return err
}
vote.Signature = sig
return nil
}

// SignProposal implements PrivValidator interface
func (pv PV) SignProposal(chainID string, proposal *tmproto.Proposal) error {
signBytes := tmtypes.ProposalSignBytes(chainID, proposal)
sig, err := pv.PrivKey.Sign(signBytes)
if err != nil {
return err
}
proposal.Signature = sig
return nil
}
10 changes: 5 additions & 5 deletions x/bank/app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ func TestSendNotEnoughBalance(t *testing.T) {
}

genAccs := []authtypes.GenesisAccount{acc}
app := simapp.SetupWithGenesisAccounts(genAccs)
app := simapp.SetupWithGenesisAccounts(t, genAccs)
ctx := app.BaseApp.NewContext(false, tmproto.Header{})

require.NoError(t, testutil.FundAccount(app.BankKeeper, ctx, addr1, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 67))))
Expand Down Expand Up @@ -127,7 +127,7 @@ func TestMsgMultiSendWithAccounts(t *testing.T) {
}

genAccs := []authtypes.GenesisAccount{acc}
app := simapp.SetupWithGenesisAccounts(genAccs)
app := simapp.SetupWithGenesisAccounts(t, genAccs)
ctx := app.BaseApp.NewContext(false, tmproto.Header{})

require.NoError(t, testutil.FundAccount(app.BankKeeper, ctx, addr1, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 67))))
Expand Down Expand Up @@ -197,7 +197,7 @@ func TestMsgMultiSendMultipleOut(t *testing.T) {
}

genAccs := []authtypes.GenesisAccount{acc1, acc2}
app := simapp.SetupWithGenesisAccounts(genAccs)
app := simapp.SetupWithGenesisAccounts(t, genAccs)
ctx := app.BaseApp.NewContext(false, tmproto.Header{})

require.NoError(t, testutil.FundAccount(app.BankKeeper, ctx, addr1, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 42))))
Expand Down Expand Up @@ -246,7 +246,7 @@ func TestMsgMultiSendMultipleInOut(t *testing.T) {
}

genAccs := []authtypes.GenesisAccount{acc1, acc2, acc4}
app := simapp.SetupWithGenesisAccounts(genAccs)
app := simapp.SetupWithGenesisAccounts(t, genAccs)
ctx := app.BaseApp.NewContext(false, tmproto.Header{})

require.NoError(t, testutil.FundAccount(app.BankKeeper, ctx, addr1, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 42))))
Expand Down Expand Up @@ -293,7 +293,7 @@ func TestMsgMultiSendDependent(t *testing.T) {
require.NoError(t, err)

genAccs := []authtypes.GenesisAccount{acc1, acc2}
app := simapp.SetupWithGenesisAccounts(genAccs)
app := simapp.SetupWithGenesisAccounts(t, genAccs)
ctx := app.BaseApp.NewContext(false, tmproto.Header{})

require.NoError(t, testutil.FundAccount(app.BankKeeper, ctx, addr1, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 42))))
Expand Down
4 changes: 2 additions & 2 deletions x/bank/bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func BenchmarkOneBankSendTxPerBlock(b *testing.B) {

// construct genesis state
genAccs := []types.GenesisAccount{&acc}
benchmarkApp := simapp.SetupWithGenesisAccounts(genAccs)
benchmarkApp := simapp.SetupWithGenesisAccounts(&testing.T{}, genAccs)
ctx := benchmarkApp.BaseApp.NewContext(false, tmproto.Header{})

// some value conceivably higher than the benchmarks would ever go
Expand Down Expand Up @@ -73,7 +73,7 @@ func BenchmarkOneBankMultiSendTxPerBlock(b *testing.B) {

// Construct genesis state
genAccs := []authtypes.GenesisAccount{&acc}
benchmarkApp := simapp.SetupWithGenesisAccounts(genAccs)
benchmarkApp := simapp.SetupWithGenesisAccounts(&testing.T{}, genAccs)
ctx := benchmarkApp.BaseApp.NewContext(false, tmproto.Header{})

// some value conceivably higher than the benchmarks would ever go
Expand Down
2 changes: 1 addition & 1 deletion x/slashing/app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func TestSlashingMsgs(t *testing.T) {
},
}

app := simapp.SetupWithGenesisAccounts(accs, balances...)
app := simapp.SetupWithGenesisAccounts(t, accs, balances...)
simapp.CheckBalance(t, app, addr1, sdk.Coins{genCoin})

description := stakingtypes.NewDescription("foo_moniker", "", "", "", "")
Expand Down
2 changes: 1 addition & 1 deletion x/staking/app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func TestStakingMsgs(t *testing.T) {
},
}

app := simapp.SetupWithGenesisAccounts(accs, balances...)
app := simapp.SetupWithGenesisAccounts(t, accs, balances...)
simapp.CheckBalance(t, app, addr1, sdk.Coins{genCoin})
simapp.CheckBalance(t, app, addr2, sdk.Coins{genCoin})

Expand Down
Loading