From de45ae7b87ef200a3fef75bbb95f5ec1102df05b Mon Sep 17 00:00:00 2001 From: Fabio Barone Date: Tue, 2 Aug 2022 16:22:43 -0500 Subject: [PATCH 01/18] first iteration --- cmd/control/control.go | 99 +++++++++++++++++------------------------- 1 file changed, 41 insertions(+), 58 deletions(-) diff --git a/cmd/control/control.go b/cmd/control/control.go index 00f8afde..1e0481fa 100644 --- a/cmd/control/control.go +++ b/cmd/control/control.go @@ -7,7 +7,6 @@ import ( "context" "encoding/base64" "encoding/json" - "errors" "fmt" "os" "os/signal" @@ -137,14 +136,17 @@ func newStartCommand() *cobra.Command { &whitelistedSubnets, "whitelisted-subnets", "", - "whitelisted subnets (comma-separated)", + "[optional] whitelisted subnets (comma-separated)", ) cmd.PersistentFlags().StringVar( &chainConfigs, "chain-configs", "", - "[optional] JSON string of map that maps from chain id to its config file contents", + "[optional] JSON string of map from chain id to its config file contents", ) + if err := cmd.MarkPersistentFlagRequired("avalanchego-path"); err != nil { + panic(err) + } return cmd } @@ -214,19 +216,10 @@ func startFunc(cmd *cobra.Command, args []string) error { func newCreateBlockchainsCommand() *cobra.Command { cmd := &cobra.Command{ - Use: "create-blockchains [options]", + Use: "create-blockchains blockchain-specs [options]", Short: "Create blockchains.", RunE: createBlockchainsFunc, - Args: cobra.ExactArgs(0), - } - cmd.PersistentFlags().StringVar( - &blockchainSpecsStr, - "blockchain-specs", - "", - "JSON string of list of [(VM name, its genesis file path, optional subnet id to use)]", - ) - if err := cmd.MarkPersistentFlagRequired("blockchain-specs"); err != nil { - panic(err) + Args: cobra.ExactArgs(1), } return cmd } @@ -238,9 +231,7 @@ func createBlockchainsFunc(cmd *cobra.Command, args []string) error { } defer cli.Close() - if blockchainSpecsStr == "" { - return errors.New("empty blockchain-specs argument") - } + blockchainSpecsStr := args[0] blockchainSpecs := []*rpcpb.BlockchainSpec{} if err := json.Unmarshal([]byte(blockchainSpecsStr), &blockchainSpecs); err != nil { @@ -439,20 +430,19 @@ func streamStatusFunc(cmd *cobra.Command, args []string) error { return nil } -var nodeName string - func newRemoveNodeCommand() *cobra.Command { cmd := &cobra.Command{ - Use: "remove-node [options]", + Use: "remove-node node-name [options]", Short: "Removes a node.", RunE: removeNodeFunc, - Args: cobra.ExactArgs(0), + Args: cobra.ExactArgs(1), } - cmd.PersistentFlags().StringVar(&nodeName, "node-name", "", "node name to remove") return cmd } func removeNodeFunc(cmd *cobra.Command, args []string) error { + // no validation for empty string required, as covered by `cobra.ExactArgs` + nodeName := args[0] cli, err := newClient() if err != nil { return err @@ -472,17 +462,11 @@ func removeNodeFunc(cmd *cobra.Command, args []string) error { func newAddNodeCommand() *cobra.Command { cmd := &cobra.Command{ - Use: "add-node [options]", + Use: "add-node node-name [options]", Short: "Add a new node to the network", RunE: addNodeFunc, - Args: cobra.ExactArgs(0), + Args: cobra.ExactArgs(1), } - cmd.PersistentFlags().StringVar( - &nodeName, - "node-name", - "", - "node name to add", - ) cmd.PersistentFlags().StringVar( &avalancheGoBinPath, "avalanchego-path", @@ -505,6 +489,8 @@ func newAddNodeCommand() *cobra.Command { } func addNodeFunc(cmd *cobra.Command, args []string) error { + // no validation for empty string required, as covered by `cobra.ExactArgs` + nodeName := args[0] cli, err := newClient() if err != nil { return err @@ -549,17 +535,11 @@ func addNodeFunc(cmd *cobra.Command, args []string) error { func newRestartNodeCommand() *cobra.Command { cmd := &cobra.Command{ - Use: "restart-node [options]", - Short: "Restarts the server.", + Use: "restart-node node-name [options]", + Short: "Restarts a node.", RunE: restartNodeFunc, - Args: cobra.ExactArgs(0), + Args: cobra.ExactArgs(1), } - cmd.PersistentFlags().StringVar( - &nodeName, - "node-name", - "", - "node name to restart", - ) cmd.PersistentFlags().StringVar( &avalancheGoBinPath, "avalanchego-path", @@ -576,6 +556,8 @@ func newRestartNodeCommand() *cobra.Command { } func restartNodeFunc(cmd *cobra.Command, args []string) error { + // no validation for empty string required, as covered by `cobra.ExactArgs` + nodeName := args[0] cli, err := newClient() if err != nil { return err @@ -600,21 +582,17 @@ func restartNodeFunc(cmd *cobra.Command, args []string) error { func newAttachPeerCommand() *cobra.Command { cmd := &cobra.Command{ - Use: "attach-peer [options]", + Use: "attach-peer node-name [options]", Short: "Attaches a peer to the node.", RunE: attachPeerFunc, - Args: cobra.ExactArgs(0), + Args: cobra.ExactArgs(1), } - cmd.PersistentFlags().StringVar( - &nodeName, - "node-name", - "", - "node name to attach a peer to", - ) return cmd } func attachPeerFunc(cmd *cobra.Command, args []string) error { + // no validation for empty string required, as covered by `cobra.ExactArgs` + nodeName := args[0] cli, err := newClient() if err != nil { return err @@ -640,17 +618,12 @@ var ( func newSendOutboundMessageCommand() *cobra.Command { cmd := &cobra.Command{ - Use: "send-outbound-message [options]", - Short: "Sends an outbound message to an attached peer.", - RunE: sendOutboundMessageFunc, - Args: cobra.ExactArgs(0), + Use: "send-outbound-message [options]", + Short: "Sends an outbound message to an attached peer.", + RunE: sendOutboundMessageFunc, + Args: cobra.ExactArgs(1), + ValidArgs: []string{"node-name"}, } - cmd.PersistentFlags().StringVar( - &nodeName, - "node-name", - "", - "node name that has an attached peer", - ) cmd.PersistentFlags().StringVar( &peerID, "peer-id", @@ -669,10 +642,21 @@ func newSendOutboundMessageCommand() *cobra.Command { "", "Message bytes in base64 encoding", ) + if err := cmd.MarkPersistentFlagRequired("peer-id"); err != nil { + panic(err) + } + if err := cmd.MarkPersistentFlagRequired("message-op"); err != nil { + panic(err) + } + if err := cmd.MarkPersistentFlagRequired("message-bytes-b64"); err != nil { + panic(err) + } return cmd } func sendOutboundMessageFunc(cmd *cobra.Command, args []string) error { + // no validation for empty string required, as covered by `cobra.ExactArgs` + nodeName := args[0] cli, err := newClient() if err != nil { return err @@ -826,7 +810,6 @@ func loadSnapshotFunc(cmd *cobra.Command, args []string) error { ctx := getAsyncContext() resp, err := cli.LoadSnapshot(ctx, args[0], opts...) - if err != nil { return err } From c6579d772c4d0cc63f110b851fa64a96623a84e6 Mon Sep 17 00:00:00 2001 From: Fabio Barone Date: Wed, 3 Aug 2022 13:38:40 -0500 Subject: [PATCH 02/18] add create blockchain e2e test --- scripts/tests.e2e.sh | 45 ++++++++++++++-- tests/e2e/e2e_test.go | 86 ++++++++++++++++++++++++++++--- tests/e2e/subnet-evm-genesis.json | 47 +++++++++++++++++ 3 files changed, 166 insertions(+), 12 deletions(-) create mode 100644 tests/e2e/subnet-evm-genesis.json diff --git a/scripts/tests.e2e.sh b/scripts/tests.e2e.sh index 593b6b9f..60b62a58 100755 --- a/scripts/tests.e2e.sh +++ b/scripts/tests.e2e.sh @@ -9,23 +9,31 @@ if ! [[ "$0" =~ scripts/tests.e2e.sh ]]; then exit 255 fi -DEFAULT_VERSION_1=1.7.12 -DEFAULT_VERSION_2=1.7.13 +DEFAULT_VERSION_1=1.7.15 +DEFAULT_VERSION_2=1.7.16 +DEFAULT_SUBNET_EVM_VERSION=0.2.4 if [ $# == 0 ]; then VERSION_1=$DEFAULT_VERSION_1 VERSION_2=$DEFAULT_VERSION_2 + SUBNET_EVM_VERSION=$DEFAULT_SUBNET_EVM_VERSION else VERSION_1=$1 if [[ -z "${VERSION_1}" ]]; then echo "Missing version argument!" - echo "Usage: ${0} [VERSION_1] [VERSION_2]" >> /dev/stderr + echo "Usage: ${0} [VERSION_1] [VERSION_2] [SUBNET_EVM_VERSION]" >> /dev/stderr exit 255 fi VERSION_2=$2 if [[ -z "${VERSION_2}" ]]; then echo "Missing version argument!" - echo "Usage: ${0} [VERSION_1] [VERSION_2]" >> /dev/stderr + echo "Usage: ${0} [VERSION_1] [VERSION_2] [SUBNET_EVM_VERSION]" >> /dev/stderr + exit 255 + fi + SUBNET_EVM_VERSION=$3 + if [[ -z "${SUBNET_EVM_VERSION}" ]]; then + echo "Missing version argument!" + echo "Usage: ${0} [VERSION_1] [VERSION_2] [SUBNET_EVM_VERSION]" >> /dev/stderr exit 255 fi fi @@ -33,6 +41,7 @@ fi echo "Running e2e tests with:" echo VERSION_1: ${VERSION_1} echo VERSION_2: ${VERSION_2} +echo SUBNET_EVM_VERSION: ${SUBNET_EVM_VERSION} if [ ! -f /tmp/avalanchego-v${VERSION_1}/avalanchego ] then @@ -93,6 +102,31 @@ then find /tmp/avalanchego-v${VERSION_2} fi +if [ ! -f /tmp/subnet-evm-v${SUBNET_EVM_VERSION}/subnet-evm ] +then + ############################ + # download subnet-evm + # https://github.com/ava-labs/subnet-evm/releases + GOARCH=$(go env GOARCH) + DOWNLOAD_URL=https://github.com/ava-labs/subnet-evm/releases/download/v${SUBNET_EVM_VERSION}/subnet-evm_${SUBNET_EVM_VERSION}_linux_${GOARCH}.tar.gz + DOWNLOAD_PATH=/tmp/subnet-evm.tar.gz + if [[ ${GOOS} == "darwin" ]]; then + DOWNLOAD_URL=https://github.com/ava-labs/subnet-evm/releases/download/v${SUBNET_EVM_VERSION}/subnet-evm_${SUBNET_EVM_VERSION}_darwin_${GOARCH}.tar.gz + fi + + rm -rf /tmp/subnet-evm-v${SUBNET_EVM_VERSION} + rm -f ${DOWNLOAD_PATH} + + echo "downloading subnet-evm ${SUBNET_EVM_VERSION} at ${DOWNLOAD_URL}" + curl -L ${DOWNLOAD_URL} -o ${DOWNLOAD_PATH} + + echo "extracting downloaded subnet-evm" + mkdir /tmp/subnet-evm-v${SUBNET_EVM_VERSION} + tar xzvf ${DOWNLOAD_PATH} -C /tmp/subnet-evm-v${SUBNET_EVM_VERSION} + # NOTE: We are copying the subnet-evm binary here to a plugin hardcoded as srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy which corresponds to the VM name `subnetevm` used as such in the test + cp /tmp/subnet-evm-v${SUBNET_EVM_VERSION}/subnet-evm /tmp/avalanchego-v${VERSION_2}/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy + find /tmp/subnet-evm-v${SUBNET_EVM_VERSION}/subnet-evm +fi ############################ echo "building runner" ./scripts/build.sh @@ -125,7 +159,8 @@ echo "running e2e tests" --grpc-endpoint="0.0.0.0:8080" \ --grpc-gateway-endpoint="0.0.0.0:8081" \ --avalanchego-path-1=/tmp/avalanchego-v${VERSION_1}/avalanchego \ ---avalanchego-path-2=/tmp/avalanchego-v${VERSION_2}/avalanchego +--avalanchego-path-2=/tmp/avalanchego-v${VERSION_2}/avalanchego \ +--subnet-evm-path=/tmp/subnet-evm-v${SUBNET_EVM_VERSION}/subnet-evm kill -9 ${PID} echo "ALL SUCCESS!" diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index 4fc3c863..5ecbe6b1 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -20,14 +20,14 @@ import ( "github.com/ava-labs/avalanche-network-runner/rpcpb" "github.com/ava-labs/avalanche-network-runner/server" "github.com/ava-labs/avalanche-network-runner/utils" - "github.com/ava-labs/avalanchego/api/admin" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/message" "github.com/ava-labs/avalanchego/utils/constants" + "github.com/prometheus/client_golang/prometheus" + ginkgo "github.com/onsi/ginkgo/v2" "github.com/onsi/gomega" - "github.com/prometheus/client_golang/prometheus" ) func TestE2e(t *testing.T) { @@ -39,11 +39,13 @@ func TestE2e(t *testing.T) { } var ( - logLevel string - gRPCEp string - gRPCGatewayEp string - execPath1 string - execPath2 string + logLevel string + gRPCEp string + gRPCGatewayEp string + execPath1 string + execPath2 string + subnetEvmPath string + existingSubnetID string newNodeName = "test-add-node" customNodeConfigs = map[string]string{ @@ -89,6 +91,12 @@ func init() { "", "avalanchego executable path (to upgrade to)", ) + flag.StringVar( + &subnetEvmPath, + "subnet-evm-path", + "", + "path to subnet-evm binary", + ) } var cli client.Client @@ -116,6 +124,70 @@ var _ = ginkgo.AfterSuite(func() { }) var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() { + ginkgo.It("can start with blockchain", func() { + color.Outf("{{green}}sending 'start' with the valid binary path:{{/}} %q\n", execPath1) + ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) + resp, err := cli.Start(ctx, execPath2, + client.WithBlockchainSpecs([]*rpcpb.BlockchainSpec{ + { + VmName: "subnetevm", + Genesis: "tests/e2e/subnet-evm-genesis.json", + }, + }), + ) + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + color.Outf("{{green}}successfully started:{{/}} %+v\n", resp.ClusterInfo.NodeNames) + + color.Outf("{{blue}}wait for health{{/}\n") + ctx, cancel = context.WithTimeout(context.Background(), 2*time.Minute) + _, err = cli.Health(ctx) + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + + color.Outf("{{blue}}get status for existing subnet ID{{/}}\n") + ctx, cancel = context.WithTimeout(context.Background(), 2*time.Minute) + subnetDeployed := false + LOOP: + for !subnetDeployed { + select { + case <-ctx.Done(): + break LOOP + case <-time.After(5 * time.Second): + stat, err := cli.Status(ctx) + gomega.Ω(err).Should(gomega.BeNil()) + if stat.ClusterInfo.CustomChainsHealthy { + subnetDeployed = true + existingSubnetID = stat.ClusterInfo.GetSubnets()[0] + gomega.Ω(existingSubnetID).Should(gomega.Not(gomega.BeNil())) + } + } + } + cancel() + gomega.Ω(subnetDeployed).Should(gomega.BeTrue()) + color.Outf("{{blue}}can create a blockchain in an existing subnet{{/}}\n") + ctx, cancel = context.WithTimeout(context.Background(), 2*time.Minute) + _, err = cli.CreateBlockchains(ctx, + []*rpcpb.BlockchainSpec{ + { + VmName: "subnetevm", + Genesis: "tests/e2e/subnet-evm-genesis.json", + SubnetId: &existingSubnetID, + }, + }, + ) + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + color.Outf("{{blue}}wait for health{{/}\n") + ctx, cancel = context.WithTimeout(context.Background(), 2*time.Minute) + _, err = cli.Health(ctx) + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + ctx, cancel = context.WithTimeout(context.Background(), 2*time.Minute) + _, err = cli.Stop(ctx) + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + }) ginkgo.It("can start", func() { ginkgo.By("start request with invalid exec path should fail", func() { ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) diff --git a/tests/e2e/subnet-evm-genesis.json b/tests/e2e/subnet-evm-genesis.json new file mode 100644 index 00000000..9c2b0e48 --- /dev/null +++ b/tests/e2e/subnet-evm-genesis.json @@ -0,0 +1,47 @@ +{ + "config": { + "chainId": 99999, + "homesteadBlock": 0, + "eip150Block": 0, + "eip150Hash": "0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0", + "eip155Block": 0, + "eip158Block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "petersburgBlock": 0, + "istanbulBlock": 0, + "muirGlacierBlock": 0, + "subnetEVMTimestamp": 0, + "feeConfig": { + "gasLimit": 20000000, + "minBaseFee": 1000000000, + "targetGas": 100000000, + "baseFeeChangeDenominator": 48, + "minBlockGasCost": 0, + "maxBlockGasCost": 10000000, + "targetBlockRate": 2, + "blockGasCostStep": 500000 + } + }, + "alloc": { + "0x323e83bb2ce09bb19088ad11d3012b39738212bc": { + "balance": "0x52B7D2DCC80CD2E4000000" + }, + "8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC": { + "balance": "0x52B7D2DCC80CD2E4000000" + }, + "Ab5801a7D398351b8bE11C439e05C5B3259aeC9B": { + "balance": "0xa796504b1cb5a7c0000" + } + }, + "nonce": "0x0", + "timestamp": "0x0", + "extraData": "0x00", + "gasLimit": "0x1312D00", + "difficulty": "0x0", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "coinbase": "0x0000000000000000000000000000000000000000", + "number": "0x0", + "gasUsed": "0x0", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000" +} From c70bfd20b722cb6be2e712970e8fd31e56b30b9c Mon Sep 17 00:00:00 2001 From: Fabio Barone Date: Wed, 3 Aug 2022 13:41:38 -0500 Subject: [PATCH 03/18] change versions and add subnet-evm to workflow --- .github/workflows/build-test-release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-test-release.yml b/.github/workflows/build-test-release.yml index 9ab4d874..7375ff18 100644 --- a/.github/workflows/build-test-release.yml +++ b/.github/workflows/build-test-release.yml @@ -54,7 +54,7 @@ jobs: go-version: 1.17 - name: Run e2e tests shell: bash - run: scripts/tests.e2e.sh 1.7.12 1.7.13 + run: scripts/tests.e2e.sh 1.7.15 1.7.16 0.2.4 release: needs: [lint_test, unit_test, e2e_test] runs-on: ubuntu-latest From d5dc88f53d0ea730c1b655a186545de264173234 Mon Sep 17 00:00:00 2001 From: Felipe Madero Date: Thu, 4 Aug 2022 08:43:43 -0300 Subject: [PATCH 04/18] replace build-dir with plugin-dir --- local/network.go | 40 +++++++++++++++--------------- local/node.go | 12 ++++----- local/snapshot.go | 12 ++++----- network/node/node.go | 4 +-- server/network.go | 58 +++++++++++++++----------------------------- 5 files changed, 54 insertions(+), 72 deletions(-) diff --git a/local/network.go b/local/network.go index 2c092da3..b4441445 100644 --- a/local/network.go +++ b/local/network.go @@ -45,6 +45,8 @@ const ( defaultLogsSubdir = "logs" // difference between unlock schedule locktime and startime in original genesis genesisLocktimeStartimeDelta = 2836800 + // TODO: replace with config.PluginDirKey when included in avalanchego + PluginDirKey = "plugin-dir" ) // interface compliance @@ -498,7 +500,7 @@ func (ln *localNetwork) addNode(nodeConfig node.Config) (node.Node, error) { dbDir: nodeData.dbDir, logsDir: nodeData.logsDir, config: nodeConfig, - buildDir: nodeData.buildDir, + pluginDir: nodeData.pluginDir, httpHost: nodeData.httpHost, attachedPeers: map[string]peer.Peer{}, } @@ -686,7 +688,7 @@ func (ln *localNetwork) removeNode(ctx context.Context, nodeName string) error { } // Restart [nodeName] using the same config, optionally changing [binaryPath], -// [buildDir], [whitelistedSubnets] +// [pluginDir], [whitelistedSubnets] func (ln *localNetwork) RestartNode( ctx context.Context, nodeName string, @@ -705,7 +707,7 @@ func (ln *localNetwork) RestartNode( if binaryPath != "" { nodeConfig.BinaryPath = binaryPath - nodeConfig.Flags[config.BuildDirKey] = filepath.Dir(binaryPath) + nodeConfig.Flags[PluginDirKey] = filepath.Join(filepath.Dir(binaryPath), "plugins") } if whitelistedSubnets != "" { @@ -759,13 +761,13 @@ func (ln *localNetwork) setNodeName(nodeConfig *node.Config) error { } type buildFlagsReturn struct { - flags []string - apiPort uint16 - p2pPort uint16 - dbDir string - logsDir string - buildDir string - httpHost string + flags []string + apiPort uint16 + p2pPort uint16 + dbDir string + logsDir string + pluginDir string + httpHost string } // buildFlags returns the: @@ -786,8 +788,8 @@ func (ln *localNetwork) buildFlags( return buildFlagsReturn{}, err } - // buildDir from all configs for node - buildDir, err := getConfigEntry(nodeConfig.Flags, configFile, config.BuildDirKey, "") + // pluginDir from all configs for node + pluginDir, err := getConfigEntry(nodeConfig.Flags, configFile, PluginDirKey, "") if err != nil { return buildFlagsReturn{}, err } @@ -845,12 +847,12 @@ func (ln *localNetwork) buildFlags( } return buildFlagsReturn{ - flags: flags, - apiPort: apiPort, - p2pPort: p2pPort, - dbDir: dbDir, - logsDir: logsDir, - buildDir: buildDir, - httpHost: httpHost, + flags: flags, + apiPort: apiPort, + p2pPort: p2pPort, + dbDir: dbDir, + logsDir: logsDir, + pluginDir: pluginDir, + httpHost: httpHost, }, nil } diff --git a/local/node.go b/local/node.go index c4d3eed1..f2b38939 100644 --- a/local/node.go +++ b/local/node.go @@ -65,8 +65,8 @@ type localNode struct { dbDir string // The logs dir of the node logsDir string - // The build dir of the node - buildDir string + // The plugin dir of the node + pluginDir string // The node config config node.Config // The node httpHost @@ -226,11 +226,11 @@ func (node *localNode) GetBinaryPath() string { } // See node.Node -func (node *localNode) GetBuildDir() string { - if node.buildDir == "" { - return filepath.Dir(node.GetBinaryPath()) +func (node *localNode) GetPluginDir() string { + if node.pluginDir == "" { + return filepath.Join(filepath.Dir(node.GetBinaryPath()), "plugins") } - return node.buildDir + return node.pluginDir } // See node.Node diff --git a/local/snapshot.go b/local/snapshot.go index e8cbe19a..f34c7a0e 100644 --- a/local/snapshot.go +++ b/local/snapshot.go @@ -26,7 +26,7 @@ func NewNetworkFromSnapshot( rootDir string, snapshotsDir string, binaryPath string, - buildDir string, + pluginDir string, chainConfigs map[string]string, flags map[string]interface{}, ) (network.Network, error) { @@ -45,7 +45,7 @@ func NewNetworkFromSnapshot( if err != nil { return net, err } - err = net.loadSnapshot(context.Background(), snapshotName, binaryPath, buildDir, chainConfigs, flags) + err = net.loadSnapshot(context.Background(), snapshotName, binaryPath, pluginDir, chainConfigs, flags) return net, err } @@ -155,7 +155,7 @@ func (ln *localNetwork) loadSnapshot( ctx context.Context, snapshotName string, binaryPath string, - buildDir string, + pluginDir string, chainConfigs map[string]string, flags map[string]interface{}, ) error { @@ -202,10 +202,10 @@ func (ln *localNetwork) loadSnapshot( networkConfig.NodeConfigs[i].BinaryPath = binaryPath } } - // replace build dir - if buildDir != "" { + // replace plugin dir + if pluginDir != "" { for i := range networkConfig.NodeConfigs { - networkConfig.NodeConfigs[i].Flags[config.BuildDirKey] = buildDir + networkConfig.NodeConfigs[i].Flags[PluginDirKey] = pluginDir } } // add chain configs diff --git a/network/node/node.go b/network/node/node.go index 9b8d263c..e6b8edee 100644 --- a/network/node/node.go +++ b/network/node/node.go @@ -45,8 +45,8 @@ type Node interface { GetDbDir() string // Return this node's logs dir GetLogsDir() string - // Return this node's build dir - GetBuildDir() string + // Return this node's plugin dir + GetPluginDir() string // Return this node's config file contents GetConfigFile() string // Return this node's config diff --git a/server/network.go b/server/network.go index acf3d1cc..509a6f7f 100644 --- a/server/network.go +++ b/server/network.go @@ -21,6 +21,11 @@ import ( "github.com/ava-labs/avalanchego/utils/logging" ) +const ( + // TODO: replace with config.PluginDirKey when included in avalanchego + PluginDirKey = "plugin-dir" +) + type localNetwork struct { logger logging.Logger @@ -94,12 +99,20 @@ func newLocalNetwork(opts localNetworkOptions) (*localNetwork, error) { return nil, err } + pluginDir := "" + if opts.execPath != "" { + pluginDir = filepath.Join(filepath.Dir(opts.execPath), "plugins") + } + if opts.pluginDir != "" { + pluginDir = opts.pluginDir + } + return &localNetwork{ logger: logger, execPath: opts.execPath, - pluginDir: opts.pluginDir, + pluginDir: pluginDir, options: opts, @@ -162,17 +175,11 @@ func (lc *localNetwork) createConfig() error { cfg.NodeConfigs[i].Flags[k] = v } - // avalanchego expects buildDir (parent dir of pluginDir) to be provided at cmdline - buildDir, err := getBuildDir(lc.execPath, lc.pluginDir) - if err != nil { - return err - } - delete(cfg.NodeConfigs[i].Flags, config.HTTPPortKey) cfg.NodeConfigs[i].Flags[config.LogsDirKey] = logDir cfg.NodeConfigs[i].Flags[config.DBPathKey] = dbDir - if buildDir != "" { - cfg.NodeConfigs[i].Flags[config.BuildDirKey] = buildDir + if lc.pluginDir != "" { + cfg.NodeConfigs[i].Flags[PluginDirKey] = lc.pluginDir } if lc.options.whitelistedSubnets != "" { cfg.NodeConfigs[i].Flags[config.WhitelistedSubnetsKey] = lc.options.whitelistedSubnets @@ -187,23 +194,6 @@ func (lc *localNetwork) createConfig() error { return nil } -// generates buildDir from pluginDir, and if not available, from execPath -// returns error if pluginDir is non empty and invalid -func getBuildDir(execPath string, pluginDir string) (string, error) { - buildDir := "" - if execPath != "" { - buildDir = filepath.Dir(execPath) - } - if pluginDir != "" { - pluginDir := filepath.Clean(pluginDir) - if filepath.Base(pluginDir) != "plugins" { - return "", fmt.Errorf("plugin dir %q is not named plugins", pluginDir) - } - buildDir = filepath.Dir(pluginDir) - } - return buildDir, nil -} - func (lc *localNetwork) start() error { if err := lc.createConfig(); err != nil { return err @@ -342,11 +332,6 @@ func (lc *localNetwork) loadSnapshot( ) error { color.Outf("{{blue}}{{bold}}create and run local network from snapshot{{/}}\n") - buildDir, err := getBuildDir(lc.execPath, lc.pluginDir) - if err != nil { - return err - } - var globalNodeConfig map[string]interface{} if lc.options.globalNodeConfig != "" { if err := json.Unmarshal([]byte(lc.options.globalNodeConfig), &globalNodeConfig); err != nil { @@ -360,7 +345,7 @@ func (lc *localNetwork) loadSnapshot( lc.options.rootDataDir, lc.options.snapshotsDir, lc.execPath, - buildDir, + lc.pluginDir, lc.options.chainConfigs, globalNodeConfig, ) @@ -460,15 +445,10 @@ func (lc *localNetwork) updateNodeInfo() error { lc.nodeInfos = make(map[string]*rpcpb.NodeInfo) for _, name := range lc.nodeNames { node := nodes[name] - var pluginDir string whitelistedSubnets, err := node.GetFlag(config.WhitelistedSubnetsKey) if err != nil { return err } - buildDir := node.GetBuildDir() - if buildDir != "" { - pluginDir = filepath.Join(buildDir, "plugins") - } lc.nodeInfos[name] = &rpcpb.NodeInfo{ Name: node.GetName(), @@ -478,7 +458,7 @@ func (lc *localNetwork) updateNodeInfo() error { LogDir: node.GetLogsDir(), DbDir: node.GetDbDir(), Config: []byte(node.GetConfigFile()), - PluginDir: pluginDir, + PluginDir: node.GetPluginDir(), WhitelistedSubnets: whitelistedSubnets, } @@ -487,7 +467,7 @@ func (lc *localNetwork) updateNodeInfo() error { lc.execPath = node.GetBinaryPath() } if lc.pluginDir == "" { - lc.pluginDir = pluginDir + lc.pluginDir = node.GetPluginDir() } // update default chain configs if empty if lc.chainConfigs == nil { From a8f707e44abeac060f20ca4b9bb17ec08bf366a7 Mon Sep 17 00:00:00 2001 From: Felipe Madero Date: Thu, 4 Aug 2022 08:51:05 -0300 Subject: [PATCH 05/18] fix E2E --- server/network.go | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/server/network.go b/server/network.go index 509a6f7f..a7456bd0 100644 --- a/server/network.go +++ b/server/network.go @@ -21,11 +21,6 @@ import ( "github.com/ava-labs/avalanchego/utils/logging" ) -const ( - // TODO: replace with config.PluginDirKey when included in avalanchego - PluginDirKey = "plugin-dir" -) - type localNetwork struct { logger logging.Logger @@ -178,9 +173,10 @@ func (lc *localNetwork) createConfig() error { delete(cfg.NodeConfigs[i].Flags, config.HTTPPortKey) cfg.NodeConfigs[i].Flags[config.LogsDirKey] = logDir cfg.NodeConfigs[i].Flags[config.DBPathKey] = dbDir - if lc.pluginDir != "" { - cfg.NodeConfigs[i].Flags[PluginDirKey] = lc.pluginDir - } + // TODO: enable this when the key is available + //if lc.pluginDir != "" { + // cfg.NodeConfigs[i].Flags[config.PluginDirKey] = lc.pluginDir + //} if lc.options.whitelistedSubnets != "" { cfg.NodeConfigs[i].Flags[config.WhitelistedSubnetsKey] = lc.options.whitelistedSubnets } From a172926cdcfe45fbc7788554d3a919310fdd7058 Mon Sep 17 00:00:00 2001 From: Felipe Madero Date: Thu, 4 Aug 2022 08:56:58 -0300 Subject: [PATCH 06/18] try fix E2E --- local/network.go | 3 +++ server/network.go | 12 ++++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/local/network.go b/local/network.go index b4441445..9bb63c63 100644 --- a/local/network.go +++ b/local/network.go @@ -432,6 +432,9 @@ func (ln *localNetwork) addNode(nodeConfig node.Config) (node.Node, error) { } addNetworkFlags(ln.log, ln.flags, nodeConfig.Flags) + // TODO: remove this when plugin-dir is available + delete(nodeConfig.Flags, PluginDirKey) + // it shouldn't happen that just one is empty, most probably both, // but in any case if just one is empty it's unusable so we just assign a new one. if nodeConfig.StakingCert == "" || nodeConfig.StakingKey == "" { diff --git a/server/network.go b/server/network.go index a7456bd0..7d697de2 100644 --- a/server/network.go +++ b/server/network.go @@ -21,6 +21,11 @@ import ( "github.com/ava-labs/avalanchego/utils/logging" ) +const ( + // TODO: replace with config.PluginDirKey when included in avalanchego + PluginDirKey = "plugin-dir" +) + type localNetwork struct { logger logging.Logger @@ -173,10 +178,9 @@ func (lc *localNetwork) createConfig() error { delete(cfg.NodeConfigs[i].Flags, config.HTTPPortKey) cfg.NodeConfigs[i].Flags[config.LogsDirKey] = logDir cfg.NodeConfigs[i].Flags[config.DBPathKey] = dbDir - // TODO: enable this when the key is available - //if lc.pluginDir != "" { - // cfg.NodeConfigs[i].Flags[config.PluginDirKey] = lc.pluginDir - //} + if lc.pluginDir != "" { + cfg.NodeConfigs[i].Flags[config.PluginDirKey] = lc.pluginDir + } if lc.options.whitelistedSubnets != "" { cfg.NodeConfigs[i].Flags[config.WhitelistedSubnetsKey] = lc.options.whitelistedSubnets } From 85508f4b04fc9904273290211583b3f69bd7a805 Mon Sep 17 00:00:00 2001 From: Felipe Madero Date: Thu, 4 Aug 2022 08:57:48 -0300 Subject: [PATCH 07/18] fix lint --- server/network.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/network.go b/server/network.go index 7d697de2..509a6f7f 100644 --- a/server/network.go +++ b/server/network.go @@ -179,7 +179,7 @@ func (lc *localNetwork) createConfig() error { cfg.NodeConfigs[i].Flags[config.LogsDirKey] = logDir cfg.NodeConfigs[i].Flags[config.DBPathKey] = dbDir if lc.pluginDir != "" { - cfg.NodeConfigs[i].Flags[config.PluginDirKey] = lc.pluginDir + cfg.NodeConfigs[i].Flags[PluginDirKey] = lc.pluginDir } if lc.options.whitelistedSubnets != "" { cfg.NodeConfigs[i].Flags[config.WhitelistedSubnetsKey] = lc.options.whitelistedSubnets From df0e1cf73e138d2404514d79e929912369c1185e Mon Sep 17 00:00:00 2001 From: Felipe Madero Date: Thu, 4 Aug 2022 09:11:17 -0300 Subject: [PATCH 08/18] try to fix unit tests --- local/network.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/local/network.go b/local/network.go index 9bb63c63..1c020f1d 100644 --- a/local/network.go +++ b/local/network.go @@ -165,7 +165,7 @@ func init() { if err != nil { panic(err) } - flags := map[string]interface{}{} + var flags map[string]interface{} if err = json.Unmarshal(flagsBytes, &flags); err != nil { panic(err) } @@ -190,7 +190,7 @@ func init() { if err != nil { panic(err) } - flags := map[string]interface{}{} + var flags map[string]interface{} if err = json.Unmarshal(flagsBytes, &flags); err != nil { panic(err) } From 528283137b4bafd4b9f273fe3a78ba06eb20c995 Mon Sep 17 00:00:00 2001 From: Felipe Madero Date: Thu, 4 Aug 2022 09:26:18 -0300 Subject: [PATCH 09/18] avoid race condition on unit tests --- local/network.go | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/local/network.go b/local/network.go index 1c020f1d..4b2d6b3f 100644 --- a/local/network.go +++ b/local/network.go @@ -165,7 +165,7 @@ func init() { if err != nil { panic(err) } - var flags map[string]interface{} + flags := map[string]interface{}{} if err = json.Unmarshal(flagsBytes, &flags); err != nil { panic(err) } @@ -190,7 +190,7 @@ func init() { if err != nil { panic(err) } - var flags map[string]interface{} + flags := map[string]interface{}{} if err = json.Unmarshal(flagsBytes, &flags); err != nil { panic(err) } @@ -313,6 +313,14 @@ func NewDefaultNetwork( return NewNetwork(log, config, "", "") } +func copyFlags(flags map[string]interface{}) map[string]interface{} { + outFlags := map[string]interface{}{} + for k, v := range flags { + outFlags[k] = v + } + return outFlags +} + // NewDefaultConfig creates a new default network config func NewDefaultConfig(binaryPath string) network.Config { config := defaultNetworkConfig @@ -320,6 +328,11 @@ func NewDefaultConfig(binaryPath string) network.Config { // Don't overwrite [DefaultNetworkConfig.NodeConfigs] config.NodeConfigs = make([]node.Config, len(defaultNetworkConfig.NodeConfigs)) copy(config.NodeConfigs, defaultNetworkConfig.NodeConfigs) + // copy maps + config.Flags = copyFlags(config.Flags) + for i := range config.NodeConfigs { + config.NodeConfigs[i].Flags = copyFlags(config.NodeConfigs[i].Flags) + } return config } From 89901ca08fdfc50eb210dc0b7d85a1c62b0efa00 Mon Sep 17 00:00:00 2001 From: Felipe Madero Date: Thu, 4 Aug 2022 13:22:09 -0300 Subject: [PATCH 10/18] address PR comments --- .github/workflows/build-test-release.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/build-test-release.yml b/.github/workflows/build-test-release.yml index 9ab4d874..887326c2 100644 --- a/.github/workflows/build-test-release.yml +++ b/.github/workflows/build-test-release.yml @@ -4,8 +4,6 @@ on: push: branches: - main - tags: - - "*" pull_request: permissions: From e7d082192431bd9956e6c09c12ad0d157041c577 Mon Sep 17 00:00:00 2001 From: Felipe Madero Date: Thu, 4 Aug 2022 14:11:48 -0300 Subject: [PATCH 11/18] address PR comments --- local/network.go | 8 +++----- server/network.go | 23 +++++++---------------- server/server.go | 21 +++++++++++++-------- 3 files changed, 23 insertions(+), 29 deletions(-) diff --git a/local/network.go b/local/network.go index 8c7451b8..02473dd9 100644 --- a/local/network.go +++ b/local/network.go @@ -454,9 +454,6 @@ func (ln *localNetwork) addNode(nodeConfig node.Config) (node.Node, error) { } addNetworkFlags(ln.log, ln.flags, nodeConfig.Flags) - // TODO: remove this when plugin-dir is available - delete(nodeConfig.Flags, PluginDirKey) - // it shouldn't happen that just one is empty, most probably both, // but in any case if just one is empty it's unusable so we just assign a new one. if nodeConfig.StakingCert == "" || nodeConfig.StakingKey == "" { @@ -713,7 +710,7 @@ func (ln *localNetwork) removeNode(ctx context.Context, nodeName string) error { } // Restart [nodeName] using the same config, optionally changing [binaryPath], -// [pluginDir], [whitelistedSubnets] +// [whitelistedSubnets] func (ln *localNetwork) RestartNode( ctx context.Context, nodeName string, @@ -732,7 +729,8 @@ func (ln *localNetwork) RestartNode( if binaryPath != "" { nodeConfig.BinaryPath = binaryPath - nodeConfig.Flags[PluginDirKey] = filepath.Join(filepath.Dir(binaryPath), "plugins") + // remove old value if present, to look for vm binaries in new binary path location + delete(nodeConfig.Flags, PluginDirKey) } if whitelistedSubnets != "" { diff --git a/server/network.go b/server/network.go index 4bbace96..fb653ffe 100644 --- a/server/network.go +++ b/server/network.go @@ -99,20 +99,12 @@ func newLocalNetwork(opts localNetworkOptions) (*localNetwork, error) { return nil, err } - pluginDir := "" - if opts.execPath != "" { - pluginDir = filepath.Join(filepath.Dir(opts.execPath), "plugins") - } - if opts.pluginDir != "" { - pluginDir = opts.pluginDir - } - return &localNetwork{ logger: logger, execPath: opts.execPath, - pluginDir: pluginDir, + pluginDir: opts.pluginDir, options: opts, @@ -146,6 +138,12 @@ func (lc *localNetwork) createConfig() error { for k, v := range globalConfig { cfg.Flags[k] = v } + if lc.pluginDir != "" { + cfg.Flags[PluginDirKey] = lc.pluginDir + } + if lc.options.whitelistedSubnets != "" { + cfg.Flags[config.WhitelistedSubnetsKey] = lc.options.whitelistedSubnets + } for i := range cfg.NodeConfigs { // NOTE: Naming convention for node names is currently `node` + number, i.e. `node1,node2,node3,...node101` @@ -181,14 +179,7 @@ func (lc *localNetwork) createConfig() error { cfg.NodeConfigs[i].Flags[config.LogsDirKey] = logDir cfg.NodeConfigs[i].Flags[config.DBPathKey] = dbDir - if lc.pluginDir != "" { - cfg.NodeConfigs[i].Flags[PluginDirKey] = lc.pluginDir - } - if lc.options.whitelistedSubnets != "" { - cfg.NodeConfigs[i].Flags[config.WhitelistedSubnetsKey] = lc.options.whitelistedSubnets - } - cfg.NodeConfigs[i].BinaryPath = lc.execPath cfg.NodeConfigs[i].RedirectStdout = lc.options.redirectNodesOutput cfg.NodeConfigs[i].RedirectStderr = lc.options.redirectNodesOutput } diff --git a/server/server.go b/server/server.go index 9a25c57a..d2a322fa 100644 --- a/server/server.go +++ b/server/server.go @@ -247,16 +247,13 @@ func (s *server) Start(ctx context.Context, req *rpcpb.StartRequest) (*rpcpb.Sta if err := utils.CheckExecPath(req.GetExecPath()); err != nil { return nil, err } - pluginDir := "" + pluginDir := filepath.Join(filepath.Dir(req.GetExecPath()), "plugins") if req.GetPluginDir() != "" { pluginDir = req.GetPluginDir() } - if pluginDir == "" { - pluginDir = filepath.Join(filepath.Dir(req.GetExecPath()), "plugins") - } chainSpecs := []network.BlockchainSpec{} if len(req.GetBlockchainSpecs()) > 0 { - zap.L().Info("plugin dir", zap.String("plugin-dir", pluginDir)) + zap.L().Info("checking vm binaries", zap.String("plugin-dir", pluginDir)) for i := range req.GetBlockchainSpecs() { spec := req.GetBlockchainSpecs()[i] if spec.SubnetId != nil { @@ -330,7 +327,7 @@ func (s *server) Start(ctx context.Context, req *rpcpb.StartRequest) (*rpcpb.Sta zap.String("whitelistedSubnets", whitelistedSubnets), zap.Int32("pid", pid), zap.String("rootDataDir", rootDataDir), - zap.String("pluginDir", pluginDir), + zap.String("pluginDir", req.GetPluginDir()), zap.Any("chainConfigs", req.ChainConfigs), zap.String("globalNodeConfig", globalNodeConfig), ) @@ -350,7 +347,7 @@ func (s *server) Start(ctx context.Context, req *rpcpb.StartRequest) (*rpcpb.Sta numNodes: numNodes, whitelistedSubnets: whitelistedSubnets, redirectNodesOutput: s.cfg.RedirectNodesOutput, - pluginDir: pluginDir, + pluginDir: req.GetPluginDir(), globalNodeConfig: globalNodeConfig, customNodeConfigs: customNodeConfigs, chainConfigs: req.ChainConfigs, @@ -445,6 +442,14 @@ func (s *server) CreateBlockchains(ctx context.Context, req *rpcpb.CreateBlockch return nil, ErrNoBlockchainSpec } + pluginDir := "" + if s.network.execPath != "" { + pluginDir = filepath.Join(filepath.Dir(s.network.execPath), "plugins") + } + if s.network.pluginDir != "" { + pluginDir = s.network.pluginDir + } + chainSpecs := []network.BlockchainSpec{} for i := range req.GetBlockchainSpecs() { vmName := req.GetBlockchainSpecs()[i].VmName @@ -459,7 +464,7 @@ func (s *server) CreateBlockchains(ctx context.Context, req *rpcpb.CreateBlockch return nil, ErrInvalidVMName } if err := utils.CheckPluginPaths( - filepath.Join(s.network.pluginDir, vmID.String()), + filepath.Join(pluginDir, vmID.String()), vmGenesisFilePath, ); err != nil { return nil, err From 382baf824f374114957c5fa26343baf2e659026f Mon Sep 17 00:00:00 2001 From: Fabio Barone Date: Thu, 4 Aug 2022 13:41:31 -0500 Subject: [PATCH 12/18] addressed PR comments --- cmd/control/control.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/control/control.go b/cmd/control/control.go index 1e0481fa..4d880c90 100644 --- a/cmd/control/control.go +++ b/cmd/control/control.go @@ -618,7 +618,7 @@ var ( func newSendOutboundMessageCommand() *cobra.Command { cmd := &cobra.Command{ - Use: "send-outbound-message [options]", + Use: "send-outbound-message node-name [options]", Short: "Sends an outbound message to an attached peer.", RunE: sendOutboundMessageFunc, Args: cobra.ExactArgs(1), From 4d824af6878984184c1937770812e5c41115bc34 Mon Sep 17 00:00:00 2001 From: Connor Daly Date: Thu, 4 Aug 2022 15:54:46 -0400 Subject: [PATCH 13/18] Revert "Remove buildir flag reloaded" --- .github/workflows/build-test-release.yml | 2 + local/network.go | 41 ++++++++--------- local/node.go | 12 ++--- local/snapshot.go | 12 ++--- network/node/node.go | 4 +- server/network.go | 57 ++++++++++++++++++------ server/server.go | 21 ++++----- 7 files changed, 86 insertions(+), 63 deletions(-) diff --git a/.github/workflows/build-test-release.yml b/.github/workflows/build-test-release.yml index 887326c2..9ab4d874 100644 --- a/.github/workflows/build-test-release.yml +++ b/.github/workflows/build-test-release.yml @@ -4,6 +4,8 @@ on: push: branches: - main + tags: + - "*" pull_request: permissions: diff --git a/local/network.go b/local/network.go index 02473dd9..7229159f 100644 --- a/local/network.go +++ b/local/network.go @@ -45,8 +45,6 @@ const ( defaultLogsSubdir = "logs" // difference between unlock schedule locktime and startime in original genesis genesisLocktimeStartimeDelta = 2836800 - // TODO: replace with config.PluginDirKey when included in avalanchego - PluginDirKey = "plugin-dir" ) // interface compliance @@ -522,7 +520,7 @@ func (ln *localNetwork) addNode(nodeConfig node.Config) (node.Node, error) { dbDir: nodeData.dbDir, logsDir: nodeData.logsDir, config: nodeConfig, - pluginDir: nodeData.pluginDir, + buildDir: nodeData.buildDir, httpHost: nodeData.httpHost, attachedPeers: map[string]peer.Peer{}, } @@ -710,7 +708,7 @@ func (ln *localNetwork) removeNode(ctx context.Context, nodeName string) error { } // Restart [nodeName] using the same config, optionally changing [binaryPath], -// [whitelistedSubnets] +// [buildDir], [whitelistedSubnets] func (ln *localNetwork) RestartNode( ctx context.Context, nodeName string, @@ -729,8 +727,7 @@ func (ln *localNetwork) RestartNode( if binaryPath != "" { nodeConfig.BinaryPath = binaryPath - // remove old value if present, to look for vm binaries in new binary path location - delete(nodeConfig.Flags, PluginDirKey) + nodeConfig.Flags[config.BuildDirKey] = filepath.Dir(binaryPath) } if whitelistedSubnets != "" { @@ -784,13 +781,13 @@ func (ln *localNetwork) setNodeName(nodeConfig *node.Config) error { } type buildFlagsReturn struct { - flags []string - apiPort uint16 - p2pPort uint16 - dbDir string - logsDir string - pluginDir string - httpHost string + flags []string + apiPort uint16 + p2pPort uint16 + dbDir string + logsDir string + buildDir string + httpHost string } // buildFlags returns the: @@ -811,8 +808,8 @@ func (ln *localNetwork) buildFlags( return buildFlagsReturn{}, err } - // pluginDir from all configs for node - pluginDir, err := getConfigEntry(nodeConfig.Flags, configFile, PluginDirKey, "") + // buildDir from all configs for node + buildDir, err := getConfigEntry(nodeConfig.Flags, configFile, config.BuildDirKey, "") if err != nil { return buildFlagsReturn{}, err } @@ -870,12 +867,12 @@ func (ln *localNetwork) buildFlags( } return buildFlagsReturn{ - flags: flags, - apiPort: apiPort, - p2pPort: p2pPort, - dbDir: dbDir, - logsDir: logsDir, - pluginDir: pluginDir, - httpHost: httpHost, + flags: flags, + apiPort: apiPort, + p2pPort: p2pPort, + dbDir: dbDir, + logsDir: logsDir, + buildDir: buildDir, + httpHost: httpHost, }, nil } diff --git a/local/node.go b/local/node.go index f2b38939..c4d3eed1 100644 --- a/local/node.go +++ b/local/node.go @@ -65,8 +65,8 @@ type localNode struct { dbDir string // The logs dir of the node logsDir string - // The plugin dir of the node - pluginDir string + // The build dir of the node + buildDir string // The node config config node.Config // The node httpHost @@ -226,11 +226,11 @@ func (node *localNode) GetBinaryPath() string { } // See node.Node -func (node *localNode) GetPluginDir() string { - if node.pluginDir == "" { - return filepath.Join(filepath.Dir(node.GetBinaryPath()), "plugins") +func (node *localNode) GetBuildDir() string { + if node.buildDir == "" { + return filepath.Dir(node.GetBinaryPath()) } - return node.pluginDir + return node.buildDir } // See node.Node diff --git a/local/snapshot.go b/local/snapshot.go index f34c7a0e..e8cbe19a 100644 --- a/local/snapshot.go +++ b/local/snapshot.go @@ -26,7 +26,7 @@ func NewNetworkFromSnapshot( rootDir string, snapshotsDir string, binaryPath string, - pluginDir string, + buildDir string, chainConfigs map[string]string, flags map[string]interface{}, ) (network.Network, error) { @@ -45,7 +45,7 @@ func NewNetworkFromSnapshot( if err != nil { return net, err } - err = net.loadSnapshot(context.Background(), snapshotName, binaryPath, pluginDir, chainConfigs, flags) + err = net.loadSnapshot(context.Background(), snapshotName, binaryPath, buildDir, chainConfigs, flags) return net, err } @@ -155,7 +155,7 @@ func (ln *localNetwork) loadSnapshot( ctx context.Context, snapshotName string, binaryPath string, - pluginDir string, + buildDir string, chainConfigs map[string]string, flags map[string]interface{}, ) error { @@ -202,10 +202,10 @@ func (ln *localNetwork) loadSnapshot( networkConfig.NodeConfigs[i].BinaryPath = binaryPath } } - // replace plugin dir - if pluginDir != "" { + // replace build dir + if buildDir != "" { for i := range networkConfig.NodeConfigs { - networkConfig.NodeConfigs[i].Flags[PluginDirKey] = pluginDir + networkConfig.NodeConfigs[i].Flags[config.BuildDirKey] = buildDir } } // add chain configs diff --git a/network/node/node.go b/network/node/node.go index e6b8edee..9b8d263c 100644 --- a/network/node/node.go +++ b/network/node/node.go @@ -45,8 +45,8 @@ type Node interface { GetDbDir() string // Return this node's logs dir GetLogsDir() string - // Return this node's plugin dir - GetPluginDir() string + // Return this node's build dir + GetBuildDir() string // Return this node's config file contents GetConfigFile() string // Return this node's config diff --git a/server/network.go b/server/network.go index fb653ffe..7bb25e7b 100644 --- a/server/network.go +++ b/server/network.go @@ -21,11 +21,6 @@ import ( "github.com/ava-labs/avalanchego/utils/logging" ) -const ( - // TODO: replace with config.PluginDirKey when included in avalanchego - PluginDirKey = "plugin-dir" -) - type localNetwork struct { logger logging.Logger @@ -138,12 +133,6 @@ func (lc *localNetwork) createConfig() error { for k, v := range globalConfig { cfg.Flags[k] = v } - if lc.pluginDir != "" { - cfg.Flags[PluginDirKey] = lc.pluginDir - } - if lc.options.whitelistedSubnets != "" { - cfg.Flags[config.WhitelistedSubnetsKey] = lc.options.whitelistedSubnets - } for i := range cfg.NodeConfigs { // NOTE: Naming convention for node names is currently `node` + number, i.e. `node1,node2,node3,...node101` @@ -173,13 +162,26 @@ func (lc *localNetwork) createConfig() error { cfg.NodeConfigs[i].Flags[k] = v } + // avalanchego expects buildDir (parent dir of pluginDir) to be provided at cmdline + buildDir, err := getBuildDir(lc.execPath, lc.pluginDir) + if err != nil { + return err + } + // remove http port defined in local network config, to get dynamic port // generation when creating a new network delete(cfg.NodeConfigs[i].Flags, config.HTTPPortKey) cfg.NodeConfigs[i].Flags[config.LogsDirKey] = logDir cfg.NodeConfigs[i].Flags[config.DBPathKey] = dbDir + if buildDir != "" { + cfg.NodeConfigs[i].Flags[config.BuildDirKey] = buildDir + } + if lc.options.whitelistedSubnets != "" { + cfg.NodeConfigs[i].Flags[config.WhitelistedSubnetsKey] = lc.options.whitelistedSubnets + } + cfg.NodeConfigs[i].BinaryPath = lc.execPath cfg.NodeConfigs[i].RedirectStdout = lc.options.redirectNodesOutput cfg.NodeConfigs[i].RedirectStderr = lc.options.redirectNodesOutput } @@ -188,6 +190,23 @@ func (lc *localNetwork) createConfig() error { return nil } +// generates buildDir from pluginDir, and if not available, from execPath +// returns error if pluginDir is non empty and invalid +func getBuildDir(execPath string, pluginDir string) (string, error) { + buildDir := "" + if execPath != "" { + buildDir = filepath.Dir(execPath) + } + if pluginDir != "" { + pluginDir := filepath.Clean(pluginDir) + if filepath.Base(pluginDir) != "plugins" { + return "", fmt.Errorf("plugin dir %q is not named plugins", pluginDir) + } + buildDir = filepath.Dir(pluginDir) + } + return buildDir, nil +} + func (lc *localNetwork) start() error { if err := lc.createConfig(); err != nil { return err @@ -326,6 +345,11 @@ func (lc *localNetwork) loadSnapshot( ) error { color.Outf("{{blue}}{{bold}}create and run local network from snapshot{{/}}\n") + buildDir, err := getBuildDir(lc.execPath, lc.pluginDir) + if err != nil { + return err + } + var globalNodeConfig map[string]interface{} if lc.options.globalNodeConfig != "" { if err := json.Unmarshal([]byte(lc.options.globalNodeConfig), &globalNodeConfig); err != nil { @@ -339,7 +363,7 @@ func (lc *localNetwork) loadSnapshot( lc.options.rootDataDir, lc.options.snapshotsDir, lc.execPath, - lc.pluginDir, + buildDir, lc.options.chainConfigs, globalNodeConfig, ) @@ -439,10 +463,15 @@ func (lc *localNetwork) updateNodeInfo() error { lc.nodeInfos = make(map[string]*rpcpb.NodeInfo) for _, name := range lc.nodeNames { node := nodes[name] + var pluginDir string whitelistedSubnets, err := node.GetFlag(config.WhitelistedSubnetsKey) if err != nil { return err } + buildDir := node.GetBuildDir() + if buildDir != "" { + pluginDir = filepath.Join(buildDir, "plugins") + } lc.nodeInfos[name] = &rpcpb.NodeInfo{ Name: node.GetName(), @@ -452,7 +481,7 @@ func (lc *localNetwork) updateNodeInfo() error { LogDir: node.GetLogsDir(), DbDir: node.GetDbDir(), Config: []byte(node.GetConfigFile()), - PluginDir: node.GetPluginDir(), + PluginDir: pluginDir, WhitelistedSubnets: whitelistedSubnets, } @@ -461,7 +490,7 @@ func (lc *localNetwork) updateNodeInfo() error { lc.execPath = node.GetBinaryPath() } if lc.pluginDir == "" { - lc.pluginDir = node.GetPluginDir() + lc.pluginDir = pluginDir } // update default chain configs if empty if lc.chainConfigs == nil { diff --git a/server/server.go b/server/server.go index d2a322fa..9a25c57a 100644 --- a/server/server.go +++ b/server/server.go @@ -247,13 +247,16 @@ func (s *server) Start(ctx context.Context, req *rpcpb.StartRequest) (*rpcpb.Sta if err := utils.CheckExecPath(req.GetExecPath()); err != nil { return nil, err } - pluginDir := filepath.Join(filepath.Dir(req.GetExecPath()), "plugins") + pluginDir := "" if req.GetPluginDir() != "" { pluginDir = req.GetPluginDir() } + if pluginDir == "" { + pluginDir = filepath.Join(filepath.Dir(req.GetExecPath()), "plugins") + } chainSpecs := []network.BlockchainSpec{} if len(req.GetBlockchainSpecs()) > 0 { - zap.L().Info("checking vm binaries", zap.String("plugin-dir", pluginDir)) + zap.L().Info("plugin dir", zap.String("plugin-dir", pluginDir)) for i := range req.GetBlockchainSpecs() { spec := req.GetBlockchainSpecs()[i] if spec.SubnetId != nil { @@ -327,7 +330,7 @@ func (s *server) Start(ctx context.Context, req *rpcpb.StartRequest) (*rpcpb.Sta zap.String("whitelistedSubnets", whitelistedSubnets), zap.Int32("pid", pid), zap.String("rootDataDir", rootDataDir), - zap.String("pluginDir", req.GetPluginDir()), + zap.String("pluginDir", pluginDir), zap.Any("chainConfigs", req.ChainConfigs), zap.String("globalNodeConfig", globalNodeConfig), ) @@ -347,7 +350,7 @@ func (s *server) Start(ctx context.Context, req *rpcpb.StartRequest) (*rpcpb.Sta numNodes: numNodes, whitelistedSubnets: whitelistedSubnets, redirectNodesOutput: s.cfg.RedirectNodesOutput, - pluginDir: req.GetPluginDir(), + pluginDir: pluginDir, globalNodeConfig: globalNodeConfig, customNodeConfigs: customNodeConfigs, chainConfigs: req.ChainConfigs, @@ -442,14 +445,6 @@ func (s *server) CreateBlockchains(ctx context.Context, req *rpcpb.CreateBlockch return nil, ErrNoBlockchainSpec } - pluginDir := "" - if s.network.execPath != "" { - pluginDir = filepath.Join(filepath.Dir(s.network.execPath), "plugins") - } - if s.network.pluginDir != "" { - pluginDir = s.network.pluginDir - } - chainSpecs := []network.BlockchainSpec{} for i := range req.GetBlockchainSpecs() { vmName := req.GetBlockchainSpecs()[i].VmName @@ -464,7 +459,7 @@ func (s *server) CreateBlockchains(ctx context.Context, req *rpcpb.CreateBlockch return nil, ErrInvalidVMName } if err := utils.CheckPluginPaths( - filepath.Join(pluginDir, vmID.String()), + filepath.Join(s.network.pluginDir, vmID.String()), vmGenesisFilePath, ); err != nil { return nil, err From 0b3ccfbd6344050a70cd6977aca172067d09db53 Mon Sep 17 00:00:00 2001 From: Fabio Barone Date: Thu, 4 Aug 2022 15:26:58 -0500 Subject: [PATCH 14/18] addressed PR comments --- tests/e2e/e2e_test.go | 297 ++++++++++++++++++++++++++++++++---------- 1 file changed, 231 insertions(+), 66 deletions(-) diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index 5ecbe6b1..adeb0b73 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -24,10 +24,9 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/message" "github.com/ava-labs/avalanchego/utils/constants" - "github.com/prometheus/client_golang/prometheus" - ginkgo "github.com/onsi/ginkgo/v2" "github.com/onsi/gomega" + "github.com/prometheus/client_golang/prometheus" ) func TestE2e(t *testing.T) { @@ -39,13 +38,12 @@ func TestE2e(t *testing.T) { } var ( - logLevel string - gRPCEp string - gRPCGatewayEp string - execPath1 string - execPath2 string - subnetEvmPath string - existingSubnetID string + logLevel string + gRPCEp string + gRPCGatewayEp string + execPath1 string + execPath2 string + subnetEvmPath string newNodeName = "test-add-node" customNodeConfigs = map[string]string{ @@ -124,70 +122,237 @@ var _ = ginkgo.AfterSuite(func() { }) var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() { - ginkgo.It("can start with blockchain", func() { - color.Outf("{{green}}sending 'start' with the valid binary path:{{/}} %q\n", execPath1) - ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) - resp, err := cli.Start(ctx, execPath2, - client.WithBlockchainSpecs([]*rpcpb.BlockchainSpec{ - { - VmName: "subnetevm", - Genesis: "tests/e2e/subnet-evm-genesis.json", + ginkgo.It("can create blockhains", func() { + existingSubnetID := "" + ginkgo.By("start with blockchain specs", func() { + color.Outf("{{green}}sending 'start' with the valid binary path:{{/}} %q\n", execPath1) + ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) + resp, err := cli.Start(ctx, execPath2, + client.WithBlockchainSpecs([]*rpcpb.BlockchainSpec{ + { + VmName: "subnetevm", + Genesis: "tests/e2e/subnet-evm-genesis.json", + }, + }), + ) + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + color.Outf("{{green}}successfully started:{{/}} %+v\n", resp.ClusterInfo.NodeNames) + }) + + ginkgo.By("wait for network to be healthy", func() { + color.Outf("{{blue}}wait for health{{/}\n") + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + _, err := cli.Health(ctx) + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + }) + + ginkgo.By("get status", func() { + color.Outf("{{blue}}get status for existing subnet ID{{/}}\n") + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + subnetDeployed := false + LOOP: + for !subnetDeployed { + select { + case <-ctx.Done(): + break LOOP + case <-time.After(5 * time.Second): + stat, err := cli.Status(ctx) + gomega.Ω(err).Should(gomega.BeNil()) + if stat.ClusterInfo.CustomChainsHealthy { + subnetDeployed = true + existingSubnetID = stat.ClusterInfo.GetSubnets()[0] + gomega.Ω(existingSubnetID).Should(gomega.Not(gomega.BeNil())) + } + } + } + cancel() + gomega.Ω(subnetDeployed).Should(gomega.BeTrue()) + }) + + time.Sleep(1 * time.Second) + ginkgo.By("can create a blockchain with a new subnet id", func() { + color.Outf("{{blue}}can create a blockchain in a new subnet{{/}}\n") + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + _, err := cli.CreateBlockchains(ctx, + []*rpcpb.BlockchainSpec{ + { + VmName: "subnetevm", + Genesis: "tests/e2e/subnet-evm-genesis.json", + }, }, - }), - ) - cancel() - gomega.Ω(err).Should(gomega.BeNil()) - color.Outf("{{green}}successfully started:{{/}} %+v\n", resp.ClusterInfo.NodeNames) + ) + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + }) - color.Outf("{{blue}}wait for health{{/}\n") - ctx, cancel = context.WithTimeout(context.Background(), 2*time.Minute) - _, err = cli.Health(ctx) - cancel() - gomega.Ω(err).Should(gomega.BeNil()) + ginkgo.By("wait for network to be healthy", func() { + color.Outf("{{blue}}wait for health{{/}\n") + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + _, err := cli.Health(ctx) + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + }) + + ginkgo.By("can create a blockchain with an existing subnet id", func() { + color.Outf("{{blue}}can create a blockchain in an existing subnet{{/}}\n") + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + _, err := cli.CreateBlockchains(ctx, + []*rpcpb.BlockchainSpec{ + { + VmName: "subnetevm", + Genesis: "tests/e2e/subnet-evm-genesis.json", + SubnetId: &existingSubnetID, + }, + }, + ) + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + }) + + ginkgo.By("wait for network to be healthy", func() { + color.Outf("{{blue}}wait for health{{/}\n") + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + _, err := cli.Health(ctx) + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + }) - color.Outf("{{blue}}get status for existing subnet ID{{/}}\n") - ctx, cancel = context.WithTimeout(context.Background(), 2*time.Minute) - subnetDeployed := false - LOOP: - for !subnetDeployed { - select { - case <-ctx.Done(): - break LOOP - case <-time.After(5 * time.Second): - stat, err := cli.Status(ctx) - gomega.Ω(err).Should(gomega.BeNil()) - if stat.ClusterInfo.CustomChainsHealthy { - subnetDeployed = true - existingSubnetID = stat.ClusterInfo.GetSubnets()[0] - gomega.Ω(existingSubnetID).Should(gomega.Not(gomega.BeNil())) + ginkgo.By("get status", func() { + color.Outf("{{blue}}get status for existing subnet ID{{/}}\n") + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + subnetDeployed := false + LOOP: + for !subnetDeployed { + select { + case <-ctx.Done(): + break LOOP + case <-time.After(5 * time.Second): + stat, err := cli.Status(ctx) + gomega.Ω(err).Should(gomega.BeNil()) + if stat.ClusterInfo.CustomChainsHealthy { + subnetDeployed = true + existingSubnetID = stat.ClusterInfo.GetSubnets()[0] + gomega.Ω(existingSubnetID).Should(gomega.Not(gomega.BeNil())) + } } } - } - cancel() - gomega.Ω(subnetDeployed).Should(gomega.BeTrue()) - color.Outf("{{blue}}can create a blockchain in an existing subnet{{/}}\n") - ctx, cancel = context.WithTimeout(context.Background(), 2*time.Minute) - _, err = cli.CreateBlockchains(ctx, - []*rpcpb.BlockchainSpec{ - { - VmName: "subnetevm", - Genesis: "tests/e2e/subnet-evm-genesis.json", - SubnetId: &existingSubnetID, + cancel() + gomega.Ω(subnetDeployed).Should(gomega.BeTrue()) + }) + + time.Sleep(1 * time.Second) + ginkgo.By("can save snapshot", func() { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + _, err := cli.SaveSnapshot(ctx, "test") + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + }) + + ginkgo.By("can load snapshot", func() { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + _, err := cli.LoadSnapshot(ctx, "test") + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + }) + + ginkgo.By("wait for network to be healthy", func() { + color.Outf("{{blue}}wait for health{{/}\n") + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + _, err := cli.Health(ctx) + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + }) + + ginkgo.By("get status", func() { + color.Outf("{{blue}}get status for existing subnet ID{{/}}\n") + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + subnetDeployed := false + LOOP: + for !subnetDeployed { + select { + case <-ctx.Done(): + break LOOP + case <-time.After(5 * time.Second): + stat, err := cli.Status(ctx) + gomega.Ω(err).Should(gomega.BeNil()) + if stat.ClusterInfo.CustomChainsHealthy { + subnetDeployed = true + existingSubnetID = stat.ClusterInfo.GetSubnets()[0] + gomega.Ω(existingSubnetID).Should(gomega.Not(gomega.BeNil())) + } + } + } + cancel() + gomega.Ω(subnetDeployed).Should(gomega.BeTrue()) + }) + + // need to remove the snapshot otherwise it fails later in the 2nd part of snapshot tests + // (testing for no snapshots) + ginkgo.By("can remove snapshot", func() { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + _, err := cli.RemoveSnapshot(ctx, "test") + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + }) + time.Sleep(1 * time.Second) + ginkgo.By("can create a blockchain with an existing subnet id", func() { + color.Outf("{{blue}}can create a blockchain in an existing subnet{{/}}\n") + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + _, err := cli.CreateBlockchains(ctx, + []*rpcpb.BlockchainSpec{ + { + VmName: "subnetevm", + Genesis: "tests/e2e/subnet-evm-genesis.json", + SubnetId: &existingSubnetID, + }, }, - }, - ) - cancel() - gomega.Ω(err).Should(gomega.BeNil()) - color.Outf("{{blue}}wait for health{{/}\n") - ctx, cancel = context.WithTimeout(context.Background(), 2*time.Minute) - _, err = cli.Health(ctx) - cancel() - gomega.Ω(err).Should(gomega.BeNil()) - ctx, cancel = context.WithTimeout(context.Background(), 2*time.Minute) - _, err = cli.Stop(ctx) - cancel() - gomega.Ω(err).Should(gomega.BeNil()) + ) + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + }) + + ginkgo.By("wait for network to be healthy", func() { + color.Outf("{{blue}}wait for health{{/}\n") + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + _, err := cli.Health(ctx) + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + }) + + ginkgo.By("get status", func() { + color.Outf("{{blue}}get status for existing subnet ID{{/}}\n") + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + subnetDeployed := false + LOOP: + for !subnetDeployed { + select { + case <-ctx.Done(): + break LOOP + case <-time.After(5 * time.Second): + stat, err := cli.Status(ctx) + gomega.Ω(err).Should(gomega.BeNil()) + if stat.ClusterInfo.CustomChainsHealthy { + subnetDeployed = true + existingSubnetID = stat.ClusterInfo.GetSubnets()[0] + gomega.Ω(existingSubnetID).Should(gomega.Not(gomega.BeNil())) + } + } + } + cancel() + gomega.Ω(subnetDeployed).Should(gomega.BeTrue()) + }) + + time.Sleep(1 * time.Second) + ginkgo.By("stop the network", func() { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + _, err := cli.Stop(ctx) + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + }) }) + ginkgo.It("can start", func() { ginkgo.By("start request with invalid exec path should fail", func() { ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) From c84176a41f88ae57eaa179fda1f689a7ad9ac4c1 Mon Sep 17 00:00:00 2001 From: Felipe Madero Date: Fri, 5 Aug 2022 13:55:45 -0300 Subject: [PATCH 15/18] bump go version --- .github/workflows/build-test-release.yml | 6 +++--- go.mod | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-test-release.yml b/.github/workflows/build-test-release.yml index 9ab4d874..f51bb2a8 100644 --- a/.github/workflows/build-test-release.yml +++ b/.github/workflows/build-test-release.yml @@ -38,7 +38,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-go@v2 with: - go-version: "1.17.2" # The Go version to use. + go-version: 1.18 - run: go test -v -timeout 10m -race ./... e2e_test: name: e2e tests @@ -51,7 +51,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v2 with: - go-version: 1.17 + go-version: 1.18 - name: Run e2e tests shell: bash run: scripts/tests.e2e.sh 1.7.12 1.7.13 @@ -66,7 +66,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v2 with: - go-version: 1.17 + go-version: 1.18 - name: Run GoReleaser uses: goreleaser/goreleaser-action@v2 with: diff --git a/go.mod b/go.mod index 20dfa9f3..e857f027 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/ava-labs/avalanche-network-runner -go 1.17 +go 1.18 require ( github.com/ava-labs/avalanchego v1.7.16 From cd6826af778592fdee97d98fb8efcc3bd4713431 Mon Sep 17 00:00:00 2001 From: Fabio Barone Date: Fri, 5 Aug 2022 12:36:24 -0500 Subject: [PATCH 16/18] fix waiting --- tests/e2e/e2e_test.go | 191 ++++++++++-------------------------------- 1 file changed, 45 insertions(+), 146 deletions(-) diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index 624338c5..6656d903 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -125,7 +125,7 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() { ginkgo.It("can create blockhains", func() { existingSubnetID := "" ginkgo.By("start with blockchain specs", func() { - color.Outf("{{green}}sending 'start' with the valid binary path:{{/}} %q\n", execPath1) + color.Outf("{{green}}sending 'start' with the valid binary path:{{/}} %q\n", execPath2) ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) resp, err := cli.Start(ctx, execPath2, client.WithBlockchainSpecs([]*rpcpb.BlockchainSpec{ @@ -140,38 +140,11 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() { color.Outf("{{green}}successfully started:{{/}} %+v\n", resp.ClusterInfo.NodeNames) }) - ginkgo.By("wait for network to be healthy", func() { - color.Outf("{{blue}}wait for health{{/}\n") - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) - _, err := cli.Health(ctx) - cancel() - gomega.Ω(err).Should(gomega.BeNil()) + ginkgo.By("wait for custom chains healthy", func() { + // ignore subnet ID here + _ = waitForCustomChainsHealthy() }) - ginkgo.By("get status", func() { - color.Outf("{{blue}}get status for existing subnet ID{{/}}\n") - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) - subnetDeployed := false - LOOP: - for !subnetDeployed { - select { - case <-ctx.Done(): - break LOOP - case <-time.After(5 * time.Second): - stat, err := cli.Status(ctx) - gomega.Ω(err).Should(gomega.BeNil()) - if stat.ClusterInfo.CustomChainsHealthy { - subnetDeployed = true - existingSubnetID = stat.ClusterInfo.GetSubnets()[0] - gomega.Ω(existingSubnetID).Should(gomega.Not(gomega.BeNil())) - } - } - } - cancel() - gomega.Ω(subnetDeployed).Should(gomega.BeTrue()) - }) - - time.Sleep(1 * time.Second) ginkgo.By("can create a blockchain with a new subnet id", func() { color.Outf("{{blue}}can create a blockchain in a new subnet{{/}}\n") ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) @@ -187,12 +160,8 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() { gomega.Ω(err).Should(gomega.BeNil()) }) - ginkgo.By("wait for network to be healthy", func() { - color.Outf("{{blue}}wait for health{{/}\n") - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) - _, err := cli.Health(ctx) - cancel() - gomega.Ω(err).Should(gomega.BeNil()) + ginkgo.By("get subnet ID", func() { + existingSubnetID = waitForCustomChainsHealthy() }) ginkgo.By("can create a blockchain with an existing subnet id", func() { @@ -211,38 +180,11 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() { gomega.Ω(err).Should(gomega.BeNil()) }) - ginkgo.By("wait for network to be healthy", func() { - color.Outf("{{blue}}wait for health{{/}\n") - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) - _, err := cli.Health(ctx) - cancel() - gomega.Ω(err).Should(gomega.BeNil()) - }) - - ginkgo.By("get status", func() { - color.Outf("{{blue}}get status for existing subnet ID{{/}}\n") - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) - subnetDeployed := false - LOOP: - for !subnetDeployed { - select { - case <-ctx.Done(): - break LOOP - case <-time.After(5 * time.Second): - stat, err := cli.Status(ctx) - gomega.Ω(err).Should(gomega.BeNil()) - if stat.ClusterInfo.CustomChainsHealthy { - subnetDeployed = true - existingSubnetID = stat.ClusterInfo.GetSubnets()[0] - gomega.Ω(existingSubnetID).Should(gomega.Not(gomega.BeNil())) - } - } - } - cancel() - gomega.Ω(subnetDeployed).Should(gomega.BeTrue()) + ginkgo.By("wait for custom chains healthy", func() { + // ignore subnet ID here + _ = waitForCustomChainsHealthy() }) - time.Sleep(1 * time.Second) ginkgo.By("can save snapshot", func() { ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) _, err := cli.SaveSnapshot(ctx, "test") @@ -257,35 +199,9 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() { gomega.Ω(err).Should(gomega.BeNil()) }) - ginkgo.By("wait for network to be healthy", func() { - color.Outf("{{blue}}wait for health{{/}\n") - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) - _, err := cli.Health(ctx) - cancel() - gomega.Ω(err).Should(gomega.BeNil()) - }) - - ginkgo.By("get status", func() { - color.Outf("{{blue}}get status for existing subnet ID{{/}}\n") - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) - subnetDeployed := false - LOOP: - for !subnetDeployed { - select { - case <-ctx.Done(): - break LOOP - case <-time.After(5 * time.Second): - stat, err := cli.Status(ctx) - gomega.Ω(err).Should(gomega.BeNil()) - if stat.ClusterInfo.CustomChainsHealthy { - subnetDeployed = true - existingSubnetID = stat.ClusterInfo.GetSubnets()[0] - gomega.Ω(existingSubnetID).Should(gomega.Not(gomega.BeNil())) - } - } - } - cancel() - gomega.Ω(subnetDeployed).Should(gomega.BeTrue()) + ginkgo.By("wait for custom chains healthy", func() { + // ignore subnet ID here + _ = waitForCustomChainsHealthy() }) // need to remove the snapshot otherwise it fails later in the 2nd part of snapshot tests @@ -313,38 +229,11 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() { gomega.Ω(err).Should(gomega.BeNil()) }) - ginkgo.By("wait for network to be healthy", func() { - color.Outf("{{blue}}wait for health{{/}\n") - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) - _, err := cli.Health(ctx) - cancel() - gomega.Ω(err).Should(gomega.BeNil()) + ginkgo.By("wait for custom chains healthy", func() { + // ignore subnet ID here + _ = waitForCustomChainsHealthy() }) - ginkgo.By("get status", func() { - color.Outf("{{blue}}get status for existing subnet ID{{/}}\n") - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) - subnetDeployed := false - LOOP: - for !subnetDeployed { - select { - case <-ctx.Done(): - break LOOP - case <-time.After(5 * time.Second): - stat, err := cli.Status(ctx) - gomega.Ω(err).Should(gomega.BeNil()) - if stat.ClusterInfo.CustomChainsHealthy { - subnetDeployed = true - existingSubnetID = stat.ClusterInfo.GetSubnets()[0] - gomega.Ω(existingSubnetID).Should(gomega.Not(gomega.BeNil())) - } - } - } - cancel() - gomega.Ω(subnetDeployed).Should(gomega.BeTrue()) - }) - - time.Sleep(1 * time.Second) ginkgo.By("stop the network", func() { ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) _, err := cli.Stop(ctx) @@ -647,26 +536,8 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() { gomega.Ω(err).Should(gomega.BeNil()) }) ginkgo.By("wait for network to be healthy", func() { - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) - var created bool - continueLoop := true - for continueLoop { - select { - case <-ctx.Done(): - continueLoop = false - case <-time.After(5 * time.Second): - ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) - status, err := cli.Status(ctx) - cancel() - gomega.Ω(err).Should(gomega.BeNil()) - created = status.ClusterInfo.CustomChainsHealthy - if created { - continueLoop = false - } - } - } - cancel() - gomega.Ω(created).Should(gomega.Equal(true)) + // ignore subnet ID here + _ = waitForCustomChainsHealthy() }) ginkgo.By("check subnets are 1", func() { ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) @@ -800,3 +671,31 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() { }) }) }) + +func waitForCustomChainsHealthy() string { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + var created bool + continueLoop := true + for continueLoop { + select { + case <-ctx.Done(): + continueLoop = false + case <-time.After(5 * time.Second): + cctx, ccancel := context.WithTimeout(context.Background(), 15*time.Second) + status, err := cli.Status(cctx) + ccancel() + gomega.Ω(err).Should(gomega.BeNil()) + created = status.ClusterInfo.CustomChainsHealthy + if created { + continueLoop = false + existingSubnetID := status.ClusterInfo.GetSubnets()[0] + gomega.Ω(existingSubnetID).Should(gomega.Not(gomega.BeNil())) + cancel() + return existingSubnetID + } + } + } + cancel() + gomega.Ω(created).Should(gomega.Equal(true)) + return "" +} From 1b3d11634921bb090df53a492d09a04a7a1d027a Mon Sep 17 00:00:00 2001 From: Felipe Madero Date: Fri, 5 Aug 2022 18:51:22 -0300 Subject: [PATCH 17/18] bump --- .golangci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.golangci.yml b/.golangci.yml index 5766f999..34d83809 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -6,7 +6,7 @@ run: - api/mocks - local/mocks - rpcpb - go: "1.17" + go: "1.18" linters: disable: From 7459a873aecc06a2138c28e5f5113f0968b5084b Mon Sep 17 00:00:00 2001 From: Fabio Barone Date: Mon, 8 Aug 2022 11:38:17 -0500 Subject: [PATCH 18/18] addressed PR comments --- tests/e2e/e2e_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index 6656d903..09b38117 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -212,7 +212,6 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() { cancel() gomega.Ω(err).Should(gomega.BeNil()) }) - time.Sleep(1 * time.Second) ginkgo.By("can create a blockchain with an existing subnet id", func() { color.Outf("{{blue}}can create a blockchain in an existing subnet{{/}}\n") ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)