github.com/ConsenSys/Quorum@v20.10.0+incompatible/cmd/geth/accountcmd_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  	"io/ioutil"
    21  	"path/filepath"
    22  	"runtime"
    23  	"strings"
    24  	"testing"
    25  
    26  	"github.com/cespare/cp"
    27  )
    28  
    29  // These tests are 'smoke tests' for the account related
    30  // subcommands and flags.
    31  //
    32  // For most tests, the test files from package accounts
    33  // are copied into a temporary keystore directory.
    34  
    35  func tmpDatadirWithKeystore(t *testing.T) string {
    36  	datadir := tmpdir(t)
    37  	keystore := filepath.Join(datadir, "keystore")
    38  	source := filepath.Join("..", "..", "accounts", "keystore", "testdata", "keystore")
    39  	if err := cp.CopyAll(keystore, source); err != nil {
    40  		t.Fatal(err)
    41  	}
    42  	// add the necessary files for geth to start with the raft consensus
    43  	geth := filepath.Join(datadir, "geth")
    44  	sourceNodeKey := filepath.Join("testdata", "geth")
    45  	if err := cp.CopyAll(geth, sourceNodeKey); err != nil {
    46  		t.Fatal(err)
    47  	}
    48  	return datadir
    49  }
    50  
    51  func runGethWithRaftConsensus(t *testing.T, args ...string) *testgeth {
    52  	argsWithRaft := append([]string{"--raft"}, args...)
    53  	return runGeth(t, argsWithRaft...)
    54  }
    55  
    56  func TestAccountListEmpty(t *testing.T) {
    57  	geth := runGeth(t, "account", "list")
    58  	geth.ExpectExit()
    59  }
    60  
    61  func TestAccountList(t *testing.T) {
    62  	datadir := tmpDatadirWithKeystore(t)
    63  	geth := runGeth(t, "account", "list", "--datadir", datadir)
    64  	defer geth.ExpectExit()
    65  	if runtime.GOOS == "windows" {
    66  		geth.Expect(`
    67  Account #0: {7ef5a6135f1fd6a02593eedc869c6d41d934aef8} keystore://{{.Datadir}}\keystore\UTC--2016-03-22T12-57-55.920751759Z--7ef5a6135f1fd6a02593eedc869c6d41d934aef8
    68  Account #1: {f466859ead1932d743d622cb74fc058882e8648a} keystore://{{.Datadir}}\keystore\aaa
    69  Account #2: {289d485d9771714cce91d3393d764e1311907acc} keystore://{{.Datadir}}\keystore\zzz
    70  `)
    71  	} else {
    72  		geth.Expect(`
    73  Account #0: {7ef5a6135f1fd6a02593eedc869c6d41d934aef8} keystore://{{.Datadir}}/keystore/UTC--2016-03-22T12-57-55.920751759Z--7ef5a6135f1fd6a02593eedc869c6d41d934aef8
    74  Account #1: {f466859ead1932d743d622cb74fc058882e8648a} keystore://{{.Datadir}}/keystore/aaa
    75  Account #2: {289d485d9771714cce91d3393d764e1311907acc} keystore://{{.Datadir}}/keystore/zzz
    76  `)
    77  	}
    78  }
    79  
    80  func TestAccountNew(t *testing.T) {
    81  	geth := runGeth(t, "account", "new", "--lightkdf")
    82  	defer geth.ExpectExit()
    83  	geth.Expect(`
    84  Your new account is locked with a password. Please give a password. Do not forget this password.
    85  !! Unsupported terminal, password will be echoed.
    86  Password: {{.InputLine "foobar"}}
    87  Repeat password: {{.InputLine "foobar"}}
    88  
    89  Your new key was generated
    90  `)
    91  	geth.ExpectRegexp(`
    92  Public address of the key:   0x[0-9a-fA-F]{40}
    93  Path of the secret key file: .*UTC--.+--[0-9a-f]{40}
    94  
    95  - You can share your public address with anyone. Others need it to interact with you.
    96  - You must NEVER share the secret key with anyone! The key controls access to your funds!
    97  - You must BACKUP your key file! Without the key, it's impossible to access account funds!
    98  - You must REMEMBER your password! Without the password, it's impossible to decrypt the key!
    99  `)
   100  }
   101  
   102  func TestAccountNewBadRepeat(t *testing.T) {
   103  	geth := runGeth(t, "account", "new", "--lightkdf")
   104  	defer geth.ExpectExit()
   105  	geth.Expect(`
   106  Your new account is locked with a password. Please give a password. Do not forget this password.
   107  !! Unsupported terminal, password will be echoed.
   108  Password: {{.InputLine "something"}}
   109  Repeat password: {{.InputLine "something else"}}
   110  Fatal: Passwords do not match
   111  `)
   112  }
   113  
   114  func TestAccountUpdate(t *testing.T) {
   115  	datadir := tmpDatadirWithKeystore(t)
   116  	geth := runGeth(t, "account", "update",
   117  		"--datadir", datadir, "--lightkdf",
   118  		"f466859ead1932d743d622cb74fc058882e8648a")
   119  	defer geth.ExpectExit()
   120  	geth.Expect(`
   121  Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3
   122  !! Unsupported terminal, password will be echoed.
   123  Password: {{.InputLine "foobar"}}
   124  Please give a new password. Do not forget this password.
   125  Password: {{.InputLine "foobar2"}}
   126  Repeat password: {{.InputLine "foobar2"}}
   127  `)
   128  }
   129  
   130  func TestWalletImport(t *testing.T) {
   131  	geth := runGeth(t, "wallet", "import", "--lightkdf", "testdata/guswallet.json")
   132  	defer geth.ExpectExit()
   133  	geth.Expect(`
   134  !! Unsupported terminal, password will be echoed.
   135  Password: {{.InputLine "foo"}}
   136  Address: {d4584b5f6229b7be90727b0fc8c6b91bb427821f}
   137  `)
   138  
   139  	files, err := ioutil.ReadDir(filepath.Join(geth.Datadir, "keystore"))
   140  	if len(files) != 1 {
   141  		t.Errorf("expected one key file in keystore directory, found %d files (error: %v)", len(files), err)
   142  	}
   143  }
   144  
   145  func TestWalletImportBadPassword(t *testing.T) {
   146  	geth := runGeth(t, "wallet", "import", "--lightkdf", "testdata/guswallet.json")
   147  	defer geth.ExpectExit()
   148  	geth.Expect(`
   149  !! Unsupported terminal, password will be echoed.
   150  Password: {{.InputLine "wrong"}}
   151  Fatal: could not decrypt key with given password
   152  `)
   153  }
   154  
   155  func TestUnlockFlag(t *testing.T) {
   156  	defer SetResetPrivateConfig("ignore")()
   157  	datadir := tmpDatadirWithKeystore(t)
   158  	geth := runGethWithRaftConsensus(t,
   159  		"--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0",
   160  		"--unlock", "f466859ead1932d743d622cb74fc058882e8648a",
   161  		"js", "testdata/empty.js")
   162  	geth.Expect(`
   163  Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3
   164  !! Unsupported terminal, password will be echoed.
   165  Password: {{.InputLine "foobar"}}
   166  `)
   167  	geth.ExpectExit()
   168  
   169  	wantMessages := []string{
   170  		"Unlocked account",
   171  		"=0xf466859eAD1932D743d622CB74FC058882E8648A",
   172  	}
   173  	for _, m := range wantMessages {
   174  		if !strings.Contains(geth.StderrText(), m) {
   175  			t.Errorf("stderr text does not contain %q", m)
   176  		}
   177  	}
   178  }
   179  
   180  func TestGethDoesntStartWithoutPrivateTransactionManagerVariableSet(t *testing.T) {
   181  	defer SetResetPrivateConfig("")()
   182  
   183  	datadir := tmpDatadirWithKeystore(t)
   184  	geth := runGeth(t,
   185  		"--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0",
   186  		"--unlock", "f466859ead1932d743d622cb74fc058882e8648a")
   187  
   188  	expectedText := "the PRIVATE_CONFIG environment variable must be specified for Quorum"
   189  
   190  	// changed to expect regexp because fatalf writes the message to stdout/stderr
   191  	geth.ExpectRegexp(expectedText)
   192  
   193  	result := strings.TrimSpace(geth.StderrText())
   194  	if !strings.Contains(result, expectedText) {
   195  		geth.Fatalf("bad stderr text. want '%s', got '%s'", expectedText, result)
   196  	}
   197  }
   198  
   199  func TestGethDoesntStartWithoutConfiguredConsensus(t *testing.T) {
   200  	defer SetResetPrivateConfig("ignore")()
   201  
   202  	datadir := tmpDatadirWithKeystore(t)
   203  	geth := runGeth(t,
   204  		"--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0")
   205  
   206  	expectedText := "Consensus not specified. Exiting!!"
   207  
   208  	// changed to expect regexp because fatalf writes the message to stdout/stderr
   209  	geth.ExpectRegexp(expectedText)
   210  }
   211  
   212  func TestGethStartsWhenConsensusAndPrivateConfigAreConfigured(t *testing.T) {
   213  	defer SetResetPrivateConfig("ignore")()
   214  
   215  	datadir := tmpDatadirWithKeystore(t)
   216  	geth := runGeth(t,
   217  		"--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0", "--raft")
   218  
   219  	geth.ExpectExit()
   220  }
   221  
   222  func TestUnlockFlagWrongPassword(t *testing.T) {
   223  	defer SetResetPrivateConfig("ignore")()
   224  	datadir := tmpDatadirWithKeystore(t)
   225  	geth := runGeth(t,
   226  		"--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0",
   227  		"--unlock", "f466859ead1932d743d622cb74fc058882e8648a")
   228  	defer geth.ExpectExit()
   229  	geth.Expect(`
   230  Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3
   231  !! Unsupported terminal, password will be echoed.
   232  Password: {{.InputLine "wrong1"}}
   233  Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 2/3
   234  Password: {{.InputLine "wrong2"}}
   235  Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 3/3
   236  Password: {{.InputLine "wrong3"}}
   237  Fatal: Failed to unlock account f466859ead1932d743d622cb74fc058882e8648a (could not decrypt key with given password)
   238  `)
   239  }
   240  
   241  // https://github.com/ethereum/go-ethereum/issues/1785
   242  func TestUnlockFlagMultiIndex(t *testing.T) {
   243  	defer SetResetPrivateConfig("ignore")()
   244  	datadir := tmpDatadirWithKeystore(t)
   245  	geth := runGethWithRaftConsensus(t,
   246  		"--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0",
   247  		"--unlock", "0,2",
   248  		"js", "testdata/empty.js")
   249  	geth.Expect(`
   250  Unlocking account 0 | Attempt 1/3
   251  !! Unsupported terminal, password will be echoed.
   252  Password: {{.InputLine "foobar"}}
   253  Unlocking account 2 | Attempt 1/3
   254  Password: {{.InputLine "foobar"}}
   255  `)
   256  	geth.ExpectExit()
   257  
   258  	wantMessages := []string{
   259  		"Unlocked account",
   260  		"=0x7EF5A6135f1FD6a02593eEdC869c6D41D934aef8",
   261  		"=0x289d485D9771714CCe91D3393D764E1311907ACc",
   262  	}
   263  	for _, m := range wantMessages {
   264  		if !strings.Contains(geth.StderrText(), m) {
   265  			t.Errorf("stderr text does not contain %q", m)
   266  		}
   267  	}
   268  }
   269  
   270  func TestUnlockFlagPasswordFile(t *testing.T) {
   271  	defer SetResetPrivateConfig("ignore")()
   272  	datadir := tmpDatadirWithKeystore(t)
   273  	geth := runGethWithRaftConsensus(t,
   274  		"--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0",
   275  		"--password", "testdata/passwords.txt", "--unlock", "0,2",
   276  		"js", "testdata/empty.js")
   277  	geth.ExpectExit()
   278  
   279  	wantMessages := []string{
   280  		"Unlocked account",
   281  		"=0x7EF5A6135f1FD6a02593eEdC869c6D41D934aef8",
   282  		"=0x289d485D9771714CCe91D3393D764E1311907ACc",
   283  	}
   284  	for _, m := range wantMessages {
   285  		if !strings.Contains(geth.StderrText(), m) {
   286  			t.Errorf("stderr text does not contain %q", m)
   287  		}
   288  	}
   289  }
   290  
   291  func TestUnlockFlagPasswordFileWrongPassword(t *testing.T) {
   292  	defer SetResetPrivateConfig("ignore")()
   293  	datadir := tmpDatadirWithKeystore(t)
   294  	geth := runGeth(t,
   295  		"--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0",
   296  		"--password", "testdata/wrong-passwords.txt", "--unlock", "0,2")
   297  	defer geth.ExpectExit()
   298  	geth.Expect(`
   299  Fatal: Failed to unlock account 0 (could not decrypt key with given password)
   300  `)
   301  }
   302  
   303  func TestUnlockFlagAmbiguous(t *testing.T) {
   304  	defer SetResetPrivateConfig("ignore")()
   305  	datadir := tmpDatadirWithKeystore(t)
   306  	store := filepath.Join("..", "..", "accounts", "keystore", "testdata", "dupes")
   307  	geth := runGethWithRaftConsensus(t,
   308  		"--datadir", datadir, "--keystore", store, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0",
   309  		"--unlock", "f466859ead1932d743d622cb74fc058882e8648a",
   310  		"js", "testdata/empty.js")
   311  	defer geth.ExpectExit()
   312  
   313  	// Helper for the expect template, returns absolute keystore path.
   314  	geth.SetTemplateFunc("keypath", func(file string) string {
   315  		abs, _ := filepath.Abs(filepath.Join(store, file))
   316  		return abs
   317  	})
   318  	geth.Expect(`
   319  Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3
   320  !! Unsupported terminal, password will be echoed.
   321  Password: {{.InputLine "foobar"}}
   322  Multiple key files exist for address f466859ead1932d743d622cb74fc058882e8648a:
   323     keystore://{{keypath "1"}}
   324     keystore://{{keypath "2"}}
   325  Testing your password against all of them...
   326  Your password unlocked keystore://{{keypath "1"}}
   327  In order to avoid this warning, you need to remove the following duplicate key files:
   328     keystore://{{keypath "2"}}
   329  `)
   330  	geth.ExpectExit()
   331  
   332  	wantMessages := []string{
   333  		"Unlocked account",
   334  		"=0xf466859eAD1932D743d622CB74FC058882E8648A",
   335  	}
   336  	for _, m := range wantMessages {
   337  		if !strings.Contains(geth.StderrText(), m) {
   338  			t.Errorf("stderr text does not contain %q", m)
   339  		}
   340  	}
   341  }
   342  
   343  func TestUnlockFlagAmbiguousWrongPassword(t *testing.T) {
   344  	defer SetResetPrivateConfig("ignore")()
   345  	store := filepath.Join("..", "..", "accounts", "keystore", "testdata", "dupes")
   346  	geth := runGeth(t,
   347  		"--keystore", store, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0",
   348  		"--unlock", "f466859ead1932d743d622cb74fc058882e8648a")
   349  	defer geth.ExpectExit()
   350  
   351  	// Helper for the expect template, returns absolute keystore path.
   352  	geth.SetTemplateFunc("keypath", func(file string) string {
   353  		abs, _ := filepath.Abs(filepath.Join(store, file))
   354  		return abs
   355  	})
   356  	geth.Expect(`
   357  Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3
   358  !! Unsupported terminal, password will be echoed.
   359  Password: {{.InputLine "wrong"}}
   360  Multiple key files exist for address f466859ead1932d743d622cb74fc058882e8648a:
   361     keystore://{{keypath "1"}}
   362     keystore://{{keypath "2"}}
   363  Testing your password against all of them...
   364  Fatal: None of the listed files could be unlocked.
   365  `)
   366  	geth.ExpectExit()
   367  }