Skip to content

Commit

Permalink
Setup e2e tests on a single chain; add balances query test (#1193)
Browse files Browse the repository at this point in the history
* create e2e image and a makefile step to build

* progress

* e2e tests in ci

* use root distroless image and correct volume path

* remove chain b references

* implement query balances

* implement TestQueryBalances

* trigger worflow

* trigger

* test-e2e Makefile step

* fmt and sleep if service unavailable

* README

* restore branches

* add changelog entry

* exclude e2e from regular tests

* -E flag for grep exclusion

* grep

* go mod tidy --compat=1.17

* manually tidy go.mod
  • Loading branch information
czarcas7ic committed Apr 29, 2022
1 parent c71f077 commit c32c5b3
Show file tree
Hide file tree
Showing 10 changed files with 212 additions and 109 deletions.
1 change: 1 addition & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,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
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 {
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 {
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 {
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

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

0 comments on commit c32c5b3

Please sign in to comment.