accountcmd_test.go 10.0 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
// Copyright 2016 The go-ethereum Authors
// This file is part of go-ethereum.
//
// go-ethereum is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// go-ethereum is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.

package main

import (
	"io/ioutil"
	"path/filepath"
F
Felix Lange 已提交
22
	"runtime"
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
	"strings"
	"testing"

	"github.com/cespare/cp"
)

// These tests are 'smoke tests' for the account related
// subcommands and flags.
//
// For most tests, the test files from package accounts
// are copied into a temporary keystore directory.

func tmpDatadirWithKeystore(t *testing.T) string {
	datadir := tmpdir(t)
	keystore := filepath.Join(datadir, "keystore")
38
	source := filepath.Join("..", "..", "accounts", "keystore", "testdata", "keystore")
39 40 41 42 43 44 45
	if err := cp.CopyAll(keystore, source); err != nil {
		t.Fatal(err)
	}
	return datadir
}

func TestAccountListEmpty(t *testing.T) {
46
	geth := runGeth(t, "account", "list")
47
	geth.ExpectExit()
48 49 50 51
}

func TestAccountList(t *testing.T) {
	datadir := tmpDatadirWithKeystore(t)
52
	geth := runGeth(t, "account", "list", "--datadir", datadir)
53
	defer geth.ExpectExit()
F
Felix Lange 已提交
54
	if runtime.GOOS == "windows" {
55
		geth.Expect(`
56 57 58
Account #0: {7ef5a6135f1fd6a02593eedc869c6d41d934aef8} keystore://{{.Datadir}}\keystore\UTC--2016-03-22T12-57-55.920751759Z--7ef5a6135f1fd6a02593eedc869c6d41d934aef8
Account #1: {f466859ead1932d743d622cb74fc058882e8648a} keystore://{{.Datadir}}\keystore\aaa
Account #2: {289d485d9771714cce91d3393d764e1311907acc} keystore://{{.Datadir}}\keystore\zzz
F
Felix Lange 已提交
59 60
`)
	} else {
61
		geth.Expect(`
62 63 64
Account #0: {7ef5a6135f1fd6a02593eedc869c6d41d934aef8} keystore://{{.Datadir}}/keystore/UTC--2016-03-22T12-57-55.920751759Z--7ef5a6135f1fd6a02593eedc869c6d41d934aef8
Account #1: {f466859ead1932d743d622cb74fc058882e8648a} keystore://{{.Datadir}}/keystore/aaa
Account #2: {289d485d9771714cce91d3393d764e1311907acc} keystore://{{.Datadir}}/keystore/zzz
65
`)
F
Felix Lange 已提交
66
	}
67 68 69
}

func TestAccountNew(t *testing.T) {
70
	geth := runGeth(t, "account", "new", "--lightkdf")
71 72
	defer geth.ExpectExit()
	geth.Expect(`
73 74 75 76 77
Your new account is locked with a password. Please give a password. Do not forget this password.
!! Unsupported terminal, password will be echoed.
Passphrase: {{.InputLine "foobar"}}
Repeat passphrase: {{.InputLine "foobar"}}
`)
78
	geth.ExpectRegexp(`Address: \{[0-9a-f]{40}\}\n`)
79 80 81
}

func TestAccountNewBadRepeat(t *testing.T) {
82
	geth := runGeth(t, "account", "new", "--lightkdf")
83 84
	defer geth.ExpectExit()
	geth.Expect(`
85 86 87 88 89 90 91 92 93 94
Your new account is locked with a password. Please give a password. Do not forget this password.
!! Unsupported terminal, password will be echoed.
Passphrase: {{.InputLine "something"}}
Repeat passphrase: {{.InputLine "something else"}}
Fatal: Passphrases do not match
`)
}

func TestAccountUpdate(t *testing.T) {
	datadir := tmpDatadirWithKeystore(t)
95
	geth := runGeth(t, "account", "update",
96
		"--datadir", datadir, "--lightkdf",
97
		"f466859ead1932d743d622cb74fc058882e8648a")
98 99
	defer geth.ExpectExit()
	geth.Expect(`
100 101 102 103 104 105 106 107 108 109
Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3
!! Unsupported terminal, password will be echoed.
Passphrase: {{.InputLine "foobar"}}
Please give a new password. Do not forget this password.
Passphrase: {{.InputLine "foobar2"}}
Repeat passphrase: {{.InputLine "foobar2"}}
`)
}

func TestWalletImport(t *testing.T) {
110
	geth := runGeth(t, "wallet", "import", "--lightkdf", "testdata/guswallet.json")
111 112
	defer geth.ExpectExit()
	geth.Expect(`
113 114 115 116 117 118 119 120 121 122 123 124
!! Unsupported terminal, password will be echoed.
Passphrase: {{.InputLine "foo"}}
Address: {d4584b5f6229b7be90727b0fc8c6b91bb427821f}
`)

	files, err := ioutil.ReadDir(filepath.Join(geth.Datadir, "keystore"))
	if len(files) != 1 {
		t.Errorf("expected one key file in keystore directory, found %d files (error: %v)", len(files), err)
	}
}

func TestWalletImportBadPassword(t *testing.T) {
125
	geth := runGeth(t, "wallet", "import", "--lightkdf", "testdata/guswallet.json")
126 127
	defer geth.ExpectExit()
	geth.Expect(`
128 129
!! Unsupported terminal, password will be echoed.
Passphrase: {{.InputLine "wrong"}}
F
Felix Lange 已提交
130
Fatal: could not decrypt key with given passphrase
131 132 133 134 135 136
`)
}

func TestUnlockFlag(t *testing.T) {
	datadir := tmpDatadirWithKeystore(t)
	geth := runGeth(t,
137
		"--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0",
138 139
		"--unlock", "f466859ead1932d743d622cb74fc058882e8648a",
		"js", "testdata/empty.js")
140
	geth.Expect(`
141 142 143 144
Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3
!! Unsupported terminal, password will be echoed.
Passphrase: {{.InputLine "foobar"}}
`)
145
	geth.ExpectExit()
146 147

	wantMessages := []string{
148
		"Unlocked account",
149
		"=0xf466859eAD1932D743d622CB74FC058882E8648A",
150 151
	}
	for _, m := range wantMessages {
152
		if !strings.Contains(geth.StderrText(), m) {
153 154 155 156 157 158 159 160
			t.Errorf("stderr text does not contain %q", m)
		}
	}
}

func TestUnlockFlagWrongPassword(t *testing.T) {
	datadir := tmpDatadirWithKeystore(t)
	geth := runGeth(t,
161
		"--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0",
162
		"--unlock", "f466859ead1932d743d622cb74fc058882e8648a")
163 164
	defer geth.ExpectExit()
	geth.Expect(`
165 166 167 168 169 170 171
Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3
!! Unsupported terminal, password will be echoed.
Passphrase: {{.InputLine "wrong1"}}
Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 2/3
Passphrase: {{.InputLine "wrong2"}}
Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 3/3
Passphrase: {{.InputLine "wrong3"}}
172
Fatal: Failed to unlock account f466859ead1932d743d622cb74fc058882e8648a (could not decrypt key with given passphrase)
173 174 175 176 177 178 179
`)
}

// https://github.com/ethereum/go-ethereum/issues/1785
func TestUnlockFlagMultiIndex(t *testing.T) {
	datadir := tmpDatadirWithKeystore(t)
	geth := runGeth(t,
180
		"--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0",
181 182
		"--unlock", "0,2",
		"js", "testdata/empty.js")
183
	geth.Expect(`
184 185 186 187 188 189
Unlocking account 0 | Attempt 1/3
!! Unsupported terminal, password will be echoed.
Passphrase: {{.InputLine "foobar"}}
Unlocking account 2 | Attempt 1/3
Passphrase: {{.InputLine "foobar"}}
`)
190
	geth.ExpectExit()
191 192

	wantMessages := []string{
193
		"Unlocked account",
194 195
		"=0x7EF5A6135f1FD6a02593eEdC869c6D41D934aef8",
		"=0x289d485D9771714CCe91D3393D764E1311907ACc",
196 197
	}
	for _, m := range wantMessages {
198
		if !strings.Contains(geth.StderrText(), m) {
199 200 201 202 203 204 205 206
			t.Errorf("stderr text does not contain %q", m)
		}
	}
}

