github.com/tyler-smith/go-ethereum@v1.9.7/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 "io/ioutil" 23 "os" 24 "testing" 25 "time" 26 27 "github.com/docker/docker/pkg/reexec" 28 "github.com/ethereum/go-ethereum/internal/cmdtest" 29 "github.com/ethereum/go-ethereum/rpc" 30 ) 31 32 func tmpdir(t *testing.T) string { 33 dir, err := ioutil.TempDir("", "geth-test") 34 if err != nil { 35 t.Fatal(err) 36 } 37 return dir 38 } 39 40 type testgeth struct { 41 *cmdtest.TestCmd 42 43 // template variables for expect 44 Datadir string 45 Etherbase string 46 } 47 48 func init() { 49 // Run the app if we've been exec'd as "geth-test" in runGeth. 50 reexec.Register("geth-test", func() { 51 if err := app.Run(os.Args); err != nil { 52 fmt.Fprintln(os.Stderr, err) 53 os.Exit(1) 54 } 55 os.Exit(0) 56 }) 57 } 58 59 func TestMain(m *testing.M) { 60 // check if we have been reexec'd 61 if reexec.Init() { 62 return 63 } 64 os.Exit(m.Run()) 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 { 74 case arg == "-datadir" || arg == "--datadir": 75 if i < len(args)-1 { 76 tt.Datadir = args[i+1] 77 } 78 case arg == "-etherbase" || arg == "--etherbase": 79 if i < len(args)-1 { 80 tt.Etherbase = args[i+1] 81 } 82 } 83 } 84 if tt.Datadir == "" { 85 tt.Datadir = tmpdir(t) 86 tt.Cleanup = func() { os.RemoveAll(tt.Datadir) } 87 args = append([]string{"-datadir", tt.Datadir}, args...) 88 // Remove the temporary datadir if something fails below. 89 defer func() { 90 if t.Failed() { 91 tt.Cleanup() 92 } 93 }() 94 } 95 96 // Boot "geth". This actually runs the test binary but the TestMain 97 // function will prevent any tests from running. 98 tt.Run("geth-test", args...) 99 100 return tt 101 } 102 103 // waitForEndpoint attempts to connect to an RPC endpoint until it succeeds. 104 func waitForEndpoint(t *testing.T, endpoint string, timeout time.Duration) { 105 probe := func() bool { 106 ctx, cancel := context.WithTimeout(context.Background(), timeout) 107 defer cancel() 108 c, err := rpc.DialContext(ctx, endpoint) 109 if c != nil { 110 _, err = c.SupportedModules() 111 c.Close() 112 } 113 return err == nil 114 } 115 116 start := time.Now() 117 for { 118 if probe() { 119 return 120 } 121 if time.Since(start) > timeout { 122 t.Fatal("endpoint", endpoint, "did not open within", timeout) 123 } 124 time.Sleep(200 * time.Millisecond) 125 } 126 }