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

Add some helpers for testing to its own package in app (backport #1008) #1056

Merged
merged 1 commit into from
Mar 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 101 additions & 0 deletions app/apptesting/test_suite.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package apptesting

import (
"fmt"
"time"

"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
"github.com/cosmos/cosmos-sdk/simapp"

abci "github.com/tendermint/tendermint/abci/types"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"

sdk "github.com/cosmos/cosmos-sdk/types"
slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
"github.com/cosmos/cosmos-sdk/x/staking/teststaking"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"

"github.com/osmosis-labs/osmosis/v7/app"
"github.com/stretchr/testify/suite"
)

// TODO: Consider an embedded struct here rather than an interface
type SuiteI interface {
GetSuite() *suite.Suite
GetCtx() sdk.Context
SetCtx(sdk.Context)
GetApp() *app.OsmosisApp
}

func SetupValidator(suite SuiteI, bondStatus stakingtypes.BondStatus) sdk.ValAddress {
valPub := secp256k1.GenPrivKey().PubKey()
valAddr := sdk.ValAddress(valPub.Address())
bondDenom := suite.GetApp().StakingKeeper.GetParams(suite.GetCtx()).BondDenom
selfBond := sdk.NewCoins(sdk.Coin{Amount: sdk.NewInt(100), Denom: bondDenom})

err := simapp.FundAccount(suite.GetApp().BankKeeper, suite.GetCtx(), sdk.AccAddress(valAddr), selfBond)
suite.GetSuite().Require().NoError(err)
sh := teststaking.NewHelper(suite.GetSuite().T(), suite.GetCtx(), *suite.GetApp().StakingKeeper)
msg := sh.CreateValidatorMsg(valAddr, valPub, selfBond[0].Amount)
sh.Handle(msg, true)
val, found := suite.GetApp().StakingKeeper.GetValidator(suite.GetCtx(), valAddr)
suite.GetSuite().Require().True(found)
val = val.UpdateStatus(bondStatus)
suite.GetApp().StakingKeeper.SetValidator(suite.GetCtx(), val)

consAddr, err := val.GetConsAddr()
suite.GetSuite().Require().NoError(err)
signingInfo := slashingtypes.NewValidatorSigningInfo(
consAddr,
suite.GetCtx().BlockHeight(),
0,
time.Unix(0, 0),
false,
0,
)
suite.GetApp().SlashingKeeper.SetValidatorSigningInfo(suite.GetCtx(), consAddr, signingInfo)

return valAddr
}

func BeginNewBlock(suite SuiteI, executeNextEpoch bool) {
valAddr := []byte(":^) at this distribution workaround")
validators := suite.GetApp().StakingKeeper.GetAllValidators(suite.GetCtx())
if len(validators) >= 1 {
valAddrFancy, err := validators[0].GetConsAddr()
suite.GetSuite().Require().NoError(err)
valAddr = valAddrFancy.Bytes()
} else {
valAddrFancy := SetupValidator(suite, stakingtypes.Bonded)
validator, _ := suite.GetApp().StakingKeeper.GetValidator(suite.GetCtx(), valAddrFancy)
valAddr2, _ := validator.GetConsAddr()
valAddr = valAddr2.Bytes()
}

epochIdentifier := suite.GetApp().SuperfluidKeeper.GetEpochIdentifier(suite.GetCtx())
epoch := suite.GetApp().EpochsKeeper.GetEpochInfo(suite.GetCtx(), epochIdentifier)
newBlockTime := suite.GetCtx().BlockTime().Add(5 * time.Second)
if executeNextEpoch {
endEpochTime := epoch.CurrentEpochStartTime.Add(epoch.Duration)
newBlockTime = endEpochTime.Add(time.Second)
}
// fmt.Println(executeNextEpoch, suite.ctx.BlockTime(), newBlockTime)
header := tmproto.Header{Height: suite.GetCtx().BlockHeight() + 1, Time: newBlockTime}
newCtx := suite.GetCtx().WithBlockTime(newBlockTime).WithBlockHeight(suite.GetCtx().BlockHeight() + 1)
suite.SetCtx(newCtx)
lastCommitInfo := abci.LastCommitInfo{
Votes: []abci.VoteInfo{{
Validator: abci.Validator{Address: valAddr, Power: 1000},
SignedLastBlock: true},
},
}
reqBeginBlock := abci.RequestBeginBlock{Header: header, LastCommitInfo: lastCommitInfo}

fmt.Println("beginning block ", suite.GetCtx().BlockHeight())
suite.GetApp().BeginBlocker(suite.GetCtx(), reqBeginBlock)
}

func EndBlock(suite SuiteI) {
reqEndBlock := abci.RequestEndBlock{Height: suite.GetCtx().BlockHeight()}
suite.GetApp().EndBlocker(suite.GetCtx(), reqEndBlock)
}
4 changes: 3 additions & 1 deletion x/superfluid/keeper/hooks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"github.com/cosmos/cosmos-sdk/simapp"
sdk "github.com/cosmos/cosmos-sdk/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
"github.com/osmosis-labs/osmosis/v7/app/apptesting"
"github.com/tendermint/tendermint/crypto/ed25519"
)

Expand Down Expand Up @@ -44,7 +45,7 @@ func (suite *KeeperTestSuite) TestSuperfluidAfterEpochEnd() {
suite.Require().NoError(err)

// run epoch actions
suite.BeginNewBlock(true)
apptesting.BeginNewBlock(suite, true)

// check lptoken twap value set
newEpochTwap := suite.app.SuperfluidKeeper.GetOsmoEquivalentMultiplier(suite.ctx, "gamm/pool/1")
Expand All @@ -58,6 +59,7 @@ func (suite *KeeperTestSuite) TestSuperfluidAfterEpochEnd() {
suite.Require().True(found)
suite.Require().Equal(sdk.NewDec(5000), delegation.Shares)
// TODO: Check reward distribution
// suite.Require().NotEqual(sdk.Coins{}, )
}
})
}
Expand Down
91 changes: 48 additions & 43 deletions x/superfluid/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,22 @@ import (
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/simapp"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/staking/teststaking"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
"github.com/osmosis-labs/osmosis/v7/app"
"github.com/osmosis-labs/osmosis/v7/app/apptesting"
"github.com/osmosis-labs/osmosis/v7/x/superfluid/types"
"github.com/stretchr/testify/suite"
abci "github.com/tendermint/tendermint/abci/types"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"

"github.com/osmosis-labs/osmosis/v7/x/gamm/pool-models/balancer"
gammtypes "github.com/osmosis-labs/osmosis/v7/x/gamm/types"
"github.com/tendermint/tendermint/crypto/ed25519"

lockupkeeper "github.com/osmosis-labs/osmosis/v7/x/lockup/keeper"
lockuptypes "github.com/osmosis-labs/osmosis/v7/x/lockup/types"

"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
epochtypes "github.com/osmosis-labs/osmosis/v7/x/epochs/types"
gammtypes "github.com/osmosis-labs/osmosis/v7/x/gamm/types"
lockuptypes "github.com/osmosis-labs/osmosis/v7/x/lockup/types"
minttypes "github.com/osmosis-labs/osmosis/v7/x/mint/types"
)

type KeeperTestSuite struct {
Expand All @@ -33,6 +33,19 @@ type KeeperTestSuite struct {
app *app.OsmosisApp
}

func (suite *KeeperTestSuite) GetSuite() *suite.Suite {
return &suite.Suite
}
func (suite *KeeperTestSuite) GetCtx() sdk.Context {
return suite.ctx
}
func (suite *KeeperTestSuite) GetApp() *app.OsmosisApp {
return suite.app
}
func (suite *KeeperTestSuite) SetCtx(ctx sdk.Context) {
suite.ctx = ctx
}

func (suite *KeeperTestSuite) SetupTest() {
suite.app = app.Setup(false)

Expand All @@ -53,6 +66,35 @@ func (suite *KeeperTestSuite) SetupTest() {
time.Hour * 7,
unbondingDuration,
})

// TODO: Revisit if this is needed, it was added due to another bug in testing that is now fixed.
epochIdentifier := suite.app.SuperfluidKeeper.GetEpochIdentifier(suite.ctx)
suite.app.EpochsKeeper.SetEpochInfo(suite.ctx, epochtypes.EpochInfo{
Identifier: epochIdentifier,
StartTime: startTime,
Duration: time.Hour,
CurrentEpochStartTime: startTime,
CurrentEpochStartHeight: 1,
CurrentEpoch: 1,
EpochCountingStarted: true,
})

mintParams := suite.app.MintKeeper.GetParams(suite.ctx)
mintParams.EpochIdentifier = epochIdentifier
mintParams.DistributionProportions = minttypes.DistributionProportions{
Staking: sdk.OneDec(),
PoolIncentives: sdk.ZeroDec(),
DeveloperRewards: sdk.ZeroDec(),
CommunityPool: sdk.ZeroDec(),
}
suite.app.MintKeeper.SetParams(suite.ctx, mintParams)
suite.app.MintKeeper.SetMinter(suite.ctx, minttypes.NewMinter(sdk.NewDec(1_000_000)))

distributionParams := suite.app.DistrKeeper.GetParams(suite.ctx)
distributionParams.BaseProposerReward = sdk.ZeroDec()
distributionParams.BonusProposerReward = sdk.ZeroDec()
distributionParams.CommunityTax = sdk.ZeroDec()
suite.app.DistrKeeper.SetParams(suite.ctx, distributionParams)
}

