-
Notifications
You must be signed in to change notification settings - Fork 3.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* add keeper tests * fix tendermint tests
- Loading branch information
1 parent
2de199f
commit 6cd6d4f
Showing
5 changed files
with
266 additions
and
47 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
package keeper_test | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" | ||
"github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" | ||
"github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" | ||
commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" | ||
"github.com/stretchr/testify/require" | ||
tmtypes "github.com/tendermint/tendermint/types" | ||
) | ||
|
||
const ( | ||
testClientType exported.ClientType = iota + 2 | ||
) | ||
|
||
func (suite *KeeperTestSuite) TestCreateClient() { | ||
// Test Valid CreateClient | ||
state, err := suite.keeper.CreateClient(suite.ctx, testClientID, exported.Tendermint, suite.consensusState) | ||
require.Nil(suite.T(), err, "CreateClient failed") | ||
|
||
// Test ClientState stored correctly | ||
expectedState := types.State{ | ||
ID: testClientID, | ||
Frozen: false, | ||
} | ||
require.Equal(suite.T(), expectedState, state, "Incorrect ClientState returned") | ||
|
||
// Test ClientType and VerifiedRoot stored correctly | ||
clientType, _ := suite.keeper.GetClientType(suite.ctx, testClientID) | ||
require.Equal(suite.T(), exported.Tendermint, clientType, "Incorrect ClientType stored") | ||
root, _ := suite.keeper.GetVerifiedRoot(suite.ctx, testClientID, suite.consensusState.GetHeight()) | ||
require.Equal(suite.T(), suite.consensusState.GetRoot(), root, "Incorrect root stored") | ||
|
||
// Test that trying to CreateClient on existing client fails | ||
_, err = suite.keeper.CreateClient(suite.ctx, testClientID, exported.Tendermint, suite.consensusState) | ||
require.NotNil(suite.T(), err, "CreateClient on existing client: %s passed", testClientID) | ||
} | ||
|
||
func (suite *KeeperTestSuite) TestUpdateClient() { | ||
privVal := tmtypes.NewMockPV() | ||
validator := tmtypes.NewValidator(privVal.GetPubKey(), 1) | ||
altValSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) | ||
altSigners := []tmtypes.PrivValidator{privVal} | ||
|
||
// Test invalid cases all fail and do not update state | ||
cases := []struct { | ||
name string | ||
malleate func() | ||
expErr bool | ||
}{ | ||
{"valid update", func() {}, false}, | ||
{"wrong client type", func() { | ||
suite.keeper.SetClientType(suite.ctx, testClientID, testClientType) | ||
}, true}, | ||
{"frozen client", func() { | ||
clientState, _ := suite.keeper.GetClientState(suite.ctx, testClientID) | ||
clientState.Frozen = true | ||
suite.keeper.SetClientState(suite.ctx, clientState) | ||
}, true}, | ||
{"past height", func() { | ||
suite.header = tendermint.MakeHeader(2, suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) | ||
}, true}, | ||
{"validatorHash incorrect", func() { | ||
suite.header = tendermint.MakeHeader(4, altValSet, suite.valSet, altSigners) | ||
}, true}, | ||
{"nextHash incorrect", func() { | ||
suite.header.NextValidatorSet = altValSet | ||
}, true}, | ||
{"header fails validateBasic", func() { | ||
suite.header.ChainID = "test" | ||
}, true}, | ||
{"verify future commit fails", func() { | ||
suite.consensusState.NextValidatorSet = altValSet | ||
suite.keeper.SetConsensusState(suite.ctx, testClientID, suite.consensusState) | ||
}, true}, | ||
} | ||
|
||
for _, tc := range cases { | ||
suite.Run(fmt.Sprintf("Case %s", tc.name), func() { | ||
// Reset suite on each subtest | ||
suite.SetupTest() | ||
|
||
_, err := suite.keeper.CreateClient(suite.ctx, testClientID, exported.Tendermint, suite.consensusState) | ||
require.Nil(suite.T(), err, "CreateClient failed") | ||
|
||
tc.malleate() | ||
err = suite.keeper.UpdateClient(suite.ctx, testClientID, suite.header) | ||
|
||
retrievedConsState, _ := suite.keeper.GetConsensusState(suite.ctx, testClientID) | ||
tmConsState, _ := retrievedConsState.(tendermint.ConsensusState) | ||
tmConsState.NextValidatorSet.TotalVotingPower() | ||
retrievedRoot, _ := suite.keeper.GetVerifiedRoot(suite.ctx, testClientID, suite.consensusState.GetHeight()+1) | ||
if tc.expErr { | ||
require.NotNil(suite.T(), err, "Invalid UpdateClient passed", tc.name) | ||
|
||
// require no state changes occurred | ||
require.Equal(suite.T(), suite.consensusState, tmConsState, "Consensus state changed after invalid UpdateClient") | ||
require.Nil(suite.T(), retrievedRoot, "Root added for new height after invalid UpdateClient") | ||
} else { | ||
require.Nil(suite.T(), err, "Valid UpdateClient failed", tc.name) | ||
|
||
// require state changes were performed correctly | ||
require.Equal(suite.T(), suite.header.GetHeight(), retrievedConsState.GetHeight(), "height not updated correctly") | ||
require.Equal(suite.T(), commitment.NewRoot(suite.header.AppHash), retrievedConsState.GetRoot(), "root not updated correctly") | ||
require.Equal(suite.T(), suite.header.NextValidatorSet, tmConsState.NextValidatorSet, "NextValidatorSet not updated correctly") | ||
|
||
} | ||
|
||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
package keeper_test | ||
|
||
import ( | ||
"testing" | ||
|
||
abci "github.com/tendermint/tendermint/abci/types" | ||
tmtypes "github.com/tendermint/tendermint/types" | ||
|
||
"github.com/cosmos/cosmos-sdk/codec" | ||
"github.com/cosmos/cosmos-sdk/simapp" | ||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
"github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" | ||
"github.com/cosmos/cosmos-sdk/x/ibc/02-client/keeper" | ||
"github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" | ||
"github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint" | ||
commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" | ||
|
||
"github.com/stretchr/testify/require" | ||
"github.com/stretchr/testify/suite" | ||
) | ||
|
||
const ( | ||
testClientID = "gaia" | ||
) | ||
|
||
type KeeperTestSuite struct { | ||
suite.Suite | ||
|
||
cdc *codec.Codec | ||
ctx sdk.Context | ||
keeper *keeper.Keeper | ||
consensusState tendermint.ConsensusState | ||
header tendermint.Header | ||
valSet *tmtypes.ValidatorSet | ||
privVal tmtypes.PrivValidator | ||
} | ||
|
||
func (suite *KeeperTestSuite) SetupTest() { | ||
isCheckTx := false | ||
app := simapp.Setup(isCheckTx) | ||
|
||
suite.cdc = app.Codec() | ||
suite.ctx = app.BaseApp.NewContext(isCheckTx, abci.Header{}) | ||
suite.keeper = &app.IBCKeeper.ClientKeeper | ||
|
||
suite.privVal = tmtypes.NewMockPV() | ||
|
||
validator := tmtypes.NewValidator(suite.privVal.GetPubKey(), 1) | ||
suite.valSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) | ||
|
||
suite.header = tendermint.MakeHeader(4, suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) | ||
|
||
suite.consensusState = tendermint.ConsensusState{ | ||
ChainID: testClientID, | ||
Height: 3, | ||
Root: commitment.NewRoot([]byte("hash")), | ||
NextValidatorSet: suite.valSet, | ||
} | ||
} | ||
|
||
func TestKeeperTestSuite(t *testing.T) { | ||
suite.Run(t, new(KeeperTestSuite)) | ||
} | ||
|
||
func (suite *KeeperTestSuite) TestSetClientState() { | ||
clientState := types.NewClientState(testClientID) | ||
suite.keeper.SetClientState(suite.ctx, clientState) | ||
|
||
retrievedState, ok := suite.keeper.GetClientState(suite.ctx, testClientID) | ||
require.True(suite.T(), ok, "GetClientState failed") | ||
require.Equal(suite.T(), clientState, retrievedState, "Client states are not equal") | ||
} | ||
|
||
func (suite *KeeperTestSuite) TestSetClientType() { | ||
suite.keeper.SetClientType(suite.ctx, testClientID, exported.Tendermint) | ||
clientType, ok := suite.keeper.GetClientType(suite.ctx, testClientID) | ||
|
||
require.True(suite.T(), ok, "GetClientType failed") | ||
require.Equal(suite.T(), exported.Tendermint, clientType, "ClientTypes not stored correctly") | ||
} | ||
|
||
func (suite *KeeperTestSuite) TestSetConsensusState() { | ||
suite.keeper.SetConsensusState(suite.ctx, testClientID, suite.consensusState) | ||
|
||
retrievedConsState, ok := suite.keeper.GetConsensusState(suite.ctx, testClientID) | ||
|
||
require.True(suite.T(), ok, "GetConsensusState failed") | ||
tmConsState, _ := retrievedConsState.(tendermint.ConsensusState) | ||
// force recalculation of unexported totalVotingPower so we can compare consensusState | ||
tmConsState.NextValidatorSet.TotalVotingPower() | ||
require.Equal(suite.T(), suite.consensusState, tmConsState, "ConsensusState not stored correctly") | ||
} | ||
|
||
func (suite *KeeperTestSuite) TestSetVerifiedRoot() { | ||
root := commitment.NewRoot([]byte("hash")) | ||
suite.keeper.SetVerifiedRoot(suite.ctx, testClientID, 3, root) | ||
|
||
retrievedRoot, ok := suite.keeper.GetVerifiedRoot(suite.ctx, testClientID, 3) | ||
|
||
require.True(suite.T(), ok, "GetVerifiedRoot failed") | ||
require.Equal(suite.T(), root, retrievedRoot, "Root stored incorrectly") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters