-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
d9f528e
commit 943f051
Showing
6 changed files
with
314 additions
and
6 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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
package integration | ||
|
||
import ( | ||
registryTypes "healthcheck/x/healthcheck/types" | ||
"healthcheck/x/monitored/types" | ||
commonTypes "healthcheck/x/types" | ||
"testing" | ||
"time" | ||
|
||
clienttypes "github.com/cosmos/ibc-go/v6/modules/core/02-client/types" | ||
channeltypes "github.com/cosmos/ibc-go/v6/modules/core/04-channel/types" | ||
ibctesting "github.com/cosmos/ibc-go/v6/testing" | ||
"github.com/stretchr/testify/suite" | ||
) | ||
|
||
func TestHealthcheckTestSuite(t *testing.T) { | ||
// Run tests | ||
suite.Run(t, NewHealthcheckTestSuite()) | ||
} | ||
|
||
func (s *HealthcheckTestSuite) TestHealthcheck() { | ||
|
||
//Send few healthcheck packets | ||
for i := 0; i < 5; i++ { | ||
ctx := s.monitoredChain.GetContext() | ||
monitoredBlockTime := ctx.BlockTime() | ||
monitoredBlockHeight := uint64(ctx.BlockHeight()) | ||
packet := commonTypes.HealthcheckUpdateData{ | ||
Block: monitoredBlockHeight, | ||
Timestamp: uint64(monitoredBlockTime.UnixNano()), | ||
} | ||
packetData, err := types.ModuleCdc.MarshalJSON(&packet) | ||
s.Require().Nil(err) | ||
|
||
timeout := uint64(monitoredBlockTime.Add(time.Hour).UnixNano()) //packet timeout | ||
sendHealthcheckPacket(s, s.path, timeout, packetData) | ||
|
||
monitoredChainEntry, found := s.registryApp.HealthcheckKeeper.GetMonitoredChain(s.registryChain.GetContext(), MonitoredChainID) | ||
s.Require().True(found) | ||
s.Require().True(monitoredBlockHeight == monitoredChainEntry.Status.Block) | ||
s.Require().True(uint64(monitoredBlockTime.UnixNano()) == monitoredChainEntry.Status.Timestamp) | ||
} | ||
} | ||
|
||
func (s *HealthcheckTestSuite) TestHealthcheckTimeout() { | ||
|
||
//Send one healthcheck packet | ||
ctx := s.monitoredChain.GetContext() | ||
monitoredBlockTime := ctx.BlockTime() | ||
monitoredBlockHeight := uint64(ctx.BlockHeight()) | ||
packet := commonTypes.HealthcheckUpdateData{ | ||
Block: monitoredBlockHeight, | ||
Timestamp: uint64(monitoredBlockTime.UnixNano()), | ||
} | ||
packetData, err := types.ModuleCdc.MarshalJSON(&packet) | ||
s.Require().Nil(err) | ||
|
||
timeout := uint64(monitoredBlockTime.Add(time.Hour).UnixNano()) //packet timeout | ||
sendHealthcheckPacket(s, s.path, timeout, packetData) | ||
|
||
monitoredChainEntry, found := s.registryApp.HealthcheckKeeper.GetMonitoredChain(s.registryChain.GetContext(), MonitoredChainID) | ||
s.Require().True(found) | ||
s.Require().True(monitoredBlockHeight == monitoredChainEntry.Status.Block) | ||
s.Require().True(uint64(monitoredBlockTime.UnixNano()) == monitoredChainEntry.Status.Timestamp) | ||
s.Require().True(monitoredChainEntry.Status.Status == string(registryTypes.Active)) | ||
channelID, found := s.registryApp.HealthcheckKeeper.GetChainToChannelMap(s.registryChain.GetContext(), MonitoredChainID) | ||
s.Require().True(found) | ||
channel, found := s.registryApp.GetIBCKeeper().ChannelKeeper.GetChannel(s.registryChain.GetContext(), commonTypes.HealthcheckPortID, channelID) | ||
s.Require().True(found) | ||
s.Require().True(channel.State == channeltypes.OPEN) | ||
updateInterval := int(monitoredChainEntry.UpdateInterval) | ||
timeoutInterval := int(monitoredChainEntry.TimeoutInterval) | ||
|
||
//Move registry chain to reach update interval which will set monitored chain to inactive | ||
for i := 0; i <= updateInterval; i++ { | ||
s.coordinator.CommitBlock(s.registryChain) | ||
} | ||
|
||
monitoredChainEntry, found = s.registryApp.HealthcheckKeeper.GetMonitoredChain(s.registryChain.GetContext(), MonitoredChainID) | ||
s.Require().True(found) | ||
s.Require().True(monitoredChainEntry.Status.Status == string(registryTypes.Inactive)) | ||
channelID, found = s.registryApp.HealthcheckKeeper.GetChainToChannelMap(s.registryChain.GetContext(), MonitoredChainID) | ||
s.Require().True(found) | ||
channel, found = s.registryApp.GetIBCKeeper().ChannelKeeper.GetChannel(s.registryChain.GetContext(), commonTypes.HealthcheckPortID, channelID) | ||
s.Require().True(found) | ||
s.Require().True(channel.State == channeltypes.OPEN) | ||
|
||
//Move registry chain to reach timeout interval which will close the channel and remove it from chainToChannel map | ||
for i := 0; i <= timeoutInterval; i++ { | ||
s.coordinator.CommitBlock(s.registryChain) | ||
} | ||
channel, found = s.registryApp.GetIBCKeeper().ChannelKeeper.GetChannel(s.registryChain.GetContext(), commonTypes.HealthcheckPortID, channelID) | ||
s.Require().True(found) | ||
s.Require().True(channel.State == channeltypes.CLOSED) | ||
_, found = s.registryApp.HealthcheckKeeper.GetChainToChannelMap(s.registryChain.GetContext(), MonitoredChainID) | ||
s.Require().False(found) | ||
|
||
} | ||
|
||
func sendHealthcheckPacket(s *HealthcheckTestSuite, path *ibctesting.Path, timeoutTimestamp uint64, data []byte) channeltypes.Packet { | ||
sequence, err := path.EndpointA.SendPacket(clienttypes.Height{}, timeoutTimestamp, data) | ||
s.Require().NoError(err) | ||
|
||
packet := s.newHealthcheckPacket(data, sequence, path, clienttypes.Height{}, timeoutTimestamp) | ||
|
||
err = path.EndpointB.RecvPacket(packet) | ||
s.Require().NoError(err) | ||
return packet | ||
} | ||
|
||
func (s *HealthcheckTestSuite) newHealthcheckPacket(data []byte, sequence uint64, path *ibctesting.Path, timeoutHeight clienttypes.Height, timeoutTimestamp uint64) channeltypes.Packet { | ||
return channeltypes.NewPacket(data, sequence, | ||
path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, | ||
path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, | ||
timeoutHeight, timeoutTimestamp) | ||
} |
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,141 @@ | ||
package integration | ||
|
||
import ( | ||
"encoding/json" | ||
monitoredApp "healthcheck/app/monitored" | ||
registryApp "healthcheck/app/registry" | ||
registryTypes "healthcheck/x/healthcheck/types" | ||
commonTypes "healthcheck/x/types" | ||
"testing" | ||
|
||
ibctesting "github.com/cosmos/ibc-go/v6/testing" | ||
"github.com/stretchr/testify/suite" | ||
"github.com/tendermint/tendermint/libs/log" | ||
dbm "github.com/tendermint/tm-db" | ||
) | ||
|
||
const ( | ||
RegistryChainID = "registry" | ||
MonitoredChainID = "monitored" | ||
) | ||
|
||
type SetupRegistryCallback func(t *testing.T, coordinator *ibctesting.Coordinator) (*ibctesting.TestChain, *registryApp.App) | ||
type SetupMonitoredCallback func(t *testing.T, coordinator *ibctesting.Coordinator) (*ibctesting.TestChain, *monitoredApp.App) | ||
|
||
type HealthcheckTestSuite struct { | ||
suite.Suite | ||
|
||
setupRegistryCallback SetupRegistryCallback | ||
setupMonitoredCallback SetupMonitoredCallback | ||
|
||
coordinator *ibctesting.Coordinator | ||
registryChain *ibctesting.TestChain | ||
monitoredChain *ibctesting.TestChain | ||
registryApp *registryApp.App | ||
monitoredApp *monitoredApp.App | ||
|
||
path *ibctesting.Path | ||
} | ||
|
||
func NewHealthcheckTestSuite() *HealthcheckTestSuite { | ||
healthcheckSuite := new(HealthcheckTestSuite) | ||
|
||
healthcheckSuite.setupRegistryCallback = func(t *testing.T, coordinator *ibctesting.Coordinator) ( | ||
*ibctesting.TestChain, | ||
*registryApp.App, | ||
) { | ||
t.Helper() | ||
ibctesting.DefaultTestingAppInit = SetupRegistryApp | ||
registry := ibctesting.NewTestChain(t, coordinator, RegistryChainID) | ||
coordinator.Chains[RegistryChainID] = registry | ||
|
||
return registry, registry.App.(*registryApp.App) | ||
} | ||
|
||
healthcheckSuite.setupMonitoredCallback = func(t *testing.T, coordinator *ibctesting.Coordinator) ( | ||
*ibctesting.TestChain, | ||
*monitoredApp.App, | ||
) { | ||
t.Helper() | ||
ibctesting.DefaultTestingAppInit = SetupMonitoredApp | ||
monitored := ibctesting.NewTestChain(t, coordinator, MonitoredChainID) | ||
coordinator.Chains[MonitoredChainID] = monitored | ||
|
||
return monitored, monitored.App.(*monitoredApp.App) | ||
} | ||
|
||
return healthcheckSuite | ||
} | ||
|
||
// SetupTest sets up in-mem state before every test | ||
func (suite *HealthcheckTestSuite) SetupTest() { | ||
suite.coordinator = ibctesting.NewCoordinator(suite.T(), 0) | ||
suite.registryChain, suite.registryApp = suite.setupRegistryCallback(suite.T(), suite.coordinator) | ||
suite.monitoredChain, suite.monitoredApp = suite.setupMonitoredCallback(suite.T(), suite.coordinator) | ||
|
||
// create clients and connection | ||
suite.path = ibctesting.NewPath(suite.monitoredChain, suite.registryChain) // clientID, connectionID, channelID empty | ||
suite.coordinator.SetupConnections(suite.path) // clientID, connectionID | ||
suite.Require().Equal("07-tendermint-0", suite.path.EndpointA.ClientID) | ||
suite.Require().Equal("connection-0", suite.path.EndpointA.ConnectionID) | ||
suite.Require().Equal("07-tendermint-0", suite.path.EndpointB.ClientID) | ||
suite.Require().Equal("connection-0", suite.path.EndpointB.ConnectionID) | ||
|
||
//register monitored chain | ||
var newMonitoredChain = registryTypes.MonitoredChain{ | ||
ChainId: MonitoredChainID, | ||
ConnectionId: suite.path.EndpointA.ConnectionID, | ||
} | ||
suite.registryApp.HealthcheckKeeper.SetMonitoredChain(suite.registryChain.GetContext(), newMonitoredChain) | ||
|
||
// - channel config | ||
suite.path.EndpointA.ChannelConfig.PortID = commonTypes.MonitoredPortID | ||
suite.path.EndpointB.ChannelConfig.PortID = commonTypes.HealthcheckPortID | ||
suite.path.EndpointA.ChannelConfig.Version = commonTypes.Version | ||
suite.path.EndpointB.ChannelConfig.Version = commonTypes.Version | ||
suite.coordinator.CreateChannels(suite.path) // setup channel | ||
suite.Require().Equal("channel-0", suite.path.EndpointA.ChannelID) | ||
suite.Require().Equal("channel-0", suite.path.EndpointB.ChannelID) | ||
} | ||
|
||
func SetupRegistryApp() (ibctesting.TestingApp, map[string]json.RawMessage) { | ||
db := dbm.NewMemDB() | ||
encCdc := registryApp.MakeEncodingConfig() | ||
app := registryApp.New( | ||
log.NewNopLogger(), | ||
db, | ||
nil, | ||
true, | ||
map[int64]bool{}, | ||
registryApp.DefaultNodeHome, | ||
5, | ||
encCdc, | ||
EmptyAppOptions{}, | ||
) | ||
return app, registryApp.NewDefaultGenesisState(encCdc.Marshaler) | ||
} | ||
|
||
func SetupMonitoredApp() (ibctesting.TestingApp, map[string]json.RawMessage) { | ||
db := dbm.NewMemDB() | ||
encCdc := monitoredApp.MakeEncodingConfig() | ||
app := monitoredApp.New( | ||
log.NewNopLogger(), | ||
db, | ||
nil, | ||
true, | ||
map[int64]bool{}, | ||
monitoredApp.DefaultNodeHome, | ||
5, | ||
encCdc, | ||
EmptyAppOptions{}, | ||
) | ||
return app, monitoredApp.NewDefaultGenesisState(encCdc.Marshaler) | ||
} | ||
|
||
// EmptyAppOptions is a stub implementing AppOptions | ||
type EmptyAppOptions struct{} | ||
|
||
// Get implements AppOptions | ||
func (ao EmptyAppOptions) Get(o string) interface{} { | ||
return nil | ||
} |
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