From e8e57602e939529af51c05636653111ee61e7da6 Mon Sep 17 00:00:00 2001 From: Cian Hatton Date: Wed, 8 Mar 2023 15:38:19 +0000 Subject: [PATCH 01/22] support configuration file for e2e tests --- e2e/README.md | 8 +- e2e/relayer/relayer.go | 8 +- e2e/sample.config.json | 25 +++++ e2e/testconfig/testconfig.go | 165 ++++++++++++++++++++++------- e2e/tests/upgrades/upgrade_test.go | 20 ++-- e2e/testsuite/testsuite.go | 21 ++-- 6 files changed, 190 insertions(+), 57 deletions(-) create mode 100644 e2e/sample.config.json diff --git a/e2e/README.md b/e2e/README.md index d6a03e4485c..ab1e9ed103d 100644 --- a/e2e/README.md +++ b/e2e/README.md @@ -37,7 +37,13 @@ be quite common in most tests. Tests can be run using a Makefile target under the e2e directory. `e2e/Makefile` -There are several envinronment variables that alter the behaviour of the make target. +The tests can be configured using a configuration file or environment variables. + +See [the example](./sample.config.json) to get started. The default location the tests look is `~/.ibc-go-e2e-config.json` +But this can be specified directly using the `E2E_CONFIG_PATH` environment variable. + +There are several environment variables that alter the behaviour of the make target which will override any +options specified in your config file. | Environment Variable | Description | Default Value | |----------------------|-------------------------------------------|---------------| diff --git a/e2e/relayer/relayer.go b/e2e/relayer/relayer.go index 7467a9f47f3..e40f0e388d9 100644 --- a/e2e/relayer/relayer.go +++ b/e2e/relayer/relayer.go @@ -16,15 +16,17 @@ const ( Hermes = "hermes" cosmosRelayerRepository = "ghcr.io/cosmos/relayer" - cosmosRelayerUser = "100:1000" // docker run -it --rm --entrypoint echo ghcr.io/cosmos/relayer "$(id -u):$(id -g)" + cosmosRelayerUser = "100:1000" ) // Config holds configuration values for the relayer used in the tests. type Config struct { // Tag is the tag used for the relayer image. - Tag string + Tag string `json:"tag"` // Type specifies the type of relayer that this is. - Type string + Type string `json:"type"` + // Image is the image that should be used for the relayer. + Image string `json:"image"` } // New returns an implementation of ibc.Relayer depending on the provided RelayerType. diff --git a/e2e/sample.config.json b/e2e/sample.config.json new file mode 100644 index 00000000000..138e2e362fb --- /dev/null +++ b/e2e/sample.config.json @@ -0,0 +1,25 @@ +{ + "chains":[ + { + "chainId":"chain-a", + "numValidators":1, + "numFullNodes":0, + "image":"ghcr.io/cosmos/ibc-go-simd", + "tag":"main", + "binary":"simd" + }, + { + "chainId":"chain-b", + "numValidators":1, + "numFullNodes":0, + "image":"ghcr.io/cosmos/ibc-go-simd", + "tag":"main", + "binary":"simd" + } + ], + "relayer":{ + "type":"rly", + "image":"ghcr.io/cosmos/relayer", + "tag":"main" + } +} diff --git a/e2e/testconfig/testconfig.go b/e2e/testconfig/testconfig.go index 48261fedce9..39159c8b3ef 100644 --- a/e2e/testconfig/testconfig.go +++ b/e2e/testconfig/testconfig.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "os" + "path" "strings" tmjson "github.com/cometbft/cometbft/libs/json" @@ -41,6 +42,8 @@ const ( ChainUpgradeTagEnv = "CHAIN_UPGRADE_TAG" // ChainUpgradePlanEnv specifies the upgrade plan name ChainUpgradePlanEnv = "CHAIN_UPGRADE_PLAN" + // E2EConfigFilePath allows you to specify a custom path for the config file to be used. + E2EConfigFilePath = "E2E_CONFIG_PATH" // defaultBinary is the default binary that will be used by the chains. defaultBinary = "simd" @@ -51,6 +54,9 @@ const ( defaultChainTag = "main" // defaultRelayerType is the default relayer that will be used if none is specified. defaultRelayerType = relayer.Rly + // defaultConfigFileName is the default filename for the config file that can be used to configure + // e2e tests. See sample.config.json as an example for what this should look like. + defaultConfigFileName = ".ibc-go-e2e-config.json" ) func getChainImage(binary string) string { @@ -60,24 +66,99 @@ func getChainImage(binary string) string { return fmt.Sprintf("ghcr.io/cosmos/ibc-go-%s", binary) } -// TestConfig holds various fields used in the E2E tests. +// TestConfig holds configuration used throughout the different e2e tests. type TestConfig struct { - ChainAConfig ChainConfig - ChainBConfig ChainConfig - RelayerConfig relayer.Config - UpgradeTag string - UpgradePlanName string + ChainConfigs []ChainConfig `json:"chains"` + RelayerConfig relayer.Config `json:"relayer"` + UpgradeConfig UpgradeConfig `json:"upgrade"` +} + +// UpgradeConfig holds values relevant to upgrade tests. +type UpgradeConfig struct { + PlanName string `json:"planName"` + Tag string `json:"tag"` } // ChainConfig holds information about an individual chain used in the tests. type ChainConfig struct { - Image string - Tag string - Binary string + ChainID string `json:"chainId"` + Image string `json:"image"` + Tag string `json:"tag"` + Binary string `json:"binary"` + NumValidators int `json:"numValidators"` + NumFullNodes int `json:"numFullNodes"` +} + +// LoadConfig attempts to load a atest configuration from the default file path. +// if any environment variables are specified, they will take precedence over the individual configuration +// options. +func LoadConfig() TestConfig { + fileTc, foundFile := fromFile() + envTc := fromEnv() + return mergeTestConfigs(fileTc, envTc, foundFile) +} + +// fromFile returns a TestConfig from a json file and a boolean indicating if the file was found. +func fromFile() (TestConfig, bool) { + var tc TestConfig + bz, err := os.ReadFile(getConfigFilePath()) + if err != nil { + return TestConfig{}, false + } + + if err := json.Unmarshal(bz, &tc); err != nil { + panic(err) + } + + return tc, true +} + +// mergeTestConfigs takes a config made from a file and a config made from environment variables +// and returns a new test config with all environment variable options taking precedence. +func mergeTestConfigs(fromFile, fromEnv TestConfig, foundFile bool) TestConfig { + if !foundFile { + return fromEnv + } + + for i, cfg := range fromEnv.ChainConfigs { + if cfg.Image != "" { + fromFile.ChainConfigs[i].Image = cfg.Image + } + + if cfg.Tag != "" { + fromFile.ChainConfigs[i].Tag = cfg.Tag + } + + if cfg.Binary != "" { + fromFile.ChainConfigs[i].Binary = cfg.Binary + } + } + + if fromEnv.RelayerConfig.Tag != "" { + fromFile.RelayerConfig.Tag = fromEnv.RelayerConfig.Tag + } + + if fromEnv.RelayerConfig.Image != "" { + fromFile.RelayerConfig.Image = fromEnv.RelayerConfig.Image + } + + if fromEnv.RelayerConfig.Type != "" { + fromFile.RelayerConfig.Type = fromEnv.RelayerConfig.Type + } + + if fromEnv.UpgradeConfig.PlanName != "" { + fromFile.UpgradeConfig.PlanName = fromEnv.UpgradeConfig.PlanName + } + + if fromEnv.UpgradeConfig.Tag != "" { + fromFile.UpgradeConfig.Tag = fromEnv.UpgradeConfig.Tag + } + + return fromFile } -// FromEnv returns a TestConfig constructed from environment variables. -func FromEnv() TestConfig { +// fromEnv returns a TestConfig constructed from environment variables. +func fromEnv() TestConfig { chainBinary, ok := os.LookupEnv(ChainBinaryEnv) if !ok { chainBinary = defaultBinary @@ -111,24 +192,42 @@ func FromEnv() TestConfig { } return TestConfig{ - ChainAConfig: ChainConfig{ - Image: chainAImage, - Tag: chainATag, - Binary: chainBinary, + ChainConfigs: []ChainConfig{ + { + Image: chainAImage, + Tag: chainATag, + Binary: chainBinary, + }, + { + Image: chainBImage, + Tag: chainBTag, + Binary: chainBinary, + }, }, - ChainBConfig: ChainConfig{ - Image: chainBImage, - Tag: chainBTag, - Binary: chainBinary, + UpgradeConfig: UpgradeConfig{ + PlanName: upgradePlan, + Tag: upgradeTag, }, - UpgradeTag: upgradeTag, - UpgradePlanName: upgradePlan, - RelayerConfig: GetRelayerConfigFromEnv(), + RelayerConfig: getRelayerConfigFromEnv(), } } -// GetRelayerConfigFromEnv returns the RelayerConfig from present environment variables. -func GetRelayerConfigFromEnv() relayer.Config { +// getConfigFilePath returns the absolute path where the e2e config file should be. +func getConfigFilePath() string { + absoluteConfigPath := os.Getenv(E2EConfigFilePath) + if absoluteConfigPath != "" { + return absoluteConfigPath + } + + homeDir, err := os.UserHomeDir() + if err != nil { + panic(err) + } + return path.Join(homeDir, defaultConfigFileName) +} + +// getRelayerConfigFromEnv returns the RelayerConfig from present environment variables. +func getRelayerConfigFromEnv() relayer.Config { relayerType := strings.TrimSpace(os.Getenv(RelayerTypeEnv)) if relayerType == "" { relayerType = defaultRelayerType @@ -150,19 +249,11 @@ func GetRelayerConfigFromEnv() relayer.Config { } func GetChainATag() string { - chainATag, ok := os.LookupEnv(ChainATagEnv) - if !ok { - panic(fmt.Sprintf("no environment variable specified for %s", ChainATagEnv)) - } - return chainATag + return LoadConfig().ChainConfigs[0].Tag } func GetChainBTag() string { - chainBTag, ok := os.LookupEnv(ChainBTagEnv) - if !ok { - return GetChainATag() - } - return chainBTag + return LoadConfig().ChainConfigs[1].Tag } // IsCI returns true if the tests are running in CI, false is returned @@ -186,9 +277,9 @@ type ChainOptionConfiguration func(options *ChainOptions) // DefaultChainOptions returns the default configuration for the chains. // These options can be configured by passing configuration functions to E2ETestSuite.GetChains. func DefaultChainOptions() ChainOptions { - tc := FromEnv() - chainACfg := newDefaultSimappConfig(tc.ChainAConfig, "simapp-a", "chain-a", "atoma") - chainBCfg := newDefaultSimappConfig(tc.ChainBConfig, "simapp-b", "chain-b", "atomb") + tc := LoadConfig() + chainACfg := newDefaultSimappConfig(tc.ChainConfigs[0], "simapp-a", tc.ChainConfigs[0].ChainID, "atoma") + chainBCfg := newDefaultSimappConfig(tc.ChainConfigs[1], "simapp-b", tc.ChainConfigs[1].ChainID, "atomb") return ChainOptions{ ChainAConfig: &chainACfg, ChainBConfig: &chainBCfg, diff --git a/e2e/tests/upgrades/upgrade_test.go b/e2e/tests/upgrades/upgrade_test.go index c8500e830dc..850205e088b 100644 --- a/e2e/tests/upgrades/upgrade_test.go +++ b/e2e/tests/upgrades/upgrade_test.go @@ -36,8 +36,8 @@ const ( ) func TestUpgradeTestSuite(t *testing.T) { - testCfg := testconfig.FromEnv() - if testCfg.UpgradeTag == "" || testCfg.UpgradePlanName == "" { + testCfg := testconfig.LoadConfig() + if testCfg.UpgradeConfig.Tag == "" || testCfg.UpgradeConfig.PlanName == "" { t.Fatal("upgrade tag and upgrade plan name must be provided in test configuration") } @@ -95,7 +95,7 @@ func (s *UpgradeTestSuite) UpgradeChain(ctx context.Context, chain *cosmos.Cosmo func (s *UpgradeTestSuite) TestIBCChainUpgrade() { t := s.T() - testCfg := testconfig.FromEnv() + testCfg := testconfig.LoadConfig() ctx := context.Background() relayer, channelA := s.SetupChainsRelayerAndChannel(ctx) @@ -152,7 +152,7 @@ func (s *UpgradeTestSuite) TestIBCChainUpgrade() { s.Require().NoError(test.WaitForBlocks(ctx, 5, chainA, chainB), "failed to wait for blocks") t.Run("upgrade chainA", func(t *testing.T) { - s.UpgradeChain(ctx, chainA, chainAUpgradeProposalWallet, testCfg.UpgradePlanName, testCfg.ChainAConfig.Tag, testCfg.UpgradeTag) + s.UpgradeChain(ctx, chainA, chainAUpgradeProposalWallet, testCfg.UpgradeConfig.PlanName, testCfg.ChainConfigs[0].Tag, testCfg.UpgradeConfig.Tag) }) t.Run("restart relayer", func(t *testing.T) { @@ -228,10 +228,10 @@ func (s *UpgradeTestSuite) TestChainUpgrade() { }) t.Run("upgrade chain", func(t *testing.T) { - testCfg := testconfig.FromEnv() + testCfg := testconfig.LoadConfig() proposerWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) - s.UpgradeChain(ctx, chain, proposerWallet, testCfg.UpgradePlanName, testCfg.ChainAConfig.Tag, testCfg.UpgradeTag) + s.UpgradeChain(ctx, chain, proposerWallet, testCfg.UpgradeConfig.PlanName, testCfg.ChainConfigs[0].Tag, testCfg.UpgradeConfig.Tag) }) t.Run("send funds to test wallet", func(t *testing.T) { @@ -254,7 +254,7 @@ func (s *UpgradeTestSuite) TestChainUpgrade() { func (s *UpgradeTestSuite) TestV5ToV6ChainUpgrade() { t := s.T() - testCfg := testconfig.FromEnv() + testCfg := testconfig.LoadConfig() ctx := context.Background() relayer, _ := s.SetupChainsRelayerAndChannel(ctx) @@ -352,7 +352,7 @@ func (s *UpgradeTestSuite) TestV5ToV6ChainUpgrade() { s.Require().NoError(test.WaitForBlocks(ctx, 5, chainA, chainB), "failed to wait for blocks") t.Run("upgrade chainA", func(t *testing.T) { - s.UpgradeChain(ctx, chainA, chainAUpgradeProposalWallet, testCfg.UpgradePlanName, testCfg.ChainAConfig.Tag, testCfg.UpgradeTag) + s.UpgradeChain(ctx, chainA, chainAUpgradeProposalWallet, testCfg.UpgradeConfig.PlanName, testCfg.ChainConfigs[0].Tag, testCfg.UpgradeConfig.Tag) }) t.Run("restart relayer", func(t *testing.T) { @@ -457,7 +457,7 @@ func (s *UpgradeTestSuite) TestV5ToV6ChainUpgrade() { // can be sent before and after the upgrade without issue func (s *UpgradeTestSuite) TestV6ToV7ChainUpgrade() { t := s.T() - testCfg := testconfig.FromEnv() + testCfg := testconfig.LoadConfig() ctx := context.Background() relayer, channelA := s.SetupChainsRelayerAndChannel(ctx) @@ -568,7 +568,7 @@ func (s *UpgradeTestSuite) TestV6ToV7ChainUpgrade() { chainAUpgradeProposalWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) t.Run("upgrade chainA", func(t *testing.T) { - s.UpgradeChain(ctx, chainA, chainAUpgradeProposalWallet, testCfg.UpgradePlanName, testCfg.ChainAConfig.Tag, testCfg.UpgradeTag) + s.UpgradeChain(ctx, chainA, chainAUpgradeProposalWallet,testCfg.UpgradeConfig.PlanName, testCfg.ChainConfigs[0].Tag, testCfg.UpgradeConfig.Tag) }) t.Run("check that the tendermint clients are active again after upgrade", func(t *testing.T) { diff --git a/e2e/testsuite/testsuite.go b/e2e/testsuite/testsuite.go index 965e4177c86..5e20414fde8 100644 --- a/e2e/testsuite/testsuite.go +++ b/e2e/testsuite/testsuite.go @@ -123,7 +123,7 @@ func (s *E2ETestSuite) GetRelayerUsers(ctx context.Context, chainOpts ...testcon func (s *E2ETestSuite) SetupChainsRelayerAndChannel(ctx context.Context, channelOpts ...func(*ibc.CreateChannelOptions)) (ibc.Relayer, ibc.ChannelOutput) { chainA, chainB := s.GetChains() - r := relayer.New(s.T(), testconfig.FromEnv().RelayerConfig, s.logger, s.DockerClient, s.network) + r := relayer.New(s.T(), testconfig.LoadConfig().RelayerConfig, s.logger, s.DockerClient, s.network) pathName := s.generatePathName() @@ -451,9 +451,9 @@ func (s *E2ETestSuite) createCosmosChains(chainOptions testconfig.ChainOptions) logger := zaptest.NewLogger(t) - numValidators, numFullNodes := getValidatorsAndFullNodes() - + numValidators, numFullNodes := getValidatorsAndFullNodes(0) chainA := cosmos.NewCosmosChain(t.Name(), *chainOptions.ChainAConfig, numValidators, numFullNodes, logger) + numValidators, numFullNodes = getValidatorsAndFullNodes(1) chainB := cosmos.NewCosmosChain(t.Name(), *chainOptions.ChainBConfig, numValidators, numFullNodes, logger) // this is intentionally called after the interchaintest.DockerSetup function. The above function registers a @@ -604,11 +604,20 @@ func GetIBCToken(fullTokenDenom string, portID, channelID string) transfertypes. } // getValidatorsAndFullNodes returns the number of validators and full nodes respectively that should be used for -// the test. If the test is running in CI, more nodes are used, when running locally a single node is used to +// the test. If the test is running in CI, more nodes are used, when running locally a single node is used by default to // use less resources and allow the tests to run faster. -func getValidatorsAndFullNodes() (int, int) { +// both the number of validators and full nodes can be overwritten in a config file. +func getValidatorsAndFullNodes(chainIdx int) (int, int) { if testconfig.IsCI() { return 4, 1 } - return 1, 0 + numFullNodes, numValidators := 1, 0 + tc := testconfig.LoadConfig() + if tc.ChainConfigs[chainIdx].NumFullNodes > 0 { + numFullNodes = tc.ChainConfigs[chainIdx].NumFullNodes + } + if tc.ChainConfigs[chainIdx].NumValidators > 0 { + numValidators = tc.ChainConfigs[chainIdx].NumValidators + } + return numValidators, numFullNodes } From 0d6ad8503f3b57e48234984962dde06cfdc92d2d Mon Sep 17 00:00:00 2001 From: Cian Hatton Date: Wed, 8 Mar 2023 15:40:41 +0000 Subject: [PATCH 02/22] return chain a tag if b tag is not specified --- e2e/testconfig/testconfig.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/e2e/testconfig/testconfig.go b/e2e/testconfig/testconfig.go index 39159c8b3ef..37290eced95 100644 --- a/e2e/testconfig/testconfig.go +++ b/e2e/testconfig/testconfig.go @@ -253,7 +253,10 @@ func GetChainATag() string { } func GetChainBTag() string { - return LoadConfig().ChainConfigs[1].Tag + if chainBTag := LoadConfig().ChainConfigs[1].Tag; chainBTag != "" { + return chainBTag + } + return GetChainATag() } // IsCI returns true if the tests are running in CI, false is returned From 15067843213bff04f47e22184bc81a12ee2331cf Mon Sep 17 00:00:00 2001 From: Cian Hatton Date: Wed, 8 Mar 2023 15:51:02 +0000 Subject: [PATCH 03/22] apply env var overrides correctly --- e2e/testconfig/testconfig.go | 42 ++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/e2e/testconfig/testconfig.go b/e2e/testconfig/testconfig.go index 37290eced95..55c970115f1 100644 --- a/e2e/testconfig/testconfig.go +++ b/e2e/testconfig/testconfig.go @@ -95,7 +95,7 @@ type ChainConfig struct { func LoadConfig() TestConfig { fileTc, foundFile := fromFile() envTc := fromEnv() - return mergeTestConfigs(fileTc, envTc, foundFile) + return applyEnvironmentVariableOverrides(fileTc, envTc, foundFile) } // fromFile returns a TestConfig from a json file and a boolean indicating if the file was found. @@ -113,44 +113,44 @@ func fromFile() (TestConfig, bool) { return tc, true } -// mergeTestConfigs takes a config made from a file and a config made from environment variables -// and returns a new test config with all environment variable options taking precedence. -func mergeTestConfigs(fromFile, fromEnv TestConfig, foundFile bool) TestConfig { +// applyEnvironmentVariableOverrides applies all environment variable changes to the config +// loaded from a file. +func applyEnvironmentVariableOverrides(fromFile, fromEnv TestConfig, foundFile bool) TestConfig { if !foundFile { return fromEnv } - for i, cfg := range fromEnv.ChainConfigs { - if cfg.Image != "" { - fromFile.ChainConfigs[i].Image = cfg.Image - } + if os.Getenv(ChainATagEnv) != "" { + fromFile.ChainConfigs[0].Tag = fromEnv.ChainConfigs[0].Tag + } - if cfg.Tag != "" { - fromFile.ChainConfigs[i].Tag = cfg.Tag - } + if os.Getenv(ChainBTagEnv) != "" { + fromFile.ChainConfigs[1].Tag = fromEnv.ChainConfigs[1].Tag + } - if cfg.Binary != "" { - fromFile.ChainConfigs[i].Binary = cfg.Binary - } + if os.Getenv(ChainBinaryEnv) != "" { + fromFile.ChainConfigs[0].Binary = fromEnv.ChainConfigs[0].Binary + fromFile.ChainConfigs[1].Binary = fromEnv.ChainConfigs[0].Binary } - if fromEnv.RelayerConfig.Tag != "" { - fromFile.RelayerConfig.Tag = fromEnv.RelayerConfig.Tag + if os.Getenv(ChainImageEnv) != "" { + fromFile.ChainConfigs[0].Image = fromEnv.ChainConfigs[0].Image + fromFile.ChainConfigs[1].Image = fromEnv.ChainConfigs[0].Image } - if fromEnv.RelayerConfig.Image != "" { - fromFile.RelayerConfig.Image = fromEnv.RelayerConfig.Image + if os.Getenv(RelayerTagEnv) != "" { + fromFile.RelayerConfig.Tag = fromEnv.RelayerConfig.Tag } - if fromEnv.RelayerConfig.Type != "" { + if os.Getenv(RelayerTypeEnv) != "" { fromFile.RelayerConfig.Type = fromEnv.RelayerConfig.Type } - if fromEnv.UpgradeConfig.PlanName != "" { + if os.Getenv(ChainUpgradePlanEnv) != "" { fromFile.UpgradeConfig.PlanName = fromEnv.UpgradeConfig.PlanName } - if fromEnv.UpgradeConfig.Tag != "" { + if os.Getenv(ChainUpgradeTagEnv) != "" { fromFile.UpgradeConfig.Tag = fromEnv.UpgradeConfig.Tag } From cb5453bc617802e3eb93160789f0bfd13c63d5a1 Mon Sep 17 00:00:00 2001 From: Cian Hatton Date: Wed, 8 Mar 2023 16:06:11 +0000 Subject: [PATCH 04/22] correctly specify chain IDs --- e2e/testconfig/testconfig.go | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/e2e/testconfig/testconfig.go b/e2e/testconfig/testconfig.go index 55c970115f1..87dd5d59a0d 100644 --- a/e2e/testconfig/testconfig.go +++ b/e2e/testconfig/testconfig.go @@ -281,8 +281,18 @@ type ChainOptionConfiguration func(options *ChainOptions) // These options can be configured by passing configuration functions to E2ETestSuite.GetChains. func DefaultChainOptions() ChainOptions { tc := LoadConfig() - chainACfg := newDefaultSimappConfig(tc.ChainConfigs[0], "simapp-a", tc.ChainConfigs[0].ChainID, "atoma") - chainBCfg := newDefaultSimappConfig(tc.ChainConfigs[1], "simapp-b", tc.ChainConfigs[1].ChainID, "atomb") + + chainAID := tc.ChainConfigs[0].ChainID + if chainAID == "" { + chainAID = "chain-a" + } + chainBID := tc.ChainConfigs[1].ChainID + if chainBID == "" { + chainBID = "chain-b" + } + + chainACfg := newDefaultSimappConfig(tc.ChainConfigs[0], "simapp-a", chainAID, "atoma") + chainBCfg := newDefaultSimappConfig(tc.ChainConfigs[1], "simapp-b", chainBID, "atomb") return ChainOptions{ ChainAConfig: &chainACfg, ChainBConfig: &chainBCfg, From 2da60ba3a85c3ed95802fbb2730b191902335a5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Colin=20Axn=C3=A9r?= <25233464+colin-axner@users.noreply.github.com> Date: Thu, 9 Mar 2023 18:14:10 +0100 Subject: [PATCH 05/22] chore: change tendermint logging to debug for e2e --- e2e/testconfig/testconfig.go | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/e2e/testconfig/testconfig.go b/e2e/testconfig/testconfig.go index 088fbd3b7bf..4bcee8ac32f 100644 --- a/e2e/testconfig/testconfig.go +++ b/e2e/testconfig/testconfig.go @@ -16,6 +16,7 @@ import ( govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" "github.com/strangelove-ventures/interchaintest/v7/ibc" + interchaintestutil "github.com/strangelove-ventures/interchaintest/v7/testutil" "github.com/cosmos/ibc-go/e2e/relayer" "github.com/cosmos/ibc-go/e2e/semverutil" @@ -197,6 +198,11 @@ func DefaultChainOptions() ChainOptions { // newDefaultSimappConfig creates an ibc configuration for simd. func newDefaultSimappConfig(cc ChainConfig, name, chainID, denom string) ibc.ChainConfig { + configFileOverrides := make(map[string]any) + tmTomlOverrides := make(interchaintestutil.Toml) + + tmTomlOverrides["log_level"] = "debug" + return ibc.ChainConfig{ Type: "cosmos", Name: name, @@ -207,15 +213,16 @@ func newDefaultSimappConfig(cc ChainConfig, name, chainID, denom string) ibc.Cha Version: cc.Tag, }, }, - Bin: cc.Binary, - Bech32Prefix: "cosmos", - CoinType: fmt.Sprint(sdk.GetConfig().GetCoinType()), - Denom: denom, - GasPrices: fmt.Sprintf("0.00%s", denom), - GasAdjustment: 1.3, - TrustingPeriod: "508h", - NoHostMount: false, - ModifyGenesis: getGenesisModificationFunction(cc), + Bin: cc.Binary, + Bech32Prefix: "cosmos", + CoinType: fmt.Sprint(sdk.GetConfig().GetCoinType()), + Denom: denom, + GasPrices: fmt.Sprintf("0.00%s", denom), + GasAdjustment: 1.3, + TrustingPeriod: "508h", + NoHostMount: false, + ModifyGenesis: getGenesisModificationFunction(cc), + ConfigFileOverrides: configFileOverrides, } } From f8d3fd57eb63ce40677255311fa8148774539a14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Colin=20Axn=C3=A9r?= <25233464+colin-axner@users.noreply.github.com> Date: Thu, 9 Mar 2023 20:50:47 +0100 Subject: [PATCH 06/22] fix: correctly set override --- e2e/testconfig/testconfig.go | 1 + 1 file changed, 1 insertion(+) diff --git a/e2e/testconfig/testconfig.go b/e2e/testconfig/testconfig.go index 4bcee8ac32f..299e0839da1 100644 --- a/e2e/testconfig/testconfig.go +++ b/e2e/testconfig/testconfig.go @@ -202,6 +202,7 @@ func newDefaultSimappConfig(cc ChainConfig, name, chainID, denom string) ibc.Cha tmTomlOverrides := make(interchaintestutil.Toml) tmTomlOverrides["log_level"] = "debug" + configFileOverrides["config/config.toml"] = tmTomlOverrides return ibc.ChainConfig{ Type: "cosmos", From 5d981e83497c62ae785c019671dbc87aa980d41d Mon Sep 17 00:00:00 2001 From: Cian Hatton Date: Fri, 10 Mar 2023 18:31:44 +0000 Subject: [PATCH 07/22] adding script to init the config file --- e2e/Makefile | 7 ++++-- e2e/scripts/init.sh | 20 +++++++++++++++ e2e/testconfig/testconfig.go | 47 +++++++++++++++++++++++++++--------- e2e/testsuite/testsuite.go | 9 +------ 4 files changed, 62 insertions(+), 21 deletions(-) create mode 100755 e2e/scripts/init.sh diff --git a/e2e/Makefile b/e2e/Makefile index 0b9802d06e1..e7fe038cf04 100644 --- a/e2e/Makefile +++ b/e2e/Makefile @@ -7,10 +7,13 @@ cleanup-ibc-test-containers: $(DOCKER) rm $$id ; \ done -e2e-test: cleanup-ibc-test-containers +init: + ./scripts/init.sh + +e2e-test: cleanup-ibc-test-containers init ./scripts/run-e2e.sh $(entrypoint) $(test) compatibility-tests: ./scripts/run-compatibility-tests.sh $(release_branch) -.PHONY: cleanup-ibc-test-containers e2e-test compatibility-tests +.PHONY: cleanup-ibc-test-containers e2e-test compatibility-tests init diff --git a/e2e/scripts/init.sh b/e2e/scripts/init.sh new file mode 100755 index 00000000000..b855522030f --- /dev/null +++ b/e2e/scripts/init.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +set -euo pipefail + +# ensure_config_file makes sure there is a config file for the e2e tests either by creating a new one using the sample, +# it is copied to either the default location or the specified env location. +function ensure_config_file(){ + local config_file_path="${HOME}/.ibc-go-e2e-config.json" + if [[ ! -z ${E2E_CONFIG_PATH} ]]; then + config_file_path="${E2E_CONFIG_PATH}" + fi + if [[ ! -f "${config_file_path}" ]]; then + echo "creating e2e config file from sample." + echo "copying sample.config.json to ${config_file_path}" + cp sample.config.json "${config_file_path}" + fi + echo "using config file at ${config_file_path} for e2e test" +} + +ensure_config_file diff --git a/e2e/testconfig/testconfig.go b/e2e/testconfig/testconfig.go index 87dd5d59a0d..3a7edec04e3 100644 --- a/e2e/testconfig/testconfig.go +++ b/e2e/testconfig/testconfig.go @@ -73,6 +73,40 @@ type TestConfig struct { UpgradeConfig UpgradeConfig `json:"upgrade"` } +// GetChainNumValidators returns the number of validators for the specific chain index. +// default 1 +func (tc TestConfig) GetChainNumValidators(idx int) int { + if tc.ChainConfigs[idx].NumValidators > 0 { + return tc.ChainConfigs[idx].NumValidators + } + return 1 +} + +// GetChainNumFullNodes returns the number of full nodes for the specific chain index. +// default 0 +func (tc TestConfig) GetChainNumFullNodes(idx int) int { + if tc.ChainConfigs[idx].NumFullNodes > 0 { + return tc.ChainConfigs[idx].NumFullNodes + } + return 0 +} + +// GetChainAID returns the chain-id for chain A. +func (tc TestConfig) GetChainAID() string { + if tc.ChainConfigs[0].ChainID != "" { + return tc.ChainConfigs[0].ChainID + } + return "chain-a" +} + +// GetChainBID returns the chain-id for chain B. +func (tc TestConfig) GetChainBID() string { + if tc.ChainConfigs[1].ChainID != "" { + return tc.ChainConfigs[1].ChainID + } + return "chain-b" +} + // UpgradeConfig holds values relevant to upgrade tests. type UpgradeConfig struct { PlanName string `json:"planName"` @@ -282,17 +316,8 @@ type ChainOptionConfiguration func(options *ChainOptions) func DefaultChainOptions() ChainOptions { tc := LoadConfig() - chainAID := tc.ChainConfigs[0].ChainID - if chainAID == "" { - chainAID = "chain-a" - } - chainBID := tc.ChainConfigs[1].ChainID - if chainBID == "" { - chainBID = "chain-b" - } - - chainACfg := newDefaultSimappConfig(tc.ChainConfigs[0], "simapp-a", chainAID, "atoma") - chainBCfg := newDefaultSimappConfig(tc.ChainConfigs[1], "simapp-b", chainBID, "atomb") + chainACfg := newDefaultSimappConfig(tc.ChainConfigs[0], "simapp-a", tc.GetChainAID(), "atoma") + chainBCfg := newDefaultSimappConfig(tc.ChainConfigs[1], "simapp-b", tc.GetChainBID(), "atomb") return ChainOptions{ ChainAConfig: &chainACfg, ChainBConfig: &chainBCfg, diff --git a/e2e/testsuite/testsuite.go b/e2e/testsuite/testsuite.go index 5e20414fde8..ef9f9a508ae 100644 --- a/e2e/testsuite/testsuite.go +++ b/e2e/testsuite/testsuite.go @@ -611,13 +611,6 @@ func getValidatorsAndFullNodes(chainIdx int) (int, int) { if testconfig.IsCI() { return 4, 1 } - numFullNodes, numValidators := 1, 0 tc := testconfig.LoadConfig() - if tc.ChainConfigs[chainIdx].NumFullNodes > 0 { - numFullNodes = tc.ChainConfigs[chainIdx].NumFullNodes - } - if tc.ChainConfigs[chainIdx].NumValidators > 0 { - numValidators = tc.ChainConfigs[chainIdx].NumValidators - } - return numValidators, numFullNodes + return tc.GetChainNumValidators(chainIdx), tc.GetChainNumFullNodes(chainIdx) } From 04304102d45b221d25c5053bfd1145e40af0fb6f Mon Sep 17 00:00:00 2001 From: Cian Hatton Date: Fri, 10 Mar 2023 18:38:33 +0000 Subject: [PATCH 08/22] cleaning up test config merging and fixing init script --- e2e/scripts/init.sh | 2 +- e2e/testconfig/testconfig.go | 34 ++++++++++++++++++---------------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/e2e/scripts/init.sh b/e2e/scripts/init.sh index b855522030f..8685c6b4e51 100755 --- a/e2e/scripts/init.sh +++ b/e2e/scripts/init.sh @@ -6,7 +6,7 @@ set -euo pipefail # it is copied to either the default location or the specified env location. function ensure_config_file(){ local config_file_path="${HOME}/.ibc-go-e2e-config.json" - if [[ ! -z ${E2E_CONFIG_PATH} ]]; then + if [[ ! -z "${E2E_CONFIG_PATH:-}" ]]; then config_file_path="${E2E_CONFIG_PATH}" fi if [[ ! -f "${config_file_path}" ]]; then diff --git a/e2e/testconfig/testconfig.go b/e2e/testconfig/testconfig.go index 3a7edec04e3..52d270442a5 100644 --- a/e2e/testconfig/testconfig.go +++ b/e2e/testconfig/testconfig.go @@ -128,8 +128,10 @@ type ChainConfig struct { // options. func LoadConfig() TestConfig { fileTc, foundFile := fromFile() - envTc := fromEnv() - return applyEnvironmentVariableOverrides(fileTc, envTc, foundFile) + if !foundFile { + return fromEnv() + } + return applyEnvironmentVariableOverrides(fileTc) } // fromFile returns a TestConfig from a json file and a boolean indicating if the file was found. @@ -149,43 +151,43 @@ func fromFile() (TestConfig, bool) { // applyEnvironmentVariableOverrides applies all environment variable changes to the config // loaded from a file. -func applyEnvironmentVariableOverrides(fromFile, fromEnv TestConfig, foundFile bool) TestConfig { - if !foundFile { - return fromEnv - } +func applyEnvironmentVariableOverrides(fromFile TestConfig) TestConfig { + envTc := fromEnv() if os.Getenv(ChainATagEnv) != "" { - fromFile.ChainConfigs[0].Tag = fromEnv.ChainConfigs[0].Tag + fromFile.ChainConfigs[0].Tag = envTc.ChainConfigs[0].Tag } if os.Getenv(ChainBTagEnv) != "" { - fromFile.ChainConfigs[1].Tag = fromEnv.ChainConfigs[1].Tag + fromFile.ChainConfigs[1].Tag = envTc.ChainConfigs[1].Tag } if os.Getenv(ChainBinaryEnv) != "" { - fromFile.ChainConfigs[0].Binary = fromEnv.ChainConfigs[0].Binary - fromFile.ChainConfigs[1].Binary = fromEnv.ChainConfigs[0].Binary + for i := range fromFile.ChainConfigs { + fromFile.ChainConfigs[i].Binary = envTc.ChainConfigs[i].Binary + } } if os.Getenv(ChainImageEnv) != "" { - fromFile.ChainConfigs[0].Image = fromEnv.ChainConfigs[0].Image - fromFile.ChainConfigs[1].Image = fromEnv.ChainConfigs[0].Image + for i := range fromFile.ChainConfigs { + fromFile.ChainConfigs[i].Image = envTc.ChainConfigs[i].Image + } } if os.Getenv(RelayerTagEnv) != "" { - fromFile.RelayerConfig.Tag = fromEnv.RelayerConfig.Tag + fromFile.RelayerConfig.Tag = envTc.RelayerConfig.Tag } if os.Getenv(RelayerTypeEnv) != "" { - fromFile.RelayerConfig.Type = fromEnv.RelayerConfig.Type + fromFile.RelayerConfig.Type = envTc.RelayerConfig.Type } if os.Getenv(ChainUpgradePlanEnv) != "" { - fromFile.UpgradeConfig.PlanName = fromEnv.UpgradeConfig.PlanName + fromFile.UpgradeConfig.PlanName = envTc.UpgradeConfig.PlanName } if os.Getenv(ChainUpgradeTagEnv) != "" { - fromFile.UpgradeConfig.Tag = fromEnv.UpgradeConfig.Tag + fromFile.UpgradeConfig.Tag = envTc.UpgradeConfig.Tag } return fromFile From b6d433d01b00e173625a36988e655c5ab4996698 Mon Sep 17 00:00:00 2001 From: Cian Hatton Date: Fri, 10 Mar 2023 18:45:07 +0000 Subject: [PATCH 09/22] added upgrade configs to sample config --- e2e/sample.config.json | 58 +++++++++++++++++++++++++----------- e2e/testconfig/testconfig.go | 3 +- 2 files changed, 41 insertions(+), 20 deletions(-) diff --git a/e2e/sample.config.json b/e2e/sample.config.json index 138e2e362fb..1742a3ec772 100644 --- a/e2e/sample.config.json +++ b/e2e/sample.config.json @@ -1,25 +1,47 @@ { - "chains":[ + "chains": [ { - "chainId":"chain-a", - "numValidators":1, - "numFullNodes":0, - "image":"ghcr.io/cosmos/ibc-go-simd", - "tag":"main", - "binary":"simd" + "chainId": "chain-a", + "numValidators": 1, + "numFullNodes": 0, + "image": "ghcr.io/cosmos/ibc-go-simd", + "tag": "main", + "binary": "simd" }, { - "chainId":"chain-b", - "numValidators":1, - "numFullNodes":0, - "image":"ghcr.io/cosmos/ibc-go-simd", - "tag":"main", - "binary":"simd" + "chainId": "chain-b", + "numValidators": 1, + "numFullNodes": 0, + "image": "ghcr.io/cosmos/ibc-go-simd", + "tag": "main", + "binary": "simd" } ], - "relayer":{ - "type":"rly", - "image":"ghcr.io/cosmos/relayer", - "tag":"main" - } + "relayer": { + "type": "rly", + "image": "ghcr.io/cosmos/relayer", + "tag": "main" + }, + "upgrades": [ + { + "tag": "v7.0.0-rc0", + "planName": "v7" + }, + { + "tag": "v7.0.0-rc1", + "planName": "v7" + }, + { + "tag": "v7.0.0", + "planName": "v7" + }, + { + "tag": "v0.4.1", + "planName": "ibc-go/v6" + }, + { + "tag": "v5.1.0", + "planName": "normal upgrade" + } + ] } diff --git a/e2e/testconfig/testconfig.go b/e2e/testconfig/testconfig.go index 52d270442a5..2710d82feb2 100644 --- a/e2e/testconfig/testconfig.go +++ b/e2e/testconfig/testconfig.go @@ -250,8 +250,7 @@ func fromEnv() TestConfig { // getConfigFilePath returns the absolute path where the e2e config file should be. func getConfigFilePath() string { - absoluteConfigPath := os.Getenv(E2EConfigFilePath) - if absoluteConfigPath != "" { + if absoluteConfigPath := os.Getenv(E2EConfigFilePath); absoluteConfigPath != "" { return absoluteConfigPath } From 3d64b25ad1555a29ac659f5ff0a6db4193f1a3b3 Mon Sep 17 00:00:00 2001 From: Cian Hatton Date: Fri, 10 Mar 2023 18:58:39 +0000 Subject: [PATCH 10/22] remove upgrade plans --- e2e/sample.config.json | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/e2e/sample.config.json b/e2e/sample.config.json index 1742a3ec772..4560e7cb4e6 100644 --- a/e2e/sample.config.json +++ b/e2e/sample.config.json @@ -21,27 +21,5 @@ "type": "rly", "image": "ghcr.io/cosmos/relayer", "tag": "main" - }, - "upgrades": [ - { - "tag": "v7.0.0-rc0", - "planName": "v7" - }, - { - "tag": "v7.0.0-rc1", - "planName": "v7" - }, - { - "tag": "v7.0.0", - "planName": "v7" - }, - { - "tag": "v0.4.1", - "planName": "ibc-go/v6" - }, - { - "tag": "v5.1.0", - "planName": "normal upgrade" - } - ] + } } From 5854ee178da97531c150981977ec80baed80ab2d Mon Sep 17 00:00:00 2001 From: Cian Hatton Date: Fri, 10 Mar 2023 19:00:46 +0000 Subject: [PATCH 11/22] added explicit environmental variable name requirement --- e2e/tests/upgrades/upgrade_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/e2e/tests/upgrades/upgrade_test.go b/e2e/tests/upgrades/upgrade_test.go index 850205e088b..55e34afb097 100644 --- a/e2e/tests/upgrades/upgrade_test.go +++ b/e2e/tests/upgrades/upgrade_test.go @@ -38,7 +38,7 @@ const ( func TestUpgradeTestSuite(t *testing.T) { testCfg := testconfig.LoadConfig() if testCfg.UpgradeConfig.Tag == "" || testCfg.UpgradeConfig.PlanName == "" { - t.Fatal("upgrade tag and upgrade plan name must be provided in test configuration") + t.Fatalf("%s and %s must be set when running an upgrade test", testconfig.ChainUpgradeTagEnv, testconfig.ChainUpgradePlanEnv) } suite.Run(t, new(UpgradeTestSuite)) @@ -568,7 +568,7 @@ func (s *UpgradeTestSuite) TestV6ToV7ChainUpgrade() { chainAUpgradeProposalWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) t.Run("upgrade chainA", func(t *testing.T) { - s.UpgradeChain(ctx, chainA, chainAUpgradeProposalWallet,testCfg.UpgradeConfig.PlanName, testCfg.ChainConfigs[0].Tag, testCfg.UpgradeConfig.Tag) + s.UpgradeChain(ctx, chainA, chainAUpgradeProposalWallet, testCfg.UpgradeConfig.PlanName, testCfg.ChainConfigs[0].Tag, testCfg.UpgradeConfig.Tag) }) t.Run("check that the tendermint clients are active again after upgrade", func(t *testing.T) { From b29c48ce38b85e1d92980dc11afedbccde5c8758 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Colin=20Axn=C3=A9r?= <25233464+colin-axner@users.noreply.github.com> Date: Mon, 13 Mar 2023 14:13:12 +0100 Subject: [PATCH 12/22] chore: change log level to info --- e2e/testconfig/testconfig.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/testconfig/testconfig.go b/e2e/testconfig/testconfig.go index 299e0839da1..cacf14dd0d9 100644 --- a/e2e/testconfig/testconfig.go +++ b/e2e/testconfig/testconfig.go @@ -201,7 +201,7 @@ func newDefaultSimappConfig(cc ChainConfig, name, chainID, denom string) ibc.Cha configFileOverrides := make(map[string]any) tmTomlOverrides := make(interchaintestutil.Toml) - tmTomlOverrides["log_level"] = "debug" + tmTomlOverrides["log_level"] = "info" // change to debug to increase cometbft logging configFileOverrides["config/config.toml"] = tmTomlOverrides return ibc.ChainConfig{ From c5ff4ae37c47cb36d559323d39f9abc29a762227 Mon Sep 17 00:00:00 2001 From: Cian Hatton Date: Tue, 14 Mar 2023 11:20:47 +0000 Subject: [PATCH 13/22] cleaned up loading config from env --- e2e/testconfig/testconfig.go | 76 +++++++++++++++++++++--------------- 1 file changed, 44 insertions(+), 32 deletions(-) diff --git a/e2e/testconfig/testconfig.go b/e2e/testconfig/testconfig.go index a579b2afa91..6c95c13611b 100644 --- a/e2e/testconfig/testconfig.go +++ b/e2e/testconfig/testconfig.go @@ -42,8 +42,8 @@ const ( ChainUpgradeTagEnv = "CHAIN_UPGRADE_TAG" // ChainUpgradePlanEnv specifies the upgrade plan name ChainUpgradePlanEnv = "CHAIN_UPGRADE_PLAN" - // E2EConfigFilePath allows you to specify a custom path for the config file to be used. - E2EConfigFilePath = "E2E_CONFIG_PATH" + // E2EConfigFilePathEnv allows you to specify a custom path for the config file to be used. + E2EConfigFilePathEnv = "E2E_CONFIG_PATH" // defaultBinary is the default binary that will be used by the chains. defaultBinary = "simd" @@ -68,9 +68,12 @@ func getChainImage(binary string) string { // TestConfig holds configuration used throughout the different e2e tests. type TestConfig struct { - ChainConfigs []ChainConfig `json:"chains"` + // ChainConfigs holds configuration values related to the chains used in the tests. + ChainConfigs []ChainConfig `json:"chains"` + // RelayerConfig holds configuration for the relayer to be used. RelayerConfig relayer.Config `json:"relayer"` - UpgradeConfig UpgradeConfig `json:"upgrade"` + // UpgradeConfig holds values used only for the upgrade tests. + UpgradeConfig UpgradeConfig `json:"upgrade"` } // GetChainNumValidators returns the number of validators for the specific chain index. @@ -195,6 +198,15 @@ func applyEnvironmentVariableOverrides(fromFile TestConfig) TestConfig { // fromEnv returns a TestConfig constructed from environment variables. func fromEnv() TestConfig { + return TestConfig{ + ChainConfigs: getChainConfigsFromEnv(), + UpgradeConfig: getUpgradePlanConfigFromEnv(), + RelayerConfig: getRelayerConfigFromEnv(), + } +} + +// getChainConfigsFromEnv returns the chain configs from environment variables. +func getChainConfigsFromEnv() []ChainConfig { chainBinary, ok := os.LookupEnv(ChainBinaryEnv) if !ok { chainBinary = defaultBinary @@ -215,42 +227,25 @@ func fromEnv() TestConfig { if ok { chainAImage = specifiedChainImage } - chainBImage := chainAImage - - upgradeTag, ok := os.LookupEnv(ChainUpgradeTagEnv) - if !ok { - upgradeTag = "" - } - upgradePlan, ok := os.LookupEnv(ChainUpgradePlanEnv) - if !ok { - upgradePlan = "" - } - - return TestConfig{ - ChainConfigs: []ChainConfig{ - { - Image: chainAImage, - Tag: chainATag, - Binary: chainBinary, - }, - { - Image: chainBImage, - Tag: chainBTag, - Binary: chainBinary, - }, + chainBImage := chainAImage + return []ChainConfig{ + { + Image: chainAImage, + Tag: chainATag, + Binary: chainBinary, }, - UpgradeConfig: UpgradeConfig{ - PlanName: upgradePlan, - Tag: upgradeTag, + { + Image: chainBImage, + Tag: chainBTag, + Binary: chainBinary, }, - RelayerConfig: getRelayerConfigFromEnv(), } } // getConfigFilePath returns the absolute path where the e2e config file should be. func getConfigFilePath() string { - if absoluteConfigPath := os.Getenv(E2EConfigFilePath); absoluteConfigPath != "" { + if absoluteConfigPath := os.Getenv(E2EConfigFilePathEnv); absoluteConfigPath != "" { return absoluteConfigPath } @@ -283,6 +278,23 @@ func getRelayerConfigFromEnv() relayer.Config { } } +// getUpgradePlanConfigFromEnv returns the upgrade config from environment variables. +func getUpgradePlanConfigFromEnv() UpgradeConfig { + upgradeTag, ok := os.LookupEnv(ChainUpgradeTagEnv) + if !ok { + upgradeTag = "" + } + + upgradePlan, ok := os.LookupEnv(ChainUpgradePlanEnv) + if !ok { + upgradePlan = "" + } + return UpgradeConfig{ + PlanName: upgradePlan, + Tag: upgradeTag, + } +} + func GetChainATag() string { return LoadConfig().ChainConfigs[0].Tag } From 2d1a8c7a7522bd04e431102345881f1e41847e04 Mon Sep 17 00:00:00 2001 From: Cian Hatton Date: Tue, 14 Mar 2023 11:38:25 +0000 Subject: [PATCH 14/22] update to use damiannolan/rly image --- e2e/sample.config.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/e2e/sample.config.json b/e2e/sample.config.json index 4560e7cb4e6..a1768fed5bf 100644 --- a/e2e/sample.config.json +++ b/e2e/sample.config.json @@ -19,7 +19,7 @@ ], "relayer": { "type": "rly", - "image": "ghcr.io/cosmos/relayer", - "tag": "main" + "image": "damiannolan/rly", + "tag": "latest" } } From b879999754be96e5b06570ec22bb7679dd68bc59 Mon Sep 17 00:00:00 2001 From: Cian Hatton Date: Tue, 14 Mar 2023 11:39:36 +0000 Subject: [PATCH 15/22] make init run before e2e test --- e2e/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/Makefile b/e2e/Makefile index 7d2316708d7..e05b3173db7 100644 --- a/e2e/Makefile +++ b/e2e/Makefile @@ -10,7 +10,7 @@ cleanup-ibc-test-containers: init: ./scripts/init.sh -e2e-test: cleanup-ibc-test-containers +e2e-test: init cleanup-ibc-test-containers ./scripts/run-e2e.sh $(test) $(entrypoint) compatibility-tests: From fb99afc426b40b85098a3e11575de3a59803bed4 Mon Sep 17 00:00:00 2001 From: Cian Hatton Date: Tue, 14 Mar 2023 11:50:19 +0000 Subject: [PATCH 16/22] add support for cometbft logging --- e2e/sample.config.json | 3 +++ e2e/testconfig/testconfig.go | 14 ++++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/e2e/sample.config.json b/e2e/sample.config.json index a1768fed5bf..c9f5a9a4a97 100644 --- a/e2e/sample.config.json +++ b/e2e/sample.config.json @@ -21,5 +21,8 @@ "type": "rly", "image": "damiannolan/rly", "tag": "latest" + }, + "cometbft": { + "logLevel": "info" } } diff --git a/e2e/testconfig/testconfig.go b/e2e/testconfig/testconfig.go index 9444578d44b..f004a1cf682 100644 --- a/e2e/testconfig/testconfig.go +++ b/e2e/testconfig/testconfig.go @@ -75,6 +75,8 @@ type TestConfig struct { RelayerConfig relayer.Config `json:"relayer"` // UpgradeConfig holds values used only for the upgrade tests. UpgradeConfig UpgradeConfig `json:"upgrade"` + // CometBFTConfig holds values for configuring CometBFT. + CometBFTConfig CometBFTConfig `json:"cometbft"` } // GetChainNumValidators returns the number of validators for the specific chain index. @@ -127,6 +129,10 @@ type ChainConfig struct { NumFullNodes int `json:"numFullNodes"` } +type CometBFTConfig struct { + LogLevel string `json:"logLevel"` +} + // LoadConfig attempts to load a atest configuration from the default file path. // if any environment variables are specified, they will take precedence over the individual configuration // options. @@ -330,8 +336,8 @@ type ChainOptionConfiguration func(options *ChainOptions) func DefaultChainOptions() ChainOptions { tc := LoadConfig() - chainACfg := newDefaultSimappConfig(tc.ChainConfigs[0], "simapp-a", tc.GetChainAID(), "atoma") - chainBCfg := newDefaultSimappConfig(tc.ChainConfigs[1], "simapp-b", tc.GetChainBID(), "atomb") + chainACfg := newDefaultSimappConfig(tc.ChainConfigs[0], "simapp-a", tc.GetChainAID(), "atoma", tc.CometBFTConfig) + chainBCfg := newDefaultSimappConfig(tc.ChainConfigs[1], "simapp-b", tc.GetChainBID(), "atomb", tc.CometBFTConfig) return ChainOptions{ ChainAConfig: &chainACfg, ChainBConfig: &chainBCfg, @@ -339,11 +345,11 @@ func DefaultChainOptions() ChainOptions { } // newDefaultSimappConfig creates an ibc configuration for simd. -func newDefaultSimappConfig(cc ChainConfig, name, chainID, denom string) ibc.ChainConfig { +func newDefaultSimappConfig(cc ChainConfig, name, chainID, denom string, cometCfg CometBFTConfig) ibc.ChainConfig { configFileOverrides := make(map[string]any) tmTomlOverrides := make(interchaintestutil.Toml) - tmTomlOverrides["log_level"] = "info" // change to debug to increase cometbft logging + tmTomlOverrides["log_level"] = cometCfg.LogLevel // change to debug in ~/.ibc-go-e2e-config.json to increase cometbft logging. configFileOverrides["config/config.toml"] = tmTomlOverrides return ibc.ChainConfig{ From 36ea3c149fc96fb2c44baaad7807c3616e75438c Mon Sep 17 00:00:00 2001 From: Cian Hatton Date: Tue, 14 Mar 2023 15:04:02 +0000 Subject: [PATCH 17/22] changed structure to yaml to enable comments in the config file --- e2e/README.md | 2 +- e2e/sample.config.json | 28 -------------------------- e2e/sample.config.yaml | 38 ++++++++++++++++++++++++++++++++++++ e2e/scripts/init.sh | 6 +++--- e2e/testconfig/testconfig.go | 33 ++++++++++++++++--------------- 5 files changed, 59 insertions(+), 48 deletions(-) delete mode 100644 e2e/sample.config.json create mode 100644 e2e/sample.config.yaml diff --git a/e2e/README.md b/e2e/README.md index 4d668ec2a52..2409c9c563b 100644 --- a/e2e/README.md +++ b/e2e/README.md @@ -39,7 +39,7 @@ Tests can be run using a Makefile target under the e2e directory. `e2e/Makefile` The tests can be configured using a configuration file or environment variables. -See [the example](./sample.config.json) to get started. The default location the tests look is `~/.ibc-go-e2e-config.json` +See [the example](./sample.config.yaml) to get started. The default location the tests look is `~/.ibc-go-e2e-config.json` But this can be specified directly using the `E2E_CONFIG_PATH` environment variable. There are several environment variables that alter the behaviour of the make target which will override any diff --git a/e2e/sample.config.json b/e2e/sample.config.json deleted file mode 100644 index c9f5a9a4a97..00000000000 --- a/e2e/sample.config.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "chains": [ - { - "chainId": "chain-a", - "numValidators": 1, - "numFullNodes": 0, - "image": "ghcr.io/cosmos/ibc-go-simd", - "tag": "main", - "binary": "simd" - }, - { - "chainId": "chain-b", - "numValidators": 1, - "numFullNodes": 0, - "image": "ghcr.io/cosmos/ibc-go-simd", - "tag": "main", - "binary": "simd" - } - ], - "relayer": { - "type": "rly", - "image": "damiannolan/rly", - "tag": "latest" - }, - "cometbft": { - "logLevel": "info" - } -} diff --git a/e2e/sample.config.yaml b/e2e/sample.config.yaml new file mode 100644 index 00000000000..6235b9edeea --- /dev/null +++ b/e2e/sample.config.yaml @@ -0,0 +1,38 @@ + + +# Many of these fields can be overridden with environment variables. +# All fields that support this have the corresponding environment variable name +# in a comment beside the field. + +--- +chains: + # the entry at index 0 corresponds to CHAIN_A +- chainId: chain-a + numValidators: 1 + numFullNodes: 0 + image: ghcr.io/cosmos/ibc-go-simd # override with CHAIN_IMAGE + tag: main # override with CHAIN_A_TAG + binary: simd # override with CHAIN_BINARY + + # the entry at index 1 corresponds to CHAIN_B +- chainId: chain-b + numValidators: 1 + numFullNodes: 0 + image: ghcr.io/cosmos/ibc-go-simd # override with CHAIN_IMAGE + tag: main # override with CHAIN_B_TAG + binary: simd # override with CHAIN_BINARY + +relayer: + type: rly # override with RELAYER_TYPE + image: damiannolan/rly + tag: latest # override with RELAYER_TAG + +cometbft: + logLevel: info + +# Required only for upgrade tests. +# Chain A will be upgraded the specified tag. +# The plan name must be registered as an upgrade handler in the given tag. +upgrade: + planName: "" + tag: "" diff --git a/e2e/scripts/init.sh b/e2e/scripts/init.sh index 8685c6b4e51..9ff395aed2a 100755 --- a/e2e/scripts/init.sh +++ b/e2e/scripts/init.sh @@ -5,14 +5,14 @@ set -euo pipefail # ensure_config_file makes sure there is a config file for the e2e tests either by creating a new one using the sample, # it is copied to either the default location or the specified env location. function ensure_config_file(){ - local config_file_path="${HOME}/.ibc-go-e2e-config.json" + local config_file_path="${HOME}/.ibc-go-e2e-config.yaml" if [[ ! -z "${E2E_CONFIG_PATH:-}" ]]; then config_file_path="${E2E_CONFIG_PATH}" fi if [[ ! -f "${config_file_path}" ]]; then echo "creating e2e config file from sample." - echo "copying sample.config.json to ${config_file_path}" - cp sample.config.json "${config_file_path}" + echo "copying sample.config.yaml to ${config_file_path}" + cp sample.config.yaml "${config_file_path}" fi echo "using config file at ${config_file_path} for e2e test" } diff --git a/e2e/testconfig/testconfig.go b/e2e/testconfig/testconfig.go index f004a1cf682..31ab12fa3f1 100644 --- a/e2e/testconfig/testconfig.go +++ b/e2e/testconfig/testconfig.go @@ -18,6 +18,7 @@ import ( govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" "github.com/strangelove-ventures/interchaintest/v7/ibc" interchaintestutil "github.com/strangelove-ventures/interchaintest/v7/testutil" + "gopkg.in/yaml.v2" "github.com/cosmos/ibc-go/e2e/relayer" "github.com/cosmos/ibc-go/e2e/semverutil" @@ -56,8 +57,8 @@ const ( // defaultRelayerType is the default relayer that will be used if none is specified. defaultRelayerType = relayer.Rly // defaultConfigFileName is the default filename for the config file that can be used to configure - // e2e tests. See sample.config.json as an example for what this should look like. - defaultConfigFileName = ".ibc-go-e2e-config.json" + // e2e tests. See sample.config.yaml as an example for what this should look like. + defaultConfigFileName = ".ibc-go-e2e-config.yaml" ) func getChainImage(binary string) string { @@ -70,13 +71,13 @@ func getChainImage(binary string) string { // TestConfig holds configuration used throughout the different e2e tests. type TestConfig struct { // ChainConfigs holds configuration values related to the chains used in the tests. - ChainConfigs []ChainConfig `json:"chains"` + ChainConfigs []ChainConfig `yaml:"chains"` // RelayerConfig holds configuration for the relayer to be used. - RelayerConfig relayer.Config `json:"relayer"` + RelayerConfig relayer.Config `yaml:"relayer"` // UpgradeConfig holds values used only for the upgrade tests. - UpgradeConfig UpgradeConfig `json:"upgrade"` + UpgradeConfig UpgradeConfig `yaml:"upgrade"` // CometBFTConfig holds values for configuring CometBFT. - CometBFTConfig CometBFTConfig `json:"cometbft"` + CometBFTConfig CometBFTConfig `yaml:"cometbft"` } // GetChainNumValidators returns the number of validators for the specific chain index. @@ -115,22 +116,22 @@ func (tc TestConfig) GetChainBID() string { // UpgradeConfig holds values relevant to upgrade tests. type UpgradeConfig struct { - PlanName string `json:"planName"` - Tag string `json:"tag"` + PlanName string `yaml:"planName"` + Tag string `yaml:"tag"` } // ChainConfig holds information about an individual chain used in the tests. type ChainConfig struct { - ChainID string `json:"chainId"` - Image string `json:"image"` - Tag string `json:"tag"` - Binary string `json:"binary"` - NumValidators int `json:"numValidators"` - NumFullNodes int `json:"numFullNodes"` + ChainID string `yaml:"chainId"` + Image string `yaml:"image"` + Tag string `yaml:"tag"` + Binary string `yaml:"binary"` + NumValidators int `yaml:"numValidators"` + NumFullNodes int `yaml:"numFullNodes"` } type CometBFTConfig struct { - LogLevel string `json:"logLevel"` + LogLevel string `yaml:"logLevel"` } // LoadConfig attempts to load a atest configuration from the default file path. @@ -152,7 +153,7 @@ func fromFile() (TestConfig, bool) { return TestConfig{}, false } - if err := json.Unmarshal(bz, &tc); err != nil { + if err := yaml.Unmarshal(bz, &tc); err != nil { panic(err) } From b2fb47ee6a1417aaad051abecd10b8eeac6cdc0f Mon Sep 17 00:00:00 2001 From: Cian Hatton Date: Tue, 14 Mar 2023 16:06:30 +0000 Subject: [PATCH 18/22] changed tags to yaml --- e2e/relayer/relayer.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/e2e/relayer/relayer.go b/e2e/relayer/relayer.go index 4fe1deea243..befcd6d127a 100644 --- a/e2e/relayer/relayer.go +++ b/e2e/relayer/relayer.go @@ -22,11 +22,11 @@ const ( // Config holds configuration values for the relayer used in the tests. type Config struct { // Tag is the tag used for the relayer image. - Tag string `json:"tag"` + Tag string `yaml:"tag"` // Type specifies the type of relayer that this is. - Type string `json:"type"` + Type string `yaml:"type"` // Image is the image that should be used for the relayer. - Image string `json:"image"` + Image string `yaml:"image"` } // New returns an implementation of ibc.Relayer depending on the provided RelayerType. From 99cccccc96c8de855e2652bdd023d9a51107c076 Mon Sep 17 00:00:00 2001 From: Cian Hatton Date: Tue, 14 Mar 2023 16:17:47 +0000 Subject: [PATCH 19/22] cleaned up comment in config file --- e2e/sample.config.yaml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/e2e/sample.config.yaml b/e2e/sample.config.yaml index 6235b9edeea..c50a49bfc28 100644 --- a/e2e/sample.config.yaml +++ b/e2e/sample.config.yaml @@ -1,8 +1,6 @@ - - +# This file contains configuration for running e2e tests. # Many of these fields can be overridden with environment variables. -# All fields that support this have the corresponding environment variable name -# in a comment beside the field. +# All fields that support this have the corresponding environment variable name in a comment beside the field. --- chains: From f188d36262a8bd77b6f143ad986dd2694d92e9eb Mon Sep 17 00:00:00 2001 From: Cian Hatton Date: Tue, 14 Mar 2023 16:29:23 +0000 Subject: [PATCH 20/22] added option to force dump logs --- e2e/sample.config.yaml | 4 ++++ e2e/testconfig/testconfig.go | 7 +++++++ e2e/testsuite/diagnostics/diagnostics.go | 10 ++++++---- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/e2e/sample.config.yaml b/e2e/sample.config.yaml index c50a49bfc28..30da46744a0 100644 --- a/e2e/sample.config.yaml +++ b/e2e/sample.config.yaml @@ -28,6 +28,10 @@ relayer: cometbft: logLevel: info +debug: + # setting this value to true will force log collection even if the test passes. + dumpLogs: false + # Required only for upgrade tests. # Chain A will be upgraded the specified tag. # The plan name must be registered as an upgrade handler in the given tag. diff --git a/e2e/testconfig/testconfig.go b/e2e/testconfig/testconfig.go index 31ab12fa3f1..88b1541b751 100644 --- a/e2e/testconfig/testconfig.go +++ b/e2e/testconfig/testconfig.go @@ -78,6 +78,8 @@ type TestConfig struct { UpgradeConfig UpgradeConfig `yaml:"upgrade"` // CometBFTConfig holds values for configuring CometBFT. CometBFTConfig CometBFTConfig `yaml:"cometbft"` + // DebugConfig holds configuration for miscellaneous options. + DebugConfig DebugConfig `yaml:"debug"` } // GetChainNumValidators returns the number of validators for the specific chain index. @@ -134,6 +136,11 @@ type CometBFTConfig struct { LogLevel string `yaml:"logLevel"` } +type DebugConfig struct { + // DumpLogs forces the logs to be collected before removing test containers. + DumpLogs bool `yaml:"dumpLogs"` +} + // LoadConfig attempts to load a atest configuration from the default file path. // if any environment variables are specified, they will take precedence over the individual configuration // options. diff --git a/e2e/testsuite/diagnostics/diagnostics.go b/e2e/testsuite/diagnostics/diagnostics.go index 896e73e804a..fc56770a8b8 100644 --- a/e2e/testsuite/diagnostics/diagnostics.go +++ b/e2e/testsuite/diagnostics/diagnostics.go @@ -18,8 +18,9 @@ import ( ) const ( - e2eDir = "e2e" - defaultFilePerm = 0750 + e2eDir = "e2e" + defaultFilePerm = 0750 + dockerInspectFileName = "docker-inspect.json" ) // Collect can be used in `t.Cleanup` and will copy all the of the container logs and relevant files @@ -27,7 +28,8 @@ const ( func Collect(t *testing.T, dc *dockerclient.Client, cfg testconfig.ChainOptions) { t.Helper() - if !t.Failed() { + debugCfg := testconfig.LoadConfig().DebugConfig + if !t.Failed() || debugCfg.DumpLogs { t.Logf("test passed, not uploading logs") return } @@ -87,7 +89,7 @@ func Collect(t *testing.T, dc *dockerclient.Client, cfg testconfig.ChainOptions) t.Logf("successfully wrote diagnostics file %s", absoluteFilePathInContainer) } - localFilePath := ospath.Join(containerDir, "docker-inspect.json") + localFilePath := ospath.Join(containerDir, dockerInspectFileName) if err := fetchAndWriteDockerInspectOutput(ctx, dc, container.ID, localFilePath); err != nil { t.Logf("failed to fetch docker inspect output: %s", err) continue From 5c0b82080259ca9292027acade9648411c5b9d17 Mon Sep 17 00:00:00 2001 From: Cian Hatton Date: Tue, 14 Mar 2023 17:08:01 +0000 Subject: [PATCH 21/22] fixed e2e readme --- e2e/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/README.md b/e2e/README.md index 2409c9c563b..32d576cd6af 100644 --- a/e2e/README.md +++ b/e2e/README.md @@ -39,7 +39,7 @@ Tests can be run using a Makefile target under the e2e directory. `e2e/Makefile` The tests can be configured using a configuration file or environment variables. -See [the example](./sample.config.yaml) to get started. The default location the tests look is `~/.ibc-go-e2e-config.json` +See [the example](./sample.config.yaml) to get started. The default location the tests look is `~/.ibc-go-e2e-config.yaml` But this can be specified directly using the `E2E_CONFIG_PATH` environment variable. There are several environment variables that alter the behaviour of the make target which will override any From 03b11dcae649a40b0acd852b9ed358f3dc42ebcd Mon Sep 17 00:00:00 2001 From: Cian Hatton Date: Wed, 15 Mar 2023 15:55:20 +0000 Subject: [PATCH 22/22] correctly handle dumpLogs value --- e2e/testsuite/diagnostics/diagnostics.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/e2e/testsuite/diagnostics/diagnostics.go b/e2e/testsuite/diagnostics/diagnostics.go index fc56770a8b8..33738705c0a 100644 --- a/e2e/testsuite/diagnostics/diagnostics.go +++ b/e2e/testsuite/diagnostics/diagnostics.go @@ -29,9 +29,12 @@ func Collect(t *testing.T, dc *dockerclient.Client, cfg testconfig.ChainOptions) t.Helper() debugCfg := testconfig.LoadConfig().DebugConfig - if !t.Failed() || debugCfg.DumpLogs { - t.Logf("test passed, not uploading logs") - return + if !debugCfg.DumpLogs { + // when we are not forcing log collection, we only upload upon test failing. + if !t.Failed() { + t.Logf("test passed, not uploading logs") + return + } } t.Logf("writing logs for test: %s", t.Name())