Skip to content

Commit

Permalink
e2e: Refactor suite setup and helpers to tests/fixture/e2e for reuse …
Browse files Browse the repository at this point in the history
…by coreth (#2265)
  • Loading branch information
maru-ava authored Nov 8, 2023
1 parent fc95834 commit aba404e
Show file tree
Hide file tree
Showing 17 changed files with 212 additions and 163 deletions.
2 changes: 1 addition & 1 deletion tests/e2e/banff/suites.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (

"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/avalanchego/tests"
"github.com/ava-labs/avalanchego/tests/e2e"
"github.com/ava-labs/avalanchego/tests/fixture/e2e"
"github.com/ava-labs/avalanchego/utils/constants"
"github.com/ava-labs/avalanchego/utils/units"
"github.com/ava-labs/avalanchego/vms/components/avax"
Expand Down
2 changes: 1 addition & 1 deletion tests/e2e/c/dynamic_fees.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import (
"github.com/ava-labs/coreth/plugin/evm"

"github.com/ava-labs/avalanchego/tests"
"github.com/ava-labs/avalanchego/tests/e2e"
"github.com/ava-labs/avalanchego/tests/fixture/e2e"
"github.com/ava-labs/avalanchego/tests/fixture/testnet"
"github.com/ava-labs/avalanchego/utils/crypto/secp256k1"
)
Expand Down
2 changes: 1 addition & 1 deletion tests/e2e/c/interchain_workflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
"github.com/ava-labs/coreth/plugin/evm"

"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/avalanchego/tests/e2e"
"github.com/ava-labs/avalanchego/tests/fixture/e2e"
"github.com/ava-labs/avalanchego/utils/constants"
"github.com/ava-labs/avalanchego/utils/crypto/secp256k1"
"github.com/ava-labs/avalanchego/utils/set"
Expand Down
76 changes: 5 additions & 71 deletions tests/e2e/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,13 @@
package e2e_test

import (
"encoding/json"
"flag"
"fmt"
"os"
"testing"

ginkgo "github.com/onsi/ginkgo/v2"

"github.com/onsi/gomega"

"github.com/stretchr/testify/require"

"github.com/ava-labs/avalanchego/tests"
"github.com/ava-labs/avalanchego/tests/e2e"
"github.com/ava-labs/avalanchego/tests/fixture"
"github.com/ava-labs/avalanchego/tests/fixture/testnet/local"
"github.com/ava-labs/avalanchego/tests/fixture/e2e"

// ensure test packages are scanned by ginkgo
_ "github.com/ava-labs/avalanchego/tests/e2e/banff"
Expand All @@ -36,75 +27,18 @@ func TestE2E(t *testing.T) {
ginkgo.RunSpecs(t, "e2e test suites")
}

var (
avalancheGoExecPath string
persistentNetworkDir string
usePersistentNetwork bool
)
var flagVars *e2e.FlagVars

func init() {
flag.StringVar(
&avalancheGoExecPath,
"avalanchego-path",
os.Getenv(local.AvalancheGoPathEnvName),
fmt.Sprintf("avalanchego executable path (required if not using a persistent network). Also possible to configure via the %s env variable.", local.AvalancheGoPathEnvName),
)
flag.StringVar(
&persistentNetworkDir,
"network-dir",
"",
fmt.Sprintf("[optional] the dir containing the configuration of a persistent network to target for testing. Useful for speeding up test development. Also possible to configure via the %s env variable.", local.NetworkDirEnvName),
)
flag.BoolVar(
&usePersistentNetwork,
"use-persistent-network",
false,
"[optional] whether to target the persistent network identified by --network-dir.",
)
flagVars = e2e.RegisterFlags()
}

var _ = ginkgo.SynchronizedBeforeSuite(func() []byte {
// Run only once in the first ginkgo process

require := require.New(ginkgo.GinkgoT())

if usePersistentNetwork && len(persistentNetworkDir) == 0 {
persistentNetworkDir = os.Getenv(local.NetworkDirEnvName)
}

// Load or create a test network
var network *local.LocalNetwork
if len(persistentNetworkDir) > 0 {
tests.Outf("{{yellow}}Using a persistent network configured at %s{{/}}\n", persistentNetworkDir)

var err error
network, err = local.ReadNetwork(persistentNetworkDir)
require.NoError(err)
} else {
network = e2e.StartLocalNetwork(avalancheGoExecPath, e2e.DefaultNetworkDir)
}

uris := network.GetURIs()
require.NotEmpty(uris, "network contains no nodes")
tests.Outf("{{green}}network URIs: {{/}} %+v\n", uris)

testDataServerURI, err := fixture.ServeTestData(fixture.TestData{
FundedKeys: network.FundedKeys,
})
tests.Outf("{{green}}test data server URI: {{/}} %+v\n", testDataServerURI)
require.NoError(err)

env := &e2e.TestEnvironment{
NetworkDir: network.Dir,
URIs: uris,
TestDataServerURI: testDataServerURI,
}
bytes, err := json.Marshal(env)
require.NoError(err)
return bytes
return e2e.NewTestEnvironment(flagVars).Marshal()
}, func(envBytes []byte) {
// Run in every ginkgo process

// Initialize the local test environment from the global state
e2e.InitTestEnvironment(envBytes)
e2e.InitSharedTestEnvironment(envBytes)
})
2 changes: 1 addition & 1 deletion tests/e2e/faultinjection/duplicate_node_id.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
"github.com/ava-labs/avalanchego/api/info"
"github.com/ava-labs/avalanchego/config"
"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/avalanchego/tests/e2e"
"github.com/ava-labs/avalanchego/tests/fixture/e2e"
"github.com/ava-labs/avalanchego/tests/fixture/testnet"
"github.com/ava-labs/avalanchego/utils/set"
)
Expand Down
2 changes: 1 addition & 1 deletion tests/e2e/p/interchain_workflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import (
"github.com/ava-labs/avalanchego/api/info"
"github.com/ava-labs/avalanchego/config"
"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/avalanchego/tests/e2e"
"github.com/ava-labs/avalanchego/tests/fixture/e2e"
"github.com/ava-labs/avalanchego/tests/fixture/testnet"
"github.com/ava-labs/avalanchego/utils/constants"
"github.com/ava-labs/avalanchego/utils/crypto/secp256k1"
Expand Down
2 changes: 1 addition & 1 deletion tests/e2e/p/permissionless_subnets.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
"github.com/stretchr/testify/require"

"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/avalanchego/tests/e2e"
"github.com/ava-labs/avalanchego/tests/fixture/e2e"
"github.com/ava-labs/avalanchego/utils/constants"
"github.com/ava-labs/avalanchego/utils/units"
"github.com/ava-labs/avalanchego/vms/components/avax"
Expand Down
2 changes: 1 addition & 1 deletion tests/e2e/p/staking_rewards.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import (
"github.com/ava-labs/avalanchego/config"
"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/avalanchego/tests"
"github.com/ava-labs/avalanchego/tests/e2e"
"github.com/ava-labs/avalanchego/tests/fixture/e2e"
"github.com/ava-labs/avalanchego/tests/fixture/testnet"
"github.com/ava-labs/avalanchego/utils/constants"
"github.com/ava-labs/avalanchego/utils/crypto/secp256k1"
Expand Down
2 changes: 1 addition & 1 deletion tests/e2e/p/workflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
"github.com/ava-labs/avalanchego/api/info"
"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/avalanchego/tests"
"github.com/ava-labs/avalanchego/tests/e2e"
"github.com/ava-labs/avalanchego/tests/fixture/e2e"
"github.com/ava-labs/avalanchego/utils"
"github.com/ava-labs/avalanchego/utils/constants"
"github.com/ava-labs/avalanchego/utils/units"
Expand Down
2 changes: 1 addition & 1 deletion tests/e2e/static-handlers/suites.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
"github.com/stretchr/testify/require"

"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/avalanchego/tests/e2e"
"github.com/ava-labs/avalanchego/tests/fixture/e2e"
"github.com/ava-labs/avalanchego/utils/cb58"
"github.com/ava-labs/avalanchego/utils/constants"
"github.com/ava-labs/avalanchego/utils/crypto/secp256k1"
Expand Down
2 changes: 1 addition & 1 deletion tests/e2e/x/interchain_workflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
"github.com/ava-labs/coreth/plugin/evm"

"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/avalanchego/tests/e2e"
"github.com/ava-labs/avalanchego/tests/fixture/e2e"
"github.com/ava-labs/avalanchego/utils/constants"
"github.com/ava-labs/avalanchego/utils/crypto/secp256k1"
"github.com/ava-labs/avalanchego/utils/set"
Expand Down
2 changes: 1 addition & 1 deletion tests/e2e/x/transfer/virtuous.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import (
"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/avalanchego/snow/choices"
"github.com/ava-labs/avalanchego/tests"
"github.com/ava-labs/avalanchego/tests/e2e"
"github.com/ava-labs/avalanchego/tests/fixture/e2e"
"github.com/ava-labs/avalanchego/utils/set"
"github.com/ava-labs/avalanchego/vms/avm"
"github.com/ava-labs/avalanchego/vms/components/avax"
Expand Down
File renamed without changes.
138 changes: 138 additions & 0 deletions tests/fixture/e2e/env.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package e2e

import (
"encoding/json"
"math/rand"
"os"
"path/filepath"
"time"

ginkgo "github.com/onsi/ginkgo/v2"

"github.com/stretchr/testify/require"

"github.com/ava-labs/avalanchego/tests"
"github.com/ava-labs/avalanchego/tests/fixture"
"github.com/ava-labs/avalanchego/tests/fixture/testnet"
"github.com/ava-labs/avalanchego/tests/fixture/testnet/local"
"github.com/ava-labs/avalanchego/utils/crypto/secp256k1"
"github.com/ava-labs/avalanchego/utils/perms"
"github.com/ava-labs/avalanchego/vms/secp256k1fx"
)

// Env is used to access shared test fixture. Intended to be
// initialized from SynchronizedBeforeSuite.
var Env *TestEnvironment

func InitSharedTestEnvironment(envBytes []byte) {
require := require.New(ginkgo.GinkgoT())
require.Nil(Env, "env already initialized")
Env = &TestEnvironment{
require: require,
}
require.NoError(json.Unmarshal(envBytes, Env))
}

type TestEnvironment struct {
// The directory where the test network configuration is stored
NetworkDir string
// URIs used to access the API endpoints of nodes of the network
URIs []testnet.NodeURI
// The URI used to access the http server that allocates test data
TestDataServerURI string

require *require.Assertions
}

func (te *TestEnvironment) Marshal() []byte {
bytes, err := json.Marshal(te)
require.NoError(ginkgo.GinkgoT(), err)
return bytes
}

// Initialize a new test environment with a shared network (either pre-existing or newly created).
func NewTestEnvironment(flagVars *FlagVars) *TestEnvironment {
require := require.New(ginkgo.GinkgoT())

persistentNetworkDir := flagVars.PersistentNetworkDir()

// Load or create a test network
var network *local.LocalNetwork
if len(persistentNetworkDir) > 0 {
tests.Outf("{{yellow}}Using a persistent network configured at %s{{/}}\n", persistentNetworkDir)

var err error
network, err = local.ReadNetwork(persistentNetworkDir)
require.NoError(err)
} else {
network = StartLocalNetwork(flagVars.AvalancheGoExecPath(), DefaultNetworkDir)
}

uris := network.GetURIs()
require.NotEmpty(uris, "network contains no nodes")
tests.Outf("{{green}}network URIs: {{/}} %+v\n", uris)

testDataServerURI, err := fixture.ServeTestData(fixture.TestData{
FundedKeys: network.FundedKeys,
})
tests.Outf("{{green}}test data server URI: {{/}} %+v\n", testDataServerURI)
require.NoError(err)

return &TestEnvironment{
NetworkDir: network.Dir,
URIs: uris,
TestDataServerURI: testDataServerURI,
}
}

// Retrieve a random URI to naively attempt to spread API load across
// nodes.
func (te *TestEnvironment) GetRandomNodeURI() testnet.NodeURI {
r := rand.New(rand.NewSource(time.Now().Unix())) //#nosec G404
nodeURI := te.URIs[r.Intn(len(te.URIs))]
tests.Outf("{{blue}} targeting node %s with URI: %s{{/}}\n", nodeURI.NodeID, nodeURI.URI)
return nodeURI
}

// Retrieve the network to target for testing.
func (te *TestEnvironment) GetNetwork() testnet.Network {
network, err := local.ReadNetwork(te.NetworkDir)
te.require.NoError(err)
return network
}

// Retrieve the specified number of funded keys allocated for the caller's exclusive use.
func (te *TestEnvironment) AllocateFundedKeys(count int) []*secp256k1.PrivateKey {
keys, err := fixture.AllocateFundedKeys(te.TestDataServerURI, count)
te.require.NoError(err)
tests.Outf("{{blue}} allocated funded key(s): %+v{{/}}\n", keys)
return keys
}

// Retrieve a funded key allocated for the caller's exclusive use.
func (te *TestEnvironment) AllocateFundedKey() *secp256k1.PrivateKey {
return te.AllocateFundedKeys(1)[0]
}

// Create a new keychain with the specified number of test keys.
func (te *TestEnvironment) NewKeychain(count int) *secp256k1fx.Keychain {
keys := te.AllocateFundedKeys(count)
return secp256k1fx.NewKeychain(keys...)
}

// Create a new private network that is not shared with other tests.
func (te *TestEnvironment) NewPrivateNetwork() testnet.Network {
// Load the shared network to retrieve its path and exec path
sharedNetwork, err := local.ReadNetwork(te.NetworkDir)
te.require.NoError(err)

// The private networks dir is under the shared network dir to ensure it
// will be included in the artifact uploaded in CI.
privateNetworksDir := filepath.Join(sharedNetwork.Dir, PrivateNetworksDirName)
te.require.NoError(os.MkdirAll(privateNetworksDir, perms.ReadWriteExecute))

return StartLocalNetwork(sharedNetwork.ExecPath, privateNetworksDir)
}
57 changes: 57 additions & 0 deletions tests/fixture/e2e/flags.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package e2e

import (
"flag"
"fmt"
"os"

"github.com/ava-labs/avalanchego/tests/fixture/testnet/local"
)

type FlagVars struct {
avalancheGoExecPath string
persistentNetworkDir string
usePersistentNetwork bool
}

func (v *FlagVars) PersistentNetworkDir() string {
if v.usePersistentNetwork && len(v.persistentNetworkDir) == 0 {
return os.Getenv(local.NetworkDirEnvName)
}
return v.persistentNetworkDir
}

func (v *FlagVars) AvalancheGoExecPath() string {
return v.avalancheGoExecPath
}

func (v *FlagVars) UsePersistentNetwork() bool {
return v.usePersistentNetwork
}

func RegisterFlags() *FlagVars {
vars := FlagVars{}
flag.StringVar(
&vars.avalancheGoExecPath,
"avalanchego-path",
os.Getenv(local.AvalancheGoPathEnvName),
fmt.Sprintf("avalanchego executable path (required if not using a persistent network). Also possible to configure via the %s env variable.", local.AvalancheGoPathEnvName),
)
flag.StringVar(
&vars.persistentNetworkDir,
"network-dir",
"",
fmt.Sprintf("[optional] the dir containing the configuration of a persistent network to target for testing. Useful for speeding up test development. Also possible to configure via the %s env variable.", local.NetworkDirEnvName),
)
flag.BoolVar(
&vars.usePersistentNetwork,
"use-persistent-network",
false,
"[optional] whether to target the persistent network identified by --network-dir.",
)

return &vars
}
Loading

0 comments on commit aba404e

Please sign in to comment.