Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tests: add option to dump genesis files in E2E tests #6100

Merged
merged 38 commits into from
Apr 11, 2024
Merged
Show file tree
Hide file tree
Changes from 36 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
65a41e2
First test to export genesis debug files
bznein Apr 5, 2024
c6266ac
Allow for configuration on chainName and genesis debug info
bznein Apr 6, 2024
9899bf4
Better path handling - and linting
bznein Apr 6, 2024
7f44b73
Extend config to everything
bznein Apr 6, 2024
a324846
Merge branch 'main' into e2e-genesis
bznein Apr 6, 2024
f55d53f
Linter
bznein Apr 6, 2024
f8f097b
Default for chain names.
bznein Apr 6, 2024
934e2f0
Revert local hack
bznein Apr 6, 2024
fe24e23
Linter
bznein Apr 6, 2024
8434b70
Default genesis chain name
bznein Apr 6, 2024
8a02d35
Use genesischainame when validating
bznein Apr 6, 2024
b9d9841
Added comment.
bznein Apr 6, 2024
3a78f8c
Comments
bznein Apr 6, 2024
06795b2
Use s.Require().NoError() instead of s.Fail()
bznein Apr 6, 2024
1cd3073
Rename import
bznein Apr 6, 2024
64b98a6
Merge branch 'main' into e2e-genesis
bznein Apr 8, 2024
c8cc6b3
Moved init logic into SetupTest
Apr 8, 2024
a46ca74
Moved init logic into SetupTest
Apr 8, 2024
d37b961
Missed one revert
bznein Apr 8, 2024
3fb3d57
Merge branch 'main' into e2e-genesis
bznein Apr 8, 2024
0261a22
Refactoring.
bznein Apr 8, 2024
63db86c
PR Feedback
bznein Apr 8, 2024
a6a6322
Merge branch 'main' into e2e-genesis
chatton Apr 8, 2024
ecd0186
Merge branch 'main' into e2e-genesis
bznein Apr 8, 2024
7d4b8d5
Small refactoring.
bznein Apr 8, 2024
e6f5512
Fix typo in comment
bznein Apr 8, 2024
7c16d6b
Merge branch 'main' into e2e-genesis
bznein Apr 9, 2024
495964b
Merge branch 'main' into e2e-genesis
bznein Apr 9, 2024
d39df3b
Merge branch 'main' into e2e-genesis
bznein Apr 9, 2024
ed2fcc9
Merge branch 'main' into e2e-genesis
chatton Apr 9, 2024
c1a77c5
Merge branch 'main' into e2e-genesis
bznein Apr 9, 2024
d6bbd8e
Merge branch 'main' into e2e-genesis
bznein Apr 9, 2024
eba5cbc
Merge branch 'main' into e2e-genesis
bznein Apr 10, 2024
35e3f74
Rename path variable and un-alias path import.
bznein Apr 10, 2024
e303ca0
Fix missing rename
bznein Apr 10, 2024
c199f76
Merge branch 'main' into e2e-genesis
bznein Apr 10, 2024
0846468
Update e2e/testsuite/testsuite.go
bznein Apr 11, 2024
f70c7d9
Unexport method.
bznein Apr 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions e2e/internal/directories/directories.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package directories

import (
"fmt"
"os"
"path"
"strings"
"testing"
)

const (
e2eDir = "e2e"

// DefaultGenesisExportPath is the default path to which Genesis debug files will be exported to.
DefaultGenesisExportPath = "diagnostics/genesis.json"
)