func TestUnlockFlagPasswordFile(t *testing.T) {
	datadir := tmpDatadirWithKeystore(t)
	geth := runGeth(t,
207
		"--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0",
208 209
		"--password", "testdata/passwords.txt", "--unlock", "0,2",
		"js", "testdata/empty.js")
210
	geth.ExpectExit()
211 212

	wantMessages := []string{
213
		"Unlocked account",
214 215
		"=0x7EF5A6135f1FD6a02593eEdC869c6D41D934aef8",
		"=0x289d485D9771714CCe91D3393D764E1311907ACc",
216 217
	}
	for _, m := range wantMessages {
218
		if !strings.Contains(geth.StderrText(), m) {
219 220 221 222 223 224 225 226
			t.Errorf("stderr text does not contain %q", m)
		}
	}
}

func TestUnlockFlagPasswordFileWrongPassword(t *testing.T) {
	datadir := tmpDatadirWithKeystore(t)
	geth := runGeth(t,
227
		"--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0",
228
		"--password", "testdata/wrong-passwords.txt", "--unlock", "0,2")
229 230
	defer geth.ExpectExit()
	geth.Expect(`
231
Fatal: Failed to unlock account 0 (could not decrypt key with given passphrase)
232 233
`)
}
234 235

func TestUnlockFlagAmbiguous(t *testing.T) {
236
	store := filepath.Join("..", "..", "accounts", "keystore", "testdata", "dupes")
237
	geth := runGeth(t,
238
		"--keystore", store, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0",
239 240
		"--unlock", "f466859ead1932d743d622cb74fc058882e8648a",
		"js", "testdata/empty.js")
241
	defer geth.ExpectExit()
242 243

	// Helper for the expect template, returns absolute keystore path.
244
	geth.SetTemplateFunc("keypath", func(file string) string {
245 246 247
		abs, _ := filepath.Abs(filepath.Join(store, file))
		return abs
	})
248
	geth.Expect(`
249 250 251 252
Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3
!! Unsupported terminal, password will be echoed.
Passphrase: {{.InputLine "foobar"}}
Multiple key files exist for address f466859ead1932d743d622cb74fc058882e8648a:
253 254
   keystore://{{keypath "1"}}
   keystore://{{keypath "2"}}
255
Testing your passphrase against all of them...
256
Your passphrase unlocked keystore://{{keypath "1"}}
257
In order to avoid this warning, you need to remove the following duplicate key files:
258
   keystore://{{keypath "2"}}
259
`)
260
	geth.ExpectExit()
261 262

	wantMessages := []string{
263
		"Unlocked account",
264
		"=0xf466859eAD1932D743d622CB74FC058882E8648A",
265 266
	}
	for _, m := range wantMessages {
267
		if !strings.Contains(geth.StderrText(), m) {
268 269 270 271 272 273
			t.Errorf("stderr text does not contain %q", m)
		}
	}
}

func TestUnlockFlagAmbiguousWrongPassword(t *testing.T) {
274
	store := filepath.Join("..", "..", "accounts", "keystore", "testdata", "dupes")
275
	geth := runGeth(t,
276
		"--keystore", store, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0",
277
		"--unlock", "f466859ead1932d743d622cb74fc058882e8648a")
278
	defer geth.ExpectExit()
279 280

	// Helper for the expect template, returns absolute keystore path.
281
	geth.SetTemplateFunc("keypath", func(file string) string {
282 283 284
		abs, _ := filepath.Abs(filepath.Join(store, file))
		return abs
	})
285
	geth.Expect(`
286 287 288 289
Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3
!! Unsupported terminal, password will be echoed.
Passphrase: {{.InputLine "wrong"}}
Multiple key files exist for address f466859ead1932d743d622cb74fc058882e8648a:
290 291
   keystore://{{keypath "1"}}
   keystore://{{keypath "2"}}
292 293 294
Testing your passphrase against all of them...
Fatal: None of the listed files could be unlocked.
`)
295
	geth.ExpectExit()
296
}