Skip to content

Commit

Permalink
feat(e2e): ran 'go-codegen interchaintest scaffold'
Browse files Browse the repository at this point in the history
  • Loading branch information
srdtrk committed Jun 7, 2024
1 parent 993464b commit 512ef63
Show file tree
Hide file tree
Showing 17 changed files with 3,436 additions and 0 deletions.
80 changes: 80 additions & 0 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
name: e2e
on:
push:
branches: [main]
pull_request:
paths:
- '**.rs'
- '**.go'
- '**.toml'
- '**.lock'
- '**.mod'
- '**.sum'
- '.github/workflows/e2e.yml'
permissions:
contents: read
jobs:
golangci:
name: lint
runs-on: ubuntu-latest
steps:
- uses: actions/setup-go@v4
with:
go-version: "1.22"
- uses: actions/checkout@v3
- name: golangci-lint
uses: golangci/golangci-lint-action@v3.7.0
with:
version: v1.59
args: --timeout 5m
working-directory: e2e/interchaintestv8
build:
strategy:
fail-fast: false
matrix:
test:
# List your tests here
- TestWithBasicTestSuite/TestBasic
name: ${{ matrix.test }}
runs-on: ubuntu-latest
steps:
- name: Checkout sources
uses: actions/checkout@v3
# You can build your contract here, you can either use docker or a custom cargo script:
# We've provided examples for both below:
#
# - name: Build Contracts with Docker
# run: |
# docker run --rm -v "$(pwd)":/code \
# --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \
# --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \
# cosmwasm/optimizer:0.15.1
# - name: Install cargo-run-script
# uses: actions-rs/cargo@v1
# with:
# command: install
# args: cargo-run-script
# - name: Build Optimized Contract
# uses: actions-rs/cargo@v1
# with:
# command: run-script
# args: optimize
- name: Setup Go
uses: actions/setup-go@v4
with:
go-version: "1.22"
check-latest: true
cache-dependency-path: |
e2e/interchaintestv8/go.sum
- name: Run Tests
run: |
cd e2e/interchaintestv8
go test -v -mod=readonly . -run=${{ matrix.test }}
- name: Upload Diagnostics on Failure
uses: actions/upload-artifact@v4
if: ${{ failure() }}
continue-on-error: true
with:
name: '${{ matrix.entrypoint }}-${{ matrix.test }}'
path: e2e/interchaintestv8/diagnostics
retention-days: 5
2 changes: 2 additions & 0 deletions e2e/interchaintestv8/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Ignore diagnostics directory
diagnostics/
82 changes: 82 additions & 0 deletions e2e/interchaintestv8/.golangci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
run:
tests: true
# # timeout for analysis, e.g. 30s, 5m, default is 1m
timeout: 5m

linters:
disable-all: true
enable:
- dogsled
- exportloopref
- errcheck
- gci
- goconst
- gocritic
- gofumpt
- gosec
- gosimple
- govet
- ineffassign
- misspell
- nakedret
- staticcheck
- thelper
- stylecheck
- revive
- typecheck
- unconvert
- unused
- misspell

issues:
exclude-rules:
- text: "unused-parameter"
linters:
- revive
- text: "SA1019:"
linters:
- staticcheck
- text: "Use of weak random number generator"
linters:
- gosec
- text: "ST1003:"
linters:
- stylecheck
# FIXME: Disabled until golangci-lint updates stylecheck with this fix:
# https://github.com/dominikh/go-tools/issues/389
- text: "ST1016:"
linters:
- stylecheck
max-issues-per-linter: 10000
max-same-issues: 10000

linters-settings:
gci:
sections:
- standard # Standard section: captures all standard packages.
- default # Default section: contains all imports that could not be matched to another section type.
- blank # blank imports
- dot # dot imports
- prefix(cosmossdk.io)
- prefix(github.com/cosmos/cosmos-sdk)
- prefix(github.com/cometbft/cometbft)
- prefix(github.com/cosmos/ibc-go)
- prefix(github.com/CosmWasm/wasmd)
- prefix(github.com/strangelove-ventures/interchaintest)
- prefix(github.com/srdtrk/cw-ibc-lite/e2esuite/v8)

