2019-12-03 14:33:20 +00:00
package app
import (
2022-01-08 00:39:27 +00:00
"encoding/json"
2019-12-03 14:33:20 +00:00
"math/rand"
2019-12-05 13:51:46 +00:00
"testing"
2020-08-17 15:06:59 +00:00
"time"
2019-12-05 13:51:46 +00:00
2022-01-08 00:39:27 +00:00
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
sdk "github.com/cosmos/cosmos-sdk/types"
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
crisiskeeper "github.com/cosmos/cosmos-sdk/x/crisis/keeper"
distkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper"
govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper"
mintkeeper "github.com/cosmos/cosmos-sdk/x/mint/keeper"
minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper"
slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper"
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
hardkeeper "github.com/kava-labs/kava/x/hard/keeper"
2019-12-05 13:51:46 +00:00
"github.com/stretchr/testify/require"
2019-12-03 14:33:20 +00:00
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/libs/log"
2022-01-08 00:39:27 +00:00
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
tmdb "github.com/tendermint/tm-db"
2019-12-03 14:33:20 +00:00
2022-01-08 00:39:27 +00:00
auctionkeeper "github.com/kava-labs/kava/x/auction/keeper"
bep3keeper "github.com/kava-labs/kava/x/bep3/keeper"
cdpkeeper "github.com/kava-labs/kava/x/cdp/keeper"
committeekeeper "github.com/kava-labs/kava/x/committee/keeper"
incentivekeeper "github.com/kava-labs/kava/x/incentive/keeper"
issuancekeeper "github.com/kava-labs/kava/x/issuance/keeper"
kavadistkeeper "github.com/kava-labs/kava/x/kavadist/keeper"
pricefeedkeeper "github.com/kava-labs/kava/x/pricefeed/keeper"
2022-03-22 21:13:27 +00:00
savingskeeper "github.com/kava-labs/kava/x/savings/keeper"
2022-01-08 00:39:27 +00:00
swapkeeper "github.com/kava-labs/kava/x/swap/keeper"
2019-12-03 14:33:20 +00:00
)
2021-06-10 13:35:44 +00:00
var (
emptyTime time . Time
emptyChainID string
)
2019-12-03 14:33:20 +00:00
// TestApp is a simple wrapper around an App. It exposes internal keepers for use in integration tests.
// This file also contains test helpers. Ideally they would be in separate package.
// Basic Usage:
2019-12-03 14:35:27 +00:00
// Create a test app with NewTestApp, then all keepers and their methods can be accessed for test setup and execution.
2019-12-03 14:33:20 +00:00
// Advanced Usage:
2019-12-03 14:35:27 +00:00
// Some tests call for an app to be initialized with some state. This can be achieved through keeper method calls (ie keeper.SetParams(...)).
// However this leads to a lot of duplicated logic similar to InitGenesis methods.
// So TestApp.InitializeFromGenesisStates() will call InitGenesis with the default genesis state.
// and TestApp.InitializeFromGenesisStates(authState, cdpState) will do the same but overwrite the auth and cdp sections of the default genesis state
// Creating the genesis states can be combersome, but helper methods can make it easier such as NewAuthGenStateFromAccounts below.
2019-12-03 14:33:20 +00:00
type TestApp struct {
App
}
2022-01-08 00:39:27 +00:00
// NewTestApp creates a new TestApp
//
// Note, it also sets the sdk config with the app's address prefix, coin type, etc.
2019-12-03 14:33:20 +00:00
func NewTestApp ( ) TestApp {
2022-01-08 00:39:27 +00:00
SetSDKConfig ( )
2020-04-23 16:35:58 +00:00
2022-01-08 00:39:27 +00:00
return NewTestAppFromSealed ( )
2019-12-03 14:33:20 +00:00
}
2022-01-08 00:39:27 +00:00
// NewTestAppFromSealed creates a TestApp without first setting sdk config.
2021-08-26 22:53:46 +00:00
func NewTestAppFromSealed ( ) TestApp {
db := tmdb . NewMemDB ( )
2022-01-08 00:39:27 +00:00
encCfg := MakeEncodingConfig ( )
app := NewApp ( log . NewNopLogger ( ) , db , DefaultNodeHome , nil , encCfg , Options { } )
2021-08-26 22:53:46 +00:00
return TestApp { App : * app }
}
2020-05-07 20:34:05 +00:00
// nolint
2022-01-08 00:39:27 +00:00
func ( tApp TestApp ) GetAccountKeeper ( ) authkeeper . AccountKeeper { return tApp . accountKeeper }
func ( tApp TestApp ) GetBankKeeper ( ) bankkeeper . Keeper { return tApp . bankKeeper }
func ( tApp TestApp ) GetStakingKeeper ( ) stakingkeeper . Keeper { return tApp . stakingKeeper }
func ( tApp TestApp ) GetSlashingKeeper ( ) slashingkeeper . Keeper { return tApp . slashingKeeper }
func ( tApp TestApp ) GetMintKeeper ( ) mintkeeper . Keeper { return tApp . mintKeeper }
func ( tApp TestApp ) GetDistrKeeper ( ) distkeeper . Keeper { return tApp . distrKeeper }
func ( tApp TestApp ) GetGovKeeper ( ) govkeeper . Keeper { return tApp . govKeeper }
func ( tApp TestApp ) GetCrisisKeeper ( ) crisiskeeper . Keeper { return tApp . crisisKeeper }
func ( tApp TestApp ) GetParamsKeeper ( ) paramskeeper . Keeper { return tApp . paramsKeeper }
func ( tApp TestApp ) GetKavadistKeeper ( ) kavadistkeeper . Keeper { return tApp . kavadistKeeper }
func ( tApp TestApp ) GetAuctionKeeper ( ) auctionkeeper . Keeper { return tApp . auctionKeeper }
func ( tApp TestApp ) GetIssuanceKeeper ( ) issuancekeeper . Keeper { return tApp . issuanceKeeper }
func ( tApp TestApp ) GetBep3Keeper ( ) bep3keeper . Keeper { return tApp . bep3Keeper }
func ( tApp TestApp ) GetPriceFeedKeeper ( ) pricefeedkeeper . Keeper { return tApp . pricefeedKeeper }
func ( tApp TestApp ) GetSwapKeeper ( ) swapkeeper . Keeper { return tApp . swapKeeper }
func ( tApp TestApp ) GetCDPKeeper ( ) cdpkeeper . Keeper { return tApp . cdpKeeper }
func ( tApp TestApp ) GetHardKeeper ( ) hardkeeper . Keeper { return tApp . hardKeeper }
func ( tApp TestApp ) GetCommitteeKeeper ( ) committeekeeper . Keeper { return tApp . committeeKeeper }
func ( tApp TestApp ) GetIncentiveKeeper ( ) incentivekeeper . Keeper { return tApp . incentiveKeeper }
2022-03-22 21:13:27 +00:00
func ( tApp TestApp ) GetSavingsKeeper ( ) savingskeeper . Keeper { return tApp . savingsKeeper }
2022-01-08 00:39:27 +00:00
// LegacyAmino returns the app's amino codec.
func ( app * App ) LegacyAmino ( ) * codec . LegacyAmino {
return app . legacyAmino
}
// AppCodec returns the app's app codec.
func ( app * App ) AppCodec ( ) codec . Codec {
return app . appCodec
}
2019-12-03 14:33:20 +00:00
2020-09-21 21:08:43 +00:00
// InitializeFromGenesisStates calls InitChain on the app using the default genesis state, overwitten with any passed in genesis states
2019-12-03 14:33:20 +00:00
func ( tApp TestApp ) InitializeFromGenesisStates ( genesisStates ... GenesisState ) TestApp {
2021-06-10 13:35:44 +00:00
return tApp . InitializeFromGenesisStatesWithTimeAndChainID ( emptyTime , emptyChainID , genesisStates ... )
2019-12-03 14:33:20 +00:00
}
2020-08-17 15:06:59 +00:00
// InitializeFromGenesisStatesWithTime calls InitChain on the app using the default genesis state, overwitten with any passed in genesis states and genesis Time
func ( tApp TestApp ) InitializeFromGenesisStatesWithTime ( genTime time . Time , genesisStates ... GenesisState ) TestApp {
2021-06-10 13:35:44 +00:00
return tApp . InitializeFromGenesisStatesWithTimeAndChainID ( genTime , emptyChainID , genesisStates ... )
2020-08-17 15:06:59 +00:00
}
2020-10-06 18:25:05 +00:00
// InitializeFromGenesisStatesWithTimeAndChainID calls InitChain on the app using the default genesis state, overwitten with any passed in genesis states and genesis Time
func ( tApp TestApp ) InitializeFromGenesisStatesWithTimeAndChainID ( genTime time . Time , chainID string , genesisStates ... GenesisState ) TestApp {
// Create a default genesis state and overwrite with provided values
genesisState := NewDefaultGenesisState ( )
for _ , state := range genesisStates {
for k , v := range state {
genesisState [ k ] = v
}
}
// Initialize the chain
2022-01-08 00:39:27 +00:00
stateBytes , err := json . Marshal ( genesisState )
2020-10-06 18:25:05 +00:00
if err != nil {
panic ( err )
}
tApp . InitChain (
abci . RequestInitChain {
Time : genTime ,
Validators : [ ] abci . ValidatorUpdate { } ,
AppStateBytes : stateBytes ,
ChainId : chainID ,
} ,
)
tApp . Commit ( )
2022-01-08 00:39:27 +00:00
tApp . BeginBlock ( abci . RequestBeginBlock { Header : tmproto . Header { Height : tApp . LastBlockHeight ( ) + 1 , Time : genTime } } )
2020-10-06 18:25:05 +00:00
return tApp
}
2022-01-08 00:39:27 +00:00
// CheckBalance requires the account address has the expected amount of coins.
2019-12-05 13:51:46 +00:00
func ( tApp TestApp ) CheckBalance ( t * testing . T , ctx sdk . Context , owner sdk . AccAddress , expectedCoins sdk . Coins ) {
2022-01-08 00:39:27 +00:00
coins := tApp . GetBankKeeper ( ) . GetAllBalances ( ctx , owner )
require . Equal ( t , expectedCoins , coins )
}
// FundAccount is a utility function that funds an account by minting and sending the coins to the address.
func ( tApp TestApp ) FundAccount ( ctx sdk . Context , addr sdk . AccAddress , amounts sdk . Coins ) error {
if err := tApp . bankKeeper . MintCoins ( ctx , minttypes . ModuleName , amounts ) ; err != nil {
return err
}
return tApp . bankKeeper . SendCoinsFromModuleToAccount ( ctx , minttypes . ModuleName , addr , amounts )
}
// NewQueryServerTestHelper creates a new QueryServiceTestHelper that wraps the provided sdk.Context.
func ( tApp TestApp ) NewQueryServerTestHelper ( ctx sdk . Context ) * baseapp . QueryServiceTestHelper {
return baseapp . NewQueryServerTestHelper ( ctx , tApp . interfaceRegistry )
}
// FundModuleAccount is a utility function that funds a module account by minting and sending the coins to the address.
func ( tApp TestApp ) FundModuleAccount ( ctx sdk . Context , recipientMod string , amounts sdk . Coins ) error {
if err := tApp . bankKeeper . MintCoins ( ctx , minttypes . ModuleName , amounts ) ; err != nil {
return err
}
return tApp . bankKeeper . SendCoinsFromModuleToModule ( ctx , minttypes . ModuleName , recipientMod , amounts )
2019-12-05 13:51:46 +00:00
}
2022-01-08 00:39:27 +00:00
// GeneratePrivKeyAddressPairsFromRand generates (deterministically) a total of n private keys and addresses.
func GeneratePrivKeyAddressPairs ( n int ) ( keys [ ] cryptotypes . PrivKey , addrs [ ] sdk . AccAddress ) {
2019-12-03 14:33:20 +00:00
r := rand . New ( rand . NewSource ( 12345 ) ) // make the generation deterministic
2022-01-08 00:39:27 +00:00
keys = make ( [ ] cryptotypes . PrivKey , n )
2019-12-03 14:33:20 +00:00
addrs = make ( [ ] sdk . AccAddress , n )
for i := 0 ; i < n ; i ++ {
secret := make ( [ ] byte , 32 )
_ , err := r . Read ( secret )
if err != nil {
panic ( "Could not read randomness" )
}
2022-01-08 00:39:27 +00:00
keys [ i ] = secp256k1 . GenPrivKeyFromSecret ( secret )
2019-12-03 14:33:20 +00:00
addrs [ i ] = sdk . AccAddress ( keys [ i ] . PubKey ( ) . Address ( ) )
}
return
}
2021-06-10 13:35:44 +00:00
2022-01-08 00:39:27 +00:00
// NewFundedGenStateWithSameCoins creates a (auth and bank) genesis state populated with accounts from the given addresses and balance.
func NewFundedGenStateWithSameCoins ( cdc codec . JSONCodec , balance sdk . Coins , addresses [ ] sdk . AccAddress ) GenesisState {
builder := NewAuthBankGenesisBuilder ( )
for _ , address := range addresses {
builder . WithSimpleAccount ( address , balance )
2021-06-10 13:35:44 +00:00
}
2022-01-08 00:39:27 +00:00
return builder . BuildMarshalled ( cdc )
2021-06-10 13:35:44 +00:00
}
2022-01-08 00:39:27 +00:00
// NewFundedGenStateWithCoins creates a (auth and bank) genesis state populated with accounts from the given addresses and coins.
func NewFundedGenStateWithCoins ( cdc codec . JSONCodec , coins [ ] sdk . Coins , addresses [ ] sdk . AccAddress ) GenesisState {
builder := NewAuthBankGenesisBuilder ( )
for i , address := range addresses {
builder . WithSimpleAccount ( address , coins [ i ] )
2021-06-10 13:35:44 +00:00
}
2022-01-08 00:39:27 +00:00
return builder . BuildMarshalled ( cdc )
2021-06-10 13:35:44 +00:00
}
2022-01-08 00:39:27 +00:00
// NewFundedGenStateWithSameCoinsWithModuleAccount creates a (auth and bank) genesis state populated with accounts from the given addresses and balance along with an empty module account
func NewFundedGenStateWithSameCoinsWithModuleAccount ( cdc codec . JSONCodec , coins sdk . Coins , addresses [ ] sdk . AccAddress , modAcc * authtypes . ModuleAccount ) GenesisState {
builder := NewAuthBankGenesisBuilder ( )
2021-06-10 13:35:44 +00:00
2022-01-08 00:39:27 +00:00
for _ , address := range addresses {
builder . WithSimpleAccount ( address , coins )
2021-06-10 13:35:44 +00:00
}
2022-01-08 00:39:27 +00:00
builder . WithSimpleModuleAccount ( modAcc . Address , nil )
2021-06-10 13:35:44 +00:00
2022-01-08 00:39:27 +00:00
return builder . BuildMarshalled ( cdc )
2021-06-10 13:35:44 +00:00
}