github.com/Finschia/finschia-sdk@v0.48.1/x/upgrade/keeper/keeper_test.go (about)

     1  package keeper_test
     2  
     3  import (
     4  	"path/filepath"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/stretchr/testify/suite"
     9  	tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
    10  
    11  	"github.com/Finschia/finschia-sdk/simapp"
    12  	store "github.com/Finschia/finschia-sdk/store/types"
    13  	sdk "github.com/Finschia/finschia-sdk/types"
    14  	"github.com/Finschia/finschia-sdk/types/module"
    15  	"github.com/Finschia/finschia-sdk/x/upgrade/keeper"
    16  	"github.com/Finschia/finschia-sdk/x/upgrade/types"
    17  )
    18  
    19  type KeeperTestSuite struct {
    20  	suite.Suite
    21  
    22  	homeDir string
    23  	app     *simapp.SimApp
    24  	ctx     sdk.Context
    25  }
    26  
    27  func (s *KeeperTestSuite) SetupTest() {
    28  	app := simapp.Setup(false)
    29  	homeDir := filepath.Join(s.T().TempDir(), "x_upgrade_keeper_test")
    30  	app.UpgradeKeeper = keeper.NewKeeper( // recreate keeper in order to use a custom home path
    31  		make(map[int64]bool), app.GetKey(types.StoreKey), app.AppCodec(), homeDir, app.BaseApp,
    32  	)
    33  	s.T().Log("home dir:", homeDir)
    34  	s.homeDir = homeDir
    35  	s.app = app
    36  	s.ctx = app.BaseApp.NewContext(false, tmproto.Header{
    37  		Time:   time.Now(),
    38  		Height: 10,
    39  	})
    40  }
    41  
    42  func (s *KeeperTestSuite) TestReadUpgradeInfoFromDisk() {
    43  	// require no error when the upgrade info file does not exist
    44  	_, err := s.app.UpgradeKeeper.ReadUpgradeInfoFromDisk()
    45  	s.Require().NoError(err)
    46  
    47  	expected := store.UpgradeInfo{
    48  		Name:   "test_upgrade",
    49  		Height: 100,
    50  	}
    51  
    52  	// create an upgrade info file
    53  	s.Require().NoError(s.app.UpgradeKeeper.DumpUpgradeInfoToDisk(expected.Height, expected.Name))
    54  
    55  	ui, err := s.app.UpgradeKeeper.ReadUpgradeInfoFromDisk()
    56  	s.Require().NoError(err)
    57  	s.Require().Equal(expected, ui)
    58  }
    59  
    60  func (s *KeeperTestSuite) TestScheduleUpgrade() {
    61  	cases := []struct {
    62  		name    string
    63  		plan    types.Plan
    64  		setup   func()
    65  		expPass bool
    66  	}{
    67  		{
    68  			name: "successful height schedule",
    69  			plan: types.Plan{
    70  				Name:   "all-good",
    71  				Info:   "some text here",
    72  				Height: 123450000,
    73  			},
    74  			setup:   func() {},
    75  			expPass: true,
    76  		},
    77  		{
    78  			name: "successful overwrite",
    79  			plan: types.Plan{
    80  				Name:   "all-good",
    81  				Info:   "some text here",
    82  				Height: 123450000,
    83  			},
    84  			setup: func() {
    85  				s.app.UpgradeKeeper.ScheduleUpgrade(s.ctx, types.Plan{
    86  					Name:   "alt-good",
    87  					Info:   "new text here",
    88  					Height: 543210000,
    89  				})
    90  			},
    91  			expPass: true,
    92  		},
    93  		{
    94  			name: "unsuccessful schedule: invalid plan",
    95  			plan: types.Plan{
    96  				Height: 123450000,
    97  			},
    98  			setup:   func() {},
    99  			expPass: false,
   100  		},
   101  		{
   102  			name: "unsuccessful height schedule: due date in past",
   103  			plan: types.Plan{
   104  				Name:   "all-good",
   105  				Info:   "some text here",
   106  				Height: 1,
   107  			},
   108  			setup:   func() {},
   109  			expPass: false,
   110  		},
   111  		{
   112  			name: "unsuccessful schedule: schedule already executed",
   113  			plan: types.Plan{
   114  				Name:   "all-good",
   115  				Info:   "some text here",
   116  				Height: 123450000,
   117  			},
   118  			setup: func() {
   119  				s.app.UpgradeKeeper.SetUpgradeHandler("all-good", func(ctx sdk.Context, plan types.Plan, vm module.VersionMap) (module.VersionMap, error) {
   120  					return vm, nil
   121  				})
   122  				s.app.UpgradeKeeper.ApplyUpgrade(s.ctx, types.Plan{
   123  					Name:   "all-good",
   124  					Info:   "some text here",
   125  					Height: 123450000,
   126  				})
   127  			},
   128  			expPass: false,
   129  		},
   130  	}
   131  
   132  	for _, tc := range cases {
   133  		tc := tc
   134  
   135  		s.Run(tc.name, func() {
   136  			// reset suite
   137  			s.SetupTest()
   138  
   139  			// setup test case
   140  			tc.setup()
   141  
   142  			err := s.app.UpgradeKeeper.ScheduleUpgrade(s.ctx, tc.plan)
   143  
   144  			if tc.expPass {
   145  				s.Require().NoError(err, "valid test case failed")
   146  			} else {
   147  				s.Require().Error(err, "invalid test case passed")
   148  			}
   149  		})
   150  	}
   151  }
   152  
   153  func (s *KeeperTestSuite) TestSetUpgradedClient() {
   154  	cs := []byte("IBC client state")
   155  
   156  	cases := []struct {
   157  		name   string
   158  		height int64
   159  		setup  func()
   160  		exists bool
   161  	}{
   162  		{
   163  			name:   "no upgraded client exists",
   164  			height: 10,
   165  			setup:  func() {},
   166  			exists: false,
   167  		},
   168  		{
   169  			name:   "success",
   170  			height: 10,
   171  			setup: func() {
   172  				s.app.UpgradeKeeper.SetUpgradedClient(s.ctx, 10, cs)
   173  			},
   174  			exists: true,
   175  		},
   176  	}
   177  
   178  	for _, tc := range cases {
   179  		// reset suite
   180  		s.SetupTest()
   181  
   182  		// setup test case
   183  		tc.setup()
   184  
   185  		gotCs, exists := s.app.UpgradeKeeper.GetUpgradedClient(s.ctx, tc.height)
   186  		if tc.exists {
   187  			s.Require().Equal(cs, gotCs, "valid case: %s did not retrieve correct client state", tc.name)
   188  			s.Require().True(exists, "valid case: %s did not retrieve client state", tc.name)
   189  		} else {
   190  			s.Require().Nil(gotCs, "invalid case: %s retrieved valid client state", tc.name)
   191  			s.Require().False(exists, "invalid case: %s retrieved valid client state", tc.name)
   192  		}
   193  	}
   194  }
   195  
   196  // Test that the protocol version successfully increments after an
   197  // upgrade and is successfully set on BaseApp's appVersion.
   198  func (s *KeeperTestSuite) TestIncrementProtocolVersion() {
   199  	oldProtocolVersion := s.app.BaseApp.AppVersion()
   200  	s.app.UpgradeKeeper.SetUpgradeHandler("dummy", func(_ sdk.Context, _ types.Plan, vm module.VersionMap) (module.VersionMap, error) { return vm, nil })
   201  	dummyPlan := types.Plan{
   202  		Name:   "dummy",
   203  		Info:   "some text here",
   204  		Height: 100,
   205  	}
   206  	s.app.UpgradeKeeper.ApplyUpgrade(s.ctx, dummyPlan)
   207  	upgradedProtocolVersion := s.app.BaseApp.AppVersion()
   208  
   209  	s.Require().Equal(oldProtocolVersion+1, upgradedProtocolVersion)
   210  }
   211  
   212  // Tests that the underlying state of x/upgrade is set correctly after
   213  // an upgrade.
   214  func (s *KeeperTestSuite) TestMigrations() {
   215  	initialVM := module.VersionMap{"bank": uint64(1)}
   216  	s.app.UpgradeKeeper.SetModuleVersionMap(s.ctx, initialVM)
   217  	vmBefore := s.app.UpgradeKeeper.GetModuleVersionMap(s.ctx)
   218  	s.app.UpgradeKeeper.SetUpgradeHandler("dummy", func(_ sdk.Context, _ types.Plan, vm module.VersionMap) (module.VersionMap, error) {
   219  		// simulate upgrading the bank module
   220  		vm["bank"] = vm["bank"] + 1
   221  		return vm, nil
   222  	})
   223  	dummyPlan := types.Plan{
   224  		Name:   "dummy",
   225  		Info:   "some text here",
   226  		Height: 123450000,
   227  	}
   228  
   229  	s.app.UpgradeKeeper.ApplyUpgrade(s.ctx, dummyPlan)
   230  	vm := s.app.UpgradeKeeper.GetModuleVersionMap(s.ctx)
   231  	s.Require().Equal(vmBefore["bank"]+1, vm["bank"])
   232  }
   233  
   234  func (s *KeeperTestSuite) TestLastCompletedUpgrade() {
   235  	keeper := s.app.UpgradeKeeper
   236  	require := s.Require()
   237  
   238  	s.T().Log("verify empty name if applied upgrades are empty")
   239  	name, height := keeper.GetLastCompletedUpgrade(s.ctx)
   240  	require.Equal("", name)
   241  	require.Equal(int64(0), height)
   242  
   243  	keeper.SetUpgradeHandler("test-v0.9", func(_ sdk.Context, _ types.Plan, vm module.VersionMap) (module.VersionMap, error) {
   244  		return vm, nil
   245  	})
   246  
   247  	keeper.ApplyUpgrade(s.ctx, types.Plan{
   248  		Name:   "test-v0.9",
   249  		Height: 10,
   250  	})
   251  
   252  	s.T().Log("verify valid upgrade name and height")
   253  	name, height = keeper.GetLastCompletedUpgrade(s.ctx)
   254  	require.Equal("test-v0.9", name)
   255  	require.Equal(int64(10), height)
   256  
   257  	keeper.SetUpgradeHandler("test-v0.10", func(_ sdk.Context, _ types.Plan, vm module.VersionMap) (module.VersionMap, error) {
   258  		return vm, nil
   259  	})
   260  
   261  	newCtx := s.ctx.WithBlockHeight(15)
   262  	keeper.ApplyUpgrade(newCtx, types.Plan{
   263  		Name:   "test-v0.10",
   264  		Height: 15,
   265  	})
   266  
   267  	s.T().Log("verify valid upgrade name and height with multiple upgrades")
   268  	name, height = keeper.GetLastCompletedUpgrade(newCtx)
   269  	require.Equal("test-v0.10", name)
   270  	require.Equal(int64(15), height)
   271  }
   272  
   273  func TestKeeperTestSuite(t *testing.T) {
   274  	suite.Run(t, new(KeeperTestSuite))
   275  }