Skip to content

Commit

Permalink
tmpnet: Separate network into orchestration and configuration
Browse files Browse the repository at this point in the history
- Move methods to read/write network into network_config.go
  • Loading branch information
marun committed Dec 21, 2023
1 parent e41fa53 commit 6939831
Show file tree
Hide file tree
Showing 11 changed files with 516 additions and 602 deletions.
2 changes: 1 addition & 1 deletion tests/e2e/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ Define any flags/configurations in [`e2e.go`](./e2e.go).
Create a new package to implement feature-specific tests, or add tests to an existing package. For example:

```
.
tests
└── e2e
├── README.md
├── e2e.go
Expand Down
4 changes: 2 additions & 2 deletions tests/fixture/e2e/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func NewTestEnvironment(flagVars *FlagVars) *TestEnvironment {
network = StartNetwork(flagVars.AvalancheGoExecPath(), DefaultNetworkDir)
}

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

Expand Down Expand Up @@ -132,5 +132,5 @@ func (te *TestEnvironment) NewPrivateNetwork() *tmpnet.Network {
privateNetworksDir := filepath.Join(sharedNetwork.Dir, PrivateNetworksDirName)
te.require.NoError(os.MkdirAll(privateNetworksDir, perms.ReadWriteExecute))

return StartNetwork(sharedNetwork.AvalancheGoPath, privateNetworksDir)
return StartNetwork(sharedNetwork.DefaultRuntimeConfig.AvalancheGoPath, privateNetworksDir)
}
18 changes: 5 additions & 13 deletions tests/fixture/e2e/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,22 +201,14 @@ func CheckBootstrapIsPossible(network *tmpnet.Network) {
}

// Start a temporary network with the provided avalanchego binary.
func StartNetwork(avalancheGoExecPath string, networkDir string) *tmpnet.Network {
func StartNetwork(avalancheGoExecPath string, rootNetworkDir string) *tmpnet.Network {
require := require.New(ginkgo.GinkgoT())

network, err := tmpnet.StartNetwork(
DefaultContext(),
ginkgo.GinkgoWriter,
networkDir,
&tmpnet.Network{
NodeRuntimeConfig: tmpnet.NodeRuntimeConfig{
AvalancheGoPath: avalancheGoExecPath,
},
},
tmpnet.DefaultNodeCount,
tmpnet.DefaultPreFundedKeyCount,
)
network, err := tmpnet.NewDefaultNetwork(ginkgo.GinkgoWriter, avalancheGoExecPath, tmpnet.DefaultNodeCount)
require.NoError(err)
require.NoError(network.Create(rootNetworkDir))
require.NoError(network.Start(DefaultContext(), ginkgo.GinkgoWriter))

ginkgo.DeferCleanup(func() {
tests.Outf("Shutting down network\n")
ctx, cancel := context.WithTimeout(context.Background(), DefaultTimeout)
Expand Down
72 changes: 19 additions & 53 deletions tests/fixture/tmpnet/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ the following non-test files:
| flags.go | FlagsMap | Simplifies configuration of avalanchego flags |
| genesis.go | | Creates test genesis |
| network.go | Network | Orchestrates and configures temporary networks |
| network_config.go | Network | Reads and writes network configuration |
| node.go | Node | Orchestrates and configures nodes |
| node_config.go | Node | Reads and writes node configuration |
| node_process.go | NodeProcess | Orchestrates node processes |
Expand Down Expand Up @@ -73,60 +74,25 @@ network.
A temporary network can be managed in code:

```golang
network, _ := tmpnet.StartNetwork(
ctx, // Context used to limit duration of waiting for network health
ginkgo.GinkgoWriter, // Writer to report progress of network start
"", // Use default root dir (~/.tmpnet)
&tmpnet.Network{
NodeRuntimeConfig: tmpnet.NodeRuntimeConfig{
ExecPath: "/path/to/avalanchego", // Defining the avalanchego exec path is required
},
},
5, // Number of initial validating nodes
50, // Number of pre-funded keys to create
network, _ := tmpnet.NewDefaultNetwork(
ginkgo.GinkgoWriter, // Writer to report progress of initialization
"/path/to/avalanchego", // The path to the binary that nodes will execute
5, // Number of initial validating nodes
)
_ = network.Create("") // Finalize network configuration and write to disk
_ = network.Start( // Start the nodes of the network and wait until they report healthy
ctx, // Context used to limit duration of waiting for network health
ginkgo.GinkgoWriter, // Writer to report progress of network start
)

uris := network.GetURIs()
uris := network.GetNodeURIs()

// Use URIs to interact with the network

// Stop all nodes in the network
network.Stop()
network.Stop(context.Background())
```

If non-default node behavior is required, the `Network` instance
supplied to `StartNetwork()` can be initialized with explicit node
configuration and by supplying a nodeCount argument of `0`:

```golang
network, _ := tmpnet.StartNetwork(
ctx,
ginkgo.GinkgoWriter,
"",
&tmpnet.Network{
NodeRuntimeConfig: tmpnet.NodeRuntimeConfig{
ExecPath: "/path/to/avalanchego",
},
Nodes: []*Node{
{ // node1 configuration is customized
Flags: FlagsMap{ // Any and all node flags can be configured here
config.DataDirKey: "/custom/path/to/node/data",
}
},
},
{}, // node2 uses default configuration
{}, // node3 uses default configuration
{}, // node4 uses default configuration
{}, // node5 uses default configuration
},
0, // Node count must be zero when setting node config
50,
)
```

Further examples of code-based usage are located in the [e2e
tests](../../e2e/e2e_test.go).

## Networking configuration

By default, nodes in a temporary network will be started with staking and
Expand Down Expand Up @@ -161,18 +127,18 @@ HOME
├── chains
│ └── C
│ └── config.json // C-Chain config for all nodes
├── defaults.json // Default flags and configuration for network
├── config.json // Common configuration (including defaults and pre-funded keys)
├── genesis.json // Genesis for all nodes
└── network.env // Sets network dir env var to simplify network usage
```

### Default flags and configuration
### Common networking configuration

The default avalanchego node flags (e.g. `--staking-port=`) and
default configuration like the avalanchego path are stored at
`[network-dir]/defaults.json`. The value for a given defaulted flag
will be set on initial and subsequently added nodes that do not supply
values for a given defaulted flag.
Network configuration such as default flags (e.g. `--log-level=`),
runtime defaults (e.g. avalanchego path) and pre-funded private keys
are stored at `[network-dir]/config.json`. A given default will only
be applied to a new node on its addition to the network if the node
does not explicitly set a given value.

### Genesis

Expand Down
29 changes: 17 additions & 12 deletions tests/fixture/tmpnet/cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"io/fs"
"os"
"path/filepath"
"time"

"github.com/spf13/cobra"

Expand Down Expand Up @@ -45,10 +46,9 @@ func main() {
rootCmd.AddCommand(versionCmd)

var (
rootDir string
execPath string
nodeCount uint8
preFundedKeyCount uint8
rootDir string
execPath string
nodeCount uint8
)
startNetworkCmd := &cobra.Command{
Use: "start-network",
Expand All @@ -60,15 +60,21 @@ func main() {

// Root dir will be defaulted on start if not provided

network := &tmpnet.Network{
NodeRuntimeConfig: tmpnet.NodeRuntimeConfig{
AvalancheGoPath: execPath,
},
network, err := tmpnet.NewDefaultNetwork(os.Stdout, execPath, int(nodeCount))
if err != nil {
return err
}
ctx, cancel := context.WithTimeout(context.Background(), tmpnet.DefaultNetworkTimeout)

if err := network.Create(rootDir); err != nil {
return err
}

// Extreme upper bound, should never take this long
networkStartTimeout := 2 * time.Minute

ctx, cancel := context.WithTimeout(context.Background(), networkStartTimeout)
defer cancel()
network, err := tmpnet.StartNetwork(ctx, os.Stdout, rootDir, network, int(nodeCount), int(preFundedKeyCount))
if err != nil {
if err := network.Start(ctx, os.Stdout); err != nil {
return err
}

Expand All @@ -94,7 +100,6 @@ func main() {
startNetworkCmd.PersistentFlags().StringVar(&rootDir, "root-dir", os.Getenv(tmpnet.RootDirEnvName), "The path to the root directory for temporary networks")
startNetworkCmd.PersistentFlags().StringVar(&execPath, "avalanchego-path", os.Getenv(tmpnet.AvalancheGoPathEnvName), "The path to an avalanchego binary")
startNetworkCmd.PersistentFlags().Uint8Var(&nodeCount, "node-count", tmpnet.DefaultNodeCount, "Number of nodes the network should initially consist of")
startNetworkCmd.PersistentFlags().Uint8Var(&preFundedKeyCount, "pre-funded-key-count", tmpnet.DefaultPreFundedKeyCount, "Number of pre-funded keys the network should start with")
rootCmd.AddCommand(startNetworkCmd)

var networkDir string
Expand Down
21 changes: 9 additions & 12 deletions tests/fixture/tmpnet/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,6 @@ import (
)

const (
// Constants defining the names of shell variables whose value can
// configure temporary network orchestration.
NetworkDirEnvName = "TMPNET_NETWORK_DIR"
RootDirEnvName = "TMPNET_ROOT_DIR"

DefaultNetworkTimeout = 2 * time.Minute

// Minimum required to ensure connectivity-based health checks will pass
Expand Down Expand Up @@ -48,12 +43,14 @@ func DefaultFlags() FlagsMap {
}
}

// C-Chain config for testing.
func DefaultCChainConfig() FlagsMap {
// Supply only non-default configuration to ensure that default
// values will be used. Available C-Chain configuration options are
// defined in the `github.com/ava-labs/coreth/evm` package.
return FlagsMap{
"log-level": "trace",
// A set of chain configurations appropriate for testing.
func DefaultChainConfigs() map[string]FlagsMap {
return map[string]FlagsMap{
// Supply only non-default configuration to ensure that default
// values will be used. Available C-Chain configuration options are
// defined in the `github.com/ava-labs/coreth/evm` package.
"C": {
"log-level": "trace",
},
}
}
Loading

0 comments on commit 6939831

Please sign in to comment.