github.com/ethereum/go-ethereum@v1.14.4-0.20240516095835-473ee8fc07a3/cmd/geth/run_test.go (about)

     1  // Copyright 2016 The go-ethereum Authors
     2  // This file is part of go-ethereum.
     3  //
     4  // go-ethereum is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // go-ethereum is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU General Public License
    15  // along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package main
    18  
    19  import (
    20  	"context"
    21  	"fmt"
    22  	"os"
    23  	"testing"
    24  	"time"
    25  
    26  	"github.com/ethereum/go-ethereum/internal/cmdtest"
    27  	"github.com/ethereum/go-ethereum/internal/reexec"
    28  	"github.com/ethereum/go-ethereum/rpc"
    29  )
    30  
    31  type testgeth struct {
    32  	*cmdtest.TestCmd
    33  
    34  	// template variables for expect
    35  	Datadir   string
    36  	Etherbase string
    37  }
    38  
    39  func init() {
    40  	// Run the app if we've been exec'd as "geth-test" in runGeth.
    41  	reexec.Register("geth-test", func() {
    42  		if err := app.Run(os.Args); err != nil {
    43  			fmt.Fprintln(os.Stderr, err)
    44  			os.Exit(1)
    45  		}
    46  		os.Exit(0)
    47  	})
    48  }
    49  
    50  func TestMain(m *testing.M) {
    51  	// check if we have been reexec'd
    52  	if reexec.Init() {
    53  		return
    54  	}
    55  	os.Exit(m.Run())
    56  }
    57  
    58  func initGeth(t *testing.T) string {
    59  	args := []string{"--networkid=42", "init", "./testdata/clique.json"}
    60  	t.Logf("Initializing geth: %v ", args)
    61  	g := runGeth(t, args...)
    62  	datadir := g.Datadir
    63  	g.WaitExit()
    64  	return datadir
    65  }
    66  
    67  // spawns geth with the given command line args. If the args don't set --datadir, the
    68  // child g gets a temporary data directory.
    69  func runGeth(t *testing.T, args ...string) *testgeth {
    70  	tt := &testgeth{}
    71  	tt.TestCmd = cmdtest.NewTestCmd(t, tt)
    72  	for i, arg := range args {
    73  		switch arg {
    74  		case "--datadir":
    75  			if i < len(args)-1 {
    76  				tt.Datadir = args[i+1]
    77  			}
    78  		case "--miner.etherbase":
    79  			if i < len(args)-1 {
    80  				tt.Etherbase = args[i+1]
    81  			}
    82  		}
    83  	}
    84  	if tt.Datadir == "" {
    85  		// The temporary datadir will be removed automatically if something fails below.
    86  		tt.Datadir = t.TempDir()
    87  		args = append([]string{"--datadir", tt.Datadir}, args...)
    88  	}
    89  
    90  	// Boot "geth". This actually runs the test binary but the TestMain
    91  	// function will prevent any tests from running.
    92  	tt.Run("geth-test", args...)
    93  
    94  	return tt
    95  }
    96  
    97  // waitForEndpoint attempts to connect to an RPC endpoint until it succeeds.
    98  func waitForEndpoint(t *testing.T, endpoint string, timeout time.Duration) {
    99  	probe := func() bool {
   100  		ctx, cancel := context.WithTimeout(context.Background(), timeout)
   101  		defer cancel()
   102  		c, err := rpc.DialContext(ctx, endpoint)
   103  		if c != nil {
   104  			_, err = c.SupportedModules()
   105  			c.Close()
   106  		}
   107  		return err == nil
   108  	}
   109  
   110  	start := time.Now()
   111  	for {
   112  		if probe() {
   113  			return
   114  		}
   115  		if time.Since(start) > timeout {
   116  			t.Fatal("endpoint", endpoint, "did not open within", timeout)
   117  		}
   118  		time.Sleep(200 * time.Millisecond)
   119  	}
   120  }