custom-order: true
dogsled:
max-blank-identifiers: 3
maligned:
# print struct with more effective memory layout or not, false by default
suggest-new: true
nolintlint:
allow-unused: false
allow-leading-space: true
require-explanation: false
require-specific: false
revive:
rules:
- name: if-return
disabled: true
19 changes: 19 additions & 0 deletions e2e/interchaintestv8/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# End to End Testing Suite with Interchaintest

The e2e tests are built using the [interchaintest](https://github.com/strangelove-ventures/interchaintest) library by Strangelove. It runs multiple docker container validators, and lets you test IBC enabled smart contracts.

These end to end tests are designed to run in the ci, but you can also run them locally.

## Running the tests locally

To run the tests locally, run the following commands from this directory:

```text
go test -v . -run=$TEST_SUITE_FN/$TEST_NAME
```

where `$TEST_NAME` is one of the test names of the `$TEST_SUITE_FN`. For example, to run the `TestBasic` test, you would run:

```text
go test -v . -run=TestWithBasicTestSuite/TestBasic
```
137 changes: 137 additions & 0 deletions e2e/interchaintestv8/basic_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
package main

import (
"context"
"fmt"
"testing"
"time"

"github.com/stretchr/testify/suite"

sdk "github.com/cosmos/cosmos-sdk/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"

transfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types"
channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types"

"github.com/strangelove-ventures/interchaintest/v8/ibc"
"github.com/strangelove-ventures/interchaintest/v8/testutil"

"github.com/srdtrk/cw-ibc-lite/e2esuite/v8/e2esuite"
)

// BasicTestSuite is a suite of tests that wraps the TestSuite
// and can provide additional functionality
type BasicTestSuite struct {
e2esuite.TestSuite
}

// SetupSuite calls the underlying BasicTestSuite's SetupSuite method
func (s *BasicTestSuite) SetupSuite(ctx context.Context) {
s.TestSuite.SetupSuite(ctx)
}

// TestWithBasicTestSuite is the boilerplate code that allows the test suite to be run
func TestWithBasicTestSuite(t *testing.T) {
suite.Run(t, new(BasicTestSuite))
}

// TestBasic is an example test function that will be run by the test suite
func (s *BasicTestSuite) TestBasic() {
ctx := context.Background()

s.SetupSuite(ctx)

wasmd1, wasmd2 := s.ChainA, s.ChainB

// Add your test code here. For example, create a transfer channel between ChainA and ChainB:
s.Run("CreateTransferChannel", func() {
err := s.Relayer.CreateChannel(ctx, s.ExecRep, s.PathName, ibc.DefaultChannelOpts())
s.Require().NoError(err)

// Wait for the channel to be created
err = testutil.WaitForBlocks(ctx, 5, s.ChainA, s.ChainB)
s.Require().NoError(err)
})

// Test if the handshake was successful
var (
wasmd1Channel ibc.ChannelOutput
wasmd2Channel ibc.ChannelOutput
)
s.Run("VerifyTransferChannel", func() {
wasmd1Channels, err := s.Relayer.GetChannels(ctx, s.ExecRep, wasmd1.Config().ChainID)
s.Require().NoError(err)
s.Require().Equal(1, len(wasmd1Channels))

wasmd1Channel = wasmd1Channels[0]
s.Require().Equal(transfertypes.PortID, wasmd1Channel.PortID)
s.Require().Equal(transfertypes.PortID, wasmd1Channel.Counterparty.PortID)
s.Require().Equal(transfertypes.Version, wasmd1Channel.Version)
s.Require().Equal(channeltypes.OPEN.String(), wasmd1Channel.State)
s.Require().Equal(channeltypes.UNORDERED.String(), wasmd1Channel.Ordering)

wasmd2Channels, err := s.Relayer.GetChannels(ctx, s.ExecRep, wasmd2.Config().ChainID)
s.Require().NoError(err)
/*
The relayer in the test suite sometimes submits multiple `ChannelOpenTry` messages,
since there is no replay protection for `ChannelOpenTry` messages, there may be
multiple channels in the state of the counterparty chain. However, only one of them,
can reach the `OPEN` state since the other will be stuck in the `TRYOPEN` state.
*/
s.Require().GreaterOrEqual(len(wasmd2Channels), 1)

wasmd2Channel = wasmd2Channels[0]
s.Require().Equal(transfertypes.PortID, wasmd2Channel.PortID)
s.Require().Equal(transfertypes.PortID, wasmd2Channel.Counterparty.PortID)
s.Require().Equal(transfertypes.Version, wasmd2Channel.Version)
s.Require().Equal(channeltypes.OPEN.String(), wasmd2Channel.State)
s.Require().Equal(channeltypes.UNORDERED.String(), wasmd2Channel.Ordering)
})

// Transfer tokens from UserA on ChainA to UserB on ChainB
s.Run("TransferTokens", func() {
/*
Transfer funds to s.UserB on ChainB from s.UserA on ChainA.
I am using the broadcaster to transfer funds to UserB to demonstrate how to use the
broadcaster, but you can also use the SendIBCTransfer method from the s.ChainA instance.
I used 200_000 gas to transfer the funds, but you can use any amount of gas you want.
*/
_, err := s.BroadcastMessages(ctx, wasmd1, s.UserA, 200_000, &transfertypes.MsgTransfer{
SourcePort: transfertypes.PortID,
SourceChannel: wasmd1Channel.ChannelID,
Token: sdk.NewInt64Coin(wasmd1.Config().Denom, 100_000),
Sender: s.UserA.FormattedAddress(),
Receiver: s.UserB.FormattedAddress(),
TimeoutTimestamp: uint64(time.Now().Add(10 * time.Minute).UnixNano()),
})
s.Require().NoError(err)

s.Require().NoError(testutil.WaitForBlocks(ctx, 5, wasmd1, wasmd2)) // Wait 5 blocks for the packet to be relayed
})

// Verify that the tokens were transferred
s.Run("VerifyTokensTransferred", func() {
chainBIBCDenom := transfertypes.ParseDenomTrace(
fmt.Sprintf("%s/%s/%s", wasmd1Channel.PortID, wasmd1Channel.ChannelID, wasmd1.Config().Denom),
).IBCDenom()

/*
Query UserB's balance
I am using the GRPCQuery to query the new user's balance to demonstrate how to use the GRPCQuery,
but you can also use the GetBalance method from the s.ChainB instance.
*/
balanceResp, err := e2esuite.GRPCQuery[banktypes.QueryBalanceResponse](ctx, wasmd2, &banktypes.QueryBalanceRequest{
Address: s.UserB.FormattedAddress(),
Denom: chainBIBCDenom,
})
s.Require().NoError(err)
s.Require().NotNil(balanceResp.Balance)

// Verify the balance
s.Require().Equal(int64(100_000), balanceResp.Balance.Amount.Int64())
})
}
57 changes: 57 additions & 0 deletions e2e/interchaintestv8/chainconfig/chain_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package chainconfig

import (
interchaintest "github.com/strangelove-ventures/interchaintest/v8"
"github.com/strangelove-ventures/interchaintest/v8/ibc"
)

var DefaultChainSpecs = []*interchaintest.ChainSpec{
// -- WASMD --
{
ChainConfig: ibc.ChainConfig{
Type: "cosmos",
Name: "wasmd-1",
ChainID: "wasmd-1",
Images: []ibc.DockerImage{
{
Repository: "cosmwasm/wasmd", // FOR LOCAL IMAGE USE: Docker Image Name
Version: "v0.50.0", // FOR LOCAL IMAGE USE: Docker Image Tag
UidGid: "1025:1025",
},
},
Bin: "wasmd",
Bech32Prefix: "wasm",
Denom: "stake",
GasPrices: "0.00stake",
GasAdjustment: 1.3,
EncodingConfig: WasmEncodingConfig(),
ModifyGenesis: defaultModifyGenesis(),
TrustingPeriod: "508h",
NoHostMount: false,
},
},
// -- WASMD --
{
ChainConfig: ibc.ChainConfig{
Type: "cosmos",
Name: "wasmd-2",
ChainID: "wasmd-2",
Images: []ibc.DockerImage{
{
Repository: "cosmwasm/wasmd", // FOR LOCAL IMAGE USE: Docker Image Name
Version: "v0.50.0", // FOR LOCAL IMAGE USE: Docker Image Tag
UidGid: "1025:1025",
},
},
Bin: "wasmd",
Bech32Prefix: "wasm",
Denom: "stake",
GasPrices: "0.00stake",
GasAdjustment: 1.3,
EncodingConfig: WasmEncodingConfig(),
ModifyGenesis: defaultModifyGenesis(),
TrustingPeriod: "508h",
NoHostMount: false,
},
},
}
Loading

0 comments on commit 512ef63

Please sign in to comment.