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

test: increase x/oracle unit test coverage (backport #798) #801

Merged
merged 1 commit into from
Apr 12, 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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
- [781](https://github.com/umee-network/umee/pull/781) Oracle module unit test cleanup.
- [782](https://github.com/umee-network/umee/pull/782) Add unit test to `x/oracle/types/denom.go` and `x/oracle/types/keys.go`.
- [786](https://github.com/umee-network/umee/pull/786) Add unit test to `x/oracle/...`.
- [798](https://github.com/umee-network/umee/pull/798) Increase `x/oracle` unit test coverage.

## [v2.0.0](https://github.com/umee-network/umee/releases/tag/v2.0.0) - 2022-04-06

Expand Down
1 change: 1 addition & 0 deletions x/oracle/keeper/msg_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ func (s *IntegrationTestSuite) TestMsgServer_AggregateExchangeRateVote() {
_, err = s.msgServer.AggregateExchangeRateVote(sdk.WrapSDKContext(ctx), voteMsg)
s.Require().NoError(err)
vote, err := s.app.OracleKeeper.GetAggregateExchangeRateVote(ctx, valAddr)
s.Require().Nil(err)
for _, v := range vote.ExchangeRateTuples {
s.Require().Contains(acceptListFlat, strings.ToLower(v.Denom))
}
Expand Down
21 changes: 21 additions & 0 deletions x/oracle/keeper/params_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package keeper_test

import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/umee-network/umee/v2/x/oracle/types"
)

func (s *IntegrationTestSuite) TestVoteThreshold() {
app, ctx := s.app, s.ctx

voteDec := app.OracleKeeper.VoteThreshold(ctx)
s.Require().Equal(sdk.MustNewDecFromStr("0.5"), voteDec)

newVoteTreshold := sdk.MustNewDecFromStr("0.6")
defaultParams := types.DefaultParams()
defaultParams.VoteThreshold = newVoteTreshold
app.OracleKeeper.SetParams(ctx, defaultParams)

voteThresholdDec := app.OracleKeeper.VoteThreshold(ctx)
s.Require().Equal(newVoteTreshold, voteThresholdDec)
}
8 changes: 6 additions & 2 deletions x/oracle/keeper/reward_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,9 @@ func (s *IntegrationTestSuite) TestRewardBallotWinners() {
s.Require().NoError(err)

var voteTargets []string
var voteTargetDenoms []string
params := s.app.OracleKeeper.GetParams(s.ctx)
for _, v := range params.AcceptList {
voteTargets = append(voteTargets, v.SymbolDenom)
voteTargetDenoms = append(voteTargetDenoms, v.BaseDenom)
}

votePeriodsPerWindow := sdk.NewDec((int64)(s.app.OracleKeeper.RewardDistributionWindow(s.ctx))).
Expand All @@ -38,3 +36,9 @@ func (s *IntegrationTestSuite) TestRewardBallotWinners() {
s.Require().Equal(sdk.NewDecFromInt(givingAmt.AmountOf(types.UmeeDenom)).QuoInt64(votePeriodsPerWindow).QuoInt64(3).TruncateInt(),
outstandingRewards.AmountOf(types.UmeeDenom))
}

func (s *IntegrationTestSuite) TestRewardBallotWinnersZeroPower() {
s.app.OracleKeeper.RewardBallotWinners(s.ctx, 0, 0, []string{}, map[string]types.Claim{valAddr.String(): {}})
outstandingRewardsDec := s.app.DistrKeeper.GetValidatorOutstandingRewardsCoins(s.ctx, valAddr)
s.Require().Equal("", outstandingRewardsDec.String())
}
84 changes: 84 additions & 0 deletions x/oracle/types/ballot_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -292,3 +292,87 @@ func TestPBStandardDeviation_Overflow(t *testing.T) {
expectedDevation := sdk.MustNewDecFromStr("871.862661203013097586")
require.Equal(t, expectedDevation, deviation)
}

func TestBallotMapToSlice(t *testing.T) {
valAddress := GenerateRandomValAddr(1)

pb := ExchangeRateBallot{
NewVoteForTally(
sdk.NewDec(1234),
UmeeSymbol,
valAddress[0],
2,
),
NewVoteForTally(
sdk.NewDec(12345),
UmeeSymbol,
valAddress[0],
1,
),
}

ballotSlice := BallotMapToSlice(map[string]ExchangeRateBallot{
UmeeDenom: pb,
IbcDenomAtom: pb,
})
require.Equal(t, []BallotDenom{{Ballot: pb, Denom: IbcDenomAtom}, {Ballot: pb, Denom: UmeeDenom}}, ballotSlice)
}

func TestExchangeRateBallotSwap(t *testing.T) {
valAddress := GenerateRandomValAddr(2)

voteTallies := []VoteForTally{
NewVoteForTally(
sdk.NewDec(1234),
UmeeSymbol,
valAddress[0],
2,
),
NewVoteForTally(
sdk.NewDec(12345),
UmeeSymbol,
valAddress[1],
1,
),
}

pb := ExchangeRateBallot{voteTallies[0], voteTallies[1]}

require.Equal(t, pb[0], voteTallies[0])
require.Equal(t, pb[1], voteTallies[1])
pb.Swap(1, 0)
require.Equal(t, pb[1], voteTallies[0])
require.Equal(t, pb[0], voteTallies[1])
}

func TestStandardDeviationUnsorted(t *testing.T) {
valAddress := GenerateRandomValAddr(1)
pb := ExchangeRateBallot{
NewVoteForTally(
sdk.NewDec(1234),
UmeeSymbol,
valAddress[0],
2,
),
NewVoteForTally(
sdk.NewDec(12),
UmeeSymbol,
valAddress[0],
1,
),
}

deviation, err := pb.StandardDeviation()
require.ErrorIs(t, err, ErrBallotNotSorted)
require.Equal(t, "0.000000000000000000", deviation.String())
}

func TestClaimMapToSlice(t *testing.T) {
valAddress := GenerateRandomValAddr(1)
claim := NewClaim(10, 1, 4, valAddress[0])
claimSlice := ClaimMapToSlice(map[string]Claim{
"testClaim": claim,
"anotherClaim": claim,
})
require.Equal(t, []Claim{claim, claim}, claimSlice)
}
14 changes: 14 additions & 0 deletions x/oracle/types/codec_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package types

import (
"testing"

"github.com/cosmos/cosmos-sdk/codec/types"
"github.com/stretchr/testify/require"
)

func TestRegisterInterfaces(t *testing.T) {
registry := types.NewInterfaceRegistry()
RegisterInterfaces(registry)
require.Equal(t, registry.ListAllInterfaces(), []string([]string{}))
}
22 changes: 21 additions & 1 deletion x/oracle/types/genesis_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package types

import (
"encoding/json"
"testing"

sdk "github.com/cosmos/cosmos-sdk/types"
Expand All @@ -9,7 +10,7 @@ import (

func TestGenesisValidation(t *testing.T) {
// Valid state
genState := DefaultGenesisState()
genState := NewGenesisState(DefaultParams(), []ExchangeRateTuple{}, []FeederDelegation{}, []MissCounter{}, []AggregateExchangeRatePrevote{}, []AggregateExchangeRateVote{})
require.NoError(t, ValidateGenesis(genState))

// Invalid Vote Period
Expand Down Expand Up @@ -57,3 +58,22 @@ func TestGenesisValidation(t *testing.T) {
genState.Params.AcceptList = DenomList{Denom{}}
require.Error(t, ValidateGenesis(genState))
}

func TestGetGenesisStateFromAppState(t *testing.T) {
emptyGenesis := GenesisState{
Params: Params{},
ExchangeRates: []ExchangeRateTuple{},
FeederDelegations: []FeederDelegation{},
MissCounters: []MissCounter{},
AggregateExchangeRatePrevotes: []AggregateExchangeRatePrevote{},
AggregateExchangeRateVotes: []AggregateExchangeRateVote{},
}

bz, err := json.Marshal(emptyGenesis)
require.Nil(t, err)

require.NotNil(t, GetGenesisStateFromAppState(ModuleCdc, map[string]json.RawMessage{
ModuleName: bz,
}))
require.NotNil(t, GetGenesisStateFromAppState(ModuleCdc, map[string]json.RawMessage{}))
}
139 changes: 106 additions & 33 deletions x/oracle/types/msgs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,27 @@ func TestMsgFeederDelegation(t *testing.T) {
sdk.AccAddress([]byte("addr2_______________")),
}

msgInvalidOperatorAddr := "invalid operator address (empty address string is not allowed): invalid address"
msgInvalidDelegatorAddr := "invalid delegate address (empty address string is not allowed): invalid address"

tests := []struct {
delegator sdk.ValAddress
delegate sdk.AccAddress
expectPass bool
delegator sdk.ValAddress
delegate sdk.AccAddress
expectPass bool
expectedErrorMsg string
}{
{sdk.ValAddress(addrs[0]), addrs[1], true},
{sdk.ValAddress{}, addrs[1], false},
{sdk.ValAddress(addrs[0]), sdk.AccAddress{}, false},
{nil, nil, false},
{sdk.ValAddress(addrs[0]), addrs[1], true, "test should pass"},
{sdk.ValAddress{}, addrs[1], false, msgInvalidOperatorAddr},
{sdk.ValAddress(addrs[0]), sdk.AccAddress{}, false, msgInvalidDelegatorAddr},
{nil, nil, false, msgInvalidOperatorAddr},
}

for i, tc := range tests {
msg := NewMsgDelegateFeedConsent(tc.delegator, tc.delegate)
if tc.expectPass {
require.Nil(t, msg.ValidateBasic(), "test: %v", i)
} else {
require.NotNil(t, msg.ValidateBasic(), "test: %v", i)
require.ErrorContainsf(t, msg.ValidateBasic(), tc.expectedErrorMsg, "test: %v", i)
}
}
}
Expand All @@ -41,25 +45,32 @@ func TestMsgAggregateExchangeRatePrevote(t *testing.T) {

exchangeRates := sdk.DecCoins{sdk.NewDecCoinFromDec(UmeeDenom, sdk.OneDec()), sdk.NewDecCoinFromDec(UmeeDenom, sdk.NewDecWithPrec(32121, 1))}
bz := GetAggregateVoteHash("1", exchangeRates.String(), sdk.ValAddress(addrs[0]))
msgInvalidHashLength := "invalid hash length; should equal 20"
msgInvalidFeederAddr := "invalid feeder address (empty address string is not allowed): invalid address"
msgInvalidOperatorAddr := "invalid operator address (empty address string is not allowed): invalid address"

tests := []struct {
hash AggregateVoteHash
exchangeRates sdk.DecCoins
voter sdk.AccAddress
expectPass bool
hash AggregateVoteHash
exchangeRates sdk.DecCoins
feeder sdk.AccAddress
validator sdk.AccAddress
expectPass bool
expectedErrorMsg string
}{
{bz, exchangeRates, addrs[0], true},
{bz[1:], exchangeRates, addrs[0], false},
{bz, exchangeRates, sdk.AccAddress{}, false},
{AggregateVoteHash{}, exchangeRates, addrs[0], false},
{bz, exchangeRates, addrs[0], addrs[0], true, "test should pass"},
{bz[1:], exchangeRates, addrs[0], addrs[0], false, msgInvalidHashLength},
{[]byte("0\x01"), exchangeRates, addrs[0], addrs[0], false, msgInvalidHashLength},
{AggregateVoteHash{}, exchangeRates, addrs[0], addrs[0], false, msgInvalidHashLength},
{bz, exchangeRates, sdk.AccAddress{}, addrs[0], false, msgInvalidFeederAddr},
{bz, exchangeRates, addrs[0], sdk.AccAddress{}, false, msgInvalidOperatorAddr},
}

for i, tc := range tests {
msg := NewMsgAggregateExchangeRatePrevote(tc.hash, tc.voter, sdk.ValAddress(tc.voter))
msg := NewMsgAggregateExchangeRatePrevote(tc.hash, tc.feeder, sdk.ValAddress(tc.validator))
if tc.expectPass {
require.NoError(t, msg.ValidateBasic(), "test: %v", i)
} else {
require.Error(t, msg.ValidateBasic(), "test: %v", i)
require.ErrorContainsf(t, msg.ValidateBasic(), tc.expectedErrorMsg, "test: %v", i)
}
}
}
Expand All @@ -73,31 +84,93 @@ func TestMsgAggregateExchangeRateVote(t *testing.T) {
exchangeRates := "foo:1.0,bar:1232.123"
zeroExchangeRates := "foo:0.0,bar:1232.132"
negativeExchangeRates := "foo:-1234.5,bar:1232.132"
overFlowExchangeRates := "foo:1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0,bar:1232.132"
overFlowMsgExchangeRates := StringWithCharset(4097, "56432")
overFlowExchangeRates := "foo:100000000000000000000000000000000000000000000000000000000000000000000000000000.01,bar:1232.132"
validSalt := "0cf33fb528b388660c3a42c3f3250e983395290b75fef255050fb5bc48a6025f"
saltWithColon := "0cf33fb528b388660c3a42c3f3250e983395290b75fef255050fb5bc48a6025:"
msgInvalidSalt := "invalid salt length; must be 64"
msgInvalidOverflowValue := "overflow: invalid exchange rate"
msgInvalidHexString := "salt must be a valid hex string: invalid salt format"
msgInvalidUnknownRequest := "must provide at least one oracle exchange rate: unknown request"
msgInvalidFeederAddr := "invalid feeder address (empty address string is not allowed): invalid address"
msgInvalidOperatorAddr := "invalid operator address (empty address string is not allowed): invalid address"
msgInvalidOraclePrice := "failed to parse exchange rates string cause: invalid oracle price: invalid coins"
msgInvalidOverflowExceedCharacter := "exchange rates string can not exceed 4096 characters: invalid request"
msgInvalidExchangeRates := "failed to parse exchange rates string cause: invalid exchange rate a: invalid coins"

tests := []struct {
voter sdk.AccAddress
salt string
exchangeRates string
expectPass bool
feeder sdk.AccAddress
validator sdk.AccAddress
salt string
exchangeRates string
expectPass bool
expectedErrorMsg string
}{
{addrs[0], validSalt, exchangeRates, true},
{addrs[0], validSalt, invalidExchangeRates, false},
{addrs[0], validSalt, zeroExchangeRates, false},
{addrs[0], validSalt, negativeExchangeRates, false},
{addrs[0], validSalt, overFlowExchangeRates, false},
{sdk.AccAddress{}, validSalt, exchangeRates, false},
{addrs[0], "", exchangeRates, false},
{addrs[0], saltWithColon, exchangeRates, false},
{addrs[0], addrs[0], validSalt, exchangeRates, true, "test should pass"},
{addrs[0], addrs[0], validSalt, invalidExchangeRates, false, msgInvalidExchangeRates},
{addrs[0], addrs[0], validSalt, zeroExchangeRates, false, msgInvalidOraclePrice},
{addrs[0], addrs[0], validSalt, negativeExchangeRates, false, msgInvalidOraclePrice},
{addrs[0], addrs[0], validSalt, overFlowMsgExchangeRates, false, msgInvalidOverflowExceedCharacter},
{addrs[0], addrs[0], validSalt, overFlowExchangeRates, false, msgInvalidOverflowValue},
{sdk.AccAddress{}, sdk.AccAddress{}, validSalt, exchangeRates, false, msgInvalidFeederAddr},
{addrs[0], sdk.AccAddress{}, validSalt, exchangeRates, false, msgInvalidOperatorAddr},
{addrs[0], addrs[0], "", exchangeRates, false, msgInvalidSalt},
{addrs[0], addrs[0], validSalt, "", false, msgInvalidUnknownRequest},
{addrs[0], addrs[0], saltWithColon, exchangeRates, false, msgInvalidHexString},
}

for i, tc := range tests {
msg := NewMsgAggregateExchangeRateVote(tc.salt, tc.exchangeRates, tc.voter, sdk.ValAddress(tc.voter))
msg := NewMsgAggregateExchangeRateVote(tc.salt, tc.exchangeRates, tc.feeder, sdk.ValAddress(tc.validator))
if tc.expectPass {
require.Nil(t, msg.ValidateBasic(), "test: %v", i)
} else {
require.NotNil(t, msg.ValidateBasic(), "test: %v", i)
require.ErrorContainsf(t, msg.ValidateBasic(), tc.expectedErrorMsg, "test: %v", i)
}
}
}

func TestNewMsgAggregateExchangeRatePrevote(t *testing.T) {
vals := GenerateRandomValAddr(2)
feederAddr := sdk.AccAddress(vals[1])

exchangeRates := sdk.DecCoins{sdk.NewDecCoinFromDec(UmeeDenom, sdk.OneDec()), sdk.NewDecCoinFromDec(UmeeDenom, sdk.NewDecWithPrec(32121, 1))}
bz := GetAggregateVoteHash("1", exchangeRates.String(), sdk.ValAddress(vals[0]))

aggregateExchangeRatePreVote := NewMsgAggregateExchangeRatePrevote(
bz,
feederAddr,
vals[0],
)

require.Equal(t, aggregateExchangeRatePreVote.Route(), RouterKey)
require.Equal(t, aggregateExchangeRatePreVote.Type(), TypeMsgAggregateExchangeRatePrevote)
require.NotNil(t, aggregateExchangeRatePreVote.GetSignBytes())
require.Equal(t, aggregateExchangeRatePreVote.GetSigners(), []sdk.AccAddress{feederAddr})
}

func TestNewMsgAggregateExchangeRateVote(t *testing.T) {
vals := GenerateRandomValAddr(2)
feederAddr := sdk.AccAddress(vals[1])

aggregateExchangeRateVote := NewMsgAggregateExchangeRateVote(
"salt",
"0.1",
feederAddr,
vals[0],
)

require.Equal(t, aggregateExchangeRateVote.Route(), RouterKey)
require.Equal(t, aggregateExchangeRateVote.Type(), TypeMsgAggregateExchangeRateVote)
require.NotNil(t, aggregateExchangeRateVote.GetSignBytes())
require.Equal(t, aggregateExchangeRateVote.GetSigners(), []sdk.AccAddress{feederAddr})
}

func TestMsgDelegateFeedConsent(t *testing.T) {
vals := GenerateRandomValAddr(2)
msgFeedConsent := NewMsgDelegateFeedConsent(vals[0], sdk.AccAddress(vals[1]))

require.Equal(t, msgFeedConsent.Route(), RouterKey)
require.Equal(t, msgFeedConsent.Type(), TypeMsgDelegateFeedConsent)
require.NotNil(t, msgFeedConsent.GetSignBytes())
require.Equal(t, msgFeedConsent.GetSigners(), []sdk.AccAddress{sdk.AccAddress(vals[0])})
}
Loading