github.com/Finschia/finschia-sdk@v0.48.1/x/capability/capability_test.go (about) 1 package capability_test 2 3 import ( 4 "testing" 5 6 "github.com/stretchr/testify/suite" 7 tmproto "github.com/tendermint/tendermint/proto/tendermint/types" 8 9 "github.com/Finschia/finschia-sdk/codec" 10 "github.com/Finschia/finschia-sdk/simapp" 11 sdk "github.com/Finschia/finschia-sdk/types" 12 "github.com/Finschia/finschia-sdk/types/module" 13 banktypes "github.com/Finschia/finschia-sdk/x/bank/types" 14 "github.com/Finschia/finschia-sdk/x/capability" 15 "github.com/Finschia/finschia-sdk/x/capability/keeper" 16 "github.com/Finschia/finschia-sdk/x/capability/types" 17 ocabci "github.com/Finschia/ostracon/abci/types" 18 ) 19 20 type CapabilityTestSuite struct { 21 suite.Suite 22 23 cdc codec.Codec 24 ctx sdk.Context 25 app *simapp.SimApp 26 keeper *keeper.Keeper 27 module module.AppModule 28 } 29 30 func (suite *CapabilityTestSuite) SetupTest() { 31 checkTx := false 32 app := simapp.Setup(checkTx) 33 cdc := app.AppCodec() 34 35 // create new keeper so we can define custom scoping before init and seal 36 keeper := keeper.NewKeeper(cdc, app.GetKey(types.StoreKey), app.GetMemKey(types.MemStoreKey)) 37 38 suite.app = app 39 suite.ctx = app.BaseApp.NewContext(checkTx, tmproto.Header{Height: 1}) 40 suite.keeper = keeper 41 suite.cdc = cdc 42 suite.module = capability.NewAppModule(cdc, *keeper) 43 } 44 45 // The following test case mocks a specific bug discovered in https://github.com/cosmos/cosmos-sdk/issues/9800 46 // and ensures that the current code successfully fixes the issue. 47 func (suite *CapabilityTestSuite) TestInitializeMemStore() { 48 sk1 := suite.keeper.ScopeToModule(banktypes.ModuleName) 49 50 cap1, err := sk1.NewCapability(suite.ctx, "transfer") 51 suite.Require().NoError(err) 52 suite.Require().NotNil(cap1) 53 54 // mock statesync by creating new keeper that shares persistent state but loses in-memory map 55 newKeeper := keeper.NewKeeper(suite.cdc, suite.app.GetKey(types.StoreKey), suite.app.GetMemKey("testingkey")) 56 newSk1 := newKeeper.ScopeToModule(banktypes.ModuleName) 57 58 // Mock App startup 59 ctx := suite.app.BaseApp.NewUncachedContext(false, tmproto.Header{}) 60 newKeeper.Seal() 61 suite.Require().False(newKeeper.IsInitialized(ctx), "memstore initialized flag set before BeginBlock") 62 63 // Mock app beginblock and ensure that no gas has been consumed and memstore is initialized 64 ctx = suite.app.BaseApp.NewContext(false, tmproto.Header{}).WithBlockGasMeter(sdk.NewGasMeter(50)) 65 prevGas := ctx.BlockGasMeter().GasConsumed() 66 restartedModule := capability.NewAppModule(suite.cdc, *newKeeper) 67 restartedModule.BeginBlock(ctx, ocabci.RequestBeginBlock{}) 68 suite.Require().True(newKeeper.IsInitialized(ctx), "memstore initialized flag not set") 69 gasUsed := ctx.BlockGasMeter().GasConsumed() 70 71 suite.Require().Equal(prevGas, gasUsed, "beginblocker consumed gas during execution") 72 73 // Mock the first transaction getting capability and subsequently failing 74 // by using a cached context and discarding all cached writes. 75 cacheCtx, _ := ctx.CacheContext() 76 _, ok := newSk1.GetCapability(cacheCtx, "transfer") 77 suite.Require().True(ok) 78 79 // Ensure that the second transaction can still receive capability even if first tx fails. 80 ctx = suite.app.BaseApp.NewContext(false, tmproto.Header{}) 81 82 cap1, ok = newSk1.GetCapability(ctx, "transfer") 83 suite.Require().True(ok) 84 85 // Ensure the capabilities don't get reinitialized on next BeginBlock 86 // by testing to see if capability returns same pointer 87 // also check that initialized flag is still set 88 restartedModule.BeginBlock(ctx, ocabci.RequestBeginBlock{}) 89 recap, ok := newSk1.GetCapability(ctx, "transfer") 90 suite.Require().True(ok) 91 suite.Require().Equal(cap1, recap, "capabilities got reinitialized after second BeginBlock") 92 suite.Require().True(newKeeper.IsInitialized(ctx), "memstore initialized flag not set") 93 } 94 95 func TestCapabilityTestSuite(t *testing.T) { 96 suite.Run(t, new(CapabilityTestSuite)) 97 }