From da5c6ced1dc0a3925f26653c24ba0934cce51f22 Mon Sep 17 00:00:00 2001 From: Alessio Treglia Date: Wed, 4 Mar 2020 17:49:59 +0000 Subject: [PATCH] types: add test cases (#5747) Upgrade gomock dependency. --- .codecov.yml | 1 + go.mod | 2 +- go.sum | 9 ++- types/address.go | 44 ++++------- types/address_test.go | 80 +++++++++++++++++++ types/config_test.go | 47 +++++++++++ types/context_test.go | 24 +++++- types/errors/abci_test.go | 32 ++++++++ types/int_test.go | 46 +++++++++++ types/invariant_test.go | 15 ++++ types/result_test.go | 161 ++++++++++++++++++++++++++++++++++++-- types/staking_test.go | 24 ++++++ types/store_test.go | 94 +++++++++++++++++++++- types/tx_msg_test.go | 23 ++++++ types/uint_test.go | 12 +++ types/utils_test.go | 45 ++++++++--- 16 files changed, 606 insertions(+), 53 deletions(-) create mode 100644 types/config_test.go create mode 100644 types/invariant_test.go create mode 100644 types/staking_test.go create mode 100644 types/tx_msg_test.go diff --git a/.codecov.yml b/.codecov.yml index f4d6cef61f60..e17633a5d388 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -47,6 +47,7 @@ ignore: - "*.md" - "*.rst" - "**/*.pb.go" + - "types/*.pb.go" - "tests/*" - "tests/**/*" - "x/**/*.pb.go" diff --git a/go.mod b/go.mod index 1599418dc4d0..c010e24ab730 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d github.com/cosmos/ledger-cosmos-go v0.11.1 github.com/gogo/protobuf v1.3.1 - github.com/golang/mock v1.3.1-0.20190508161146-9fa652df1129 + github.com/golang/mock v1.4.1 github.com/golang/protobuf v1.3.4 github.com/gorilla/handlers v1.4.2 github.com/gorilla/mux v1.7.4 diff --git a/go.sum b/go.sum index 5ad52215962c..ae529cbb3acf 100644 --- a/go.sum +++ b/go.sum @@ -85,8 +85,8 @@ github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekf github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1-0.20190508161146-9fa652df1129 h1:tT8iWCYw4uOem71yYA3htfH+LNopJvcqZQshm56G5L4= -github.com/golang/mock v1.3.1-0.20190508161146-9fa652df1129/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.1 h1:ocYkMQY5RrXTYgXl7ICpV0IXwlEQGwKIsery4gyXa1U= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -322,6 +322,7 @@ golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= @@ -368,3 +369,7 @@ gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +rsc.io/quote/v3 v3.1.0 h1:9JKUTTIUgS6kzR9mK1YuGKv6Nl+DijDNIc0ghT58FaY= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/types/address.go b/types/address.go index 839af224d01f..c2a645b3077a 100644 --- a/types/address.go +++ b/types/address.go @@ -98,16 +98,8 @@ type AccAddress []byte // AccAddressFromHex creates an AccAddress from a hex string. func AccAddressFromHex(address string) (addr AccAddress, err error) { - if len(address) == 0 { - return addr, errors.New("decoding Bech32 address failed: must provide an address") - } - - bz, err := hex.DecodeString(address) - if err != nil { - return nil, err - } - - return AccAddress(bz), nil + bz, err := addressBytesFromHexString(address) + return AccAddress(bz), err } // VerifyAddressFormat verifies that the provided bytes form a valid address @@ -265,16 +257,8 @@ type ValAddress []byte // ValAddressFromHex creates a ValAddress from a hex string. func ValAddressFromHex(address string) (addr ValAddress, err error) { - if len(address) == 0 { - return addr, errors.New("decoding Bech32 address failed: must provide an address") - } - - bz, err := hex.DecodeString(address) - if err != nil { - return nil, err - } - - return ValAddress(bz), nil + bz, err := addressBytesFromHexString(address) + return ValAddress(bz), err } // ValAddressFromBech32 creates a ValAddress from a Bech32 string. @@ -420,16 +404,8 @@ type ConsAddress []byte // ConsAddressFromHex creates a ConsAddress from a hex string. func ConsAddressFromHex(address string) (addr ConsAddress, err error) { - if len(address) == 0 { - return addr, errors.New("decoding Bech32 address failed: must provide an address") - } - - bz, err := hex.DecodeString(address) - if err != nil { - return nil, err - } - - return ConsAddress(bz), nil + bz, err := addressBytesFromHexString(address) + return ConsAddress(bz), err } // ConsAddressFromBech32 creates a ConsAddress from a Bech32 string. @@ -695,3 +671,11 @@ func GetFromBech32(bech32str, prefix string) ([]byte, error) { return bz, nil } + +func addressBytesFromHexString(address string) ([]byte, error) { + if len(address) == 0 { + return nil, errors.New("decoding Bech32 address failed: must provide an address") + } + + return hex.DecodeString(address) +} diff --git a/types/address_test.go b/types/address_test.go index 5193404d093f..8a928a43c923 100644 --- a/types/address_test.go +++ b/types/address_test.go @@ -1,6 +1,7 @@ package types_test import ( + "bytes" "encoding/hex" "fmt" "math/rand" @@ -8,6 +9,7 @@ import ( "testing" "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/crypto" yaml "gopkg.in/yaml.v2" "github.com/tendermint/tendermint/crypto/ed25519" @@ -37,6 +39,7 @@ func testMarshal(t *testing.T, original interface{}, res interface{}, marshal fu } func TestEmptyAddresses(t *testing.T) { + t.Parallel() require.Equal(t, (types.AccAddress{}).String(), "") require.Equal(t, (types.ValAddress{}).String(), "") require.Equal(t, (types.ConsAddress{}).String(), "") @@ -145,6 +148,9 @@ func TestRandBech32AccAddrConsistency(t *testing.T) { err = (*types.AccAddress)(nil).UnmarshalJSON([]byte("\"" + str + "\"")) require.NotNil(t, err) } + + _, err := types.AccAddressFromHex("") + require.Equal(t, "decoding Bech32 address failed: must provide an address", err.Error()) } func TestValAddr(t *testing.T) { @@ -168,6 +174,7 @@ func TestValAddr(t *testing.T) { res, err = types.ValAddressFromHex(str) require.Nil(t, err) require.Equal(t, acc, res) + } for _, str := range invalidStrs { @@ -180,6 +187,10 @@ func TestValAddr(t *testing.T) { err = (*types.ValAddress)(nil).UnmarshalJSON([]byte("\"" + str + "\"")) require.NotNil(t, err) } + + // test empty string + _, err := types.ValAddressFromHex("") + require.Equal(t, "decoding Bech32 address failed: must provide an address", err.Error()) } func TestConsAddress(t *testing.T) { @@ -215,6 +226,10 @@ func TestConsAddress(t *testing.T) { err = (*types.ConsAddress)(nil).UnmarshalJSON([]byte("\"" + str + "\"")) require.NotNil(t, err) } + + // test empty string + _, err := types.ConsAddressFromHex("") + require.Equal(t, "decoding Bech32 address failed: must provide an address", err.Error()) } const letterBytes = "abcdefghijklmnopqrstuvwxyz" @@ -410,3 +425,68 @@ func TestMustBech32ifyAddressBytes(t *testing.T) { }) } } + +func TestAddressTypesEquals(t *testing.T) { + t.Parallel() + addr1 := secp256k1.GenPrivKey().PubKey().Address() + accAddr1 := types.AccAddress(addr1) + consAddr1 := types.ConsAddress(addr1) + valAddr1 := types.ValAddress(addr1) + + addr2 := secp256k1.GenPrivKey().PubKey().Address() + accAddr2 := types.AccAddress(addr2) + consAddr2 := types.ConsAddress(addr2) + valAddr2 := types.ValAddress(addr2) + + // equality + require.True(t, accAddr1.Equals(accAddr1)) + require.True(t, consAddr1.Equals(consAddr1)) + require.True(t, valAddr1.Equals(valAddr1)) + + // emptiness + require.True(t, types.AccAddress{}.Equals(types.AccAddress{})) + require.True(t, types.AccAddress{}.Equals(types.AccAddress(nil))) + require.True(t, types.AccAddress(nil).Equals(types.AccAddress{})) + require.True(t, types.AccAddress(nil).Equals(types.AccAddress(nil))) + + require.True(t, types.ConsAddress{}.Equals(types.ConsAddress{})) + require.True(t, types.ConsAddress{}.Equals(types.ConsAddress(nil))) + require.True(t, types.ConsAddress(nil).Equals(types.ConsAddress{})) + require.True(t, types.ConsAddress(nil).Equals(types.ConsAddress(nil))) + + require.True(t, types.ValAddress{}.Equals(types.ValAddress{})) + require.True(t, types.ValAddress{}.Equals(types.ValAddress(nil))) + require.True(t, types.ValAddress(nil).Equals(types.ValAddress{})) + require.True(t, types.ValAddress(nil).Equals(types.ValAddress(nil))) + + require.False(t, accAddr1.Equals(accAddr2)) + require.Equal(t, accAddr1.Equals(accAddr2), accAddr2.Equals(accAddr1)) + require.False(t, consAddr1.Equals(consAddr2)) + require.Equal(t, consAddr1.Equals(consAddr2), consAddr2.Equals(consAddr1)) + require.False(t, valAddr1.Equals(valAddr2)) + require.Equal(t, valAddr1.Equals(valAddr2), valAddr2.Equals(valAddr1)) +} + +func TestNilAddressTypesEmpty(t *testing.T) { + t.Parallel() + require.True(t, types.AccAddress(nil).Empty()) + require.True(t, types.ConsAddress(nil).Empty()) + require.True(t, types.ValAddress(nil).Empty()) +} + +func TestGetConsAddress(t *testing.T) { + t.Parallel() + pk := secp256k1.GenPrivKey().PubKey() + require.NotEqual(t, types.GetConsAddress(pk), pk.Address()) + require.True(t, bytes.Equal(types.GetConsAddress(pk).Bytes(), pk.Address().Bytes())) + require.Panics(t, func() { types.GetConsAddress(crypto.PubKey(nil)) }) +} + +func TestGetFromBech32(t *testing.T) { + _, err := types.GetFromBech32("", "prefix") + require.Error(t, err) + require.Equal(t, "decoding Bech32 address failed: must provide an address", err.Error()) + _, err = types.GetFromBech32("cosmos1qqqsyqcyq5rqwzqfys8f67", "x") + require.Error(t, err) + require.Equal(t, "invalid Bech32 prefix; expected x, got cosmos", err.Error()) +} diff --git a/types/config_test.go b/types/config_test.go new file mode 100644 index 000000000000..7c902c1962fb --- /dev/null +++ b/types/config_test.go @@ -0,0 +1,47 @@ +package types_test + +import ( + "errors" + "testing" + + "github.com/stretchr/testify/require" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func TestConfig_SetCoinType(t *testing.T) { + config := &sdk.Config{} + require.Equal(t, uint32(0), config.GetCoinType()) + config.SetCoinType(99) + require.Equal(t, uint32(99), config.GetCoinType()) + + config.Seal() + require.Panics(t, func() { config.SetCoinType(99) }) +} + +func TestConfig_SetTxEncoder(t *testing.T) { + mockErr := errors.New("test") + config := &sdk.Config{} + require.Nil(t, config.GetTxEncoder()) + encFunc := sdk.TxEncoder(func(tx sdk.Tx) ([]byte, error) { return nil, nil }) + config.SetTxEncoder(encFunc) + _, err := config.GetTxEncoder()(sdk.Tx(nil)) + require.Error(t, mockErr, err) + + config.Seal() + require.Panics(t, func() { config.SetTxEncoder(encFunc) }) +} + +func TestConfig_SetFullFundraiserPath(t *testing.T) { + config := &sdk.Config{} + require.Equal(t, "", config.GetFullFundraiserPath()) + config.SetFullFundraiserPath("test/path") + require.Equal(t, "test/path", config.GetFullFundraiserPath()) + + config.Seal() + require.Panics(t, func() { config.SetFullFundraiserPath("x/test/path") }) +} + +func TestKeyringServiceName(t *testing.T) { + require.Equal(t, sdk.DefaultKeyringServiceName, sdk.KeyringServiceName()) +} diff --git a/types/context_test.go b/types/context_test.go index d8e893364d7d..9f08178624d3 100644 --- a/types/context_test.go +++ b/types/context_test.go @@ -1,6 +1,7 @@ package types_test import ( + "context" "testing" "time" @@ -110,6 +111,7 @@ func TestContextWithCustom(t *testing.T) { logger := NewMockLogger() voteinfos := []abci.VoteInfo{{}} meter := types.NewGasMeter(10000) + blockGasMeter := types.NewGasMeter(20000) minGasPrices := types.DecCoins{types.NewInt64DecCoin("feetoken", 1)} ctx = types.NewContext(nil, header, ischeck, logger) @@ -121,7 +123,8 @@ func TestContextWithCustom(t *testing.T) { WithTxBytes(txbytes). WithVoteInfos(voteinfos). WithGasMeter(meter). - WithMinGasPrices(minGasPrices) + WithMinGasPrices(minGasPrices). + WithBlockGasMeter(blockGasMeter) require.Equal(t, height, ctx.BlockHeight()) require.Equal(t, chainid, ctx.ChainID()) require.Equal(t, ischeck, ctx.IsCheckTx()) @@ -130,6 +133,25 @@ func TestContextWithCustom(t *testing.T) { require.Equal(t, voteinfos, ctx.VoteInfos()) require.Equal(t, meter, ctx.GasMeter()) require.Equal(t, minGasPrices, ctx.MinGasPrices()) + require.Equal(t, blockGasMeter, ctx.BlockGasMeter()) + + require.False(t, ctx.WithIsCheckTx(false).IsCheckTx()) + + // test IsReCheckTx + require.False(t, ctx.IsReCheckTx()) + ctx = ctx.WithIsCheckTx(false) + ctx = ctx.WithIsReCheckTx(true) + require.True(t, ctx.IsCheckTx()) + require.True(t, ctx.IsReCheckTx()) + + // test consensus param + require.Nil(t, ctx.ConsensusParams()) + cp := &abci.ConsensusParams{} + require.Equal(t, cp, ctx.WithConsensusParams(cp).ConsensusParams()) + + // test inner context + newContext := context.WithValue(ctx.Context(), "key", "value") + require.NotEqual(t, ctx.Context(), ctx.WithContext(newContext).Context()) } // Testing saving/loading of header fields to/from the context diff --git a/types/errors/abci_test.go b/types/errors/abci_test.go index c098811ea474..9b9e8280aac7 100644 --- a/types/errors/abci_test.go +++ b/types/errors/abci_test.go @@ -5,6 +5,9 @@ import ( "io" "strings" "testing" + + "github.com/stretchr/testify/require" + abci "github.com/tendermint/tendermint/abci/types" ) func TestABCInfo(t *testing.T) { @@ -185,6 +188,8 @@ func TestRedact(t *testing.T) { if err := Redact(serr); err == serr { t.Error("reduct must not pass through a stdlib error") } + + require.Nil(t, Redact(nil)) } func TestABCIInfoSerializeErr(t *testing.T) { @@ -271,3 +276,30 @@ func (customErr) Codespace() string { return "extern" } func (customErr) ABCICode() uint32 { return 999 } func (customErr) Error() string { return "custom" } + +func TestResponseCheckDeliverTx(t *testing.T) { + t.Parallel() + require.Equal(t, abci.ResponseCheckTx{ + Codespace: "extern", + Code: 999, + Log: "custom", + GasWanted: int64(1), + GasUsed: int64(2), + }, ResponseCheckTx(customErr{}, 1, 2)) + require.Equal(t, abci.ResponseDeliverTx{ + Codespace: "extern", + Code: 999, + Log: "custom", + GasWanted: int64(1), + GasUsed: int64(2), + }, ResponseDeliverTx(customErr{}, 1, 2)) +} + +func TestQueryResult(t *testing.T) { + t.Parallel() + require.Equal(t, abci.ResponseQuery{ + Codespace: "extern", + Code: 999, + Log: "custom", + }, QueryResult(customErr{})) +} diff --git a/types/int_test.go b/types/int_test.go index 7a8ceade1748..aa55ee659ebd 100644 --- a/types/int_test.go +++ b/types/int_test.go @@ -10,6 +10,7 @@ import ( ) func TestFromInt64(t *testing.T) { + t.Parallel() for n := 0; n < 20; n++ { r := rand.Int63() require.Equal(t, r, NewInt(r).Int64()) @@ -17,6 +18,7 @@ func TestFromInt64(t *testing.T) { } func TestFromUint64(t *testing.T) { + t.Parallel() for n := 0; n < 20; n++ { r := rand.Uint64() require.True(t, NewIntFromUint64(r).IsUint64()) @@ -25,6 +27,7 @@ func TestFromUint64(t *testing.T) { } func TestIntPanic(t *testing.T) { + t.Parallel() // Max Int = 2^255-1 = 5.789e+76 // Min Int = -(2^255-1) = -5.789e+76 require.NotPanics(t, func() { NewIntWithDecimal(1, 76) }) @@ -85,6 +88,7 @@ func TestIntPanic(t *testing.T) { // and (U/)Int is immutable value(see TestImmutability(U/)Int) // it is safe to use randomness in the tests func TestIdentInt(t *testing.T) { + t.Parallel() for d := 0; d < 1000; d++ { n := rand.Int63() i := NewInt(n) @@ -121,6 +125,7 @@ func maxint(i1, i2 int64) int64 { } func TestArithInt(t *testing.T) { + t.Parallel() for d := 0; d < 1000; d++ { n1 := int64(rand.Int31()) i1 := NewInt(n1) @@ -152,6 +157,7 @@ func TestArithInt(t *testing.T) { } func TestCompInt(t *testing.T) { + t.Parallel() for d := 0; d < 1000; d++ { n1 := int64(rand.Int31()) i1 := NewInt(n1) @@ -165,6 +171,7 @@ func TestCompInt(t *testing.T) { {i1.Equal(i2), n1 == n2}, {i1.GT(i2), n1 > n2}, {i1.LT(i2), n1 < n2}, + {i1.LTE(i2), n1 <= n2}, } for tcnum, tc := range cases { @@ -192,6 +199,7 @@ func randint() Int { } func TestImmutabilityAllInt(t *testing.T) { + t.Parallel() ops := []func(*Int){ func(i *Int) { _ = i.Add(randint()) }, func(i *Int) { _ = i.Sub(randint()) }, @@ -242,6 +250,7 @@ func intarithraw(uifn func(Int, int64) Int, bifn func(*big.Int, *big.Int, *big.I } func TestImmutabilityArithInt(t *testing.T) { + t.Parallel() size := 500 ops := []intop{ @@ -323,6 +332,7 @@ func TestEncodingRandom(t *testing.T) { } func TestEncodingTableInt(t *testing.T) { + t.Parallel() var i Int cases := []struct { @@ -397,6 +407,7 @@ func TestEncodingTableInt(t *testing.T) { } func TestEncodingTableUint(t *testing.T) { + t.Parallel() var i Uint cases := []struct { @@ -451,6 +462,7 @@ func TestEncodingTableUint(t *testing.T) { } func TestSerializationOverflow(t *testing.T) { + t.Parallel() bx, _ := new(big.Int).SetString("91888242871839275229946405745257275988696311157297823662689937894645226298583", 10) x := Int{bx} y := new(Int) @@ -469,3 +481,37 @@ func TestSerializationOverflow(t *testing.T) { err = y.UnmarshalJSON(bz) require.Error(t, err) } + +func TestIntMod(t *testing.T) { + t.Parallel() + tests := []struct { + name string + x int64 + y int64 + ret int64 + wantPanic bool + }{ + {"3 % 10", 3, 10, 3, false}, + {"10 % 3", 10, 3, 1, false}, + {"4 % 2", 4, 2, 0, false}, + {"2 % 0", 2, 0, 0, true}, + } + + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + if tt.wantPanic { + require.Panics(t, func() { NewInt(tt.x).Mod(NewInt(tt.y)) }) + require.Panics(t, func() { NewInt(tt.x).ModRaw(tt.y) }) + return + } + require.True(t, NewInt(tt.x).Mod(NewInt(tt.y)).Equal(NewInt(tt.ret))) + require.True(t, NewInt(tt.x).ModRaw(tt.y).Equal(NewInt(tt.ret))) + }) + } +} + +func TestIntEq(t *testing.T) { + require.True(IntEq(t, ZeroInt(), ZeroInt())) + require.False(IntEq(t, OneInt(), ZeroInt())) +} diff --git a/types/invariant_test.go b/types/invariant_test.go new file mode 100644 index 000000000000..fe5965011532 --- /dev/null +++ b/types/invariant_test.go @@ -0,0 +1,15 @@ +package types_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func TestFormatInvariant(t *testing.T) { + t.Parallel() + require.Equal(t, ": invariant\n\n", sdk.FormatInvariant("", "", "")) + require.Equal(t, "module: name invariant\nmsg\n", sdk.FormatInvariant("module", "name", "msg")) +} diff --git a/types/result_test.go b/types/result_test.go index 992045778654..08e260d400b0 100644 --- a/types/result_test.go +++ b/types/result_test.go @@ -1,17 +1,24 @@ -package types +package types_test import ( + "encoding/hex" + "strings" "testing" "github.com/stretchr/testify/require" + abci "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/libs/bytes" + ctypes "github.com/tendermint/tendermint/rpc/core/types" "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" ) func TestParseABCILog(t *testing.T) { + t.Parallel() logs := `[{"log":"","msg_index":1,"success":true}]` - res, err := ParseABCILogs(logs) + res, err := sdk.ParseABCILogs(logs) require.NoError(t, err) require.Len(t, res, 1) require.Equal(t, res[0].Log, "") @@ -19,11 +26,155 @@ func TestParseABCILog(t *testing.T) { } func TestABCIMessageLog(t *testing.T) { - events := Events{NewEvent("transfer", NewAttribute("sender", "foo"))} - msgLog := NewABCIMessageLog(0, "", events) + t.Parallel() + events := sdk.Events{sdk.NewEvent("transfer", sdk.NewAttribute("sender", "foo"))} + msgLog := sdk.NewABCIMessageLog(0, "", events) - msgLogs := ABCIMessageLogs{msgLog} + msgLogs := sdk.ABCIMessageLogs{msgLog} bz, err := codec.Cdc.MarshalJSON(msgLogs) require.NoError(t, err) require.Equal(t, string(bz), msgLogs.String()) } + +func TestNewSearchTxsResult(t *testing.T) { + t.Parallel() + got := sdk.NewSearchTxsResult(150, 20, 2, 20, []sdk.TxResponse{}) + require.Equal(t, sdk.SearchTxsResult{ + TotalCount: 150, + Count: 20, + PageNumber: 2, + PageTotal: 8, + Limit: 20, + Txs: []sdk.TxResponse{}, + }, got) +} + +/* + Codespace: res.TxResult.Codespace, + Code: res.TxResult.Code, + Data: strings.ToUpper(hex.EncodeToString(res.TxResult.Data)), + RawLog: res.TxResult.Log, + Logs: parsedLogs, + Info: res.TxResult.Info, + GasWanted: res.TxResult.GasWanted, + GasUsed: res.TxResult.GasUsed, + Tx: tx, + Timestamp: timestamp, +*/ + +func TestResponseResultTx(t *testing.T) { + t.Parallel() + deliverTxResult := abci.ResponseDeliverTx{ + Codespace: "codespace", + Code: 1, + Data: []byte("data"), + Log: `[]`, + Info: "info", + GasWanted: 100, + GasUsed: 90, + } + resultTx := &ctypes.ResultTx{ + Hash: bytes.HexBytes([]byte("test")), + Height: 10, + TxResult: deliverTxResult, + } + logs, err := sdk.ParseABCILogs(`[]`) + require.NoError(t, err) + want := sdk.TxResponse{ + TxHash: "74657374", + Height: 10, + Codespace: "codespace", + Code: 1, + Data: strings.ToUpper(hex.EncodeToString([]byte("data"))), + RawLog: `[]`, + Logs: logs, + Info: "info", + GasWanted: 100, + GasUsed: 90, + Tx: sdk.Tx(nil), + Timestamp: "timestamp", + } + + require.Equal(t, want, sdk.NewResponseResultTx(resultTx, sdk.Tx(nil), "timestamp")) + require.Equal(t, sdk.TxResponse{}, sdk.NewResponseResultTx(nil, sdk.Tx(nil), "timestamp")) + require.Equal(t, `Response: + Height: 10 + TxHash: 74657374 + Code: 1 + Data: 64617461 + Raw Log: [] + Logs: [] + Info: info + GasWanted: 100 + GasUsed: 90 + Codespace: codespace + Timestamp: timestamp`, sdk.NewResponseResultTx(resultTx, sdk.Tx(nil), "timestamp").String()) + require.True(t, sdk.TxResponse{}.Empty()) + require.False(t, want.Empty()) + + resultBroadcastTx := &ctypes.ResultBroadcastTx{ + Code: 1, + Data: []byte("data"), + Log: `[]`, + Hash: bytes.HexBytes([]byte("test")), + } + require.Equal(t, sdk.TxResponse{ + Code: 1, + Data: "64617461", + RawLog: `[]`, + Logs: logs, + TxHash: "74657374", + }, sdk.NewResponseFormatBroadcastTx(resultBroadcastTx)) + require.Equal(t, sdk.TxResponse{}, sdk.NewResponseFormatBroadcastTx(nil)) +} + +func TestResponseFormatBroadcastTxCommit(t *testing.T) { + // test nil + require.Equal(t, sdk.TxResponse{}, sdk.NewResponseFormatBroadcastTxCommit(nil)) + + logs, err := sdk.ParseABCILogs(`[]`) + require.NoError(t, err) + + // test checkTx + checkTxResult := &ctypes.ResultBroadcastTxCommit{ + Height: 10, + Hash: bytes.HexBytes([]byte("test")), + CheckTx: abci.ResponseCheckTx{ + Code: 90, + Data: nil, + Log: `[]`, + Info: "info", + GasWanted: 99, + GasUsed: 100, + Codespace: "codespace", + }, + } + deliverTxResult := &ctypes.ResultBroadcastTxCommit{ + Height: 10, + Hash: bytes.HexBytes([]byte("test")), + DeliverTx: abci.ResponseDeliverTx{ + Code: 90, + Data: nil, + Log: `[]`, + Info: "info", + GasWanted: 99, + GasUsed: 100, + Codespace: "codespace", + }, + } + + want := sdk.TxResponse{ + Height: 10, + TxHash: "74657374", + Codespace: "codespace", + Code: 90, + Data: "", + RawLog: `[]`, + Logs: logs, + Info: "info", + GasWanted: 99, + GasUsed: 100, + } + require.Equal(t, want, sdk.NewResponseFormatBroadcastTxCommit(checkTxResult)) + require.Equal(t, want, sdk.NewResponseFormatBroadcastTxCommit(deliverTxResult)) +} diff --git a/types/staking_test.go b/types/staking_test.go new file mode 100644 index 000000000000..ddeab0d07036 --- /dev/null +++ b/types/staking_test.go @@ -0,0 +1,24 @@ +package types_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func TestBondStatus(t *testing.T) { + require.False(t, sdk.Unbonded.Equal(sdk.Bonded)) + require.False(t, sdk.Unbonded.Equal(sdk.Unbonding)) + require.False(t, sdk.Bonded.Equal(sdk.Unbonding)) + require.Panicsf(t, func() { sdk.BondStatus(0).String() }, "invalid bond status") + require.Equal(t, sdk.BondStatusUnbonded, sdk.BondStatus(sdk.Unbonded).String()) + require.Equal(t, sdk.BondStatusBonded, sdk.BondStatus(sdk.Bonded).String()) + require.Equal(t, sdk.BondStatusUnbonding, sdk.BondStatus(sdk.Unbonding).String()) +} + +func TestTokensToConsensusPower(t *testing.T) { + require.Equal(t, int64(0), sdk.TokensToConsensusPower(sdk.NewInt(999_999))) + require.Equal(t, int64(1), sdk.TokensToConsensusPower(sdk.NewInt(1_000_000))) +} diff --git a/types/store_test.go b/types/store_test.go index 06f609d17471..a4af3a663f65 100644 --- a/types/store_test.go +++ b/types/store_test.go @@ -1,9 +1,14 @@ -package types +package types_test import ( "testing" "github.com/stretchr/testify/require" + dbm "github.com/tendermint/tm-db" + + "github.com/cosmos/cosmos-sdk/store/rootmulti" + "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" ) func TestPrefixEndBytes(t *testing.T) { @@ -21,18 +26,99 @@ func TestPrefixEndBytes(t *testing.T) { } for _, test := range testCases { - end := PrefixEndBytes(test.prefix) + end := sdk.PrefixEndBytes(test.prefix) require.Equal(t, test.expected, end) } } func TestCommitID(t *testing.T) { - var empty CommitID + var empty sdk.CommitID require.True(t, empty.IsZero()) - var nonempty = CommitID{ + var nonempty = sdk.CommitID{ Version: 1, Hash: []byte("testhash"), } require.False(t, nonempty.IsZero()) } + +func TestNewKVStoreKeys(t *testing.T) { + t.Parallel() + require.Equal(t, map[string]*sdk.KVStoreKey{}, sdk.NewKVStoreKeys()) + require.Equal(t, 1, len(sdk.NewKVStoreKeys("one"))) +} + +func TestNewTransientStoreKeys(t *testing.T) { + t.Parallel() + require.Equal(t, map[string]*sdk.TransientStoreKey{}, sdk.NewTransientStoreKeys()) + require.Equal(t, 1, len(sdk.NewTransientStoreKeys("one"))) +} + +func TestNewInfiniteGasMeter(t *testing.T) { + t.Parallel() + gm := sdk.NewInfiniteGasMeter() + require.NotNil(t, gm) + _, ok := gm.(types.GasMeter) + require.True(t, ok) +} + +func TestStoreTypes(t *testing.T) { + t.Parallel() + require.Equal(t, sdk.InclusiveEndBytes([]byte("endbytes")), types.InclusiveEndBytes([]byte("endbytes"))) +} + +func TestDiffKVStores(t *testing.T) { + t.Parallel() + store1, store2 := initTestStores(t) + // Two equal stores + k1, v1 := []byte("k1"), []byte("v1") + store1.Set(k1, v1) + store2.Set(k1, v1) + + checkDiffResults(t, store1, store2) + + // delete k1 from store2, which is now empty + store2.Delete(k1) + checkDiffResults(t, store1, store2) + + // set k1 in store2, different value than what store1 holds for k1 + v2 := []byte("v2") + store2.Set(k1, v2) + checkDiffResults(t, store1, store2) + + // add k2 to store2 + k2 := []byte("k2") + store2.Set(k2, v2) + checkDiffResults(t, store1, store2) + + // Reset stores + store1.Delete(k1) + store2.Delete(k1) + store2.Delete(k2) + + // Same keys, different value. Comparisons will be nil as prefixes are skipped. + prefix := []byte("prefix:") + k1Prefixed := append(prefix, k1...) + store1.Set(k1Prefixed, v1) + store2.Set(k1Prefixed, v2) + checkDiffResults(t, store1, store2) +} + +func initTestStores(t *testing.T) (types.KVStore, types.KVStore) { + db := dbm.NewMemDB() + ms := rootmulti.NewStore(db) + + key1 := types.NewKVStoreKey("store1") + key2 := types.NewKVStoreKey("store2") + require.NotPanics(t, func() { ms.MountStoreWithDB(key1, types.StoreTypeIAVL, db) }) + require.NotPanics(t, func() { ms.MountStoreWithDB(key2, types.StoreTypeIAVL, db) }) + require.NoError(t, ms.LoadLatestVersion()) + return ms.GetKVStore(key1), ms.GetKVStore(key2) +} + +func checkDiffResults(t *testing.T, store1, store2 types.KVStore) { + kvAs1, kvBs1 := sdk.DiffKVStores(store1, store2, nil) + kvAs2, kvBs2 := types.DiffKVStores(store1, store2, nil) + require.Equal(t, kvAs1, kvAs2) + require.Equal(t, kvBs1, kvBs2) +} diff --git a/types/tx_msg_test.go b/types/tx_msg_test.go new file mode 100644 index 000000000000..5023cbec575a --- /dev/null +++ b/types/tx_msg_test.go @@ -0,0 +1,23 @@ +package types_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func TestTestMsg(t *testing.T) { + t.Parallel() + addr := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} + accAddr := sdk.AccAddress(addr) + + msg := sdk.NewTestMsg(accAddr) + require.NotNil(t, msg) + require.Equal(t, "TestMsg", msg.Route()) + require.Equal(t, "Test message", msg.Type()) + require.Nil(t, msg.ValidateBasic()) + require.NotPanics(t, func() { msg.GetSignBytes() }) + require.Equal(t, []sdk.AccAddress{accAddr}, msg.GetSigners()) +} diff --git a/types/uint_test.go b/types/uint_test.go index 548dea5064eb..5f496b5c83d2 100644 --- a/types/uint_test.go +++ b/types/uint_test.go @@ -287,3 +287,15 @@ func TestRelativePow(t *testing.T) { require.Equal(t, tc.want, res, "unexpected result for test case %d, input: %v, got: %v", i, tc.args, res) } } + +func TestUintSize(t *testing.T) { + x := Uint{i: nil} + require.Equal(t, 1, x.Size()) + x = NewUint(0) + require.Equal(t, 1, x.Size()) + x = NewUint(10) + require.Equal(t, 2, x.Size()) + x = NewUint(100) + require.Equal(t, 3, x.Size()) + +} diff --git a/types/utils_test.go b/types/utils_test.go index 6aa652220e55..4ffc67c6101c 100644 --- a/types/utils_test.go +++ b/types/utils_test.go @@ -1,4 +1,4 @@ -package types +package types_test import ( "bytes" @@ -6,6 +6,8 @@ import ( "time" "github.com/stretchr/testify/require" + + sdk "github.com/cosmos/cosmos-sdk/types" ) func TestSortJSON(t *testing.T) { @@ -33,14 +35,14 @@ func TestSortJSON(t *testing.T) { for tcIndex, tc := range cases { tc := tc - got, err := SortJSON([]byte(tc.unsortedJSON)) + got, err := sdk.SortJSON([]byte(tc.unsortedJSON)) if tc.wantErr { require.NotNil(t, err, "tc #%d", tcIndex) - require.Panics(t, func() { MustSortJSON([]byte(tc.unsortedJSON)) }) + require.Panics(t, func() { sdk.MustSortJSON([]byte(tc.unsortedJSON)) }) } else { require.Nil(t, err, "tc #%d, err=%s", tcIndex, err) - require.NotPanics(t, func() { MustSortJSON([]byte(tc.unsortedJSON)) }) - require.Equal(t, got, MustSortJSON([]byte(tc.unsortedJSON))) + require.NotPanics(t, func() { sdk.MustSortJSON([]byte(tc.unsortedJSON)) }) + require.Equal(t, got, sdk.MustSortJSON([]byte(tc.unsortedJSON))) } require.Equal(t, string(got), tc.want) @@ -60,19 +62,42 @@ func TestTimeFormatAndParse(t *testing.T) { tc := tc timeFromRFC, err := time.Parse(time.RFC3339Nano, tc.RFC3339NanoStr) require.Nil(t, err) - timeFromSDKFormat, err := time.Parse(SortableTimeFormat, tc.SDKSortableTimeStr) + timeFromSDKFormat, err := time.Parse(sdk.SortableTimeFormat, tc.SDKSortableTimeStr) require.Nil(t, err) require.True(t, timeFromRFC.Equal(timeFromSDKFormat)) - require.Equal(t, timeFromRFC.Format(SortableTimeFormat), tc.SDKSortableTimeStr) + require.Equal(t, timeFromRFC.Format(sdk.SortableTimeFormat), tc.SDKSortableTimeStr) } } func TestCopyBytes(t *testing.T) { t.Parallel() - require.Nil(t, CopyBytes(nil)) - require.Equal(t, 0, len(CopyBytes([]byte{}))) + require.Nil(t, sdk.CopyBytes(nil)) + require.Equal(t, 0, len(sdk.CopyBytes([]byte{}))) bs := []byte("test") - bsCopy := CopyBytes(bs) + bsCopy := sdk.CopyBytes(bs) require.True(t, bytes.Equal(bs, bsCopy)) } + +func TestUint64ToBigEndian(t *testing.T) { + t.Parallel() + require.Equal(t, []byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, sdk.Uint64ToBigEndian(uint64(0))) + require.Equal(t, []byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa}, sdk.Uint64ToBigEndian(uint64(10))) +} + +func TestFormatTimeBytes(t *testing.T) { + t.Parallel() + tm, err := time.Parse("Jan 2, 2006 at 3:04pm (MST)", "Mar 3, 2020 at 7:54pm (PST)") + require.NoError(t, err) + require.Equal(t, "2020-03-03T19:54:00.000000000", string(sdk.FormatTimeBytes(tm))) +} + +func TestParseTimeBytes(t *testing.T) { + t.Parallel() + tm, err := sdk.ParseTimeBytes([]byte("2020-03-03T19:54:00.000000000")) + require.NoError(t, err) + require.True(t, tm.Equal(time.Date(2020, 3, 3, 19, 54, 0, 0, time.UTC))) + + _, err = sdk.ParseTimeBytes([]byte{}) + require.Error(t, err) +}