diff --git a/.github/workflows/e2e-test-workflow-call.yml b/.github/workflows/e2e-test-workflow-call.yml index c19fb6ed2d4..18af44e5280 100644 --- a/.github/workflows/e2e-test-workflow-call.yml +++ b/.github/workflows/e2e-test-workflow-call.yml @@ -6,6 +6,11 @@ on: required: false type: string default: '' # empty string means run all tests + temp-run-full-suite: + description: 'This flag exists to run a hard coded set of tests and will be phased out' + required: false + type: boolean + default: false test: description: 'test name to run as standalone' required: false @@ -253,3 +258,49 @@ jobs: name: '${{ matrix.entrypoint }}-${{ matrix.test }}' path: e2e/diagnostics retention-days: 5 + + e2e-test-suites: + # temporary flag. eventually this field will not exist and this will be the default. + if: ${{ inputs.temp-run-full-suite }} + runs-on: ubuntu-latest + needs: + - build-test-matrix + - docker-build + - docker-build-wasm + env: + CHAIN_IMAGE: '${{ inputs.chain-image }}' + CHAIN_A_TAG: '${{ inputs.chain-a-tag }}' + CHAIN_B_TAG: '${{ inputs.chain-b-tag }}' + RELAYER_IMAGE: '${{ inputs.relayer-image }}' + RELAYER_TAG: '${{ inputs.relayer-tag }}' + RELAYER_ID: '${{ inputs.relayer-type }}' + CHAIN_BINARY: '${{ inputs.chain-binary }}' + CHAIN_UPGRADE_TAG: '${{ inputs.chain-upgrade-tag }}' + CHAIN_UPGRADE_PLAN: '${{ inputs.upgrade-plan-name }}' + strategy: + fail-fast: false + matrix: + include: + # for now we explicitly specify this test suite. + - entrypoint: TestTransferTestSuite + steps: + - uses: actions/checkout@v4 + with: + repository: cosmos/ibc-go + - uses: actions/setup-go@v5 + with: + go-version: '1.22' + cache-dependency-path: 'e2e/go.sum' + - name: Run e2e Test + id: e2e_test + run: | + cd e2e + make e2e-suite entrypoint=${{ matrix.entrypoint }} + - name: Upload Diagnostics + uses: actions/upload-artifact@v4 + if: ${{ failure() && inputs.upload-logs }} + continue-on-error: true + with: + name: '${{ matrix.entrypoint }}-${{ matrix.test }}' + path: e2e/diagnostics + retention-days: 5 \ No newline at end of file diff --git a/.github/workflows/e2e.yaml b/.github/workflows/e2e.yaml index a15261b4888..8f0f069a738 100644 --- a/.github/workflows/e2e.yaml +++ b/.github/workflows/e2e.yaml @@ -67,4 +67,6 @@ jobs: chain-b-tag: '${{ needs.determine-image-tag.outputs.simd-tag }}' chain-binary: 'simd' # on regular PRs we won't run upgrade tests. - test-exclusions: 'TestUpgradeTestSuite,TestGrandpaTestSuite,TestIBCWasmUpgradeTestSuite' + # NOTE: we are exluding TestTransferTestSuite as we run this full suite instead of each individual test. + test-exclusions: 'TestUpgradeTestSuite,TestGrandpaTestSuite,TestIBCWasmUpgradeTestSuite,TestTransferTestSuite' + temp-run-full-suite: true diff --git a/e2e/Makefile b/e2e/Makefile index e34391ae3ef..34938edb50e 100644 --- a/e2e/Makefile +++ b/e2e/Makefile @@ -14,7 +14,7 @@ e2e-test: init cleanup-ibc-test-containers ./scripts/run-e2e.sh $(test) $(entrypoint) e2e-suite: init cleanup-ibc-test-containers - RUN_SUITE="true" ./scripts/run-e2e.sh $(test) $(entrypoint) + RUN_SUITE="true" ./scripts/run-e2e.sh "" $(entrypoint) compatibility-tests: ./scripts/run-compatibility-tests.sh $(release_branch) diff --git a/e2e/scripts/run-e2e.sh b/e2e/scripts/run-e2e.sh index 5c345dd94a5..58c5b3db683 100755 --- a/e2e/scripts/run-e2e.sh +++ b/e2e/scripts/run-e2e.sh @@ -2,8 +2,8 @@ set -eo pipefail -TEST="${1}" -ENTRY_POINT="${2:-}" +TEST="${1:-}" +export ENTRY_POINT="${2:-}" function _verify_jq() { if ! command -v jq > /dev/null ; then @@ -19,7 +19,7 @@ function _verify_fzf() { fi } -function _verify_dependencies() { +function _verify_test_dependencies() { if [ -z "${TEST}" ]; then # fzf is only required if we are not explicitly specifying a test. _verify_fzf @@ -28,6 +28,14 @@ function _verify_dependencies() { _verify_jq } +function _verify_suite_dependencies() { + if [ -z "${ENTRY_POINT}" ]; then + # fzf is only required if we are not explicitly specifying an entrypoint. + _verify_fzf + fi + # jq is always required to determine the entrypoint of the test. + _verify_jq +} # _select_test_config lets you dynamically select a test config for the specific test. function _select_test_config() { @@ -51,7 +59,7 @@ function _get_test(){ # run_test runs a single E2E test. function run_test() { - # if the dev configs directory is present, enable fzf completion to select a test config file to use. + _verify_test_dependencies # if test is set, that is used directly, otherwise the test can be interactively provided if fzf is installed. TEST="$(_get_test ${TEST})" @@ -78,23 +86,23 @@ function run_test() { # run_suite runs a full E2E test suite. function run_suite() { + _verify_suite_dependencies # if jq is installed, we can automatically determine the test entrypoint. - if command -v jq > /dev/null; then + if [ -z "${ENTRY_POINT}" ]; then cd .. ENTRY_POINT="$(go run -mod=readonly cmd/build_test_matrix/main.go | jq -r '.include[] | .entrypoint' | uniq | fzf)" cd - > /dev/null fi # find the name of the file that has this test in it. - test_file="$(grep --recursive --files-with-matches './tests' -e "${ENTRY_POINT}")" + test_file="$(grep --recursive --files-with-matches './tests' -e "${ENTRY_POINT}(")" test_dir="$(dirname $test_file)" - # TODO: add the -p flag to run tests in parallel - go test -v "${test_dir}" --run ${ENTRY_POINT} -timeout 30m + go test -v "${test_dir}" --run ^${ENTRY_POINT}$ -timeout 30m -p 10 } -_verify_dependencies +# if the dev configs directory is present, enable fzf completion to select a test config file to use. if [[ -d "dev-configs" ]]; then export E2E_CONFIG_PATH="$(pwd)/dev-configs/$(_select_test_config)" echo "Using configuration file at ${E2E_CONFIG_PATH}" diff --git a/e2e/tests/core/02-client/client_test.go b/e2e/tests/core/02-client/client_test.go index ae041a3b4cb..100ed215ce0 100644 --- a/e2e/tests/core/02-client/client_test.go +++ b/e2e/tests/core/02-client/client_test.go @@ -65,6 +65,9 @@ func (s *ClientTestSuite) TestScheduleIBCUpgrade_Succeeds() { t := s.T() ctx := context.TODO() + testName := t.Name() + s.CreateDefaultPaths(testName) + chainA, chainB := s.GetChains() chainAWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) @@ -169,14 +172,15 @@ func (s *ClientTestSuite) TestClientUpdateProposal_Succeeds() { badTrustingPeriod = time.Second * 10 ) - relayer := s.GetRelayer() + testName := t.Name() + relayer := s.CreateDefaultPaths(testName) t.Run("create substitute client with correct trusting period", func(t *testing.T) { // TODO: update when client identifier created is accessible // currently assumes first client is 07-tendermint-0 substituteClientID = clienttypes.FormatClientIdentifier(ibcexported.Tendermint, 0) - pathName = s.GetPaths()[0] + pathName = s.GetPaths(testName)[0] }) chainA, chainB := s.GetChains() @@ -249,14 +253,15 @@ func (s *ClientTestSuite) TestRecoverClient_Succeeds() { badTrustingPeriod = time.Second * 10 ) - relayer := s.GetRelayer() + testName := t.Name() + relayer := s.CreateDefaultPaths(testName) t.Run("create substitute client with correct trusting period", func(t *testing.T) { // TODO: update when client identifier created is accessible // currently assumes first client is 07-tendermint-0 substituteClientID = clienttypes.FormatClientIdentifier(ibcexported.Tendermint, 0) - pathName = s.GetPaths()[0] + pathName = s.GetPaths(testName)[0] }) chainA, chainB := s.GetChains() @@ -334,13 +339,15 @@ func (s *ClientTestSuite) TestClient_Update_Misbehaviour() { err error ) - relayer := s.GetRelayer() + testName := t.Name() + relayer := s.CreateDefaultPaths(testName) + chainA, chainB := s.GetChains() s.Require().NoError(test.WaitForBlocks(ctx, 10, chainA, chainB)) t.Run("update clients", func(t *testing.T) { - err := relayer.UpdateClients(ctx, s.GetRelayerExecReporter(), s.GetPaths()[0]) + err := relayer.UpdateClients(ctx, s.GetRelayerExecReporter(), s.GetPaths(testName)[0]) s.Require().NoError(err) clientState, err = query.ClientState(ctx, chainA, ibctesting.FirstClientID) @@ -356,7 +363,7 @@ func (s *ClientTestSuite) TestClient_Update_Misbehaviour() { }) t.Run("update clients", func(t *testing.T) { - err := relayer.UpdateClients(ctx, s.GetRelayerExecReporter(), s.GetPaths()[0]) + err := relayer.UpdateClients(ctx, s.GetRelayerExecReporter(), s.GetPaths(testName)[0]) s.Require().NoError(err) clientState, err = query.ClientState(ctx, chainA, ibctesting.FirstClientID) @@ -438,6 +445,9 @@ func (s *ClientTestSuite) TestAllowedClientsParam() { t := s.T() ctx := context.TODO() + testName := t.Name() + s.CreateDefaultPaths(testName) + chainA, chainB := s.GetChains() chainAVersion := chainA.Config().Images[0].Version chainAWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) diff --git a/e2e/tests/core/03-connection/connection_test.go b/e2e/tests/core/03-connection/connection_test.go index 93dbcd98004..04546ca58ff 100644 --- a/e2e/tests/core/03-connection/connection_test.go +++ b/e2e/tests/core/03-connection/connection_test.go @@ -33,8 +33,8 @@ type ConnectionTestSuite struct { testsuite.E2ETestSuite } -func (s *ConnectionTestSuite) SetupTest() { - s.SetupPaths(ibc.DefaultClientOpts(), s.TransferChannelOptions()) +func (s *ConnectionTestSuite) CreateConnectionTestPath(testName string) (ibc.Relayer, ibc.ChannelOutput) { + return s.CreatePaths(ibc.DefaultClientOpts(), s.TransferChannelOptions(), testName), s.GetChainAChannelForTest(testName) } // QueryMaxExpectedTimePerBlockParam queries the on-chain max expected time per block param for 03-connection @@ -65,7 +65,8 @@ func (s *ConnectionTestSuite) TestMaxExpectedTimePerBlockParam() { t := s.T() ctx := context.TODO() - relayer, channelA := s.GetRelayer(), s.GetChainAChannel() + testName := t.Name() + relayer, channelA := s.CreateConnectionTestPath(testName) chainA, chainB := s.GetChains() chainAVersion := chainA.Config().Images[0].Version @@ -126,7 +127,7 @@ func (s *ConnectionTestSuite) TestMaxExpectedTimePerBlockParam() { }) t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) + s.StartRelayer(relayer, testName) }) t.Run("packets are relayed", func(t *testing.T) { diff --git a/e2e/tests/interchain_accounts/base_test.go b/e2e/tests/interchain_accounts/base_test.go index 76e6e53beed..6cb18dcf12e 100644 --- a/e2e/tests/interchain_accounts/base_test.go +++ b/e2e/tests/interchain_accounts/base_test.go @@ -62,9 +62,9 @@ func (s *InterchainAccountsTestSuite) testMsgSendTxSuccessfulTransfer(order chan t := s.T() ctx := context.TODO() - // setup relayers and connection-0 between two chains - // channel-0 is a transfer channel but it will not be used in this test case - relayer := s.GetRelayer() + testName := t.Name() + relayer := s.CreateDefaultPaths(testName) + chainA, chainB := s.GetChains() // setup 2 accounts: controller account on chain A, a second chain B account. @@ -84,7 +84,7 @@ func (s *InterchainAccountsTestSuite) testMsgSendTxSuccessfulTransfer(order chan }) t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) + s.StartRelayer(relayer, testName) }) t.Run("verify interchain account", func(t *testing.T) { @@ -161,7 +161,9 @@ func (s *InterchainAccountsTestSuite) TestMsgSendTx_FailedTransfer_InsufficientF t := s.T() ctx := context.TODO() - relayer := s.GetRelayer() + testName := t.Name() + relayer := s.CreateDefaultPaths(testName) + chainA, chainB := s.GetChains() // setup 2 accounts: controller account on chain A, a second chain B account. @@ -181,7 +183,7 @@ func (s *InterchainAccountsTestSuite) TestMsgSendTx_FailedTransfer_InsufficientF }) t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) + s.StartRelayer(relayer, testName) }) t.Run("verify interchain account", func(t *testing.T) { @@ -249,7 +251,9 @@ func (s *InterchainAccountsTestSuite) TestMsgSendTx_SuccessfulTransfer_AfterReop t := s.T() ctx := context.TODO() - relayer := s.GetRelayer() + testName := t.Name() + relayer := s.CreateDefaultPaths(testName) + chainA, chainB := s.GetChains() // setup 2 accounts: controller account on chain A, a second chain B account. @@ -277,7 +281,7 @@ func (s *InterchainAccountsTestSuite) TestMsgSendTx_SuccessfulTransfer_AfterReop }) t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) + s.StartRelayer(relayer, testName) }) t.Run("verify interchain account", func(t *testing.T) { @@ -342,7 +346,7 @@ func (s *InterchainAccountsTestSuite) TestMsgSendTx_SuccessfulTransfer_AfterReop }) t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) + s.StartRelayer(relayer, testName) }) t.Run("verify channel is closed due to timeout on ordered channel", func(t *testing.T) { @@ -436,9 +440,9 @@ func (s *InterchainAccountsTestSuite) testMsgSendTxSuccessfulGovProposal(order c t := s.T() ctx := context.TODO() - // setup relayers and connection-0 between two chains - // channel-0 is a transfer channel but it will not be used in this test case - relayer := s.GetRelayer() + testName := t.Name() + relayer := s.CreateDefaultPaths(testName) + chainA, chainB := s.GetChains() // setup 2 accounts: controller account on chain A, a second chain B account. @@ -457,7 +461,7 @@ func (s *InterchainAccountsTestSuite) testMsgSendTxSuccessfulGovProposal(order c }) t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) + s.StartRelayer(relayer, testName) }) t.Run("verify interchain account", func(t *testing.T) { diff --git a/e2e/tests/interchain_accounts/gov_test.go b/e2e/tests/interchain_accounts/gov_test.go index 98f1acd9fed..b0a46e1d026 100644 --- a/e2e/tests/interchain_accounts/gov_test.go +++ b/e2e/tests/interchain_accounts/gov_test.go @@ -40,7 +40,9 @@ func (s *InterchainAccountsGovTestSuite) TestInterchainAccountsGovIntegration() t := s.T() ctx := context.TODO() - relayer := s.GetRelayer() + testName := t.Name() + relayer := s.CreateDefaultPaths(testName) + chainA, chainB := s.GetChains() controllerAccount := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) @@ -58,7 +60,7 @@ func (s *InterchainAccountsGovTestSuite) TestInterchainAccountsGovIntegration() }) t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) + s.StartRelayer(relayer, testName) }) s.Require().NoError(test.WaitForBlocks(ctx, 10, chainA, chainB)) diff --git a/e2e/tests/interchain_accounts/groups_test.go b/e2e/tests/interchain_accounts/groups_test.go index 2ebc61d660e..82c486c47d7 100644 --- a/e2e/tests/interchain_accounts/groups_test.go +++ b/e2e/tests/interchain_accounts/groups_test.go @@ -86,7 +86,9 @@ func (s *InterchainAccountsGroupsTestSuite) TestInterchainAccountsGroupsIntegrat err error ) - relayer := s.GetRelayer() + testName := t.Name() + relayer := s.CreateDefaultPaths(testName) + chainA, chainB := s.GetChains() chainAWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) @@ -135,7 +137,7 @@ func (s *InterchainAccountsGroupsTestSuite) TestInterchainAccountsGroupsIntegrat }) t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) + s.StartRelayer(relayer, testName) }) t.Run("verify interchain account registration success", func(t *testing.T) { diff --git a/e2e/tests/interchain_accounts/incentivized_test.go b/e2e/tests/interchain_accounts/incentivized_test.go index b4424f264f3..14ad055425c 100644 --- a/e2e/tests/interchain_accounts/incentivized_test.go +++ b/e2e/tests/interchain_accounts/incentivized_test.go @@ -40,7 +40,9 @@ func (s *IncentivizedInterchainAccountsTestSuite) TestMsgSendTx_SuccessfulBankSe t := s.T() ctx := context.TODO() - relayer := s.GetRelayer() + testName := t.Name() + relayer := s.CreateDefaultPaths(testName) + chainA, chainB := s.GetChains() var ( @@ -78,7 +80,7 @@ func (s *IncentivizedInterchainAccountsTestSuite) TestMsgSendTx_SuccessfulBankSe }) t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) + s.StartRelayer(relayer, testName) }) var channelOutput ibc.ChannelOutput @@ -174,7 +176,7 @@ func (s *IncentivizedInterchainAccountsTestSuite) TestMsgSendTx_SuccessfulBankSe }) t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) + s.StartRelayer(relayer, testName) }) t.Run("packets are relayed", func(t *testing.T) { @@ -216,7 +218,9 @@ func (s *IncentivizedInterchainAccountsTestSuite) TestMsgSendTx_FailedBankSend_I t := s.T() ctx := context.TODO() - relayer := s.GetRelayer() + testName := t.Name() + relayer := s.CreateDefaultPaths(testName) + chainA, chainB := s.GetChains() var ( @@ -254,7 +258,7 @@ func (s *IncentivizedInterchainAccountsTestSuite) TestMsgSendTx_FailedBankSend_I }) t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) + s.StartRelayer(relayer, testName) }) var channelOutput ibc.ChannelOutput @@ -341,7 +345,7 @@ func (s *IncentivizedInterchainAccountsTestSuite) TestMsgSendTx_FailedBankSend_I }) t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) + s.StartRelayer(relayer, testName) }) t.Run("packets are relayed", func(t *testing.T) { diff --git a/e2e/tests/interchain_accounts/localhost_test.go b/e2e/tests/interchain_accounts/localhost_test.go index e11233c2f2c..a52e86762ad 100644 --- a/e2e/tests/interchain_accounts/localhost_test.go +++ b/e2e/tests/interchain_accounts/localhost_test.go @@ -42,6 +42,9 @@ func (s *LocalhostInterchainAccountsTestSuite) TestInterchainAccounts_Localhost( t := s.T() ctx := context.TODO() + testName := t.Name() + s.CreateDefaultPaths(testName) + chainA, _ := s.GetChains() chainADenom := chainA.Config().Denom @@ -195,6 +198,9 @@ func (s *LocalhostInterchainAccountsTestSuite) TestInterchainAccounts_ReopenChan t := s.T() ctx := context.TODO() + testName := t.Name() + s.CreateDefaultPaths(testName) + chainA, _ := s.GetChains() chainADenom := chainA.Config().Denom diff --git a/e2e/tests/interchain_accounts/params_test.go b/e2e/tests/interchain_accounts/params_test.go index afe6893cf16..ee4dabb0747 100644 --- a/e2e/tests/interchain_accounts/params_test.go +++ b/e2e/tests/interchain_accounts/params_test.go @@ -60,6 +60,9 @@ func (s *InterchainAccountsParamsTestSuite) TestControllerEnabledParam() { t := s.T() ctx := context.TODO() + testName := t.Name() + s.CreateDefaultPaths(testName) + chainA, _ := s.GetChains() chainAVersion := chainA.Config().Images[0].Version @@ -112,7 +115,9 @@ func (s *InterchainAccountsParamsTestSuite) TestHostEnabledParam() { t := s.T() ctx := context.TODO() - relayer := s.GetRelayer() + testName := t.Name() + relayer := s.CreateDefaultPaths(testName) + chainA, chainB := s.GetChains() chainBVersion := chainB.Config().Images[0].Version @@ -142,7 +147,7 @@ func (s *InterchainAccountsParamsTestSuite) TestHostEnabledParam() { }) t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) + s.StartRelayer(relayer, testName) }) t.Run("verify interchain account", func(t *testing.T) { @@ -229,7 +234,7 @@ func (s *InterchainAccountsParamsTestSuite) TestHostEnabledParam() { }) t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) + s.StartRelayer(relayer, testName) }) s.Require().NoError(test.WaitForBlocks(ctx, 10, chainA, chainB)) diff --git a/e2e/tests/interchain_accounts/query_test.go b/e2e/tests/interchain_accounts/query_test.go index cd648b19455..dd7a46c9581 100644 --- a/e2e/tests/interchain_accounts/query_test.go +++ b/e2e/tests/interchain_accounts/query_test.go @@ -38,9 +38,9 @@ func (s *InterchainAccountsQueryTestSuite) TestInterchainAccountsQuery() { t := s.T() ctx := context.TODO() - // setup relayers and connection-0 between two chains - // channel-0 is a transfer channel but it will not be used in this test case - relayer := s.GetRelayer() + testName := t.Name() + relayer := s.CreateDefaultPaths(testName) + chainA, chainB := s.GetChains() chainBVersion := chainB.Config().Images[0].Version @@ -61,7 +61,7 @@ func (s *InterchainAccountsQueryTestSuite) TestInterchainAccountsQuery() { }) t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) + s.StartRelayer(relayer, testName) }) t.Run("verify interchain account", func(t *testing.T) { diff --git a/e2e/tests/interchain_accounts/upgrades_test.go b/e2e/tests/interchain_accounts/upgrades_test.go index af7b22e7ea4..1f9fcbc13fa 100644 --- a/e2e/tests/interchain_accounts/upgrades_test.go +++ b/e2e/tests/interchain_accounts/upgrades_test.go @@ -43,9 +43,9 @@ func (s *InterchainAccountsChannelUpgradesTestSuite) TestMsgSendTx_SuccessfulTra t := s.T() ctx := context.TODO() - // setup relayers and connection-0 between two chains - // channel-0 is a transfer channel but it will not be used in this test case - relayer := s.GetRelayer() + testName := t.Name() + relayer := s.CreateDefaultPaths(testName) + chainA, chainB := s.GetChains() // setup 2 accounts: controller account on chain A, a second chain B account. @@ -74,7 +74,7 @@ func (s *InterchainAccountsChannelUpgradesTestSuite) TestMsgSendTx_SuccessfulTra }) t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) + s.StartRelayer(relayer, testName) }) t.Run("verify interchain account", func(t *testing.T) { @@ -223,7 +223,10 @@ func (s *InterchainAccountsChannelUpgradesTestSuite) TestChannelUpgrade_ICAChann t := s.T() ctx := context.TODO() - relayer := s.GetRelayer() + testName := t.Name() + + relayer := s.CreateDefaultPaths(testName) + chainA, chainB := s.GetChains() // setup 2 accounts: controller account on chain A, a second chain B account. @@ -258,7 +261,7 @@ func (s *InterchainAccountsChannelUpgradesTestSuite) TestChannelUpgrade_ICAChann }) t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) + s.StartRelayer(relayer, testName) }) t.Run("verify interchain account", func(t *testing.T) { @@ -360,7 +363,7 @@ func (s *InterchainAccountsChannelUpgradesTestSuite) TestChannelUpgrade_ICAChann }) t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) + s.StartRelayer(relayer, testName) }) t.Run("verify channel A is closed due to timeout on ordered channel", func(t *testing.T) { diff --git a/e2e/tests/transfer/authz_test.go b/e2e/tests/transfer/authz_test.go index 24ea055d6bd..44b7091dae5 100644 --- a/e2e/tests/transfer/authz_test.go +++ b/e2e/tests/transfer/authz_test.go @@ -32,8 +32,8 @@ type AuthzTransferTestSuite struct { testsuite.E2ETestSuite } -func (suite *AuthzTransferTestSuite) SetupTest() { - suite.SetupPaths(ibc.DefaultClientOpts(), suite.TransferChannelOptions()) +func (suite *AuthzTransferTestSuite) CreateAuthzTestPath(testName string) (ibc.Relayer, ibc.ChannelOutput) { + return suite.CreatePaths(ibc.DefaultClientOpts(), suite.TransferChannelOptions(), testName), suite.GetChainAChannelForTest(testName) } // QueryGranterGrants returns all GrantAuthorizations for the given granterAddress. @@ -52,7 +52,9 @@ func (suite *AuthzTransferTestSuite) TestAuthz_MsgTransfer_Succeeds() { t := suite.T() ctx := context.TODO() - relayer, channelA := suite.GetRelayer(), suite.GetChainAChannel() + testName := t.Name() + relayer, channelA := suite.CreateAuthzTestPath(testName) + chainA, chainB := suite.GetChains() chainADenom := chainA.Config().Denom @@ -66,7 +68,7 @@ func (suite *AuthzTransferTestSuite) TestAuthz_MsgTransfer_Succeeds() { receiverWalletAddress := receiverWallet.FormattedAddress() t.Run("start relayer", func(t *testing.T) { - suite.StartRelayer(relayer) + suite.StartRelayer(relayer, testName) }) // createMsgGrantFn initializes a TransferAuthorization and broadcasts a MsgGrant message. @@ -212,7 +214,8 @@ func (suite *AuthzTransferTestSuite) TestAuthz_InvalidTransferAuthorizations() { t := suite.T() ctx := context.TODO() - relayer, channelA := suite.GetRelayer(), suite.GetChainAChannel() + testName := t.Name() + relayer, channelA := suite.CreateAuthzTestPath(testName) chainA, chainB := suite.GetChains() chainADenom := chainA.Config().Denom @@ -228,7 +231,7 @@ func (suite *AuthzTransferTestSuite) TestAuthz_InvalidTransferAuthorizations() { receiverWalletAddress := receiverWallet.FormattedAddress() t.Run("start relayer", func(t *testing.T) { - suite.StartRelayer(relayer) + suite.StartRelayer(relayer, testName) }) const spendLimit = 1000 diff --git a/e2e/tests/transfer/base_test.go b/e2e/tests/transfer/base_test.go index 7acafea833f..a818b2f3ac1 100644 --- a/e2e/tests/transfer/base_test.go +++ b/e2e/tests/transfer/base_test.go @@ -7,7 +7,6 @@ import ( "testing" "time" - "github.com/strangelove-ventures/interchaintest/v8/chain/cosmos" "github.com/strangelove-ventures/interchaintest/v8/ibc" test "github.com/strangelove-ventures/interchaintest/v8/testutil" testifysuite "github.com/stretchr/testify/suite" @@ -15,14 +14,11 @@ import ( sdkmath "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" - govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" - paramsproposaltypes "github.com/cosmos/cosmos-sdk/x/params/types/proposal" "github.com/cosmos/ibc-go/e2e/testsuite" "github.com/cosmos/ibc-go/e2e/testsuite/query" "github.com/cosmos/ibc-go/e2e/testvalues" transfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" - ibctesting "github.com/cosmos/ibc-go/v8/testing" ) func TestTransferTestSuite(t *testing.T) { @@ -30,20 +26,30 @@ func TestTransferTestSuite(t *testing.T) { } type TransferTestSuite struct { - testsuite.E2ETestSuite + transferTester } -func (s *TransferTestSuite) SetupTest() { - s.SetupPaths(ibc.DefaultClientOpts(), s.TransferChannelOptions()) +// transferTester defines some helper functions that can be used in various test suites +// that test transfer functionality. +type transferTester struct { + testsuite.E2ETestSuite } // QueryTransferParams queries the on-chain send enabled param for the transfer module -func (s *TransferTestSuite) QueryTransferParams(ctx context.Context, chain ibc.Chain) transfertypes.Params { +func (s *transferTester) QueryTransferParams(ctx context.Context, chain ibc.Chain) transfertypes.Params { res, err := query.GRPCQuery[transfertypes.QueryParamsResponse](ctx, chain, &transfertypes.QueryParamsRequest{}) s.Require().NoError(err) return *res.Params } +// CreateTransferPath sets up a path between chainA and chainB with a transfer channel and returns the relayer wired +// up to watch the channel and port IDs created. +func (s *transferTester) CreateTransferPath(testName string) (ibc.Relayer, ibc.ChannelOutput) { + relayer, channel := s.CreatePaths(ibc.DefaultClientOpts(), s.TransferChannelOptions(), testName), s.GetChainAChannelForTest(testName) + s.T().Logf("test %s running on portID %s channelID %s", testName, channel.PortID, channel.ChannelID) + return relayer, channel +} + // TestMsgTransfer_Succeeds_Nonincentivized will test sending successful IBC transfers from chainA to chainB. // The transfer will occur over a basic transfer channel (non incentivized) and both native and non-native tokens // will be sent forwards and backwards in the IBC transfer timeline (both chains will act as source and receiver chains). @@ -51,10 +57,17 @@ func (s *TransferTestSuite) TestMsgTransfer_Succeeds_Nonincentivized() { t := s.T() ctx := context.TODO() - relayer, channelA := s.GetRelayer(), s.GetChainAChannel() + testName := t.Name() + + // NOTE: t.Parallel() should be called before SetupPath in all tests. + // t.Name() must be stored in a variable before t.Parallel() otherwise t.Name() is not + // deterministic. + t.Parallel() + + relayer, channelA := s.CreateTransferPath(testName) chainA, chainB := s.GetChains() - chainAVersion := chainA.Config().Images[0].Version + chainBVersion := chainB.Config().Images[0].Version chainADenom := chainA.Config().Denom @@ -65,12 +78,13 @@ func (s *TransferTestSuite) TestMsgTransfer_Succeeds_Nonincentivized() { chainBAddress := chainBWallet.FormattedAddress() s.Require().NoError(test.WaitForBlocks(ctx, 1, chainA, chainB), "failed to wait for blocks") - t.Run("ensure capability module BeginBlock is executed", func(t *testing.T) { - // by restarting the chain we ensure that the capability module's BeginBlocker is executed. - s.Require().NoError(chainA.(*cosmos.CosmosChain).StopAllNodes(ctx)) - s.Require().NoError(chainA.(*cosmos.CosmosChain).StartAllNodes(ctx)) - s.Require().NoError(test.WaitForBlocks(ctx, 5, chainA), "failed to wait for blocks") - }) + // TODO: https://github.com/cosmos/ibc-go/issues/6743 + // t.Run("ensure capability module BeginBlock is executed", func(t *testing.T) { + // // by restarting the chain we ensure that the capability module's BeginBlocker is executed. + // s.Require().NoError(chainA.(*cosmos.CosmosChain).StopAllNodes(ctx)) + // s.Require().NoError(chainA.(*cosmos.CosmosChain).StartAllNodes(ctx)) + // s.Require().NoError(test.WaitForBlocks(ctx, 5, chainA), "failed to wait for blocks") + // }) t.Run("native IBC token transfer from chainA to chainB, sender is source of tokens", func(t *testing.T) { transferTxResp := s.Transfer(ctx, chainA, chainAWallet, channelA.PortID, channelA.ChannelID, testvalues.DefaultTransferCoins(chainADenom), chainAAddress, chainBAddress, s.GetTimeoutHeight(ctx, chainB), 0, "") @@ -84,17 +98,18 @@ func (s *TransferTestSuite) TestMsgTransfer_Succeeds_Nonincentivized() { expected := testvalues.StartingTokenAmount - testvalues.IBCTransferAmount s.Require().Equal(expected, actualBalance) - if testvalues.TotalEscrowFeatureReleases.IsSupported(chainAVersion) { - actualTotalEscrow, err := query.TotalEscrowForDenom(ctx, chainA, chainADenom) - s.Require().NoError(err) - - expectedTotalEscrow := sdk.NewCoin(chainADenom, sdkmath.NewInt(testvalues.IBCTransferAmount)) - s.Require().Equal(expectedTotalEscrow, actualTotalEscrow) - } + // TODO: cannot query total escrow if tests in parallel are using the same denom. + // if testvalues.TotalEscrowFeatureReleases.IsSupported(chainAVersion) { + // actualTotalEscrow, err := query.TotalEscrowForDenom(ctx, chainA, chainADenom) + // s.Require().NoError(err) + // + // expectedTotalEscrow := sdk.NewCoin(chainADenom, sdkmath.NewInt(testvalues.IBCTransferAmount)) + // s.Require().Equal(expectedTotalEscrow, actualTotalEscrow) + // } }) t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) + s.StartRelayer(relayer, testName) }) chainBIBCToken := testsuite.GetIBCToken(chainADenom, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID) @@ -126,11 +141,12 @@ func (s *TransferTestSuite) TestMsgTransfer_Succeeds_Nonincentivized() { s.Require().Equal(sdkmath.ZeroInt(), actualBalance) - if testvalues.TotalEscrowFeatureReleases.IsSupported(chainBVersion) { - actualTotalEscrow, err := query.TotalEscrowForDenom(ctx, chainB, chainBIBCToken.IBCDenom()) - s.Require().NoError(err) - s.Require().Equal(sdk.NewCoin(chainBIBCToken.IBCDenom(), sdkmath.NewInt(0)), actualTotalEscrow) // total escrow is zero because sending chain is not source for tokens - } + // https://github.com/cosmos/ibc-go/issues/6742 + // if testvalues.TotalEscrowFeatureReleases.IsSupported(chainBVersion) { + // actualTotalEscrow, err := query.TotalEscrowForDenom(ctx, chainB, chainBIBCToken.IBCDenom()) + // s.Require().NoError(err) + // s.Require().Equal(sdk.NewCoin(chainBIBCToken.IBCDenom(), sdkmath.NewInt(0)), actualTotalEscrow) // total escrow is zero because sending chain is not source for tokens + // } }) s.Require().NoError(test.WaitForBlocks(ctx, 5, chainA, chainB), "failed to wait for blocks") @@ -145,13 +161,14 @@ func (s *TransferTestSuite) TestMsgTransfer_Succeeds_Nonincentivized() { s.Require().Equal(expected, actualBalance) }) - if testvalues.TotalEscrowFeatureReleases.IsSupported(chainAVersion) { - t.Run("tokens are un-escrowed", func(t *testing.T) { - actualTotalEscrow, err := query.TotalEscrowForDenom(ctx, chainA, chainADenom) - s.Require().NoError(err) - s.Require().Equal(sdk.NewCoin(chainADenom, sdkmath.NewInt(0)), actualTotalEscrow) // total escrow is zero because tokens have come back - }) - } + // https://github.com/cosmos/ibc-go/issues/6742 + // if testvalues.TotalEscrowFeatureReleases.IsSupported(chainAVersion) { + // t.Run("tokens are un-escrowed", func(t *testing.T) { + // actualTotalEscrow, err := query.TotalEscrowForDenom(ctx, chainA, chainADenom) + // s.Require().NoError(err) + // s.Require().Equal(sdk.NewCoin(chainADenom, sdkmath.NewInt(0)), actualTotalEscrow) // total escrow is zero because tokens have come back + // }) + // } } // TestMsgTransfer_Succeeds_MultiDenom will test sending successful IBC transfers from chainA to chainB. @@ -160,7 +177,10 @@ func (s *TransferTestSuite) TestMsgTransfer_Succeeds_Nonincentivized_MultiDenom( t := s.T() ctx := context.TODO() - relayer, channelA := s.GetRelayer(), s.GetChainAChannel() + testName := t.Name() + t.Parallel() + relayer, channelA := s.CreateTransferPath(testName) + chainA, chainB := s.GetChains() chainADenom := chainA.Config().Denom @@ -189,15 +209,16 @@ func (s *TransferTestSuite) TestMsgTransfer_Succeeds_Nonincentivized_MultiDenom( expected := testvalues.StartingTokenAmount - testvalues.IBCTransferAmount s.Require().Equal(expected, actualBalance) - actualTotalEscrow, err := query.TotalEscrowForDenom(ctx, chainA, chainADenom) - s.Require().NoError(err) - - expectedTotalEscrow := sdk.NewCoin(chainADenom, sdkmath.NewInt(testvalues.IBCTransferAmount)) - s.Require().Equal(expectedTotalEscrow, actualTotalEscrow) + // https://github.com/cosmos/ibc-go/issues/6742 + // actualTotalEscrow, err := query.TotalEscrowForDenom(ctx, chainA, chainADenom) + // s.Require().NoError(err) + // + // expectedTotalEscrow := sdk.NewCoin(chainADenom, sdkmath.NewInt(testvalues.IBCTransferAmount)) + // s.Require().Equal(expectedTotalEscrow, actualTotalEscrow) }) t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) + s.StartRelayer(relayer, testName) }) t.Run("packets are relayed", func(t *testing.T) { @@ -247,11 +268,12 @@ func (s *TransferTestSuite) TestMsgTransfer_Succeeds_Nonincentivized_MultiDenom( }) }) - t.Run("native chainA tokens are un-escrowed", func(t *testing.T) { - actualTotalEscrow, err := query.TotalEscrowForDenom(ctx, chainA, chainADenom) - s.Require().NoError(err) - s.Require().Equal(sdk.NewCoin(chainADenom, sdkmath.NewInt(0)), actualTotalEscrow) // total escrow is zero because tokens have come back - }) + // https://github.com/cosmos/ibc-go/issues/6742 + // t.Run("native chainA tokens are un-escrowed", func(t *testing.T) { + // actualTotalEscrow, err := query.TotalEscrowForDenom(ctx, chainA, chainADenom) + // s.Require().NoError(err) + // s.Require().Equal(sdk.NewCoin(chainADenom, sdkmath.NewInt(0)), actualTotalEscrow) // total escrow is zero because tokens have come back + // }) } // TestMsgTransfer_Fails_InvalidAddress_MultiDenom attempts to send a multidenom IBC transfer @@ -260,7 +282,10 @@ func (s *TransferTestSuite) TestMsgTransfer_Fails_InvalidAddress_MultiDenom() { t := s.T() ctx := context.TODO() - relayer, channelA := s.GetRelayer(), s.GetChainAChannel() + testName := t.Name() + t.Parallel() + relayer, channelA := s.CreateTransferPath(testName) + chainA, chainB := s.GetChains() chainADenom := chainA.Config().Denom @@ -288,15 +313,16 @@ func (s *TransferTestSuite) TestMsgTransfer_Fails_InvalidAddress_MultiDenom() { expected := testvalues.StartingTokenAmount - testvalues.IBCTransferAmount s.Require().Equal(expected, actualBalance) - actualTotalEscrow, err := query.TotalEscrowForDenom(ctx, chainA, chainADenom) - s.Require().NoError(err) - - expectedTotalEscrow := sdk.NewCoin(chainADenom, sdkmath.NewInt(testvalues.IBCTransferAmount)) - s.Require().Equal(expectedTotalEscrow, actualTotalEscrow) + // https://github.com/cosmos/ibc-go/issues/6742 + // actualTotalEscrow, err := query.TotalEscrowForDenom(ctx, chainA, chainADenom) + // s.Require().NoError(err) + // + // expectedTotalEscrow := sdk.NewCoin(chainADenom, sdkmath.NewInt(testvalues.IBCTransferAmount)) + // s.Require().Equal(expectedTotalEscrow, actualTotalEscrow) }) t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) + s.StartRelayer(relayer, testName) }) t.Run("packets are relayed", func(t *testing.T) { @@ -347,7 +373,7 @@ func (s *TransferTestSuite) TestMsgTransfer_Fails_InvalidAddress_MultiDenom() { }) t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) + s.StartRelayer(relayer, testName) }) t.Run("packets are relayed", func(t *testing.T) { @@ -379,9 +405,12 @@ func (s *TransferTestSuite) TestMsgTransfer_Fails_InvalidAddress() { t := s.T() ctx := context.TODO() - relayer, channelA := s.GetRelayer(), s.GetChainAChannel() + testName := t.Name() + t.Parallel() + relayer, channelA := s.CreateTransferPath(testName) chainA, chainB := s.GetChains() + chainADenom := chainA.Config().Denom chainAWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) @@ -403,7 +432,7 @@ func (s *TransferTestSuite) TestMsgTransfer_Fails_InvalidAddress() { }) t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) + s.StartRelayer(relayer, testName) }) t.Run("packets are relayed", func(t *testing.T) { @@ -423,7 +452,10 @@ func (s *TransferTestSuite) TestMsgTransfer_Timeout_Nonincentivized() { t := s.T() ctx := context.TODO() - relayer, channelA := s.GetRelayer(), s.GetChainAChannel() + testName := t.Name() + t.Parallel() + relayer, channelA := s.CreateTransferPath(testName) + chainA, _ := s.GetChains() chainAWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) @@ -451,7 +483,7 @@ func (s *TransferTestSuite) TestMsgTransfer_Timeout_Nonincentivized() { }) t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) + s.StartRelayer(relayer, testName) }) t.Run("ensure escrowed tokens have been refunded to sender due to timeout", func(t *testing.T) { @@ -467,180 +499,6 @@ func (s *TransferTestSuite) TestMsgTransfer_Timeout_Nonincentivized() { }) } -// TestSendEnabledParam tests changing ics20 SendEnabled parameter -func (s *TransferTestSuite) TestSendEnabledParam() { - t := s.T() - ctx := context.TODO() - - channelA := s.GetChainAChannel() - - chainA, chainB := s.GetChains() - chainAVersion := chainA.Config().Images[0].Version - chainADenom := chainA.Config().Denom - - chainAWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) - chainAAddress := chainAWallet.FormattedAddress() - - chainBWallet := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) - chainBAddress := chainBWallet.FormattedAddress() - - isSelfManagingParams := testvalues.SelfParamsFeatureReleases.IsSupported(chainAVersion) - - govModuleAddress, err := query.ModuleAccountAddress(ctx, govtypes.ModuleName, chainA) - s.Require().NoError(err) - s.Require().NotNil(govModuleAddress) - - s.Require().NoError(test.WaitForBlocks(ctx, 1, chainA, chainB), "failed to wait for blocks") - - t.Run("ensure transfer sending is enabled", func(t *testing.T) { - enabled := s.QueryTransferParams(ctx, chainA).SendEnabled - s.Require().True(enabled) - }) - - t.Run("ensure packets can be sent", func(t *testing.T) { - transferTxResp := s.Transfer(ctx, chainA, chainAWallet, channelA.PortID, channelA.ChannelID, testvalues.DefaultTransferCoins(chainADenom), chainAAddress, chainBAddress, s.GetTimeoutHeight(ctx, chainB), 0, "") - s.AssertTxSuccess(transferTxResp) - }) - - t.Run("change send enabled parameter to disabled", func(t *testing.T) { - if isSelfManagingParams { - msg := transfertypes.NewMsgUpdateParams(govModuleAddress.String(), transfertypes.NewParams(false, true)) - s.ExecuteAndPassGovV1Proposal(ctx, msg, chainA, chainAWallet) - } else { - changes := []paramsproposaltypes.ParamChange{ - paramsproposaltypes.NewParamChange(transfertypes.StoreKey, string(transfertypes.KeySendEnabled), "false"), - } - - proposal := paramsproposaltypes.NewParameterChangeProposal(ibctesting.Title, ibctesting.Description, changes) - s.ExecuteAndPassGovV1Beta1Proposal(ctx, chainA, chainAWallet, proposal) - } - }) - - t.Run("ensure transfer params are disabled", func(t *testing.T) { - enabled := s.QueryTransferParams(ctx, chainA).SendEnabled - s.Require().False(enabled) - }) - - t.Run("ensure ics20 transfer fails", func(t *testing.T) { - transferTxResp := s.Transfer(ctx, chainA, chainAWallet, channelA.PortID, channelA.ChannelID, testvalues.DefaultTransferCoins(chainADenom), chainAAddress, chainBAddress, s.GetTimeoutHeight(ctx, chainB), 0, "") - s.AssertTxFailure(transferTxResp, transfertypes.ErrSendDisabled) - }) -} - -// TestReceiveEnabledParam tests changing ics20 ReceiveEnabled parameter -func (s *TransferTestSuite) TestReceiveEnabledParam() { - t := s.T() - ctx := context.TODO() - - relayer, channelA := s.GetRelayer(), s.GetChainAChannel() - - chainA, chainB := s.GetChains() - chainAVersion := chainA.Config().Images[0].Version - - chainAWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) - chainBWallet := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) - - var ( - chainBDenom = chainB.Config().Denom - chainAIBCToken = testsuite.GetIBCToken(chainBDenom, channelA.PortID, channelA.ChannelID) // IBC token sent to chainA - - chainAAddress = chainAWallet.FormattedAddress() - chainBAddress = chainBWallet.FormattedAddress() - ) - - isSelfManagingParams := testvalues.SelfParamsFeatureReleases.IsSupported(chainAVersion) - - govModuleAddress, err := query.ModuleAccountAddress(ctx, govtypes.ModuleName, chainA) - s.Require().NoError(err) - s.Require().NotNil(govModuleAddress) - - s.Require().NoError(test.WaitForBlocks(ctx, 1, chainA, chainB), "failed to wait for blocks") - - t.Run("ensure transfer receive is enabled", func(t *testing.T) { - enabled := s.QueryTransferParams(ctx, chainA).ReceiveEnabled - s.Require().True(enabled) - }) - - t.Run("ensure packets can be received, send from chainB to chainA", func(t *testing.T) { - t.Run("send from chainB to chainA", func(t *testing.T) { - transferTxResp := s.Transfer(ctx, chainB, chainBWallet, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID, testvalues.DefaultTransferCoins(chainBDenom), chainBAddress, chainAAddress, s.GetTimeoutHeight(ctx, chainA), 0, "") - s.AssertTxSuccess(transferTxResp) - }) - - t.Run("tokens are escrowed", func(t *testing.T) { - actualBalance, err := s.GetChainBNativeBalance(ctx, chainBWallet) - s.Require().NoError(err) - - expected := testvalues.StartingTokenAmount - testvalues.IBCTransferAmount - s.Require().Equal(expected, actualBalance) - }) - - t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) - }) - - t.Run("packets are relayed", func(t *testing.T) { - s.AssertPacketRelayed(ctx, chainA, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID, 1) - actualBalance, err := query.Balance(ctx, chainA, chainAAddress, chainAIBCToken.IBCDenom()) - - s.Require().NoError(err) - - expected := testvalues.IBCTransferAmount - s.Require().Equal(expected, actualBalance.Int64()) - }) - - t.Run("stop relayer", func(t *testing.T) { - s.StopRelayer(ctx, relayer) - }) - }) - - t.Run("change receive enabled parameter to disabled ", func(t *testing.T) { - if isSelfManagingParams { - msg := transfertypes.NewMsgUpdateParams(govModuleAddress.String(), transfertypes.NewParams(false, false)) - s.ExecuteAndPassGovV1Proposal(ctx, msg, chainA, chainAWallet) - } else { - changes := []paramsproposaltypes.ParamChange{ - paramsproposaltypes.NewParamChange(transfertypes.StoreKey, string(transfertypes.KeyReceiveEnabled), "false"), - } - - proposal := paramsproposaltypes.NewParameterChangeProposal(ibctesting.Title, ibctesting.Description, changes) - s.ExecuteAndPassGovV1Beta1Proposal(ctx, chainA, chainAWallet, proposal) - } - }) - - t.Run("ensure transfer params are disabled", func(t *testing.T) { - enabled := s.QueryTransferParams(ctx, chainA).ReceiveEnabled - s.Require().False(enabled) - }) - - t.Run("ensure ics20 transfer fails", func(t *testing.T) { - t.Run("send from chainB to chainA", func(t *testing.T) { - transferTxResp := s.Transfer(ctx, chainB, chainBWallet, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID, testvalues.DefaultTransferCoins(chainBDenom), chainBAddress, chainAAddress, s.GetTimeoutHeight(ctx, chainA), 0, "") - s.AssertTxSuccess(transferTxResp) - }) - - t.Run("tokens are escrowed", func(t *testing.T) { - actualBalance, err := s.GetChainBNativeBalance(ctx, chainBWallet) - s.Require().NoError(err) - - expected := testvalues.StartingTokenAmount - (testvalues.IBCTransferAmount * 2) // second send - s.Require().Equal(expected, actualBalance) - }) - - t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) - }) - - t.Run("tokens are unescrowed in failed acknowledgement", func(t *testing.T) { - actualBalance, err := s.GetChainBNativeBalance(ctx, chainBWallet) - s.Require().NoError(err) - - expected := testvalues.StartingTokenAmount - testvalues.IBCTransferAmount // only first send marked - s.Require().Equal(expected, actualBalance) - }) - }) -} - // This can be used to test sending with a transfer packet with a memo given different combinations of // ibc-go versions. // @@ -652,9 +510,12 @@ func (s *TransferTestSuite) TestMsgTransfer_WithMemo() { t := s.T() ctx := context.TODO() - relayer, channelA := s.GetRelayer(), s.GetChainAChannel() + testName := t.Name() + t.Parallel() + relayer, channelA := s.CreateTransferPath(testName) chainA, chainB := s.GetChains() + chainADenom := chainA.Config().Denom chainAWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) @@ -679,7 +540,7 @@ func (s *TransferTestSuite) TestMsgTransfer_WithMemo() { }) t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) + s.StartRelayer(relayer, testName) }) chainBIBCToken := testsuite.GetIBCToken(chainADenom, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID) diff --git a/e2e/tests/transfer/forwarding_test.go b/e2e/tests/transfer/forwarding_test.go index ed1e07ec958..bbd46865e2b 100644 --- a/e2e/tests/transfer/forwarding_test.go +++ b/e2e/tests/transfer/forwarding_test.go @@ -46,19 +46,28 @@ func (s *TransferForwardingTestSuite) testForwardingThreeChains(lastChainVersion ctx := context.TODO() t := s.T() - relayer, chains := s.GetRelayer(), s.GetAllChains() + testName := t.Name() + t.Parallel() + relayer := s.CreateDefaultPaths(testName) + + chains := s.GetAllChains() chainA, chainB, chainC := chains[0], chains[1], chains[2] + s.Require().Len(s.GetChannelsForTest(chainA, testName), 1, "expected one channel on chain A") + s.Require().Len(s.GetChannelsForTest(chainB, testName), 2, "expected two channels on chain B") + s.Require().Len(s.GetChannelsForTest(chainC, testName), 1, "expected one channel on chain C") + + channelAtoB := s.GetChainAChannelForTest(testName) + var channelBtoC ibc.ChannelOutput - channelAtoB := s.GetChainAChannel() if lastChainVersion == transfertypes.V2 { - channelBtoC = s.GetChainChannel(testsuite.ChainChannelPair{ChainIdx: 1, ChannelIdx: 1}) + channelBtoC = s.GetChannelsForTest(chainB, testName)[1] + s.Require().Equal(transfertypes.V2, channelBtoC.Version, "the channel version is not ics20-2") } else { opts := s.TransferChannelOptions() opts.Version = transfertypes.V1 - chains := s.GetAllChains() - channelBtoC, _ = s.CreatePath(ctx, chains[1], chains[2], ibc.DefaultClientOpts(), opts) + channelBtoC, _ = s.CreatePath(ctx, relayer, chainB, chainC, ibc.DefaultClientOpts(), opts, testName) s.Require().Equal(transfertypes.V1, channelBtoC.Version, "the channel version is not ics20-1") } @@ -89,7 +98,7 @@ func (s *TransferForwardingTestSuite) testForwardingThreeChains(lastChainVersion }) t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) + s.StartRelayer(relayer, testName) }) t.Run("packets are relayed from A to B to C", func(t *testing.T) { diff --git a/e2e/tests/transfer/incentivized_test.go b/e2e/tests/transfer/incentivized_test.go index 7b42a6b509d..0f0fb050726 100644 --- a/e2e/tests/transfer/incentivized_test.go +++ b/e2e/tests/transfer/incentivized_test.go @@ -36,16 +36,19 @@ func TestIncentivizedTransferTestSuite(t *testing.T) { testifysuite.Run(t, new(IncentivizedTransferTestSuite)) } -// SetupTest explicitly enables fee middleware in the channel options. -func (s *IncentivizedTransferTestSuite) SetupTest() { - s.SetupPaths(ibc.DefaultClientOpts(), s.FeeTransferChannelOptions()) +// CreateTransferFeePath explicitly enables fee middleware in the channel options. +func (s *IncentivizedTransferTestSuite) CreateTransferFeePath(testName string) (ibc.Relayer, ibc.ChannelOutput) { + return s.CreatePaths(ibc.DefaultClientOpts(), s.FeeTransferChannelOptions(), testName), s.GetChainAChannelForTest(testName) } func (s *IncentivizedTransferTestSuite) TestMsgPayPacketFee_AsyncSingleSender_Succeeds() { t := s.T() ctx := context.TODO() - relayer, channelA := s.GetRelayer(), s.GetChainAChannel() + testName := t.Name() + + relayer, channelA := s.CreateTransferFeePath(testName) + chainA, chainB := s.GetChains() chainAVersion := chainA.Config().Images[0].Version @@ -140,7 +143,7 @@ func (s *IncentivizedTransferTestSuite) TestMsgPayPacketFee_AsyncSingleSender_Su }) t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) + s.StartRelayer(relayer, testName) }) t.Run("packets are relayed", func(t *testing.T) { @@ -163,7 +166,9 @@ func (s *IncentivizedTransferTestSuite) TestMsgPayPacketFee_InvalidReceiverAccou t := s.T() ctx := context.TODO() - relayer, channelA := s.GetRelayer(), s.GetChainAChannel() + testName := t.Name() + relayer, channelA := s.CreateTransferFeePath(testName) + chainA, chainB := s.GetChains() chainAVersion := chainA.Config().Images[0].Version @@ -268,7 +273,7 @@ func (s *IncentivizedTransferTestSuite) TestMsgPayPacketFee_InvalidReceiverAccou }) t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) + s.StartRelayer(relayer, testName) }) t.Run("packets are relayed", func(t *testing.T) { @@ -291,7 +296,9 @@ func (s *IncentivizedTransferTestSuite) TestMultiMsg_MsgPayPacketFeeSingleSender t := s.T() ctx := context.TODO() - relayer, channelA := s.GetRelayer(), s.GetChainAChannel() + testName := t.Name() + relayer, channelA := s.CreateTransferFeePath(testName) + chainA, chainB := s.GetChains() chainAVersion := chainA.Config().Images[0].Version @@ -381,7 +388,7 @@ func (s *IncentivizedTransferTestSuite) TestMultiMsg_MsgPayPacketFeeSingleSender }) t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) + s.StartRelayer(relayer, testName) }) t.Run("packets are relayed", func(t *testing.T) { @@ -411,7 +418,9 @@ func (s *IncentivizedTransferTestSuite) TestMsgPayPacketFee_SingleSender_TimesOu t := s.T() ctx := context.TODO() - relayer, channelA := s.GetRelayer(), s.GetChainAChannel() + testName := t.Name() + relayer, channelA := s.CreateTransferFeePath(testName) + chainA, chainB := s.GetChains() chainAVersion := chainA.Config().Images[0].Version @@ -505,7 +514,7 @@ func (s *IncentivizedTransferTestSuite) TestMsgPayPacketFee_SingleSender_TimesOu }) t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) + s.StartRelayer(relayer, testName) }) t.Run("packets are relayed", func(t *testing.T) { @@ -527,7 +536,9 @@ func (s *IncentivizedTransferTestSuite) TestPayPacketFeeAsync_SingleSender_NoCou t := s.T() ctx := context.TODO() - relayer, channelA := s.GetRelayer(), s.GetChainAChannel() + testName := t.Name() + relayer, channelA := s.CreateTransferFeePath(testName) + chainA, _ := s.GetChains() chainAVersion := chainA.Config().Images[0].Version @@ -603,7 +614,7 @@ func (s *IncentivizedTransferTestSuite) TestPayPacketFeeAsync_SingleSender_NoCou }) t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) + s.StartRelayer(relayer, testName) }) t.Run("with no counterparty address", func(t *testing.T) { @@ -628,7 +639,9 @@ func (s *IncentivizedTransferTestSuite) TestMsgPayPacketFee_AsyncMultipleSenders t := s.T() ctx := context.TODO() - relayer, channelA := s.GetRelayer(), s.GetChainAChannel() + testName := t.Name() + relayer, channelA := s.CreateTransferFeePath(testName) + chainA, chainB := s.GetChains() chainAVersion := chainA.Config().Images[0].Version @@ -749,7 +762,7 @@ func (s *IncentivizedTransferTestSuite) TestMsgPayPacketFee_AsyncMultipleSenders }) t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) + s.StartRelayer(relayer, testName) }) t.Run("packets are relayed", func(t *testing.T) { diff --git a/e2e/tests/transfer/localhost_test.go b/e2e/tests/transfer/localhost_test.go index 982f05a6b68..81027b3dfd9 100644 --- a/e2e/tests/transfer/localhost_test.go +++ b/e2e/tests/transfer/localhost_test.go @@ -35,9 +35,10 @@ func (s *LocalhostTransferTestSuite) TestMsgTransfer_Localhost() { t := s.T() ctx := context.TODO() - channelA := s.GetChainAChannel() - chainA, _ := s.GetChains() + + channelVersion := transfertypes.V2 + chainADenom := chainA.Config().Denom rlyWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) @@ -55,7 +56,7 @@ func (s *LocalhostTransferTestSuite) TestMsgTransfer_Localhost() { t.Run("channel open init localhost", func(t *testing.T) { msgChanOpenInit := channeltypes.NewMsgChannelOpenInit( - transfertypes.PortID, channelA.Version, + transfertypes.PortID, channelVersion, channeltypes.UNORDERED, []string{exported.LocalhostConnectionID}, transfertypes.PortID, rlyWallet.FormattedAddress(), ) @@ -70,10 +71,10 @@ func (s *LocalhostTransferTestSuite) TestMsgTransfer_Localhost() { t.Run("channel open try localhost", func(t *testing.T) { msgChanOpenTry := channeltypes.NewMsgChannelOpenTry( - transfertypes.PortID, channelA.Version, + transfertypes.PortID, channelVersion, channeltypes.UNORDERED, []string{exported.LocalhostConnectionID}, transfertypes.PortID, msgChanOpenInitRes.ChannelId, - channelA.Version, localhost.SentinelProof, clienttypes.ZeroHeight(), rlyWallet.FormattedAddress(), + channelVersion, localhost.SentinelProof, clienttypes.ZeroHeight(), rlyWallet.FormattedAddress(), ) txResp := s.BroadcastMessages(ctx, chainA, rlyWallet, msgChanOpenTry) @@ -85,7 +86,7 @@ func (s *LocalhostTransferTestSuite) TestMsgTransfer_Localhost() { t.Run("channel open ack localhost", func(t *testing.T) { msgChanOpenAck := channeltypes.NewMsgChannelOpenAck( transfertypes.PortID, msgChanOpenInitRes.ChannelId, - msgChanOpenTryRes.ChannelId, channelA.Version, + msgChanOpenTryRes.ChannelId, channelVersion, localhost.SentinelProof, clienttypes.ZeroHeight(), rlyWallet.FormattedAddress(), ) @@ -117,7 +118,7 @@ func (s *LocalhostTransferTestSuite) TestMsgTransfer_Localhost() { t.Run("send packet localhost ibc transfer", func(t *testing.T) { var err error - txResp := s.Transfer(ctx, chainA, userAWallet, transfertypes.PortID, msgChanOpenInitRes.ChannelId, testvalues.DefaultTransferCoins(chainADenom), userAWallet.FormattedAddress(), userBWallet.FormattedAddress(), clienttypes.NewHeight(1, 100), 0, "") + txResp := s.Transfer(ctx, chainA, userAWallet, transfertypes.PortID, msgChanOpenInitRes.ChannelId, testvalues.DefaultTransferCoins(chainADenom), userAWallet.FormattedAddress(), userBWallet.FormattedAddress(), clienttypes.NewHeight(1, 500), 0, "") s.AssertTxSuccess(txResp) packet, err = ibctesting.ParsePacketFromEvents(txResp.Events) diff --git a/e2e/tests/transfer/send_enabled_test.go b/e2e/tests/transfer/send_enabled_test.go new file mode 100644 index 00000000000..dcc8d17de03 --- /dev/null +++ b/e2e/tests/transfer/send_enabled_test.go @@ -0,0 +1,98 @@ +//go:build !test_e2e + +package transfer + +import ( + "context" + "testing" + + test "github.com/strangelove-ventures/interchaintest/v8/testutil" + testifysuite "github.com/stretchr/testify/suite" + + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + paramsproposaltypes "github.com/cosmos/cosmos-sdk/x/params/types/proposal" + + "github.com/cosmos/ibc-go/e2e/testsuite" + "github.com/cosmos/ibc-go/e2e/testsuite/query" + "github.com/cosmos/ibc-go/e2e/testvalues" + transfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" + ibctesting "github.com/cosmos/ibc-go/v8/testing" +) + +func TestTransferTestSuiteSendEnabled(t *testing.T) { + testifysuite.Run(t, new(TransferTestSuiteSendEnabled)) +} + +type TransferTestSuiteSendEnabled struct { + transferTester +} + +func (s *TransferTestSuiteSendEnabled) SetupSuite() { + s.SetupChains(context.TODO(), nil, func(options *testsuite.ChainOptions) { + options.RelayerCount = 1 + }) +} + +// TestSendEnabledParam tests changing ics20 SendEnabled parameter +func (s *TransferTestSuiteSendEnabled) TestSendEnabledParam() { + t := s.T() + ctx := context.TODO() + + testName := t.Name() + // Note: explicitly not using t.Parallel() in this test as it makes chain wide changes + s.CreateTransferPath(testName) + + chainA, chainB := s.GetChains() + + channelA := s.GetChainAChannelForTest(testName) + chainAVersion := chainA.Config().Images[0].Version + chainADenom := chainA.Config().Denom + + chainAWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + chainAAddress := chainAWallet.FormattedAddress() + + chainBWallet := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) + chainBAddress := chainBWallet.FormattedAddress() + + isSelfManagingParams := testvalues.SelfParamsFeatureReleases.IsSupported(chainAVersion) + + govModuleAddress, err := query.ModuleAccountAddress(ctx, govtypes.ModuleName, chainA) + s.Require().NoError(err) + s.Require().NotNil(govModuleAddress) + + s.Require().NoError(test.WaitForBlocks(ctx, 1, chainA, chainB), "failed to wait for blocks") + + t.Run("ensure transfer sending is enabled", func(t *testing.T) { + enabled := s.QueryTransferParams(ctx, chainA).SendEnabled + s.Require().True(enabled) + }) + + t.Run("ensure packets can be sent", func(t *testing.T) { + transferTxResp := s.Transfer(ctx, chainA, chainAWallet, channelA.PortID, channelA.ChannelID, testvalues.DefaultTransferCoins(chainADenom), chainAAddress, chainBAddress, s.GetTimeoutHeight(ctx, chainB), 0, "") + s.AssertTxSuccess(transferTxResp) + }) + + t.Run("change send enabled parameter to disabled", func(t *testing.T) { + if isSelfManagingParams { + msg := transfertypes.NewMsgUpdateParams(govModuleAddress.String(), transfertypes.NewParams(false, true)) + s.ExecuteAndPassGovV1Proposal(ctx, msg, chainA, chainAWallet) + } else { + changes := []paramsproposaltypes.ParamChange{ + paramsproposaltypes.NewParamChange(transfertypes.StoreKey, string(transfertypes.KeySendEnabled), "false"), + } + + proposal := paramsproposaltypes.NewParameterChangeProposal(ibctesting.Title, ibctesting.Description, changes) + s.ExecuteAndPassGovV1Beta1Proposal(ctx, chainA, chainAWallet, proposal) + } + }) + + t.Run("ensure transfer params are disabled", func(t *testing.T) { + enabled := s.QueryTransferParams(ctx, chainA).SendEnabled + s.Require().False(enabled) + }) + + t.Run("ensure ics20 transfer fails", func(t *testing.T) { + transferTxResp := s.Transfer(ctx, chainA, chainAWallet, channelA.PortID, channelA.ChannelID, testvalues.DefaultTransferCoins(chainADenom), chainAAddress, chainBAddress, s.GetTimeoutHeight(ctx, chainB), 0, "") + s.AssertTxFailure(transferTxResp, transfertypes.ErrSendDisabled) + }) +} diff --git a/e2e/tests/transfer/send_receive_test.go b/e2e/tests/transfer/send_receive_test.go new file mode 100644 index 00000000000..98efb227337 --- /dev/null +++ b/e2e/tests/transfer/send_receive_test.go @@ -0,0 +1,154 @@ +//go:build !test_e2e + +package transfer + +import ( + "context" + "testing" + + test "github.com/strangelove-ventures/interchaintest/v8/testutil" + testifysuite "github.com/stretchr/testify/suite" + + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + paramsproposaltypes "github.com/cosmos/cosmos-sdk/x/params/types/proposal" + + "github.com/cosmos/ibc-go/e2e/testsuite" + "github.com/cosmos/ibc-go/e2e/testsuite/query" + "github.com/cosmos/ibc-go/e2e/testvalues" + transfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" + ibctesting "github.com/cosmos/ibc-go/v8/testing" +) + +func TestTransferTestSuiteSendReceive(t *testing.T) { + testifysuite.Run(t, new(TransferTestSuiteSendReceive)) +} + +type TransferTestSuiteSendReceive struct { + transferTester +} + +func (s *TransferTestSuiteSendReceive) SetupSuite() { + s.SetupChains(context.TODO(), nil, func(options *testsuite.ChainOptions) { + options.RelayerCount = 1 + }) +} + +// TestReceiveEnabledParam tests changing ics20 ReceiveEnabled parameter +func (s *TransferTestSuiteSendReceive) TestReceiveEnabledParam() { + t := s.T() + ctx := context.TODO() + + testName := t.Name() + // Note: explicitly not using t.Parallel() in this test as it makes chain wide changes + s.CreateTransferPath(testName) + + chainA, chainB := s.GetChains() + + relayer := s.GetRelayerForTest(testName) + channelA := s.GetChainAChannelForTest(testName) + + chainAVersion := chainA.Config().Images[0].Version + + chainAWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + chainBWallet := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) + + var ( + chainBDenom = chainB.Config().Denom + chainAIBCToken = testsuite.GetIBCToken(chainBDenom, channelA.PortID, channelA.ChannelID) // IBC token sent to chainA + + chainAAddress = chainAWallet.FormattedAddress() + chainBAddress = chainBWallet.FormattedAddress() + ) + + isSelfManagingParams := testvalues.SelfParamsFeatureReleases.IsSupported(chainAVersion) + + govModuleAddress, err := query.ModuleAccountAddress(ctx, govtypes.ModuleName, chainA) + s.Require().NoError(err) + s.Require().NotNil(govModuleAddress) + + s.Require().NoError(test.WaitForBlocks(ctx, 1, chainA, chainB), "failed to wait for blocks") + + t.Run("ensure transfer receive is enabled", func(t *testing.T) { + enabled := s.QueryTransferParams(ctx, chainA).ReceiveEnabled + s.Require().True(enabled) + }) + + t.Run("ensure packets can be received, send from chainB to chainA", func(t *testing.T) { + t.Run("send from chainB to chainA", func(t *testing.T) { + transferTxResp := s.Transfer(ctx, chainB, chainBWallet, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID, testvalues.DefaultTransferCoins(chainBDenom), chainBAddress, chainAAddress, s.GetTimeoutHeight(ctx, chainA), 0, "") + s.AssertTxSuccess(transferTxResp) + }) + + t.Run("tokens are escrowed", func(t *testing.T) { + actualBalance, err := s.GetChainBNativeBalance(ctx, chainBWallet) + s.Require().NoError(err) + + expected := testvalues.StartingTokenAmount - testvalues.IBCTransferAmount + s.Require().Equal(expected, actualBalance) + }) + + t.Run("start relayer", func(t *testing.T) { + s.StartRelayer(relayer, testName) + }) + + t.Run("packets are relayed", func(t *testing.T) { + s.AssertPacketRelayed(ctx, chainA, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID, 1) + actualBalance, err := query.Balance(ctx, chainA, chainAAddress, chainAIBCToken.IBCDenom()) + + s.Require().NoError(err) + + expected := testvalues.IBCTransferAmount + s.Require().Equal(expected, actualBalance.Int64()) + }) + + t.Run("stop relayer", func(t *testing.T) { + s.StopRelayer(ctx, relayer) + }) + }) + + t.Run("change receive enabled parameter to disabled ", func(t *testing.T) { + if isSelfManagingParams { + msg := transfertypes.NewMsgUpdateParams(govModuleAddress.String(), transfertypes.NewParams(false, false)) + s.ExecuteAndPassGovV1Proposal(ctx, msg, chainA, chainAWallet) + } else { + changes := []paramsproposaltypes.ParamChange{ + paramsproposaltypes.NewParamChange(transfertypes.StoreKey, string(transfertypes.KeyReceiveEnabled), "false"), + } + + proposal := paramsproposaltypes.NewParameterChangeProposal(ibctesting.Title, ibctesting.Description, changes) + s.ExecuteAndPassGovV1Beta1Proposal(ctx, chainA, chainAWallet, proposal) + } + }) + + t.Run("ensure transfer params are disabled", func(t *testing.T) { + enabled := s.QueryTransferParams(ctx, chainA).ReceiveEnabled + s.Require().False(enabled) + }) + + t.Run("ensure ics20 transfer fails", func(t *testing.T) { + t.Run("send from chainB to chainA", func(t *testing.T) { + transferTxResp := s.Transfer(ctx, chainB, chainBWallet, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID, testvalues.DefaultTransferCoins(chainBDenom), chainBAddress, chainAAddress, s.GetTimeoutHeight(ctx, chainA), 0, "") + s.AssertTxSuccess(transferTxResp) + }) + + t.Run("tokens are escrowed", func(t *testing.T) { + actualBalance, err := s.GetChainBNativeBalance(ctx, chainBWallet) + s.Require().NoError(err) + + expected := testvalues.StartingTokenAmount - (testvalues.IBCTransferAmount * 2) // second send + s.Require().Equal(expected, actualBalance) + }) + + t.Run("start relayer", func(t *testing.T) { + s.StartRelayer(relayer, testName) + }) + + t.Run("tokens are unescrowed in failed acknowledgement", func(t *testing.T) { + actualBalance, err := s.GetChainBNativeBalance(ctx, chainBWallet) + s.Require().NoError(err) + + expected := testvalues.StartingTokenAmount - testvalues.IBCTransferAmount // only first send marked + s.Require().Equal(expected, actualBalance) + }) + }) +} diff --git a/e2e/tests/transfer/upgradesv1_test.go b/e2e/tests/transfer/upgradesv1_test.go index 0227031d62f..e2b61a64a10 100644 --- a/e2e/tests/transfer/upgradesv1_test.go +++ b/e2e/tests/transfer/upgradesv1_test.go @@ -30,10 +30,10 @@ type TransferChannelUpgradesV1TestSuite struct { testsuite.E2ETestSuite } -func (s *TransferChannelUpgradesV1TestSuite) SetupTest() { +func (s *TransferChannelUpgradesV1TestSuite) SetupChannelUpgradesV1Test(testName string) { opts := s.TransferChannelOptions() opts.Version = transfertypes.V1 - s.SetupPaths(ibc.DefaultClientOpts(), opts) + s.CreatePaths(ibc.DefaultClientOpts(), opts, testName) } // TestChannelUpgrade_WithICS20v2_Succeeds tests upgrading a transfer channel to ICS20 v2. @@ -41,7 +41,10 @@ func (s *TransferChannelUpgradesV1TestSuite) TestChannelUpgrade_WithICS20v2_Succ t := s.T() ctx := context.TODO() - relayer, channelA := s.GetRelayer(), s.GetChainAChannel() + testName := t.Name() + s.SetupChannelUpgradesV1Test(testName) + + relayer, channelA := s.GetRelayerForTest(testName), s.GetChainAChannelForTest(testName) channelB := channelA.Counterparty chainA, chainB := s.GetChains() @@ -94,7 +97,7 @@ func (s *TransferChannelUpgradesV1TestSuite) TestChannelUpgrade_WithICS20v2_Succ }) t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) + s.StartRelayer(relayer, testName) }) t.Run("packets are relayed", func(t *testing.T) { @@ -182,7 +185,10 @@ func (s *TransferChannelUpgradesV1TestSuite) TestChannelUpgrade_WithFeeMiddlewar t := s.T() ctx := context.TODO() - relayer, channelA := s.GetRelayer(), s.GetChainAChannel() + testName := t.Name() + s.SetupChannelUpgradesV1Test(testName) + + relayer, channelA := s.GetRelayerForTest(testName), s.GetChainAChannelForTest(testName) channelB := channelA.Counterparty chainA, chainB := s.GetChains() @@ -222,7 +228,7 @@ func (s *TransferChannelUpgradesV1TestSuite) TestChannelUpgrade_WithFeeMiddlewar }) t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) + s.StartRelayer(relayer, testName) }) t.Run("execute gov proposal to initiate channel upgrade", func(t *testing.T) { diff --git a/e2e/tests/transfer/upgradesv2_test.go b/e2e/tests/transfer/upgradesv2_test.go index 88854f7deac..8941c783b03 100644 --- a/e2e/tests/transfer/upgradesv2_test.go +++ b/e2e/tests/transfer/upgradesv2_test.go @@ -31,8 +31,8 @@ type TransferChannelUpgradesTestSuite struct { testsuite.E2ETestSuite } -func (s *TransferChannelUpgradesTestSuite) SetupTest() { - s.SetupPaths(ibc.DefaultClientOpts(), s.TransferChannelOptions()) +func (s *TransferChannelUpgradesTestSuite) SetupChannelUpgradesPath(testName string) { + s.CreatePaths(ibc.DefaultClientOpts(), s.TransferChannelOptions(), testName) } // TestChannelUpgrade_WithFeeMiddleware_Succeeds tests upgrading a transfer channel to wire up fee middleware @@ -40,7 +40,10 @@ func (s *TransferChannelUpgradesTestSuite) TestChannelUpgrade_WithFeeMiddleware_ t := s.T() ctx := context.TODO() - relayer, channelA := s.GetRelayer(), s.GetChainAChannel() + testName := t.Name() + s.SetupChannelUpgradesPath(testName) + + relayer, channelA := s.GetRelayerForTest(testName), s.GetChainAChannelForTest(testName) channelB := channelA.Counterparty @@ -95,7 +98,7 @@ func (s *TransferChannelUpgradesTestSuite) TestChannelUpgrade_WithFeeMiddleware_ }) t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) + s.StartRelayer(relayer, testName) }) s.Require().NoError(test.WaitForBlocks(ctx, 10, chainA, chainB), "failed to wait for blocks") @@ -191,7 +194,7 @@ func (s *TransferChannelUpgradesTestSuite) TestChannelUpgrade_WithFeeMiddleware_ }) t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) + s.StartRelayer(relayer, testName) }) t.Run("send incentivized transfer packet", func(t *testing.T) { @@ -258,7 +261,10 @@ func (s *TransferChannelUpgradesTestSuite) TestChannelDowngrade_WithICS20v1_Succ t := s.T() ctx := context.TODO() - relayer, channelA := s.GetRelayer(), s.GetChainAChannel() + testName := t.Name() + s.SetupChannelUpgradesPath(testName) + + relayer, channelA := s.GetRelayerForTest(testName), s.GetChainAChannelForTest(testName) channelB := channelA.Counterparty chainA, chainB := s.GetChains() @@ -284,7 +290,7 @@ func (s *TransferChannelUpgradesTestSuite) TestChannelDowngrade_WithICS20v1_Succ }) t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) + s.StartRelayer(relayer, testName) }) t.Run("execute gov proposal to initiate channel upgrade", func(t *testing.T) { @@ -350,7 +356,10 @@ func (s *TransferChannelUpgradesTestSuite) TestChannelUpgrade_WithFeeMiddleware_ t := s.T() ctx := context.TODO() - relayer, channelA := s.GetRelayer(), s.GetChainAChannel() + testName := t.Name() + s.SetupChannelUpgradesPath(testName) + + relayer, channelA := s.GetRelayerForTest(testName), s.GetChainAChannelForTest(testName) channelB := channelA.Counterparty @@ -396,7 +405,7 @@ func (s *TransferChannelUpgradesTestSuite) TestChannelUpgrade_WithFeeMiddleware_ s.Require().NoError(test.WaitForBlocks(ctx, 10, chainA, chainB), "failed to wait for blocks") t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) + s.StartRelayer(relayer, testName) }) t.Run("packets are relayed between chain A and chain B", func(t *testing.T) { @@ -440,7 +449,11 @@ func (s *TransferChannelUpgradesTestSuite) TestChannelUpgrade_WithFeeMiddleware_ t := s.T() ctx := context.TODO() - relayer, channelA := s.GetRelayer(), s.GetChainAChannel() + testName := t.Name() + s.SetupChannelUpgradesPath(testName) + + relayer, channelA := s.GetRelayerForTest(testName), s.GetChainAChannelForTest(testName) + chainA, chainB := s.GetChains() channelB := channelA.Counterparty @@ -462,7 +475,7 @@ func (s *TransferChannelUpgradesTestSuite) TestChannelUpgrade_WithFeeMiddleware_ }) t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) + s.StartRelayer(relayer, testName) }) s.Require().NoError(test.WaitForBlocks(ctx, 10, chainA, chainB), "failed to wait for blocks") diff --git a/e2e/tests/upgrades/genesis_test.go b/e2e/tests/upgrades/genesis_test.go index c5c8a154168..2030aa87bdc 100644 --- a/e2e/tests/upgrades/genesis_test.go +++ b/e2e/tests/upgrades/genesis_test.go @@ -37,27 +37,36 @@ type GenesisTestSuite struct { testsuite.E2ETestSuite } +// TODO: this configuration was originally being applied to `GetChains` in the test body, but it is not +// actually being propagated correctly. If we want to apply the configuration, we can uncomment this code +// however the test actually fails when this is done. +// func (s *GenesisTestSuite) SetupSuite() { +// configFileOverrides := make(map[string]any) +// appTomlOverrides := make(test.Toml) +// +// appTomlOverrides["halt-height"] = haltHeight +// configFileOverrides["config/app.toml"] = appTomlOverrides +// +// s.SetupChains(context.TODO(), nil, func(options *testsuite.ChainOptions) { +// // create chains with specified chain configuration options +// options.ChainSpecs[0].ConfigFileOverrides = configFileOverrides +// }) +// } + func (s *GenesisTestSuite) TestIBCGenesis() { t := s.T() - configFileOverrides := make(map[string]any) - appTomlOverrides := make(test.Toml) + chainA, chainB := s.GetChains() - appTomlOverrides["halt-height"] = haltHeight - configFileOverrides["config/app.toml"] = appTomlOverrides - chainOpts := func(options *testsuite.ChainOptions) { - options.ChainSpecs[0].ConfigFileOverrides = configFileOverrides - } + ctx := context.Background() + testName := t.Name() - // create chains with specified chain configuration options - chainA, chainB := s.GetChains(chainOpts) + relayer := s.CreateDefaultPaths(testName) + channelA := s.GetChainAChannelForTest(testName) - ctx := context.Background() - relayer, channelA := s.GetRelayer(), s.GetChainAChannel() var ( chainADenom = chainA.Config().Denom chainBIBCToken = testsuite.GetIBCToken(chainADenom, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID) // IBC token sent to chainB - ) chainAWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) @@ -98,7 +107,7 @@ func (s *GenesisTestSuite) TestIBCGenesis() { }) t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) + s.StartRelayer(relayer, testName) }) t.Run("ics20: packets are relayed", func(t *testing.T) { @@ -112,6 +121,8 @@ func (s *GenesisTestSuite) TestIBCGenesis() { s.Require().Equal(expected, actualBalance.Int64()) }) + s.Require().NoError(test.WaitForBlocks(ctx, 10, chainA, chainB), "failed to wait for blocks") + t.Run("ics27: verify interchain account", func(t *testing.T) { res, err := query.GRPCQuery[controllertypes.QueryInterchainAccountResponse](ctx, chainA, &controllertypes.QueryInterchainAccountRequest{ Owner: controllerAddress, @@ -131,7 +142,7 @@ func (s *GenesisTestSuite) TestIBCGenesis() { s.Require().NoError(test.WaitForBlocks(ctx, 10, chainA, chainB), "failed to wait for blocks") t.Run("Halt chain and export genesis", func(t *testing.T) { - s.HaltChainAndExportGenesis(ctx, chainA.(*cosmos.CosmosChain), relayer, haltHeight) + s.HaltChainAndExportGenesis(ctx, chainA.(*cosmos.CosmosChain), haltHeight) }) t.Run("ics20: native IBC token transfer from chainA to chainB, sender is source of tokens", func(t *testing.T) { @@ -194,7 +205,7 @@ func (s *GenesisTestSuite) TestIBCGenesis() { s.Require().NoError(test.WaitForBlocks(ctx, 5, chainA, chainB), "failed to wait for blocks") } -func (s *GenesisTestSuite) HaltChainAndExportGenesis(ctx context.Context, chain *cosmos.CosmosChain, relayer ibc.Relayer, haltHeight int64) { +func (s *GenesisTestSuite) HaltChainAndExportGenesis(ctx context.Context, chain *cosmos.CosmosChain, haltHeight int64) { timeoutCtx, timeoutCtxCancel := context.WithTimeout(ctx, time.Minute*2) defer timeoutCtxCancel() diff --git a/e2e/tests/upgrades/upgrade_test.go b/e2e/tests/upgrades/upgrade_test.go index 6e194a138cd..c3b16cf6f38 100644 --- a/e2e/tests/upgrades/upgrade_test.go +++ b/e2e/tests/upgrades/upgrade_test.go @@ -5,7 +5,6 @@ package upgrades import ( "context" "fmt" - "strings" "sync" "testing" "time" @@ -56,13 +55,8 @@ type UpgradeTestSuite struct { testsuite.E2ETestSuite } -func (s *UpgradeTestSuite) SetupTest() { - channelOpts := s.TransferChannelOptions() - // TODO(chatton) hack to handle special case for the v8 to v8.1 upgrade test. - if strings.HasSuffix(s.T().Name(), "TestV8ToV8_1ChainUpgrade") { - channelOpts = s.FeeTransferChannelOptions() - } - s.SetupPaths(ibc.DefaultClientOpts(), channelOpts) +func (s *UpgradeTestSuite) CreateUpgradeTestPath(testName string) (ibc.Relayer, ibc.ChannelOutput) { + return s.CreatePaths(ibc.DefaultClientOpts(), s.TransferChannelOptions(), testName), s.GetChainAChannelForTest(testName) } // UpgradeChain upgrades a chain to a specific version using the planName provided. @@ -129,7 +123,9 @@ func (s *UpgradeTestSuite) TestIBCChainUpgrade() { testCfg := testsuite.LoadConfig() ctx := context.Background() - relayer, channelA := s.GetRelayer(), s.GetChainAChannel() + testName := t.Name() + relayer, channelA := s.CreateUpgradeTestPath(testName) + chainA, chainB := s.GetChains() var ( @@ -166,7 +162,7 @@ func (s *UpgradeTestSuite) TestIBCChainUpgrade() { }) t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) + s.StartRelayer(relayer, testName) }) t.Run("packets are relayed", func(t *testing.T) { @@ -188,7 +184,7 @@ func (s *UpgradeTestSuite) TestIBCChainUpgrade() { t.Run("restart relayer", func(t *testing.T) { s.StopRelayer(ctx, relayer) - s.StartRelayer(relayer) + s.StartRelayer(relayer, testName) }) t.Run("native IBC token transfer from chainA to chainB, sender is source of tokens", func(t *testing.T) { @@ -234,6 +230,9 @@ func (s *UpgradeTestSuite) TestChainUpgrade() { ctx := context.Background() + testName := t.Name() + s.CreateUpgradeTestPath(testName) + // TODO(chatton): this test is still creating a relayer and a channel, but it is not using them. chain := s.GetAllChains()[0] @@ -294,7 +293,10 @@ func (s *UpgradeTestSuite) TestV6ToV7ChainUpgrade() { testCfg := testsuite.LoadConfig() ctx := context.Background() - relayer, channelA := s.GetRelayer(), s.GetChainAChannel() + testName := t.Name() + + relayer, channelA := s.CreateUpgradeTestPath(testName) + chainA, chainB := s.GetChains() var ( @@ -382,7 +384,7 @@ func (s *UpgradeTestSuite) TestV6ToV7ChainUpgrade() { }) t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) + s.StartRelayer(relayer, testName) }) t.Run("packets are relayed", func(t *testing.T) { @@ -408,7 +410,7 @@ func (s *UpgradeTestSuite) TestV6ToV7ChainUpgrade() { // in some cases after an upgrade. tc := testsuite.LoadConfig() if tc.GetActiveRelayerConfig().ID == e2erelayer.Hermes { - s.RestartRelayer(ctx, relayer) + s.RestartRelayer(ctx, relayer, testName) } t.Run("check that the tendermint clients are active again after upgrade", func(t *testing.T) { @@ -448,7 +450,10 @@ func (s *UpgradeTestSuite) TestV7ToV7_1ChainUpgrade() { testCfg := testsuite.LoadConfig() ctx := context.Background() - relayer, channelA := s.GetRelayer(), s.GetChainAChannel() + testName := t.Name() + + relayer, channelA := s.CreateUpgradeTestPath(testName) + chainA, chainB := s.GetChains() chainADenom := chainA.Config().Denom @@ -475,7 +480,7 @@ func (s *UpgradeTestSuite) TestV7ToV7_1ChainUpgrade() { }) t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) + s.StartRelayer(relayer, testName) }) chainBIBCToken := testsuite.GetIBCToken(chainADenom, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID) @@ -539,7 +544,10 @@ func (s *UpgradeTestSuite) TestV7ToV8ChainUpgrade() { testCfg := testsuite.LoadConfig() ctx := context.Background() - relayer, channelA := s.GetRelayer(), s.GetChainAChannel() + testName := t.Name() + + relayer, channelA := s.CreateUpgradeTestPath(testName) + chainA, chainB := s.GetChains() chainADenom := chainA.Config().Denom @@ -566,7 +574,7 @@ func (s *UpgradeTestSuite) TestV7ToV8ChainUpgrade() { }) t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) + s.StartRelayer(relayer, testName) }) chainBIBCToken := testsuite.GetIBCToken(chainADenom, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID) @@ -632,7 +640,10 @@ func (s *UpgradeTestSuite) TestV8ToV8_1ChainUpgrade() { t := s.T() ctx := context.Background() - relayer, channelA := s.GetRelayer(), s.GetChainAChannel() + testName := t.Name() + relayer := s.CreatePaths(ibc.DefaultClientOpts(), s.FeeTransferChannelOptions(), testName) + + channelA := s.GetChainAChannelForTest(testName) chainA, chainB := s.GetChains() chainADenom := chainA.Config().Denom @@ -721,7 +732,7 @@ func (s *UpgradeTestSuite) TestV8ToV8_1ChainUpgrade() { }) t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) + s.StartRelayer(relayer, testName) }) chainBIBCToken := testsuite.GetIBCToken(chainADenom, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID) @@ -759,7 +770,10 @@ func (s *UpgradeTestSuite) TestV8ToV8_1ChainUpgrade_ChannelUpgrades() { testCfg := testsuite.LoadConfig() ctx := context.Background() - relayer, channelA := s.GetRelayer(), s.GetChainAChannel() + testName := t.Name() + + relayer, channelA := s.CreateUpgradeTestPath(testName) + channelB := channelA.Counterparty chainA, chainB := s.GetChains() @@ -862,7 +876,7 @@ func (s *UpgradeTestSuite) TestV8ToV8_1ChainUpgrade_ChannelUpgrades() { }) t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) + s.StartRelayer(relayer, testName) }) s.Require().NoError(test.WaitForBlocks(ctx, 10, chainA, chainB), "failed to wait for blocks") @@ -956,7 +970,7 @@ func (s *UpgradeTestSuite) TestV8ToV8_1ChainUpgrade_ChannelUpgrades() { }) t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) + s.StartRelayer(relayer, testName) }) t.Run("send incentivized transfer packet", func(t *testing.T) { diff --git a/e2e/tests/wasm/grandpa_test.go b/e2e/tests/wasm/grandpa_test.go index a0eade9cb1e..09739bb4054 100644 --- a/e2e/tests/wasm/grandpa_test.go +++ b/e2e/tests/wasm/grandpa_test.go @@ -119,7 +119,7 @@ func (s *GrandpaTestSuite) SetupSuite() { }) } -func (s *GrandpaTestSuite) SetupTest() { +func (s *GrandpaTestSuite) SetupGrandpaPath(testName string) { ctx := context.TODO() chainA, chainB := s.GetChains() @@ -143,7 +143,7 @@ func (s *GrandpaTestSuite) SetupTest() { s.Require().NotEmpty(checksum, "checksum was empty but should not have been") s.T().Log("pushed wasm client proposal") - r := s.GetRelayer() + r := s.GetRelayerForTest(testName) err = r.SetClientContractHash(ctx, s.GetRelayerExecReporter(), cosmosChain.Config(), checksum) s.Require().NoError(err) @@ -154,7 +154,7 @@ func (s *GrandpaTestSuite) SetupTest() { channelOpts := ibc.DefaultChannelOpts() channelOpts.Version = transfertypes.V1 - s.SetupPaths(ibc.DefaultClientOpts(), channelOpts) + s.CreatePaths(ibc.DefaultClientOpts(), channelOpts, testName) } // TestMsgTransfer_Succeeds_GrandpaContract features @@ -170,6 +170,9 @@ func (s *GrandpaTestSuite) TestMsgTransfer_Succeeds_GrandpaContract() { ctx := context.Background() t := s.T() + testName := t.Name() + s.SetupGrandpaPath(testName) + chainA, chainB := s.GetChains() polkadotChain, ok := chainA.(*polkadot.PolkadotChain) @@ -178,7 +181,7 @@ func (s *GrandpaTestSuite) TestMsgTransfer_Succeeds_GrandpaContract() { cosmosChain, ok := chainB.(*cosmos.CosmosChain) s.Require().True(ok) - r := s.GetRelayer() + r := s.GetRelayerForTest(testName) eRep := s.GetRelayerExecReporter() @@ -196,7 +199,7 @@ func (s *GrandpaTestSuite) TestMsgTransfer_Succeeds_GrandpaContract() { } // Start relayer - s.Require().NoError(r.StartRelayer(ctx, eRep, s.GetPaths()...)) + s.Require().NoError(r.StartRelayer(ctx, eRep, s.GetPaths(testName)...)) t.Run("send successful IBC transfer from Cosmos to Polkadot parachain", func(t *testing.T) { // Send 1.77 stake from cosmosUser to parachainUser @@ -280,6 +283,9 @@ func (s *GrandpaTestSuite) TestMsgTransfer_TimesOut_GrandpaContract() { ctx := context.Background() t := s.T() + testName := t.Name() + s.SetupGrandpaPath(testName) + chainA, chainB := s.GetChains() polkadotChain, ok := chainA.(*polkadot.PolkadotChain) @@ -288,7 +294,7 @@ func (s *GrandpaTestSuite) TestMsgTransfer_TimesOut_GrandpaContract() { cosmosChain, ok := chainB.(*cosmos.CosmosChain) s.Require().True(ok) - r := s.GetRelayer() + r := s.GetRelayerForTest(testName) eRep := s.GetRelayerExecReporter() @@ -352,8 +358,12 @@ func (s *GrandpaTestSuite) TestMsgTransfer_TimesOut_GrandpaContract() { // * Pushes a new wasm client contract to the Cosmos chain // * Migrates the wasm client contract func (s *GrandpaTestSuite) TestMsgMigrateContract_Success_GrandpaContract() { + t := s.T() ctx := context.Background() + testName := t.Name() + s.SetupGrandpaPath(testName) + _, chainB := s.GetChains() cosmosChain, ok := chainB.(*cosmos.CosmosChain) @@ -404,8 +414,12 @@ func (s *GrandpaTestSuite) TestMsgMigrateContract_Success_GrandpaContract() { // * Pushes a new wasm client contract to the Cosmos chain // * Migrates the wasm client contract with a contract that will always fail migration func (s *GrandpaTestSuite) TestMsgMigrateContract_ContractError_GrandpaContract() { + t := s.T() ctx := context.Background() + testName := t.Name() + s.SetupGrandpaPath(testName) + _, chainB := s.GetChains() cosmosChain, ok := chainB.(*cosmos.CosmosChain) @@ -458,8 +472,13 @@ func (s *GrandpaTestSuite) TestMsgMigrateContract_ContractError_GrandpaContract( // - ics10_grandpa_cw_expiry.wasm.gz // This contract modifies the unbonding period to 1600s with the trusting period being calculated as (unbonding period / 3). func (s *GrandpaTestSuite) TestRecoverClient_Succeeds_GrandpaContract() { + t := s.T() + ctx := context.Background() + testName := t.Name() + s.SetupGrandpaPath(testName) + // set the trusting period to a value which will still be valid upon client creation, but invalid before the first update // the contract uses 1600s as the unbonding period with the trusting period evaluating to (unbonding period / 3) modifiedTrustingPeriod := (1600 * time.Second) / 3 @@ -472,7 +491,7 @@ func (s *GrandpaTestSuite) TestRecoverClient_Succeeds_GrandpaContract() { cosmosChain, ok := chainB.(*cosmos.CosmosChain) s.Require().True(ok) - r := s.GetRelayer() + r := s.GetRelayerForTest(testName) cosmosWallet := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) diff --git a/e2e/testsuite/testsuite.go b/e2e/testsuite/testsuite.go index 4f5812bb432..b5fc55fafa6 100644 --- a/e2e/testsuite/testsuite.go +++ b/e2e/testsuite/testsuite.go @@ -17,6 +17,7 @@ import ( test "github.com/strangelove-ventures/interchaintest/v8/testutil" testifysuite "github.com/stretchr/testify/suite" "go.uber.org/zap" + "golang.org/x/exp/slices" sdkmath "cosmossdk.io/math" @@ -54,12 +55,11 @@ type E2ETestSuite struct { // chains is a list of chains that are created for the test suite. // each test suite has a single slice of chains that are used for all individual test // cases. - chains []ibc.Chain - relayers relayer.Map - logger *zap.Logger - DockerClient *dockerclient.Client - network string - startRelayerFn func(relayer ibc.Relayer) + chains []ibc.Chain + relayers relayer.Map + logger *zap.Logger + DockerClient *dockerclient.Client + network string // pathNameIndex is the latest index to be used for generating chains pathNameIndex int64 @@ -69,6 +69,8 @@ type E2ETestSuite struct { testPaths map[string][]string channels map[string]map[ibc.Chain][]ibc.ChannelOutput + // channelLock ensures concurrent tests are not creating and accessing channels as the same time. + channelLock sync.Mutex // relayerLock ensures concurrent tests are not accessing the pool of relayers as the same time. relayerLock sync.Mutex // relayerPool is a pool of relayers that can be used in tests. @@ -163,6 +165,9 @@ func (s *E2ETestSuite) initalizeRelayerPool(n int) []ibc.Relayer { // connections and channels between the chains. func (s *E2ETestSuite) SetupChains(ctx context.Context, channelOptionsModifier ChainOptionModifier, chainSpecOpts ...ChainOptionConfiguration) { s.T().Logf("Setting up chains: %s", s.T().Name()) + + s.Require().NoError(os.Setenv("KEEP_CONTAINERS", "true")) + s.initState() s.configureGenesisDebugExport() @@ -175,7 +180,7 @@ func (s *E2ETestSuite) SetupChains(ctx context.Context, channelOptionsModifier C s.relayerPool = s.initalizeRelayerPool(chainOptions.RelayerCount) - ic := s.newInterchain(ctx, s.relayerPool, s.chains, channelOptionsModifier) + ic := s.newInterchain(s.relayerPool, s.chains, channelOptionsModifier) buildOpts := interchaintest.InterchainBuildOptions{ TestName: s.T().Name(), @@ -188,36 +193,46 @@ func (s *E2ETestSuite) SetupChains(ctx context.Context, channelOptionsModifier C s.Require().NoError(ic.Build(ctx, s.GetRelayerExecReporter(), buildOpts)) } -// SetupTest will by default use the default channel options to create a path between the chains. -// if non default channel options are required, the test suite must override the `SetupTest` function. -func (s *E2ETestSuite) SetupTest() { - s.SetupPaths(ibc.DefaultClientOpts(), defaultChannelOpts(s.GetAllChains())) +// CreateDefaultPaths creates a path between the chains using the default client and channel options. +// this should be called as the setup function in most tests if no additional options are required. +func (s *E2ETestSuite) CreateDefaultPaths(testName string) ibc.Relayer { + return s.CreatePaths(ibc.DefaultClientOpts(), DefaultChannelOpts(s.GetAllChains()), testName) } -// SetupPaths creates paths between the chains using the provided client and channel options. +// CreatePaths creates paths between the chains using the provided client and channel options. // The paths are created such that ChainA is connected to ChainB, ChainB is connected to ChainC etc. -func (s *E2ETestSuite) SetupPaths(clientOpts ibc.CreateClientOptions, channelOpts ibc.CreateChannelOptions) { - s.T().Logf("Setting up path for: %s", s.T().Name()) +func (s *E2ETestSuite) CreatePaths(clientOpts ibc.CreateClientOptions, channelOpts ibc.CreateChannelOptions, testName string) ibc.Relayer { + s.T().Logf("Setting up path for: %s", testName) + + if s.channels[testName] == nil { + s.channels[testName] = make(map[ibc.Chain][]ibc.ChannelOutput) + } + + r := s.GetRelayerForTest(testName) ctx := context.TODO() allChains := s.GetAllChains() for i := 0; i < len(allChains)-1; i++ { chainA, chainB := allChains[i], allChains[i+1] - _, _ = s.CreatePath(ctx, chainA, chainB, clientOpts, channelOpts) + s.CreatePath(ctx, r, chainA, chainB, clientOpts, channelOpts, testName) } + + return r } // CreatePath creates a path between chainA and chainB using the provided client and channel options. func (s *E2ETestSuite) CreatePath( ctx context.Context, + r ibc.Relayer, chainA ibc.Chain, chainB ibc.Chain, clientOpts ibc.CreateClientOptions, channelOpts ibc.CreateChannelOptions, + testName string, ) (chainAChannel ibc.ChannelOutput, chainBChannel ibc.ChannelOutput) { - r := s.GetRelayer() - pathName := s.generatePathName() + s.testPaths[testName] = append(s.testPaths[testName], pathName) + s.T().Logf("establishing path between %s and %s on path %s", chainA.Config().ChainID, chainB.Config().ChainID, pathName) err := r.GeneratePath(ctx, s.GetRelayerExecReporter(), chainA.Config().ChainID, chainB.Config().ChainID, pathName) @@ -234,68 +249,75 @@ func (s *E2ETestSuite) CreatePath( err = test.WaitForBlocks(ctx, 1, chainA, chainB) s.Require().NoError(err) - err = r.CreateChannel(ctx, s.GetRelayerExecReporter(), pathName, channelOpts) - s.Require().NoError(err) - err = test.WaitForBlocks(ctx, 1, chainA, chainB) - s.Require().NoError(err) + s.createChannelWithLock(ctx, r, pathName, testName, channelOpts, chainA, chainB) - channelsA, err := r.GetChannels(ctx, s.GetRelayerExecReporter(), chainA.Config().ChainID) - s.Require().NoError(err) + aChannels := s.channels[testName][chainA] + bChannels := s.channels[testName][chainB] - channelsB, err := r.GetChannels(ctx, s.GetRelayerExecReporter(), chainB.Config().ChainID) + return aChannels[len(aChannels)-1], bChannels[len(bChannels)-1] +} + +// createChannelWithLock creates a channel between the two provided chains for the given test name. This applies a lock +// to ensure that the channels that are created are correctly mapped to the test that created them. +func (s *E2ETestSuite) createChannelWithLock(ctx context.Context, r ibc.Relayer, pathName, testName string, channelOpts ibc.CreateChannelOptions, chainA, chainB ibc.Chain) { + // NOTE: we need to lock the creation of channels and applying of packet filters, as if we don't, the result + // of `r.GetChannels` may return channels created by other relayers in different tests. + s.channelLock.Lock() + defer s.channelLock.Unlock() + + err := r.CreateChannel(ctx, s.GetRelayerExecReporter(), pathName, channelOpts) + s.Require().NoError(err) + err = test.WaitForBlocks(ctx, 1, chainA, chainB) s.Require().NoError(err) - if s.channels[s.T().Name()] == nil { - s.channels[s.T().Name()] = make(map[ibc.Chain][]ibc.ChannelOutput) - } + for _, c := range []ibc.Chain{chainA, chainB} { + channels, err := r.GetChannels(ctx, s.GetRelayerExecReporter(), c.Config().ChainID) + s.Require().NoError(err) - // keep track of channels associated with a given chain for access within the tests. - s.channels[s.T().Name()][chainA] = channelsA - s.channels[s.T().Name()][chainB] = channelsB + if _, ok := s.channels[testName][c]; !ok { + s.channels[testName][c] = []ibc.ChannelOutput{} + } - s.testPaths[s.T().Name()] = append(s.testPaths[s.T().Name()], pathName) + // keep track of channels associated with a given chain for access within the tests. + // only the most recent channel is relevant. + s.channels[testName][c] = append(s.channels[testName][c], getLatestChannel(channels)) - return channelsA[len(channelsA)-1], channelsB[len(channelsB)-1] + err = relayer.ApplyPacketFilter(ctx, s.T(), r, c.Config().ChainID, s.channels[testName][c]) + s.Require().NoError(err, "failed to watch port and channel on chain: %s", c.Config().ChainID) + } } -type ChainChannelPair struct { - ChainIdx uint64 - ChannelIdx uint64 +// getLatestChannel returns the latest channel from the list of channels. +func getLatestChannel(channels []ibc.ChannelOutput) ibc.ChannelOutput { + return slices.MaxFunc(channels, func(a, b ibc.ChannelOutput) int { + seqA, _ := channeltypes.ParseChannelSequence(a.ChannelID) + seqB, _ := channeltypes.ParseChannelSequence(b.ChannelID) + return int(seqA - seqB) + }) } -// GetChainAChannel returns the ibc.ChannelOutput for the current test. +// GetChainAChannelForTest returns the ibc.ChannelOutput for the current test. // this defaults to the first entry in the list, and will be what is needed in the case of // a single channel test. -func (s *E2ETestSuite) GetChainAChannel() ibc.ChannelOutput { - return s.GetChainChannel(ChainChannelPair{ChainIdx: 0, ChannelIdx: 0}) +func (s *E2ETestSuite) GetChainAChannelForTest(testName string) ibc.ChannelOutput { + return s.GetChannelsForTest(s.GetAllChains()[0], testName)[0] } -// GetChainChannel returns the ibc.ChannelOutput at the specified index for a specific -// entry in the list of chains. -func (s *E2ETestSuite) GetChainChannel(id ChainChannelPair) ibc.ChannelOutput { - chains := s.GetAllChains() - s.Require().Less(id.ChainIdx, uint64(len(chains)), "required index %d is larger than the last index in the list of chains (%d)", id.ChainIdx, len(chains)-1) - - chain := chains[id.ChainIdx] - channels := s.GetChannels(chain) - s.Require().Less(id.ChannelIdx, uint64(len(channels)), "required channel index %d is larger than the last index in the list of channels (%d)", id.ChannelIdx, len(channels)-1) - return channels[id.ChannelIdx] -} - -// GetChannels returns all channels for the current test. -func (s *E2ETestSuite) GetChannels(chain ibc.Chain) []ibc.ChannelOutput { - channels, ok := s.channels[s.T().Name()][chain] - s.Require().True(ok, "channel not found for test %s", s.T().Name()) +// GetChannelsForTest returns all channels for the specified test. +func (s *E2ETestSuite) GetChannelsForTest(chain ibc.Chain, testName string) []ibc.ChannelOutput { + channels, ok := s.channels[testName][chain] + s.Require().True(ok, "channel not found for test %s", testName) return channels } -// GetRelayer returns the relayer for the current test from the available pool of relayers. +// GetRelayerForTest returns the relayer for the current test from the available pool of relayers. // once a relayer has been returned to a test, it is cached and will be reused for the duration of the test. -func (s *E2ETestSuite) GetRelayer() ibc.Relayer { +func (s *E2ETestSuite) GetRelayerForTest(testName string) ibc.Relayer { s.relayerLock.Lock() defer s.relayerLock.Unlock() - if r, ok := s.testRelayerMap[s.T().Name()]; ok { + if r, ok := s.testRelayerMap[testName]; ok { + s.T().Logf("relayer already created for test: %s", testName) return r } @@ -308,15 +330,15 @@ func (s *E2ETestSuite) GetRelayer() ibc.Relayer { // remove the relayer from the pool s.relayerPool = s.relayerPool[1:] - s.testRelayerMap[s.T().Name()] = r + s.testRelayerMap[testName] = r return r } // GetRelayerUsers returns two ibc.Wallet instances which can be used for the relayer users // on the two chains. -func (s *E2ETestSuite) GetRelayerUsers(ctx context.Context, chainOpts ...ChainOptionConfiguration) (ibc.Wallet, ibc.Wallet) { - chains := s.GetAllChains(chainOpts...) +func (s *E2ETestSuite) GetRelayerUsers(ctx context.Context) (ibc.Wallet, ibc.Wallet) { + chains := s.GetAllChains() chainA, chainB := chains[0], chains[1] chainAAccountBytes, err := chainA.GetAddress(ctx, ChainARelayerName) s.Require().NoError(err) @@ -341,7 +363,7 @@ func (s *E2ETestSuite) GetRelayerUsers(ctx context.Context, chainOpts ...ChainOp type ChainOptionModifier func(chainA, chainB ibc.Chain) func(options *ibc.CreateChannelOptions) // newInterchain constructs a new interchain instance that creates channels between the chains. -func (s *E2ETestSuite) newInterchain(ctx context.Context, relayers []ibc.Relayer, chains []ibc.Chain, modificationProvider ChainOptionModifier) *interchaintest.Interchain { +func (s *E2ETestSuite) newInterchain(relayers []ibc.Relayer, chains []ibc.Chain, modificationProvider ChainOptionModifier) *interchaintest.Interchain { ic := interchaintest.NewInterchain() for _, chain := range chains { ic.AddChain(chain) @@ -357,7 +379,7 @@ func (s *E2ETestSuite) newInterchain(ctx context.Context, relayers []ibc.Relayer // - chainC and chainD etc for i := 0; i < len(chains)-1; i++ { pathName := s.generatePathName() - channelOpts := defaultChannelOpts(chains) + channelOpts := DefaultChannelOpts(chains) chain1, chain2 := chains[i], chains[i+1] if modificationProvider != nil { @@ -377,24 +399,6 @@ func (s *E2ETestSuite) newInterchain(ctx context.Context, relayers []ibc.Relayer } } - s.startRelayerFn = func(relayer ibc.Relayer) { - // depending on the test, the path names will be different. - // whenever a relayer is started, it should use the paths associated with the test the relayer is running in. - pathNames, ok := s.testPaths[s.T().Name()] - s.Require().True(ok, "path names not found for test %s", s.T().Name()) - - err := relayer.StartRelayer(ctx, s.GetRelayerExecReporter(), pathNames...) - s.Require().NoError(err, fmt.Sprintf("failed to start relayer: %s", err)) - - var chainHeighters []test.ChainHeighter - for _, c := range chains { - chainHeighters = append(chainHeighters, c) - } - - // wait for every chain to produce some blocks before using the relayer. - s.Require().NoError(test.WaitForBlocks(ctx, 10, chainHeighters...), "failed to wait for blocks") - } - return ic } @@ -405,8 +409,8 @@ func (s *E2ETestSuite) generatePathName() string { return pathName } -func (s *E2ETestSuite) GetPaths() []string { - paths, ok := s.testPaths[s.T().Name()] +func (s *E2ETestSuite) GetPaths(testName string) []string { + paths, ok := s.testPaths[testName] s.Require().True(ok, "paths not found for test %s", s.T().Name()) return paths } @@ -450,14 +454,14 @@ func (s *E2ETestSuite) UpdateClients(ctx context.Context, ibcrelayer ibc.Relayer // GetChains returns two chains that can be used in a test. The pair returned // is unique to the current test being run. Note: this function does not create containers. -func (s *E2ETestSuite) GetChains(chainOpts ...ChainOptionConfiguration) (ibc.Chain, ibc.Chain) { - chains := s.GetAllChains(chainOpts...) +func (s *E2ETestSuite) GetChains() (ibc.Chain, ibc.Chain) { + chains := s.GetAllChains() return chains[0], chains[1] } // GetAllChains returns all chains that can be used in a test. The chains returned // are unique to the current test being run. Note: this function does not create containers. -func (s *E2ETestSuite) GetAllChains(chainOpts ...ChainOptionConfiguration) []ibc.Chain { +func (s *E2ETestSuite) GetAllChains() []ibc.Chain { // chains are stored on a per test suite level chains := s.chains s.Require().NotEmpty(chains, "chains not found for test %s", s.testSuiteName) @@ -501,12 +505,17 @@ func (s *E2ETestSuite) RecoverRelayerWallets(ctx context.Context, ibcrelayer ibc } // StartRelayer starts the given ibcrelayer. -func (s *E2ETestSuite) StartRelayer(ibcrelayer ibc.Relayer) { - if s.startRelayerFn == nil { - panic(errors.New("cannot start relayer before it is created")) +func (s *E2ETestSuite) StartRelayer(r ibc.Relayer, testName string) { + s.Require().NoError(r.StartRelayer(context.TODO(), s.GetRelayerExecReporter(), s.GetPaths(testName)...), "failed to start relayer") + + chains := s.GetAllChains() + var chainHeighters []test.ChainHeighter + for _, c := range chains { + chainHeighters = append(chainHeighters, c) } - s.startRelayerFn(ibcrelayer) + // wait for every chain to produce some blocks before using the relayer. + s.Require().NoError(test.WaitForBlocks(context.TODO(), 10, chainHeighters...), "failed to wait for blocks") } // StopRelayer stops the given ibcrelayer. @@ -516,9 +525,9 @@ func (s *E2ETestSuite) StopRelayer(ctx context.Context, ibcrelayer ibc.Relayer) } // RestartRelayer restarts the given relayer. -func (s *E2ETestSuite) RestartRelayer(ctx context.Context, ibcrelayer ibc.Relayer) { +func (s *E2ETestSuite) RestartRelayer(ctx context.Context, ibcrelayer ibc.Relayer, testName string) { s.StopRelayer(ctx, ibcrelayer) - s.StartRelayer(ibcrelayer) + s.StartRelayer(ibcrelayer, testName) } // CreateUserOnChainA creates a user with the given amount of funds on chain A. @@ -768,8 +777,8 @@ func ThreeChainSetup() ChainOptionConfiguration { } } -// defaultChannelOpts returns the default chain options for the test suite based on the provided chains. -func defaultChannelOpts(chains []ibc.Chain) ibc.CreateChannelOptions { +// DefaultChannelOpts returns the default chain options for the test suite based on the provided chains. +func DefaultChannelOpts(chains []ibc.Chain) ibc.CreateChannelOptions { channelOptions := ibc.DefaultChannelOpts() channelOptions.Version = determineDefaultTransferVersion(chains) return channelOptions