update cdp keeper tests

This commit is contained in:
rhuairahrighairigh 2019-12-03 14:35:27 +00:00
parent 6f3cb815a2
commit ce2b2e2213
6 changed files with 136 additions and 191 deletions

View File

@ -41,6 +41,7 @@ import (
// So TestApp.InitializeFromGenesisStates() will call InitGenesis with the default genesis state. // 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 // 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. // Creating the genesis states can be combersome, but helper methods can make it easier such as NewAuthGenStateFromAccounts below.
//
type TestApp struct { type TestApp struct {
App App
} }

View File

@ -1,19 +1,19 @@
package keeper package keeper_test
import ( import (
"testing" "testing"
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
authexported "github.com/cosmos/cosmos-sdk/x/auth/exported"
"github.com/cosmos/cosmos-sdk/x/mock"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types" abci "github.com/tendermint/tendermint/abci/types"
"github.com/kava-labs/kava/app"
keep "github.com/kava-labs/kava/x/cdp/keeper"
) )
// Test the bank functionality of the CDP keeper // Test the bank functionality of the CDP keeper
func TestKeeper_AddSubtractGetCoins(t *testing.T) { func TestKeeper_AddSubtractGetCoins(t *testing.T) {
_, addrs := mock.GeneratePrivKeyAddressPairs(1) _, addrs := app.GeneratePrivKeyAddressPairs(1)
normalAddr := addrs[0] normalAddr := addrs[0]
tests := []struct { tests := []struct {
@ -25,28 +25,23 @@ func TestKeeper_AddSubtractGetCoins(t *testing.T) {
}{ }{
{"addNormalAddress", normalAddr, true, cs(c("usdx", 53)), cs(c("usdx", 153), c("kava", 100))}, {"addNormalAddress", normalAddr, true, cs(c("usdx", 53)), cs(c("usdx", 153), c("kava", 100))},
{"subNormalAddress", normalAddr, false, cs(c("usdx", 53)), cs(c("usdx", 47), c("kava", 100))}, {"subNormalAddress", normalAddr, false, cs(c("usdx", 53)), cs(c("usdx", 47), c("kava", 100))},
{"addLiquidatorStable", LiquidatorAccountAddress, true, cs(c("usdx", 53)), cs(c("usdx", 153))}, {"addLiquidatorStable", keep.LiquidatorAccountAddress, true, cs(c("usdx", 53)), cs(c("usdx", 153))},
{"subLiquidatorStable", LiquidatorAccountAddress, false, cs(c("usdx", 53)), cs(c("usdx", 47))}, {"subLiquidatorStable", keep.LiquidatorAccountAddress, false, cs(c("usdx", 53)), cs(c("usdx", 47))},
{"addLiquidatorGov", LiquidatorAccountAddress, true, cs(c("kava", 53)), cs(c("usdx", 100))}, // no change to balance {"addLiquidatorGov", keep.LiquidatorAccountAddress, true, cs(c("kava", 53)), cs(c("usdx", 100))}, // no change to balance
{"subLiquidatorGov", LiquidatorAccountAddress, false, cs(c("kava", 53)), cs(c("usdx", 100))}, // no change to balance {"subLiquidatorGov", keep.LiquidatorAccountAddress, false, cs(c("kava", 53)), cs(c("usdx", 100))}, // no change to balance
} }
for _, tc := range tests { for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
// setup keeper // setup app with an account
mapp, keeper, _, _ := setUpMockAppWithoutGenesis() tApp := app.NewTestApp()
// initialize an account with coins authGenState := tApp.NewAuthGenStateFromAccounts([]sdk.AccAddress{normalAddr}, []sdk.Coins{cs(c("usdx", 100), c("kava", 100))})
genAcc := auth.BaseAccount{ tApp.InitializeFromGenesisStates(authGenState)
Address: normalAddr,
Coins: cs(c("usdx", 100), c("kava", 100)),
}
mock.SetGenesis(mapp, []authexported.Account{&genAcc})
// create a new context and setup the liquidator account // create a new context and setup the liquidator account
header := abci.Header{Height: mapp.LastBlockHeight() + 1} ctx := tApp.NewContext(false, abci.Header{})
mapp.BeginBlock(abci.RequestBeginBlock{Header: header}) keeper := tApp.GetCDPKeeper()
ctx := mapp.BaseApp.NewContext(false, header) keeper.SetLiquidatorModuleAccount(ctx, keep.LiquidatorModuleAccount{cs(c("usdx", 100))}) // set gov coin "balance" to zero
keeper.setLiquidatorModuleAccount(ctx, LiquidatorModuleAccount{cs(c("usdx", 100))}) // set gov coin "balance" to zero
// perform the test action // perform the test action
var err sdk.Error var err sdk.Error
@ -56,9 +51,6 @@ func TestKeeper_AddSubtractGetCoins(t *testing.T) {
_, err = keeper.SubtractCoins(ctx, tc.address, tc.amount) _, err = keeper.SubtractCoins(ctx, tc.address, tc.amount)
} }
mapp.EndBlock(abci.RequestEndBlock{})
mapp.Commit()
// check balances are as expected // check balances are as expected
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, tc.expectedCoins, keeper.GetCoins(ctx, tc.address)) require.Equal(t, tc.expectedCoins, keeper.GetCoins(ctx, tc.address))

View File

@ -0,0 +1,46 @@
package keeper_test
import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/kava-labs/kava/x/cdp/types"
)
// Avoid cluttering test cases with long function name
func i(in int64) sdk.Int { return sdk.NewInt(in) }
func d(str string) sdk.Dec { return sdk.MustNewDecFromStr(str) }
func c(denom string, amount int64) sdk.Coin { return sdk.NewInt64Coin(denom, amount) }
func cs(coins ...sdk.Coin) sdk.Coins { return sdk.NewCoins(coins...) }
func defaultParamsMulti() types.CdpParams {
return types.CdpParams{
GlobalDebtLimit: sdk.NewInt(1000000),
CollateralParams: []types.CollateralParams{
{
Denom: "btc",
LiquidationRatio: sdk.MustNewDecFromStr("1.5"),
DebtLimit: sdk.NewInt(500000),
},
{
Denom: "xrp",
LiquidationRatio: sdk.MustNewDecFromStr("2.0"),
DebtLimit: sdk.NewInt(500000),
},
},
StableDenoms: []string{"usdx"},
}
}
func defaultParamsSingle() types.CdpParams {
return types.CdpParams{
GlobalDebtLimit: sdk.NewInt(1000000),
CollateralParams: []types.CollateralParams{
{
Denom: "xrp",
LiquidationRatio: sdk.MustNewDecFromStr("2.0"),
DebtLimit: sdk.NewInt(500000),
},
},
StableDenoms: []string{"usdx"},
}
}

View File

@ -126,13 +126,13 @@ func (k Keeper) ModifyCDP(ctx sdk.Context, owner sdk.AccAddress, collateralDenom
} }
// Set CDP // Set CDP
if cdp.CollateralAmount.IsZero() && cdp.Debt.IsZero() { // TODO maybe abstract this logic into SetCDP if cdp.CollateralAmount.IsZero() && cdp.Debt.IsZero() { // TODO maybe abstract this logic into SetCDP
k.deleteCDP(ctx, cdp) k.DeleteCDP(ctx, cdp)
} else { } else {
k.SetCDP(ctx, cdp) k.SetCDP(ctx, cdp)
} }
// set total debts // set total debts
k.SetGlobalDebt(ctx, gDebt) k.SetGlobalDebt(ctx, gDebt)
k.setCollateralState(ctx, collateralState) k.SetCollateralState(ctx, collateralState)
return nil return nil
} }
@ -195,11 +195,11 @@ func (k Keeper) PartialSeizeCDP(ctx sdk.Context, owner sdk.AccAddress, collatera
// Store updated state // Store updated state
if cdp.CollateralAmount.IsZero() && cdp.Debt.IsZero() { // TODO maybe abstract this logic into SetCDP if cdp.CollateralAmount.IsZero() && cdp.Debt.IsZero() { // TODO maybe abstract this logic into SetCDP
k.deleteCDP(ctx, cdp) k.DeleteCDP(ctx, cdp)
} else { } else {
k.SetCDP(ctx, cdp) k.SetCDP(ctx, cdp)
} }
k.setCollateralState(ctx, collateralState) k.SetCollateralState(ctx, collateralState)
return nil return nil
} }
@ -264,7 +264,7 @@ func (k Keeper) SetCDP(ctx sdk.Context, cdp types.CDP) {
bz := k.cdc.MustMarshalBinaryLengthPrefixed(cdp) bz := k.cdc.MustMarshalBinaryLengthPrefixed(cdp)
store.Set(k.getCDPKey(cdp.Owner, cdp.CollateralDenom), bz) store.Set(k.getCDPKey(cdp.Owner, cdp.CollateralDenom), bz)
} }
func (k Keeper) deleteCDP(ctx sdk.Context, cdp types.CDP) { // TODO should this id the cdp by passing in owner,collateralDenom pair? func (k Keeper) DeleteCDP(ctx sdk.Context, cdp types.CDP) { // TODO should this id the cdp by passing in owner,collateralDenom pair?
// get store // get store
store := ctx.KVStore(k.key) store := ctx.KVStore(k.key)
// delete key // delete key
@ -354,7 +354,7 @@ func (k Keeper) GetCollateralState(ctx sdk.Context, collateralDenom string) (typ
k.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &collateralState) k.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &collateralState)
return collateralState, true return collateralState, true
} }
func (k Keeper) setCollateralState(ctx sdk.Context, collateralstate types.CollateralState) { func (k Keeper) SetCollateralState(ctx sdk.Context, collateralstate types.CollateralState) {
// get store // get store
store := ctx.KVStore(k.key) store := ctx.KVStore(k.key)
// marshal and set // marshal and set
@ -422,7 +422,7 @@ func (k Keeper) AddCoins(ctx sdk.Context, address sdk.AccAddress, amount sdk.Coi
return amount, sdk.ErrInsufficientCoins(fmt.Sprintf("insufficient account funds; %s < %s", lma.Coins, amount)) return amount, sdk.ErrInsufficientCoins(fmt.Sprintf("insufficient account funds; %s < %s", lma.Coins, amount))
} }
lma.Coins = updatedCoins lma.Coins = updatedCoins
k.setLiquidatorModuleAccount(ctx, lma) k.SetLiquidatorModuleAccount(ctx, lma)
return updatedCoins, nil return updatedCoins, nil
} else { } else {
return k.bankKeeper.AddCoins(ctx, address, amount) return k.bankKeeper.AddCoins(ctx, address, amount)
@ -445,7 +445,7 @@ func (k Keeper) SubtractCoins(ctx sdk.Context, address sdk.AccAddress, amount sd
return amount, sdk.ErrInsufficientCoins(fmt.Sprintf("insufficient account funds; %s < %s", lma.Coins, amount)) return amount, sdk.ErrInsufficientCoins(fmt.Sprintf("insufficient account funds; %s < %s", lma.Coins, amount))
} }
lma.Coins = updatedCoins lma.Coins = updatedCoins
k.setLiquidatorModuleAccount(ctx, lma) k.SetLiquidatorModuleAccount(ctx, lma)
return updatedCoins, nil return updatedCoins, nil
} else { } else {
return k.bankKeeper.SubtractCoins(ctx, address, amount) return k.bankKeeper.SubtractCoins(ctx, address, amount)
@ -483,7 +483,7 @@ func (k Keeper) getLiquidatorModuleAccount(ctx sdk.Context) LiquidatorModuleAcco
k.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &lma) k.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &lma)
return lma return lma
} }
func (k Keeper) setLiquidatorModuleAccount(ctx sdk.Context, lma LiquidatorModuleAccount) { func (k Keeper) SetLiquidatorModuleAccount(ctx sdk.Context, lma LiquidatorModuleAccount) {
store := ctx.KVStore(k.key) store := ctx.KVStore(k.key)
bz := k.cdc.MustMarshalBinaryLengthPrefixed(lma) bz := k.cdc.MustMarshalBinaryLengthPrefixed(lma)
store.Set(liquidatorAccountKey, bz) store.Set(liquidatorAccountKey, bz)

View File

@ -1,27 +1,26 @@
package keeper package keeper_test
import ( import (
"fmt" "fmt"
"testing" "testing"
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
authexported "github.com/cosmos/cosmos-sdk/x/auth/exported"
"github.com/cosmos/cosmos-sdk/x/mock"
"github.com/kava-labs/kava/x/cdp/types"
"github.com/kava-labs/kava/x/pricefeed"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types" abci "github.com/tendermint/tendermint/abci/types"
"github.com/kava-labs/kava/app"
"github.com/kava-labs/kava/x/cdp/types"
"github.com/kava-labs/kava/x/pricefeed"
) )
// How could one reduce the number of params in the test cases. Create a table driven test for each of the 4 add/withdraw collateral/debt? // How could one reduce the number of params in the test cases. Create a table driven test for each of the 4 add/withdraw collateral/debt?
// These are more like app level tests - I think this is a symptom of having 'ModifyCDP' do a lot. Could be easier for testing purposes to break it down. // These are more like app level tests - I think this is a symptom of having 'ModifyCDP' do a lot. Could be easier for testing purposes to break it down.
func TestKeeper_ModifyCDP(t *testing.T) { func TestKeeper_ModifyCDP(t *testing.T) {
_, addrs := mock.GeneratePrivKeyAddressPairs(1) _, addrs := app.GeneratePrivKeyAddressPairs(1)
ownerAddr := addrs[0] ownerAddr := addrs[0]
type state struct { // TODO this allows invalid state to be set up, should it? type state struct {
CDP types.CDP CDP types.CDP
OwnerCoins sdk.Coins OwnerCoins sdk.Coins
GlobalDebt sdk.Int GlobalDebt sdk.Int
@ -95,26 +94,24 @@ func TestKeeper_ModifyCDP(t *testing.T) {
for _, tc := range tests { for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
// setup keeper // setup keeper
mapp, keeper, _, _ := setUpMockAppWithoutGenesis() tApp := app.NewTestApp()
// initialize cdp owner account with coins // initialize cdp owner account with coins
genAcc := auth.BaseAccount{ authGen := tApp.NewAuthGenStateFromAccounts([]sdk.AccAddress{ownerAddr}, []sdk.Coins{tc.priorState.OwnerCoins})
Address: ownerAddr, tApp.InitializeFromGenesisStates(authGen)
Coins: tc.priorState.OwnerCoins, // create a context for db access
} ctx := tApp.NewContext(false, abci.Header{})
mock.SetGenesis(mapp, []authexported.Account{&genAcc})
// create a new context
header := abci.Header{Height: mapp.LastBlockHeight() + 1}
mapp.BeginBlock(abci.RequestBeginBlock{Header: header})
ctx := mapp.BaseApp.NewContext(false, header)
keeper.SetParams(ctx, defaultParamsSingle())
// setup store state // setup store state
keeper := tApp.GetCDPKeeper()
keeper.SetParams(ctx, defaultParamsSingle())
pricefeedKeeper := tApp.GetPriceFeedKeeper()
ap := pricefeed.AssetParams{ ap := pricefeed.AssetParams{
Assets: []pricefeed.Asset{ Assets: []pricefeed.Asset{
pricefeed.Asset{AssetCode: "xrp", Description: ""}, pricefeed.Asset{AssetCode: "xrp", Description: ""},
}, },
} }
keeper.pricefeedKeeper.SetAssetParams(ctx, ap) pricefeedKeeper.SetAssetParams(ctx, ap)
_, err := keeper.pricefeedKeeper.SetPrice( _, err := pricefeedKeeper.SetPrice(
ctx, ownerAddr, "xrp", ctx, ownerAddr, "xrp",
sdk.MustNewDecFromStr(tc.price), sdk.MustNewDecFromStr(tc.price),
sdk.NewInt(ctx.BlockHeight()+10)) sdk.NewInt(ctx.BlockHeight()+10))
@ -123,7 +120,7 @@ func TestKeeper_ModifyCDP(t *testing.T) {
t.Log(err) t.Log(err)
t.Log(tc.name) t.Log(tc.name)
} }
err = keeper.pricefeedKeeper.SetCurrentPrices(ctx) err = pricefeedKeeper.SetCurrentPrices(ctx)
if err != nil { if err != nil {
t.Log("test context height", ctx.BlockHeight()) t.Log("test context height", ctx.BlockHeight())
t.Log(err) t.Log(err)
@ -134,20 +131,17 @@ func TestKeeper_ModifyCDP(t *testing.T) {
} }
keeper.SetGlobalDebt(ctx, tc.priorState.GlobalDebt) keeper.SetGlobalDebt(ctx, tc.priorState.GlobalDebt)
if tc.priorState.CollateralState.Denom != "" { if tc.priorState.CollateralState.Denom != "" {
keeper.setCollateralState(ctx, tc.priorState.CollateralState) keeper.SetCollateralState(ctx, tc.priorState.CollateralState)
} }
// call func under test // call func under test
err = keeper.ModifyCDP(ctx, tc.args.owner, tc.args.collateralDenom, tc.args.changeInCollateral, tc.args.changeInDebt) err = keeper.ModifyCDP(ctx, tc.args.owner, tc.args.collateralDenom, tc.args.changeInCollateral, tc.args.changeInDebt)
mapp.EndBlock(abci.RequestEndBlock{})
mapp.Commit()
// get new state for verification // get new state for verification
actualCDP, found := keeper.GetCDP(ctx, tc.args.owner, tc.args.collateralDenom) actualCDP, found := keeper.GetCDP(ctx, tc.args.owner, tc.args.collateralDenom)
if tc.name == "removeTooMuchCollateral" { if tc.name == "removeTooMuchCollateral" {
t.Log(actualCDP.String()) t.Log(actualCDP.String())
} }
// check for err // check for err
if tc.expectPass { if tc.expectPass {
require.NoError(t, err, fmt.Sprint(err)) require.NoError(t, err, fmt.Sprint(err))
@ -166,45 +160,48 @@ func TestKeeper_ModifyCDP(t *testing.T) {
require.Equal(t, tc.expectedState.GlobalDebt, actualGDebt) require.Equal(t, tc.expectedState.GlobalDebt, actualGDebt)
require.Equal(t, tc.expectedState.CollateralState, actualCstate) require.Equal(t, tc.expectedState.CollateralState, actualCstate)
// check owner balance // check owner balance
mock.CheckBalance(t, mapp, ownerAddr, tc.expectedState.OwnerCoins) require.Equal(t, tc.expectedState.OwnerCoins, tApp.GetAccountKeeper().GetAccount(ctx, ownerAddr).GetCoins())
}) })
} }
} }
// TODO change to table driven test to test more test cases
func TestKeeper_PartialSeizeCDP(t *testing.T) { func TestKeeper_PartialSeizeCDP(t *testing.T) {
// Setup // Setup
const collateral = "xrp" const collateral = "xrp"
mapp, keeper, _, _ := setUpMockAppWithoutGenesis() _, addrs := app.GeneratePrivKeyAddressPairs(1)
genAccs, addrs, _, _ := mock.CreateGenAccounts(1, cs(c(collateral, 100)))
testAddr := addrs[0] testAddr := addrs[0]
mock.SetGenesis(mapp, genAccs)
tApp := app.NewTestApp()
authGenState := tApp.NewAuthGenStateFromAccounts(addrs, []sdk.Coins{cs(c(collateral, 100))})
tApp.InitializeFromGenesisStates(authGenState)
ctx := tApp.NewContext(false, abci.Header{})
keeper := tApp.GetCDPKeeper()
// setup pricefeed // setup pricefeed
header := abci.Header{Height: mapp.LastBlockHeight() + 1} pricefeedKeeper := tApp.GetPriceFeedKeeper()
mapp.BeginBlock(abci.RequestBeginBlock{Header: header})
ctx := mapp.BaseApp.NewContext(false, header)
keeper.SetParams(ctx, defaultParamsSingle())
ap := pricefeed.AssetParams{ ap := pricefeed.AssetParams{
Assets: []pricefeed.Asset{ Assets: []pricefeed.Asset{
pricefeed.Asset{AssetCode: "xrp", Description: ""}, pricefeed.Asset{AssetCode: collateral, Description: ""},
}, },
} }
keeper.pricefeedKeeper.SetAssetParams(ctx, ap) pricefeedKeeper.SetAssetParams(ctx, ap)
keeper.pricefeedKeeper.SetPrice( pricefeedKeeper.SetPrice(
ctx, sdk.AccAddress{}, collateral, ctx, sdk.AccAddress{}, collateral,
sdk.MustNewDecFromStr("1.00"), sdk.MustNewDecFromStr("1.00"),
i(10)) i(10))
keeper.pricefeedKeeper.SetCurrentPrices(ctx) require.NoError(t, pricefeedKeeper.SetCurrentPrices(ctx))
// Create CDP // Create CDP
keeper.SetGlobalDebt(ctx, i(0)) keeper.SetParams(ctx, defaultParamsSingle())
err := keeper.ModifyCDP(ctx, testAddr, collateral, i(10), i(5)) err := keeper.ModifyCDP(ctx, testAddr, collateral, i(10), i(5))
require.NoError(t, err) require.NoError(t, err)
// Reduce price // Reduce price
keeper.pricefeedKeeper.SetPrice( pricefeedKeeper.SetPrice(
ctx, sdk.AccAddress{}, collateral, ctx, sdk.AccAddress{}, collateral,
sdk.MustNewDecFromStr("0.90"), sdk.MustNewDecFromStr("0.90"),
i(10)) i(10))
keeper.pricefeedKeeper.SetCurrentPrices(ctx) require.NoError(t, pricefeedKeeper.SetCurrentPrices(ctx))
// Seize entire CDP // Seize entire CDP
err = keeper.PartialSeizeCDP(ctx, testAddr, collateral, i(10), i(5)) err = keeper.PartialSeizeCDP(ctx, testAddr, collateral, i(10), i(5))
@ -220,14 +217,12 @@ func TestKeeper_PartialSeizeCDP(t *testing.T) {
func TestKeeper_GetCDPs(t *testing.T) { func TestKeeper_GetCDPs(t *testing.T) {
// setup keeper // setup keeper
mapp, keeper, _, _ := setUpMockAppWithoutGenesis() tApp := app.NewTestApp()
mock.SetGenesis(mapp, []authexported.Account(nil)) ctx := tApp.NewContext(true, abci.Header{})
header := abci.Header{Height: mapp.LastBlockHeight() + 1} keeper := tApp.GetCDPKeeper()
mapp.BeginBlock(abci.RequestBeginBlock{Header: header})
ctx := mapp.BaseApp.NewContext(false, header)
keeper.SetParams(ctx, defaultParamsMulti()) keeper.SetParams(ctx, defaultParamsMulti())
// setup CDPs // setup CDPs
_, addrs := mock.GeneratePrivKeyAddressPairs(2) _, addrs := app.GeneratePrivKeyAddressPairs(2)
cdps := types.CDPs{ cdps := types.CDPs{
{addrs[0], "xrp", i(4000), i(5)}, {addrs[0], "xrp", i(4000), i(5)},
{addrs[1], "xrp", i(4000), i(2000)}, {addrs[1], "xrp", i(4000), i(2000)},
@ -285,7 +280,7 @@ func TestKeeper_GetCDPs(t *testing.T) {
_, err = keeper.GetCDPs(ctx, "", d("0.34023")) _, err = keeper.GetCDPs(ctx, "", d("0.34023"))
require.Error(t, err) require.Error(t, err)
// Check deleting a CDP removes it // Check deleting a CDP removes it
keeper.deleteCDP(ctx, cdps[0]) keeper.DeleteCDP(ctx, cdps[0])
returnedCdps, err = keeper.GetCDPs(ctx, "", sdk.Dec{}) returnedCdps, err = keeper.GetCDPs(ctx, "", sdk.Dec{})
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, require.Equal(t,
@ -295,14 +290,15 @@ func TestKeeper_GetCDPs(t *testing.T) {
returnedCdps, returnedCdps,
) )
} }
func TestKeeper_GetSetDeleteCDP(t *testing.T) { func TestKeeper_GetSetDeleteCDP(t *testing.T) {
// setup keeper, create CDP // setup keeper, create CDP
mapp, keeper, _, _ := setUpMockAppWithoutGenesis() tApp := app.NewTestApp()
header := abci.Header{Height: mapp.LastBlockHeight() + 1} ctx := tApp.NewContext(true, abci.Header{})
mapp.BeginBlock(abci.RequestBeginBlock{Header: header}) keeper := tApp.GetCDPKeeper()
ctx := mapp.BaseApp.NewContext(false, header)
keeper.SetParams(ctx, defaultParamsSingle()) keeper.SetParams(ctx, defaultParamsSingle())
_, addrs := mock.GeneratePrivKeyAddressPairs(1) _, addrs := app.GeneratePrivKeyAddressPairs(1)
cdp := types.CDP{addrs[0], "xrp", i(412), i(56)} cdp := types.CDP{addrs[0], "xrp", i(412), i(56)}
// write and read from store // write and read from store
@ -314,7 +310,7 @@ func TestKeeper_GetSetDeleteCDP(t *testing.T) {
require.Equal(t, cdp, readCDP) require.Equal(t, cdp, readCDP)
// delete auction // delete auction
keeper.deleteCDP(ctx, cdp) keeper.DeleteCDP(ctx, cdp)
// check auction does not exist // check auction does not exist
_, found = keeper.GetCDP(ctx, cdp.Owner, cdp.CollateralDenom) _, found = keeper.GetCDP(ctx, cdp.Owner, cdp.CollateralDenom)
@ -322,10 +318,9 @@ func TestKeeper_GetSetDeleteCDP(t *testing.T) {
} }
func TestKeeper_GetSetGDebt(t *testing.T) { func TestKeeper_GetSetGDebt(t *testing.T) {
// setup keeper, create GDebt // setup keeper, create GDebt
mapp, keeper, _, _ := setUpMockAppWithoutGenesis() tApp := app.NewTestApp()
header := abci.Header{Height: mapp.LastBlockHeight() + 1} ctx := tApp.NewContext(true, abci.Header{})
mapp.BeginBlock(abci.RequestBeginBlock{Header: header}) keeper := tApp.GetCDPKeeper()
ctx := mapp.BaseApp.NewContext(false, header)
keeper.SetParams(ctx, defaultParamsSingle()) keeper.SetParams(ctx, defaultParamsSingle())
gDebt := i(4120000) gDebt := i(4120000)
@ -339,15 +334,14 @@ func TestKeeper_GetSetGDebt(t *testing.T) {
func TestKeeper_GetSetCollateralState(t *testing.T) { func TestKeeper_GetSetCollateralState(t *testing.T) {
// setup keeper, create CState // setup keeper, create CState
mapp, keeper, _, _ := setUpMockAppWithoutGenesis() tApp := app.NewTestApp()
header := abci.Header{Height: mapp.LastBlockHeight() + 1} ctx := tApp.NewContext(true, abci.Header{})
mapp.BeginBlock(abci.RequestBeginBlock{Header: header}) keeper := tApp.GetCDPKeeper()
ctx := mapp.BaseApp.NewContext(false, header)
keeper.SetParams(ctx, defaultParamsSingle()) keeper.SetParams(ctx, defaultParamsSingle())
collateralState := types.CollateralState{"xrp", i(15400)} collateralState := types.CollateralState{"xrp", i(15400)}
// write and read from store // write and read from store
keeper.setCollateralState(ctx, collateralState) keeper.SetCollateralState(ctx, collateralState)
readCState, found := keeper.GetCollateralState(ctx, collateralState.Denom) readCState, found := keeper.GetCollateralState(ctx, collateralState.Denom)
// check before and after match // check before and after match

View File

@ -1,88 +0,0 @@
package keeper
import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/bank"
"github.com/cosmos/cosmos-sdk/x/mock"
"github.com/kava-labs/kava/x/cdp/types"
"github.com/kava-labs/kava/x/pricefeed"
"github.com/tendermint/tendermint/crypto"
)
// Mock app is an ABCI app with an in memory database.
// This function creates an app, setting up the keepers, routes, begin and end blockers.
// But leaves it to the tests to call InitChain (done by calling mock.SetGenesis)
// The app works by submitting ABCI messages.
// - InitChain sets up the app db from genesis.
// - BeginBlock starts the delivery of a new block
// - DeliverTx delivers a tx
// - EndBlock signals the end of a block
// - Commit ?
func setUpMockAppWithoutGenesis() (*mock.App, Keeper, []sdk.AccAddress, []crypto.PrivKey) {
// Create uninitialized mock app
mapp := mock.NewApp()
// Register codecs
types.RegisterCodec(mapp.Cdc)
// Create keepers
keyCDP := sdk.NewKVStoreKey("cdp")
keyPriceFeed := sdk.NewKVStoreKey(pricefeed.StoreKey)
pk := mapp.ParamsKeeper
priceFeedKeeper := pricefeed.NewKeeper(keyPriceFeed, mapp.Cdc, pk.Subspace(pricefeed.DefaultParamspace).WithKeyTable(pricefeed.ParamKeyTable()), pricefeed.DefaultCodespace)
blacklistedAddrs := make(map[string]bool)
bankKeeper := bank.NewBaseKeeper(mapp.AccountKeeper, pk.Subspace(bank.DefaultParamspace), bank.DefaultCodespace, blacklistedAddrs)
cdpKeeper := NewKeeper(mapp.Cdc, keyCDP, pk.Subspace(types.DefaultParamspace), priceFeedKeeper, bankKeeper)
// Mount and load the stores
err := mapp.CompleteSetup(keyPriceFeed, keyCDP)
if err != nil {
panic("mock app setup failed")
}
// Create a bunch (ie 10) of pre-funded accounts to use for tests
genAccs, addrs, _, privKeys := mock.CreateGenAccounts(10, sdk.NewCoins(sdk.NewInt64Coin("token1", 100), sdk.NewInt64Coin("token2", 100)))
mock.SetGenesis(mapp, genAccs)
return mapp, cdpKeeper, addrs, privKeys
}
// Avoid cluttering test cases with long function name
func i(in int64) sdk.Int { return sdk.NewInt(in) }
func d(str string) sdk.Dec { return sdk.MustNewDecFromStr(str) }
func c(denom string, amount int64) sdk.Coin { return sdk.NewInt64Coin(denom, amount) }
func cs(coins ...sdk.Coin) sdk.Coins { return sdk.NewCoins(coins...) }
func defaultParamsMulti() types.CdpParams {
return types.CdpParams{
GlobalDebtLimit: sdk.NewInt(1000000),
CollateralParams: []types.CollateralParams{
{
Denom: "btc",
LiquidationRatio: sdk.MustNewDecFromStr("1.5"),
DebtLimit: sdk.NewInt(500000),
},
{
Denom: "xrp",
LiquidationRatio: sdk.MustNewDecFromStr("2.0"),
DebtLimit: sdk.NewInt(500000),
},
},
StableDenoms: []string{"usdx"},
}
}
func defaultParamsSingle() types.CdpParams {
return types.CdpParams{
GlobalDebtLimit: sdk.NewInt(1000000),
CollateralParams: []types.CollateralParams{
{
Denom: "xrp",
LiquidationRatio: sdk.MustNewDecFromStr("2.0"),
DebtLimit: sdk.NewInt(500000),
},
},
StableDenoms: []string{"usdx"},
}
}