func (suite *KeeperTestSuite) SetupDefaultPool() {
Expand All @@ -61,25 +103,6 @@ func (suite *KeeperTestSuite) SetupDefaultPool() {
suite.Require().Equal(poolId, uint64(1))
}

func (suite *KeeperTestSuite) BeginNewBlock(executeNextEpoch bool) {
epochIdentifier := suite.app.SuperfluidKeeper.GetEpochIdentifier(suite.ctx)
epoch := suite.app.EpochsKeeper.GetEpochInfo(suite.ctx, epochIdentifier)
newBlockTime := suite.ctx.BlockTime().Add(5 * time.Second)
if executeNextEpoch {
endEpochTime := epoch.CurrentEpochStartTime.Add(epoch.Duration)
newBlockTime = endEpochTime.Add(time.Second)
}
header := tmproto.Header{Height: suite.ctx.BlockHeight() + 1, Time: newBlockTime}
reqBeginBlock := abci.RequestBeginBlock{Header: header}
suite.app.BeginBlocker(suite.ctx, reqBeginBlock)

}

func (suite *KeeperTestSuite) EndBlock() {
reqEndBlock := abci.RequestEndBlock{Height: suite.ctx.BlockHeight()}
suite.app.EndBlocker(suite.ctx, reqEndBlock)
}

// CreateRandomAccounts is a function return a list of randomly generated AccAddresses
func CreateRandomAccounts(numAccts int) []sdk.AccAddress {
testAddrs := make([]sdk.AccAddress, numAccts)
Expand Down Expand Up @@ -125,28 +148,10 @@ func (suite *KeeperTestSuite) LockTokens(addr sdk.AccAddress, coins sdk.Coins, d
return msgResponse.ID
}

func (suite *KeeperTestSuite) SetupValidator(bondStatus stakingtypes.BondStatus) sdk.ValAddress {
valPub := secp256k1.GenPrivKey().PubKey()
valAddr := sdk.ValAddress(valPub.Address())
bondDenom := suite.app.StakingKeeper.GetParams(suite.ctx).BondDenom
selfBond := sdk.NewCoins(sdk.Coin{Amount: sdk.NewInt(100), Denom: bondDenom})

simapp.FundAccount(suite.app.BankKeeper, suite.ctx, sdk.AccAddress(valAddr), selfBond)
sh := teststaking.NewHelper(suite.T(), suite.ctx, *suite.app.StakingKeeper)
msg := sh.CreateValidatorMsg(valAddr, valPub, selfBond[0].Amount)
sh.Handle(msg, true)
val, found := suite.app.StakingKeeper.GetValidator(suite.ctx, valAddr)
suite.Require().True(found)
val = val.UpdateStatus(bondStatus)
suite.app.StakingKeeper.SetValidator(suite.ctx, val)

return valAddr
}

func (suite *KeeperTestSuite) SetupValidators(bondStatuses []stakingtypes.BondStatus) []sdk.ValAddress {
valAddrs := []sdk.ValAddress{}
for _, status := range bondStatuses {
valAddr := suite.SetupValidator(status)
valAddr := apptesting.SetupValidator(suite, status)
valAddrs = append(valAddrs, valAddr)
}
return valAddrs
Expand Down