Add migration integraton tests
This commit is contained in:
@@ -2,6 +2,7 @@ package keeper
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
@@ -461,9 +462,8 @@ func TestMigrate(t *testing.T) {
|
||||
accKeeper, keeper := keepers.AccountKeeper, keepers.WasmKeeper
|
||||
|
||||
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
|
||||
topUp := sdk.NewCoins(sdk.NewInt64Coin("denom", 5000))
|
||||
creator := createFakeFundedAccount(ctx, accKeeper, deposit.Add(deposit...))
|
||||
fred := createFakeFundedAccount(ctx, accKeeper, topUp)
|
||||
fred := createFakeFundedAccount(ctx, accKeeper, sdk.NewCoins(sdk.NewInt64Coin("denom", 5000)))
|
||||
|
||||
wasmCode, err := ioutil.ReadFile("./testdata/contract.wasm")
|
||||
require.NoError(t, err)
|
||||
@@ -475,12 +475,20 @@ func TestMigrate(t *testing.T) {
|
||||
require.NotEqual(t, originalContractID, newContractID)
|
||||
|
||||
_, _, anyAddr := keyPubAddr()
|
||||
_, _, newVerifierAddr := keyPubAddr()
|
||||
initMsg := InitMsg{
|
||||
Verifier: fred,
|
||||
Beneficiary: anyAddr,
|
||||
}
|
||||
initMsgBz, err := json.Marshal(initMsg)
|
||||
require.NoError(t, err)
|
||||
|
||||
migMsg := struct {
|
||||
Verifier sdk.AccAddress `json:"verifier"`
|
||||
}{Verifier: newVerifierAddr}
|
||||
migMsgBz, err := json.Marshal(migMsg)
|
||||
require.NoError(t, err)
|
||||
|
||||
specs := map[string]struct {
|
||||
admin sdk.AccAddress
|
||||
overrideContractAddr sdk.AccAddress
|
||||
@@ -488,28 +496,35 @@ func TestMigrate(t *testing.T) {
|
||||
codeID uint64
|
||||
migrateMsg []byte
|
||||
expErr *sdkerrors.Error
|
||||
expVerifier sdk.AccAddress
|
||||
}{
|
||||
"all good with same code id": {
|
||||
admin: creator,
|
||||
caller: creator,
|
||||
codeID: originalContractID,
|
||||
admin: creator,
|
||||
caller: creator,
|
||||
codeID: originalContractID,
|
||||
migrateMsg: migMsgBz,
|
||||
expVerifier: newVerifierAddr,
|
||||
},
|
||||
"all good with new code id": {
|
||||
admin: creator,
|
||||
caller: creator,
|
||||
codeID: newContractID,
|
||||
"all good with different code id": {
|
||||
admin: creator,
|
||||
caller: creator,
|
||||
codeID: newContractID,
|
||||
migrateMsg: migMsgBz,
|
||||
expVerifier: newVerifierAddr,
|
||||
},
|
||||
"all good with admin set": {
|
||||
admin: fred,
|
||||
caller: fred,
|
||||
codeID: newContractID,
|
||||
admin: fred,
|
||||
caller: fred,
|
||||
codeID: newContractID,
|
||||
migrateMsg: migMsgBz,
|
||||
expVerifier: newVerifierAddr,
|
||||
},
|
||||
"prevent migration when admin was not set on instantiate": {
|
||||
caller: creator,
|
||||
codeID: originalContractID,
|
||||
expErr: sdkerrors.ErrUnauthorized,
|
||||
},
|
||||
"prevent migration when not admin": {
|
||||
"prevent migration when not sent by admin": {
|
||||
caller: creator,
|
||||
admin: fred,
|
||||
codeID: originalContractID,
|
||||
@@ -528,18 +543,21 @@ func TestMigrate(t *testing.T) {
|
||||
codeID: originalContractID,
|
||||
expErr: sdkerrors.ErrInvalidRequest,
|
||||
},
|
||||
"fail when migration caused error": {
|
||||
"fail in contract with invalid migrate msg": {
|
||||
admin: creator,
|
||||
caller: creator,
|
||||
codeID: originalContractID,
|
||||
migrateMsg: bytes.Repeat([]byte{0x1}, 7), // condition hard coded in stub: >6 = error
|
||||
migrateMsg: bytes.Repeat([]byte{0x1}, 7),
|
||||
expErr: types.ErrMigrationFailed,
|
||||
},
|
||||
"fail in contract without migrate msg": {
|
||||
admin: creator,
|
||||
caller: creator,
|
||||
codeID: originalContractID,
|
||||
expErr: types.ErrMigrationFailed,
|
||||
},
|
||||
}
|
||||
var (
|
||||
builtIntoGoCosmWasmStubGas = sdk.Gas(10000)
|
||||
builtIntoGoCosmWasmStubData = []byte(("my-migration-response-data"))
|
||||
)
|
||||
|
||||
for msg, spec := range specs {
|
||||
t.Run(msg, func(t *testing.T) {
|
||||
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
|
||||
@@ -548,26 +566,82 @@ func TestMigrate(t *testing.T) {
|
||||
if spec.overrideContractAddr != nil {
|
||||
addr = spec.overrideContractAddr
|
||||
}
|
||||
gasBefore := ctx.GasMeter().GasConsumed()
|
||||
res, err := keeper.Migrate(ctx, addr, spec.caller, spec.codeID, spec.migrateMsg)
|
||||
_, err = keeper.Migrate(ctx, addr, spec.caller, spec.codeID, spec.migrateMsg)
|
||||
require.True(t, spec.expErr.Is(err), "expected %v but got %+v", spec.expErr, err)
|
||||
if spec.expErr != nil {
|
||||
return
|
||||
}
|
||||
gasAfter := ctx.GasMeter().GasConsumed()
|
||||
assert.Greater(t, gasAfter-gasBefore, builtIntoGoCosmWasmStubGas/GasMultiplier)
|
||||
assert.Equal(t, builtIntoGoCosmWasmStubData, res.Data)
|
||||
cInfo := keeper.GetContractInfo(ctx, addr)
|
||||
assert.Equal(t, spec.codeID, cInfo.CodeID)
|
||||
assert.Equal(t, originalContractID, cInfo.PreviousCodeID)
|
||||
assert.Equal(t, types.NewCreatedAt(ctx), cInfo.LastUpdated)
|
||||
// TODO: check contract store was updated by migration code (impl also in contract)
|
||||
// TODO: check any messages dispatched proper
|
||||
// TODO: check events?
|
||||
|
||||
m := keeper.QueryRaw(ctx, addr, []byte("config"))
|
||||
require.Len(t, m, 1)
|
||||
var stored map[string][]byte
|
||||
require.NoError(t, json.Unmarshal(m[0].Value, &stored))
|
||||
require.Contains(t, stored, "verifier")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, spec.expVerifier, sdk.AccAddress(stored["verifier"]))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMigrateWithDispatchedMessage(t *testing.T) {
|
||||
tempDir, err := ioutil.TempDir("", "wasm")
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(tempDir)
|
||||
ctx, keepers := CreateTestInput(t, false, tempDir, SupportedFeatures, nil, nil)
|
||||
accKeeper, keeper := keepers.AccountKeeper, keepers.WasmKeeper
|
||||
|
||||
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
|
||||
creator := createFakeFundedAccount(ctx, accKeeper, deposit.Add(deposit...))
|
||||
fred := createFakeFundedAccount(ctx, accKeeper, sdk.NewCoins(sdk.NewInt64Coin("denom", 5000)))
|
||||
|
||||
wasmCode, err := ioutil.ReadFile("./testdata/contract.wasm")
|
||||
require.NoError(t, err)
|
||||
burnerCode, err := ioutil.ReadFile("./testdata/burner.wasm")
|
||||
require.NoError(t, err)
|
||||
|
||||
originalContractID, err := keeper.Create(ctx, creator, wasmCode, "", "")
|
||||
require.NoError(t, err)
|
||||
burnerContractID, err := keeper.Create(ctx, creator, burnerCode, "", "")
|
||||
require.NoError(t, err)
|
||||
require.NotEqual(t, originalContractID, burnerContractID)
|
||||
|
||||
_, _, myPayoutAddr := keyPubAddr()
|
||||
initMsg := InitMsg{
|
||||
Verifier: fred,
|
||||
Beneficiary: fred,
|
||||
}
|
||||
initMsgBz, err := json.Marshal(initMsg)
|
||||
require.NoError(t, err)
|
||||
|
||||
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
|
||||
addr, err := keeper.Instantiate(ctx, originalContractID, creator, fred, initMsgBz, "demo contract", deposit)
|
||||
require.NoError(t, err)
|
||||
|
||||
migMsg := struct {
|
||||
Payout sdk.AccAddress `json:"payout"`
|
||||
}{Payout: myPayoutAddr}
|
||||
migMsgBz, err := json.Marshal(migMsg)
|
||||
require.NoError(t, err)
|
||||
|
||||
res, err := keeper.Migrate(ctx, addr, fred, burnerContractID, migMsgBz)
|
||||
require.NoError(t, err)
|
||||
dataBz, err := base64.StdEncoding.DecodeString(string(res.Data))
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "burnt", string(dataBz))
|
||||
|
||||
// all persistent data cleared
|
||||
m := keeper.QueryRaw(ctx, addr, []byte("config"))
|
||||
require.Len(t, m, 0)
|
||||
|
||||
// and all deposit tokens sent to myPayoutAddr
|
||||
balance := accKeeper.GetAccount(ctx, myPayoutAddr).GetCoins()
|
||||
assert.Equal(t, deposit, balance)
|
||||
}
|
||||
|
||||
func TestUpdateContractAdmin(t *testing.T) {
|
||||
tempDir, err := ioutil.TempDir("", "wasm")
|
||||
require.NoError(t, err)
|
||||
|
||||
Reference in New Issue
Block a user