// E2E finds the e2e directory above the test.
func E2E(t *testing.T) (string, error) {
t.Helper()

wd, err := os.Getwd()
if err != nil {
return "", err
}

const maxAttempts = 100
count := 0
for ; !strings.HasSuffix(wd, e2eDir) || count > maxAttempts; wd = path.Dir(wd) {
count++
}

// arbitrary value to avoid getting stuck in an infinite loop if this is called
// in a context where the e2e directory does not exist.
if count > maxAttempts {
return "", fmt.Errorf("unable to find e2e directory after %d tries", maxAttempts)
}
chatton marked this conversation as resolved.
Show resolved Hide resolved

return wd, nil
}
28 changes: 2 additions & 26 deletions e2e/testsuite/diagnostics/diagnostics.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ import (
dockerclient "github.com/docker/docker/client"

"github.com/cosmos/ibc-go/e2e/dockerutil"
"github.com/cosmos/ibc-go/e2e/internal/directories"
)

const (
dockerInspectFileName = "docker-inspect.json"
e2eDir = "e2e"
defaultFilePerm = 0o750
)

Expand All @@ -37,7 +37,7 @@ func Collect(t *testing.T, dc *dockerclient.Client, debugModeEnabled bool, chain
t.Logf("writing logs for test: %s", t.Name())

ctx := context.TODO()
e2eDir, err := getE2EDir(t)
e2eDir, err := directories.E2E(t)
if err != nil {
t.Logf("failed finding log directory: %s", err)
return
Expand Down Expand Up @@ -161,27 +161,3 @@ func relayerDiagnosticAbsoluteFilePaths() []string {
"/home/hermes/.hermes/config.toml",
}
}

// getE2EDir finds the e2e directory above the test.
func getE2EDir(t *testing.T) (string, error) {
t.Helper()

wd, err := os.Getwd()
if err != nil {
return "", err
}

const maxAttempts = 100
count := 0
for ; !strings.HasSuffix(wd, e2eDir) || count > maxAttempts; wd = ospath.Dir(wd) {
count++
}

// arbitrary value to avoid getting stuck in an infinite loop if this is called
// in a context where the e2e directory does not exist.
if count > maxAttempts {
return "", fmt.Errorf("unable to find e2e directory after %d tries", maxAttempts)
}

return wd, nil
}
71 changes: 69 additions & 2 deletions e2e/testsuite/testconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ const (
defaultConfigFileName = ".ibc-go-e2e-config.yaml"
)

// defaultChainNames contains the default name for chainA and chainB.
var defaultChainNames = []string{"simapp-a", "simapp-b"}

func getChainImage(binary string) string {
if binary == "" {
binary = defaultBinary
Expand Down Expand Up @@ -103,6 +106,10 @@ func (tc TestConfig) Validate() error {
if err := tc.validateRelayers(); err != nil {
return fmt.Errorf("invalid relayer configuration: %w", err)
}

if err := tc.validateGenesisDebugConfig(); err != nil {
return fmt.Errorf("invalid Genesis debug configuration: %w", err)
}
return nil
}

Expand Down Expand Up @@ -163,6 +170,31 @@ func (tc TestConfig) validateRelayers() error {
return nil
}

// GetChainIndex returns the index of the chain with the given name, if it
// exists.
func (tc TestConfig) GetChainIndex(name string) (int, error) {
for i := range tc.ChainConfigs {
chainName := tc.GetChainName(i)
if chainName == name {
return i, nil
}
}
return -1, fmt.Errorf("chain %s not found in chain configs", name)
}

// validateGenesisDebugConfig validates configuration of Genesis debug options/
func (tc TestConfig) validateGenesisDebugConfig() error {
cfg := tc.DebugConfig.GenesisDebug
if !cfg.DumpGenesisDebugInfo {
return nil
}

// Verify that the provided chain exists in our config
_, err := tc.GetChainIndex(tc.GetGenesisChainName())

return err
}

// GetActiveRelayerConfig returns the currently specified relayer config.
func (tc TestConfig) GetActiveRelayerConfig() *relayer.Config {
for _, r := range tc.RelayerConfigs {
Expand Down Expand Up @@ -207,6 +239,26 @@ func (tc TestConfig) GetChainBID() string {
return "chainB-1"
}

// GetChainName returns the name of the chain given an index.
func (tc TestConfig) GetChainName(idx int) string {
// Assumes that only valid indices are provided. We do the same in several other places.
chainName := tc.ChainConfigs[idx].Name
if chainName == "" {
chainName = defaultChainNames[idx]
}
return chainName
}

// GetGenesisChainName returns the name of the chain for which to dump Genesis files.
// If no chain is provided, it uses the default one (chainA).
func (tc TestConfig) GetGenesisChainName() string {
name := tc.DebugConfig.GenesisDebug.ChainName
if name == "" {
return tc.GetChainName(0)
}
return name
}

// UpgradeConfig holds values relevant to upgrade tests.
type UpgradeConfig struct {
PlanName string `yaml:"planName"`
Expand All @@ -216,6 +268,7 @@ type UpgradeConfig struct {
// ChainConfig holds information about an individual chain used in the tests.
type ChainConfig struct {
ChainID string `yaml:"chainId"`
Name string `yaml:"name"`
Image string `yaml:"image"`
Tag string `yaml:"tag"`
Binary string `yaml:"binary"`
Expand All @@ -227,9 +280,23 @@ type CometBFTConfig struct {
LogLevel string `yaml:"logLevel"`
}

type GenesisDebugConfig struct {
// DumpGenesisDebugInfo enables the output of Genesis debug files.
DumpGenesisDebugInfo bool `yaml:"dumpGenesisDebugInfo"`

// ExportFilePath specifies which path to export Genesis debug files to.
ExportFilePath string `yaml:"filePath"`

// ChainName represent which chain to get Genesis debug info for.
ChainName string `yaml:"chainName"`
}

type DebugConfig struct {
// DumpLogs forces the logs to be collected before removing test containers.
DumpLogs bool `yaml:"dumpLogs"`

// GenesisDebug contains debug information specific to Genesis.
GenesisDebug GenesisDebugConfig `yaml:"genesis"`
}

// LoadConfig attempts to load a atest configuration from the default file path.
Expand Down Expand Up @@ -471,8 +538,8 @@ type ChainOptionConfiguration func(options *ChainOptions)
func DefaultChainOptions() ChainOptions {
tc := LoadConfig()

chainACfg := newDefaultSimappConfig(tc.ChainConfigs[0], "simapp-a", tc.GetChainAID(), "atoma", tc.CometBFTConfig)
chainBCfg := newDefaultSimappConfig(tc.ChainConfigs[1], "simapp-b", tc.GetChainBID(), "atomb", tc.CometBFTConfig)
chainACfg := newDefaultSimappConfig(tc.ChainConfigs[0], tc.GetChainName(0), tc.GetChainAID(), "atoma", tc.CometBFTConfig)
chainBCfg := newDefaultSimappConfig(tc.ChainConfigs[1], tc.GetChainName(1), tc.GetChainBID(), "atomb", tc.CometBFTConfig)

chainAVal, chainAFn := getValidatorsAndFullNodes(0)
chainBVal, chainBFn := getValidatorsAndFullNodes(1)
Expand Down
60 changes: 53 additions & 7 deletions e2e/testsuite/testsuite.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"context"
"errors"
"fmt"
"os"
"path"
"strings"

dockerclient "github.com/docker/docker/client"
Expand All @@ -19,6 +21,7 @@ import (

govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"

"github.com/cosmos/ibc-go/e2e/internal/directories"
"github.com/cosmos/ibc-go/e2e/relayer"
"github.com/cosmos/ibc-go/e2e/testsuite/diagnostics"
feetypes "github.com/cosmos/ibc-go/v8/modules/apps/29-fee/types"
Expand Down Expand Up @@ -67,6 +70,49 @@ func newPath(chainA, chainB ibc.Chain) pathPair {
}
}

func (s *E2ETestSuite) SetupTest() {
s.ConfigureGenesisDebugExport()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this basically means we'll run these per test yea? Is this expected behavior?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, basically just a way to make sure that env vars get set for each specific test based on the config.

}

// ConfigureGenesisDebugExport sets, if needed, env variables to enable exporting of Genesis debug files.
func (s *E2ETestSuite) ConfigureGenesisDebugExport() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looking now, I think we can make this unexported actually, should never have as need for this outside of this testsuite.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

tc := LoadConfig()
t := s.T()
cfg := tc.DebugConfig.GenesisDebug
if !cfg.DumpGenesisDebugInfo {
return
}

// Set the export path.
exportPath := cfg.ExportFilePath

// If no path is provided, use the default (e2e/diagnostics/genesis.json).
if exportPath == "" {
e2eDir, err := directories.E2E(t)
s.Require().NoError(err, "can't get e2edir")
exportPath = path.Join(e2eDir, directories.DefaultGenesisExportPath)
}

if !path.IsAbs(exportPath) {
wd, err := os.Getwd()
s.Require().NoError(err, "can't get working directory")
exportPath = path.Join(wd, exportPath)
}

// This env variables are set by the interchain test code:
// https://github.com/strangelove-ventures/interchaintest/blob/7aa0fd6487f76238ab44231fdaebc34627bc5990/chain/cosmos/cosmos_chain.go#L1007-L1008
t.Setenv("EXPORT_GENESIS_FILE_PATH", exportPath)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe add a link to interchaintest code for where this is used


chainName := tc.GetGenesisChainName()
chainIdx, err := tc.GetChainIndex(chainName)
s.Require().NoError(err)

// Interchaintest adds a suffix (https://github.com/strangelove-ven pftures/interchaintest/blob/a3f4c7bcccf1925ffa6dc793a298f15497919a38/chainspec.go#L125)
bznein marked this conversation as resolved.
Show resolved Hide resolved
// to the chain name, so we need to do the same.
genesisChainName := fmt.Sprintf("%s-%d", chainName, chainIdx+1)
t.Setenv("EXPORT_GENESIS_CHAIN", genesisChainName)
}

// 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) {
Expand Down Expand Up @@ -173,9 +219,9 @@ func (s *E2ETestSuite) SetupSingleChain(ctx context.Context) ibc.Chain {

// generatePathName generates the path name using the test suites name
func (s *E2ETestSuite) generatePathName() string {
path := s.GetPathName(s.pathNameIndex)
pathName := s.GetPathName(s.pathNameIndex)
s.pathNameIndex++
return path
return pathName
}

// GetPathName returns the name of a path at a specific index. This can be used in tests
Expand Down Expand Up @@ -219,9 +265,9 @@ func (s *E2ETestSuite) GetChains(chainOpts ...ChainOptionConfiguration) (ibc.Cha
s.paths = map[string]pathPair{}
}

path, ok := s.paths[s.T().Name()]
suitePath, ok := s.paths[s.T().Name()]
if ok {
return path.chainA, path.chainB
return suitePath.chainA, suitePath.chainB
}

chainOptions := DefaultChainOptions()
Expand All @@ -230,8 +276,8 @@ func (s *E2ETestSuite) GetChains(chainOpts ...ChainOptionConfiguration) (ibc.Cha
}

chainA, chainB := s.createChains(chainOptions)
path = newPath(chainA, chainB)
s.paths[s.T().Name()] = path
suitePath = newPath(chainA, chainB)
s.paths[s.T().Name()] = suitePath

if s.proposalIDs == nil {
s.proposalIDs = map[string]uint64{}
Expand All @@ -240,7 +286,7 @@ func (s *E2ETestSuite) GetChains(chainOpts ...ChainOptionConfiguration) (ibc.Cha
s.proposalIDs[chainA.Config().ChainID] = 1
s.proposalIDs[chainB.Config().ChainID] = 1

return path.chainA, path.chainB
return suitePath.chainA, suitePath.chainB
}

// GetRelayerWallets returns the ibcrelayer wallets associated with the chains.
Expand Down
Loading