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 }