From 0946fdcb49c96b081464729722978f7aab5274b2 Mon Sep 17 00:00:00 2001 From: Maru Newby Date: Wed, 15 Jan 2025 20:31:05 -0800 Subject: [PATCH] [testing] Support direnv to simplify usage of test tooling --- .envrc | 11 +++++++++++ bin/ginkgo | 10 ++++++++++ scripts/build_xsvm.sh | 16 +++++++++++----- scripts/ginkgo.sh | 6 ------ scripts/tests.e2e.bootstrap_monitor.sh | 2 +- scripts/tests.e2e.existing.sh | 2 +- scripts/tests.e2e.sh | 2 +- scripts/tests.upgrade.sh | 2 +- tests/e2e/README.md | 18 +++++++++++++----- tests/fixture/e2e/flags.go | 4 ++-- tests/fixture/tmpnet/README.md | 17 +++++++++++------ tests/fixture/tmpnet/cmd/main.go | 9 ++++++++- tests/fixture/tmpnet/network.go | 1 + tests/fixture/tmpnet/node_process.go | 5 +++-- 14 files changed, 74 insertions(+), 31 deletions(-) create mode 100644 .envrc create mode 100755 bin/ginkgo delete mode 100755 scripts/ginkgo.sh diff --git a/.envrc b/.envrc new file mode 100644 index 000000000000..41994c131f7b --- /dev/null +++ b/.envrc @@ -0,0 +1,11 @@ +# 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 +export AVAGO_PLUGIN_DIR=$PWD/build/plugins diff --git a/bin/ginkgo b/bin/ginkgo new file mode 100755 index 000000000000..9067692f07e3 --- /dev/null +++ b/bin/ginkgo @@ -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 "${@}" diff --git a/scripts/build_xsvm.sh b/scripts/build_xsvm.sh index d67e2cbc2075..c21cd4022a94 100755 --- a/scripts/build_xsvm.sh +++ b/scripts/build_xsvm.sh @@ -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 diff --git a/scripts/ginkgo.sh b/scripts/ginkgo.sh deleted file mode 100755 index 6934a86b7cd5..000000000000 --- a/scripts/ginkgo.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -# If an explicit version is not specified, go run uses the ginkgo version from go.mod -go run github.com/onsi/ginkgo/v2/ginkgo "${@}" diff --git a/scripts/tests.e2e.bootstrap_monitor.sh b/scripts/tests.e2e.bootstrap_monitor.sh index 1d6b170d2eba..c4361515bc0b 100755 --- a/scripts/tests.e2e.bootstrap_monitor.sh +++ b/scripts/tests.e2e.bootstrap_monitor.sh @@ -63,4 +63,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 diff --git a/scripts/tests.e2e.existing.sh b/scripts/tests.e2e.existing.sh index 6cc01a9b44eb..6e078c556359 100755 --- a/scripts/tests.e2e.existing.sh +++ b/scripts/tests.e2e.existing.sh @@ -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 diff --git a/scripts/tests.e2e.sh b/scripts/tests.e2e.sh index e1af3694e90c..042b9a32d2e7 100755 --- a/scripts/tests.e2e.sh +++ b/scripts/tests.e2e.sh @@ -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[@]}" "${@}" diff --git a/scripts/tests.upgrade.sh b/scripts/tests.upgrade.sh index 1f94d30f3121..131bab047b2c 100755 --- a/scripts/tests.upgrade.sh +++ b/scripts/tests.upgrade.sh @@ -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}" diff --git a/tests/e2e/README.md b/tests/e2e/README.md index 6b0770961276..6d1fdc6ce26a 100644 --- a/tests/e2e/README.md +++ b/tests/e2e/README.md @@ -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 an [.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 @@ -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 @@ -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 @@ -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 @@ -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 ... ``` diff --git a/tests/fixture/e2e/flags.go b/tests/fixture/e2e/flags.go index bfbaa1eff9f4..e5afcb9aa5f2 100644 --- a/tests/fixture/e2e/flags.go +++ b/tests/fixture/e2e/flags.go @@ -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 @@ -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, diff --git a/tests/fixture/tmpnet/README.md b/tests/fixture/tmpnet/README.md index 17b3ef2600b2..ae9c54942508 100644 --- a/tests/fixture/tmpnet/README.md +++ b/tests/fixture/tmpnet/README.md @@ -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) @@ -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 @@ -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 an [.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 @@ -269,7 +274,7 @@ PROMETHEUS_ID= PROMETHEUS_PASSWORD= ./scripts/run_prometheus.sh LOKI_ID= LOKI_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 diff --git a/tests/fixture/tmpnet/cmd/main.go b/tests/fixture/tmpnet/cmd/main.go index 15afd472925e..1e5ebbf39735 100644 --- a/tests/fixture/tmpnet/cmd/main.go +++ b/tests/fixture/tmpnet/cmd/main.go @@ -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" @@ -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) diff --git a/tests/fixture/tmpnet/network.go b/tests/fixture/tmpnet/network.go index 63e2306eb200..3a93f32b29df 100644 --- a/tests/fixture/tmpnet/network.go +++ b/tests/fixture/tmpnet/network.go @@ -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 diff --git a/tests/fixture/tmpnet/node_process.go b/tests/fixture/tmpnet/node_process.go index 2f16ddd19a0d..9cf6027fc9c0 100644 --- a/tests/fixture/tmpnet/node_process.go +++ b/tests/fixture/tmpnet/node_process.go @@ -28,13 +28,14 @@ import ( ) const ( - AvalancheGoPathEnvName = "AVALANCHEGO_PATH" - AvalancheGoPluginDirEnvName = "AVALANCHEGO_PLUGIN_DIR" + AvalancheGoPathEnvName = "AVALANCHEGO_PATH" defaultNodeInitTimeout = 10 * time.Second ) var ( + AvalancheGoPluginDirEnvName = config.EnvVarName(config.EnvPrefix, config.PluginDirKey) + errNodeAlreadyRunning = errors.New("failed to start node: node is already running") errNotRunning = errors.New("node is not running") )