github.com/Finschia/finschia-sdk@v0.49.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 err := s.app.UpgradeKeeper.ScheduleUpgrade(s.ctx, types.Plan{ 86 Name: "alt-good", 87 Info: "new text here", 88 Height: 543210000, 89 }) 90 s.Require().NoError(err) 91 }, 92 expPass: true, 93 }, 94 { 95 name: "unsuccessful schedule: invalid plan", 96 plan: types.Plan{ 97 Height: 123450000, 98 }, 99 setup: func() {}, 100 expPass: false, 101 }, 102 { 103 name: "unsuccessful height schedule: due date in past", 104 plan: types.Plan{ 105 Name: "all-good", 106 Info: "some text here", 107 Height: 1, 108 }, 109 setup: func() {}, 110 expPass: false, 111 }, 112 { 113 name: "unsuccessful schedule: schedule already executed", 114 plan: types.Plan{ 115 Name: "all-good", 116 Info: "some text here", 117 Height: 123450000, 118 }, 119 setup: func() { 120 s.app.UpgradeKeeper.SetUpgradeHandler("all-good", func(ctx sdk.Context, plan types.Plan, vm module.VersionMap) (module.VersionMap, error) { 121 return vm, nil 122 }) 123 s.app.UpgradeKeeper.ApplyUpgrade(s.ctx, types.Plan{ 124 Name: "all-good", 125 Info: "some text here", 126 Height: 123450000, 127 }) 128 }, 129 expPass: false, 130 }, 131 } 132 133 for _, tc := range cases { 134 s.Run(tc.name, func() { 135 // reset suite 136 s.SetupTest() 137 138 // setup test case 139 tc.setup() 140 141 err := s.app.UpgradeKeeper.ScheduleUpgrade(s.ctx, tc.plan) 142 143 if tc.expPass { 144 s.Require().NoError(err, "valid test case failed") 145 } else { 146 s.Require().Error(err, "invalid test case passed") 147 } 148 }) 149 } 150 } 151 152 func (s *KeeperTestSuite) TestSetUpgradedClient() { 153 cs := []byte("IBC client state") 154 155 cases := []struct { 156 name string 157 height int64 158 setup func() 159 exists bool 160 }{ 161 { 162 name: "no upgraded client exists", 163 height: 10, 164 setup: func() {}, 165 exists: false, 166 }, 167 { 168 name: "success", 169 height: 10, 170 setup: func() { 171 err := s.app.UpgradeKeeper.SetUpgradedClient(s.ctx, 10, cs) 172 s.Require().NoError(err) 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"]++ 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 }