github.com/cosmos/cosmos-sdk@v0.50.10/testutil/integration/example_test.go (about)

     1  package integration_test
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  
     7  	cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"
     8  	"github.com/google/go-cmp/cmp"
     9  
    10  	"cosmossdk.io/core/appmodule"
    11  	"cosmossdk.io/log"
    12  	storetypes "cosmossdk.io/store/types"
    13  
    14  	addresscodec "github.com/cosmos/cosmos-sdk/codec/address"
    15  	"github.com/cosmos/cosmos-sdk/runtime"
    16  	"github.com/cosmos/cosmos-sdk/testutil/integration"
    17  	sdk "github.com/cosmos/cosmos-sdk/types"
    18  	moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil"
    19  	"github.com/cosmos/cosmos-sdk/x/auth"
    20  	authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
    21  	authsims "github.com/cosmos/cosmos-sdk/x/auth/simulation"
    22  	authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
    23  	"github.com/cosmos/cosmos-sdk/x/mint"
    24  	mintkeeper "github.com/cosmos/cosmos-sdk/x/mint/keeper"
    25  	minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
    26  )
    27  
    28  // Example shows how to use the integration test framework to test the integration of SDK modules.
    29  // Panics are used in this example, but in a real test case, you should use the testing.T object and assertions.
    30  func Example() {
    31  	// in this example we are testing the integration of the following modules:
    32  	// - mint, which directly depends on auth, bank and staking
    33  	encodingCfg := moduletestutil.MakeTestEncodingConfig(auth.AppModuleBasic{}, mint.AppModuleBasic{})
    34  	keys := storetypes.NewKVStoreKeys(authtypes.StoreKey, minttypes.StoreKey)
    35  	authority := authtypes.NewModuleAddress("gov").String()
    36  
    37  	// replace the logger by testing values in a real test case (e.g. log.NewTestLogger(t))
    38  	logger := log.NewNopLogger()
    39  
    40  	cms := integration.CreateMultiStore(keys, logger)
    41  	newCtx := sdk.NewContext(cms, cmtproto.Header{}, true, logger)
    42  
    43  	accountKeeper := authkeeper.NewAccountKeeper(
    44  		encodingCfg.Codec,
    45  		runtime.NewKVStoreService(keys[authtypes.StoreKey]),
    46  		authtypes.ProtoBaseAccount,
    47  		map[string][]string{minttypes.ModuleName: {authtypes.Minter}},
    48  		addresscodec.NewBech32Codec("cosmos"),
    49  		"cosmos",
    50  		authority,
    51  	)
    52  
    53  	// subspace is nil because we don't test params (which is legacy anyway)
    54  	authModule := auth.NewAppModule(encodingCfg.Codec, accountKeeper, authsims.RandomGenesisAccounts, nil)
    55  
    56  	// here bankkeeper and staking keeper is nil because we are not testing them
    57  	// subspace is nil because we don't test params (which is legacy anyway)
    58  	mintKeeper := mintkeeper.NewKeeper(encodingCfg.Codec, runtime.NewKVStoreService(keys[minttypes.StoreKey]), nil, accountKeeper, nil, authtypes.FeeCollectorName, authority)
    59  	mintModule := mint.NewAppModule(encodingCfg.Codec, mintKeeper, accountKeeper, nil, nil)
    60  
    61  	// create the application and register all the modules from the previous step
    62  	integrationApp := integration.NewIntegrationApp(
    63  		newCtx,
    64  		logger,
    65  		keys,
    66  		encodingCfg.Codec,
    67  		map[string]appmodule.AppModule{
    68  			authtypes.ModuleName: authModule,
    69  			minttypes.ModuleName: mintModule,
    70  		},
    71  	)
    72  
    73  	// register the message and query servers
    74  	authtypes.RegisterMsgServer(integrationApp.MsgServiceRouter(), authkeeper.NewMsgServerImpl(accountKeeper))
    75  	minttypes.RegisterMsgServer(integrationApp.MsgServiceRouter(), mintkeeper.NewMsgServerImpl(mintKeeper))
    76  	minttypes.RegisterQueryServer(integrationApp.QueryHelper(), mintkeeper.NewQueryServerImpl(mintKeeper))
    77  
    78  	params := minttypes.DefaultParams()
    79  	params.BlocksPerYear = 10000
    80  
    81  	// now we can use the application to test a mint message
    82  	result, err := integrationApp.RunMsg(&minttypes.MsgUpdateParams{
    83  		Authority: authority,
    84  		Params:    params,
    85  	})
    86  	if err != nil {
    87  		panic(err)
    88  	}
    89  
    90  	// in this example the result is an empty response, a nil check is enough
    91  	// in other cases, it is recommended to check the result value.
    92  	if result == nil {
    93  		panic(fmt.Errorf("unexpected nil result"))
    94  	}
    95  
    96  	// we now check the result
    97  	resp := minttypes.MsgUpdateParamsResponse{}
    98  	err = encodingCfg.Codec.Unmarshal(result.Value, &resp)
    99  	if err != nil {
   100  		panic(err)
   101  	}
   102  
   103  	sdkCtx := sdk.UnwrapSDKContext(integrationApp.Context())
   104  
   105  	// we should also check the state of the application
   106  	got, err := mintKeeper.Params.Get(sdkCtx)
   107  	if err != nil {
   108  		panic(err)
   109  	}
   110  
   111  	if diff := cmp.Diff(got, params); diff != "" {
   112  		panic(diff)
   113  	}
   114  	fmt.Println(got.BlocksPerYear)
   115  	// Output: 10000
   116  }
   117  
   118  // ExampleOneModule shows how to use the integration test framework to test the integration of a single module.
   119  // That module has no dependency on other modules.
   120  func Example_oneModule() {
   121  	// in this example we are testing the integration of the auth module:
   122  	encodingCfg := moduletestutil.MakeTestEncodingConfig(auth.AppModuleBasic{})
   123  	keys := storetypes.NewKVStoreKeys(authtypes.StoreKey)
   124  	authority := authtypes.NewModuleAddress("gov").String()
   125  
   126  	// replace the logger by testing values in a real test case (e.g. log.NewTestLogger(t))
   127  	logger := log.NewLogger(io.Discard)
   128  
   129  	cms := integration.CreateMultiStore(keys, logger)
   130  	newCtx := sdk.NewContext(cms, cmtproto.Header{}, true, logger)
   131  
   132  	accountKeeper := authkeeper.NewAccountKeeper(
   133  		encodingCfg.Codec,
   134  		runtime.NewKVStoreService(keys[authtypes.StoreKey]),
   135  		authtypes.ProtoBaseAccount,
   136  		map[string][]string{minttypes.ModuleName: {authtypes.Minter}},
   137  		addresscodec.NewBech32Codec("cosmos"),
   138  		"cosmos",
   139  		authority,
   140  	)
   141  
   142  	// subspace is nil because we don't test params (which is legacy anyway)
   143  	authModule := auth.NewAppModule(encodingCfg.Codec, accountKeeper, authsims.RandomGenesisAccounts, nil)
   144  
   145  	// create the application and register all the modules from the previous step
   146  	integrationApp := integration.NewIntegrationApp(
   147  		newCtx,
   148  		logger,
   149  		keys,
   150  		encodingCfg.Codec,
   151  		map[string]appmodule.AppModule{
   152  			authtypes.ModuleName: authModule,
   153  		},
   154  	)
   155  
   156  	// register the message and query servers
   157  	authtypes.RegisterMsgServer(integrationApp.MsgServiceRouter(), authkeeper.NewMsgServerImpl(accountKeeper))
   158  
   159  	params := authtypes.DefaultParams()
   160  	params.MaxMemoCharacters = 1000
   161  
   162  	// now we can use the application to test a mint message
   163  	result, err := integrationApp.RunMsg(&authtypes.MsgUpdateParams{
   164  		Authority: authority,
   165  		Params:    params,
   166  	},
   167  		// this allows to the begin and end blocker of the module before and after the message
   168  		integration.WithAutomaticFinalizeBlock(),
   169  		// this allows to commit the state after the message
   170  		integration.WithAutomaticCommit(),
   171  	)
   172  	if err != nil {
   173  		panic(err)
   174  	}
   175  
   176  	// verify that the begin and end blocker were called
   177  	// NOTE: in this example, we are testing auth, which doesn't have any begin or end blocker
   178  	// so verifying the block height is enough
   179  	if integrationApp.LastBlockHeight() != 2 {
   180  		panic(fmt.Errorf("expected block height to be 2, got %d", integrationApp.LastBlockHeight()))
   181  	}
   182  
   183  	// in this example the result is an empty response, a nil check is enough
   184  	// in other cases, it is recommended to check the result value.
   185  	if result == nil {
   186  		panic(fmt.Errorf("unexpected nil result"))
   187  	}
   188  
   189  	// we now check the result
   190  	resp := authtypes.MsgUpdateParamsResponse{}
   191  	err = encodingCfg.Codec.Unmarshal(result.Value, &resp)
   192  	if err != nil {
   193  		panic(err)
   194  	}
   195  
   196  	sdkCtx := sdk.UnwrapSDKContext(integrationApp.Context())
   197  
   198  	// we should also check the state of the application
   199  	got := accountKeeper.GetParams(sdkCtx)
   200  	if diff := cmp.Diff(got, params); diff != "" {
   201  		panic(diff)
   202  	}
   203  	fmt.Println(got.MaxMemoCharacters)
   204  	// Output: 1000
   205  }