Files
evm/tests/utils/command.go
T

141 lines
4.0 KiB
Go

// Copyright (C) 2020-2022, Lux Industries, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package utils
import (
"context"
"fmt"
"os"
"os/exec"
"strings"
"time"
"github.com/luxfi/log"
"github.com/go-cmd/cmd"
"github.com/onsi/ginkgo/v2"
"github.com/onsi/gomega"
"github.com/stretchr/testify/require"
"github.com/luxfi/node/v2/api/health"
)
// RunCommand starts the command [bin] with the given [args] and returns the command to the caller
// TODO cmd package mentions we can do this more efficiently with cmd.NewCmdOptions rather than looping
// and calling Status().
func RunCommand(bin string, args ...string) (*cmd.Cmd, error) {
log.Info("Executing", "cmd", fmt.Sprintf("%s %s", bin, strings.Join(args, " ")))
curCmd := cmd.NewCmd(bin, args...)
_ = curCmd.Start()
// to stream outputs
ticker := time.NewTicker(10 * time.Millisecond)
go func() {
prevLine := ""
for range ticker.C {
status := curCmd.Status()
n := len(status.Stdout)
if n == 0 {
continue
}
line := status.Stdout[n-1]
if prevLine != line && line != "" {
fmt.Println("[streaming output]", line)
}
prevLine = line
}
}()
return curCmd, nil
}
func RegisterPingTest() {
require := require.New(ginkgo.GinkgoT())
ginkgo.It("ping the network", ginkgo.Label("ping"), func() {
client := health.NewClient(DefaultLocalNodeURI)
healthyReply, err := client.Health(context.Background(), nil)
require.NoError(err)
require.NotNil(healthyReply)
require.True(healthyReply.Healthy)
})
}
// RegisterNodeRun registers a before suite that starts a Lux process to use for the e2e tests
// and an after suite that stops the Lux process
func RegisterNodeRun() {
// BeforeSuite starts a Lux process to use for the e2e tests
var startCmd *cmd.Cmd
_ = ginkgo.BeforeSuite(func() {
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel()
wd, err := os.Getwd()
gomega.Expect(err).Should(gomega.BeNil())
log.Info("Starting Lux node", "wd", wd)
cmd, err := RunCommand("./scripts/run.sh")
startCmd = cmd
gomega.Expect(err).Should(gomega.BeNil())
// Assumes that startCmd will launch a node with HTTP Port at [utils.DefaultLocalNodeURI]
healthClient := health.NewClient(DefaultLocalNodeURI)
// Wait for the node to be healthy
ticker := time.NewTicker(100 * time.Millisecond)
defer ticker.Stop()
timeout := time.After(HealthCheckTimeout)
for {
select {
case <-ticker.C:
healthyReply, err := healthClient.Health(ctx, nil)
if err == nil && healthyReply != nil && healthyReply.Healthy {
gomega.Expect(true).Should(gomega.BeTrue())
return
}
case <-timeout:
gomega.Expect(false).Should(gomega.BeTrue(), "Node did not become healthy within timeout")
return
}
}
log.Info("Lux node is healthy")
})
ginkgo.AfterSuite(func() {
gomega.Expect(startCmd).ShouldNot(gomega.BeNil())
gomega.Expect(startCmd.Stop()).Should(gomega.Succeed())
// TODO add a new node to bootstrap off of the existing node and ensure it can bootstrap all subnets
// created during the test
})
}
// RunHardhatTests runs the hardhat tests in the given [testPath] on the blockchain with [blockchainID]
// [execPath] is the path where the test command is executed
func RunHardhatTests(ctx context.Context, blockchainID string, execPath string, testPath string) {
chainURI := GetDefaultChainURI(blockchainID)
RunHardhatTestsCustomURI(ctx, chainURI, execPath, testPath)
}
func RunHardhatTestsCustomURI(ctx context.Context, chainURI string, execPath string, testPath string) {
require := require.New(ginkgo.GinkgoT())
log.Info(
"Executing HardHat tests on blockchain",
"testPath", testPath,
"ChainURI", chainURI,
)
cmd := exec.Command("npx", "hardhat", "test", testPath, "--network", "local")
cmd.Dir = execPath
log.Info("Sleeping to wait for test ping", "rpcURI", chainURI)
err := os.Setenv("RPC_URI", chainURI)
require.NoError(err)
log.Info("Running test command", "cmd", cmd.String())
out, err := cmd.CombinedOutput()
fmt.Printf("\nCombined output:\n\n%s\n", string(out))
require.NoError(err)
}