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

test: switch e2e test setup to create genesis and configs via Dockertest #1363

Merged
merged 20 commits into from
Apr 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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: |
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
46 changes: 29 additions & 17 deletions tests/e2e/chain/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
czarcas7ic marked this conversation as resolved.
Show resolved Hide resolved
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)

Expand All @@ -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 {
Expand All @@ -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 {
czarcas7ic marked this conversation as resolved.
Show resolved Hide resolved
for i := 0; i < count; i++ {
// create node
node := c.createValidator(i)
Expand All @@ -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 {
Expand All @@ -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,
}
}
50 changes: 25 additions & 25 deletions tests/e2e/chain/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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 {
Comment on lines 166 to +168
Copy link
Member

Choose a reason for hiding this comment

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

Not relevant to this PR, but I think we should extract this into a separate function, and add some more docs on whats going on with stakeAmountCoin, its non-obvious to me

Copy link
Contributor

Choose a reason for hiding this comment

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

Sure, I believe this is just adding the initial self-bond amount to each validator IIRC.

stakeAmountCoin := StakeAmountCoinA
if c.Id != ChainAID {
if c.chainMeta.Id != ChainAID {
stakeAmountCoin = StakeAmountCoinB
}
createValmsg, err := val.buildCreateValidatorMsg(stakeAmountCoin)
Expand Down Expand Up @@ -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
Expand All @@ -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)
Expand All @@ -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)
}

Expand All @@ -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
Expand Down
25 changes: 25 additions & 0 deletions tests/e2e/chain/export.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package chain
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a doc.go on this package, export? What is it's purpose/intended use-case?

Copy link
Member Author

@czarcas7ic czarcas7ic Apr 28, 2022

Choose a reason for hiding this comment

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

We marshal the data into a json within the docker container in order to later retrieve this data by the e2e test suite. When I initually tried to unmarshal this data however, I ran into an issue where the marshaler did not know how to handle some sdk structs that dont get exported. @p0mvn created this export package in order to export only the required structs needed to initialize the genesis and configs in order to get around this issue.

Copy link
Member

Choose a reason for hiding this comment

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

There is a README explaining what this package is for:
https://github.com/osmosis-labs/osmosis/blob/main/tests/e2e/README.md

@czarcas7ic could you check if README needs to be updated after this PR please

Copy link
Member

Choose a reason for hiding this comment

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

We can probably add to it by saying that the e2e test runner now does chain initialization in the container by default.

Other updates I noticed:

  • there is no upgrade package anymore, it was renamed earlier
  • state marshaling and unmarshaling on the volume


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)
}
2 changes: 1 addition & 1 deletion tests/e2e/chain/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Loading