diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e60197fcfb3..a75e14ab5a3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -87,6 +87,7 @@ jobs: - name: Build Docker Image run: | make docker-build-debug + make docker-build-e2e-chain-init if: env.GIT_DIFF - name: Test E2E run: | diff --git a/CHANGELOG.md b/CHANGELOG.md index 458b9d8a469..585c6948fc2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -50,6 +50,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * ### Minor improvements & Bug Fixes +* [#1363](https://github.com/osmosis-labs/osmosis/pull/1363) Switch e2e test setup to create genesis and configs via Dockertest * [#1335](https://github.com/osmosis-labs/osmosis/pull/1335) Add utility for deriving total orderings from partial orderings. * [#1308](https://github.com/osmosis-labs/osmosis/pull/1308) Make panics inside of epochs no longer chain halt by default. * [#1286](https://github.com/osmosis-labs/osmosis/pull/1286) Fix release build scripts. diff --git a/tests/e2e/chain/chain.go b/tests/e2e/chain/chain.go index 0a4e0d3f4f3..a746bcc7440 100644 --- a/tests/e2e/chain/chain.go +++ b/tests/e2e/chain/chain.go @@ -9,24 +9,24 @@ const ( keyringAppName = "testnet" ) -type Chain struct { - DataDir string - Id string - Validators []*Validator +// internalChain contains the same info as chain, but with the validator structs instead using the internal validator +// representation, with more derived data +type internalChain struct { + chainMeta ChainMeta + validators []*internalValidator } -func new(id, dataDir string) (*Chain, error) { - return &Chain{ +func new(id, dataDir string) (*internalChain, error) { + chainMeta := ChainMeta{ Id: id, DataDir: dataDir, + } + return &internalChain{ + chainMeta: chainMeta, }, nil } -func (c *Chain) configDir() string { - return fmt.Sprintf("%s/%s", c.DataDir, c.Id) -} - -func (c *Chain) createAndInitValidators(count int) error { +func (c *internalChain) createAndInitValidators(count int) error { for i := 0; i < count; i++ { node := c.createValidator(i) @@ -35,7 +35,7 @@ func (c *Chain) createAndInitValidators(count int) error { return err } - c.Validators = append(c.Validators, node) + c.validators = append(c.validators, node) // create keys if err := node.createKey("val"); err != nil { @@ -52,7 +52,7 @@ func (c *Chain) createAndInitValidators(count int) error { return nil } -func (c *Chain) createAndInitValidatorsWithMnemonics(count int, mnemonics []string) error { +func (c *internalChain) createAndInitValidatorsWithMnemonics(count int, mnemonics []string) error { for i := 0; i < count; i++ { // create node node := c.createValidator(i) @@ -62,7 +62,7 @@ func (c *Chain) createAndInitValidatorsWithMnemonics(count int, mnemonics []stri return err } - c.Validators = append(c.Validators, node) + c.validators = append(c.validators, node) // create keys if err := node.createKeyFromMnemonic("val", mnemonics[i]); err != nil { @@ -79,10 +79,22 @@ func (c *Chain) createAndInitValidatorsWithMnemonics(count int, mnemonics []stri return nil } -func (c *Chain) createValidator(index int) *Validator { - return &Validator{ +func (c *internalChain) createValidator(index int) *internalValidator { + return &internalValidator{ chain: c, index: index, - moniker: fmt.Sprintf("%s-osmosis-%d", c.Id, index), + moniker: fmt.Sprintf("%s-osmosis-%d", c.chainMeta.Id, index), + } +} + +func (c *internalChain) export() *Chain { + exportValidators := make([]*Validator, 0, len(c.validators)) + for _, v := range c.validators { + exportValidators = append(exportValidators, v.export()) + } + + return &Chain{ + ChainMeta: c.chainMeta, + Validators: exportValidators, } } diff --git a/tests/e2e/chain/config.go b/tests/e2e/chain/config.go index a5abf60041e..28bc3ba3016 100644 --- a/tests/e2e/chain/config.go +++ b/tests/e2e/chain/config.go @@ -120,12 +120,12 @@ func addAccount(path, moniker, amountStr string, accAddr sdk.AccAddress) error { return genutil.ExportGenesisFile(genDoc, genFile) } -func initGenesis(c *Chain) error { +func initGenesis(c *internalChain) error { serverCtx := server.NewDefaultContext() config := serverCtx.Config - config.SetRoot(c.Validators[0].ConfigDir()) - config.Moniker = c.Validators[0].GetMoniker() + config.SetRoot(c.validators[0].configDir()) + config.Moniker = c.validators[0].getMoniker() genFilePath := config.GenesisFile() appGenState, genDoc, err := genutiltypes.GenesisStateFromGenFile(genFilePath) @@ -164,10 +164,10 @@ func initGenesis(c *Chain) error { } // generate genesis txs - genTxs := make([]json.RawMessage, len(c.Validators)) - for i, val := range c.Validators { + genTxs := make([]json.RawMessage, len(c.validators)) + for i, val := range c.validators { stakeAmountCoin := StakeAmountCoinA - if c.Id != ChainAID { + if c.chainMeta.Id != ChainAID { stakeAmountCoin = StakeAmountCoinB } createValmsg, err := val.buildCreateValidatorMsg(stakeAmountCoin) @@ -209,38 +209,38 @@ func initGenesis(c *Chain) error { } // write the updated genesis file to each validator - for _, val := range c.Validators { - if err := util.WriteFile(filepath.Join(val.ConfigDir(), "config", "genesis.json"), bz); err != nil { + for _, val := range c.validators { + if err := util.WriteFile(filepath.Join(val.configDir(), "config", "genesis.json"), bz); err != nil { return err } } return nil } -func initNodes(c *Chain) error { +func initNodes(c *internalChain) error { if err := c.createAndInitValidators(2); err != nil { return err } // initialize a genesis file for the first validator - val0ConfigDir := c.Validators[0].ConfigDir() - for _, val := range c.Validators { - if c.Id == ChainAID { - if err := addAccount(val0ConfigDir, "", InitBalanceStrA, val.GetKeyInfo().GetAddress()); err != nil { + val0ConfigDir := c.validators[0].configDir() + for _, val := range c.validators { + if c.chainMeta.Id == ChainAID { + if err := addAccount(val0ConfigDir, "", InitBalanceStrA, val.getKeyInfo().GetAddress()); err != nil { return err } - } else if c.Id == ChainBID { - if err := addAccount(val0ConfigDir, "", InitBalanceStrB, val.GetKeyInfo().GetAddress()); err != nil { + } else if c.chainMeta.Id == ChainBID { + if err := addAccount(val0ConfigDir, "", InitBalanceStrB, val.getKeyInfo().GetAddress()); err != nil { return err } } } // copy the genesis file to the remaining validators - for _, val := range c.Validators[1:] { + for _, val := range c.validators[1:] { _, err := util.CopyFile( filepath.Join(val0ConfigDir, "config", "genesis.json"), - filepath.Join(val.ConfigDir(), "config", "genesis.json"), + filepath.Join(val.configDir(), "config", "genesis.json"), ) if err != nil { return err @@ -249,9 +249,9 @@ func initNodes(c *Chain) error { return nil } -func initValidatorConfigs(c *Chain) error { - for i, val := range c.Validators { - tmCfgPath := filepath.Join(val.ConfigDir(), "config", "config.toml") +func initValidatorConfigs(c *internalChain) error { + for i, val := range c.validators { + tmCfgPath := filepath.Join(val.configDir(), "config", "config.toml") vpr := viper.New() vpr.SetConfigFile(tmCfgPath) @@ -266,20 +266,20 @@ func initValidatorConfigs(c *Chain) error { valConfig.P2P.ListenAddress = "tcp://0.0.0.0:26656" valConfig.P2P.AddrBookStrict = false - valConfig.P2P.ExternalAddress = fmt.Sprintf("%s:%d", val.InstanceName(), 26656) + valConfig.P2P.ExternalAddress = fmt.Sprintf("%s:%d", val.instanceName(), 26656) valConfig.RPC.ListenAddress = "tcp://0.0.0.0:26657" valConfig.StateSync.Enable = false valConfig.LogLevel = "info" var peers []string - for j := 0; j < len(c.Validators); j++ { + for j := 0; j < len(c.validators); j++ { if i == j { continue } - peer := c.Validators[j] - peerID := fmt.Sprintf("%s@%s%d:26656", peer.getNodeKey().ID(), peer.GetMoniker(), j) + peer := c.validators[j] + peerID := fmt.Sprintf("%s@%s%d:26656", peer.getNodeKey().ID(), peer.getMoniker(), j) peers = append(peers, peerID) } @@ -288,7 +288,7 @@ func initValidatorConfigs(c *Chain) error { tmconfig.WriteConfigFile(tmCfgPath, valConfig) // set application configuration - appCfgPath := filepath.Join(val.ConfigDir(), "config", "app.toml") + appCfgPath := filepath.Join(val.configDir(), "config", "app.toml") appConfig := srvconfig.DefaultConfig() appConfig.API.Enable = true diff --git a/tests/e2e/chain/export.go b/tests/e2e/chain/export.go new file mode 100644 index 00000000000..d2b7922dbaa --- /dev/null +++ b/tests/e2e/chain/export.go @@ -0,0 +1,25 @@ +package chain + +import "fmt" + +type ChainMeta struct { + DataDir string `json:"dataDir"` + Id string `json:"id"` +} + +type Validator struct { + Name string `json:"name"` + ConfigDir string `json:"configDir"` + Index int `json:"index"` + Mnemonic string `json:"mnemonic"` + PublicAddress string `json:"publicAddress"` +} + +type Chain struct { + ChainMeta ChainMeta `json:"chainMeta"` + Validators []*Validator `json:"validators"` +} + +func (c *ChainMeta) configDir() string { + return fmt.Sprintf("%s/%s", c.DataDir, c.Id) +} diff --git a/tests/e2e/chain/main.go b/tests/e2e/chain/main.go index 20453d7186d..56cfc89b329 100644 --- a/tests/e2e/chain/main.go +++ b/tests/e2e/chain/main.go @@ -14,5 +14,5 @@ func Init(id, dataDir string) (*Chain, error) { if err := initValidatorConfigs(chain); err != nil { return nil, err } - return chain, nil + return chain.export(), nil } diff --git a/tests/e2e/chain/validator.go b/tests/e2e/chain/validator.go index a494a5d2355..5f57a71a2bc 100644 --- a/tests/e2e/chain/validator.go +++ b/tests/e2e/chain/validator.go @@ -30,8 +30,8 @@ import ( "github.com/osmosis-labs/osmosis/v7/tests/e2e/util" ) -type Validator struct { - chain *Chain +type internalValidator struct { + chain *internalChain index int moniker string mnemonic string @@ -42,31 +42,27 @@ type Validator struct { nodeKey p2p.NodeKey } -func (v *Validator) InstanceName() string { +func (v *internalValidator) instanceName() string { return fmt.Sprintf("%s%d", v.moniker, v.index) } -func (v *Validator) ConfigDir() string { - return fmt.Sprintf("%s/%s", v.chain.configDir(), v.InstanceName()) +func (v *internalValidator) configDir() string { + return fmt.Sprintf("%s/%s", v.chain.chainMeta.configDir(), v.instanceName()) } -func (v *Validator) GetKeyInfo() keyring.Info { +func (v *internalValidator) getKeyInfo() keyring.Info { return v.keyInfo } -func (v *Validator) GetMoniker() string { +func (v *internalValidator) getMoniker() string { return v.moniker } -func (v *Validator) GetMnemonic() string { +func (v *internalValidator) getMnemonic() string { return v.mnemonic } -func (v *Validator) GetIndex() int { - return v.index -} - -func (v *Validator) buildCreateValidatorMsg(amount sdk.Coin) (sdk.Msg, error) { +func (v *internalValidator) buildCreateValidatorMsg(amount sdk.Coin) (sdk.Msg, error) { description := stakingtypes.NewDescription(v.moniker, "", "", "", "") commissionRates := stakingtypes.CommissionRates{ Rate: sdk.MustNewDecFromStr("0.1"), @@ -92,16 +88,16 @@ func (v *Validator) buildCreateValidatorMsg(amount sdk.Coin) (sdk.Msg, error) { ) } -func (v *Validator) createConfig() error { - p := path.Join(v.ConfigDir(), "config") +func (v *internalValidator) createConfig() error { + p := path.Join(v.configDir(), "config") return os.MkdirAll(p, 0o755) } -func (v *Validator) createNodeKey() error { +func (v *internalValidator) createNodeKey() error { serverCtx := server.NewDefaultContext() config := serverCtx.Config - config.SetRoot(v.ConfigDir()) + config.SetRoot(v.configDir()) config.Moniker = v.moniker nodeKey, err := p2p.LoadOrGenNodeKey(config.NodeKeyFile()) @@ -113,11 +109,11 @@ func (v *Validator) createNodeKey() error { return nil } -func (v *Validator) createConsensusKey() error { +func (v *internalValidator) createConsensusKey() error { serverCtx := server.NewDefaultContext() config := serverCtx.Config - config.SetRoot(v.ConfigDir()) + config.SetRoot(v.configDir()) config.Moniker = v.moniker pvKeyFile := config.PrivValidatorKeyFile() @@ -136,8 +132,8 @@ func (v *Validator) createConsensusKey() error { return nil } -func (v *Validator) createKeyFromMnemonic(name, mnemonic string) error { - kb, err := keyring.New(keyringAppName, keyring.BackendTest, v.ConfigDir(), nil) +func (v *internalValidator) createKeyFromMnemonic(name, mnemonic string) error { + kb, err := keyring.New(keyringAppName, keyring.BackendTest, v.configDir(), nil) if err != nil { return err } @@ -170,7 +166,7 @@ func (v *Validator) createKeyFromMnemonic(name, mnemonic string) error { return nil } -func (v *Validator) createKey(name string) error { +func (v *internalValidator) createKey(name string) error { mnemonic, err := createMnemonic() if err != nil { return err @@ -179,14 +175,24 @@ func (v *Validator) createKey(name string) error { return v.createKeyFromMnemonic(name, mnemonic) } -func (v *Validator) getNodeKey() *p2p.NodeKey { +func (v *internalValidator) export() *Validator { + return &Validator{ + Name: v.instanceName(), + ConfigDir: v.configDir(), + Index: v.index, + Mnemonic: v.mnemonic, + PublicAddress: v.keyInfo.GetAddress().String(), + } +} + +func (v *internalValidator) getNodeKey() *p2p.NodeKey { return &v.nodeKey } -func (v *Validator) getGenesisDoc() (*tmtypes.GenesisDoc, error) { +func (v *internalValidator) getGenesisDoc() (*tmtypes.GenesisDoc, error) { serverCtx := server.NewDefaultContext() config := serverCtx.Config - config.SetRoot(v.ConfigDir()) + config.SetRoot(v.configDir()) genFile := config.GenesisFile() doc := &tmtypes.GenesisDoc{} @@ -207,7 +213,7 @@ func (v *Validator) getGenesisDoc() (*tmtypes.GenesisDoc, error) { return doc, nil } -func (v *Validator) init() error { +func (v *internalValidator) init() error { if err := v.createConfig(); err != nil { return err } @@ -215,7 +221,7 @@ func (v *Validator) init() error { serverCtx := server.NewDefaultContext() config := serverCtx.Config - config.SetRoot(v.ConfigDir()) + config.SetRoot(v.configDir()) config.Moniker = v.moniker genDoc, err := v.getGenesisDoc() @@ -228,7 +234,7 @@ func (v *Validator) init() error { return fmt.Errorf("failed to JSON encode app genesis state: %w", err) } - genDoc.ChainID = v.chain.Id + genDoc.ChainID = v.chain.chainMeta.Id genDoc.Validators = nil genDoc.AppState = appState @@ -254,19 +260,19 @@ func createMnemonic() (string, error) { return mnemonic, nil } -func (v *Validator) signMsg(msgs ...sdk.Msg) (*sdktx.Tx, error) { +func (v *internalValidator) signMsg(msgs ...sdk.Msg) (*sdktx.Tx, error) { txBuilder := util.EncodingConfig.TxConfig.NewTxBuilder() if err := txBuilder.SetMsgs(msgs...); err != nil { return nil, err } - txBuilder.SetMemo(fmt.Sprintf("%s@%s:26656", v.nodeKey.ID(), v.InstanceName())) + txBuilder.SetMemo(fmt.Sprintf("%s@%s:26656", v.nodeKey.ID(), v.instanceName())) txBuilder.SetFeeAmount(sdk.NewCoins()) txBuilder.SetGasLimit(200000) signerData := authsigning.SignerData{ - ChainID: v.chain.Id, + ChainID: v.chain.chainMeta.Id, AccountNumber: 0, Sequence: 0, } diff --git a/tests/e2e/chain_init/main.go b/tests/e2e/chain_init/main.go index edb26b0c199..12275a56baa 100644 --- a/tests/e2e/chain_init/main.go +++ b/tests/e2e/chain_init/main.go @@ -1,6 +1,7 @@ package main import ( + "encoding/json" "flag" "fmt" "os" @@ -9,8 +10,13 @@ import ( ) func main() { - var dataDir string + var ( + dataDir string + chainId string + ) + flag.StringVar(&dataDir, "data-dir", "", "chain data directory") + flag.StringVar(&chainId, "chain-id", "", "chain ID") flag.Parse() if len(dataDir) == 0 { @@ -21,9 +27,14 @@ func main() { panic(err) } - chain, err := chain.Init(chain.ChainAID, dataDir) + createdChain, err := chain.Init(chainId, dataDir) if err != nil { panic(err) } - fmt.Println(chain) + + b, _ := json.Marshal(createdChain) + fileName := fmt.Sprintf("%v/%v-encode", dataDir, chainId) + if err = os.WriteFile(fileName, b, 0777); err != nil { + panic(err) + } } diff --git a/tests/e2e/e2e_setup_test.go b/tests/e2e/e2e_setup_test.go index b3f8988df21..7e2ac86197e 100644 --- a/tests/e2e/e2e_setup_test.go +++ b/tests/e2e/e2e_setup_test.go @@ -24,6 +24,8 @@ import ( "github.com/osmosis-labs/osmosis/v7/tests/e2e/util" ) +const maxRetries = 10 // max retries for json unmarshalling + type IntegrationTestSuite struct { suite.Suite @@ -32,6 +34,7 @@ type IntegrationTestSuite struct { dkrPool *dockertest.Pool dkrNet *dockertest.Network hermesResource *dockertest.Resource + initResource *dockertest.Resource valResources map[string][]*dockertest.Resource } @@ -52,10 +55,12 @@ func (s *IntegrationTestSuite) SetupSuite() { // 2. Start both networks. // 3. Run IBC relayer betweeen the two chains. // 4. Execute various e2e tests, including IBC. + s.configureDockerResources(chain.ChainAID, chain.ChainBID) + s.configureChain(chain.ChainAID) + s.Require().NoError(s.dkrPool.Purge(s.initResource)) s.configureChain(chain.ChainBID) - - s.configureDockerResources() + s.Require().NoError(s.dkrPool.Purge(s.initResource)) s.runValidators(s.chains[0], 0) s.runValidators(s.chains[1], 10) @@ -85,7 +90,7 @@ func (s *IntegrationTestSuite) TearDownSuite() { s.Require().NoError(s.dkrPool.RemoveNetwork(s.dkrNet)) for _, chain := range s.chains { - os.RemoveAll(chain.DataDir) + os.RemoveAll(chain.ChainMeta.DataDir) } for _, td := range s.tmpDirs { @@ -94,22 +99,22 @@ func (s *IntegrationTestSuite) TearDownSuite() { } func (s *IntegrationTestSuite) runValidators(c *chain.Chain, portOffset int) { - s.T().Logf("starting Osmosis %s validator containers...", c.Id) + s.T().Logf("starting Osmosis %s validator containers...", c.ChainMeta.Id) - s.valResources[c.Id] = make([]*dockertest.Resource, len(c.Validators)) + s.valResources[c.ChainMeta.Id] = make([]*dockertest.Resource, len(c.Validators)) for i, val := range c.Validators { runOpts := &dockertest.RunOptions{ - Name: val.InstanceName(), + Name: val.Name, NetworkID: s.dkrNet.Network.ID, Mounts: []string{ - fmt.Sprintf("%s/:/osmosis/.osmosisd", val.ConfigDir()), + fmt.Sprintf("%s/:/osmosis/.osmosisd", val.ConfigDir), }, Repository: "osmosis", Tag: "debug", } // expose the first validator for debugging and communication - if val.GetIndex() == 0 { + if val.Index == 0 { runOpts.PortBindings = map[docker.Port][]docker.PortBinding{ "1317/tcp": {{HostIP: "", HostPort: fmt.Sprintf("%d", 1317+portOffset)}}, "6060/tcp": {{HostIP: "", HostPort: fmt.Sprintf("%d", 6060+portOffset)}}, @@ -127,8 +132,8 @@ func (s *IntegrationTestSuite) runValidators(c *chain.Chain, portOffset int) { resource, err := s.dkrPool.RunWithOptions(runOpts, noRestart) s.Require().NoError(err) - s.valResources[c.Id][i] = resource - s.T().Logf("started Osmosis %s validator container: %s", c.Id, resource.Container.ID) + s.valResources[c.ChainMeta.Id][i] = resource + s.T().Logf("started Osmosis %s validator container: %s", c.ChainMeta.Id, resource.Container.ID) } rpcClient, err := rpchttp.New("tcp://localhost:26657", "/websocket") @@ -177,7 +182,7 @@ func (s *IntegrationTestSuite) runIBCRelayer() { s.hermesResource, err = s.dkrPool.RunWithOptions( &dockertest.RunOptions{ - Name: fmt.Sprintf("%s-%s-relayer", s.chains[0].Id, s.chains[1].Id), + Name: fmt.Sprintf("%s-%s-relayer", s.chains[0].ChainMeta.Id, s.chains[1].ChainMeta.Id), Repository: "osmolabs/hermes", Tag: "0.13.0", NetworkID: s.dkrNet.Network.ID, @@ -195,12 +200,12 @@ func (s *IntegrationTestSuite) runIBCRelayer() { "3031/tcp": {{HostIP: "", HostPort: "3031"}}, }, Env: []string{ - fmt.Sprintf("OSMO_A_E2E_CHAIN_ID=%s", s.chains[0].Id), - fmt.Sprintf("OSMO_B_E2E_CHAIN_ID=%s", s.chains[1].Id), - fmt.Sprintf("OSMO_A_E2E_VAL_MNEMONIC=%s", osmoAVal.GetMnemonic()), - fmt.Sprintf("OSMO_B_E2E_VAL_MNEMONIC=%s", osmoBVal.GetMnemonic()), - fmt.Sprintf("OSMO_A_E2E_VAL_HOST=%s", s.valResources[s.chains[0].Id][0].Container.Name[1:]), - fmt.Sprintf("OSMO_B_E2E_VAL_HOST=%s", s.valResources[s.chains[1].Id][0].Container.Name[1:]), + fmt.Sprintf("OSMO_A_E2E_CHAIN_ID=%s", s.chains[0].ChainMeta.Id), + fmt.Sprintf("OSMO_B_E2E_CHAIN_ID=%s", s.chains[1].ChainMeta.Id), + fmt.Sprintf("OSMO_A_E2E_VAL_MNEMONIC=%s", osmoAVal.Mnemonic), + fmt.Sprintf("OSMO_B_E2E_VAL_MNEMONIC=%s", osmoBVal.Mnemonic), + fmt.Sprintf("OSMO_A_E2E_VAL_HOST=%s", s.valResources[s.chains[0].ChainMeta.Id][0].Container.Name[1:]), + fmt.Sprintf("OSMO_B_E2E_VAL_HOST=%s", s.valResources[s.chains[1].ChainMeta.Id][0].Container.Name[1:]), }, Entrypoint: []string{ "sh", @@ -255,18 +260,61 @@ func (s *IntegrationTestSuite) runIBCRelayer() { func (s *IntegrationTestSuite) configureChain(chainId string) { s.T().Logf("starting e2e infrastructure for chain-id: %s", chainId) tmpDir, err := ioutil.TempDir("", "osmosis-e2e-testnet-") + + s.T().Logf("temp directory for chain-id %v: %v", chainId, tmpDir) s.Require().NoError(err) - newChain, err := chain.Init(chainId, tmpDir) - s.chains = append(s.chains, newChain) + + s.initResource, err = s.dkrPool.RunWithOptions( + &dockertest.RunOptions{ + Name: fmt.Sprintf("%s", chainId), + Repository: "osmosis-e2e-chain-init", + Tag: "debug", + NetworkID: s.dkrNet.Network.ID, + Cmd: []string{ + fmt.Sprintf("--data-dir=%s", tmpDir), + fmt.Sprintf("--chain-id=%s", chainId), + }, + User: "root:root", + Mounts: []string{ + fmt.Sprintf("%s:%s", tmpDir, tmpDir), + }, + }, + noRestart, + ) s.Require().NoError(err) + + var newChain chain.Chain + + fileName := fmt.Sprintf("%v/%v-encode", tmpDir, chainId) + s.T().Logf("serialized init file for chain-id %v: %v", chainId, fileName) + + // loop through the reading and unmarshaling of the init file a total of maxRetries or until error is nil + // without this, test attempts to unmarshal file before docker container is finished writing + for i := 0; i < maxRetries; i++ { + encJson, _ := os.ReadFile(fileName) + err = json.Unmarshal(encJson, &newChain) + if err == nil { + break + } + + if i == maxRetries-1 { + s.Require().NoError(err) + } + + if i > 0 { + time.Sleep(1 * time.Second) + } + } + s.chains = append(s.chains, &newChain) + } -func (s *IntegrationTestSuite) configureDockerResources() { +func (s *IntegrationTestSuite) configureDockerResources(chainIDOne, chainIDTwo string) { var err error s.dkrPool, err = dockertest.NewPool("") s.Require().NoError(err) - s.dkrNet, err = s.dkrPool.CreateNetwork(fmt.Sprintf("%s-%s-testnet", s.chains[0].Id, s.chains[1].Id)) + s.dkrNet, err = s.dkrPool.CreateNetwork(fmt.Sprintf("%s-%s-testnet", chainIDOne, chainIDTwo)) s.Require().NoError(err) s.valResources = make(map[string][]*dockertest.Resource) diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index f00327dc16e..01b98400fce 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -22,14 +22,14 @@ func (s *IntegrationTestSuite) TestQueryBalances() { expectedBalancesB = []uint64{chain.OsmoBalanceB, chain.StakeBalanceB - chain.StakeAmountB, chain.IbcSendAmount} ) - chainAAPIEndpoint := fmt.Sprintf("http://%s", s.valResources[s.chains[0].Id][0].GetHostPort("1317/tcp")) - balancesA, err := queryBalances(chainAAPIEndpoint, s.chains[0].Validators[0].GetKeyInfo().GetAddress().String()) + chainAAPIEndpoint := fmt.Sprintf("http://%s", s.valResources[s.chains[0].ChainMeta.Id][0].GetHostPort("1317/tcp")) + balancesA, err := queryBalances(chainAAPIEndpoint, s.chains[0].Validators[0].PublicAddress) s.Require().NoError(err) s.Require().NotNil(balancesA) s.Require().Equal(2, len(balancesA)) - chainBAPIEndpoint := fmt.Sprintf("http://%s", s.valResources[s.chains[1].Id][0].GetHostPort("1317/tcp")) - balancesB, err := queryBalances(chainBAPIEndpoint, s.chains[1].Validators[0].GetKeyInfo().GetAddress().String()) + chainBAPIEndpoint := fmt.Sprintf("http://%s", s.valResources[s.chains[1].ChainMeta.Id][0].GetHostPort("1317/tcp")) + balancesB, err := queryBalances(chainBAPIEndpoint, s.chains[1].Validators[0].PublicAddress) s.Require().NoError(err) s.Require().NotNil(balancesB) s.Require().Equal(3, len(balancesB)) @@ -100,11 +100,11 @@ func (s *IntegrationTestSuite) TestIBCTokenTransfer() { var ibcStakeDenom string s.Run("send_uosmo_to_chainB", func() { - recipient := s.chains[1].Validators[0].GetKeyInfo().GetAddress().String() + recipient := s.chains[1].Validators[0].PublicAddress token := sdk.NewInt64Coin(chain.OsmoDenom, chain.IbcSendAmount) // 3,300uosmo - s.sendIBC(s.chains[0].Id, s.chains[1].Id, recipient, token) + s.sendIBC(s.chains[0].ChainMeta.Id, s.chains[1].ChainMeta.Id, recipient, token) - chainBAPIEndpoint := fmt.Sprintf("http://%s", s.valResources[s.chains[1].Id][0].GetHostPort("1317/tcp")) + chainBAPIEndpoint := fmt.Sprintf("http://%s", s.valResources[s.chains[1].ChainMeta.Id][0].GetHostPort("1317/tcp")) // require the recipient account receives the IBC tokens (IBC packets ACKd) var ( diff --git a/tests/e2e/e2e_util_test.go b/tests/e2e/e2e_util_test.go index fb6d7de3727..83976442b76 100644 --- a/tests/e2e/e2e_util_test.go +++ b/tests/e2e/e2e_util_test.go @@ -11,7 +11,7 @@ import ( ) func (s *IntegrationTestSuite) connectIBCChains() { - s.T().Logf("connecting %s and %s chains via IBC", s.chains[0].Id, s.chains[1].Id) + s.T().Logf("connecting %s and %s chains via IBC", s.chains[0].ChainMeta.Id, s.chains[1].ChainMeta.Id) ctx, cancel := context.WithTimeout(context.Background(), time.Minute) defer cancel() @@ -26,8 +26,8 @@ func (s *IntegrationTestSuite) connectIBCChains() { "hermes", "create", "channel", - s.chains[0].Id, - s.chains[1].Id, + s.chains[0].ChainMeta.Id, + s.chains[1].ChainMeta.Id, "--port-a=transfer", "--port-b=transfer", }, @@ -56,7 +56,7 @@ func (s *IntegrationTestSuite) connectIBCChains() { "failed to connect chains via IBC: %s", errBuf.String(), ) - s.T().Logf("connected %s and %s chains via IBC", s.chains[0].Id, s.chains[1].Id) + s.T().Logf("connected %s and %s chains via IBC", s.chains[0].ChainMeta.Id, s.chains[1].ChainMeta.Id) } func (s *IntegrationTestSuite) sendIBC(srcChainID, dstChainID, recipient string, token sdk.Coin) {