From d2c295003d8ce33efcef0bafcf91d5a2fb782e28 Mon Sep 17 00:00:00 2001 From: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> Date: Wed, 27 Sep 2023 09:14:34 +0200 Subject: [PATCH] test: introduce flag for trace input to e2e framework (#1318) * Add json marshal/unmarshal for test traces * Remove auto-generated trace files * Add an example trace to see the input format * Add comment in rapid test * Remove duplicated test case * Remove TODO in favor of comment * Reduce code duplication * Run go mod tidy and make format * Correct testdata directory in gitignore * Remove testdata directory * Remove testdata from gitignore * Add tracehandler_testdata * Remove example trace, since there are examples in the test data * Revert unintentional change to .gitignore * Remove propType field from generator * Add docstrings to action_rapid test and state_rapid_test to better explain what the files are doing * Add flag for reading test traces * Refactor testRun to testConfig and remove testConfig specification for predefined cases * Remove ::testConfig from Makefile * Re-add removed BUILDDIR instruction * Re-add removed newline * Fix duplicated words * Checkout tracehandler testdata from main * Remove unecessary test trace * Commit merged file --- .github/workflows/automated-tests.yml | 14 ++ Makefile | 4 + tests/e2e/actions.go | 104 +++++------ tests/e2e/actions_sovereign_chain.go | 6 +- tests/e2e/config.go | 36 ++-- tests/e2e/main.go | 237 +++++++++++++++++++------- tests/e2e/state.go | 64 +++---- 7 files changed, 301 insertions(+), 164 deletions(-) diff --git a/.github/workflows/automated-tests.yml b/.github/workflows/automated-tests.yml index ad53314e76..f7d9988bad 100644 --- a/.github/workflows/automated-tests.yml +++ b/.github/workflows/automated-tests.yml @@ -56,3 +56,17 @@ jobs: go-version: "1.20" - name: E2E tests run: make test-e2e-short-cometmock + Trace-Tests: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + lfs: true + - name: Checkout LFS objects + run: git lfs checkout + - name: Setup Go + uses: actions/setup-go@v4 + with: + go-version: "1.20" + - name: E2E tests + run: make test-trace diff --git a/Makefile b/Makefile index a65db076ab..516db825bd 100644 --- a/Makefile +++ b/Makefile @@ -77,6 +77,10 @@ test-gaia-e2e-parallel-tagged: test-no-cache: go test ./... -count=1 && go run ./tests/e2e/... +# test reading a trace from a file +test-trace: + go run ./tests/e2e/... --test-file tests/e2e/tracehandler_testdata/happyPath.json::default + ############################################################################### ### Linting ### ############################################################################### diff --git a/tests/e2e/actions.go b/tests/e2e/actions.go index 408c9066fc..386404baaa 100644 --- a/tests/e2e/actions.go +++ b/tests/e2e/actions.go @@ -31,7 +31,7 @@ type SendTokensAction struct { const done = "done!!!!!!!!" -func (tr TestRun) sendTokens( +func (tr TestConfig) sendTokens( action SendTokensAction, verbose bool, ) { @@ -76,7 +76,7 @@ type StartChainValidator struct { Stake uint } -func (tr *TestRun) startChain( +func (tr *TestConfig) startChain( action StartChainAction, verbose bool, ) { @@ -193,7 +193,7 @@ type submitTextProposalAction struct { Description string } -func (tr TestRun) submitTextProposal( +func (tr TestConfig) submitTextProposal( action submitTextProposalAction, verbose bool, ) { @@ -230,7 +230,7 @@ type submitConsumerAdditionProposalAction struct { DistributionChannel string } -func (tr TestRun) submitConsumerAdditionProposal( +func (tr TestConfig) submitConsumerAdditionProposal( action submitConsumerAdditionProposalAction, verbose bool, ) { @@ -301,7 +301,7 @@ type submitConsumerRemovalProposalAction struct { StopTimeOffset time.Duration // offset from time.Now() } -func (tr TestRun) submitConsumerRemovalProposal( +func (tr TestConfig) submitConsumerRemovalProposal( action submitConsumerRemovalProposalAction, verbose bool, ) { @@ -377,7 +377,7 @@ type paramChangeJSON struct { Value interface{} `json:"value"` } -func (tr TestRun) submitParamChangeProposal( +func (tr TestConfig) submitParamChangeProposal( action submitParamChangeLegacyProposalAction, verbose bool, ) { @@ -441,7 +441,7 @@ type submitEquivocationProposalAction struct { From ValidatorID } -func (tr TestRun) submitEquivocationProposal(action submitEquivocationProposalAction, verbose bool) { +func (tr TestConfig) submitEquivocationProposal(action submitEquivocationProposalAction, verbose bool) { val := tr.validatorConfigs[action.Validator] providerChain := tr.chainConfigs[ChainID("provi")] @@ -510,7 +510,7 @@ type voteGovProposalAction struct { PropNumber uint } -func (tr *TestRun) voteGovProposal( +func (tr *TestConfig) voteGovProposal( action voteGovProposalAction, verbose bool, ) { @@ -553,7 +553,7 @@ type startConsumerChainAction struct { GenesisChanges string } -func (tr *TestRun) startConsumerChain( +func (tr *TestConfig) startConsumerChain( action startConsumerChainAction, verbose bool, ) { @@ -597,7 +597,7 @@ type ChangeoverChainAction struct { GenesisChanges string } -func (tr TestRun) changeoverChain( +func (tr TestConfig) changeoverChain( action ChangeoverChainAction, verbose bool, ) { @@ -634,7 +634,7 @@ func (tr TestRun) changeoverChain( }, verbose) } -func (tr TestRun) startChangeover( +func (tr TestConfig) startChangeover( action ChangeoverChainAction, verbose bool, ) { @@ -769,7 +769,7 @@ const gorelayerChainConfigTemplate = ` } }` -func (tr TestRun) addChainToRelayer( +func (tr TestConfig) addChainToRelayer( action addChainToRelayerAction, verbose bool, ) { @@ -780,7 +780,7 @@ func (tr TestRun) addChainToRelayer( } } -func (tr TestRun) addChainToGorelayer( +func (tr TestConfig) addChainToGorelayer( action addChainToRelayerAction, verbose bool, ) { @@ -818,7 +818,7 @@ func (tr TestRun) addChainToGorelayer( executeCommand(keyRestoreCommand, "restore keys") } -func (tr TestRun) addChainToHermes( +func (tr TestConfig) addChainToHermes( action addChainToRelayerAction, verbose bool, ) { @@ -897,7 +897,7 @@ type addIbcConnectionAction struct { ClientB uint } -func (tr TestRun) addIbcConnection( +func (tr TestConfig) addIbcConnection( action addIbcConnectionAction, verbose bool, ) { @@ -908,7 +908,7 @@ func (tr TestRun) addIbcConnection( } } -func (tr TestRun) addIbcConnectionGorelayer( +func (tr TestConfig) addIbcConnectionGorelayer( action addIbcConnectionAction, verbose bool, ) { @@ -966,7 +966,7 @@ type createIbcClientsAction struct { // if clients are not provided hermes will first // create new clients and then a new connection // otherwise, it would use client provided as CLI argument (-a-client) -func (tr TestRun) createIbcClientsHermes( +func (tr TestConfig) createIbcClientsHermes( action createIbcClientsAction, verbose bool, ) { @@ -1003,7 +1003,7 @@ func (tr TestRun) createIbcClientsHermes( } } -func (tr TestRun) addIbcConnectionHermes( +func (tr TestConfig) addIbcConnectionHermes( action addIbcConnectionAction, verbose bool, ) { @@ -1053,7 +1053,7 @@ type addIbcChannelAction struct { type startRelayerAction struct{} -func (tr TestRun) startRelayer( +func (tr TestConfig) startRelayer( action startRelayerAction, verbose bool, ) { @@ -1064,7 +1064,7 @@ func (tr TestRun) startRelayer( } } -func (tr TestRun) startGorelayer( +func (tr TestConfig) startGorelayer( action startRelayerAction, verbose bool, ) { @@ -1083,7 +1083,7 @@ func (tr TestRun) startGorelayer( } } -func (tr TestRun) startHermes( +func (tr TestConfig) startHermes( action startRelayerAction, verbose bool, ) { @@ -1102,7 +1102,7 @@ func (tr TestRun) startHermes( } } -func (tr TestRun) addIbcChannel( +func (tr TestConfig) addIbcChannel( action addIbcChannelAction, verbose bool, ) { @@ -1113,7 +1113,7 @@ func (tr TestRun) addIbcChannel( } } -func (tr TestRun) addIbcChannelGorelayer( +func (tr TestConfig) addIbcChannelGorelayer( action addIbcChannelAction, verbose bool, ) { @@ -1131,7 +1131,7 @@ func (tr TestRun) addIbcChannelGorelayer( executeCommand(cmd, "addChannel") } -func (tr TestRun) addIbcChannelHermes( +func (tr TestConfig) addIbcChannelHermes( action addIbcChannelAction, verbose bool, ) { @@ -1194,7 +1194,7 @@ type transferChannelCompleteAction struct { ChannelB uint } -func (tr TestRun) transferChannelComplete( +func (tr TestConfig) transferChannelComplete( action transferChannelCompleteAction, verbose bool, ) { @@ -1282,7 +1282,7 @@ type relayPacketsAction struct { Channel uint } -func (tr TestRun) relayPackets( +func (tr TestConfig) relayPackets( action relayPacketsAction, verbose bool, ) { @@ -1293,7 +1293,7 @@ func (tr TestRun) relayPackets( } } -func (tr TestRun) relayPacketsGorelayer( +func (tr TestConfig) relayPacketsGorelayer( action relayPacketsAction, verbose bool, ) { @@ -1317,7 +1317,7 @@ func (tr TestRun) relayPacketsGorelayer( tr.waitBlocks(action.ChainB, 1, 30*time.Second) } -func (tr TestRun) relayPacketsHermes( +func (tr TestConfig) relayPacketsHermes( action relayPacketsAction, verbose bool, ) { @@ -1348,7 +1348,7 @@ type relayRewardPacketsToProviderAction struct { Channel uint } -func (tr TestRun) relayRewardPacketsToProvider( +func (tr TestConfig) relayRewardPacketsToProvider( action relayRewardPacketsToProviderAction, verbose bool, ) { @@ -1369,7 +1369,7 @@ type delegateTokensAction struct { Amount uint } -func (tr TestRun) delegateTokens( +func (tr TestConfig) delegateTokens( action delegateTokensAction, verbose bool, ) { @@ -1413,7 +1413,7 @@ type unbondTokensAction struct { Amount uint } -func (tr TestRun) unbondTokens( +func (tr TestConfig) unbondTokens( action unbondTokensAction, verbose bool, ) { @@ -1458,7 +1458,7 @@ type cancelUnbondTokensAction struct { Amount uint } -func (tr TestRun) cancelUnbondTokens( +func (tr TestConfig) cancelUnbondTokens( action cancelUnbondTokensAction, verbose bool, ) { @@ -1527,7 +1527,7 @@ type redelegateTokensAction struct { Amount uint } -func (tr TestRun) redelegateTokens(action redelegateTokensAction, verbose bool) { +func (tr TestConfig) redelegateTokens(action redelegateTokensAction, verbose bool) { srcCfg := tr.validatorConfigs[action.Src] dstCfg := tr.validatorConfigs[action.Dst] @@ -1580,7 +1580,7 @@ type downtimeSlashAction struct { // takes a string representation of the private key like // `{"address":"DF090A4880B54CD57B2A79E64D9E969BD7514B09","pub_key":{"type":"tendermint/PubKeyEd25519","value":"ujY14AgopV907IYgPAk/5x8c9267S4fQf89nyeCPTes="},"priv_key":{"type":"tendermint/PrivKeyEd25519","value":"TRJgf7lkTjs/sj43pyweEOanyV7H7fhnVivOi0A4yjW6NjXgCCilX3TshiA8CT/nHxz3brtLh9B/z2fJ4I9N6w=="}}` // and returns the value of the "address" field -func (tr TestRun) getValidatorKeyAddressFromString(keystring string) string { +func (tr TestConfig) getValidatorKeyAddressFromString(keystring string) string { var key struct { Address string `json:"address"` } @@ -1591,7 +1591,7 @@ func (tr TestRun) getValidatorKeyAddressFromString(keystring string) string { return key.Address } -func (tr TestRun) invokeDowntimeSlash(action downtimeSlashAction, verbose bool) { +func (tr TestConfig) invokeDowntimeSlash(action downtimeSlashAction, verbose bool) { // Bring validator down tr.setValidatorDowntime(action.Chain, action.Validator, true, verbose) // Wait appropriate amount of blocks for validator to be slashed @@ -1601,7 +1601,7 @@ func (tr TestRun) invokeDowntimeSlash(action downtimeSlashAction, verbose bool) } // Sets validator downtime by setting the virtual ethernet interface of a node to "up" or "down" -func (tr TestRun) setValidatorDowntime(chain ChainID, validator ValidatorID, down, verbose bool) { +func (tr TestConfig) setValidatorDowntime(chain ChainID, validator ValidatorID, down, verbose bool) { var lastArg string if down { lastArg = "down" @@ -1644,7 +1644,7 @@ func (tr TestRun) setValidatorDowntime(chain ChainID, validator ValidatorID, dow } } -func (tr TestRun) GetValidatorPrivateKeyAddress(chain ChainID, validator ValidatorID) string { +func (tr TestConfig) GetValidatorPrivateKeyAddress(chain ChainID, validator ValidatorID) string { var validatorPrivateKeyAddress string if chain == ChainID("provi") { validatorPrivateKeyAddress = tr.getValidatorKeyAddressFromString(tr.validatorConfigs[validator].PrivValidatorKey) @@ -1666,7 +1666,7 @@ type unjailValidatorAction struct { } // Sends an unjail transaction to the provider chain -func (tr TestRun) unjailValidator(action unjailValidatorAction, verbose bool) { +func (tr TestConfig) unjailValidator(action unjailValidatorAction, verbose bool) { // wait until downtime_jail_duration has elapsed, to make sure the validator can be unjailed tr.WaitTime(61 * time.Second) @@ -1705,7 +1705,7 @@ type registerRepresentativeAction struct { Stakes []uint } -func (tr TestRun) registerRepresentative( +func (tr TestConfig) registerRepresentative( action registerRepresentativeAction, verbose bool, ) { @@ -1762,7 +1762,7 @@ type submitChangeRewardDenomsProposalAction struct { From ValidatorID } -func (tr TestRun) submitChangeRewardDenomsProposal(action submitChangeRewardDenomsProposalAction, verbose bool) { +func (tr TestConfig) submitChangeRewardDenomsProposal(action submitChangeRewardDenomsProposalAction, verbose bool) { providerChain := tr.chainConfigs[ChainID("provi")] prop := client.ChangeRewardDenomsProposalJSON{ @@ -1831,7 +1831,7 @@ type doublesignSlashAction struct { Chain ChainID } -func (tr TestRun) invokeDoublesignSlash( +func (tr TestConfig) invokeDoublesignSlash( action doublesignSlashAction, verbose bool, ) { @@ -1868,7 +1868,7 @@ type lightClientEquivocationAttackAction struct { Chain ChainID } -func (tr TestRun) lightClientEquivocationAttack( +func (tr TestConfig) lightClientEquivocationAttack( action lightClientEquivocationAttackAction, verbose bool, ) { @@ -1884,7 +1884,7 @@ type lightClientAmnesiaAttackAction struct { Chain ChainID } -func (tr TestRun) lightClientAmnesiaAttack( +func (tr TestConfig) lightClientAmnesiaAttack( action lightClientAmnesiaAttackAction, verbose bool, ) { @@ -1900,7 +1900,7 @@ type lightClientLunaticAttackAction struct { Chain ChainID } -func (tr TestRun) lightClientLunaticAttack( +func (tr TestConfig) lightClientLunaticAttack( action lightClientLunaticAttackAction, verbose bool, ) { @@ -1915,7 +1915,7 @@ const ( LightClientLunaticAttack LightClientAttackType = "Lunatic" ) -func (tr TestRun) lightClientAttack( +func (tr TestConfig) lightClientAttack( validator ValidatorID, chain ChainID, attackType LightClientAttackType, @@ -1945,7 +1945,7 @@ type assignConsumerPubKeyAction struct { ExpectedError string } -func (tr TestRun) assignConsumerPubKey(action assignConsumerPubKeyAction, verbose bool) { +func (tr TestConfig) assignConsumerPubKey(action assignConsumerPubKeyAction, verbose bool) { valCfg := tr.validatorConfigs[action.Validator] // Note: to get error response reported back from this command '--gas auto' needs to be set. @@ -2054,7 +2054,7 @@ type slashThrottleDequeueAction struct { Timeout time.Duration } -func (tr TestRun) waitForSlashThrottleDequeue( +func (tr TestConfig) waitForSlashThrottleDequeue( action slashThrottleDequeueAction, verbose bool, ) { @@ -2094,7 +2094,7 @@ func uintPointer(i uint) *uint { // GetPathNameForGorelayer returns the name of the path between two given chains used by Gorelayer. // Since paths are bidirectional, we need either chain to be able to be provided as first or second argument // and still return the same name, so we sort the chain names alphabetically. -func (tr TestRun) GetPathNameForGorelayer(chainA, chainB ChainID) string { +func (tr TestConfig) GetPathNameForGorelayer(chainA, chainB ChainID) string { var pathName string if string(chainA) < string(chainB) { pathName = string(chainA) + "-" + string(chainB) @@ -2108,10 +2108,10 @@ func (tr TestRun) GetPathNameForGorelayer(chainA, chainB ChainID) string { // WaitTime waits for the given duration. // To make sure that the new timestamp is visible on-chain, it also waits until at least one block has been // produced on each chain after waiting. -// The CometMock version of this takes a pointer to the TestRun as it needs to manipulate +// The CometMock version of this takes a pointer to the TestConfig as it needs to manipulate // information in the testrun that stores how much each chain has waited, to keep times in sync. -// Be careful that all functions calling WaitTime should therefore also take a pointer to the TestRun. -func (tr *TestRun) WaitTime(duration time.Duration) { +// Be careful that all functions calling WaitTime should therefore also take a pointer to the TestConfig. +func (tr *TestConfig) WaitTime(duration time.Duration) { if !tr.useCometmock { time.Sleep(duration) } else { @@ -2126,7 +2126,7 @@ func (tr *TestRun) WaitTime(duration time.Duration) { } } -func (tr TestRun) AdvanceTimeForChain(chain ChainID, duration time.Duration) { +func (tr TestConfig) AdvanceTimeForChain(chain ChainID, duration time.Duration) { // cometmock avoids sleeping, and instead advances time for all chains method := "advance_time" params := fmt.Sprintf(`{"duration_in_seconds": "%d"}`, int(math.Ceil(duration.Seconds()))) diff --git a/tests/e2e/actions_sovereign_chain.go b/tests/e2e/actions_sovereign_chain.go index 88aa8bf03d..af5f6abab3 100644 --- a/tests/e2e/actions_sovereign_chain.go +++ b/tests/e2e/actions_sovereign_chain.go @@ -18,7 +18,7 @@ type StartSovereignChainAction struct { // calls a simplified startup script (start-sovereign.sh) and runs a validator node // upgrades are simpler with a single validator node since only one node needs to be upgraded -func (tr TestRun) startSovereignChain( +func (tr TestConfig) startSovereignChain( action StartSovereignChainAction, verbose bool, ) { @@ -112,7 +112,7 @@ type LegacyUpgradeProposalAction struct { UpgradeHeight uint64 } -func (tr *TestRun) submitLegacyUpgradeProposal(action LegacyUpgradeProposalAction, verbose bool) { +func (tr *TestConfig) submitLegacyUpgradeProposal(action LegacyUpgradeProposalAction, verbose bool) { submit := fmt.Sprintf( `%s tx gov submit-legacy-proposal software-upgrade %s \ --title %s \ @@ -161,7 +161,7 @@ type waitUntilBlockAction struct { Chain ChainID } -func (tr *TestRun) waitUntilBlockOnChain(action waitUntilBlockAction) { +func (tr *TestConfig) waitUntilBlockOnChain(action waitUntilBlockAction) { fmt.Println("waitUntilBlockOnChain is waiting for block:", action.Block) tr.waitUntilBlock(action.Chain, action.Block, 120*time.Second) fmt.Println("waitUntilBlockOnChain done waiting for block:", action.Block) diff --git a/tests/e2e/config.go b/tests/e2e/config.go index 6726ab2304..0a164c2cec 100644 --- a/tests/e2e/config.go +++ b/tests/e2e/config.go @@ -59,8 +59,8 @@ type ContainerConfig struct { Now time.Time } -// TODO: Split out TestRun and system wide config like localsdkpath -type TestRun struct { +// TODO: Split out TestConfig and system wide config like localsdkpath +type TestConfig struct { // These are the non altered values during a typical test run, where multiple test runs can exist // to validate different action sequences and corresponding state checks. containerConfig ContainerConfig @@ -84,8 +84,8 @@ type TestRun struct { name string } -// Initialize initializes the TestRun instance by setting the runningChains field to an empty map. -func (tr *TestRun) Initialize() { +// Initialize initializes the TestConfig instance by setting the runningChains field to an empty map. +func (tr *TestConfig) Initialize() { tr.runningChains = make(map[ChainID]bool) } @@ -151,8 +151,8 @@ func getDefaultValidators() map[ValidatorID]ValidatorConfig { } } -func SlashThrottleTestRun() TestRun { - tr := TestRun{ +func SlashThrottleTestConfig() TestConfig { + tr := TestConfig{ name: "slash-throttling", containerConfig: ContainerConfig{ ContainerName: "interchain-security-slash-container", @@ -196,8 +196,8 @@ func SlashThrottleTestRun() TestRun { return tr } -func DefaultTestRun() TestRun { - tr := TestRun{ +func DefaultTestConfig() TestConfig { + tr := TestConfig{ name: "default", containerConfig: ContainerConfig{ ContainerName: "interchain-security-container", @@ -241,7 +241,7 @@ func DefaultTestRun() TestRun { return tr } -func DemocracyTestRun(allowReward bool) TestRun { +func DemocracyTestConfig(allowReward bool) TestConfig { consumerGenChanges := ".app_state.ccvconsumer.params.blocks_per_distribution_transmission = \"20\" | " + ".app_state.gov.voting_params.voting_period = \"10s\" | " + ".app_state.slashing.params.signed_blocks_window = \"10\" | " + @@ -254,7 +254,7 @@ func DemocracyTestRun(allowReward bool) TestRun { consumerGenChanges += " | .app_state.ccvconsumer.params.reward_denoms = [\"stake\"]" } - tr := TestRun{ + tr := TestConfig{ name: "democracy", containerConfig: ContainerConfig{ ContainerName: "interchain-security-democ-container", @@ -293,8 +293,8 @@ func DemocracyTestRun(allowReward bool) TestRun { return tr } -func MultiConsumerTestRun() TestRun { - tr := TestRun{ +func MultiConsumerTestConfig() TestConfig { + tr := TestConfig{ name: "multi-consumer", containerConfig: ContainerConfig{ ContainerName: "interchain-security-multic-container", @@ -348,8 +348,8 @@ func MultiConsumerTestRun() TestRun { return tr } -func ChangeoverTestRun() TestRun { - tr := TestRun{ +func ChangeoverTestConfig() TestConfig { + tr := TestConfig{ name: "changeover", containerConfig: ContainerConfig{ ContainerName: "interchain-security-changeover-container", @@ -395,7 +395,7 @@ func ChangeoverTestRun() TestRun { return tr } -func (s *TestRun) SetDockerConfig(localSdkPath string, useGaia bool, gaiaTag string) { +func (s *TestConfig) SetDockerConfig(localSdkPath string, useGaia bool, gaiaTag string) { if localSdkPath != "" { fmt.Println("USING LOCAL SDK", localSdkPath) } @@ -408,11 +408,11 @@ func (s *TestRun) SetDockerConfig(localSdkPath string, useGaia bool, gaiaTag str s.localSdkPath = localSdkPath } -func (s *TestRun) SetCometMockConfig(useCometmock bool) { +func (s *TestConfig) SetCometMockConfig(useCometmock bool) { s.useCometmock = useCometmock } -func (s *TestRun) SetRelayerConfig(useRly bool) { +func (s *TestConfig) SetRelayerConfig(useRly bool) { s.useGorelayer = useRly } @@ -423,7 +423,7 @@ func (s *TestRun) SetRelayerConfig(useRly bool) { // within the container will be named as "$CHAIN_ID-$VAL_ID-out" etc. // where this name is constrained to 15 bytes or less. Therefore each string literal // used as a validatorID or chainID needs to be 5 char or less. -func (s *TestRun) validateStringLiterals() { +func (s *TestConfig) validateStringLiterals() { for valID, valConfig := range s.validatorConfigs { if len(valID) > 5 { diff --git a/tests/e2e/main.go b/tests/e2e/main.go index d24f42676a..87c617be18 100644 --- a/tests/e2e/main.go +++ b/tests/e2e/main.go @@ -49,30 +49,74 @@ var ( ) var ( - testSelection TestSet - testMap map[string]*testRunWithSteps = map[string]*testRunWithSteps{ - "happy-path-short": { - testRun: DefaultTestRun(), steps: shortHappyPathSteps, - description: `This is like the happy path, but skips steps -that involve starting or stopping nodes for the same chain outside of the chain setup or teardown. -This is suited for CometMock+Gorelayer testing`, - }, - "light-client-attack": { - testRun: DefaultTestRun(), steps: lightClientAttackSteps, - description: `This is like the short happy path, but will slash validators for LightClientAttackEvidence instead of DuplicateVoteEvidence. -This is suited for CometMock+Gorelayer testing, but currently does not work with CometBFT, -since causing light client attacks is not implemented.`, - }, - "happy-path": {testRun: DefaultTestRun(), steps: happyPathSteps, description: "happy path tests"}, - "changeover": {testRun: ChangeoverTestRun(), steps: changeoverSteps, description: "changeover tests"}, - "democracy-reward": {testRun: DemocracyTestRun(true), steps: democracyRewardsSteps, description: "democracy tests allowing rewards"}, - "democracy": {testRun: DemocracyTestRun(false), steps: democracySteps, description: "democracy tests"}, - "slash-throttle": {testRun: SlashThrottleTestRun(), steps: slashThrottleSteps, description: "slash throttle tests"}, - "multiconsumer": {testRun: MultiConsumerTestRun(), steps: multipleConsumers, description: "multi consumer tests"}, + selectedTests TestSet + + // map the test config names to their structs to allow for easy selection of test configs, + // and also to programatically set parameters, i.e. see DemocracyTestConfig + testConfigs = map[string]TestConfig{ + "default": DefaultTestConfig(), + "changeover": ChangeoverTestConfig(), + "democracy": DemocracyTestConfig(false), + "democracy-reward": DemocracyTestConfig(true), + "slash-throttle": SlashThrottleTestConfig(), + "multiconsumer": MultiConsumerTestConfig(), } ) -func executeTests(tests []testRunWithSteps) (err error) { +var selectedTestfiles TestSet + +var stepChoices = map[string]StepChoice{ + "happy-path-short": { + name: "happy-path-short", + steps: shortHappyPathSteps, + description: `This is like the happy path, but skips steps that involve starting or stopping nodes for the same chain outside of the chain setup or teardown. This is suited for CometMock+Gorelayer testing`, + testConfig: DefaultTestConfig(), + }, + "light-client-attack": { + name: "light-client-attack", + steps: lightClientAttackSteps, + description: `This is like the short happy path, but will slash validators for LightClientAttackEvidence instead of DuplicateVoteEvidence. This is suited for CometMock+Gorelayer testing, but currently does not work with CometBFT, since causing light client attacks is not implemented`, + testConfig: DefaultTestConfig(), + }, + "happy-path": { + name: "happy-path", + steps: happyPathSteps, + description: "happy path tests", + testConfig: DefaultTestConfig(), + }, + "changeover": { + name: "changeover", + steps: changeoverSteps, + description: "changeover tests", + testConfig: ChangeoverTestConfig(), + }, + "democracy-reward": { + name: "democracy-reward", + steps: democracyRewardsSteps, + description: "democracy tests allowing rewards", + testConfig: DemocracyTestConfig(true), + }, + "democracy": { + name: "democracy", + steps: democracySteps, + description: "democracy tests", + testConfig: DemocracyTestConfig(false), + }, + "slash-throttle": { + name: "slash-throttle", + steps: slashThrottleSteps, + description: "slash throttle tests", + testConfig: SlashThrottleTestConfig(), + }, + "multiconsumer": { + name: "multiconsumer", + steps: multipleConsumers, + description: "multi consumer tests", + testConfig: MultiConsumerTestConfig(), + }, +} + +func executeTests(tests []testStepsWithConfig) (err error) { if parallel != nil && *parallel { fmt.Println("=============== running all tests in parallel ===============") } @@ -81,7 +125,7 @@ func executeTests(tests []testRunWithSteps) (err error) { for _, testCase := range tests { if parallel != nil && *parallel { wg.Add(1) - go func(run testRunWithSteps) { + go func(run testStepsWithConfig) { defer wg.Done() run.testRun.Run(run.steps, *localSdkPath, *useGaia, *gaiaTag) }(testCase) @@ -97,57 +141,131 @@ func executeTests(tests []testRunWithSteps) (err error) { return } +func getTestCaseUsageString() string { + var builder strings.Builder + + // Test case selection + builder.WriteString("This flag is used to reference existing, defined test cases to be run.") + builder.WriteString("Test case selection:\nSelection of test steps to be executed:\n") + for _, stepChoice := range stepChoices { + builder.WriteString(fmt.Sprintf("- %s : %s.\n", stepChoice.name, stepChoice.description)) + } + builder.WriteString("\n") + + // Test runner selection + builder.WriteString("Test runner selection:\nSelection of test runners to be executed:\n") + for _, testConfig := range testConfigs { + builder.WriteString(fmt.Sprintf("- %s\n", testConfig.name)) + } + builder.WriteString("\n") + + // Example + builder.WriteString("Example: -tc multiconsumer::multiconsumer -tc happy-path::default") + + return builder.String() +} + +func getTestFileUsageString() string { + var builder strings.Builder + + builder.WriteString("This flag is used to reference files containing step traces to be run.\n") + builder.WriteString("Each filename should be separated by '::' from the test runner name.\n") + + // Test runner selection + builder.WriteString("Test runner selection:\nSelection of test runners to be executed:\n") + for _, testConfig := range testConfigs { + builder.WriteString(fmt.Sprintf("- %s\n", testConfig.name)) + } + builder.WriteString("\n") + + // Example + builder.WriteString("Example: -test-file awesome-trace.json::default -test-file other-trace.json::default") + + return builder.String() +} + func parseArguments() (err error) { - flag.Var(&testSelection, "tc", - fmt.Sprintf("Selection of test cases to be executed:\n%s,\n%s", - func() string { - var keys []string - for k, v := range testMap { - keys = append(keys, fmt.Sprintf("- %s : %s", k, v.description)) - } - return strings.Join(keys, "\n") - }(), - "Example: -tc multiconsumer -tc happy-path ")) + flag.Var(&selectedTests, "tc", + getTestCaseUsageString()) + + flag.Var(&selectedTestfiles, "test-file", + getTestFileUsageString()) flag.Parse() // Enforce go-relayer in case of cometmock as hermes is not yet supported if useCometmock != nil && *useCometmock && (useGorelayer == nil || !*useGorelayer) { fmt.Println("Enforcing go-relayer as cometmock is requested") if err = flag.Set("use-gorelayer", "true"); err != nil { - return - } - } - // check if specified test case exists - for _, tc := range testSelection { - if _, hasKey := testMap[tc]; !hasKey { - err := fmt.Errorf("unknown test case '%s'", tc) return err } } - return + return nil } -func getTestCases(selection TestSet) (tests []testRunWithSteps) { +type testStepsWithConfig struct { + testRun TestConfig + steps []Step +} + +func getTestCases(selectedPredefinedTests, selectedTestFiles TestSet) (tests []testStepsWithConfig) { // Run default tests if no test cases were selected - if len(selection) == 0 { - selection = TestSet{ + if len(selectedPredefinedTests) == 0 && len(selectedTestFiles) == 0 { + selectedPredefinedTests = TestSet{ "changeover", "happy-path", "democracy-reward", "democracy", "slash-throttle", } if includeMultiConsumer != nil && *includeMultiConsumer { - selection = append(selection, "multiconsumer") + selectedPredefinedTests = append(selectedPredefinedTests, "multiconsumer") } } - // Get tests from selection - tests = []testRunWithSteps{} - for _, tc := range selection { - if _, exists := testMap[tc]; !exists { - log.Fatalf("Test case '%s' not found", tc) + tests = []testStepsWithConfig{} + // Get predefined from selection + for _, tc := range selectedPredefinedTests { + // first part of tc is the steps, second part is the test runner + + if _, exists := stepChoices[tc]; !exists { + log.Fatalf("Step choice '%s' not found.\nsee usage info:\n%s", tc, getTestCaseUsageString()) } - tests = append(tests, *testMap[tc]) + + stepChoice := stepChoices[tc] + + tests = append(tests, testStepsWithConfig{ + testRun: stepChoice.testConfig, + steps: stepChoice.steps, + }, + ) } - return + + // get test cases from files + for _, testFile := range selectedTestFiles { + // first part is the file, second part is the test runner + splitTcString := strings.Split(testFile, "::") + if len(splitTcString) != 2 { + log.Fatalf("Test file '%s' is invalid.\nsee usage info:\n%s", testFile, getTestFileUsageString()) + } + + testFileName := splitTcString[0] + testRunnerName := splitTcString[1] + + if _, exists := testConfigs[testRunnerName]; !exists { + log.Fatalf("Test runner '%s' not found.\nsee usage info:\n%s", testRunnerName, getTestFileUsageString()) + } + + testConfig := testConfigs[testRunnerName] + + testCase, err := GlobalJSONParser.ReadTraceFromFile(testFileName) + if err != nil { + log.Fatalf("Error reading test file '%s': %s", testFileName, err) + } + + tests = append(tests, testStepsWithConfig{ + testRun: testConfig, + steps: testCase, + }) + } + + return tests } // runs E2E tests @@ -159,7 +277,7 @@ func main() { log.Fatalf("Error parsing command arguments %s\n", err) } - testCases := getTestCases(testSelection) + testCases := getTestCases(selectedTests, selectedTestfiles) start := time.Now() err := executeTests(testCases) @@ -171,7 +289,7 @@ func main() { // Run sets up docker container and executes the steps in the test run. // Docker containers are torn down after the test run is complete. -func (tr *TestRun) Run(steps []Step, localSdkPath string, useGaia bool, gaiaTag string) { +func (tr *TestConfig) Run(steps []Step, localSdkPath string, useGaia bool, gaiaTag string) { tr.SetDockerConfig(localSdkPath, useGaia, gaiaTag) tr.SetCometMockConfig(*useCometmock) tr.SetRelayerConfig(*useGorelayer) @@ -182,13 +300,14 @@ func (tr *TestRun) Run(steps []Step, localSdkPath string, useGaia bool, gaiaTag tr.teardownDocker() } -type testRunWithSteps struct { - testRun TestRun +type StepChoice struct { + name string steps []Step description string + testConfig TestConfig } -func (tr *TestRun) runStep(step Step, verbose bool) { +func (tr *TestConfig) runStep(step Step, verbose bool) { switch action := step.Action.(type) { case StartChainAction: tr.startChain(action, verbose) @@ -278,7 +397,7 @@ func (tr *TestRun) runStep(step Step, verbose bool) { } // executeSteps sequentially runs steps. -func (tr *TestRun) executeSteps(steps []Step) { +func (tr *TestConfig) executeSteps(steps []Step) { fmt.Printf("=============== started %s tests ===============\n", tr.name) start := time.Now() @@ -292,7 +411,7 @@ func (tr *TestRun) executeSteps(steps []Step) { fmt.Printf("=============== finished %s tests in %v ===============\n", tr.name, time.Since(start)) } -func (tr *TestRun) startDocker() { +func (tr *TestConfig) startDocker() { fmt.Printf("=============== building %s testRun ===============\n", tr.name) localSdk := tr.localSdkPath if localSdk == "" { @@ -356,7 +475,7 @@ func (tr *TestRun) startDocker() { // remove docker container to reduce resource usage // otherwise the chain will keep running in the background -func (tr *TestRun) teardownDocker() { +func (tr *TestConfig) teardownDocker() { fmt.Printf("=============== tearing down %s testRun ===============\n", tr.name) //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. cmd := exec.Command("docker", "kill", tr.containerConfig.InstanceName) diff --git a/tests/e2e/state.go b/tests/e2e/state.go index f6beb3445c..ebfed57652 100644 --- a/tests/e2e/state.go +++ b/tests/e2e/state.go @@ -109,7 +109,7 @@ type Param struct { Value string } -func (tr TestRun) getState(modelState State) State { +func (tr TestConfig) getState(modelState State) State { systemState := State{} for k, modelState := range modelState { log.Println("Getting model state for chain: ", k) @@ -119,7 +119,7 @@ func (tr TestRun) getState(modelState State) State { return systemState } -func (tr TestRun) getChainState(chain ChainID, modelState ChainState) ChainState { +func (tr TestConfig) getChainState(chain ChainID, modelState ChainState) ChainState { chainState := ChainState{} if modelState.ValBalances != nil { @@ -195,7 +195,7 @@ func (tr TestRun) getChainState(chain ChainID, modelState ChainState) ChainState var blockHeightRegex = regexp.MustCompile(`block_height: "(\d+)"`) -func (tr TestRun) getBlockHeight(chain ChainID) uint { +func (tr TestConfig) getBlockHeight(chain ChainID) uint { //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. bz, err := exec.Command("docker", "exec", tr.containerConfig.InstanceName, tr.chainConfigs[chain].BinaryName, @@ -215,7 +215,7 @@ func (tr TestRun) getBlockHeight(chain ChainID) uint { return uint(blockHeight) } -func (tr TestRun) waitBlocks(chain ChainID, blocks uint, timeout time.Duration) { +func (tr TestConfig) waitBlocks(chain ChainID, blocks uint, timeout time.Duration) { if tr.useCometmock { // call advance_blocks method on cometmock // curl -H 'Content-Type: application/json' -H 'Accept:application/json' --data '{"jsonrpc":"2.0","method":"advance_blocks","params":{"num_blocks": "36000000"},"id":1}' 127.0.0.1:22331 @@ -241,7 +241,7 @@ func (tr TestRun) waitBlocks(chain ChainID, blocks uint, timeout time.Duration) } } -func (tr TestRun) waitUntilBlock(chain ChainID, block uint, timeout time.Duration) { +func (tr TestConfig) waitUntilBlock(chain ChainID, block uint, timeout time.Duration) { start := time.Now() for { thisBlock := tr.getBlockHeight(chain) @@ -255,7 +255,7 @@ func (tr TestRun) waitUntilBlock(chain ChainID, block uint, timeout time.Duratio } } -func (tr TestRun) getBalances(chain ChainID, modelState map[ValidatorID]uint) map[ValidatorID]uint { +func (tr TestConfig) getBalances(chain ChainID, modelState map[ValidatorID]uint) map[ValidatorID]uint { actualState := map[ValidatorID]uint{} for k := range modelState { actualState[k] = tr.getBalance(chain, k) @@ -264,7 +264,7 @@ func (tr TestRun) getBalances(chain ChainID, modelState map[ValidatorID]uint) ma return actualState } -func (tr TestRun) getProposals(chain ChainID, modelState map[uint]Proposal) map[uint]Proposal { +func (tr TestConfig) getProposals(chain ChainID, modelState map[uint]Proposal) map[uint]Proposal { actualState := map[uint]Proposal{} for k := range modelState { actualState[k] = tr.getProposal(chain, k) @@ -273,7 +273,7 @@ func (tr TestRun) getProposals(chain ChainID, modelState map[uint]Proposal) map[ return actualState } -func (tr TestRun) getValPowers(chain ChainID, modelState map[ValidatorID]uint) map[ValidatorID]uint { +func (tr TestConfig) getValPowers(chain ChainID, modelState map[ValidatorID]uint) map[ValidatorID]uint { actualState := map[ValidatorID]uint{} for k := range modelState { actualState[k] = tr.getValPower(chain, k) @@ -282,7 +282,7 @@ func (tr TestRun) getValPowers(chain ChainID, modelState map[ValidatorID]uint) m return actualState } -func (tr TestRun) getRepresentativePowers(chain ChainID, modelState map[ValidatorID]uint) map[ValidatorID]uint { +func (tr TestConfig) getRepresentativePowers(chain ChainID, modelState map[ValidatorID]uint) map[ValidatorID]uint { actualState := map[ValidatorID]uint{} for k := range modelState { actualState[k] = tr.getRepresentativePower(chain, k) @@ -291,7 +291,7 @@ func (tr TestRun) getRepresentativePowers(chain ChainID, modelState map[Validato return actualState } -func (tr TestRun) getParams(chain ChainID, modelState []Param) []Param { +func (tr TestConfig) getParams(chain ChainID, modelState []Param) []Param { actualState := []Param{} for _, p := range modelState { actualState = append(actualState, Param{Subspace: p.Subspace, Key: p.Key, Value: tr.getParam(chain, p)}) @@ -300,7 +300,7 @@ func (tr TestRun) getParams(chain ChainID, modelState []Param) []Param { return actualState } -func (tr TestRun) getRewards(chain ChainID, modelState Rewards) Rewards { +func (tr TestConfig) getRewards(chain ChainID, modelState Rewards) Rewards { receivedRewards := map[ValidatorID]bool{} currentBlock := tr.getBlockHeight(chain) @@ -318,7 +318,7 @@ func (tr TestRun) getRewards(chain ChainID, modelState Rewards) Rewards { return Rewards{IsRewarded: receivedRewards, IsIncrementalReward: modelState.IsIncrementalReward, IsNativeDenom: modelState.IsNativeDenom} } -func (tr TestRun) getReward(chain ChainID, validator ValidatorID, blockHeight uint, isNativeDenom bool) float64 { +func (tr TestConfig) getReward(chain ChainID, validator ValidatorID, blockHeight uint, isNativeDenom bool) float64 { delAddresss := tr.validatorConfigs[validator].DelAddress if chain != ChainID("provi") && tr.validatorConfigs[validator].UseConsumerKey { delAddresss = tr.validatorConfigs[validator].ConsumerDelAddress @@ -345,7 +345,7 @@ func (tr TestRun) getReward(chain ChainID, validator ValidatorID, blockHeight ui return gjson.Get(string(bz), denomCondition).Float() } -func (tr TestRun) getBalance(chain ChainID, validator ValidatorID) uint { +func (tr TestConfig) getBalance(chain ChainID, validator ValidatorID) uint { //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. valDelAddress := tr.validatorConfigs[validator].DelAddress if chain != ChainID("provi") && tr.validatorConfigs[validator].UseConsumerKey { @@ -373,7 +373,7 @@ func (tr TestRun) getBalance(chain ChainID, validator ValidatorID) uint { var noProposalRegex = regexp.MustCompile(`doesn't exist: key not found`) // interchain-securityd query gov proposals -func (tr TestRun) getProposal(chain ChainID, proposal uint) Proposal { +func (tr TestConfig) getProposal(chain ChainID, proposal uint) Proposal { //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. bz, err := exec.Command("docker", "exec", tr.containerConfig.InstanceName, tr.chainConfigs[chain].BinaryName, @@ -497,7 +497,7 @@ type ValPubKey struct { Value string `yaml:"value"` } -func (tr TestRun) getValPower(chain ChainID, validator ValidatorID) uint { +func (tr TestConfig) getValPower(chain ChainID, validator ValidatorID) uint { if *verbose { log.Println("getting validator power for chain: ", chain, " validator: ", validator) } @@ -547,7 +547,7 @@ func (tr TestRun) getValPower(chain ChainID, validator ValidatorID) uint { return 0 } -func (tr TestRun) getRepresentativePower(chain ChainID, validator ValidatorID) uint { +func (tr TestConfig) getRepresentativePower(chain ChainID, validator ValidatorID) uint { //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. bz, err := exec.Command("docker", "exec", tr.containerConfig.InstanceName, tr.chainConfigs[chain].BinaryName, @@ -566,7 +566,7 @@ func (tr TestRun) getRepresentativePower(chain ChainID, validator ValidatorID) u return uint(amount.Uint()) } -func (tr TestRun) getParam(chain ChainID, param Param) string { +func (tr TestConfig) getParam(chain ChainID, param Param) string { //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. bz, err := exec.Command("docker", "exec", tr.containerConfig.InstanceName, tr.chainConfigs[chain].BinaryName, @@ -588,7 +588,7 @@ func (tr TestRun) getParam(chain ChainID, param Param) string { // getConsumerChains returns a list of consumer chains that're being secured by the provider chain, // determined by querying the provider chain. -func (tr TestRun) getConsumerChains(chain ChainID) map[ChainID]bool { +func (tr TestConfig) getConsumerChains(chain ChainID) map[ChainID]bool { //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. cmd := exec.Command("docker", "exec", tr.containerConfig.InstanceName, tr.chainConfigs[chain].BinaryName, @@ -612,7 +612,7 @@ func (tr TestRun) getConsumerChains(chain ChainID) map[ChainID]bool { return chains } -func (tr TestRun) getConsumerAddresses(chain ChainID, modelState map[ValidatorID]string) map[ValidatorID]string { +func (tr TestConfig) getConsumerAddresses(chain ChainID, modelState map[ValidatorID]string) map[ValidatorID]string { actualState := map[ValidatorID]string{} for k := range modelState { actualState[k] = tr.getConsumerAddress(chain, k) @@ -621,7 +621,7 @@ func (tr TestRun) getConsumerAddresses(chain ChainID, modelState map[ValidatorID return actualState } -func (tr TestRun) getProviderAddresses(chain ChainID, modelState map[ValidatorID]string) map[ValidatorID]string { +func (tr TestConfig) getProviderAddresses(chain ChainID, modelState map[ValidatorID]string) map[ValidatorID]string { actualState := map[ValidatorID]string{} for k := range modelState { actualState[k] = tr.getProviderAddressFromConsumer(chain, k) @@ -630,7 +630,7 @@ func (tr TestRun) getProviderAddresses(chain ChainID, modelState map[ValidatorID return actualState } -func (tr TestRun) getConsumerAddress(consumerChain ChainID, validator ValidatorID) string { +func (tr TestConfig) getConsumerAddress(consumerChain ChainID, validator ValidatorID) string { //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. cmd := exec.Command("docker", "exec", tr.containerConfig.InstanceName, tr.chainConfigs[ChainID("provi")].BinaryName, @@ -648,7 +648,7 @@ func (tr TestRun) getConsumerAddress(consumerChain ChainID, validator ValidatorI return addr } -func (tr TestRun) getProviderAddressFromConsumer(consumerChain ChainID, validator ValidatorID) string { +func (tr TestConfig) getProviderAddressFromConsumer(consumerChain ChainID, validator ValidatorID) string { //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. cmd := exec.Command("docker", "exec", tr.containerConfig.InstanceName, tr.chainConfigs[ChainID("provi")].BinaryName, @@ -667,7 +667,7 @@ func (tr TestRun) getProviderAddressFromConsumer(consumerChain ChainID, validato return addr } -func (tr TestRun) getGlobalSlashQueueSize() uint { +func (tr TestConfig) getGlobalSlashQueueSize() uint { //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. cmd := exec.Command("docker", "exec", tr.containerConfig.InstanceName, tr.chainConfigs[ChainID("provi")].BinaryName, @@ -684,7 +684,7 @@ func (tr TestRun) getGlobalSlashQueueSize() uint { return uint(len(packets)) } -func (tr TestRun) getConsumerChainPacketQueueSize(consumerChain ChainID) uint { +func (tr TestConfig) getConsumerChainPacketQueueSize(consumerChain ChainID) uint { //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. cmd := exec.Command("docker", "exec", tr.containerConfig.InstanceName, tr.chainConfigs[ChainID("provi")].BinaryName, @@ -702,7 +702,7 @@ func (tr TestRun) getConsumerChainPacketQueueSize(consumerChain ChainID) uint { return uint(size) } -func (tr TestRun) getRegisteredConsumerRewardDenoms(chain ChainID) []string { +func (tr TestConfig) getRegisteredConsumerRewardDenoms(chain ChainID) []string { //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. cmd := exec.Command("docker", "exec", tr.containerConfig.InstanceName, tr.chainConfigs[chain].BinaryName, @@ -724,7 +724,7 @@ func (tr TestRun) getRegisteredConsumerRewardDenoms(chain ChainID) []string { return rewardDenoms } -func (tr TestRun) getValidatorNode(chain ChainID, validator ValidatorID) string { +func (tr TestConfig) getValidatorNode(chain ChainID, validator ValidatorID) string { // for CometMock, validatorNodes are all the same address as the query node (which is CometMocks address) if tr.useCometmock { return tr.getQueryNode(chain) @@ -733,27 +733,27 @@ func (tr TestRun) getValidatorNode(chain ChainID, validator ValidatorID) string return "tcp://" + tr.getValidatorIP(chain, validator) + ":26658" } -func (tr TestRun) getValidatorIP(chain ChainID, validator ValidatorID) string { +func (tr TestConfig) getValidatorIP(chain ChainID, validator ValidatorID) string { return tr.chainConfigs[chain].IpPrefix + "." + tr.validatorConfigs[validator].IpSuffix } -func (tr TestRun) getValidatorHome(chain ChainID, validator ValidatorID) string { +func (tr TestConfig) getValidatorHome(chain ChainID, validator ValidatorID) string { return `/` + string(tr.chainConfigs[chain].ChainId) + `/validator` + fmt.Sprint(validator) } // getQueryNode returns query node tcp address on chain. -func (tr TestRun) getQueryNode(chain ChainID) string { +func (tr TestConfig) getQueryNode(chain ChainID) string { return fmt.Sprintf("tcp://%s", tr.getQueryNodeRPCAddress(chain)) } -func (tr TestRun) getQueryNodeRPCAddress(chain ChainID) string { +func (tr TestConfig) getQueryNodeRPCAddress(chain ChainID) string { return fmt.Sprintf("%s:26658", tr.getQueryNodeIP(chain)) } // getQueryNodeIP returns query node IP for chain, // ipSuffix is hardcoded to be 253 on all query nodes // except for "sover" chain where there's only one node -func (tr TestRun) getQueryNodeIP(chain ChainID) string { +func (tr TestConfig) getQueryNodeIP(chain ChainID) string { if chain == ChainID("sover") { // return address of first and only validator return fmt.Sprintf("%s.%s", @@ -763,7 +763,7 @@ func (tr TestRun) getQueryNodeIP(chain ChainID) string { return fmt.Sprintf("%s.253", tr.chainConfigs[chain].IpPrefix) } -func (tr TestRun) curlJsonRPCRequest(method, params, address string) { +func (tr TestConfig) curlJsonRPCRequest(method, params, address string) { cmd_template := `curl -H 'Content-Type: application/json' -H 'Accept:application/json' --data '{"jsonrpc":"2.0","method":"%s","params":%s,"id":1}' %s` //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments.