Skip to content

Commit

Permalink
Merge branch 'master' into update-versions-v1.12.2
Browse files Browse the repository at this point in the history
  • Loading branch information
StephenButtolph committed Jan 28, 2025
2 parents 42878d0 + ab46198 commit f60b99e
Show file tree
Hide file tree
Showing 22 changed files with 120 additions and 90 deletions.
12 changes: 12 additions & 0 deletions .envrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Repo-local commands like ginkgo and tmpnetctl
PATH_add bin

# Built binaries like avalanchego and xsvm
PATH_add build

# Configure the explicit built path of avalanchego for tmpnet usage
export AVALANCHEGO_PATH=$PWD/build/avalanchego

# Configure the local plugin directory for both avalanchego and tmpnet usage
mkdir -p $PWD/build/plugins # avalanchego will FATAL if the directory does not exist
export AVAGO_PLUGIN_DIR="${AVAGO_PLUGIN_DIR:-$PWD/build/plugins}" # Use an existing value if set
10 changes: 10 additions & 0 deletions bin/ginkgo
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/usr/bin/env bash

set -euo pipefail

# Ensure the go command is run from the root of the repository so that its go.mod file is used
AVALANCHE_PATH=$(cd "$( dirname "${BASH_SOURCE[0]}" )"; cd .. && pwd )
cd "${AVALANCHE_PATH}"

# If an explicit version is not specified, go run uses the ginkgo version from go.mod
go run github.com/onsi/ginkgo/v2/ginkgo "${@}"
8 changes: 8 additions & 0 deletions config/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,14 @@ const (
defaultUnexpandedDataDir = "$" + AvalancheGoDataDirVar

DefaultProcessContextFilename = "process.json"

// The default plugin path of $HOME/.avalanchego/plugins is not
// suitable for docker images since $HOME might be writable but
// the plugin directory should not be. The value below is in the
// same hierarchy as avalanchego on the docker image
// (/avalanchego/build/avalanchego) and consistent with the
// location already used by subnet-evm.
DefaultImagePluginDir = "/avalanchego/build/plugins"
)

var (
Expand Down
2 changes: 1 addition & 1 deletion scripts/build_antithesis_images.sh
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ else
echo "Generating compose configuration for ${TEST_SETUP}"
gen_antithesis_compose_config "${IMAGE_TAG}" "${AVALANCHE_PATH}/tests/antithesis/xsvm/gencomposeconfig" \
"${AVALANCHE_PATH}/build/antithesis/xsvm" \
"AVALANCHEGO_PATH=${AVALANCHE_PATH}/build/avalanchego AVALANCHEGO_PLUGIN_DIR=${HOME}/.avalanchego/plugins"
"AVALANCHEGO_PATH=${AVALANCHE_PATH}/build/avalanchego AVAGO_PLUGIN_DIR=${AVALANCHE_PATH}/build/plugins"

build_antithesis_images_for_avalanchego "${TEST_SETUP}" "${IMAGE_PREFIX}" "${AVALANCHE_PATH}/vms/example/xsvm/Dockerfile"
fi
16 changes: 11 additions & 5 deletions scripts/build_xsvm.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,14 @@ source ./scripts/constants.sh
echo "Building xsvm plugin..."
go build -o ./build/xsvm ./vms/example/xsvm/cmd/xsvm/

PLUGIN_DIR="$HOME/.avalanchego/plugins"
PLUGIN_PATH="${PLUGIN_DIR}/v3m4wPxaHpvGr8qfMeyK6PRW3idZrPHmYcMTt7oXdK47yurVH"
echo "Symlinking ./build/xsvm to ${PLUGIN_PATH}"
mkdir -p "${PLUGIN_DIR}"
ln -sf "${PWD}/build/xsvm" "${PLUGIN_PATH}"
# Symlink to both global and local plugin directories to simplify
# usage for testing. The local directory should be preferred but the
# global directory remains supported for backwards compatibility.
LOCAL_PLUGIN_PATH="${PWD}/build/plugins"
GLOBAL_PLUGIN_PATH="${HOME}/.avalanchego/plugins"
for plugin_dir in "${GLOBAL_PLUGIN_PATH}" "${LOCAL_PLUGIN_PATH}"; do
PLUGIN_PATH="${plugin_dir}/v3m4wPxaHpvGr8qfMeyK6PRW3idZrPHmYcMTt7oXdK47yurVH"
echo "Symlinking ./build/xsvm to ${PLUGIN_PATH}"
mkdir -p "${plugin_dir}"
ln -sf "${PWD}/build/xsvm" "${PLUGIN_PATH}"
done
6 changes: 0 additions & 6 deletions scripts/ginkgo.sh

This file was deleted.

2 changes: 1 addition & 1 deletion scripts/tests.e2e.bootstrap_monitor.sh
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,4 @@ ensure_command "kind-with-registry.sh" "https://raw.githubusercontent.com/kubern
# call them without a qualifying path.
PATH="${PWD}/bin:$PATH" bash -x "${PWD}/bin/kind-with-registry.sh"

KUBECONFIG="$HOME/.kube/config" PATH="${PWD}/bin:$PATH" ./scripts/ginkgo.sh -v ./tests/fixture/bootstrapmonitor/e2e
KUBECONFIG="$HOME/.kube/config" PATH="${PWD}/bin:$PATH" ./bin/ginkgo -v ./tests/fixture/bootstrapmonitor/e2e
2 changes: 1 addition & 1 deletion scripts/tests.e2e.existing.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ function print_separator {
function cleanup {
print_separator
echo "cleaning up reusable network"
./scripts/ginkgo.sh -v ./tests/e2e -- --stop-network
./bin/ginkgo -v ./tests/e2e -- --stop-network
}
trap cleanup EXIT

Expand Down
2 changes: 1 addition & 1 deletion scripts/tests.e2e.sh
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,4 @@ fi

#################################
# shellcheck disable=SC2086
./scripts/ginkgo.sh ${GINKGO_ARGS} -v ./tests/e2e -- "${E2E_ARGS[@]}" "${@}"
./bin/ginkgo ${GINKGO_ARGS} -v ./tests/e2e -- "${E2E_ARGS[@]}" "${@}"
2 changes: 1 addition & 1 deletion scripts/tests.upgrade.sh
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,6 @@ source ./scripts/constants.sh
#################################
# By default, it runs all upgrade test cases!
echo "running upgrade tests against the local cluster with ${AVALANCHEGO_PATH}"
./scripts/ginkgo.sh -v ./tests/upgrade -- \
./bin/ginkgo -v ./tests/upgrade -- \
--avalanchego-path="/tmp/avalanchego-v${VERSION}/avalanchego" \
--avalanchego-path-to-upgrade-to="${AVALANCHEGO_PATH}"
2 changes: 1 addition & 1 deletion tests/antithesis/avalanchego/gencomposeconfig/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const baseImageName = "antithesis-avalanchego"
// Creates docker-compose.yml and its associated volumes in the target path.
func main() {
network := tmpnet.LocalNetworkOrPanic()
if err := antithesis.GenerateComposeConfig(network, baseImageName, "" /* runtimePluginDir */); err != nil {
if err := antithesis.GenerateComposeConfig(network, baseImageName); err != nil {
tests.NewDefaultLogger("").Fatal("failed to generate compose config",
zap.Error(err),
)
Expand Down
39 changes: 21 additions & 18 deletions tests/antithesis/compose.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,24 +22,28 @@ import (

const bootstrapIndex = 0

const (
targetPathEnvName = "TARGET_PATH"
imageTagEnvName = "IMAGE_TAG"
)

var (
errTargetPathEnvVarNotSet = errors.New("TARGET_PATH environment variable not set")
errImageTagEnvVarNotSet = errors.New("IMAGE_TAG environment variable not set")
errAvalancheGoEvVarNotSet = errors.New("AVALANCHEGO_PATH environment variable not set")
errPluginDirEnvVarNotSet = errors.New("AVALANCHEGO_PLUGIN_DIR environment variable not set")
errTargetPathEnvVarNotSet = errors.New(targetPathEnvName + " environment variable not set")
errImageTagEnvVarNotSet = errors.New(imageTagEnvName + " environment variable not set")
errAvalancheGoEvVarNotSet = errors.New(tmpnet.AvalancheGoPathEnvName + " environment variable not set")
errPluginDirEnvVarNotSet = errors.New(tmpnet.AvalancheGoPluginDirEnvName + " environment variable not set")
)

// Creates docker compose configuration for an antithesis test setup. Configuration is via env vars to
// simplify usage by main entrypoints. If the provided network includes a subnet, the initial DB state for
// the subnet will be created and written to the target path. The runtimePluginDir should be set if the node
// image used for the test setup uses a path other than the default (~/.avalanchego/plugins).
func GenerateComposeConfig(network *tmpnet.Network, baseImageName string, runtimePluginDir string) error {
targetPath := os.Getenv("TARGET_PATH")
// the subnet will be created and written to the target path.
func GenerateComposeConfig(network *tmpnet.Network, baseImageName string) error {
targetPath := os.Getenv(targetPathEnvName)
if len(targetPath) == 0 {
return errTargetPathEnvVarNotSet
}

imageTag := os.Getenv("IMAGE_TAG")
imageTag := os.Getenv(imageTagEnvName)
if len(imageTag) == 0 {
return errImageTagEnvVarNotSet
}
Expand Down Expand Up @@ -70,7 +74,7 @@ func GenerateComposeConfig(network *tmpnet.Network, baseImageName string, runtim
nodeImageName := fmt.Sprintf("%s-node:%s", baseImageName, imageTag)
workloadImageName := fmt.Sprintf("%s-workload:%s", baseImageName, imageTag)

if err := initComposeConfig(network, nodeImageName, workloadImageName, targetPath, runtimePluginDir); err != nil {
if err := initComposeConfig(network, nodeImageName, workloadImageName, targetPath); err != nil {
return fmt.Errorf("failed to generate compose config: %w", err)
}

Expand All @@ -84,10 +88,9 @@ func initComposeConfig(
nodeImageName string,
workloadImageName string,
targetPath string,
pluginDir string,
) error {
// Generate a compose project for the specified network
project, err := newComposeProject(network, nodeImageName, workloadImageName, pluginDir)
project, err := newComposeProject(network, nodeImageName, workloadImageName)
if err != nil {
return fmt.Errorf("failed to create compose project: %w", err)
}
Expand Down Expand Up @@ -125,7 +128,7 @@ func initComposeConfig(

// Create a new docker compose project for an antithesis test setup
// for the provided network configuration.
func newComposeProject(network *tmpnet.Network, nodeImageName string, workloadImageName string, pluginDir string) (*types.Project, error) {
func newComposeProject(network *tmpnet.Network, nodeImageName string, workloadImageName string) (*types.Project, error) {
networkName := "avalanche-testnet"
baseNetworkAddress := "10.0.20"

Expand Down Expand Up @@ -163,11 +166,6 @@ func newComposeProject(network *tmpnet.Network, nodeImageName string, workloadIm
config.StakingSignerKeyContentKey: signerKey,
}

// Set a non-default plugin dir if provided
if len(pluginDir) > 0 {
env[config.PluginDirKey] = pluginDir
}

// Apply configuration appropriate to a test network
for k, v := range tmpnet.DefaultTestFlags() {
switch value := v.(type) {
Expand Down Expand Up @@ -195,6 +193,11 @@ func newComposeProject(network *tmpnet.Network, nodeImageName string, workloadIm
return nil, err
}
if len(trackSubnets) > 0 {
// The plugin dir is only required when subnets will be
// tracked. VM images are expected to put their plugins in
// the default dir.
env[config.PluginDirKey] = config.DefaultImagePluginDir

env[config.TrackSubnetsKey] = trackSubnets
if i == bootstrapIndex {
// DB volume for bootstrap node will need to initialized with the subnet
Expand Down
3 changes: 1 addition & 2 deletions tests/antithesis/xsvm/Dockerfile.node
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ FROM $AVALANCHEGO_NODE_IMAGE AS execution
ARG BUILDER_WORKDIR

# Copy the executable into the container
RUN mkdir -p /root/.avalanchego/plugins
COPY --from=builder $BUILDER_WORKDIR/build/xsvm \
/root/.avalanchego/plugins/v3m4wPxaHpvGr8qfMeyK6PRW3idZrPHmYcMTt7oXdK47yurVH
/avalanchego/build/plugins/v3m4wPxaHpvGr8qfMeyK6PRW3idZrPHmYcMTt7oXdK47yurVH

# The node image's entrypoint will be reused.
2 changes: 1 addition & 1 deletion tests/antithesis/xsvm/gencomposeconfig/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func main() {
network.Subnets = []*tmpnet.Subnet{
subnet.NewXSVMOrPanic("xsvm", genesis.VMRQKey, network.Nodes...),
}
if err := antithesis.GenerateComposeConfig(network, baseImageName, "" /* runtimePluginDir */); err != nil {
if err := antithesis.GenerateComposeConfig(network, baseImageName); err != nil {
tests.NewDefaultLogger("").Fatal("failed to generate compose config",
zap.Error(err),
)
Expand Down
18 changes: 13 additions & 5 deletions tests/e2e/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,19 @@
```bash
./scripts/build.sh # Builds avalanchego for use in deploying a test network
./scripts/build_xsvm.sh # Builds xsvm for use in deploying a test network with a subnet
./scripts/ginkgo.sh -v ./tests/e2e -- --avalanchego-path=./build/avalanchego
./bin/ginkgo -v ./tests/e2e -- --avalanchego-path=./build/avalanchego
```

See [`tests.e2e.sh`](../../scripts/tests.e2e.sh) for an example.

### Simplifying usage with direnv

The repo includes a [.envrc](../../.envrc) that can be applied by
[direnv](https://direnv.net/) when in a shell. This will enable
`ginkgo` to be invoked directly (without a `./bin/` prefix ) and
without having to specify the `--avalanchego-path` or `--plugin-dir`
flags.

### Filtering test execution with labels

In cases where a change can be verified against only a subset of
Expand All @@ -24,7 +32,7 @@ primarily target the X-Chain:


```bash
./scripts/ginkgo.sh -v --label-filter=x ./tests/e2e -- --avalanchego-path=./build/avalanchego
./bin/ginkgo -v --label-filter=x ./tests/e2e -- --avalanchego-path=./build/avalanchego
```

The ginkgo docs provide further detail on [how to compose label
Expand Down Expand Up @@ -62,7 +70,7 @@ To enable network reuse across test runs, pass `--reuse-network` as an
argument to the test suite:

```bash
./scripts/gingko.sh -v ./tests/e2e -- --avalanchego-path=/path/to/avalanchego --reuse-network
./bin/gingko -v ./tests/e2e -- --avalanchego-path=/path/to/avalanchego --reuse-network
```

If a network is not already running the first time the suite runs with
Expand All @@ -85,7 +93,7 @@ To stop a network configured for reuse, invoke the test suite with the
immediately without executing any tests:

```bash
./scripts/gingko.sh -v ./tests/e2e -- --stop-network
./bin/gingko -v ./tests/e2e -- --stop-network
```

## Skipping bootstrap checks
Expand All @@ -97,5 +105,5 @@ these bootstrap checks during development, set the
`E2E_SKIP_BOOTSTRAP_CHECKS` env var to a non-empty value:

```bash
E2E_SKIP_BOOTSTRAP_CHECKS=1 ./scripts/ginkgo.sh -v ./tests/e2e ...
E2E_SKIP_BOOTSTRAP_CHECKS=1 ./bin/ginkgo -v ./tests/e2e ...
```
4 changes: 2 additions & 2 deletions tests/fixture/e2e/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ func (v *FlagVars) NodeCount() int {
return v.nodeCount
}

func getEnvWithDefault(envVar, defaultVal string) string {
func GetEnvWithDefault(envVar, defaultVal string) string {
val := os.Getenv(envVar)
if len(val) == 0 {
return defaultVal
Expand All @@ -96,7 +96,7 @@ func RegisterFlags() *FlagVars {
flag.StringVar(
&vars.pluginDir,
"plugin-dir",
getEnvWithDefault(tmpnet.AvalancheGoPluginDirEnvName, os.ExpandEnv("$HOME/.avalanchego/plugins")),
GetEnvWithDefault(tmpnet.AvalancheGoPluginDirEnvName, os.ExpandEnv("$HOME/.avalanchego/plugins")),
fmt.Sprintf(
"[optional] the dir containing VM plugins. Also possible to configure via the %s env variable.",
tmpnet.AvalancheGoPluginDirEnvName,
Expand Down
17 changes: 11 additions & 6 deletions tests/fixture/tmpnet/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,8 @@ A temporary network can be managed by the `tmpnetctl` cli tool:
```bash
# From the root of the avalanchego repo

# Build the tmpnetctl binary
$ ./scripts/build_tmpnetctl.sh

# Start a new network. Possible to specify the number of nodes (> 1) with --node-count.
$ ./build/tmpnetctl start-network --avalanchego-path=/path/to/avalanchego
$ ./bin/tmpnetctl start-network --avalanchego-path=/path/to/avalanchego
...
Started network /home/me/.tmpnet/networks/20240306-152305.924531 (UUID: abaab590-b375-44f6-9ca5-f8a6dc061725)

Expand All @@ -60,7 +57,7 @@ Configure tmpnetctl to target this network by default with one of the following
- export TMPNET_NETWORK_DIR=/home/me/.tmpnet/networks/latest

# Stop the network
$ ./build/tmpnetctl stop-network --network-dir=/path/to/network
$ ./bin/tmpnetctl stop-network --network-dir=/path/to/network
```

Note the export of the path ending in `latest`. This is a symlink that
Expand All @@ -69,6 +66,14 @@ the `TMPNET_NETWORK_DIR` env var to this symlink ensures that
`tmpnetctl` commands target the most recently deployed temporary
network.

### Simplifying usage with direnv

The repo includes a [.envrc](../../../.envrc) that can be applied by
[direnv](https://direnv.net/) when in a shell. This will enable
`tmpnetctl` to be invoked directly (without a `./bin/` prefix ) and
without having to specify the `--avalanchego-path` or `--plugin-dir`
flags.

#### Deprecated usage with e2e suite

`tmpnetctl` was previously used to create temporary networks for use
Expand Down Expand Up @@ -269,7 +274,7 @@ PROMETHEUS_USERNAME=<username> PROMETHEUS_PASSWORD=<password> ./scripts/run_prom
LOKI_USERNAME=<username> LOKI_PASSWORD=<password> ./scripts/run_promtail.sh

# Network start emits link to grafana displaying collected logs and metrics
./build/tmpnetctl start-network
./bin/tmpnetctl start-network

# Configure metrics collection from a local node binding to the default API
# port of 9650 and storing its logs in ~/.avalanchego/logs. The script will
Expand Down
9 changes: 8 additions & 1 deletion tests/fixture/tmpnet/cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"go.uber.org/zap"

"github.com/ava-labs/avalanchego/tests"
"github.com/ava-labs/avalanchego/tests/fixture/e2e"
"github.com/ava-labs/avalanchego/tests/fixture/tmpnet"
"github.com/ava-labs/avalanchego/utils/logging"
"github.com/ava-labs/avalanchego/version"
Expand Down Expand Up @@ -117,9 +118,15 @@ func main() {
return nil
},
}
// TODO(marun) Enable reuse of flags across tmpnetctl and e2e
startNetworkCmd.PersistentFlags().StringVar(&rootDir, "root-dir", os.Getenv(tmpnet.RootDirEnvName), "The path to the root directory for temporary networks")
startNetworkCmd.PersistentFlags().StringVar(&avalancheGoPath, "avalanchego-path", os.Getenv(tmpnet.AvalancheGoPathEnvName), "The path to an avalanchego binary")
startNetworkCmd.PersistentFlags().StringVar(&pluginDir, "plugin-dir", os.ExpandEnv("$HOME/.avalanchego/plugins"), "[optional] the dir containing VM plugins")
startNetworkCmd.PersistentFlags().StringVar(
&pluginDir,
"plugin-dir",
e2e.GetEnvWithDefault(tmpnet.AvalancheGoPluginDirEnvName, os.ExpandEnv("$HOME/.avalanchego/plugins")),
"[optional] the dir containing VM plugins",
)
startNetworkCmd.PersistentFlags().Uint8Var(&nodeCount, "node-count", tmpnet.DefaultNodeCount, "Number of nodes the network should initially consist of")
startNetworkCmd.PersistentFlags().StringVar(&networkOwner, "network-owner", "", "The string identifying the intended owner of the network")
rootCmd.AddCommand(startNetworkCmd)
Expand Down
18 changes: 1 addition & 17 deletions tests/fixture/tmpnet/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ func ReadNetwork(dir string) (*Network, error) {
func (n *Network) EnsureDefaultConfig(log logging.Logger, avalancheGoPath string, pluginDir string) error {
log.Info("preparing configuration for new network",
zap.String("avalanchegoPath", avalancheGoPath),
zap.String("pluginDir", pluginDir),
)

// A UUID supports centralized metrics collection
Expand Down Expand Up @@ -510,23 +511,6 @@ func (n *Network) StartNode(ctx context.Context, log logging.Logger, node *Node)

// Restart a single node.
func (n *Network) RestartNode(ctx context.Context, log logging.Logger, node *Node) error {
// Ensure the node reuses the same API port across restarts to ensure
// consistent labeling of metrics. Otherwise prometheus's automatic
// addition of the `instance` label (host:port) results in
// segmentation of results for a given node every time the port
// changes on restart. This segmentation causes graphs on the grafana
// dashboards to display multiple series per graph for a given node,
// one for each port that the node used.
//
// There is a non-zero chance of the port being allocatted to a
// different process and the node subsequently being unable to start,
// but the alternative is having to update the grafana dashboards
// query-by-query to ensure that node metrics ignore the instance
// label.
if err := node.SaveAPIPort(); err != nil {
return err
}

if err := node.Stop(ctx); err != nil {
return fmt.Errorf("failed to stop node %s: %w", node.NodeID, err)
}
Expand Down
Loading

0 comments on commit f60b99e

Please sign in to comment.