github.com/zjj1991/quorum@v0.0.0-20190524123704-ae4b0a1e1a19/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 = "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 coinbase := "0x491937757d1b26e29c507b8d4c0b233c2747e68d" 74 75 datadir := setupIstanbul(t) 76 defer os.RemoveAll(datadir) 77 78 // Start a geth console, make sure it's cleaned up and terminate the console 79 geth := runGeth(t, 80 "--datadir", datadir, "--port", "0", "--maxpeers", "0", "--nodiscover", "--nat", "none", 81 "--etherbase", coinbase, "--shh", 82 "console") 83 84 // Gather all the infos the welcome message needs to contain 85 geth.SetTemplateFunc("goos", func() string { return runtime.GOOS }) 86 geth.SetTemplateFunc("goarch", func() string { return runtime.GOARCH }) 87 geth.SetTemplateFunc("gover", runtime.Version) 88 geth.SetTemplateFunc("gethver", func() string { return params.VersionWithMeta }) 89 geth.SetTemplateFunc("quorumver", func() string { return params.QuorumVersion }) 90 geth.SetTemplateFunc("niltime", func() string { return time.Unix(0, 0).Format(time.RFC1123) }) 91 geth.SetTemplateFunc("apis", func() string { return ipcAPIs }) 92 93 // Verify the actual welcome message to the required template 94 geth.Expect(` 95 Welcome to the Geth JavaScript console! 96 97 instance: Geth/v{{gethver}}(quorum-v{{quorumver}})/{{goos}}-{{goarch}}/{{gover}} 98 coinbase: {{.Etherbase}} 99 at block: 0 ({{niltime}}) 100 datadir: {{.Datadir}} 101 modules: {{apis}} 102 103 > {{.InputLine "exit"}} 104 `) 105 geth.ExpectExit() 106 } 107 108 // Tests that a console can be attached to a running node via various means. 109 func TestIPCAttachWelcome(t *testing.T) { 110 // Configure the instance for IPC attachement 111 coinbase := "0x491937757d1b26e29c507b8d4c0b233c2747e68d" 112 var ipc string 113 114 datadir := setupIstanbul(t) 115 defer os.RemoveAll(datadir) 116 117 if runtime.GOOS == "windows" { 118 ipc = `\\.\pipe\geth` + strconv.Itoa(trulyRandInt(100000, 999999)) 119 } else { 120 ipc = filepath.Join(datadir, "geth.ipc") 121 } 122 123 // Note: we need --shh because testAttachWelcome checks for default 124 // list of ipc modules and shh is included there. 125 geth := runGeth(t, 126 "--datadir", datadir, "--port", "0", "--maxpeers", "0", "--nodiscover", "--nat", "none", 127 "--etherbase", coinbase, "--shh", "--ipcpath", ipc) 128 129 time.Sleep(2 * time.Second) // Simple way to wait for the RPC endpoint to open 130 testAttachWelcome(t, geth, "ipc:"+ipc, ipcAPIs) 131 132 geth.Interrupt() 133 geth.ExpectExit() 134 } 135 136 func TestHTTPAttachWelcome(t *testing.T) { 137 coinbase := "0x491937757d1b26e29c507b8d4c0b233c2747e68d" 138 port := strconv.Itoa(trulyRandInt(1024, 65536)) // Yeah, sometimes this will fail, sorry :P 139 140 datadir := setupIstanbul(t) 141 defer os.RemoveAll(datadir) 142 143 geth := runGeth(t, 144 "--datadir", datadir, "--port", "0", "--maxpeers", "0", "--nodiscover", "--nat", "none", 145 "--etherbase", coinbase, "--rpc", "--rpcport", port) 146 147 time.Sleep(2 * time.Second) // Simple way to wait for the RPC endpoint to open 148 testAttachWelcome(t, geth, "http://localhost:"+port, httpAPIs) 149 150 geth.Interrupt() 151 geth.ExpectExit() 152 } 153 154 func TestWSAttachWelcome(t *testing.T) { 155 coinbase := "0x491937757d1b26e29c507b8d4c0b233c2747e68d" 156 port := strconv.Itoa(trulyRandInt(1024, 65536)) // Yeah, sometimes this will fail, sorry :P 157 158 datadir := setupIstanbul(t) 159 defer os.RemoveAll(datadir) 160 161 geth := runGeth(t, 162 "--datadir", datadir, "--port", "0", "--maxpeers", "0", "--nodiscover", "--nat", "none", 163 "--etherbase", coinbase, "--ws", "--wsport", port) 164 165 time.Sleep(2 * time.Second) // Simple way to wait for the RPC endpoint to open 166 testAttachWelcome(t, geth, "ws://localhost:"+port, httpAPIs) 167 168 geth.Interrupt() 169 geth.ExpectExit() 170 } 171 172 func testAttachWelcome(t *testing.T, geth *testgeth, endpoint, apis string) { 173 // Attach to a running geth note and terminate immediately 174 attach := runGeth(t, "attach", endpoint) 175 defer attach.ExpectExit() 176 attach.CloseStdin() 177 178 // Gather all the infos the welcome message needs to contain 179 attach.SetTemplateFunc("goos", func() string { return runtime.GOOS }) 180 attach.SetTemplateFunc("goarch", func() string { return runtime.GOARCH }) 181 attach.SetTemplateFunc("gover", runtime.Version) 182 attach.SetTemplateFunc("gethver", func() string { return params.VersionWithMeta }) 183 attach.SetTemplateFunc("quorumver", func() string { return params.QuorumVersion }) 184 attach.SetTemplateFunc("etherbase", func() string { return geth.Etherbase }) 185 attach.SetTemplateFunc("niltime", func() string { return time.Unix(0, 0).Format(time.RFC1123) }) 186 attach.SetTemplateFunc("ipc", func() bool { return strings.HasPrefix(endpoint, "ipc") }) 187 attach.SetTemplateFunc("datadir", func() string { return geth.Datadir }) 188 attach.SetTemplateFunc("apis", func() string { return apis }) 189 190 // Verify the actual welcome message to the required template 191 attach.Expect(` 192 Welcome to the Geth JavaScript console! 193 194 instance: Geth/v{{gethver}}(quorum-v{{quorumver}})/{{goos}}-{{goarch}}/{{gover}} 195 coinbase: {{etherbase}} 196 at block: 0 ({{niltime}}){{if ipc}} 197 datadir: {{datadir}}{{end}} 198 modules: {{apis}} 199 200 > {{.InputLine "exit" }} 201 `) 202 attach.ExpectExit() 203 } 204 205 // trulyRandInt generates a crypto random integer used by the console tests to 206 // not clash network ports with other tests running cocurrently. 207 func trulyRandInt(lo, hi int) int { 208 num, _ := rand.Int(rand.Reader, big.NewInt(int64(hi-lo))) 209 return int(num.Int64()) + lo 210 } 211 212 // setupIstanbul creates a temporary directory and copies nodekey and genesis.json. 213 // It initializes istanbul by calling geth init 214 func setupIstanbul(t *testing.T) string { 215 datadir := tmpdir(t) 216 gethPath := filepath.Join(datadir, "geth") 217 os.Mkdir(gethPath, 0700) 218 219 // Initialize the data directory with the custom genesis block 220 json := filepath.Join(datadir, "genesis.json") 221 if err := ioutil.WriteFile(json, []byte(genesis), 0600); err != nil { 222 t.Fatalf("failed to write genesis file: %v", err) 223 } 224 225 nodeKeyFile := filepath.Join(gethPath, "nodekey") 226 if err := ioutil.WriteFile(nodeKeyFile, []byte(nodeKey), 0600); err != nil { 227 t.Fatalf("failed to write nodekey file: %v", err) 228 } 229 230 runGeth(t, "--datadir", datadir, "init", json).WaitExit() 231 232 return datadir 233 }