github.com/Finschia/finschia-sdk@v0.48.1/types/context_test.go (about) 1 package types_test 2 3 import ( 4 "context" 5 "testing" 6 "time" 7 8 "github.com/golang/mock/gomock" 9 "github.com/stretchr/testify/suite" 10 abci "github.com/tendermint/tendermint/abci/types" 11 tmproto "github.com/tendermint/tendermint/proto/tendermint/types" 12 13 "github.com/Finschia/finschia-sdk/crypto/keys/secp256k1" 14 "github.com/Finschia/finschia-sdk/tests/mocks" 15 "github.com/Finschia/finschia-sdk/testutil" 16 "github.com/Finschia/finschia-sdk/types" 17 ) 18 19 type contextTestSuite struct { 20 suite.Suite 21 } 22 23 func TestContextTestSuite(t *testing.T) { 24 suite.Run(t, new(contextTestSuite)) 25 } 26 27 func (s *contextTestSuite) TestCacheContext() { 28 key := types.NewKVStoreKey(s.T().Name() + "_TestCacheContext") 29 k1 := []byte("hello") 30 v1 := []byte("world") 31 k2 := []byte("key") 32 v2 := []byte("value") 33 34 ctx := testutil.DefaultContext(key, types.NewTransientStoreKey("transient_"+s.T().Name())) 35 store := ctx.KVStore(key) 36 store.Set(k1, v1) 37 s.Require().Equal(v1, store.Get(k1)) 38 s.Require().Nil(store.Get(k2)) 39 40 cctx, write := ctx.CacheContext() 41 cstore := cctx.KVStore(key) 42 s.Require().Equal(v1, cstore.Get(k1)) 43 s.Require().Nil(cstore.Get(k2)) 44 45 cstore.Set(k2, v2) 46 s.Require().Equal(v2, cstore.Get(k2)) 47 s.Require().Nil(store.Get(k2)) 48 49 write() 50 51 s.Require().Equal(v2, store.Get(k2)) 52 } 53 54 func (s *contextTestSuite) TestLogContext() { 55 key := types.NewKVStoreKey(s.T().Name()) 56 ctx := testutil.DefaultContext(key, types.NewTransientStoreKey("transient_"+s.T().Name())) 57 ctrl := gomock.NewController(s.T()) 58 s.T().Cleanup(ctrl.Finish) 59 60 logger := mocks.NewMockLogger(ctrl) 61 logger.EXPECT().Debug("debug") 62 logger.EXPECT().Info("info") 63 logger.EXPECT().Error("error") 64 65 ctx = ctx.WithLogger(logger) 66 ctx.Logger().Debug("debug") 67 ctx.Logger().Info("info") 68 ctx.Logger().Error("error") 69 } 70 71 type dummy int64 //nolint:unused 72 73 func (d dummy) Clone() interface{} { 74 return d 75 } 76 77 // Testing saving/loading sdk type values to/from the context 78 func (s *contextTestSuite) TestContextWithCustom() { 79 var ctx types.Context 80 s.Require().True(ctx.IsZero()) 81 82 ctrl := gomock.NewController(s.T()) 83 s.T().Cleanup(ctrl.Finish) 84 85 header := tmproto.Header{} 86 height := int64(1) 87 chainid := "chainid" 88 ischeck := true 89 txbytes := []byte("txbytes") 90 logger := mocks.NewMockLogger(ctrl) 91 voteinfos := []abci.VoteInfo{{}} 92 meter := types.NewGasMeter(10000) 93 blockGasMeter := types.NewGasMeter(20000) 94 minGasPrices := types.DecCoins{types.NewInt64DecCoin("feetoken", 1)} 95 headerHash := []byte("headerHash") 96 97 ctx = types.NewContext(nil, header, ischeck, logger) 98 s.Require().Equal(header, ctx.BlockHeader()) 99 100 ctx = ctx. 101 WithBlockHeight(height). 102 WithChainID(chainid). 103 WithTxBytes(txbytes). 104 WithVoteInfos(voteinfos). 105 WithGasMeter(meter). 106 WithMinGasPrices(minGasPrices). 107 WithBlockGasMeter(blockGasMeter). 108 WithHeaderHash(headerHash) 109 s.Require().Equal(height, ctx.BlockHeight()) 110 s.Require().Equal(chainid, ctx.ChainID()) 111 s.Require().Equal(ischeck, ctx.IsCheckTx()) 112 s.Require().Equal(txbytes, ctx.TxBytes()) 113 s.Require().Equal(logger, ctx.Logger()) 114 s.Require().Equal(voteinfos, ctx.VoteInfos()) 115 s.Require().Equal(meter, ctx.GasMeter()) 116 s.Require().Equal(minGasPrices, ctx.MinGasPrices()) 117 s.Require().Equal(blockGasMeter, ctx.BlockGasMeter()) 118 s.Require().Equal(headerHash, ctx.HeaderHash().Bytes()) 119 s.Require().False(ctx.WithIsCheckTx(false).IsCheckTx()) 120 121 // test IsReCheckTx 122 s.Require().False(ctx.IsReCheckTx()) 123 ctx = ctx.WithIsCheckTx(false) 124 ctx = ctx.WithIsReCheckTx(true) 125 s.Require().True(ctx.IsCheckTx()) 126 s.Require().True(ctx.IsReCheckTx()) 127 128 // test consensus param 129 s.Require().Nil(ctx.ConsensusParams()) 130 cp := &abci.ConsensusParams{} 131 s.Require().Equal(cp, ctx.WithConsensusParams(cp).ConsensusParams()) 132 133 // test inner context 134 newContext := context.WithValue(ctx.Context(), "key", "value") //nolint:golint,staticcheck 135 s.Require().NotEqual(ctx.Context(), ctx.WithContext(newContext).Context()) 136 } 137 138 // Testing saving/loading of header fields to/from the context 139 func (s *contextTestSuite) TestContextHeader() { 140 var ctx types.Context 141 142 height := int64(5) 143 time := time.Now() 144 addr := secp256k1.GenPrivKey().PubKey().Address() 145 proposer := types.ConsAddress(addr) 146 147 ctx = types.NewContext(nil, tmproto.Header{}, false, nil) 148 149 ctx = ctx. 150 WithBlockHeight(height). 151 WithBlockTime(time). 152 WithProposer(proposer) 153 s.Require().Equal(height, ctx.BlockHeight()) 154 s.Require().Equal(height, ctx.BlockHeader().Height) 155 s.Require().Equal(time.UTC(), ctx.BlockHeader().Time) 156 s.Require().Equal(proposer.Bytes(), ctx.BlockHeader().ProposerAddress) 157 } 158 159 func (s *contextTestSuite) TestContextHeaderClone() { 160 cases := map[string]struct { 161 h tmproto.Header 162 }{ 163 "empty": { 164 h: tmproto.Header{}, 165 }, 166 "height": { 167 h: tmproto.Header{ 168 Height: 77, 169 }, 170 }, 171 "time": { 172 h: tmproto.Header{ 173 Time: time.Unix(12345677, 12345), 174 }, 175 }, 176 "zero time": { 177 h: tmproto.Header{ 178 Time: time.Unix(0, 0), 179 }, 180 }, 181 "many items": { 182 h: tmproto.Header{ 183 Height: 823, 184 Time: time.Unix(9999999999, 0), 185 ChainID: "silly-demo", 186 }, 187 }, 188 "many items with hash": { 189 h: tmproto.Header{ 190 Height: 823, 191 Time: time.Unix(9999999999, 0), 192 ChainID: "silly-demo", 193 AppHash: []byte{5, 34, 11, 3, 23}, 194 ConsensusHash: []byte{11, 3, 23, 87, 3, 1}, 195 }, 196 }, 197 } 198 199 for name, tc := range cases { 200 tc := tc 201 s.T().Run(name, func(t *testing.T) { 202 ctx := types.NewContext(nil, tc.h, false, nil) 203 s.Require().Equal(tc.h.Height, ctx.BlockHeight()) 204 s.Require().Equal(tc.h.Time.UTC(), ctx.BlockTime()) 205 206 // update only changes one field 207 var newHeight int64 = 17 208 ctx = ctx.WithBlockHeight(newHeight) 209 s.Require().Equal(newHeight, ctx.BlockHeight()) 210 s.Require().Equal(tc.h.Time.UTC(), ctx.BlockTime()) 211 }) 212 } 213 } 214 215 func (s *contextTestSuite) TestUnwrapSDKContext() { 216 sdkCtx := types.NewContext(nil, tmproto.Header{}, false, nil) 217 ctx := types.WrapSDKContext(sdkCtx) 218 sdkCtx2 := types.UnwrapSDKContext(ctx) 219 s.Require().Equal(sdkCtx, sdkCtx2) 220 221 ctx = context.Background() 222 s.Require().Panics(func() { types.UnwrapSDKContext(ctx) }) 223 }