Files
evm/tests/utils_e2e/command.go_e2e

127 lines
3.6 KiB
Plaintext

//go:build e2e
// Copyright (C) 2019-2025, 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/go-cmd/cmd"
"github.com/luxfi/log"
"github.com/luxfi/vm/api/health"
"github.com/onsi/ginkgo/v2"
"github.com/stretchr/testify/require"
)
// 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)
healthy, err := client.Readiness(context.Background(), nil)
require.NoError(err)
require.True(healthy.Healthy)
})
}
// RegisterNodeRun registers a before suite that starts an Luxd process to use for the e2e tests
// and an after suite that stops the Luxd process
func RegisterNodeRun() {
require := require.New(ginkgo.GinkgoT())
// BeforeSuite starts an Luxd 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()
require.NoError(err)
log.Info("Starting Luxd node", "wd", wd)
cmd, err := RunCommand("./scripts/run.sh")
startCmd = cmd
require.NoError(err)
// Assumes that startCmd will launch a node with HTTP Port at [utils.DefaultLocalNodeURI]
healthClient := health.NewClient(DefaultLocalNodeURI)
healthy, err := health.AwaitReady(ctx, healthClient, HealthCheckTimeout, nil)
require.NoError(err)
require.True(healthy)
log.Info("Luxd node is healthy")
})
ginkgo.AfterSuite(func() {
require.NotNil(startCmd)
require.NoError(startCmd.Stop())
// 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)
require.NoError(os.Setenv("RPC_URI", chainURI))
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)
}