diff --git a/CHANGELOG.md b/CHANGELOG.md index d1d23cbffe..a5ded9aeaa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -50,6 +50,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/...`. ## [v2.0.0](https://github.com/umee-network/umee/releases/tag/v2.0.0) - 2022-04-06 diff --git a/x/oracle/keeper/grpc_query_test.go b/x/oracle/keeper/grpc_query_test.go index b22cf50255..39f242f4b5 100644 --- a/x/oracle/keeper/grpc_query_test.go +++ b/x/oracle/keeper/grpc_query_test.go @@ -1,32 +1,32 @@ package keeper_test import ( - "context" "math/rand" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/tendermint/tendermint/crypto/secp256k1" umeeapp "github.com/umee-network/umee/v2/app" + "github.com/umee-network/umee/v2/x/oracle/keeper" "github.com/umee-network/umee/v2/x/oracle/types" ) func (s *IntegrationTestSuite) TestQuerier_ActiveExchangeRates() { s.app.OracleKeeper.SetExchangeRate(s.ctx, exchangeRate, sdk.OneDec()) - res, err := s.queryClient.ActiveExchangeRates(context.Background(), &types.QueryActiveExchangeRatesRequest{}) + res, err := s.queryClient.ActiveExchangeRates(s.ctx.Context(), &types.QueryActiveExchangeRatesRequest{}) s.Require().NoError(err) s.Require().Equal([]string{exchangeRate}, res.ActiveRates) } func (s *IntegrationTestSuite) TestQuerier_ExchangeRates() { s.app.OracleKeeper.SetExchangeRate(s.ctx, exchangeRate, sdk.OneDec()) - res, err := s.queryClient.ExchangeRates(context.Background(), &types.QueryExchangeRatesRequest{}) + res, err := s.queryClient.ExchangeRates(s.ctx.Context(), &types.QueryExchangeRatesRequest{}) s.Require().NoError(err) s.Require().Equal(sdk.DecCoins{ sdk.NewDecCoinFromDec(exchangeRate, sdk.OneDec()), }, res.ExchangeRates) - res, err = s.queryClient.ExchangeRates(context.Background(), &types.QueryExchangeRatesRequest{ + res, err = s.queryClient.ExchangeRates(s.ctx.Context(), &types.QueryExchangeRatesRequest{ Denom: exchangeRate, }) s.Require().NoError(err) @@ -44,7 +44,7 @@ func (s *IntegrationTestSuite) TestQuerier_FeeederDelegation() { err := s.app.OracleKeeper.ValidateFeeder(s.ctx, feederAddr, valAddr) s.Require().Error(err) - _, err = s.queryClient.FeederDelegation(context.Background(), &types.QueryFeederDelegationRequest{ + _, err = s.queryClient.FeederDelegation(s.ctx.Context(), &types.QueryFeederDelegationRequest{ ValidatorAddr: inactiveValidator, }) s.Require().Error(err) @@ -54,7 +54,7 @@ func (s *IntegrationTestSuite) TestQuerier_FeeederDelegation() { err = s.app.OracleKeeper.ValidateFeeder(s.ctx, feederAddr, valAddr) s.Require().NoError(err) - res, err := s.queryClient.FeederDelegation(context.Background(), &types.QueryFeederDelegationRequest{ + res, err := s.queryClient.FeederDelegation(s.ctx.Context(), &types.QueryFeederDelegationRequest{ ValidatorAddr: valAddr.String(), }) s.Require().NoError(err) @@ -64,7 +64,7 @@ func (s *IntegrationTestSuite) TestQuerier_FeeederDelegation() { func (s *IntegrationTestSuite) TestQuerier_MissCounter() { missCounter := uint64(rand.Intn(100)) - res, err := s.queryClient.MissCounter(context.Background(), &types.QueryMissCounterRequest{ + res, err := s.queryClient.MissCounter(s.ctx.Context(), &types.QueryMissCounterRequest{ ValidatorAddr: valAddr.String(), }) s.Require().NoError(err) @@ -72,7 +72,7 @@ func (s *IntegrationTestSuite) TestQuerier_MissCounter() { s.app.OracleKeeper.SetMissCounter(s.ctx, valAddr, missCounter) - res, err = s.queryClient.MissCounter(context.Background(), &types.QueryMissCounterRequest{ + res, err = s.queryClient.MissCounter(s.ctx.Context(), &types.QueryMissCounterRequest{ ValidatorAddr: valAddr.String(), }) s.Require().NoError(err) @@ -91,7 +91,7 @@ func (s *IntegrationTestSuite) TestQuerier_AggregatePrevote() { s.Require().NoError(err) s.Require().Equal(prevote, res) - queryRes, err := s.queryClient.AggregatePrevote(context.Background(), &types.QueryAggregatePrevoteRequest{ + queryRes, err := s.queryClient.AggregatePrevote(s.ctx.Context(), &types.QueryAggregatePrevoteRequest{ ValidatorAddr: valAddr.String(), }) s.Require().NoError(err) @@ -103,7 +103,7 @@ func (s *IntegrationTestSuite) TestQuerier_AggregatePrevote() { } func (s *IntegrationTestSuite) TestQuerier_AggregatePrevotes() { - res, err := s.queryClient.AggregatePrevotes(context.Background(), &types.QueryAggregatePrevotesRequest{}) + res, err := s.queryClient.AggregatePrevotes(s.ctx.Context(), &types.QueryAggregatePrevotesRequest{}) s.Require().Equal([]types.AggregateExchangeRatePrevote(nil), res.AggregatePrevotes) s.Require().NoError(err) } @@ -121,7 +121,7 @@ func (s *IntegrationTestSuite) TestQuerier_AggregateVote() { } s.app.OracleKeeper.SetAggregateExchangeRateVote(s.ctx, valAddr, vote) - res, err := s.queryClient.AggregateVote(context.Background(), &types.QueryAggregateVoteRequest{ + res, err := s.queryClient.AggregateVote(s.ctx.Context(), &types.QueryAggregateVoteRequest{ ValidatorAddr: valAddr.String(), }) s.Require().NoError(err) @@ -132,13 +132,128 @@ func (s *IntegrationTestSuite) TestQuerier_AggregateVote() { } func (s *IntegrationTestSuite) TestQuerier_AggregateVotes() { - res, err := s.queryClient.AggregateVotes(context.Background(), &types.QueryAggregateVotesRequest{}) + res, err := s.queryClient.AggregateVotes(s.ctx.Context(), &types.QueryAggregateVotesRequest{}) s.Require().NoError(err) s.Require().Equal([]types.AggregateExchangeRateVote(nil), res.AggregateVotes) } +func (s *IntegrationTestSuite) TestQuerier_AggregateVoteInvalidExchangeRate() { + res, err := s.queryClient.AggregateVote(s.ctx.Context(), &types.QueryAggregateVoteRequest{ + ValidatorAddr: valAddr.String(), + }) + s.Require().Nil(res) + s.Require().ErrorContains(err, "no aggregate vote") +} + +func (s *IntegrationTestSuite) TestQuerier_AggregatePrevoteInvalidExchangeRate() { + res, err := s.queryClient.AggregatePrevote(s.ctx.Context(), &types.QueryAggregatePrevoteRequest{ + ValidatorAddr: valAddr.String(), + }) + s.Require().Nil(res) + s.Require().ErrorContains(err, "no aggregate prevote") +} + func (s *IntegrationTestSuite) TestQuerier_Params() { - res, err := s.queryClient.Params(context.Background(), &types.QueryParamsRequest{}) + res, err := s.queryClient.Params(s.ctx.Context(), &types.QueryParamsRequest{}) s.Require().NoError(err) s.Require().Equal(types.DefaultGenesisState().Params, res.Params) } + +func (s *IntegrationTestSuite) TestQuerier_ExchangeRatesInvalidExchangeRate() { + resExchangeRate, err := s.queryClient.ExchangeRates(s.ctx.Context(), &types.QueryExchangeRatesRequest{ + Denom: " ", + }) + s.Require().Nil(resExchangeRate) + s.Require().ErrorContains(err, "unknown denom") +} + +func (s *IntegrationTestSuite) TestQuerier_AggregatePrevoteInvalidValAddr() { + resExchangeRate, err := s.queryClient.AggregatePrevote(s.ctx.Context(), &types.QueryAggregatePrevoteRequest{ + ValidatorAddr: "valAddrInvalid", + }) + s.Require().Nil(resExchangeRate) + s.Require().ErrorContains(err, "decoding bech32 failed") +} + +func (s *IntegrationTestSuite) TestQuerier_AggregatePrevotesAppendVotes() { + s.app.OracleKeeper.SetAggregateExchangeRatePrevote(s.ctx, valAddr, types.NewAggregateExchangeRatePrevote( + types.AggregateVoteHash{}, + valAddr, + uint64(s.ctx.BlockHeight()), + )) + + _, err := s.queryClient.AggregatePrevotes(s.ctx.Context(), &types.QueryAggregatePrevotesRequest{}) + s.Require().Nil(err) +} + +func (s *IntegrationTestSuite) TestQuerier_AggregateVotesAppendVotes() { + s.app.OracleKeeper.SetAggregateExchangeRateVote(s.ctx, valAddr, types.NewAggregateExchangeRateVote( + types.DefaultGenesisState().ExchangeRates, + valAddr, + )) + + _, err := s.queryClient.AggregateVotes(s.ctx.Context(), &types.QueryAggregateVotesRequest{}) + s.Require().Nil(err) +} + +func (s *IntegrationTestSuite) TestEmptyRequest() { + q := keeper.NewQuerier(keeper.Keeper{}) + const emptyRequestErrorMsg = "empty request" + + resParams, err := q.Params(s.ctx.Context(), nil) + s.Require().Nil(resParams) + s.Require().ErrorContains(err, emptyRequestErrorMsg) + + resExchangeRate, err := q.ExchangeRates(s.ctx.Context(), nil) + s.Require().Nil(resExchangeRate) + s.Require().ErrorContains(err, emptyRequestErrorMsg) + + resActiveExchangeRates, err := q.ActiveExchangeRates(s.ctx.Context(), nil) + s.Require().Nil(resActiveExchangeRates) + s.Require().ErrorContains(err, emptyRequestErrorMsg) + + resFeederDelegation, err := q.FeederDelegation(s.ctx.Context(), nil) + s.Require().Nil(resFeederDelegation) + s.Require().ErrorContains(err, emptyRequestErrorMsg) + + resMissCounter, err := q.MissCounter(s.ctx.Context(), nil) + s.Require().Nil(resMissCounter) + s.Require().ErrorContains(err, emptyRequestErrorMsg) + + resAggregatePrevote, err := q.AggregatePrevote(s.ctx.Context(), nil) + s.Require().Nil(resAggregatePrevote) + s.Require().ErrorContains(err, emptyRequestErrorMsg) + + resAggregatePrevotes, err := q.AggregatePrevotes(s.ctx.Context(), nil) + s.Require().Nil(resAggregatePrevotes) + s.Require().ErrorContains(err, emptyRequestErrorMsg) + + resAggregateVote, err := q.AggregateVote(s.ctx.Context(), nil) + s.Require().Nil(resAggregateVote) + s.Require().ErrorContains(err, emptyRequestErrorMsg) + + resAggregateVotes, err := q.AggregateVotes(s.ctx.Context(), nil) + s.Require().Nil(resAggregateVotes) + s.Require().ErrorContains(err, emptyRequestErrorMsg) +} + +func (s *IntegrationTestSuite) TestInvalidBechAddress() { + q := keeper.NewQuerier(keeper.Keeper{}) + invalidAddressMsg := "empty address string is not allowed" + + resFeederDelegation, err := q.FeederDelegation(s.ctx.Context(), &types.QueryFeederDelegationRequest{}) + s.Require().Nil(resFeederDelegation) + s.Require().ErrorContains(err, invalidAddressMsg) + + resMissCounter, err := q.MissCounter(s.ctx.Context(), &types.QueryMissCounterRequest{}) + s.Require().Nil(resMissCounter) + s.Require().ErrorContains(err, invalidAddressMsg) + + resAggregatePrevote, err := q.AggregatePrevote(s.ctx.Context(), &types.QueryAggregatePrevoteRequest{}) + s.Require().Nil(resAggregatePrevote) + s.Require().ErrorContains(err, invalidAddressMsg) + + resAggregateVote, err := q.AggregateVote(s.ctx.Context(), &types.QueryAggregateVoteRequest{}) + s.Require().Nil(resAggregateVote) + s.Require().ErrorContains(err, invalidAddressMsg) +} diff --git a/x/oracle/types/params_test.go b/x/oracle/types/params_test.go index 3e33a9dbc8..628a6ffcda 100644 --- a/x/oracle/types/params_test.go +++ b/x/oracle/types/params_test.go @@ -8,6 +8,119 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) +func TestParamKeyTable(t *testing.T) { + require.NotNil(t, ParamKeyTable()) +} + +func TestValidateVotePeriod(t *testing.T) { + err := validateVotePeriod("invalidUint64") + require.ErrorContains(t, err, "invalid parameter type: string") + + err = validateVotePeriod(uint64(0)) + require.ErrorContains(t, err, "vote period must be positive: 0") + + err = validateVotePeriod(uint64(10)) + require.Nil(t, err) +} + +func TestValidateVoteThreshold(t *testing.T) { + err := validateVoteThreshold("invalidSdkType") + require.ErrorContains(t, err, "invalid parameter type: string") + + err = validateVoteThreshold(sdk.MustNewDecFromStr("0.31")) + require.ErrorContains(t, err, "vote threshold must be bigger than 33%: 0.310000000000000000") + + err = validateVoteThreshold(sdk.MustNewDecFromStr("40.0")) + require.ErrorContains(t, err, "vote threshold too large: 40.000000000000000000") + + err = validateVoteThreshold(sdk.MustNewDecFromStr("0.35")) + require.Nil(t, err) +} + +func TestValidateRewardBand(t *testing.T) { + err := validateRewardBand("invalidSdkType") + require.ErrorContains(t, err, "invalid parameter type: string") + + err = validateRewardBand(sdk.MustNewDecFromStr("-0.31")) + require.ErrorContains(t, err, "reward band must be positive: -0.310000000000000000") + + err = validateRewardBand(sdk.MustNewDecFromStr("40.0")) + require.ErrorContains(t, err, "reward band is too large: 40.000000000000000000") + + err = validateRewardBand(sdk.OneDec()) + require.Nil(t, err) +} + +func TestValidateRewardDistributionWindow(t *testing.T) { + err := validateRewardDistributionWindow("invalidUint64") + require.ErrorContains(t, err, "invalid parameter type: string") + + err = validateRewardDistributionWindow(uint64(0)) + require.ErrorContains(t, err, "reward distribution window must be positive: 0") + + err = validateRewardDistributionWindow(uint64(10)) + require.Nil(t, err) +} + +func TestValidateAcceptList(t *testing.T) { + err := validateAcceptList("invalidUint64") + require.ErrorContains(t, err, "invalid parameter type: string") + + err = validateAcceptList(DenomList{ + {BaseDenom: ""}, + }) + require.ErrorContains(t, err, "oracle parameter AcceptList Denom must have BaseDenom") + + err = validateAcceptList(DenomList{ + {BaseDenom: DenomUmee.BaseDenom, SymbolDenom: ""}, + }) + require.ErrorContains(t, err, "oracle parameter AcceptList Denom must have SymbolDenom") + + err = validateAcceptList(DenomList{ + {BaseDenom: DenomUmee.BaseDenom, SymbolDenom: DenomUmee.SymbolDenom}, + }) + require.Nil(t, err) +} + +func TestValidateSlashFraction(t *testing.T) { + err := validateSlashFraction("invalidSdkType") + require.ErrorContains(t, err, "invalid parameter type: string") + + err = validateSlashFraction(sdk.MustNewDecFromStr("-0.31")) + require.ErrorContains(t, err, "slash fraction must be positive: -0.310000000000000000") + + err = validateSlashFraction(sdk.MustNewDecFromStr("40.0")) + require.ErrorContains(t, err, "slash fraction is too large: 40.000000000000000000") + + err = validateSlashFraction(sdk.OneDec()) + require.Nil(t, err) +} + +func TestValidateSlashWindow(t *testing.T) { + err := validateSlashWindow("invalidUint64") + require.ErrorContains(t, err, "invalid parameter type: string") + + err = validateSlashWindow(uint64(0)) + require.ErrorContains(t, err, "slash window must be positive: 0") + + err = validateSlashWindow(uint64(10)) + require.Nil(t, err) +} + +func TestValidateMinValidPerWindow(t *testing.T) { + err := validateMinValidPerWindow("invalidSdkType") + require.ErrorContains(t, err, "invalid parameter type: string") + + err = validateMinValidPerWindow(sdk.MustNewDecFromStr("-0.31")) + require.ErrorContains(t, err, "min valid per window must be positive: -0.310000000000000000") + + err = validateMinValidPerWindow(sdk.MustNewDecFromStr("40.0")) + require.ErrorContains(t, err, "min valid per window is too large: 40.000000000000000000") + + err = validateMinValidPerWindow(sdk.OneDec()) + require.Nil(t, err) +} + func TestParamsEqual(t *testing.T) { p1 := DefaultParams() err := p1.Validate() diff --git a/x/oracle/types/vote_test.go b/x/oracle/types/vote_test.go index e72f558240..2edbb2fa81 100644 --- a/x/oracle/types/vote_test.go +++ b/x/oracle/types/vote_test.go @@ -3,9 +3,44 @@ package types import ( "testing" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" ) +func TestAggregateExchangeRatePrevoteString(t *testing.T) { + addr := sdk.ValAddress(sdk.AccAddress([]byte("addr1_______________"))) + aggregateVoteHash := GetAggregateVoteHash("salt", "UMEE:100,ATOM:100", addr) + aggregateExchangeRatePreVote := NewAggregateExchangeRatePrevote( + aggregateVoteHash, + addr, + 100, + ) + + require.Equal(t, "hash: 19c30cf9ea8aa0e0b03904162cadec0f2024a76d\nvoter: umeevaloper1v9jxgu33ta047h6lta047h6lta047h6l5ltnvg\nsubmit_block: 100\n", aggregateExchangeRatePreVote.String()) +} + +func TestAggregateExchangeRateVoteString(t *testing.T) { + aggregateExchangeRatePreVote := NewAggregateExchangeRateVote( + ExchangeRateTuples{ + NewExchangeRateTuple(UmeeDenom, sdk.OneDec()), + }, + sdk.ValAddress(sdk.AccAddress([]byte("addr1_______________"))), + ) + + require.Equal(t, "exchange_rate_tuples:\n - denom: uumee\n exchange_rate: \"1.000000000000000000\"\nvoter: umeevaloper1v9jxgu33ta047h6lta047h6lta047h6l5ltnvg\n", aggregateExchangeRatePreVote.String()) +} + +func TestExchangeRateTuplesString(t *testing.T) { + exchangeRateTuple := NewExchangeRateTuple(UmeeDenom, sdk.OneDec()) + require.Equal(t, exchangeRateTuple.String(), "denom: uumee\nexchange_rate: \"1.000000000000000000\"\n") + + exchangeRateTuples := ExchangeRateTuples{ + exchangeRateTuple, + NewExchangeRateTuple(IbcDenomAtom, sdk.SmallestDec()), + } + require.Equal(t, "- denom: uumee\n exchange_rate: \"1.000000000000000000\"\n- denom: ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2\n exchange_rate: \"0.000000000000000001\"\n", exchangeRateTuples.String()) +} + func TestParseExchangeRateTuples(t *testing.T) { valid := "uumee:123.0,uatom:123.123" _, err := ParseExchangeRateTuples(valid) @@ -34,4 +69,8 @@ func TestParseExchangeRateTuples(t *testing.T) { multiplePricesPerRate := "uumee:123: uumee:456,uusdc:789" _, err = ParseExchangeRateTuples(multiplePricesPerRate) require.Error(t, err) + + res, err := ParseExchangeRateTuples("") + require.Nil(t, err) + require.Nil(t, res) }