github.com/cosmos/cosmos-sdk@v0.50.10/types/module/module_test.go (about) 1 package module_test 2 3 import ( 4 "context" 5 "encoding/json" 6 "errors" 7 "io" 8 "testing" 9 10 abci "github.com/cometbft/cometbft/abci/types" 11 cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" 12 "github.com/golang/mock/gomock" 13 "github.com/spf13/cobra" 14 "github.com/stretchr/testify/require" 15 "google.golang.org/grpc" 16 17 "cosmossdk.io/core/appmodule" 18 "cosmossdk.io/log" 19 20 "github.com/cosmos/cosmos-sdk/codec" 21 "github.com/cosmos/cosmos-sdk/codec/types" 22 "github.com/cosmos/cosmos-sdk/testutil/mock" 23 sdk "github.com/cosmos/cosmos-sdk/types" 24 "github.com/cosmos/cosmos-sdk/types/module" 25 authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" 26 ) 27 28 var errFoo = errors.New("dummy") 29 30 func (MockCoreAppModule) GetQueryCmd() *cobra.Command { 31 return &cobra.Command{ 32 Use: "foo", 33 } 34 } 35 36 func TestBasicManager(t *testing.T) { 37 mockCtrl := gomock.NewController(t) 38 t.Cleanup(mockCtrl.Finish) 39 legacyAmino := codec.NewLegacyAmino() 40 interfaceRegistry := types.NewInterfaceRegistry() 41 cdc := codec.NewProtoCodec(interfaceRegistry) 42 43 // Test with a legacy module, a mock core module that doesn't return anything, 44 // and a core module defined in this file 45 expDefaultGenesis := map[string]json.RawMessage{ 46 "mockAppModuleBasic1": json.RawMessage(``), 47 "mockCoreAppModule2": json.RawMessage(`null`), 48 "mockCoreAppModule3": json.RawMessage(`{ 49 "someField": "someKey" 50 }`), 51 } 52 53 // legacy module 54 mockAppModuleBasic1 := mock.NewMockAppModuleWithAllExtensions(mockCtrl) 55 mockAppModuleBasic1.EXPECT().Name().AnyTimes().Return("mockAppModuleBasic1") 56 mockAppModuleBasic1.EXPECT().DefaultGenesis(gomock.Eq(cdc)).Times(1).Return(json.RawMessage(``)) 57 // Allow ValidateGenesis to be called any times because other module can fail before this one is called. 58 mockAppModuleBasic1.EXPECT().ValidateGenesis(gomock.Eq(cdc), gomock.Eq(nil), gomock.Eq(expDefaultGenesis["mockAppModuleBasic1"])).AnyTimes().Return(nil) 59 mockAppModuleBasic1.EXPECT().RegisterLegacyAminoCodec(gomock.Eq(legacyAmino)).Times(1) 60 mockAppModuleBasic1.EXPECT().RegisterInterfaces(gomock.Eq(interfaceRegistry)).Times(1) 61 62 // mock core API module 63 mockCoreAppModule2 := mock.NewMockCoreAppModule(mockCtrl) 64 mockCoreAppModule2.EXPECT().DefaultGenesis(gomock.Any()).AnyTimes().Return(nil) 65 mockCoreAppModule2.EXPECT().ValidateGenesis(gomock.Any()).AnyTimes().Return(nil) 66 mockAppModule2 := module.CoreAppModuleBasicAdaptor("mockCoreAppModule2", mockCoreAppModule2) 67 68 // mock core API module (but all methods are implemented) 69 mockCoreAppModule3 := module.CoreAppModuleBasicAdaptor("mockCoreAppModule3", MockCoreAppModule{}) 70 71 mm := module.NewBasicManager(mockAppModuleBasic1, mockAppModule2, mockCoreAppModule3) 72 73 require.Equal(t, mockAppModuleBasic1, mm["mockAppModuleBasic1"]) 74 require.Equal(t, mockAppModule2, mm["mockCoreAppModule2"]) 75 require.Equal(t, mockCoreAppModule3, mm["mockCoreAppModule3"]) 76 77 mm.RegisterLegacyAminoCodec(legacyAmino) 78 mm.RegisterInterfaces(interfaceRegistry) 79 80 require.Equal(t, expDefaultGenesis, mm.DefaultGenesis(cdc)) 81 82 var data map[string]string 83 require.Equal(t, map[string]string(nil), data) 84 85 require.ErrorIs(t, mm.ValidateGenesis(cdc, nil, expDefaultGenesis), errFoo) 86 87 mockCmd := &cobra.Command{Use: "root"} 88 mm.AddTxCommands(mockCmd) 89 mm.AddQueryCommands(mockCmd) 90 require.Equal(t, 1, len(mockCmd.Commands())) 91 92 // validate genesis returns nil 93 require.Nil(t, module.NewBasicManager().ValidateGenesis(cdc, nil, expDefaultGenesis)) 94 } 95 96 func TestAssertNoForgottenModules(t *testing.T) { 97 mockCtrl := gomock.NewController(t) 98 t.Cleanup(mockCtrl.Finish) 99 mockAppModule1 := mock.NewMockHasABCIEndBlock(mockCtrl) 100 mockAppModule3 := mock.NewMockCoreAppModule(mockCtrl) 101 102 mockAppModule1.EXPECT().Name().Times(2).Return("module1") 103 mm := module.NewManager( 104 mockAppModule1, 105 module.CoreAppModuleBasicAdaptor("module3", mockAppModule3), 106 ) 107 require.NotNil(t, mm) 108 require.Equal(t, 2, len(mm.Modules)) 109 110 require.Equal(t, []string{"module1", "module3"}, mm.OrderInitGenesis) 111 require.PanicsWithValue(t, "all modules must be defined when setting SetOrderInitGenesis, missing: [module3]", func() { 112 mm.SetOrderInitGenesis("module1") 113 }) 114 115 require.Equal(t, []string{"module1", "module3"}, mm.OrderExportGenesis) 116 require.PanicsWithValue(t, "all modules must be defined when setting SetOrderExportGenesis, missing: [module3]", func() { 117 mm.SetOrderExportGenesis("module1") 118 }) 119 120 require.Equal(t, []string{"module1", "module3"}, mm.OrderEndBlockers) 121 require.PanicsWithValue(t, "all modules must be defined when setting SetOrderEndBlockers, missing: [module1]", func() { 122 mm.SetOrderEndBlockers("module3") 123 }) 124 } 125 126 func TestManagerOrderSetters(t *testing.T) { 127 mockCtrl := gomock.NewController(t) 128 t.Cleanup(mockCtrl.Finish) 129 mockAppModule1 := mock.NewMockAppModule(mockCtrl) 130 mockAppModule2 := mock.NewMockAppModule(mockCtrl) 131 mockAppModule3 := mock.NewMockCoreAppModule(mockCtrl) 132 133 mockAppModule1.EXPECT().Name().Times(2).Return("module1") 134 mockAppModule2.EXPECT().Name().Times(2).Return("module2") 135 mm := module.NewManager(mockAppModule1, mockAppModule2, module.CoreAppModuleBasicAdaptor("module3", mockAppModule3)) 136 require.NotNil(t, mm) 137 require.Equal(t, 3, len(mm.Modules)) 138 139 require.Equal(t, []string{"module1", "module2", "module3"}, mm.OrderInitGenesis) 140 mm.SetOrderInitGenesis("module2", "module1", "module3") 141 require.Equal(t, []string{"module2", "module1", "module3"}, mm.OrderInitGenesis) 142 143 require.Equal(t, []string{"module1", "module2", "module3"}, mm.OrderExportGenesis) 144 mm.SetOrderExportGenesis("module2", "module1", "module3") 145 require.Equal(t, []string{"module2", "module1", "module3"}, mm.OrderExportGenesis) 146 147 require.Equal(t, []string{}, mm.OrderPreBlockers) 148 mm.SetOrderPreBlockers("module2", "module1", "module3") 149 require.Equal(t, []string{"module2", "module1", "module3"}, mm.OrderPreBlockers) 150 151 require.Equal(t, []string{"module1", "module2", "module3"}, mm.OrderBeginBlockers) 152 mm.SetOrderBeginBlockers("module2", "module1", "module3") 153 require.Equal(t, []string{"module2", "module1", "module3"}, mm.OrderBeginBlockers) 154 155 require.Equal(t, []string{"module1", "module2", "module3"}, mm.OrderEndBlockers) 156 mm.SetOrderEndBlockers("module2", "module1", "module3") 157 require.Equal(t, []string{"module2", "module1", "module3"}, mm.OrderEndBlockers) 158 159 require.Equal(t, []string{"module1", "module2", "module3"}, mm.OrderPrepareCheckStaters) 160 mm.SetOrderPrepareCheckStaters("module3", "module2", "module1") 161 require.Equal(t, []string{"module3", "module2", "module1"}, mm.OrderPrepareCheckStaters) 162 163 require.Equal(t, []string{"module1", "module2", "module3"}, mm.OrderPrecommiters) 164 mm.SetOrderPrecommiters("module3", "module2", "module1") 165 require.Equal(t, []string{"module3", "module2", "module1"}, mm.OrderPrecommiters) 166 } 167 168 func TestManager_RegisterInvariants(t *testing.T) { 169 mockCtrl := gomock.NewController(t) 170 t.Cleanup(mockCtrl.Finish) 171 172 mockAppModule1 := mock.NewMockAppModuleWithAllExtensions(mockCtrl) 173 mockAppModule2 := mock.NewMockAppModuleWithAllExtensions(mockCtrl) 174 mockAppModule3 := mock.NewMockCoreAppModule(mockCtrl) 175 mockAppModule1.EXPECT().Name().Times(2).Return("module1") 176 mockAppModule2.EXPECT().Name().Times(2).Return("module2") 177 // TODO: This is not working for Core API modules yet 178 mm := module.NewManager(mockAppModule1, mockAppModule2, module.CoreAppModuleBasicAdaptor("mockAppModule3", mockAppModule3)) 179 require.NotNil(t, mm) 180 require.Equal(t, 3, len(mm.Modules)) 181 182 // test RegisterInvariants 183 mockInvariantRegistry := mock.NewMockInvariantRegistry(mockCtrl) 184 mockAppModule1.EXPECT().RegisterInvariants(gomock.Eq(mockInvariantRegistry)).Times(1) 185 mockAppModule2.EXPECT().RegisterInvariants(gomock.Eq(mockInvariantRegistry)).Times(1) 186 mm.RegisterInvariants(mockInvariantRegistry) 187 } 188 189 func TestManager_RegisterQueryServices(t *testing.T) { 190 mockCtrl := gomock.NewController(t) 191 t.Cleanup(mockCtrl.Finish) 192 193 mockAppModule1 := mock.NewMockAppModuleWithAllExtensions(mockCtrl) 194 mockAppModule2 := mock.NewMockAppModuleWithAllExtensions(mockCtrl) 195 mockAppModule3 := MockCoreAppModule{} 196 mockAppModule1.EXPECT().Name().Times(2).Return("module1") 197 mockAppModule2.EXPECT().Name().Times(2).Return("module2") 198 // TODO: This is not working for Core API modules yet 199 mm := module.NewManager(mockAppModule1, mockAppModule2, module.CoreAppModuleBasicAdaptor("mockAppModule3", mockAppModule3)) 200 require.NotNil(t, mm) 201 require.Equal(t, 3, len(mm.Modules)) 202 203 msgRouter := mock.NewMockServer(mockCtrl) 204 msgRouter.EXPECT().RegisterService(gomock.Any(), gomock.Any()).Times(1) 205 queryRouter := mock.NewMockServer(mockCtrl) 206 queryRouter.EXPECT().RegisterService(gomock.Any(), gomock.Any()).Times(1) 207 208 interfaceRegistry := types.NewInterfaceRegistry() 209 cdc := codec.NewProtoCodec(interfaceRegistry) 210 cfg := module.NewConfigurator(cdc, msgRouter, queryRouter) 211 mockAppModule1.EXPECT().RegisterServices(cfg).Times(1) 212 mockAppModule2.EXPECT().RegisterServices(cfg).Times(1) 213 214 require.NotPanics(t, func() { mm.RegisterServices(cfg) }) 215 } 216 217 func TestManager_InitGenesis(t *testing.T) { 218 mockCtrl := gomock.NewController(t) 219 t.Cleanup(mockCtrl.Finish) 220 221 mockAppModule1 := mock.NewMockAppModuleWithAllExtensions(mockCtrl) 222 mockAppModule2 := mock.NewMockAppModuleWithAllExtensions(mockCtrl) 223 mockAppModule3 := mock.NewMockCoreAppModule(mockCtrl) 224 mockAppModule1.EXPECT().Name().Times(2).Return("module1") 225 mockAppModule2.EXPECT().Name().Times(4).Return("module2") 226 mm := module.NewManager(mockAppModule1, mockAppModule2, module.CoreAppModuleBasicAdaptor("module3", mockAppModule3)) 227 require.NotNil(t, mm) 228 require.Equal(t, 3, len(mm.Modules)) 229 230 ctx := sdk.NewContext(nil, cmtproto.Header{}, false, log.NewNopLogger()) 231 interfaceRegistry := types.NewInterfaceRegistry() 232 cdc := codec.NewProtoCodec(interfaceRegistry) 233 genesisData := map[string]json.RawMessage{"module1": json.RawMessage(`{"key": "value"}`)} 234 235 // this should panic since the validator set is empty even after init genesis 236 mockAppModule1.EXPECT().InitGenesis(gomock.Eq(ctx), gomock.Eq(cdc), gomock.Eq(genesisData["module1"])).Times(1) 237 _, err := mm.InitGenesis(ctx, cdc, genesisData) 238 require.ErrorContains(t, err, "validator set is empty after InitGenesis") 239 240 // test panic 241 genesisData = map[string]json.RawMessage{ 242 "module1": json.RawMessage(`{"key": "value"}`), 243 "module2": json.RawMessage(`{"key": "value"}`), 244 "module3": json.RawMessage(`{"key": "value"}`), 245 } 246 247 mockAppModuleABCI1 := mock.NewMockAppModuleWithAllExtensionsABCI(mockCtrl) 248 mockAppModuleABCI2 := mock.NewMockAppModuleWithAllExtensionsABCI(mockCtrl) 249 mockAppModuleABCI1.EXPECT().Name().Times(4).Return("module1") 250 mockAppModuleABCI2.EXPECT().Name().Times(2).Return("module2") 251 mmABCI := module.NewManager(mockAppModuleABCI1, mockAppModuleABCI2) 252 // panic because more than one module returns validator set updates 253 mockAppModuleABCI1.EXPECT().InitGenesis(gomock.Eq(ctx), gomock.Eq(cdc), gomock.Eq(genesisData["module1"])).Times(1).Return([]abci.ValidatorUpdate{{}}) 254 mockAppModuleABCI2.EXPECT().InitGenesis(gomock.Eq(ctx), gomock.Eq(cdc), gomock.Eq(genesisData["module2"])).Times(1).Return([]abci.ValidatorUpdate{{}}) 255 _, err = mmABCI.InitGenesis(ctx, cdc, genesisData) 256 require.ErrorContains(t, err, "validator InitGenesis updates already set by a previous module") 257 258 // happy path 259 260 mm2 := module.NewManager(mockAppModuleABCI1, mockAppModule2, module.CoreAppModuleBasicAdaptor("module3", mockAppModule3)) 261 mockAppModuleABCI1.EXPECT().InitGenesis(gomock.Eq(ctx), gomock.Eq(cdc), gomock.Eq(genesisData["module1"])).Times(1).Return([]abci.ValidatorUpdate{{}}) 262 mockAppModule2.EXPECT().InitGenesis(gomock.Eq(ctx), gomock.Eq(cdc), gomock.Eq(genesisData["module2"])).Times(1) 263 mockAppModule3.EXPECT().InitGenesis(gomock.Eq(ctx), gomock.Any()).Times(1).Return(nil) 264 _, err = mm2.InitGenesis(ctx, cdc, genesisData) 265 require.NoError(t, err) 266 } 267 268 func TestManager_ExportGenesis(t *testing.T) { 269 mockCtrl := gomock.NewController(t) 270 t.Cleanup(mockCtrl.Finish) 271 272 mockAppModule1 := mock.NewMockAppModuleWithAllExtensions(mockCtrl) 273 mockAppModule2 := mock.NewMockAppModuleWithAllExtensions(mockCtrl) 274 mockCoreAppModule := MockCoreAppModule{} 275 mockAppModule1.EXPECT().Name().Times(2).Return("module1") 276 mockAppModule2.EXPECT().Name().Times(2).Return("module2") 277 mm := module.NewManager(mockAppModule1, mockAppModule2, module.CoreAppModuleBasicAdaptor("mockCoreAppModule", mockCoreAppModule)) 278 require.NotNil(t, mm) 279 require.Equal(t, 3, len(mm.Modules)) 280 281 ctx := sdk.NewContext(nil, cmtproto.Header{}, false, log.NewNopLogger()) 282 interfaceRegistry := types.NewInterfaceRegistry() 283 cdc := codec.NewProtoCodec(interfaceRegistry) 284 mockAppModule1.EXPECT().ExportGenesis(gomock.Eq(ctx), gomock.Eq(cdc)).AnyTimes().Return(json.RawMessage(`{"key1": "value1"}`)) 285 mockAppModule2.EXPECT().ExportGenesis(gomock.Eq(ctx), gomock.Eq(cdc)).AnyTimes().Return(json.RawMessage(`{"key2": "value2"}`)) 286 287 want := map[string]json.RawMessage{ 288 "module1": json.RawMessage(`{"key1": "value1"}`), 289 "module2": json.RawMessage(`{"key2": "value2"}`), 290 "mockCoreAppModule": json.RawMessage(`{ 291 "someField": "someKey" 292 }`), 293 } 294 295 res, err := mm.ExportGenesis(ctx, cdc) 296 require.NoError(t, err) 297 require.Equal(t, want, res) 298 299 res, err = mm.ExportGenesisForModules(ctx, cdc, []string{}) 300 require.NoError(t, err) 301 require.Equal(t, want, res) 302 303 res, err = mm.ExportGenesisForModules(ctx, cdc, []string{"module1"}) 304 require.NoError(t, err) 305 require.Equal(t, map[string]json.RawMessage{"module1": json.RawMessage(`{"key1": "value1"}`)}, res) 306 307 res, err = mm.ExportGenesisForModules(ctx, cdc, []string{"module2"}) 308 require.NoError(t, err) 309 require.NotEqual(t, map[string]json.RawMessage{"module1": json.RawMessage(`{"key1": "value1"}`)}, res) 310 311 _, err = mm.ExportGenesisForModules(ctx, cdc, []string{"module1", "modulefoo"}) 312 require.Error(t, err) 313 } 314 315 func TestManager_EndBlock(t *testing.T) { 316 mockCtrl := gomock.NewController(t) 317 t.Cleanup(mockCtrl.Finish) 318 319 mockAppModule1 := mock.NewMockHasABCIEndBlock(mockCtrl) 320 mockAppModule2 := mock.NewMockHasABCIEndBlock(mockCtrl) 321 mockAppModule3 := mock.NewMockAppModule(mockCtrl) 322 mockAppModule1.EXPECT().Name().Times(2).Return("module1") 323 mockAppModule2.EXPECT().Name().Times(2).Return("module2") 324 mockAppModule3.EXPECT().Name().Times(2).Return("module3") 325 mm := module.NewManager(mockAppModule1, mockAppModule2, mockAppModule3) 326 require.NotNil(t, mm) 327 require.Equal(t, 3, len(mm.Modules)) 328 329 mockAppModule1.EXPECT().EndBlock(gomock.Any()).Times(1).Return([]abci.ValidatorUpdate{{}}, nil) 330 mockAppModule2.EXPECT().EndBlock(gomock.Any()).Times(1) 331 ret, err := mm.EndBlock(sdk.Context{}) 332 require.NoError(t, err) 333 require.Equal(t, []abci.ValidatorUpdate{{}}, ret.ValidatorUpdates) 334 335 // test panic 336 mockAppModule1.EXPECT().EndBlock(gomock.Any()).Times(1).Return([]abci.ValidatorUpdate{{}}, nil) 337 mockAppModule2.EXPECT().EndBlock(gomock.Any()).Times(1).Return([]abci.ValidatorUpdate{{}}, nil) 338 _, err = mm.EndBlock(sdk.Context{}) 339 require.Error(t, err) 340 } 341 342 // Core API exclusive tests 343 func TestCoreAPIManager(t *testing.T) { 344 mockCtrl := gomock.NewController(t) 345 module1 := mock.NewMockCoreAppModule(mockCtrl) 346 module2 := MockCoreAppModule{} 347 mm := module.NewManagerFromMap(map[string]appmodule.AppModule{ 348 "module1": module1, 349 "module2": module2, 350 }) 351 352 require.NotNil(t, mm) 353 require.Equal(t, 2, len(mm.Modules)) 354 require.Equal(t, module1, mm.Modules["module1"]) 355 require.Equal(t, module2, mm.Modules["module2"]) 356 } 357 358 func TestCoreAPIManager_InitGenesis(t *testing.T) { 359 mockCtrl := gomock.NewController(t) 360 t.Cleanup(mockCtrl.Finish) 361 362 mockAppModule1 := mock.NewMockCoreAppModule(mockCtrl) 363 mm := module.NewManagerFromMap(map[string]appmodule.AppModule{"module1": mockAppModule1}) 364 require.NotNil(t, mm) 365 require.Equal(t, 1, len(mm.Modules)) 366 367 ctx := sdk.NewContext(nil, cmtproto.Header{}, false, log.NewNopLogger()) 368 interfaceRegistry := types.NewInterfaceRegistry() 369 cdc := codec.NewProtoCodec(interfaceRegistry) 370 genesisData := map[string]json.RawMessage{"module1": json.RawMessage(`{"key": "value"}`)} 371 372 // this should panic since the validator set is empty even after init genesis 373 mockAppModule1.EXPECT().InitGenesis(gomock.Eq(ctx), gomock.Any()).Times(1).Return(nil) 374 _, err := mm.InitGenesis(ctx, cdc, genesisData) 375 require.ErrorContains(t, err, "validator set is empty after InitGenesis, please ensure at least one validator is initialized with a delegation greater than or equal to the DefaultPowerReduction") 376 377 // TODO: add happy path test. We are not returning any validator updates, this will come with the services. 378 // REF: https://github.com/cosmos/cosmos-sdk/issues/14688 379 } 380 381 func TestCoreAPIManager_ExportGenesis(t *testing.T) { 382 mockAppModule1 := MockCoreAppModule{} 383 mockAppModule2 := MockCoreAppModule{} 384 mm := module.NewManagerFromMap(map[string]appmodule.AppModule{ 385 "module1": mockAppModule1, 386 "module2": mockAppModule2, 387 }) 388 require.NotNil(t, mm) 389 require.Equal(t, 2, len(mm.Modules)) 390 391 ctx := sdk.NewContext(nil, cmtproto.Header{}, false, log.NewNopLogger()) 392 interfaceRegistry := types.NewInterfaceRegistry() 393 cdc := codec.NewProtoCodec(interfaceRegistry) 394 want := map[string]json.RawMessage{ 395 "module1": json.RawMessage(`{ 396 "someField": "someKey" 397 }`), 398 "module2": json.RawMessage(`{ 399 "someField": "someKey" 400 }`), 401 } 402 403 res, err := mm.ExportGenesis(ctx, cdc) 404 require.NoError(t, err) 405 require.Equal(t, want, res) 406 407 res, err = mm.ExportGenesisForModules(ctx, cdc, []string{}) 408 require.NoError(t, err) 409 require.Equal(t, want, res) 410 411 res, err = mm.ExportGenesisForModules(ctx, cdc, []string{"module1"}) 412 require.NoError(t, err) 413 require.Equal(t, map[string]json.RawMessage{"module1": want["module1"]}, res) 414 415 res, err = mm.ExportGenesisForModules(ctx, cdc, []string{"module2"}) 416 require.NoError(t, err) 417 require.NotEqual(t, map[string]json.RawMessage{"module1": want["module1"]}, res) 418 419 _, err = mm.ExportGenesisForModules(ctx, cdc, []string{"module1", "modulefoo"}) 420 require.Error(t, err) 421 } 422 423 func TestCoreAPIManagerOrderSetters(t *testing.T) { 424 mockCtrl := gomock.NewController(t) 425 t.Cleanup(mockCtrl.Finish) 426 mockAppModule1 := mock.NewMockCoreAppModule(mockCtrl) 427 mockAppModule2 := mock.NewMockCoreAppModule(mockCtrl) 428 mockAppModule3 := mock.NewMockCoreAppModule(mockCtrl) 429 430 mm := module.NewManagerFromMap( 431 map[string]appmodule.AppModule{ 432 "module1": mockAppModule1, 433 "module2": mockAppModule2, 434 "module3": mockAppModule3, 435 }) 436 require.NotNil(t, mm) 437 require.Equal(t, 3, len(mm.Modules)) 438 439 require.Equal(t, []string{"module1", "module2", "module3"}, mm.OrderInitGenesis) 440 mm.SetOrderInitGenesis("module2", "module1", "module3") 441 require.Equal(t, []string{"module2", "module1", "module3"}, mm.OrderInitGenesis) 442 443 require.Equal(t, []string{"module1", "module2", "module3"}, mm.OrderExportGenesis) 444 mm.SetOrderExportGenesis("module2", "module1", "module3") 445 require.Equal(t, []string{"module2", "module1", "module3"}, mm.OrderExportGenesis) 446 447 require.Equal(t, []string{}, mm.OrderPreBlockers) 448 mm.SetOrderPreBlockers("module2", "module1", "module3") 449 require.Equal(t, []string{"module2", "module1", "module3"}, mm.OrderPreBlockers) 450 451 require.Equal(t, []string{"module1", "module2", "module3"}, mm.OrderBeginBlockers) 452 mm.SetOrderBeginBlockers("module2", "module1", "module3") 453 require.Equal(t, []string{"module2", "module1", "module3"}, mm.OrderBeginBlockers) 454 455 require.Equal(t, []string{"module1", "module2", "module3"}, mm.OrderEndBlockers) 456 mm.SetOrderEndBlockers("module2", "module1", "module3") 457 require.Equal(t, []string{"module2", "module1", "module3"}, mm.OrderEndBlockers) 458 459 require.Equal(t, []string{"module1", "module2", "module3"}, mm.OrderPrepareCheckStaters) 460 mm.SetOrderPrepareCheckStaters("module3", "module2", "module1") 461 require.Equal(t, []string{"module3", "module2", "module1"}, mm.OrderPrepareCheckStaters) 462 463 require.Equal(t, []string{"module1", "module2", "module3"}, mm.OrderPrecommiters) 464 mm.SetOrderPrecommiters("module3", "module2", "module1") 465 require.Equal(t, []string{"module3", "module2", "module1"}, mm.OrderPrecommiters) 466 } 467 468 func TestCoreAPIManager_PreBlock(t *testing.T) { 469 mockCtrl := gomock.NewController(t) 470 t.Cleanup(mockCtrl.Finish) 471 472 mockAppModule1 := mock.NewMockCoreAppModuleWithPreBlock(mockCtrl) 473 mm := module.NewManagerFromMap(map[string]appmodule.AppModule{ 474 "module1": mockAppModule1, 475 "module2": mock.NewMockCoreAppModule(mockCtrl), 476 }) 477 require.NotNil(t, mm) 478 require.Equal(t, 2, len(mm.Modules)) 479 require.Equal(t, 1, len(mm.OrderPreBlockers)) 480 481 mockAppModule1.EXPECT().PreBlock(gomock.Any()).Times(1).Return(&sdk.ResponsePreBlock{ 482 ConsensusParamsChanged: true, 483 }, nil) 484 res, err := mm.PreBlock(sdk.Context{}) 485 require.NoError(t, err) 486 require.True(t, res.ConsensusParamsChanged) 487 488 // test false 489 mockAppModule1.EXPECT().PreBlock(gomock.Any()).Times(1).Return(&sdk.ResponsePreBlock{ 490 ConsensusParamsChanged: false, 491 }, nil) 492 res, err = mm.PreBlock(sdk.Context{}) 493 require.NoError(t, err) 494 require.False(t, res.ConsensusParamsChanged) 495 496 // test error 497 mockAppModule1.EXPECT().PreBlock(gomock.Any()).Times(1).Return(nil, errors.New("some error")) 498 _, err = mm.PreBlock(sdk.Context{}) 499 require.EqualError(t, err, "some error") 500 } 501 502 func TestCoreAPIManager_BeginBlock(t *testing.T) { 503 mockCtrl := gomock.NewController(t) 504 t.Cleanup(mockCtrl.Finish) 505 506 mockAppModule1 := mock.NewMockCoreAppModule(mockCtrl) 507 mockAppModule2 := mock.NewMockCoreAppModule(mockCtrl) 508 mm := module.NewManagerFromMap(map[string]appmodule.AppModule{ 509 "module1": mockAppModule1, 510 "module2": mockAppModule2, 511 }) 512 require.NotNil(t, mm) 513 require.Equal(t, 2, len(mm.Modules)) 514 515 mockAppModule1.EXPECT().BeginBlock(gomock.Any()).Times(1).Return(nil) 516 mockAppModule2.EXPECT().BeginBlock(gomock.Any()).Times(1).Return(nil) 517 _, err := mm.BeginBlock(sdk.Context{}) 518 require.NoError(t, err) 519 520 // test panic 521 mockAppModule1.EXPECT().BeginBlock(gomock.Any()).Times(1).Return(errors.New("some error")) 522 _, err = mm.BeginBlock(sdk.Context{}) 523 require.EqualError(t, err, "some error") 524 } 525 526 func TestCoreAPIManager_EndBlock(t *testing.T) { 527 mockCtrl := gomock.NewController(t) 528 t.Cleanup(mockCtrl.Finish) 529 530 mockAppModule1 := mock.NewMockCoreAppModule(mockCtrl) 531 mockAppModule2 := mock.NewMockCoreAppModule(mockCtrl) 532 mm := module.NewManagerFromMap(map[string]appmodule.AppModule{ 533 "module1": mockAppModule1, 534 "module2": mockAppModule2, 535 }) 536 require.NotNil(t, mm) 537 require.Equal(t, 2, len(mm.Modules)) 538 539 mockAppModule1.EXPECT().EndBlock(gomock.Any()).Times(1).Return(nil) 540 mockAppModule2.EXPECT().EndBlock(gomock.Any()).Times(1).Return(nil) 541 res, err := mm.EndBlock(sdk.Context{}) 542 require.NoError(t, err) 543 require.Len(t, res.ValidatorUpdates, 0) 544 545 // test panic 546 mockAppModule1.EXPECT().EndBlock(gomock.Any()).Times(1).Return(errors.New("some error")) 547 _, err = mm.EndBlock(sdk.Context{}) 548 require.EqualError(t, err, "some error") 549 } 550 551 func TestManager_PrepareCheckState(t *testing.T) { 552 mockCtrl := gomock.NewController(t) 553 t.Cleanup(mockCtrl.Finish) 554 555 mockAppModule1 := mock.NewMockCoreAppModule(mockCtrl) 556 mockAppModule2 := mock.NewMockCoreAppModule(mockCtrl) 557 mm := module.NewManagerFromMap(map[string]appmodule.AppModule{ 558 "module1": mockAppModule1, 559 "module2": mockAppModule2, 560 }) 561 require.NotNil(t, mm) 562 require.Equal(t, 2, len(mm.Modules)) 563 564 mockAppModule1.EXPECT().PrepareCheckState(gomock.Any()).Times(1).Return(nil) 565 mockAppModule2.EXPECT().PrepareCheckState(gomock.Any()).Times(1).Return(nil) 566 err := mm.PrepareCheckState(sdk.Context{}) 567 require.NoError(t, err) 568 569 mockAppModule1.EXPECT().PrepareCheckState(gomock.Any()).Times(1).Return(errors.New("some error")) 570 err = mm.PrepareCheckState(sdk.Context{}) 571 require.EqualError(t, err, "some error") 572 } 573 574 func TestManager_Precommit(t *testing.T) { 575 mockCtrl := gomock.NewController(t) 576 t.Cleanup(mockCtrl.Finish) 577 578 mockAppModule1 := mock.NewMockCoreAppModule(mockCtrl) 579 mockAppModule2 := mock.NewMockCoreAppModule(mockCtrl) 580 mm := module.NewManagerFromMap(map[string]appmodule.AppModule{ 581 "module1": mockAppModule1, 582 "module2": mockAppModule2, 583 }) 584 require.NotNil(t, mm) 585 require.Equal(t, 2, len(mm.Modules)) 586 587 mockAppModule1.EXPECT().Precommit(gomock.Any()).Times(1).Return(nil) 588 mockAppModule2.EXPECT().Precommit(gomock.Any()).Times(1).Return(nil) 589 err := mm.Precommit(sdk.Context{}) 590 require.NoError(t, err) 591 592 mockAppModule1.EXPECT().Precommit(gomock.Any()).Times(1).Return(errors.New("some error")) 593 err = mm.Precommit(sdk.Context{}) 594 require.EqualError(t, err, "some error") 595 } 596 597 // MockCoreAppModule allows us to test functions like DefaultGenesis 598 type MockCoreAppModule struct{} 599 600 // RegisterServices implements appmodule.HasServices 601 func (MockCoreAppModule) RegisterServices(reg grpc.ServiceRegistrar) error { 602 // Use Auth's service definitions as a placeholder 603 authtypes.RegisterQueryServer(reg, &authtypes.UnimplementedQueryServer{}) 604 authtypes.RegisterMsgServer(reg, &authtypes.UnimplementedMsgServer{}) 605 return nil 606 } 607 608 func (MockCoreAppModule) IsOnePerModuleType() {} 609 func (MockCoreAppModule) IsAppModule() {} 610 func (MockCoreAppModule) DefaultGenesis(target appmodule.GenesisTarget) error { 611 someFieldWriter, err := target("someField") 612 if err != nil { 613 return err 614 } 615 someFieldWriter.Write([]byte(`"someKey"`)) 616 return someFieldWriter.Close() 617 } 618 619 func (MockCoreAppModule) ValidateGenesis(src appmodule.GenesisSource) error { 620 rdr, err := src("someField") 621 if err != nil { 622 return err 623 } 624 data, err := io.ReadAll(rdr) 625 if err != nil { 626 return err 627 } 628 629 // this check will always fail, but it's just an example 630 if string(data) != `"dummy validation"` { 631 return errFoo 632 } 633 634 return nil 635 } 636 func (MockCoreAppModule) InitGenesis(context.Context, appmodule.GenesisSource) error { return nil } 637 func (MockCoreAppModule) ExportGenesis(ctx context.Context, target appmodule.GenesisTarget) error { 638 wrt, err := target("someField") 639 if err != nil { 640 return err 641 } 642 wrt.Write([]byte(`"someKey"`)) 643 return wrt.Close() 644 } 645 646 var ( 647 _ appmodule.AppModule = MockCoreAppModule{} 648 _ appmodule.HasGenesis = MockCoreAppModule{} 649 _ appmodule.HasServices = MockCoreAppModule{} 650 )