github.com/MetalBlockchain/subnet-evm@v0.6.3/tests/utils/command.go (about)

     1  // Copyright (C) 2019-2022, Ava Labs, Inc. All rights reserved.
     2  // See the file LICENSE for licensing terms.
     3  
     4  package utils
     5  
     6  import (
     7  	"context"
     8  	"fmt"
     9  	"os"
    10  	"os/exec"
    11  	"strings"
    12  	"time"
    13  
    14  	"github.com/MetalBlockchain/metalgo/api/health"
    15  	"github.com/ethereum/go-ethereum/log"
    16  	"github.com/go-cmd/cmd"
    17  	"github.com/onsi/ginkgo/v2"
    18  	"github.com/onsi/gomega"
    19  )
    20  
    21  // RunCommand starts the command [bin] with the given [args] and returns the command to the caller
    22  // TODO cmd package mentions we can do this more efficiently with cmd.NewCmdOptions rather than looping
    23  // and calling Status().
    24  func RunCommand(bin string, args ...string) (*cmd.Cmd, error) {
    25  	log.Info("Executing", "cmd", fmt.Sprintf("%s %s", bin, strings.Join(args, " ")))
    26  
    27  	curCmd := cmd.NewCmd(bin, args...)
    28  	_ = curCmd.Start()
    29  
    30  	// to stream outputs
    31  	ticker := time.NewTicker(10 * time.Millisecond)
    32  	go func() {
    33  		prevLine := ""
    34  		for range ticker.C {
    35  			status := curCmd.Status()
    36  			n := len(status.Stdout)
    37  			if n == 0 {
    38  				continue
    39  			}
    40  
    41  			line := status.Stdout[n-1]
    42  			if prevLine != line && line != "" {
    43  				fmt.Println("[streaming output]", line)
    44  			}
    45  
    46  			prevLine = line
    47  		}
    48  	}()
    49  
    50  	return curCmd, nil
    51  }
    52  
    53  func RegisterPingTest() {
    54  	ginkgo.It("ping the network", ginkgo.Label("ping"), func() {
    55  		client := health.NewClient(DefaultLocalNodeURI)
    56  		healthy, err := client.Readiness(context.Background(), nil)
    57  		gomega.Expect(err).Should(gomega.BeNil())
    58  		gomega.Expect(healthy.Healthy).Should(gomega.BeTrue())
    59  	})
    60  }
    61  
    62  // RegisterNodeRun registers a before suite that starts an AvalancheGo process to use for the e2e tests
    63  // and an after suite that stops the AvalancheGo process
    64  func RegisterNodeRun() {
    65  	// BeforeSuite starts an AvalancheGo process to use for the e2e tests
    66  	var startCmd *cmd.Cmd
    67  	_ = ginkgo.BeforeSuite(func() {
    68  		ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
    69  		defer cancel()
    70  
    71  		wd, err := os.Getwd()
    72  		gomega.Expect(err).Should(gomega.BeNil())
    73  		log.Info("Starting AvalancheGo node", "wd", wd)
    74  		cmd, err := RunCommand("./scripts/run.sh")
    75  		startCmd = cmd
    76  		gomega.Expect(err).Should(gomega.BeNil())
    77  
    78  		// Assumes that startCmd will launch a node with HTTP Port at [utils.DefaultLocalNodeURI]
    79  		healthClient := health.NewClient(DefaultLocalNodeURI)
    80  		healthy, err := health.AwaitReady(ctx, healthClient, HealthCheckTimeout, nil)
    81  		gomega.Expect(err).Should(gomega.BeNil())
    82  		gomega.Expect(healthy).Should(gomega.BeTrue())
    83  		log.Info("AvalancheGo node is healthy")
    84  	})
    85  
    86  	ginkgo.AfterSuite(func() {
    87  		gomega.Expect(startCmd).ShouldNot(gomega.BeNil())
    88  		gomega.Expect(startCmd.Stop()).Should(gomega.BeNil())
    89  		// TODO add a new node to bootstrap off of the existing node and ensure it can bootstrap all subnets
    90  		// created during the test
    91  	})
    92  }
    93  
    94  // RunDefaultHardhatTests runs the hardhat tests in the given [testPath] on the blockchain with [blockchainID]
    95  // [execPath] is the path where the test command is executed
    96  func RunHardhatTests(ctx context.Context, blockchainID string, execPath string, testPath string) {
    97  	chainURI := GetDefaultChainURI(blockchainID)
    98  	RunHardhatTestsCustomURI(ctx, chainURI, execPath, testPath)
    99  }
   100  
   101  func RunHardhatTestsCustomURI(ctx context.Context, chainURI string, execPath string, testPath string) {
   102  	log.Info(
   103  		"Executing HardHat tests on blockchain",
   104  		"testPath", testPath,
   105  		"ChainURI", chainURI,
   106  	)
   107  
   108  	cmd := exec.Command("npx", "hardhat", "test", testPath, "--network", "local")
   109  	cmd.Dir = execPath
   110  
   111  	log.Info("Sleeping to wait for test ping", "rpcURI", chainURI)
   112  	err := os.Setenv("RPC_URI", chainURI)
   113  	gomega.Expect(err).Should(gomega.BeNil())
   114  	log.Info("Running test command", "cmd", cmd.String())
   115  
   116  	out, err := cmd.CombinedOutput()
   117  	fmt.Printf("\nCombined output:\n\n%s\n", string(out))
   118  	gomega.Expect(err).Should(gomega.BeNil())
   119  }