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 }