github.com/hyperion-hyn/go-ethereum@v2.4.0+incompatible/cmd/geth/consolecmd_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 "crypto/rand" 21 "io/ioutil" 22 "math/big" 23 "os" 24 "path/filepath" 25 "runtime" 26 "strconv" 27 "strings" 28 "testing" 29 "time" 30 31 "github.com/ethereum/go-ethereum/params" 32 ) 33 34 const ( 35 ipcAPIs = "admin:1.0 debug:1.0 eth:1.0 istanbul:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 shh:1.0 txpool:1.0 web3:1.0" 36 httpAPIs = "admin:1.0 eth:1.0 net:1.0 rpc:1.0 web3:1.0" 37 nodeKey = "b68c0338aa4b266bf38ebe84c6199ae9fac8b29f32998b3ed2fbeafebe8d65c9" 38 ) 39 40 var genesis = `{ 41 "config": { 42 "chainId": 2017, 43 "homesteadBlock": 1, 44 "eip150Block": 2, 45 "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", 46 "eip155Block": 3, 47 "eip158Block": 3, 48 "istanbul": { 49 "epoch": 30000, 50 "policy": 0 51 } 52 }, 53 "nonce": "0x0", 54 "timestamp": "0x0", 55 "gasLimit": "0x47b760", 56 "difficulty": "0x1", 57 "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365", 58 "coinbase": "0x0000000000000000000000000000000000000000", 59 "alloc": { 60 "491937757d1b26e29c507b8d4c0b233c2747e68d": { 61 "balance": "0x446c3b15f9926687d2c40534fdb564000000000000" 62 } 63 }, 64 "number": "0x0", 65 "gasUsed": "0x0", 66 "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000" 67 } 68 ` 69 70 // Tests that a node embedded within a console can be started up properly and 71 // then terminated by closing the input stream. 72 func TestConsoleWelcome(t *testing.T) { 73 defer SetResetPrivateConfig("ignore")() 74 coinbase := "0x491937757d1b26e29c507b8d4c0b233c2747e68d" 75 76 datadir := setupIstanbul(t) 77 defer os.RemoveAll(datadir) 78 79 // Start a geth console, make sure it's cleaned up and terminate the console 80 geth := runGeth(t, 81 "--datadir", datadir, "--port", "0", "--maxpeers", "0", "--nodiscover", "--nat", "none", 82 "--etherbase", coinbase, "--shh", 83 "console") 84 85 // Gather all the infos the welcome message needs to contain 86 geth.SetTemplateFunc("goos", func() string { return runtime.GOOS }) 87 geth.SetTemplateFunc("goarch", func() string { return runtime.GOARCH }) 88 geth.SetTemplateFunc("gover", runtime.Version) 89 geth.SetTemplateFunc("gethver", func() string { return params.VersionWithMeta }) 90 geth.SetTemplateFunc("quorumver", func() string { return params.QuorumVersion }) 91 geth.SetTemplateFunc("niltime", func() string { return time.Unix(0, 0).Format(time.RFC1123) }) 92 geth.SetTemplateFunc("apis", func() string { return ipcAPIs }) 93 94 // Verify the actual welcome message to the required template 95 geth.Expect(` 96 Welcome to the Geth JavaScript console! 97 98 instance: Geth/v{{gethver}}(quorum-v{{quorumver}})/{{goos}}-{{goarch}}/{{gover}} 99 coinbase: {{.Etherbase}} 100 at block: 0 ({{niltime}}) 101 datadir: {{.Datadir}} 102 modules: {{apis}} 103 104 > {{.InputLine "exit"}} 105 `) 106 geth.ExpectExit() 107 } 108 109 // Tests that a console can be attached to a running node via various means. 110 func TestIPCAttachWelcome(t *testing.T) { 111 defer SetResetPrivateConfig("ignore")() 112 // Configure the instance for IPC attachement 113 coinbase := "0x491937757d1b26e29c507b8d4c0b233c2747e68d" 114 var ipc string 115 116 datadir := setupIstanbul(t) 117 defer os.RemoveAll(datadir) 118 119 if runtime.GOOS == "windows" { 120 ipc = `\\.\pipe\geth` + strconv.Itoa(trulyRandInt(100000, 999999)) 121 } else { 122 ipc = filepath.Join(datadir, "geth.ipc") 123 } 124 125 // Note: we need --shh because testAttachWelcome checks for default 126 // list of ipc modules and shh is included there. 127 geth := runGeth(t, 128 "--datadir", datadir, "--port", "0", "--maxpeers", "0", "--nodiscover", "--nat", "none", 129 "--etherbase", coinbase, "--shh", "--ipcpath", ipc) 130 131 time.Sleep(2 * time.Second) // Simple way to wait for the RPC endpoint to open 132 testAttachWelcome(t, geth, "ipc:"+ipc, ipcAPIs) 133 134 geth.Interrupt() 135 geth.ExpectExit() 136 } 137 138 func TestHTTPAttachWelcome(t *testing.T) { 139 defer SetResetPrivateConfig("ignore")() 140 coinbase := "0x491937757d1b26e29c507b8d4c0b233c2747e68d" 141 port := strconv.Itoa(trulyRandInt(1024, 65536)) // Yeah, sometimes this will fail, sorry :P 142 143 datadir := setupIstanbul(t) 144 defer os.RemoveAll(datadir) 145 146 geth := runGeth(t, 147 "--datadir", datadir, "--port", "0", "--maxpeers", "0", "--nodiscover", "--nat", "none", 148 "--etherbase", coinbase, "--rpc", "--rpcport", port, "--rpcapi", "admin,eth,net,web3") 149 150 time.Sleep(2 * time.Second) // Simple way to wait for the RPC endpoint to open 151 testAttachWelcome(t, geth, "http://localhost:"+port, httpAPIs) 152 153 geth.Interrupt() 154 geth.ExpectExit() 155 } 156 157 func TestWSAttachWelcome(t *testing.T) { 158 defer SetResetPrivateConfig("ignore")() 159 coinbase := "0x491937757d1b26e29c507b8d4c0b233c2747e68d" 160 port := strconv.Itoa(trulyRandInt(1024, 65536)) // Yeah, sometimes this will fail, sorry :P 161 162 datadir := setupIstanbul(t) 163 defer os.RemoveAll(datadir) 164 165 geth := runGeth(t, 166 "--datadir", datadir, "--port", "0", "--maxpeers", "0", "--nodiscover", "--nat", "none", 167 "--etherbase", coinbase, "--ws", "--wsport", port, "--wsapi", "admin,eth,net,web3") 168 169 time.Sleep(2 * time.Second) // Simple way to wait for the RPC endpoint to open 170 testAttachWelcome(t, geth, "ws://localhost:"+port, httpAPIs) 171 172 geth.Interrupt() 173 geth.ExpectExit() 174 } 175 176 func testAttachWelcome(t *testing.T, geth *testgeth, endpoint, apis string) { 177 // Attach to a running geth note and terminate immediately 178 attach := runGeth(t, "attach", endpoint) 179 defer attach.ExpectExit() 180 attach.CloseStdin() 181 182 // Gather all the infos the welcome message needs to contain 183 attach.SetTemplateFunc("goos", func() string { return runtime.GOOS }) 184 attach.SetTemplateFunc("goarch", func() string { return runtime.GOARCH }) 185 attach.SetTemplateFunc("gover", runtime.Version) 186 attach.SetTemplateFunc("gethver", func() string { return params.VersionWithMeta }) 187 attach.SetTemplateFunc("quorumver", func() string { return params.QuorumVersion }) 188 attach.SetTemplateFunc("etherbase", func() string { return geth.Etherbase }) 189 attach.SetTemplateFunc("niltime", func() string { return time.Unix(0, 0).Format(time.RFC1123) }) 190 attach.SetTemplateFunc("ipc", func() bool { return strings.HasPrefix(endpoint, "ipc") || strings.Contains(apis, "admin") }) 191 attach.SetTemplateFunc("datadir", func() string { return geth.Datadir }) 192 attach.SetTemplateFunc("apis", func() string { return apis }) 193 194 // Verify the actual welcome message to the required template 195 attach.Expect(` 196 Welcome to the Geth JavaScript console! 197 198 instance: Geth/v{{gethver}}(quorum-v{{quorumver}})/{{goos}}-{{goarch}}/{{gover}} 199 coinbase: {{etherbase}} 200 at block: 0 ({{niltime}}){{if ipc}} 201 datadir: {{datadir}}{{end}} 202 modules: {{apis}} 203 204 > {{.InputLine "exit" }} 205 `) 206 attach.ExpectExit() 207 } 208 209 // trulyRandInt generates a crypto random integer used by the console tests to 210 // not clash network ports with other tests running cocurrently. 211 func trulyRandInt(lo, hi int) int { 212 num, _ := rand.Int(rand.Reader, big.NewInt(int64(hi-lo))) 213 return int(num.Int64()) + lo 214 } 215 216 // setupIstanbul creates a temporary directory and copies nodekey and genesis.json. 217 // It initializes istanbul by calling geth init 218 func setupIstanbul(t *testing.T) string { 219 datadir := tmpdir(t) 220 gethPath := filepath.Join(datadir, "geth") 221 os.Mkdir(gethPath, 0700) 222 223 // Initialize the data directory with the custom genesis block 224 json := filepath.Join(datadir, "genesis.json") 225 if err := ioutil.WriteFile(json, []byte(genesis), 0600); err != nil { 226 t.Fatalf("failed to write genesis file: %v", err) 227 } 228 229 nodeKeyFile := filepath.Join(gethPath, "nodekey") 230 if err := ioutil.WriteFile(nodeKeyFile, []byte(nodeKey), 0600); err != nil { 231 t.Fatalf("failed to write nodekey file: %v", err) 232 } 233 234 runGeth(t, "--datadir", datadir, "init", json).WaitExit() 235 236 return datadir 237 } 238 239 func SetResetPrivateConfig(value string) func() { 240 existingValue := os.Getenv("PRIVATE_CONFIG") 241 os.Setenv("PRIVATE_CONFIG", value) 242 return func() { 243 os.Setenv("PRIVATE_CONFIG", existingValue) 244 } 245 }