diff --git a/cli/app/app.go b/cli/app/app.go new file mode 100644 index 000000000..c62b5e42d --- /dev/null +++ b/cli/app/app.go @@ -0,0 +1,41 @@ +package app + +import ( + "fmt" + "os" + "runtime" + + "github.com/nspcc-dev/neo-go/cli/query" + "github.com/nspcc-dev/neo-go/cli/server" + "github.com/nspcc-dev/neo-go/cli/smartcontract" + "github.com/nspcc-dev/neo-go/cli/util" + "github.com/nspcc-dev/neo-go/cli/vm" + "github.com/nspcc-dev/neo-go/cli/wallet" + "github.com/nspcc-dev/neo-go/pkg/config" + "github.com/urfave/cli" +) + +func versionPrinter(c *cli.Context) { + _, _ = fmt.Fprintf(c.App.Writer, "NeoGo\nVersion: %s\nGoVersion: %s\n", + config.Version, + runtime.Version(), + ) +} + +// New creates a NeoGo instance of [cli.App] with all commands included. +func New() *cli.App { + cli.VersionPrinter = versionPrinter + ctl := cli.NewApp() + ctl.Name = "neo-go" + ctl.Version = config.Version + ctl.Usage = "Official Go client for Neo" + ctl.ErrWriter = os.Stdout + + ctl.Commands = append(ctl.Commands, server.NewCommands()...) + ctl.Commands = append(ctl.Commands, smartcontract.NewCommands()...) + ctl.Commands = append(ctl.Commands, wallet.NewCommands()...) + ctl.Commands = append(ctl.Commands, vm.NewCommands()...) + ctl.Commands = append(ctl.Commands, util.NewCommands()...) + ctl.Commands = append(ctl.Commands, query.NewCommands()...) + return ctl +} diff --git a/cli/app/main_test.go b/cli/app/main_test.go new file mode 100644 index 000000000..b4452921b --- /dev/null +++ b/cli/app/main_test.go @@ -0,0 +1,18 @@ +package app_test + +import ( + "testing" + + "github.com/nspcc-dev/neo-go/internal/testcli" + "github.com/nspcc-dev/neo-go/pkg/config" +) + +func TestCLIVersion(t *testing.T) { + config.Version = "0.90.0-test" // Zero-length version string disables '--version' completely. + e := testcli.NewExecutor(t, false) + e.Run(t, "neo-go", "--version") + e.CheckNextLine(t, "^NeoGo") + e.CheckNextLine(t, "^Version:") + e.CheckNextLine(t, "^GoVersion:") + e.CheckEOF(t) +} diff --git a/cli/main.go b/cli/main.go index f854c43cc..7976815da 100644 --- a/cli/main.go +++ b/cli/main.go @@ -1,48 +1,15 @@ package main import ( - "fmt" "os" - "runtime" - "github.com/nspcc-dev/neo-go/cli/query" - "github.com/nspcc-dev/neo-go/cli/server" - "github.com/nspcc-dev/neo-go/cli/smartcontract" - "github.com/nspcc-dev/neo-go/cli/util" - "github.com/nspcc-dev/neo-go/cli/vm" - "github.com/nspcc-dev/neo-go/cli/wallet" - "github.com/nspcc-dev/neo-go/pkg/config" - "github.com/urfave/cli" + "github.com/nspcc-dev/neo-go/cli/app" ) func main() { - ctl := newApp() + ctl := app.New() if err := ctl.Run(os.Args); err != nil { panic(err) } } - -func versionPrinter(c *cli.Context) { - _, _ = fmt.Fprintf(c.App.Writer, "NeoGo\nVersion: %s\nGoVersion: %s\n", - config.Version, - runtime.Version(), - ) -} - -func newApp() *cli.App { - cli.VersionPrinter = versionPrinter - ctl := cli.NewApp() - ctl.Name = "neo-go" - ctl.Version = config.Version - ctl.Usage = "Official Go client for Neo" - ctl.ErrWriter = os.Stdout - - ctl.Commands = append(ctl.Commands, server.NewCommands()...) - ctl.Commands = append(ctl.Commands, smartcontract.NewCommands()...) - ctl.Commands = append(ctl.Commands, wallet.NewCommands()...) - ctl.Commands = append(ctl.Commands, vm.NewCommands()...) - ctl.Commands = append(ctl.Commands, util.NewCommands()...) - ctl.Commands = append(ctl.Commands, query.NewCommands()...) - return ctl -} diff --git a/cli/main_test.go b/cli/main_test.go deleted file mode 100644 index 427dc103f..000000000 --- a/cli/main_test.go +++ /dev/null @@ -1,14 +0,0 @@ -package main - -import ( - "testing" -) - -func TestCLIVersion(t *testing.T) { - e := newExecutor(t, false) - e.Run(t, "neo-go", "--version") - e.checkNextLine(t, "^NeoGo") - e.checkNextLine(t, "^Version:") - e.checkNextLine(t, "^GoVersion:") - e.checkEOF(t) -} diff --git a/cli/nep11_test.go b/cli/nep_test/nep11_test.go similarity index 79% rename from cli/nep11_test.go rename to cli/nep_test/nep11_test.go index a652ec094..adcc22e29 100644 --- a/cli/nep11_test.go +++ b/cli/nep_test/nep11_test.go @@ -1,4 +1,4 @@ -package main +package nep_test import ( "bytes" @@ -13,6 +13,7 @@ import ( "strconv" "testing" + "github.com/nspcc-dev/neo-go/internal/testcli" "github.com/nspcc-dev/neo-go/pkg/core/native/nativenames" "github.com/nspcc-dev/neo-go/pkg/core/state" "github.com/nspcc-dev/neo-go/pkg/encoding/address" @@ -26,12 +27,12 @@ import ( const ( // nftOwnerAddr is the owner of NFT-ND HASHY token (../examples/nft-nd/nft.go). nftOwnerAddr = "NbrUYaZgyhSkNoRo9ugRyEMdUZxrhkNaWB" - nftOwnerWallet = "../examples/my_wallet.json" + nftOwnerWallet = "../../examples/my_wallet.json" nftOwnerPass = "qwerty" ) func TestNEP11Import(t *testing.T) { - e := newExecutor(t, true) + e := testcli.NewExecutor(t, true) tmpDir := t.TempDir() walletPath := filepath.Join(tmpDir, "walletForImport.json") @@ -68,12 +69,12 @@ func TestNEP11Import(t *testing.T) { e.RunWithError(t, append(args, "--token", neoContractHash.StringLE())...) checkInfo := func(t *testing.T, h util.Uint160, name string, symbol string, decimals int) { - e.checkNextLine(t, "^Name:\\s*"+name) - e.checkNextLine(t, "^Symbol:\\s*"+symbol) - e.checkNextLine(t, "^Hash:\\s*"+h.StringLE()) - e.checkNextLine(t, "^Decimals:\\s*"+strconv.Itoa(decimals)) - e.checkNextLine(t, "^Address:\\s*"+address.Uint160ToString(h)) - e.checkNextLine(t, "^Standard:\\s*"+string(manifest.NEP11StandardName)) + e.CheckNextLine(t, "^Name:\\s*"+name) + e.CheckNextLine(t, "^Symbol:\\s*"+symbol) + e.CheckNextLine(t, "^Hash:\\s*"+h.StringLE()) + e.CheckNextLine(t, "^Decimals:\\s*"+strconv.Itoa(decimals)) + e.CheckNextLine(t, "^Address:\\s*"+address.Uint160ToString(h)) + e.CheckNextLine(t, "^Standard:\\s*"+string(manifest.NEP11StandardName)) } t.Run("Info", func(t *testing.T) { t.Run("excessive parameters", func(t *testing.T) { @@ -89,7 +90,7 @@ func TestNEP11Import(t *testing.T) { e.Run(t, "neo-go", "wallet", "nep11", "info", "--wallet", walletPath) checkInfo(t, nnsContractHash, "NameService", "NNS", 0) - e.checkNextLine(t, "") + e.CheckNextLine(t, "") checkInfo(t, nfsContractHash, "NeoFS Object NFT", "NFSO", 2) }) }) @@ -109,7 +110,7 @@ func TestNEP11Import(t *testing.T) { } func TestNEP11_ND_OwnerOf_BalanceOf_Transfer(t *testing.T) { - e := newExecutor(t, true) + e := testcli.NewExecutor(t, true) tmpDir := t.TempDir() // copy wallet to temp dir in order not to overwrite the original file @@ -123,13 +124,13 @@ func TestNEP11_ND_OwnerOf_BalanceOf_Transfer(t *testing.T) { e.In.WriteString("one\r") e.Run(t, "neo-go", "wallet", "nep17", "transfer", "--rpc-endpoint", "http://"+e.RPC.Addr, - "--wallet", validatorWallet, + "--wallet", testcli.ValidatorWallet, "--to", nftOwnerAddr, "--token", "GAS", "--amount", "10000", "--force", - "--from", validatorAddr) - e.checkTxPersisted(t) + "--from", testcli.ValidatorAddr) + e.CheckTxPersisted(t) // deploy NFT HASHY contract h := deployNFTContract(t, e) @@ -145,7 +146,7 @@ func TestNEP11_ND_OwnerOf_BalanceOf_Transfer(t *testing.T) { "--amount", "10", "--force", "--from", nftOwnerAddr) - txMint, _ := e.checkTxPersisted(t) + txMint, _ := e.CheckTxPersisted(t) // get NFT ID from AER aer, err := e.Chain.GetAppExecResults(txMint.Hash(), trigger.Application) @@ -169,8 +170,8 @@ func TestNEP11_ND_OwnerOf_BalanceOf_Transfer(t *testing.T) { "--wallet", wall, "--address", nftOwnerAddr} checkBalanceResult := func(t *testing.T, acc string, ids ...[]byte) { - e.checkNextLine(t, "^\\s*Account\\s+"+acc) - e.checkNextLine(t, "^\\s*HASHY:\\s+HASHY NFT \\("+h.StringLE()+"\\)") + e.CheckNextLine(t, "^\\s*Account\\s+"+acc) + e.CheckNextLine(t, "^\\s*HASHY:\\s+HASHY NFT \\("+h.StringLE()+"\\)") // Hashes can be ordered in any way, so make a regexp for them. var tokstring = "(" @@ -183,11 +184,11 @@ func TestNEP11_ND_OwnerOf_BalanceOf_Transfer(t *testing.T) { tokstring += ")" for range ids { - e.checkNextLine(t, "^\\s*Token: "+tokstring+"\\s*$") - e.checkNextLine(t, "^\\s*Amount: 1\\s*$") - e.checkNextLine(t, "^\\s*Updated: [0-9]+\\s*$") + e.CheckNextLine(t, "^\\s*Token: "+tokstring+"\\s*$") + e.CheckNextLine(t, "^\\s*Amount: 1\\s*$") + e.CheckNextLine(t, "^\\s*Updated: [0-9]+\\s*$") } - e.checkEOF(t) + e.CheckEOF(t) } // balance check: by symbol, token is not imported e.Run(t, append(cmdCheckBalance, "--token", "HASHY")...) @@ -233,7 +234,7 @@ func TestNEP11_ND_OwnerOf_BalanceOf_Transfer(t *testing.T) { // ownerOf: good e.Run(t, cmdOwnerOf...) - e.checkNextLine(t, nftOwnerAddr) + e.CheckNextLine(t, nftOwnerAddr) // tokensOf: missing contract hash cmdTokensOf := []string{"neo-go", "wallet", "nep11", "tokensOf", @@ -248,7 +249,7 @@ func TestNEP11_ND_OwnerOf_BalanceOf_Transfer(t *testing.T) { // tokensOf: good e.Run(t, cmdTokensOf...) - require.Equal(t, hex.EncodeToString(tokenID), e.getNextLine(t)) + require.Equal(t, hex.EncodeToString(tokenID), e.GetNextLine(t)) // properties: no contract cmdProperties := []string{ @@ -264,7 +265,7 @@ func TestNEP11_ND_OwnerOf_BalanceOf_Transfer(t *testing.T) { // properties: ok e.Run(t, cmdProperties...) - require.Equal(t, fmt.Sprintf(`{"name":"HASHY %s"}`, base64.StdEncoding.EncodeToString(tokenID)), e.getNextLine(t)) + require.Equal(t, fmt.Sprintf(`{"name":"HASHY %s"}`, base64.StdEncoding.EncodeToString(tokenID)), e.GetNextLine(t)) // tokensOf: good, several tokens tokenID1 := mint(t) @@ -274,8 +275,8 @@ func TestNEP11_ND_OwnerOf_BalanceOf_Transfer(t *testing.T) { fst, snd = snd, fst } - require.Equal(t, hex.EncodeToString(fst), e.getNextLine(t)) - require.Equal(t, hex.EncodeToString(snd), e.getNextLine(t)) + require.Equal(t, hex.EncodeToString(fst), e.GetNextLine(t)) + require.Equal(t, hex.EncodeToString(snd), e.GetNextLine(t)) // tokens: missing contract hash cmdTokens := []string{"neo-go", "wallet", "nep11", "tokens", @@ -288,8 +289,8 @@ func TestNEP11_ND_OwnerOf_BalanceOf_Transfer(t *testing.T) { e.RunWithError(t, append(cmdTokens, "additional")...) // tokens: good, several tokens e.Run(t, cmdTokens...) - require.Equal(t, hex.EncodeToString(fst), e.getNextLine(t)) - require.Equal(t, hex.EncodeToString(snd), e.getNextLine(t)) + require.Equal(t, hex.EncodeToString(fst), e.GetNextLine(t)) + require.Equal(t, hex.EncodeToString(snd), e.GetNextLine(t)) // balance check: several tokens, ok e.Run(t, append(cmdCheckBalance, "--token", h.StringLE())...) @@ -299,7 +300,7 @@ func TestNEP11_ND_OwnerOf_BalanceOf_Transfer(t *testing.T) { "neo-go", "wallet", "nep11", "transfer", "--rpc-endpoint", "http://" + e.RPC.Addr, "--wallet", wall, - "--to", validatorAddr, + "--to", testcli.ValidatorAddr, "--from", nftOwnerAddr, "--force", } @@ -317,7 +318,7 @@ func TestNEP11_ND_OwnerOf_BalanceOf_Transfer(t *testing.T) { // transfer: good e.In.WriteString(nftOwnerPass + "\r") e.Run(t, append(cmdTransfer, "--id", hex.EncodeToString(tokenID))...) - e.checkTxPersisted(t) + e.CheckTxPersisted(t) // check balance after transfer e.Run(t, append(cmdCheckBalance, "--token", h.StringLE())...) @@ -338,7 +339,7 @@ func TestNEP11_ND_OwnerOf_BalanceOf_Transfer(t *testing.T) { } e.In.WriteString(nftOwnerPass + "\r") e.Run(t, cmdTransfer...) - tx, _ := e.checkTxPersisted(t) + tx, _ := e.CheckTxPersisted(t) // check OnNEP11Payment event aer, err := e.Chain.GetAppExecResults(tx.Hash(), trigger.Application) require.NoError(t, err) @@ -363,28 +364,28 @@ func TestNEP11_ND_OwnerOf_BalanceOf_Transfer(t *testing.T) { // historic calls still remember the good old days. cmdOwnerOf = append(cmdOwnerOf, "--historic", hashBeforeTransfer.StringLE()) e.Run(t, cmdOwnerOf...) - e.checkNextLine(t, nftOwnerAddr) + e.CheckNextLine(t, nftOwnerAddr) cmdTokensOf = append(cmdTokensOf, "--historic", hashBeforeTransfer.StringLE()) e.Run(t, cmdTokensOf...) - require.Equal(t, hex.EncodeToString(tokenID), e.getNextLine(t)) + require.Equal(t, hex.EncodeToString(tokenID), e.GetNextLine(t)) cmdTokens = append(cmdTokens, "--historic", hashBeforeTransfer.StringLE()) e.Run(t, cmdTokens...) - require.Equal(t, hex.EncodeToString(tokenID), e.getNextLine(t)) + require.Equal(t, hex.EncodeToString(tokenID), e.GetNextLine(t)) // this one is not affected by transfer, but anyway cmdProperties = append(cmdProperties, "--historic", hashBeforeTransfer.StringLE()) e.Run(t, cmdProperties...) - require.Equal(t, fmt.Sprintf(`{"name":"HASHY %s"}`, base64.StdEncoding.EncodeToString(tokenID)), e.getNextLine(t)) + require.Equal(t, fmt.Sprintf(`{"name":"HASHY %s"}`, base64.StdEncoding.EncodeToString(tokenID)), e.GetNextLine(t)) } func TestNEP11_D_OwnerOf_BalanceOf_Transfer(t *testing.T) { - e := newExecutor(t, true) + e := testcli.NewExecutor(t, true) tmpDir := t.TempDir() // copy wallet to temp dir in order not to overwrite the original file - bytesRead, err := os.ReadFile(validatorWallet) + bytesRead, err := os.ReadFile(testcli.ValidatorWallet) require.NoError(t, err) wall := filepath.Join(tmpDir, "my_wallet.json") err = os.WriteFile(wall, bytesRead, 0755) @@ -395,7 +396,7 @@ func TestNEP11_D_OwnerOf_BalanceOf_Transfer(t *testing.T) { mint := func(t *testing.T, containerID, objectID util.Uint256) []byte { // mint 1.00 NFSO token by transferring 10 GAS to NFSO contract - e.In.WriteString(validatorPass + "\r") + e.In.WriteString(testcli.ValidatorPass + "\r") e.Run(t, "neo-go", "wallet", "nep17", "transfer", "--rpc-endpoint", "http://"+e.RPC.Addr, "--wallet", wall, @@ -403,10 +404,10 @@ func TestNEP11_D_OwnerOf_BalanceOf_Transfer(t *testing.T) { "--token", "GAS", "--amount", "10", "--force", - "--from", validatorAddr, + "--from", testcli.ValidatorAddr, "--", "[", "hash256:"+containerID.StringLE(), "hash256:"+objectID.StringLE(), "]", ) - txMint, _ := e.checkTxPersisted(t) + txMint, _ := e.CheckTxPersisted(t) // get NFT ID from AER aer, err := e.Chain.GetAppExecResults(txMint.Hash(), trigger.Application) @@ -434,12 +435,12 @@ func TestNEP11_D_OwnerOf_BalanceOf_Transfer(t *testing.T) { "--rpc-endpoint", "http://"+e.RPC.Addr, "--token", h.StringLE(), "--id", hex.EncodeToString(token1ID)) - jProps := e.getNextLine(t) + jProps := e.GetNextLine(t) props := make(map[string]string) require.NoError(t, json.Unmarshal([]byte(jProps), &props)) require.Equal(t, base64.StdEncoding.EncodeToString(container1ID.BytesBE()), props["containerID"]) require.Equal(t, base64.StdEncoding.EncodeToString(object1ID.BytesBE()), props["objectID"]) - e.checkEOF(t) + e.CheckEOF(t) type idAmount struct { id string @@ -450,17 +451,17 @@ func TestNEP11_D_OwnerOf_BalanceOf_Transfer(t *testing.T) { cmdCheckBalance := []string{"neo-go", "wallet", "nep11", "balance", "--rpc-endpoint", "http://" + e.RPC.Addr, "--wallet", wall, - "--address", validatorAddr} + "--address", testcli.ValidatorAddr} checkBalanceResult := func(t *testing.T, acc string, objs ...idAmount) { - e.checkNextLine(t, "^\\s*Account\\s+"+acc) - e.checkNextLine(t, "^\\s*NFSO:\\s+NeoFS Object NFT \\("+h.StringLE()+"\\)") + e.CheckNextLine(t, "^\\s*Account\\s+"+acc) + e.CheckNextLine(t, "^\\s*NFSO:\\s+NeoFS Object NFT \\("+h.StringLE()+"\\)") for _, o := range objs { - e.checkNextLine(t, "^\\s*Token: "+o.id+"\\s*$") - e.checkNextLine(t, "^\\s*Amount: "+o.amount+"\\s*$") - e.checkNextLine(t, "^\\s*Updated: [0-9]+\\s*$") + e.CheckNextLine(t, "^\\s*Token: "+o.id+"\\s*$") + e.CheckNextLine(t, "^\\s*Amount: "+o.amount+"\\s*$") + e.CheckNextLine(t, "^\\s*Updated: [0-9]+\\s*$") } - e.checkEOF(t) + e.CheckEOF(t) } tokz := []idAmount{ {hex.EncodeToString(token1ID), "1"}, @@ -468,15 +469,15 @@ func TestNEP11_D_OwnerOf_BalanceOf_Transfer(t *testing.T) { } // balance check: by symbol, token is not imported e.Run(t, append(cmdCheckBalance, "--token", "NFSO")...) - checkBalanceResult(t, validatorAddr, tokz...) + checkBalanceResult(t, testcli.ValidatorAddr, tokz...) // overall NFSO balance check: by hash, ok e.Run(t, append(cmdCheckBalance, "--token", h.StringLE())...) - checkBalanceResult(t, validatorAddr, tokz...) + checkBalanceResult(t, testcli.ValidatorAddr, tokz...) // particular NFSO balance check: by hash, ok e.Run(t, append(cmdCheckBalance, "--token", h.StringLE(), "--id", hex.EncodeToString(token2ID))...) - checkBalanceResult(t, validatorAddr, tokz[1]) + checkBalanceResult(t, testcli.ValidatorAddr, tokz[1]) // import token e.Run(t, "neo-go", "wallet", "nep11", "import", @@ -486,11 +487,11 @@ func TestNEP11_D_OwnerOf_BalanceOf_Transfer(t *testing.T) { // overall balance check: by symbol, ok e.Run(t, append(cmdCheckBalance, "--token", "NFSO")...) - checkBalanceResult(t, validatorAddr, tokz...) + checkBalanceResult(t, testcli.ValidatorAddr, tokz...) // particular balance check: by symbol, ok e.Run(t, append(cmdCheckBalance, "--token", "NFSO", "--id", hex.EncodeToString(token1ID))...) - checkBalanceResult(t, validatorAddr, tokz[0]) + checkBalanceResult(t, testcli.ValidatorAddr, tokz[0]) // remove token from wallet e.In.WriteString("y\r") @@ -510,7 +511,7 @@ func TestNEP11_D_OwnerOf_BalanceOf_Transfer(t *testing.T) { // ownerOfD: good e.Run(t, cmdOwnerOf...) - e.checkNextLine(t, validatorAddr) + e.CheckNextLine(t, testcli.ValidatorAddr) // tokensOf: missing contract hash cmdTokensOf := []string{"neo-go", "wallet", "nep11", "tokensOf", @@ -521,13 +522,13 @@ func TestNEP11_D_OwnerOf_BalanceOf_Transfer(t *testing.T) { // tokensOf: missing owner address e.RunWithError(t, cmdTokensOf...) - cmdTokensOf = append(cmdTokensOf, "--address", validatorAddr) + cmdTokensOf = append(cmdTokensOf, "--address", testcli.ValidatorAddr) // tokensOf: good e.Run(t, cmdTokensOf...) - require.Equal(t, hex.EncodeToString(token1ID), e.getNextLine(t)) - require.Equal(t, hex.EncodeToString(token2ID), e.getNextLine(t)) - e.checkEOF(t) + require.Equal(t, hex.EncodeToString(token1ID), e.GetNextLine(t)) + require.Equal(t, hex.EncodeToString(token2ID), e.GetNextLine(t)) + e.CheckEOF(t) // properties: no contract cmdProperties := []string{ @@ -546,12 +547,12 @@ func TestNEP11_D_OwnerOf_BalanceOf_Transfer(t *testing.T) { // properties: ok e.Run(t, cmdProperties...) - jProps = e.getNextLine(t) + jProps = e.GetNextLine(t) props = make(map[string]string) require.NoError(t, json.Unmarshal([]byte(jProps), &props)) require.Equal(t, base64.StdEncoding.EncodeToString(container2ID.BytesBE()), props["containerID"]) require.Equal(t, base64.StdEncoding.EncodeToString(object2ID.BytesBE()), props["objectID"]) - e.checkEOF(t) + e.CheckEOF(t) // tokensOf: good, several tokens e.Run(t, cmdTokensOf...) @@ -560,8 +561,8 @@ func TestNEP11_D_OwnerOf_BalanceOf_Transfer(t *testing.T) { fst, snd = snd, fst } - require.Equal(t, hex.EncodeToString(fst), e.getNextLine(t)) - require.Equal(t, hex.EncodeToString(snd), e.getNextLine(t)) + require.Equal(t, hex.EncodeToString(fst), e.GetNextLine(t)) + require.Equal(t, hex.EncodeToString(snd), e.GetNextLine(t)) // tokens: missing contract hash cmdTokens := []string{"neo-go", "wallet", "nep11", "tokens", @@ -572,40 +573,40 @@ func TestNEP11_D_OwnerOf_BalanceOf_Transfer(t *testing.T) { // tokens: good, several tokens e.Run(t, cmdTokens...) - require.Equal(t, hex.EncodeToString(fst), e.getNextLine(t)) - require.Equal(t, hex.EncodeToString(snd), e.getNextLine(t)) + require.Equal(t, hex.EncodeToString(fst), e.GetNextLine(t)) + require.Equal(t, hex.EncodeToString(snd), e.GetNextLine(t)) // balance check: several tokens, ok e.Run(t, append(cmdCheckBalance, "--token", h.StringLE())...) - checkBalanceResult(t, validatorAddr, tokz...) + checkBalanceResult(t, testcli.ValidatorAddr, tokz...) cmdTransfer := []string{ "neo-go", "wallet", "nep11", "transfer", "--rpc-endpoint", "http://" + e.RPC.Addr, "--wallet", wall, "--to", nftOwnerAddr, - "--from", validatorAddr, + "--from", testcli.ValidatorAddr, "--force", } // transfer: unimported token with symbol id specified - e.In.WriteString(validatorPass + "\r") + e.In.WriteString(testcli.ValidatorPass + "\r") e.RunWithError(t, append(cmdTransfer, "--token", "NFSO")...) cmdTransfer = append(cmdTransfer, "--token", h.StringLE()) // transfer: no id specified - e.In.WriteString(validatorPass + "\r") + e.In.WriteString(testcli.ValidatorPass + "\r") e.RunWithError(t, cmdTransfer...) // transfer: good - e.In.WriteString(validatorPass + "\r") + e.In.WriteString(testcli.ValidatorPass + "\r") e.Run(t, append(cmdTransfer, "--id", hex.EncodeToString(token1ID))...) - e.checkTxPersisted(t) + e.CheckTxPersisted(t) // check balance after transfer e.Run(t, append(cmdCheckBalance, "--token", h.StringLE())...) - checkBalanceResult(t, validatorAddr, tokz[1]) // only token2ID expected to be on the balance + checkBalanceResult(t, testcli.ValidatorAddr, tokz[1]) // only token2ID expected to be on the balance // transfer: good, 1/4 of the balance, to NEP-11-Payable contract, with data verifyH := deployVerifyContract(t, e) @@ -614,21 +615,21 @@ func TestNEP11_D_OwnerOf_BalanceOf_Transfer(t *testing.T) { "--rpc-endpoint", "http://" + e.RPC.Addr, "--wallet", wall, "--to", verifyH.StringLE(), - "--from", validatorAddr, + "--from", testcli.ValidatorAddr, "--token", h.StringLE(), "--id", hex.EncodeToString(token2ID), "--amount", "0.25", "--force", "string:some_data", } - e.In.WriteString(validatorPass + "\r") + e.In.WriteString(testcli.ValidatorPass + "\r") e.Run(t, cmdTransfer...) - tx, _ := e.checkTxPersisted(t) + tx, _ := e.CheckTxPersisted(t) // check OnNEP11Payment event aer, err := e.Chain.GetAppExecResults(tx.Hash(), trigger.Application) require.NoError(t, err) require.Equal(t, 2, len(aer[0].Events)) - validatorHash, err := address.StringToUint160(validatorAddr) + validatorHash, err := address.StringToUint160(testcli.ValidatorAddr) require.NoError(t, err) require.Equal(t, state.NotificationEvent{ ScriptHash: verifyH, @@ -644,17 +645,21 @@ func TestNEP11_D_OwnerOf_BalanceOf_Transfer(t *testing.T) { // check balance after transfer e.Run(t, append(cmdCheckBalance, "--token", h.StringLE())...) tokz[1].amount = "0.75" - checkBalanceResult(t, validatorAddr, tokz[1]) + checkBalanceResult(t, testcli.ValidatorAddr, tokz[1]) } -func deployNFSContract(t *testing.T, e *executor) util.Uint160 { - return deployContract(t, e, "../examples/nft-d/nft.go", "../examples/nft-d/nft.yml", validatorWallet, validatorAddr, validatorPass) +func deployNFSContract(t *testing.T, e *testcli.Executor) util.Uint160 { + return testcli.DeployContract(t, e, "../../examples/nft-d/nft.go", "../../examples/nft-d/nft.yml", testcli.ValidatorWallet, testcli.ValidatorAddr, testcli.ValidatorPass) } -func deployNFTContract(t *testing.T, e *executor) util.Uint160 { - return deployContract(t, e, "../examples/nft-nd/nft.go", "../examples/nft-nd/nft.yml", nftOwnerWallet, nftOwnerAddr, nftOwnerPass) +func deployNFTContract(t *testing.T, e *testcli.Executor) util.Uint160 { + return testcli.DeployContract(t, e, "../../examples/nft-nd/nft.go", "../../examples/nft-nd/nft.yml", nftOwnerWallet, nftOwnerAddr, nftOwnerPass) } -func deployNNSContract(t *testing.T, e *executor) util.Uint160 { - return deployContract(t, e, "../examples/nft-nd-nns/", "../examples/nft-nd-nns/nns.yml", validatorWallet, validatorAddr, validatorPass) +func deployNNSContract(t *testing.T, e *testcli.Executor) util.Uint160 { + return testcli.DeployContract(t, e, "../../examples/nft-nd-nns/", "../../examples/nft-nd-nns/nns.yml", testcli.ValidatorWallet, testcli.ValidatorAddr, testcli.ValidatorPass) +} + +func deployVerifyContract(t *testing.T, e *testcli.Executor) util.Uint160 { + return testcli.DeployContract(t, e, "../smartcontract/testdata/verify.go", "../smartcontract/testdata/verify.yml", testcli.ValidatorWallet, testcli.ValidatorAddr, testcli.ValidatorPass) } diff --git a/cli/nep17_test.go b/cli/nep_test/nep17_test.go similarity index 67% rename from cli/nep17_test.go rename to cli/nep_test/nep17_test.go index 6a43f96e6..081780928 100644 --- a/cli/nep17_test.go +++ b/cli/nep_test/nep17_test.go @@ -1,4 +1,4 @@ -package main +package nep_test import ( "io" @@ -8,6 +8,7 @@ import ( "strings" "testing" + "github.com/nspcc-dev/neo-go/internal/testcli" "github.com/nspcc-dev/neo-go/pkg/core/native/nativenames" "github.com/nspcc-dev/neo-go/pkg/encoding/address" "github.com/nspcc-dev/neo-go/pkg/encoding/fixedn" @@ -17,24 +18,24 @@ import ( ) func TestNEP17Balance(t *testing.T) { - e := newExecutor(t, true) + e := testcli.NewExecutor(t, true) cmdbalance := []string{"neo-go", "wallet", "nep17", "balance"} cmdbase := append(cmdbalance, "--rpc-endpoint", "http://"+e.RPC.Addr, - "--wallet", validatorWallet, + "--wallet", testcli.ValidatorWallet, ) - cmd := append(cmdbase, "--address", validatorAddr) + cmd := append(cmdbase, "--address", testcli.ValidatorAddr) t.Run("excessive parameters", func(t *testing.T) { e.RunWithError(t, append(cmd, "--token", "NEO", "gas")...) }) t.Run("NEO", func(t *testing.T) { - b, index := e.Chain.GetGoverningTokenBalance(validatorHash) + b, index := e.Chain.GetGoverningTokenBalance(testcli.ValidatorHash) checkResult := func(t *testing.T) { - e.checkNextLine(t, "^\\s*Account\\s+"+validatorAddr) - e.checkNextLine(t, "^\\s*NEO:\\s+NeoToken \\("+e.Chain.GoverningTokenHash().StringLE()+"\\)") - e.checkNextLine(t, "^\\s*Amount\\s*:\\s*"+b.String()+"$") - e.checkNextLine(t, "^\\s*Updated\\s*:\\s*"+strconv.FormatUint(uint64(index), 10)) - e.checkEOF(t) + e.CheckNextLine(t, "^\\s*Account\\s+"+testcli.ValidatorAddr) + e.CheckNextLine(t, "^\\s*NEO:\\s+NeoToken \\("+e.Chain.GoverningTokenHash().StringLE()+"\\)") + e.CheckNextLine(t, "^\\s*Amount\\s*:\\s*"+b.String()+"$") + e.CheckNextLine(t, "^\\s*Updated\\s*:\\s*"+strconv.FormatUint(uint64(index), 10)) + e.CheckEOF(t) } t.Run("Alias", func(t *testing.T) { e.Run(t, append(cmd, "--token", "NEO")...) @@ -47,67 +48,67 @@ func TestNEP17Balance(t *testing.T) { }) t.Run("GAS", func(t *testing.T) { e.Run(t, append(cmd, "--token", "GAS")...) - e.checkNextLine(t, "^\\s*Account\\s+"+validatorAddr) - e.checkNextLine(t, "^\\s*GAS:\\s+GasToken \\("+e.Chain.UtilityTokenHash().StringLE()+"\\)") - b := e.Chain.GetUtilityTokenBalance(validatorHash) - e.checkNextLine(t, "^\\s*Amount\\s*:\\s*"+fixedn.Fixed8(b.Int64()).String()+"$") + e.CheckNextLine(t, "^\\s*Account\\s+"+testcli.ValidatorAddr) + e.CheckNextLine(t, "^\\s*GAS:\\s+GasToken \\("+e.Chain.UtilityTokenHash().StringLE()+"\\)") + b := e.Chain.GetUtilityTokenBalance(testcli.ValidatorHash) + e.CheckNextLine(t, "^\\s*Amount\\s*:\\s*"+fixedn.Fixed8(b.Int64()).String()+"$") }) t.Run("zero balance of known token", func(t *testing.T) { e.Run(t, append(cmdbase, []string{"--token", "NEO"}...)...) addr1, err := address.StringToUint160("Nhfg3TbpwogLvDGVvAvqyThbsHgoSUKwtn") require.NoError(t, err) - e.checkNextLine(t, "^Account "+address.Uint160ToString(addr1)) - e.checkNextLine(t, "^\\s*NEO:\\s+NeoToken \\("+e.Chain.GoverningTokenHash().StringLE()+"\\)") - e.checkNextLine(t, "^\\s*Amount\\s*:\\s*"+fixedn.Fixed8(0).String()+"$") - e.checkNextLine(t, "^\\s*Updated:") - e.checkNextLine(t, "^\\s*$") + e.CheckNextLine(t, "^Account "+address.Uint160ToString(addr1)) + e.CheckNextLine(t, "^\\s*NEO:\\s+NeoToken \\("+e.Chain.GoverningTokenHash().StringLE()+"\\)") + e.CheckNextLine(t, "^\\s*Amount\\s*:\\s*"+fixedn.Fixed8(0).String()+"$") + e.CheckNextLine(t, "^\\s*Updated:") + e.CheckNextLine(t, "^\\s*$") }) t.Run("all accounts", func(t *testing.T) { e.Run(t, cmdbase...) addr1, err := address.StringToUint160("Nhfg3TbpwogLvDGVvAvqyThbsHgoSUKwtn") require.NoError(t, err) - e.checkNextLine(t, "^Account "+address.Uint160ToString(addr1)) - e.checkNextLine(t, "^\\s*GAS:\\s+GasToken \\("+e.Chain.UtilityTokenHash().StringLE()+"\\)") + e.CheckNextLine(t, "^Account "+address.Uint160ToString(addr1)) + e.CheckNextLine(t, "^\\s*GAS:\\s+GasToken \\("+e.Chain.UtilityTokenHash().StringLE()+"\\)") balance := e.Chain.GetUtilityTokenBalance(addr1) - e.checkNextLine(t, "^\\s*Amount\\s*:\\s*"+fixedn.Fixed8(balance.Int64()).String()+"$") - e.checkNextLine(t, "^\\s*Updated:") - e.checkNextLine(t, "^\\s*$") + e.CheckNextLine(t, "^\\s*Amount\\s*:\\s*"+fixedn.Fixed8(balance.Int64()).String()+"$") + e.CheckNextLine(t, "^\\s*Updated:") + e.CheckNextLine(t, "^\\s*$") addr2, err := address.StringToUint160("NVTiAjNgagDkTr5HTzDmQP9kPwPHN5BgVq") require.NoError(t, err) - e.checkNextLine(t, "^Account "+address.Uint160ToString(addr2)) - e.checkNextLine(t, "^\\s*$") + e.CheckNextLine(t, "^Account "+address.Uint160ToString(addr2)) + e.CheckNextLine(t, "^\\s*$") addr3, err := address.StringToUint160("NfgHwwTi3wHAS8aFAN243C5vGbkYDpqLHP") require.NoError(t, err) - e.checkNextLine(t, "^Account "+address.Uint160ToString(addr3)) + e.CheckNextLine(t, "^Account "+address.Uint160ToString(addr3)) // The order of assets is undefined. for i := 0; i < 2; i++ { - line := e.getNextLine(t) + line := e.GetNextLine(t) if strings.Contains(line, "GAS") { - e.checkLine(t, line, "^\\s*GAS:\\s+GasToken \\("+e.Chain.UtilityTokenHash().StringLE()+"\\)") + e.CheckLine(t, line, "^\\s*GAS:\\s+GasToken \\("+e.Chain.UtilityTokenHash().StringLE()+"\\)") balance = e.Chain.GetUtilityTokenBalance(addr3) - e.checkNextLine(t, "^\\s*Amount\\s*:\\s*"+fixedn.Fixed8(balance.Int64()).String()+"$") - e.checkNextLine(t, "^\\s*Updated:") + e.CheckNextLine(t, "^\\s*Amount\\s*:\\s*"+fixedn.Fixed8(balance.Int64()).String()+"$") + e.CheckNextLine(t, "^\\s*Updated:") } else { - balance, index := e.Chain.GetGoverningTokenBalance(validatorHash) - e.checkLine(t, line, "^\\s*NEO:\\s+NeoToken \\("+e.Chain.GoverningTokenHash().StringLE()+"\\)") - e.checkNextLine(t, "^\\s*Amount\\s*:\\s*"+balance.String()+"$") - e.checkNextLine(t, "^\\s*Updated\\s*:\\s*"+strconv.FormatUint(uint64(index), 10)) + balance, index := e.Chain.GetGoverningTokenBalance(testcli.ValidatorHash) + e.CheckLine(t, line, "^\\s*NEO:\\s+NeoToken \\("+e.Chain.GoverningTokenHash().StringLE()+"\\)") + e.CheckNextLine(t, "^\\s*Amount\\s*:\\s*"+balance.String()+"$") + e.CheckNextLine(t, "^\\s*Updated\\s*:\\s*"+strconv.FormatUint(uint64(index), 10)) } } - e.checkNextLine(t, "^\\s*$") + e.CheckNextLine(t, "^\\s*$") addr4, err := address.StringToUint160("NQ3nAdFQXzemHC9uvr4af2Ysap6aZJpqgN") // deployed verify.go contract require.NoError(t, err) - e.checkNextLine(t, "^Account "+address.Uint160ToString(addr4)) - e.checkEOF(t) + e.CheckNextLine(t, "^Account "+address.Uint160ToString(addr4)) + e.CheckEOF(t) }) t.Run("Bad token", func(t *testing.T) { e.Run(t, append(cmd, "--token", "kek")...) - e.checkNextLine(t, "^\\s*Account\\s+"+validatorAddr) - e.checkNextLine(t, `^\s*Can't find data for "kek" token\s*`) - e.checkEOF(t) + e.CheckNextLine(t, "^\\s*Account\\s+"+testcli.ValidatorAddr) + e.CheckNextLine(t, `^\s*Can't find data for "kek" token\s*`) + e.CheckEOF(t) }) t.Run("Bad wallet", func(t *testing.T) { e.RunWithError(t, append(cmdbalance, "--wallet", "/dev/null")...) @@ -115,18 +116,18 @@ func TestNEP17Balance(t *testing.T) { } func TestNEP17Transfer(t *testing.T) { - w, err := wallet.NewWalletFromFile("testdata/testwallet.json") + w, err := wallet.NewWalletFromFile("../testdata/testwallet.json") require.NoError(t, err) - e := newExecutor(t, true) + e := testcli.NewExecutor(t, true) args := []string{ "neo-go", "wallet", "nep17", "transfer", "--rpc-endpoint", "http://" + e.RPC.Addr, - "--wallet", validatorWallet, + "--wallet", testcli.ValidatorWallet, "--to", w.Accounts[0].Address, "--token", "NEO", "--amount", "1", - "--from", validatorAddr, + "--from", testcli.ValidatorAddr, } t.Run("missing receiver", func(t *testing.T) { @@ -157,10 +158,10 @@ func TestNEP17Transfer(t *testing.T) { e.In.WriteString("one\r") e.In.WriteString("Y\r") e.Run(t, args...) - e.checkNextLine(t, `^Network fee:\s*(\d|\.)+`) - e.checkNextLine(t, `^System fee:\s*(\d|\.)+`) - e.checkNextLine(t, `^Total fee:\s*(\d|\.)+`) - e.checkTxPersisted(t) + e.CheckNextLine(t, `^Network fee:\s*(\d|\.)+`) + e.CheckNextLine(t, `^System fee:\s*(\d|\.)+`) + e.CheckNextLine(t, `^Total fee:\s*(\d|\.)+`) + e.CheckTxPersisted(t) sh := w.Accounts[0].ScriptHash() b, _ := e.Chain.GetGoverningTokenBalance(sh) @@ -169,7 +170,7 @@ func TestNEP17Transfer(t *testing.T) { t.Run("with force", func(t *testing.T) { e.In.WriteString("one\r") e.Run(t, append(args, "--force")...) - e.checkTxPersisted(t) + e.CheckTxPersisted(t) b, _ := e.Chain.GetGoverningTokenBalance(sh) require.Equal(t, big.NewInt(2), b) @@ -182,18 +183,18 @@ func TestNEP17Transfer(t *testing.T) { e.In.WriteString("one\r") e.Run(t, "neo-go", "wallet", "nep17", "multitransfer", "--rpc-endpoint", "http://"+e.RPC.Addr, - "--wallet", validatorWallet, - "--from", validatorAddr, + "--wallet", testcli.ValidatorWallet, + "--from", testcli.ValidatorAddr, "--force", "NEO:"+validatorDefault+":42", "GAS:"+validatorDefault+":7") - e.checkTxPersisted(t) + e.CheckTxPersisted(t) args := args[:len(args)-2] // cut '--from' argument args = append(args, "--force") e.In.WriteString("one\r") e.Run(t, args...) - e.checkTxPersisted(t) + e.CheckTxPersisted(t) b, _ := e.Chain.GetGoverningTokenBalance(sh) require.Equal(t, big.NewInt(3), b) @@ -208,62 +209,62 @@ func TestNEP17Transfer(t *testing.T) { e.In.WriteString("one\r") e.Run(t, "neo-go", "wallet", "nep17", "multitransfer", "--rpc-endpoint", "http://"+e.RPC.Addr, - "--wallet", validatorWallet, - "--from", validatorAddr, + "--wallet", testcli.ValidatorWallet, + "--from", testcli.ValidatorAddr, "--force", "NEO:"+validatorDefault+":42", "GAS:"+validatorDefault+":7", - "--", validatorAddr+":Global") - e.checkTxPersisted(t) + "--", testcli.ValidatorAddr+":Global") + e.CheckTxPersisted(t) }) validTil := e.Chain.BlockHeight() + 100 cmd := []string{ "neo-go", "wallet", "nep17", "transfer", "--rpc-endpoint", "http://" + e.RPC.Addr, - "--wallet", validatorWallet, + "--wallet", testcli.ValidatorWallet, "--to", address.Uint160ToString(e.Chain.GetNotaryContractScriptHash()), "--token", "GAS", "--amount", "1", - "--from", validatorAddr, + "--from", testcli.ValidatorAddr, "--force", - "[", validatorAddr, strconv.Itoa(int(validTil)), "]"} + "[", testcli.ValidatorAddr, strconv.Itoa(int(validTil)), "]"} t.Run("with data", func(t *testing.T) { e.In.WriteString("one\r") e.Run(t, cmd...) - e.checkTxPersisted(t) + e.CheckTxPersisted(t) }) t.Run("with data and signers", func(t *testing.T) { t.Run("invalid sender's scope", func(t *testing.T) { e.In.WriteString("one\r") - e.RunWithError(t, append(cmd, "--", validatorAddr+":None")...) + e.RunWithError(t, append(cmd, "--", testcli.ValidatorAddr+":None")...) }) t.Run("good", func(t *testing.T) { e.In.WriteString("one\r") - e.Run(t, append(cmd, "--", validatorAddr+":Global")...) // CalledByEntry is enough, but it's the default value, so check something else - e.checkTxPersisted(t) + e.Run(t, append(cmd, "--", testcli.ValidatorAddr+":Global")...) // CalledByEntry is enough, but it's the default value, so check something else + e.CheckTxPersisted(t) }) t.Run("several signers", func(t *testing.T) { e.In.WriteString("one\r") - e.Run(t, append(cmd, "--", validatorAddr, hVerify.StringLE())...) - e.checkTxPersisted(t) + e.Run(t, append(cmd, "--", testcli.ValidatorAddr, hVerify.StringLE())...) + e.CheckTxPersisted(t) }) }) } func TestNEP17MultiTransfer(t *testing.T) { - privs, _ := generateKeys(t, 3) + privs, _ := testcli.GenerateKeys(t, 3) - e := newExecutor(t, true) + e := testcli.NewExecutor(t, true) neoContractHash, err := e.Chain.GetNativeContractScriptHash(nativenames.Neo) require.NoError(t, err) args := []string{ "neo-go", "wallet", "nep17", "multitransfer", "--rpc-endpoint", "http://" + e.RPC.Addr, - "--wallet", validatorWallet, - "--from", validatorAddr, + "--wallet", testcli.ValidatorWallet, + "--from", testcli.ValidatorAddr, "--force", "NEO:" + privs[0].Address() + ":42", "GAS:" + privs[1].Address() + ":7", @@ -274,7 +275,7 @@ func TestNEP17MultiTransfer(t *testing.T) { t.Run("no cosigners", func(t *testing.T) { e.In.WriteString("one\r") e.Run(t, args...) - e.checkTxPersisted(t) + e.CheckTxPersisted(t) b, _ := e.Chain.GetGoverningTokenBalance(privs[0].GetScriptHash()) require.Equal(t, big.NewInt(42), b) @@ -287,24 +288,24 @@ func TestNEP17MultiTransfer(t *testing.T) { t.Run("invalid sender scope", func(t *testing.T) { e.In.WriteString("one\r") e.RunWithError(t, append(args, - "--", validatorAddr+":None")...) // invalid sender scope + "--", testcli.ValidatorAddr+":None")...) // invalid sender scope }) t.Run("Global sender scope", func(t *testing.T) { e.In.WriteString("one\r") e.Run(t, append(args, - "--", validatorAddr+":Global")...) - e.checkTxPersisted(t) + "--", testcli.ValidatorAddr+":Global")...) + e.CheckTxPersisted(t) }) t.Run("Several cosigners", func(t *testing.T) { e.In.WriteString("one\r") e.Run(t, append(args, - "--", validatorAddr, hVerify.StringLE())...) - e.checkTxPersisted(t) + "--", testcli.ValidatorAddr, hVerify.StringLE())...) + e.CheckTxPersisted(t) }) } func TestNEP17ImportToken(t *testing.T) { - e := newExecutor(t, true) + e := testcli.NewExecutor(t, true) tmpDir := t.TempDir() walletPath := filepath.Join(tmpDir, "walletForImport.json") @@ -342,12 +343,12 @@ func TestNEP17ImportToken(t *testing.T) { t.Run("Info", func(t *testing.T) { checkGASInfo := func(t *testing.T) { - e.checkNextLine(t, "^Name:\\s*GasToken") - e.checkNextLine(t, "^Symbol:\\s*GAS") - e.checkNextLine(t, "^Hash:\\s*"+gasContractHash.StringLE()) - e.checkNextLine(t, "^Decimals:\\s*8") - e.checkNextLine(t, "^Address:\\s*"+address.Uint160ToString(gasContractHash)) - e.checkNextLine(t, "^Standard:\\s*"+string(manifest.NEP17StandardName)) + e.CheckNextLine(t, "^Name:\\s*GasToken") + e.CheckNextLine(t, "^Symbol:\\s*GAS") + e.CheckNextLine(t, "^Hash:\\s*"+gasContractHash.StringLE()) + e.CheckNextLine(t, "^Decimals:\\s*8") + e.CheckNextLine(t, "^Address:\\s*"+address.Uint160ToString(gasContractHash)) + e.CheckNextLine(t, "^Standard:\\s*"+string(manifest.NEP17StandardName)) } t.Run("excessive parameters", func(t *testing.T) { e.RunWithError(t, "neo-go", "wallet", "nep17", "info", @@ -364,12 +365,12 @@ func TestNEP17ImportToken(t *testing.T) { checkGASInfo(t) _, err := e.Out.ReadString('\n') require.NoError(t, err) - e.checkNextLine(t, "^Name:\\s*NeoToken") - e.checkNextLine(t, "^Symbol:\\s*NEO") - e.checkNextLine(t, "^Hash:\\s*"+neoContractHash.StringLE()) - e.checkNextLine(t, "^Decimals:\\s*0") - e.checkNextLine(t, "^Address:\\s*"+address.Uint160ToString(neoContractHash)) - e.checkNextLine(t, "^Standard:\\s*"+string(manifest.NEP17StandardName)) + e.CheckNextLine(t, "^Name:\\s*NeoToken") + e.CheckNextLine(t, "^Symbol:\\s*NEO") + e.CheckNextLine(t, "^Hash:\\s*"+neoContractHash.StringLE()) + e.CheckNextLine(t, "^Decimals:\\s*0") + e.CheckNextLine(t, "^Address:\\s*"+address.Uint160ToString(neoContractHash)) + e.CheckNextLine(t, "^Standard:\\s*"+string(manifest.NEP17StandardName)) }) t.Run("Remove", func(t *testing.T) { e.RunWithError(t, "neo-go", "wallet", "nep17", "remove", diff --git a/cli/options_test.go b/cli/options/cli_options_test.go similarity index 74% rename from cli/options_test.go rename to cli/options/cli_options_test.go index 5658f8179..4353de239 100644 --- a/cli/options_test.go +++ b/cli/options/cli_options_test.go @@ -1,20 +1,22 @@ -package main +package options_test import ( "flag" "testing" + "github.com/nspcc-dev/neo-go/cli/app" "github.com/nspcc-dev/neo-go/cli/options" + "github.com/nspcc-dev/neo-go/internal/testcli" "github.com/stretchr/testify/require" "github.com/urfave/cli" ) func TestGetRPCClient(t *testing.T) { - e := newExecutor(t, true) + e := testcli.NewExecutor(t, true) t.Run("no endpoint", func(t *testing.T) { set := flag.NewFlagSet("flagSet", flag.ExitOnError) - ctx := cli.NewContext(cli.NewApp(), set, nil) + ctx := cli.NewContext(app.New(), set, nil) gctx, _ := options.GetTimeoutContext(ctx) _, ec := options.GetRPCClient(gctx, ctx) require.Equal(t, 1, ec.ExitCode()) @@ -23,7 +25,7 @@ func TestGetRPCClient(t *testing.T) { t.Run("success", func(t *testing.T) { set := flag.NewFlagSet("flagSet", flag.ExitOnError) set.String(options.RPCEndpointFlag, "http://"+e.RPC.Addr, "") - ctx := cli.NewContext(cli.NewApp(), set, nil) + ctx := cli.NewContext(app.New(), set, nil) gctx, _ := options.GetTimeoutContext(ctx) _, ec := options.GetRPCClient(gctx, ctx) require.Nil(t, ec) diff --git a/cli/query_test.go b/cli/query/query_test.go similarity index 66% rename from cli/query_test.go rename to cli/query/query_test.go index 3daa6ea8f..447064fe1 100644 --- a/cli/query_test.go +++ b/cli/query/query_test.go @@ -1,4 +1,4 @@ -package main +package query_test import ( "encoding/base64" @@ -10,6 +10,7 @@ import ( "time" "github.com/nspcc-dev/neo-go/internal/random" + "github.com/nspcc-dev/neo-go/internal/testcli" "github.com/nspcc-dev/neo-go/pkg/core/transaction" "github.com/nspcc-dev/neo-go/pkg/encoding/address" "github.com/nspcc-dev/neo-go/pkg/encoding/fixedn" @@ -22,24 +23,24 @@ import ( ) func TestQueryTx(t *testing.T) { - e := newExecutorSuspended(t) + e := testcli.NewExecutorSuspended(t) - w, err := wallet.NewWalletFromFile("testdata/testwallet.json") + w, err := wallet.NewWalletFromFile("../testdata/testwallet.json") require.NoError(t, err) transferArgs := []string{ "neo-go", "wallet", "nep17", "transfer", "--rpc-endpoint", "http://" + e.RPC.Addr, - "--wallet", validatorWallet, + "--wallet", testcli.ValidatorWallet, "--to", w.Accounts[0].Address, "--token", "NEO", - "--from", validatorAddr, + "--from", testcli.ValidatorAddr, "--force", } e.In.WriteString("one\r") e.Run(t, append(transferArgs, "--amount", "1")...) - line := e.getNextLine(t) + line := e.GetNextLine(t) txHash, err := util.Uint256DecodeStringLE(line) require.NoError(t, err) @@ -48,42 +49,42 @@ func TestQueryTx(t *testing.T) { args := []string{"neo-go", "query", "tx", "--rpc-endpoint", "http://" + e.RPC.Addr} e.Run(t, append(args, txHash.StringLE())...) - e.checkNextLine(t, `Hash:\s+`+txHash.StringLE()) - e.checkNextLine(t, `OnChain:\s+false`) - e.checkNextLine(t, `ValidUntil:\s+`+strconv.FormatUint(uint64(tx.ValidUntilBlock), 10)) - e.checkEOF(t) + e.CheckNextLine(t, `Hash:\s+`+txHash.StringLE()) + e.CheckNextLine(t, `OnChain:\s+false`) + e.CheckNextLine(t, `ValidUntil:\s+`+strconv.FormatUint(uint64(tx.ValidUntilBlock), 10)) + e.CheckEOF(t) height := e.Chain.BlockHeight() go e.Chain.Run() require.Eventually(t, func() bool { return e.Chain.BlockHeight() > height }, time.Second*2, time.Millisecond*50) e.Run(t, append(args, txHash.StringLE())...) - e.checkNextLine(t, `Hash:\s+`+txHash.StringLE()) - e.checkNextLine(t, `OnChain:\s+true`) + e.CheckNextLine(t, `Hash:\s+`+txHash.StringLE()) + e.CheckNextLine(t, `OnChain:\s+true`) _, height, err = e.Chain.GetTransaction(txHash) require.NoError(t, err) - e.checkNextLine(t, `BlockHash:\s+`+e.Chain.GetHeaderHash(int(height)).StringLE()) - e.checkNextLine(t, `Success:\s+true`) - e.checkEOF(t) + e.CheckNextLine(t, `BlockHash:\s+`+e.Chain.GetHeaderHash(int(height)).StringLE()) + e.CheckNextLine(t, `Success:\s+true`) + e.CheckEOF(t) t.Run("verbose", func(t *testing.T) { e.Run(t, append(args, "--verbose", txHash.StringLE())...) - e.compareQueryTxVerbose(t, tx) + compareQueryTxVerbose(t, e, tx) t.Run("FAULT", func(t *testing.T) { e.In.WriteString("one\r") e.Run(t, "neo-go", "contract", "invokefunction", "--rpc-endpoint", "http://"+e.RPC.Addr, - "--wallet", validatorWallet, - "--address", validatorAddr, + "--wallet", testcli.ValidatorWallet, + "--address", testcli.ValidatorAddr, "--force", random.Uint160().StringLE(), "randomMethod") - e.checkNextLine(t, `Warning:`) - e.checkNextLine(t, "Sending transaction") - line := strings.TrimPrefix(e.getNextLine(t), "Sent invocation transaction ") + e.CheckNextLine(t, `Warning:`) + e.CheckNextLine(t, "Sending transaction") + line := strings.TrimPrefix(e.GetNextLine(t), "Sent invocation transaction ") txHash, err := util.Uint256DecodeStringLE(line) require.NoError(t, err) @@ -93,7 +94,7 @@ func TestQueryTx(t *testing.T) { tx, _, err := e.Chain.GetTransaction(txHash) require.NoError(t, err) e.Run(t, append(args, "--verbose", txHash.StringLE())...) - e.compareQueryTxVerbose(t, tx) + compareQueryTxVerbose(t, e, tx) }) }) @@ -113,43 +114,43 @@ func TestQueryTx(t *testing.T) { }) } -func (e *executor) compareQueryTxVerbose(t *testing.T, tx *transaction.Transaction) { - e.checkNextLine(t, `Hash:\s+`+tx.Hash().StringLE()) - e.checkNextLine(t, `OnChain:\s+true`) +func compareQueryTxVerbose(t *testing.T, e *testcli.Executor, tx *transaction.Transaction) { + e.CheckNextLine(t, `Hash:\s+`+tx.Hash().StringLE()) + e.CheckNextLine(t, `OnChain:\s+true`) _, height, err := e.Chain.GetTransaction(tx.Hash()) require.NoError(t, err) - e.checkNextLine(t, `BlockHash:\s+`+e.Chain.GetHeaderHash(int(height)).StringLE()) + e.CheckNextLine(t, `BlockHash:\s+`+e.Chain.GetHeaderHash(int(height)).StringLE()) res, _ := e.Chain.GetAppExecResults(tx.Hash(), trigger.Application) - e.checkNextLine(t, fmt.Sprintf(`Success:\s+%t`, res[0].Execution.VMState == vmstate.Halt)) + e.CheckNextLine(t, fmt.Sprintf(`Success:\s+%t`, res[0].Execution.VMState == vmstate.Halt)) for _, s := range tx.Signers { - e.checkNextLine(t, fmt.Sprintf(`Signer:\s+%s\s*\(%s\)`, address.Uint160ToString(s.Account), s.Scopes.String())) + e.CheckNextLine(t, fmt.Sprintf(`Signer:\s+%s\s*\(%s\)`, address.Uint160ToString(s.Account), s.Scopes.String())) } - e.checkNextLine(t, `SystemFee:\s+`+fixedn.Fixed8(tx.SystemFee).String()+" GAS$") - e.checkNextLine(t, `NetworkFee:\s+`+fixedn.Fixed8(tx.NetworkFee).String()+" GAS$") - e.checkNextLine(t, `Script:\s+`+regexp.QuoteMeta(base64.StdEncoding.EncodeToString(tx.Script))) + e.CheckNextLine(t, `SystemFee:\s+`+fixedn.Fixed8(tx.SystemFee).String()+" GAS$") + e.CheckNextLine(t, `NetworkFee:\s+`+fixedn.Fixed8(tx.NetworkFee).String()+" GAS$") + e.CheckNextLine(t, `Script:\s+`+regexp.QuoteMeta(base64.StdEncoding.EncodeToString(tx.Script))) c := vm.NewContext(tx.Script) n := 0 for ; c.NextIP() < c.LenInstr(); _, _, err = c.Next() { require.NoError(t, err) n++ } - e.checkScriptDump(t, n) + e.CheckScriptDump(t, n) if res[0].Execution.VMState != vmstate.Halt { - e.checkNextLine(t, `Exception:\s+`+regexp.QuoteMeta(res[0].Execution.FaultException)) + e.CheckNextLine(t, `Exception:\s+`+regexp.QuoteMeta(res[0].Execution.FaultException)) } - e.checkEOF(t) + e.CheckEOF(t) } func TestQueryHeight(t *testing.T) { - e := newExecutor(t, true) + e := testcli.NewExecutor(t, true) args := []string{"neo-go", "query", "height", "--rpc-endpoint", "http://" + e.RPC.Addr} e.Run(t, args...) - e.checkNextLine(t, `^Latest block: [0-9]+$`) - e.checkNextLine(t, `^Validated state: [0-9]+$`) - e.checkEOF(t) + e.CheckNextLine(t, `^Latest block: [0-9]+$`) + e.CheckNextLine(t, `^Validated state: [0-9]+$`) + e.CheckEOF(t) t.Run("excessive arguments", func(t *testing.T) { e.RunWithError(t, append(args, "something")...) }) diff --git a/cli/dump_test.go b/cli/server/cli_dump_test.go similarity index 93% rename from cli/dump_test.go rename to cli/server/cli_dump_test.go index 0490156b6..4911de3bc 100644 --- a/cli/dump_test.go +++ b/cli/server/cli_dump_test.go @@ -1,4 +1,4 @@ -package main +package server_test import ( "os" @@ -6,6 +6,7 @@ import ( "strconv" "testing" + "github.com/nspcc-dev/neo-go/internal/testcli" "github.com/nspcc-dev/neo-go/pkg/config" "github.com/stretchr/testify/require" "gopkg.in/yaml.v3" @@ -16,7 +17,7 @@ func TestDBRestoreDump(t *testing.T) { loadConfig := func(t *testing.T) config.Config { chainPath := filepath.Join(tmpDir, "neogotestchain") - cfg, err := config.LoadFile(filepath.Join("..", "config", "protocol.unit_testnet.yml")) + cfg, err := config.LoadFile(filepath.Join("..", "..", "config", "protocol.unit_testnet.yml")) require.NoError(t, err, "could not load config") cfg.ApplicationConfiguration.DBConfiguration.Type = "leveldb" cfg.ApplicationConfiguration.DBConfiguration.LevelDBOptions.DataDirectoryPath = chainPath @@ -30,9 +31,9 @@ func TestDBRestoreDump(t *testing.T) { cfgPath := filepath.Join(tmpDir, "protocol.unit_testnet.yml") require.NoError(t, os.WriteFile(cfgPath, out, os.ModePerm)) - // generated via `go run ./scripts/gendump/main.go --out ./cli/testdata/chain50x2.acc --blocks 50 --txs 2` + // generated via `go run ./scripts/gendump/main.go --out ./cli/server/testdata/chain50x2.acc --blocks 50 --txs 2` const inDump = "./testdata/chain50x2.acc" - e := newExecutor(t, false) + e := testcli.NewExecutor(t, false) stateDump := filepath.Join(tmpDir, "neogo.teststate") baseArgs := []string{"neo-go", "db", "restore", "--unittest", diff --git a/cli/server_test.go b/cli/server/cli_server_test.go similarity index 92% rename from cli/server_test.go rename to cli/server/cli_server_test.go index 09403c418..ccaf646e9 100644 --- a/cli/server_test.go +++ b/cli/server/cli_server_test.go @@ -1,4 +1,4 @@ -package main +package server_test import ( "errors" @@ -11,6 +11,7 @@ import ( "time" "github.com/nspcc-dev/neo-go/cli/server" + "github.com/nspcc-dev/neo-go/internal/testcli" "github.com/nspcc-dev/neo-go/pkg/config" "github.com/stretchr/testify/require" "gopkg.in/yaml.v3" @@ -18,7 +19,7 @@ import ( func TestServerStart(t *testing.T) { tmpDir := t.TempDir() - goodCfg, err := config.LoadFile(filepath.Join("..", "config", "protocol.unit_testnet.yml")) + goodCfg, err := config.LoadFile(filepath.Join("..", "..", "config", "protocol.unit_testnet.yml")) require.NoError(t, err, "could not load config") ptr := &goodCfg saveCfg := func(t *testing.T, f func(cfg *config.Config)) string { @@ -39,7 +40,7 @@ func TestServerStart(t *testing.T) { } baseCmd := []string{"neo-go", "node", "--unittest", "--config-path", tmpDir} - e := newExecutor(t, false) + e := testcli.NewExecutor(t, false) t.Run("invalid config path", func(t *testing.T) { e.RunWithError(t, baseCmd...) @@ -120,11 +121,11 @@ func TestServerStart(t *testing.T) { for _, expected := range lines { // It should be regexp, so escape all backslashes. expected = strings.ReplaceAll(expected, `\`, `\\`) - e.checkLine(t, line, expected) - line = e.getNextLine(t) + e.CheckLine(t, line, expected) + line = e.GetNextLine(t) } - e.checkNextLine(t, "") - e.checkEOF(t) + e.CheckNextLine(t, "") + e.CheckEOF(t) }) } } diff --git a/cli/testdata/chain50x2.acc b/cli/server/testdata/chain50x2.acc similarity index 100% rename from cli/testdata/chain50x2.acc rename to cli/server/testdata/chain50x2.acc diff --git a/cli/contract_test.go b/cli/smartcontract/contract_test.go similarity index 87% rename from cli/contract_test.go rename to cli/smartcontract/contract_test.go index 55e6bfa6d..5d3984520 100644 --- a/cli/contract_test.go +++ b/cli/smartcontract/contract_test.go @@ -1,4 +1,4 @@ -package main +package smartcontract_test import ( "bytes" @@ -12,6 +12,7 @@ import ( "github.com/nspcc-dev/neo-go/cli/smartcontract" "github.com/nspcc-dev/neo-go/internal/random" + "github.com/nspcc-dev/neo-go/internal/testcli" "github.com/nspcc-dev/neo-go/pkg/config" "github.com/nspcc-dev/neo-go/pkg/core/interop/storage" "github.com/nspcc-dev/neo-go/pkg/core/state" @@ -32,7 +33,7 @@ import ( func TestCalcHash(t *testing.T) { tmpDir := t.TempDir() - e := newExecutor(t, false) + e := testcli.NewExecutor(t, false) nefPath := "./testdata/verify.nef" src, err := os.ReadFile(nefPath) @@ -83,15 +84,15 @@ func TestCalcHash(t *testing.T) { }) t.Run("valid, uint160", func(t *testing.T) { e.Run(t, append(cmd, "--sender", sender.StringLE())...) - e.checkNextLine(t, expected.StringLE()) + e.CheckNextLine(t, expected.StringLE()) }) t.Run("valid, uint160 with 0x", func(t *testing.T) { e.Run(t, append(cmd, "--sender", "0x"+sender.StringLE())...) - e.checkNextLine(t, expected.StringLE()) + e.CheckNextLine(t, expected.StringLE()) }) t.Run("valid, address", func(t *testing.T) { e.Run(t, append(cmd, "--sender", address.Uint160ToString(sender))...) - e.checkNextLine(t, expected.StringLE()) + e.CheckNextLine(t, expected.StringLE()) }) } @@ -103,7 +104,7 @@ func TestContractBindings(t *testing.T) { smartcontract.ModVersion = "v0.0.0" tmpDir := t.TempDir() - e := newExecutor(t, false) + e := testcli.NewExecutor(t, false) ctrPath := filepath.Join(tmpDir, "testcontract") e.Run(t, "neo-go", "contract", "init", "--name", ctrPath) @@ -152,7 +153,7 @@ func Blocks() []*alias.Block { wd, err := os.Getwd() require.NoError(t, err) data = append(data, "\nreplace github.com/nspcc-dev/neo-go/pkg/interop => "...) - data = append(data, filepath.Join(wd, "../pkg/interop")...) + data = append(data, filepath.Join(wd, "../../pkg/interop")...) require.NoError(t, os.WriteFile(goMod, data, os.ModePerm)) cmd = append(cmd, "--config", cfgPath, @@ -163,7 +164,7 @@ func Blocks() []*alias.Block { e.RunWithError(t, append(cmd, "something")...) }) e.Run(t, cmd...) - e.checkEOF(t) + e.CheckEOF(t) require.FileExists(t, bindingsPath) outPath := filepath.Join(t.TempDir(), "binding.go") @@ -216,7 +217,7 @@ func TestContractInitAndCompile(t *testing.T) { smartcontract.ModVersion = "v0.0.0" tmpDir := t.TempDir() - e := newExecutor(t, false) + e := testcli.NewExecutor(t, false) t.Run("no path is provided", func(t *testing.T) { e.RunWithError(t, "neo-go", "contract", "init") @@ -269,7 +270,7 @@ func TestContractInitAndCompile(t *testing.T) { wd, err := os.Getwd() require.NoError(t, err) data = append(data, "\nreplace github.com/nspcc-dev/neo-go/pkg/interop => "...) - data = append(data, filepath.Join(wd, "../pkg/interop")...) + data = append(data, filepath.Join(wd, "../../pkg/interop")...) require.NoError(t, os.WriteFile(goMod, data, os.ModePerm)) cmd = append(cmd, "--config", cfgPath) @@ -279,20 +280,20 @@ func TestContractInitAndCompile(t *testing.T) { }) e.Run(t, cmd...) - e.checkEOF(t) + e.CheckEOF(t) require.FileExists(t, nefPath) require.FileExists(t, manifestPath) t.Run("output hex script with --verbose", func(t *testing.T) { e.Run(t, append(cmd, "--verbose")...) - e.checkNextLine(t, "^[0-9a-hA-H]+$") + e.CheckNextLine(t, "^[0-9a-hA-H]+$") }) } // Checks that error is returned if GAS available for test-invoke exceeds // GAS needed to be consumed. func TestDeployBigContract(t *testing.T) { - e := newExecutorWithConfig(t, true, true, func(c *config.Config) { + e := testcli.NewExecutorWithConfig(t, true, true, func(c *config.Config) { c.ApplicationConfiguration.RPC.MaxGasInvoke = fixedn.Fixed8(1) }) @@ -307,15 +308,15 @@ func TestDeployBigContract(t *testing.T) { "--config", "testdata/deploy/neo-go.yml", "--out", nefName, "--manifest", manifestName) - e.In.WriteString("one\r") + e.In.WriteString(testcli.ValidatorPass + "\r") e.RunWithError(t, "neo-go", "contract", "deploy", "--rpc-endpoint", "http://"+e.RPC.Addr, - "--wallet", validatorWallet, "--address", validatorAddr, + "--wallet", testcli.ValidatorWallet, "--address", testcli.ValidatorAddr, "--in", nefName, "--manifest", manifestName) } func TestContractDeployWithData(t *testing.T) { - eCompile := newExecutor(t, false) + eCompile := testcli.NewExecutor(t, false) // For proper nef generation. config.Version = "0.90.0-test" @@ -329,11 +330,11 @@ func TestContractDeployWithData(t *testing.T) { "--out", nefName, "--manifest", manifestName) deployContract := func(t *testing.T, haveData bool, scope string) { - e := newExecutor(t, true) + e := testcli.NewExecutor(t, true) cmd := []string{ "neo-go", "contract", "deploy", "--rpc-endpoint", "http://" + e.RPC.Addr, - "--wallet", validatorWallet, "--address", validatorAddr, + "--wallet", testcli.ValidatorWallet, "--address", testcli.ValidatorAddr, "--in", nefName, "--manifest", manifestName, "--force", } @@ -342,14 +343,14 @@ func TestContractDeployWithData(t *testing.T) { cmd = append(cmd, "[", "key1", "12", "key2", "take_me_to_church", "]") } if scope != "" { - cmd = append(cmd, "--", validatorAddr+":"+scope) + cmd = append(cmd, "--", testcli.ValidatorAddr+":"+scope) } else { scope = "CalledByEntry" } - e.In.WriteString("one\r") + e.In.WriteString(testcli.ValidatorPass + "\r") e.Run(t, cmd...) - tx, _ := e.checkTxPersisted(t, "Sent invocation transaction ") + tx, _ := e.CheckTxPersisted(t, "Sent invocation transaction ") require.Equal(t, scope, tx.Signers[0].Scopes.String()) if !haveData { return @@ -392,7 +393,7 @@ func TestContractDeployWithData(t *testing.T) { } func TestDeployWithSigners(t *testing.T) { - e := newExecutor(t, true) + e := testcli.NewExecutor(t, true) // For proper nef generation. config.Version = "0.90.0-test" @@ -408,61 +409,61 @@ func TestDeployWithSigners(t *testing.T) { t.Run("missing nef", func(t *testing.T) { e.RunWithError(t, "neo-go", "contract", "deploy", "--rpc-endpoint", "http://"+e.RPC.Addr, - "--wallet", validatorWallet, "--address", validatorAddr, + "--wallet", testcli.ValidatorWallet, "--address", testcli.ValidatorAddr, "--in", "", "--manifest", manifestName) }) t.Run("missing manifest", func(t *testing.T) { e.RunWithError(t, "neo-go", "contract", "deploy", "--rpc-endpoint", "http://"+e.RPC.Addr, - "--wallet", validatorWallet, "--address", validatorAddr, + "--wallet", testcli.ValidatorWallet, "--address", testcli.ValidatorAddr, "--in", nefName, "--manifest", "") }) t.Run("corrupted data", func(t *testing.T) { e.RunWithError(t, "neo-go", "contract", "deploy", "--rpc-endpoint", "http://"+e.RPC.Addr, - "--wallet", validatorWallet, "--address", validatorAddr, + "--wallet", testcli.ValidatorWallet, "--address", testcli.ValidatorAddr, "--in", nefName, "--manifest", manifestName, "[", "str1") }) t.Run("invalid data", func(t *testing.T) { e.RunWithError(t, "neo-go", "contract", "deploy", "--rpc-endpoint", "http://"+e.RPC.Addr, - "--wallet", validatorWallet, "--address", validatorAddr, + "--wallet", testcli.ValidatorWallet, "--address", testcli.ValidatorAddr, "--in", nefName, "--manifest", manifestName, "str1", "str2") }) t.Run("missing wallet", func(t *testing.T) { e.RunWithError(t, "neo-go", "contract", "deploy", "--rpc-endpoint", "http://"+e.RPC.Addr, - "--address", validatorAddr, + "--address", testcli.ValidatorAddr, "--in", nefName, "--manifest", manifestName, "[", "str1", "str2", "]") }) t.Run("missing RPC", func(t *testing.T) { e.RunWithError(t, "neo-go", "contract", "deploy", - "--wallet", validatorWallet, "--address", validatorAddr, + "--wallet", testcli.ValidatorWallet, "--address", testcli.ValidatorAddr, "--in", nefName, "--manifest", manifestName, "[", "str1", "str2", "]") }) - e.In.WriteString("one\r") + e.In.WriteString(testcli.ValidatorPass + "\r") e.Run(t, "neo-go", "contract", "deploy", "--rpc-endpoint", "http://"+e.RPC.Addr, - "--wallet", validatorWallet, "--address", validatorAddr, + "--wallet", testcli.ValidatorWallet, "--address", testcli.ValidatorAddr, "--in", nefName, "--manifest", manifestName, "--force", - "--", validatorAddr+":Global") - tx, _ := e.checkTxPersisted(t, "Sent invocation transaction ") + "--", testcli.ValidatorAddr+":Global") + tx, _ := e.CheckTxPersisted(t, "Sent invocation transaction ") require.Equal(t, transaction.Global, tx.Signers[0].Scopes) } func TestContractManifestGroups(t *testing.T) { - e := newExecutor(t, true) + e := testcli.NewExecutor(t, true) // For proper nef generation. config.Version = "0.90.0-test" tmpDir := t.TempDir() - _, err := wallet.NewWalletFromFile(testWalletPath) + _, err := wallet.NewWalletFromFile(testcli.TestWalletPath) require.NoError(t, err) nefName := filepath.Join(tmpDir, "deploy.nef") @@ -481,93 +482,70 @@ func TestContractManifestGroups(t *testing.T) { }) t.Run("invalid sender", func(t *testing.T) { e.RunWithError(t, "neo-go", "contract", "manifest", "add-group", - "--wallet", testWalletPath, "--address", testWalletAccount, + "--wallet", testcli.TestWalletPath, "--address", testcli.TestWalletAccount, "--sender", "not-a-sender") }) t.Run("invalid NEF file", func(t *testing.T) { e.RunWithError(t, "neo-go", "contract", "manifest", "add-group", - "--wallet", testWalletPath, "--address", testWalletAccount, - "--sender", testWalletAccount, "--nef", tmpDir) + "--wallet", testcli.TestWalletPath, "--address", testcli.TestWalletAccount, + "--sender", testcli.TestWalletAccount, "--nef", tmpDir) }) t.Run("corrupted NEF file", func(t *testing.T) { f := filepath.Join(tmpDir, "invalid.nef") require.NoError(t, os.WriteFile(f, []byte{1, 2, 3}, os.ModePerm)) e.RunWithError(t, "neo-go", "contract", "manifest", "add-group", - "--wallet", testWalletPath, "--address", testWalletAccount, - "--sender", testWalletAccount, "--nef", f) + "--wallet", testcli.TestWalletPath, "--address", testcli.TestWalletAccount, + "--sender", testcli.TestWalletAccount, "--nef", f) }) t.Run("invalid manifest file", func(t *testing.T) { e.RunWithError(t, "neo-go", "contract", "manifest", "add-group", - "--wallet", testWalletPath, "--address", testWalletAccount, - "--sender", testWalletAccount, "--nef", nefName, + "--wallet", testcli.TestWalletPath, "--address", testcli.TestWalletAccount, + "--sender", testcli.TestWalletAccount, "--nef", nefName, "--manifest", tmpDir) }) t.Run("corrupted manifest file", func(t *testing.T) { f := filepath.Join(tmpDir, "invalid.manifest.json") require.NoError(t, os.WriteFile(f, []byte{1, 2, 3}, os.ModePerm)) e.RunWithError(t, "neo-go", "contract", "manifest", "add-group", - "--wallet", testWalletPath, "--address", testWalletAccount, - "--sender", testWalletAccount, "--nef", nefName, + "--wallet", testcli.TestWalletPath, "--address", testcli.TestWalletAccount, + "--sender", testcli.TestWalletAccount, "--nef", nefName, "--manifest", f) }) t.Run("unknown account", func(t *testing.T) { e.RunWithError(t, "neo-go", "contract", "manifest", "add-group", - "--wallet", testWalletPath, "--address", util.Uint160{}.StringLE(), - "--sender", testWalletAccount, "--nef", nefName, + "--wallet", testcli.TestWalletPath, "--address", util.Uint160{}.StringLE(), + "--sender", testcli.TestWalletAccount, "--nef", nefName, "--manifest", manifestName) }) cmd := []string{"neo-go", "contract", "manifest", "add-group", "--nef", nefName, "--manifest", manifestName} t.Run("excessive parameters", func(t *testing.T) { - e.RunWithError(t, append(cmd, "--wallet", testWalletPath, - "--sender", testWalletAccount, "--address", testWalletAccount, "something")...) + e.RunWithError(t, append(cmd, "--wallet", testcli.TestWalletPath, + "--sender", testcli.TestWalletAccount, "--address", testcli.TestWalletAccount, "something")...) }) e.In.WriteString("testpass\r") - e.Run(t, append(cmd, "--wallet", testWalletPath, - "--sender", testWalletAccount, "--address", testWalletAccount)...) + e.Run(t, append(cmd, "--wallet", testcli.TestWalletPath, + "--sender", testcli.TestWalletAccount, "--address", testcli.TestWalletAccount)...) e.In.WriteString("testpass\r") // should override signature with the previous sender - e.Run(t, append(cmd, "--wallet", testWalletPath, - "--sender", validatorAddr, "--address", testWalletAccount)...) + e.Run(t, append(cmd, "--wallet", testcli.TestWalletPath, + "--sender", testcli.ValidatorAddr, "--address", testcli.TestWalletAccount)...) - e.In.WriteString("one\r") + e.In.WriteString(testcli.ValidatorPass + "\r") e.Run(t, "neo-go", "contract", "deploy", "--rpc-endpoint", "http://"+e.RPC.Addr, "--in", nefName, "--manifest", manifestName, "--force", - "--wallet", validatorWallet, "--address", validatorAddr) + "--wallet", testcli.ValidatorWallet, "--address", testcli.ValidatorAddr) } -func deployVerifyContract(t *testing.T, e *executor) util.Uint160 { - return deployContract(t, e, "testdata/verify.go", "testdata/verify.yml", validatorWallet, validatorAddr, "one") -} - -func deployContract(t *testing.T, e *executor, inPath, configPath, wallet, address, pass string) util.Uint160 { - tmpDir := t.TempDir() - nefName := filepath.Join(tmpDir, "contract.nef") - manifestName := filepath.Join(tmpDir, "contract.manifest.json") - e.Run(t, "neo-go", "contract", "compile", - "--in", inPath, - "--config", configPath, - "--out", nefName, "--manifest", manifestName) - e.In.WriteString(pass + "\r") - e.Run(t, "neo-go", "contract", "deploy", - "--rpc-endpoint", "http://"+e.RPC.Addr, - "--wallet", wallet, "--address", address, - "--force", - "--in", nefName, "--manifest", manifestName) - e.checkTxPersisted(t, "Sent invocation transaction ") - line, err := e.Out.ReadString('\n') - require.NoError(t, err) - line = strings.TrimSpace(strings.TrimPrefix(line, "Contract: ")) - h, err := util.Uint160DecodeStringLE(line) - require.NoError(t, err) - return h +func deployVerifyContract(t *testing.T, e *testcli.Executor) util.Uint160 { + return testcli.DeployContract(t, e, "testdata/verify.go", "testdata/verify.yml", testcli.ValidatorWallet, testcli.ValidatorAddr, testcli.ValidatorPass) } func TestContract_TestInvokeScript(t *testing.T) { - e := newExecutor(t, true) + e := testcli.NewExecutor(t, true) tmpDir := t.TempDir() badNef := filepath.Join(tmpDir, "invalid.nef") goodNef := filepath.Join(tmpDir, "deploy.nef") @@ -638,7 +616,7 @@ func TestContract_TestInvokeScript(t *testing.T) { } func TestComlileAndInvokeFunction(t *testing.T) { - e := newExecutor(t, true) + e := testcli.NewExecutor(t, true) // For proper nef generation. config.Version = "0.90.0-test" @@ -654,18 +632,18 @@ func TestComlileAndInvokeFunction(t *testing.T) { tmp := t.TempDir() configPath := filepath.Join(tmp, "config.yaml") cfg := config.Wallet{ - Path: validatorWallet, - Password: "one", + Path: testcli.ValidatorWallet, + Password: testcli.ValidatorPass, } yml, err := yaml.Marshal(cfg) require.NoError(t, err) require.NoError(t, os.WriteFile(configPath, yml, 0666)) e.Run(t, "neo-go", "contract", "deploy", "--rpc-endpoint", "http://"+e.RPC.Addr, "--force", - "--wallet-config", configPath, "--address", validatorAddr, + "--wallet-config", configPath, "--address", testcli.ValidatorAddr, "--in", nefName, "--manifest", manifestName) - e.checkTxPersisted(t, "Sent invocation transaction ") + e.CheckTxPersisted(t, "Sent invocation transaction ") line, err := e.Out.ReadString('\n') require.NoError(t, err) line = strings.TrimSpace(strings.TrimPrefix(line, "Contract: ")) @@ -679,9 +657,9 @@ func TestComlileAndInvokeFunction(t *testing.T) { "--manifest", manifestName) e.Run(t, "neo-go", "contract", "calc-hash", - "--sender", validatorAddr, "--in", nefName, + "--sender", testcli.ValidatorAddr, "--in", nefName, "--manifest", manifestName) - e.checkNextLine(t, h.StringLE()) + e.CheckNextLine(t, h.StringLE()) }) cmd := []string{"neo-go", "contract", "testinvokefunction", @@ -746,28 +724,28 @@ func TestComlileAndInvokeFunction(t *testing.T) { e.RunWithError(t, cmd...) }) t.Run("non-existent address", func(t *testing.T) { - cmd := append(cmd, "--wallet", validatorWallet, + cmd := append(cmd, "--wallet", testcli.ValidatorWallet, "--address", random.Uint160().StringLE(), h.StringLE(), "getValue") e.RunWithError(t, cmd...) }) t.Run("invalid password", func(t *testing.T) { e.In.WriteString("invalid_password\r") - cmd := append(cmd, "--wallet", validatorWallet, + cmd := append(cmd, "--wallet", testcli.ValidatorWallet, h.StringLE(), "getValue") e.RunWithError(t, cmd...) }) t.Run("good: default address", func(t *testing.T) { e.In.WriteString("one\r") e.In.WriteString("y\r") - e.Run(t, append(cmd, "--wallet", validatorWallet, h.StringLE(), "getValue")...) + e.Run(t, append(cmd, "--wallet", testcli.ValidatorWallet, h.StringLE(), "getValue")...) }) t.Run("good: from wallet config", func(t *testing.T) { e.In.WriteString("y\r") e.Run(t, append(cmd, "--wallet-config", configPath, h.StringLE(), "getValue")...) }) - cmd = append(cmd, "--wallet", validatorWallet, "--address", validatorAddr) + cmd = append(cmd, "--wallet", testcli.ValidatorWallet, "--address", testcli.ValidatorAddr) t.Run("cancelled", func(t *testing.T) { e.In.WriteString("one\r") e.In.WriteString("n\r") @@ -792,7 +770,7 @@ func TestComlileAndInvokeFunction(t *testing.T) { e.In.WriteString("one\r") e.In.WriteString("y\r") e.Run(t, append(cmd, h.StringLE(), "getValue", - "--", validatorAddr, hVerify.StringLE())...) + "--", testcli.ValidatorAddr, hVerify.StringLE())...) }) }) @@ -802,7 +780,7 @@ func TestComlileAndInvokeFunction(t *testing.T) { cmd = []string{"neo-go", "contract", "invokefunction", "--rpc-endpoint", "http://" + e.RPC.Addr, "--out", txout, - "--wallet", validatorWallet, "--address", validatorAddr, + "--wallet", testcli.ValidatorWallet, "--address", testcli.ValidatorAddr, } t.Run("without cosigner", func(t *testing.T) { @@ -813,15 +791,15 @@ func TestComlileAndInvokeFunction(t *testing.T) { t.Run("with cosigner", func(t *testing.T) { t.Run("cosigner is sender (none)", func(t *testing.T) { e.In.WriteString("one\r") - e.RunWithError(t, append(cmd, h.StringLE(), "checkSenderWitness", "--", validatorAddr+":None")...) + e.RunWithError(t, append(cmd, h.StringLE(), "checkSenderWitness", "--", testcli.ValidatorAddr+":None")...) }) t.Run("cosigner is sender (customcontract)", func(t *testing.T) { e.In.WriteString("one\r") - e.Run(t, append(cmd, h.StringLE(), "checkSenderWitness", "--", validatorAddr+":CustomContracts:"+h.StringLE())...) + e.Run(t, append(cmd, h.StringLE(), "checkSenderWitness", "--", testcli.ValidatorAddr+":CustomContracts:"+h.StringLE())...) }) t.Run("cosigner is sender (global)", func(t *testing.T) { e.In.WriteString("one\r") - e.Run(t, append(cmd, h.StringLE(), "checkSenderWitness", "--", validatorAddr+":Global")...) + e.Run(t, append(cmd, h.StringLE(), "checkSenderWitness", "--", testcli.ValidatorAddr+":Global")...) }) acc, err := wallet.NewAccount() @@ -839,7 +817,7 @@ func TestComlileAndInvokeFunction(t *testing.T) { t.Run("good", func(t *testing.T) { e.In.WriteString("one\r") - e.Run(t, append(cmd, hVerify.StringLE(), "verify", "--", multisigAddr)...) + e.Run(t, append(cmd, hVerify.StringLE(), "verify", "--", testcli.MultisigAddr)...) }) }) @@ -924,13 +902,13 @@ func TestComlileAndInvokeFunction(t *testing.T) { e.In.WriteString("one\r") e.Run(t, "neo-go", "contract", "invokefunction", "--rpc-endpoint", "http://"+e.RPC.Addr, - "--wallet", validatorWallet, "--address", validatorAddr, + "--wallet", testcli.ValidatorWallet, "--address", testcli.ValidatorAddr, "--force", h.StringLE(), "update", "bytes:"+hex.EncodeToString(rawNef), "bytes:"+hex.EncodeToString(rawManifest), ) - e.checkTxPersisted(t, "Sent invocation transaction ") + e.CheckTxPersisted(t, "Sent invocation transaction ") indexAfterUpdate = e.Chain.BlockHeight() e.In.WriteString("one\r") @@ -970,7 +948,7 @@ func TestComlileAndInvokeFunction(t *testing.T) { } func TestContractInspect(t *testing.T) { - e := newExecutor(t, false) + e := testcli.NewExecutor(t, false) // For proper nef generation. config.Version = "0.90.0-test" @@ -1004,14 +982,14 @@ func TestContractInspect(t *testing.T) { func TestCompileExamples(t *testing.T) { tmpDir := t.TempDir() - const examplePath = "../examples" + const examplePath = "../../examples" infos, err := os.ReadDir(examplePath) require.NoError(t, err) // For proper nef generation. config.Version = "0.90.0-test" - e := newExecutor(t, false) + e := testcli.NewExecutor(t, false) for _, info := range infos { if !info.IsDir() { diff --git a/cli/testdata/deploy/main.go b/cli/smartcontract/testdata/deploy/main.go similarity index 96% rename from cli/testdata/deploy/main.go rename to cli/smartcontract/testdata/deploy/main.go index b0b83f588..42bf4c06f 100644 --- a/cli/testdata/deploy/main.go +++ b/cli/smartcontract/testdata/deploy/main.go @@ -1,7 +1,7 @@ package deploy import ( - "github.com/nspcc-dev/neo-go/cli/testdata/deploy/sub" + "github.com/nspcc-dev/neo-go/cli/smartcontract/testdata/deploy/sub" "github.com/nspcc-dev/neo-go/pkg/interop" "github.com/nspcc-dev/neo-go/pkg/interop/contract" "github.com/nspcc-dev/neo-go/pkg/interop/iterator" diff --git a/cli/testdata/deploy/neo-go.yml b/cli/smartcontract/testdata/deploy/neo-go.yml similarity index 100% rename from cli/testdata/deploy/neo-go.yml rename to cli/smartcontract/testdata/deploy/neo-go.yml diff --git a/cli/testdata/deploy/sub/put.go b/cli/smartcontract/testdata/deploy/sub/put.go similarity index 100% rename from cli/testdata/deploy/sub/put.go rename to cli/smartcontract/testdata/deploy/sub/put.go diff --git a/cli/testdata/deploy/updated.go b/cli/smartcontract/testdata/deploy/updated.go similarity index 100% rename from cli/testdata/deploy/updated.go rename to cli/smartcontract/testdata/deploy/updated.go diff --git a/cli/testdata/invalid1/invalid.go b/cli/smartcontract/testdata/invalid1/invalid.go similarity index 100% rename from cli/testdata/invalid1/invalid.go rename to cli/smartcontract/testdata/invalid1/invalid.go diff --git a/cli/testdata/invalid1/invalid.yml b/cli/smartcontract/testdata/invalid1/invalid.yml similarity index 100% rename from cli/testdata/invalid1/invalid.yml rename to cli/smartcontract/testdata/invalid1/invalid.yml diff --git a/cli/testdata/invalid2/invalid.go b/cli/smartcontract/testdata/invalid2/invalid.go similarity index 100% rename from cli/testdata/invalid2/invalid.go rename to cli/smartcontract/testdata/invalid2/invalid.go diff --git a/cli/testdata/invalid2/invalid.yml b/cli/smartcontract/testdata/invalid2/invalid.yml similarity index 100% rename from cli/testdata/invalid2/invalid.yml rename to cli/smartcontract/testdata/invalid2/invalid.yml diff --git a/cli/testdata/invalid3/invalid.go b/cli/smartcontract/testdata/invalid3/invalid.go similarity index 100% rename from cli/testdata/invalid3/invalid.go rename to cli/smartcontract/testdata/invalid3/invalid.go diff --git a/cli/testdata/invalid3/invalid.yml b/cli/smartcontract/testdata/invalid3/invalid.yml similarity index 100% rename from cli/testdata/invalid3/invalid.yml rename to cli/smartcontract/testdata/invalid3/invalid.yml diff --git a/cli/testdata/invalid4/invalid.go b/cli/smartcontract/testdata/invalid4/invalid.go similarity index 100% rename from cli/testdata/invalid4/invalid.go rename to cli/smartcontract/testdata/invalid4/invalid.go diff --git a/cli/testdata/invalid4/invalid.yml b/cli/smartcontract/testdata/invalid4/invalid.yml similarity index 100% rename from cli/testdata/invalid4/invalid.yml rename to cli/smartcontract/testdata/invalid4/invalid.yml diff --git a/cli/testdata/verify.go b/cli/smartcontract/testdata/verify.go similarity index 100% rename from cli/testdata/verify.go rename to cli/smartcontract/testdata/verify.go diff --git a/cli/testdata/verify.manifest.json b/cli/smartcontract/testdata/verify.manifest.json similarity index 100% rename from cli/testdata/verify.manifest.json rename to cli/smartcontract/testdata/verify.manifest.json diff --git a/cli/testdata/verify.nef b/cli/smartcontract/testdata/verify.nef similarity index 100% rename from cli/testdata/verify.nef rename to cli/smartcontract/testdata/verify.nef diff --git a/cli/testdata/verify.yml b/cli/smartcontract/testdata/verify.yml similarity index 100% rename from cli/testdata/verify.yml rename to cli/smartcontract/testdata/verify.yml diff --git a/cli/util/util_test.go b/cli/util/util_test.go new file mode 100644 index 000000000..e2f073465 --- /dev/null +++ b/cli/util/util_test.go @@ -0,0 +1,26 @@ +package util_test + +import ( + "testing" + + "github.com/nspcc-dev/neo-go/internal/testcli" + "github.com/nspcc-dev/neo-go/pkg/util" +) + +func TestUtilConvert(t *testing.T) { + e := testcli.NewExecutor(t, false) + + e.Run(t, "neo-go", "util", "convert", util.Uint160{1, 2, 3}.StringLE()) + e.CheckNextLine(t, "f975") // int to hex + e.CheckNextLine(t, "\\+XU=") // int to base64 + e.CheckNextLine(t, "NKuyBkoGdZZSLyPbJEetheRhMrGSCQx7YL") // BE to address + e.CheckNextLine(t, "NL1JGiyJXdTkvFksXbFxgLJcWLj8Ewe7HW") // LE to address + e.CheckNextLine(t, "Hex to String") // hex to string + e.CheckNextLine(t, "5753853598078696051256155186041784866529345536") // hex to int + e.CheckNextLine(t, "0102030000000000000000000000000000000000") // swap endianness + e.CheckNextLine(t, "Base64 to String") // base64 to string + e.CheckNextLine(t, "368753434210909009569191652203865891677393101439813372294890211308228051") // base64 to bigint + e.CheckNextLine(t, "30303030303030303030303030303030303030303030303030303030303030303030303330323031") // string to hex + e.CheckNextLine(t, "MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAzMDIwMQ==") // string to base64 + e.CheckEOF(t) +} diff --git a/cli/util_test.go b/cli/util_test.go deleted file mode 100644 index e845e7f37..000000000 --- a/cli/util_test.go +++ /dev/null @@ -1,25 +0,0 @@ -package main - -import ( - "testing" - - "github.com/nspcc-dev/neo-go/pkg/util" -) - -func TestUtilConvert(t *testing.T) { - e := newExecutor(t, false) - - e.Run(t, "neo-go", "util", "convert", util.Uint160{1, 2, 3}.StringLE()) - e.checkNextLine(t, "f975") // int to hex - e.checkNextLine(t, "\\+XU=") // int to base64 - e.checkNextLine(t, "NKuyBkoGdZZSLyPbJEetheRhMrGSCQx7YL") // BE to address - e.checkNextLine(t, "NL1JGiyJXdTkvFksXbFxgLJcWLj8Ewe7HW") // LE to address - e.checkNextLine(t, "Hex to String") // hex to string - e.checkNextLine(t, "5753853598078696051256155186041784866529345536") // hex to int - e.checkNextLine(t, "0102030000000000000000000000000000000000") // swap endianness - e.checkNextLine(t, "Base64 to String") // base64 to string - e.checkNextLine(t, "368753434210909009569191652203865891677393101439813372294890211308228051") // base64 to bigint - e.checkNextLine(t, "30303030303030303030303030303030303030303030303030303030303030303030303330323031") // string to hex - e.checkNextLine(t, "MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAzMDIwMQ==") // string to base64 - e.checkEOF(t) -} diff --git a/cli/candidate_test.go b/cli/wallet/candidate_test.go similarity index 59% rename from cli/candidate_test.go rename to cli/wallet/candidate_test.go index 077c46c07..9f59f870b 100644 --- a/cli/candidate_test.go +++ b/cli/wallet/candidate_test.go @@ -1,4 +1,4 @@ -package main +package wallet_test import ( "encoding/hex" @@ -6,6 +6,7 @@ import ( "strconv" "testing" + "github.com/nspcc-dev/neo-go/internal/testcli" "github.com/stretchr/testify/require" ) @@ -13,135 +14,137 @@ import ( // We don't create a new account here, because chain will // stop working after validator will change. func TestRegisterCandidate(t *testing.T) { - e := newExecutor(t, true) + e := testcli.NewExecutor(t, true) - validatorHex := hex.EncodeToString(validatorPriv.PublicKey().Bytes()) + validatorAddress := testcli.ValidatorPriv.Address() + validatorPublic := testcli.ValidatorPriv.PublicKey() + validatorHex := hex.EncodeToString(validatorPublic.Bytes()) e.In.WriteString("one\r") e.Run(t, "neo-go", "wallet", "nep17", "multitransfer", "--rpc-endpoint", "http://"+e.RPC.Addr, - "--wallet", validatorWallet, - "--from", validatorAddr, + "--wallet", testcli.ValidatorWallet, + "--from", testcli.ValidatorAddr, "--force", - "NEO:"+validatorPriv.Address()+":10", - "GAS:"+validatorPriv.Address()+":10000") - e.checkTxPersisted(t) + "NEO:"+validatorAddress+":10", + "GAS:"+validatorAddress+":10000") + e.CheckTxPersisted(t) e.Run(t, "neo-go", "query", "committee", "--rpc-endpoint", "http://"+e.RPC.Addr) - e.checkNextLine(t, "^\\s*"+validatorHex) + e.CheckNextLine(t, "^\\s*"+validatorHex) e.Run(t, "neo-go", "query", "candidates", "--rpc-endpoint", "http://"+e.RPC.Addr) - e.checkNextLine(t, "^\\s*Key.+$") // Header. - e.checkEOF(t) + e.CheckNextLine(t, "^\\s*Key.+$") // Header. + e.CheckEOF(t) // missing address e.RunWithError(t, "neo-go", "wallet", "candidate", "register", "--rpc-endpoint", "http://"+e.RPC.Addr, - "--wallet", validatorWallet) + "--wallet", testcli.ValidatorWallet) // additional parameter e.RunWithError(t, "neo-go", "wallet", "candidate", "register", "--rpc-endpoint", "http://"+e.RPC.Addr, - "--wallet", validatorWallet, - "--address", validatorPriv.Address(), + "--wallet", testcli.ValidatorWallet, + "--address", validatorAddress, "error") e.In.WriteString("one\r") e.Run(t, "neo-go", "wallet", "candidate", "register", "--rpc-endpoint", "http://"+e.RPC.Addr, - "--wallet", validatorWallet, - "--address", validatorPriv.Address()) - e.checkTxPersisted(t) + "--wallet", testcli.ValidatorWallet, + "--address", validatorAddress) + e.CheckTxPersisted(t) vs, err := e.Chain.GetEnrollments() require.NoError(t, err) require.Equal(t, 1, len(vs)) - require.Equal(t, validatorPriv.PublicKey(), vs[0].Key) + require.Equal(t, validatorPublic, vs[0].Key) require.Equal(t, big.NewInt(0), vs[0].Votes) t.Run("VoteUnvote", func(t *testing.T) { // positional instead of a flag. e.RunWithError(t, "neo-go", "wallet", "candidate", "vote", "--rpc-endpoint", "http://"+e.RPC.Addr, - "--wallet", validatorWallet, - "--address", validatorPriv.Address(), + "--wallet", testcli.ValidatorWallet, + "--address", validatorAddress, validatorHex) // not "--candidate hex", but "hex". e.In.WriteString("one\r") e.Run(t, "neo-go", "wallet", "candidate", "vote", "--rpc-endpoint", "http://"+e.RPC.Addr, - "--wallet", validatorWallet, - "--address", validatorPriv.Address(), + "--wallet", testcli.ValidatorWallet, + "--address", validatorAddress, "--candidate", validatorHex) - _, index := e.checkTxPersisted(t) + _, index := e.CheckTxPersisted(t) vs, err = e.Chain.GetEnrollments() require.Equal(t, 1, len(vs)) - require.Equal(t, validatorPriv.PublicKey(), vs[0].Key) - b, _ := e.Chain.GetGoverningTokenBalance(validatorPriv.GetScriptHash()) + require.Equal(t, validatorPublic, vs[0].Key) + b, _ := e.Chain.GetGoverningTokenBalance(testcli.ValidatorPriv.GetScriptHash()) require.Equal(t, b, vs[0].Votes) e.Run(t, "neo-go", "query", "committee", "--rpc-endpoint", "http://"+e.RPC.Addr) - e.checkNextLine(t, "^\\s*"+validatorHex) + e.CheckNextLine(t, "^\\s*"+validatorHex) e.Run(t, "neo-go", "query", "candidates", "--rpc-endpoint", "http://"+e.RPC.Addr) - e.checkNextLine(t, "^\\s*Key.+$") // Header. - e.checkNextLine(t, "^\\s*"+validatorHex+"\\s*"+b.String()+"\\s*true\\s*true$") - e.checkEOF(t) + e.CheckNextLine(t, "^\\s*Key.+$") // Header. + e.CheckNextLine(t, "^\\s*"+validatorHex+"\\s*"+b.String()+"\\s*true\\s*true$") + e.CheckEOF(t) // check state e.Run(t, "neo-go", "query", "voter", "--rpc-endpoint", "http://"+e.RPC.Addr, - validatorPriv.Address()) - e.checkNextLine(t, "^\\s*Voted:\\s+"+validatorHex+"\\s+\\("+validatorPriv.Address()+"\\)$") - e.checkNextLine(t, "^\\s*Amount\\s*:\\s*"+b.String()+"$") - e.checkNextLine(t, "^\\s*Block\\s*:\\s*"+strconv.FormatUint(uint64(index), 10)) - e.checkEOF(t) + validatorAddress) + e.CheckNextLine(t, "^\\s*Voted:\\s+"+validatorHex+"\\s+\\("+validatorAddress+"\\)$") + e.CheckNextLine(t, "^\\s*Amount\\s*:\\s*"+b.String()+"$") + e.CheckNextLine(t, "^\\s*Block\\s*:\\s*"+strconv.FormatUint(uint64(index), 10)) + e.CheckEOF(t) // unvote e.In.WriteString("one\r") e.Run(t, "neo-go", "wallet", "candidate", "vote", "--rpc-endpoint", "http://"+e.RPC.Addr, - "--wallet", validatorWallet, - "--address", validatorPriv.Address()) - _, index = e.checkTxPersisted(t) + "--wallet", testcli.ValidatorWallet, + "--address", validatorAddress) + _, index = e.CheckTxPersisted(t) vs, err = e.Chain.GetEnrollments() require.Equal(t, 1, len(vs)) - require.Equal(t, validatorPriv.PublicKey(), vs[0].Key) + require.Equal(t, validatorPublic, vs[0].Key) require.Equal(t, big.NewInt(0), vs[0].Votes) // check state e.Run(t, "neo-go", "query", "voter", "--rpc-endpoint", "http://"+e.RPC.Addr, - validatorPriv.Address()) - e.checkNextLine(t, "^\\s*Voted:\\s+"+"null") // no vote. - e.checkNextLine(t, "^\\s*Amount\\s*:\\s*"+b.String()+"$") - e.checkNextLine(t, "^\\s*Block\\s*:\\s*"+strconv.FormatUint(uint64(index), 10)) - e.checkEOF(t) + validatorAddress) + e.CheckNextLine(t, "^\\s*Voted:\\s+"+"null") // no vote. + e.CheckNextLine(t, "^\\s*Amount\\s*:\\s*"+b.String()+"$") + e.CheckNextLine(t, "^\\s*Block\\s*:\\s*"+strconv.FormatUint(uint64(index), 10)) + e.CheckEOF(t) }) // missing address e.RunWithError(t, "neo-go", "wallet", "candidate", "unregister", "--rpc-endpoint", "http://"+e.RPC.Addr, - "--wallet", validatorWallet) + "--wallet", testcli.ValidatorWallet) // additional argument e.RunWithError(t, "neo-go", "wallet", "candidate", "unregister", "--rpc-endpoint", "http://"+e.RPC.Addr, - "--wallet", validatorWallet, - "--address", validatorPriv.Address(), + "--wallet", testcli.ValidatorWallet, + "--address", validatorAddress, "argument") e.In.WriteString("one\r") e.Run(t, "neo-go", "wallet", "candidate", "unregister", "--rpc-endpoint", "http://"+e.RPC.Addr, - "--wallet", validatorWallet, - "--address", validatorPriv.Address()) - e.checkTxPersisted(t) + "--wallet", testcli.ValidatorWallet, + "--address", validatorAddress) + e.CheckTxPersisted(t) vs, err = e.Chain.GetEnrollments() require.Equal(t, 0, len(vs)) @@ -149,7 +152,7 @@ func TestRegisterCandidate(t *testing.T) { // query voter: missing address e.RunWithError(t, "neo-go", "query", "voter") // Excessive parameters. - e.RunWithError(t, "neo-go", "query", "voter", "--rpc-endpoint", "http://"+e.RPC.Addr, validatorPriv.Address(), validatorPriv.Address()) + e.RunWithError(t, "neo-go", "query", "voter", "--rpc-endpoint", "http://"+e.RPC.Addr, validatorAddress, validatorAddress) e.RunWithError(t, "neo-go", "query", "committee", "--rpc-endpoint", "http://"+e.RPC.Addr, "something") e.RunWithError(t, "neo-go", "query", "candidates", "--rpc-endpoint", "http://"+e.RPC.Addr, "something") } diff --git a/cli/multisig_test.go b/cli/wallet/multisig_test.go similarity index 90% rename from cli/multisig_test.go rename to cli/wallet/multisig_test.go index 742822940..0eb3a2219 100644 --- a/cli/multisig_test.go +++ b/cli/wallet/multisig_test.go @@ -1,4 +1,4 @@ -package main +package wallet_test import ( "encoding/hex" @@ -9,6 +9,7 @@ import ( "path/filepath" "testing" + "github.com/nspcc-dev/neo-go/internal/testcli" "github.com/nspcc-dev/neo-go/pkg/crypto/hash" "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/encoding/address" @@ -24,9 +25,9 @@ import ( // 1. Transfer funds to a created multisig address. // 2. Transfer from multisig to another account. func TestSignMultisigTx(t *testing.T) { - e := newExecutor(t, true) + e := testcli.NewExecutor(t, true) - privs, pubs := generateKeys(t, 3) + privs, pubs := testcli.GenerateKeys(t, 3) script, err := smartcontract.CreateMultiSigRedeemScript(2, pubs) require.NoError(t, err) multisigHash := hash.Hash160(script) @@ -55,12 +56,12 @@ func TestSignMultisigTx(t *testing.T) { e.In.WriteString("one\r") e.Run(t, "neo-go", "wallet", "nep17", "multitransfer", "--rpc-endpoint", "http://"+e.RPC.Addr, - "--wallet", validatorWallet, - "--from", validatorAddr, + "--wallet", testcli.ValidatorWallet, + "--from", testcli.ValidatorAddr, "--force", "NEO:"+multisigAddr+":4", "GAS:"+multisigAddr+":1") - e.checkTxPersisted(t) + e.CheckTxPersisted(t) // Sign and transfer funds to another account. priv, err := keys.NewPrivateKey() @@ -145,8 +146,8 @@ func TestSignMultisigTx(t *testing.T) { t.Run("no invoke", func(t *testing.T) { e.Run(t, "neo-go", "util", "txdump", txPath) - e.checkTxTestInvokeOutput(t, 11) - e.checkEOF(t) + e.CheckTxTestInvokeOutput(t, 11) + e.CheckEOF(t) }) t.Run("excessive parameters", func(t *testing.T) { @@ -157,7 +158,7 @@ func TestSignMultisigTx(t *testing.T) { e.Run(t, "neo-go", "util", "txdump", "--rpc-endpoint", "http://"+e.RPC.Addr, txPath) - e.checkTxTestInvokeOutput(t, 11) + e.CheckTxTestInvokeOutput(t, 11) res := new(result.Invoke) require.NoError(t, json.Unmarshal(e.Out.Bytes(), res)) require.Equal(t, vmstate.Halt.String(), res.State, res.FaultException) @@ -196,7 +197,7 @@ func TestSignMultisigTx(t *testing.T) { "--rpc-endpoint", "http://"+e.RPC.Addr, "--wallet", wallet2Path, "--address", multisigAddr, "--in", txPath, "--out", txPath) - e.checkTxPersisted(t) + e.CheckTxPersisted(t) }) t.Run("double-sign", func(t *testing.T) { e.In.WriteString("pass\r") @@ -251,7 +252,7 @@ func TestSignMultisigTx(t *testing.T) { "--rpc-endpoint", "http://"+e.RPC.Addr, "--wallet", wallet1Path, "--address", address.Uint160ToString(h), "--in", txPath, "--out", txPath) - tx, _ := e.checkTxPersisted(t) + tx, _ := e.CheckTxPersisted(t) require.Equal(t, 3, len(tx.Signers)) b, _ := e.Chain.GetGoverningTokenBalance(priv.GetScriptHash()) @@ -261,20 +262,6 @@ func TestSignMultisigTx(t *testing.T) { }) } -func (e *executor) checkTxTestInvokeOutput(t *testing.T, scriptSize int) { - e.checkNextLine(t, `Hash:\s+`) - e.checkNextLine(t, `OnChain:\s+false`) - e.checkNextLine(t, `ValidUntil:\s+\d+`) - e.checkNextLine(t, `Signer:\s+\w+`) - e.checkNextLine(t, `SystemFee:\s+(\d|\.)+`) - e.checkNextLine(t, `NetworkFee:\s+(\d|\.)+`) - e.checkNextLine(t, `Script:\s+\w+`) - e.checkScriptDump(t, scriptSize) -} - -func (e *executor) checkScriptDump(t *testing.T, scriptSize int) { - e.checkNextLine(t, `INDEX\s+`) - for i := 0; i < scriptSize; i++ { - e.checkNextLine(t, `\d+\s+\w+`) - } +func deployVerifyContract(t *testing.T, e *testcli.Executor) util.Uint160 { + return testcli.DeployContract(t, e, "../smartcontract/testdata/verify.go", "../smartcontract/testdata/verify.yml", testcli.ValidatorWallet, testcli.ValidatorAddr, testcli.ValidatorPass) } diff --git a/cli/testdata/wallets/testwallet_NEO2.json b/cli/wallet/testdata/testwallet_NEO2.json similarity index 100% rename from cli/testdata/wallets/testwallet_NEO2.json rename to cli/wallet/testdata/testwallet_NEO2.json diff --git a/cli/testdata/wallets/testwallet_NEO3.json b/cli/wallet/testdata/testwallet_NEO3.json similarity index 100% rename from cli/testdata/wallets/testwallet_NEO3.json rename to cli/wallet/testdata/testwallet_NEO3.json diff --git a/cli/wallet_test.go b/cli/wallet/wallet_test.go similarity index 87% rename from cli/wallet_test.go rename to cli/wallet/wallet_test.go index d0393175c..db1601b5c 100644 --- a/cli/wallet_test.go +++ b/cli/wallet/wallet_test.go @@ -1,4 +1,4 @@ -package main +package wallet_test import ( "encoding/hex" @@ -10,6 +10,7 @@ import ( "testing" "github.com/chzyer/readline" + "github.com/nspcc-dev/neo-go/internal/testcli" "github.com/nspcc-dev/neo-go/pkg/config" "github.com/nspcc-dev/neo-go/pkg/crypto/hash" "github.com/nspcc-dev/neo-go/pkg/crypto/keys" @@ -23,7 +24,7 @@ import ( func TestWalletAccountRemove(t *testing.T) { tmpDir := t.TempDir() - e := newExecutor(t, false) + e := testcli.NewExecutor(t, false) walletPath := filepath.Join(tmpDir, "wallet.json") e.In.WriteString("acc1\r") @@ -71,7 +72,7 @@ func TestWalletAccountRemove(t *testing.T) { func TestWalletChangePassword(t *testing.T) { tmpDir := t.TempDir() - e := newExecutor(t, false) + e := testcli.NewExecutor(t, false) walletPath := filepath.Join(tmpDir, "wallet.json") e.In.WriteString("acc1\r") @@ -142,7 +143,7 @@ func TestWalletChangePassword(t *testing.T) { } func TestWalletInit(t *testing.T) { - e := newExecutor(t, false) + e := testcli.NewExecutor(t, false) t.Run("missing path", func(t *testing.T) { e.RunWithError(t, "neo-go", "wallet", "init") @@ -363,7 +364,7 @@ func TestWalletInit(t *testing.T) { "--wallet", walletPath, "--min", "2") }) - privs, pubs := generateKeys(t, 4) + privs, pubs := testcli.GenerateKeys(t, 4) cmd := []string{"neo-go", "wallet", "import-multisig", "--wallet", walletPath, "--min", "2"} @@ -423,94 +424,94 @@ func TestWalletInit(t *testing.T) { } func TestWalletExport(t *testing.T) { - e := newExecutor(t, false) + e := testcli.NewExecutor(t, false) t.Run("missing wallet", func(t *testing.T) { e.RunWithError(t, "neo-go", "wallet", "export") }) t.Run("invalid address", func(t *testing.T) { e.RunWithError(t, "neo-go", "wallet", "export", - "--wallet", validatorWallet, "not-an-address") + "--wallet", testcli.ValidatorWallet, "not-an-address") }) t.Run("Encrypted", func(t *testing.T) { e.Run(t, "neo-go", "wallet", "export", - "--wallet", validatorWallet, validatorAddr) + "--wallet", testcli.ValidatorWallet, testcli.ValidatorAddr) line, err := e.Out.ReadString('\n') require.NoError(t, err) - enc, err := keys.NEP2Encrypt(validatorPriv, "one", keys.ScryptParams{N: 2, R: 1, P: 1}) // these params used in validator wallet for better resources consumption + enc, err := keys.NEP2Encrypt(testcli.ValidatorPriv, "one", keys.ScryptParams{N: 2, R: 1, P: 1}) // these params used in validator wallet for better resources consumption require.NoError(t, err) require.Equal(t, enc, strings.TrimSpace(line)) }) t.Run("Decrypted", func(t *testing.T) { t.Run("NoAddress", func(t *testing.T) { e.RunWithError(t, "neo-go", "wallet", "export", - "--wallet", validatorWallet, "--decrypt") + "--wallet", testcli.ValidatorWallet, "--decrypt") }) t.Run("EOF reading password", func(t *testing.T) { e.RunWithError(t, "neo-go", "wallet", "export", - "--wallet", validatorWallet, "--decrypt", validatorAddr) + "--wallet", testcli.ValidatorWallet, "--decrypt", testcli.ValidatorAddr) }) t.Run("invalid password", func(t *testing.T) { e.In.WriteString("invalid_pass\r") e.RunWithError(t, "neo-go", "wallet", "export", - "--wallet", validatorWallet, "--decrypt", validatorAddr) + "--wallet", testcli.ValidatorWallet, "--decrypt", testcli.ValidatorAddr) }) e.In.WriteString("one\r") e.Run(t, "neo-go", "wallet", "export", - "--wallet", validatorWallet, "--decrypt", validatorAddr) + "--wallet", testcli.ValidatorWallet, "--decrypt", testcli.ValidatorAddr) line, err := e.Out.ReadString('\n') require.NoError(t, err) - require.Equal(t, validatorWIF, strings.TrimSpace(line)) + require.Equal(t, testcli.ValidatorWIF, strings.TrimSpace(line)) }) } func TestWalletClaimGas(t *testing.T) { - e := newExecutor(t, true) + e := testcli.NewExecutor(t, true) t.Run("missing wallet path", func(t *testing.T) { e.RunWithError(t, "neo-go", "wallet", "claim", "--rpc-endpoint", "http://"+e.RPC.Addr, - "--address", testWalletAccount) + "--address", testcli.TestWalletAccount) }) t.Run("missing address", func(t *testing.T) { e.RunWithError(t, "neo-go", "wallet", "claim", "--rpc-endpoint", "http://"+e.RPC.Addr, - "--wallet", testWalletPath) + "--wallet", testcli.TestWalletPath) }) t.Run("invalid address", func(t *testing.T) { e.RunWithError(t, "neo-go", "wallet", "claim", "--rpc-endpoint", "http://"+e.RPC.Addr, - "--wallet", testWalletPath, + "--wallet", testcli.TestWalletPath, "--address", util.Uint160{}.StringLE()) }) t.Run("missing endpoint", func(t *testing.T) { e.In.WriteString("testpass\r") e.RunWithError(t, "neo-go", "wallet", "claim", - "--wallet", testWalletPath, - "--address", testWalletAccount) + "--wallet", testcli.TestWalletPath, + "--address", testcli.TestWalletAccount) }) t.Run("insufficient funds", func(t *testing.T) { e.In.WriteString("testpass\r") e.RunWithError(t, "neo-go", "wallet", "claim", "--rpc-endpoint", "http://"+e.RPC.Addr, - "--wallet", testWalletPath, - "--address", testWalletAccount) + "--wallet", testcli.TestWalletPath, + "--address", testcli.TestWalletAccount) }) args := []string{ "neo-go", "wallet", "nep17", "multitransfer", "--rpc-endpoint", "http://" + e.RPC.Addr, - "--wallet", validatorWallet, - "--from", validatorAddr, + "--wallet", testcli.ValidatorWallet, + "--from", testcli.ValidatorAddr, "--force", - "NEO:" + testWalletAccount + ":1000", - "GAS:" + testWalletAccount + ":1000", // for tx send + "NEO:" + testcli.TestWalletAccount + ":1000", + "GAS:" + testcli.TestWalletAccount + ":1000", // for tx send } e.In.WriteString("one\r") e.Run(t, args...) - e.checkTxPersisted(t) + e.CheckTxPersisted(t) - h, err := address.StringToUint160(testWalletAccount) + h, err := address.StringToUint160(testcli.TestWalletAccount) require.NoError(t, err) balanceBefore := e.Chain.GetUtilityTokenBalance(h) @@ -522,9 +523,9 @@ func TestWalletClaimGas(t *testing.T) { e.In.WriteString("testpass\r") e.Run(t, "neo-go", "wallet", "claim", "--rpc-endpoint", "http://"+e.RPC.Addr, - "--wallet", testWalletPath, - "--address", testWalletAccount) - tx, height := e.checkTxPersisted(t) + "--wallet", testcli.TestWalletPath, + "--address", testcli.TestWalletAccount) + tx, height := e.CheckTxPersisted(t) balanceBefore.Sub(balanceBefore, big.NewInt(tx.NetworkFee+tx.SystemFee)) balanceBefore.Add(balanceBefore, cl) @@ -539,7 +540,7 @@ func TestWalletClaimGas(t *testing.T) { func TestWalletImportDeployed(t *testing.T) { tmpDir := t.TempDir() - e := newExecutor(t, true) + e := testcli.NewExecutor(t, true) h := deployVerifyContract(t, e) walletPath := filepath.Join(tmpDir, "wallet.json") @@ -606,11 +607,11 @@ func TestWalletImportDeployed(t *testing.T) { e.In.WriteString("one\r") e.Run(t, "neo-go", "wallet", "nep17", "multitransfer", "--rpc-endpoint", "http://"+e.RPC.Addr, - "--wallet", validatorWallet, "--from", validatorAddr, + "--wallet", testcli.ValidatorWallet, "--from", testcli.ValidatorAddr, "--force", "NEO:"+contractAddr+":10", "GAS:"+contractAddr+":10") - e.checkTxPersisted(t) + e.CheckTxPersisted(t) privTo, err := keys.NewPrivateKey() require.NoError(t, err) @@ -621,7 +622,7 @@ func TestWalletImportDeployed(t *testing.T) { "--wallet", walletPath, "--from", contractAddr, "--force", "--to", privTo.Address(), "--token", "NEO", "--amount", "1") - e.checkTxPersisted(t) + e.CheckTxPersisted(t) b, _ := e.Chain.GetGoverningTokenBalance(h) require.Equal(t, big.NewInt(9), b) @@ -631,7 +632,7 @@ func TestWalletImportDeployed(t *testing.T) { } func TestStripKeys(t *testing.T) { - e := newExecutor(t, true) + e := testcli.NewExecutor(t, true) tmpDir := t.TempDir() walletPath := filepath.Join(tmpDir, "wallet.json") e.In.WriteString("acc1\r") @@ -661,13 +662,13 @@ func TestStripKeys(t *testing.T) { } func TestOfflineSigning(t *testing.T) { - e := newExecutor(t, true) + e := testcli.NewExecutor(t, true) tmpDir := t.TempDir() walletPath := filepath.Join(tmpDir, "wallet.json") txPath := filepath.Join(tmpDir, "tx.json") // Copy wallet. - w, err := wallet.NewWalletFromFile(validatorWallet) + w, err := wallet.NewWalletFromFile(testcli.ValidatorWallet) require.NoError(t, err) jOut, err := w.JSON() require.NoError(t, err) @@ -680,7 +681,7 @@ func TestOfflineSigning(t *testing.T) { args := []string{"neo-go", "wallet", "nep17", "transfer", "--rpc-endpoint", "http://" + e.RPC.Addr, "--wallet", walletPath, - "--from", validatorAddr, + "--from", testcli.ValidatorAddr, "--to", w.Accounts[0].Address, "--token", "NEO", "--amount", "1", @@ -692,7 +693,7 @@ func TestOfflineSigning(t *testing.T) { e.Run(t, append(args, "--out", txPath)...) // It can't be signed with the original wallet. e.RunWithError(t, "neo-go", "wallet", "sign", - "--wallet", walletPath, "--address", validatorAddr, + "--wallet", walletPath, "--address", testcli.ValidatorAddr, "--in", txPath, "--out", txPath) t.Run("sendtx", func(t *testing.T) { // And it can't be sent. @@ -710,22 +711,22 @@ func TestOfflineSigning(t *testing.T) { // But it can be signed with a proper wallet. e.In.WriteString("one\r") e.Run(t, "neo-go", "wallet", "sign", - "--wallet", validatorWallet, "--address", validatorAddr, + "--wallet", testcli.ValidatorWallet, "--address", testcli.ValidatorAddr, "--in", txPath, "--out", txPath) // And then anyone can send (even via wallet sign). e.Run(t, "neo-go", "wallet", "sign", "--rpc-endpoint", "http://"+e.RPC.Addr, - "--wallet", walletPath, "--address", validatorAddr, + "--wallet", walletPath, "--address", testcli.ValidatorAddr, "--in", txPath) }) - e.checkTxPersisted(t) + e.CheckTxPersisted(t) t.Run("simple signature", func(t *testing.T) { simpleAddr := w.Accounts[0].Address args := []string{"neo-go", "wallet", "nep17", "transfer", "--rpc-endpoint", "http://" + e.RPC.Addr, "--wallet", walletPath, "--from", simpleAddr, - "--to", validatorAddr, + "--to", testcli.ValidatorAddr, "--token", "NEO", "--amount", "1", "--force", @@ -741,7 +742,7 @@ func TestOfflineSigning(t *testing.T) { // But can be with a proper one. e.In.WriteString("one\r") e.Run(t, "neo-go", "wallet", "sign", - "--wallet", validatorWallet, "--address", simpleAddr, + "--wallet", testcli.ValidatorWallet, "--address", simpleAddr, "--in", txPath, "--out", txPath) // Sending without an RPC node is not likely to succeed. e.RunWithError(t, "neo-go", "util", "sendtx", txPath) @@ -753,18 +754,18 @@ func TestOfflineSigning(t *testing.T) { } func TestWalletDump(t *testing.T) { - e := newExecutor(t, false) + e := testcli.NewExecutor(t, false) t.Run("missing wallet", func(t *testing.T) { e.RunWithError(t, "neo-go", "wallet", "dump") }) - cmd := []string{"neo-go", "wallet", "dump", "--wallet", testWalletPath} + cmd := []string{"neo-go", "wallet", "dump", "--wallet", testcli.TestWalletPath} e.Run(t, cmd...) rawStr := strings.TrimSpace(e.Out.String()) w := new(wallet.Wallet) require.NoError(t, json.Unmarshal([]byte(rawStr), w)) require.Equal(t, 1, len(w.Accounts)) - require.Equal(t, testWalletAccount, w.Accounts[0].Address) + require.Equal(t, testcli.TestWalletAccount, w.Accounts[0].Address) t.Run("with decrypt", func(t *testing.T) { cmd = append(cmd, "--decrypt") @@ -782,13 +783,13 @@ func TestWalletDump(t *testing.T) { w := new(wallet.Wallet) require.NoError(t, json.Unmarshal([]byte(rawStr), w)) require.Equal(t, 1, len(w.Accounts)) - require.Equal(t, testWalletAccount, w.Accounts[0].Address) + require.Equal(t, testcli.TestWalletAccount, w.Accounts[0].Address) }) t.Run("good, from wallet config", func(t *testing.T) { tmp := t.TempDir() configPath := filepath.Join(tmp, "config.yaml") cfg := config.Wallet{ - Path: testWalletPath, + Path: testcli.TestWalletPath, Password: "testpass", } res, err := yaml.Marshal(cfg) @@ -799,31 +800,31 @@ func TestWalletDump(t *testing.T) { w := new(wallet.Wallet) require.NoError(t, json.Unmarshal([]byte(rawStr), w)) require.Equal(t, 1, len(w.Accounts)) - require.Equal(t, testWalletAccount, w.Accounts[0].Address) + require.Equal(t, testcli.TestWalletAccount, w.Accounts[0].Address) }) }) } func TestWalletDumpKeys(t *testing.T) { - e := newExecutor(t, false) + e := testcli.NewExecutor(t, false) t.Run("missing wallet", func(t *testing.T) { e.RunWithError(t, "neo-go", "wallet", "dump-keys") }) - cmd := []string{"neo-go", "wallet", "dump-keys", "--wallet", validatorWallet} + cmd := []string{"neo-go", "wallet", "dump-keys", "--wallet", testcli.ValidatorWallet} pubRegex := "^0[23][a-hA-H0-9]{64}$" t.Run("all", func(t *testing.T) { e.Run(t, cmd...) - e.checkNextLine(t, "Nhfg3TbpwogLvDGVvAvqyThbsHgoSUKwtn") - e.checkNextLine(t, pubRegex) - e.checkNextLine(t, "^\\s*$") - e.checkNextLine(t, "NVTiAjNgagDkTr5HTzDmQP9kPwPHN5BgVq") + e.CheckNextLine(t, "Nhfg3TbpwogLvDGVvAvqyThbsHgoSUKwtn") + e.CheckNextLine(t, pubRegex) + e.CheckNextLine(t, "^\\s*$") + e.CheckNextLine(t, "NVTiAjNgagDkTr5HTzDmQP9kPwPHN5BgVq") for i := 0; i < 4; i++ { - e.checkNextLine(t, pubRegex) + e.CheckNextLine(t, pubRegex) } - e.checkNextLine(t, "^\\s*$") - e.checkNextLine(t, "NfgHwwTi3wHAS8aFAN243C5vGbkYDpqLHP") - e.checkNextLine(t, pubRegex) - e.checkEOF(t) + e.CheckNextLine(t, "^\\s*$") + e.CheckNextLine(t, "NfgHwwTi3wHAS8aFAN243C5vGbkYDpqLHP") + e.CheckNextLine(t, pubRegex) + e.CheckEOF(t) }) t.Run("unknown address", func(t *testing.T) { cmd := append(cmd, "--address", util.Uint160{}.StringLE()) @@ -832,39 +833,39 @@ func TestWalletDumpKeys(t *testing.T) { t.Run("simple signature", func(t *testing.T) { cmd := append(cmd, "--address", "Nhfg3TbpwogLvDGVvAvqyThbsHgoSUKwtn") e.Run(t, cmd...) - e.checkNextLine(t, "simple signature contract") - e.checkNextLine(t, pubRegex) - e.checkEOF(t) + e.CheckNextLine(t, "simple signature contract") + e.CheckNextLine(t, pubRegex) + e.CheckEOF(t) }) t.Run("3/4 multisig", func(t *testing.T) { cmd := append(cmd, "-a", "NVTiAjNgagDkTr5HTzDmQP9kPwPHN5BgVq") e.Run(t, cmd...) - e.checkNextLine(t, "3 out of 4 multisig contract") + e.CheckNextLine(t, "3 out of 4 multisig contract") for i := 0; i < 4; i++ { - e.checkNextLine(t, pubRegex) + e.CheckNextLine(t, pubRegex) } - e.checkEOF(t) + e.CheckEOF(t) }) t.Run("1/1 multisig", func(t *testing.T) { cmd := append(cmd, "--address", "NfgHwwTi3wHAS8aFAN243C5vGbkYDpqLHP") e.Run(t, cmd...) - e.checkNextLine(t, "1 out of 1 multisig contract") - e.checkNextLine(t, pubRegex) - e.checkEOF(t) + e.CheckNextLine(t, "1 out of 1 multisig contract") + e.CheckNextLine(t, pubRegex) + e.CheckEOF(t) }) } // Testcase is the wallet of privnet validator. func TestWalletConvert(t *testing.T) { tmpDir := t.TempDir() - e := newExecutor(t, false) + e := testcli.NewExecutor(t, false) outPath := filepath.Join(tmpDir, "wallet.json") cmd := []string{"neo-go", "wallet", "convert"} t.Run("missing wallet", func(t *testing.T) { e.RunWithError(t, cmd...) }) - cmd = append(cmd, "--wallet", "testdata/wallets/testwallet_NEO2.json") + cmd = append(cmd, "--wallet", "testdata/testwallet_NEO2.json") t.Run("missing out path", func(t *testing.T) { e.RunWithError(t, cmd...) }) @@ -886,12 +887,12 @@ func TestWalletConvert(t *testing.T) { e.In.WriteString("one\r") e.In.WriteString("one\r") e.Run(t, "neo-go", "wallet", "convert", - "--wallet", "testdata/wallets/testwallet_NEO2.json", + "--wallet", "testdata/testwallet_NEO2.json", "--out", outPath) actual, err := wallet.NewWalletFromFile(outPath) require.NoError(t, err) - expected, err := wallet.NewWalletFromFile("testdata/wallets/testwallet_NEO3.json") + expected, err := wallet.NewWalletFromFile("testdata/testwallet_NEO3.json") require.NoError(t, err) require.Equal(t, len(actual.Accounts), len(expected.Accounts)) for _, exp := range expected.Accounts { @@ -903,3 +904,7 @@ func TestWalletConvert(t *testing.T) { require.Equal(t, exp, act) } } + +func deployNNSContract(t *testing.T, e *testcli.Executor) util.Uint160 { + return testcli.DeployContract(t, e, "../../examples/nft-nd-nns/", "../../examples/nft-nd-nns/nns.yml", testcli.ValidatorWallet, testcli.ValidatorAddr, testcli.ValidatorPass) +} diff --git a/config/protocol.unit_testnet.single.yml b/config/protocol.unit_testnet.single.yml index 889b477bf..fa7b0f066 100644 --- a/config/protocol.unit_testnet.single.yml +++ b/config/protocol.unit_testnet.single.yml @@ -45,7 +45,7 @@ ApplicationConfiguration: MaxPeers: 10 AttemptConnPeers: 5 UnlockWallet: - Path: "testdata/wallet1_solo.json" + Path: "../testdata/wallet1_solo.json" Password: "one" P2PNotary: Enabled: false diff --git a/cli/executor_test.go b/internal/testcli/executor.go similarity index 65% rename from cli/executor_test.go rename to internal/testcli/executor.go index e3b8e81b9..6bcb1adcb 100644 --- a/cli/executor_test.go +++ b/internal/testcli/executor.go @@ -1,4 +1,11 @@ -package main +/* +Package testcli contains auxiliary code to test CLI commands. + +All testdata assets for it are contained in the cli directory and paths here +use `../` prefix to reference them because the package itself is used from +cli/* subpackages. +*/ +package testcli import ( "bytes" @@ -6,11 +13,13 @@ import ( "fmt" "io" "math" + "path/filepath" "strings" "sync" "testing" "time" + "github.com/nspcc-dev/neo-go/cli/app" "github.com/nspcc-dev/neo-go/cli/input" "github.com/nspcc-dev/neo-go/pkg/config" "github.com/nspcc-dev/neo-go/pkg/consensus" @@ -32,25 +41,25 @@ import ( ) const ( - validatorWIF = "KxyjQ8eUa4FHt3Gvioyt1Wz29cTUrE4eTqX3yFSk1YFCsPL8uNsY" - validatorAddr = "NfgHwwTi3wHAS8aFAN243C5vGbkYDpqLHP" - multisigAddr = "NVTiAjNgagDkTr5HTzDmQP9kPwPHN5BgVq" + ValidatorWIF = "KxyjQ8eUa4FHt3Gvioyt1Wz29cTUrE4eTqX3yFSk1YFCsPL8uNsY" + ValidatorAddr = "NfgHwwTi3wHAS8aFAN243C5vGbkYDpqLHP" + MultisigAddr = "NVTiAjNgagDkTr5HTzDmQP9kPwPHN5BgVq" - testWalletPath = "testdata/testwallet.json" - testWalletAccount = "Nfyz4KcsgYepRJw1W5C2uKCi6QWKf7v6gG" + TestWalletPath = "../testdata/testwallet.json" + TestWalletAccount = "Nfyz4KcsgYepRJw1W5C2uKCi6QWKf7v6gG" - validatorWallet = "testdata/wallet1_solo.json" - validatorPass = "one" + ValidatorWallet = "../testdata/wallet1_solo.json" + ValidatorPass = "one" ) var ( - validatorHash, _ = address.StringToUint160(validatorAddr) - validatorPriv, _ = keys.NewPrivateKeyFromWIF(validatorWIF) + ValidatorHash, _ = address.StringToUint160(ValidatorAddr) + ValidatorPriv, _ = keys.NewPrivateKeyFromWIF(ValidatorWIF) ) -// executor represents context for a test instance. +// Executor represents context for a test instance. // It can be safely used in multiple tests, but not in parallel. -type executor struct { +type Executor struct { // CLI is a cli application to test. CLI *cli.App // Chain is a blockchain instance (can be empty). @@ -120,8 +129,8 @@ func (w *ConcurrentBuffer) Reset() { w.buf.Reset() } -func newTestChain(t *testing.T, f func(*config.Config), run bool) (*core.Blockchain, *rpcsrv.Server, *network.Server) { - configPath := "../config/protocol.unit_testnet.single.yml" +func NewTestChain(t *testing.T, f func(*config.Config), run bool) (*core.Blockchain, *rpcsrv.Server, *network.Server) { + configPath := "../../config/protocol.unit_testnet.single.yml" cfg, err := config.LoadFile(configPath) require.NoError(t, err, "could not load config") if f != nil { @@ -160,17 +169,17 @@ func newTestChain(t *testing.T, f func(*config.Config), run bool) (*core.Blockch return chain, &rpcServer, netSrv } -func newExecutor(t *testing.T, needChain bool) *executor { - return newExecutorWithConfig(t, needChain, true, nil) +func NewExecutor(t *testing.T, needChain bool) *Executor { + return NewExecutorWithConfig(t, needChain, true, nil) } -func newExecutorSuspended(t *testing.T) *executor { - return newExecutorWithConfig(t, true, false, nil) +func NewExecutorSuspended(t *testing.T) *Executor { + return NewExecutorWithConfig(t, true, false, nil) } -func newExecutorWithConfig(t *testing.T, needChain, runChain bool, f func(*config.Config)) *executor { - e := &executor{ - CLI: newApp(), +func NewExecutorWithConfig(t *testing.T, needChain, runChain bool, f func(*config.Config)) *Executor { + e := &Executor{ + CLI: app.New(), Out: NewConcurrentBuffer(), Err: bytes.NewBuffer(nil), In: bytes.NewBuffer(nil), @@ -178,7 +187,7 @@ func newExecutorWithConfig(t *testing.T, needChain, runChain bool, f func(*confi e.CLI.Writer = e.Out e.CLI.ErrWriter = e.Err if needChain { - e.Chain, e.RPC, e.NetSrv = newTestChain(t, f, runChain) + e.Chain, e.RPC, e.NetSrv = NewTestChain(t, f, runChain) } t.Cleanup(func() { e.Close(t) @@ -186,7 +195,7 @@ func newExecutorWithConfig(t *testing.T, needChain, runChain bool, f func(*confi return e } -func (e *executor) Close(t *testing.T) { +func (e *Executor) Close(t *testing.T) { input.Terminal = nil if e.RPC != nil { e.RPC.Shutdown() @@ -202,7 +211,7 @@ func (e *executor) Close(t *testing.T) { // GetTransaction returns tx with hash h after it has persisted. // If it is in mempool, we can just wait for the next block, otherwise // it must be already in chain. 1 second is time per block in a unittest chain. -func (e *executor) GetTransaction(t *testing.T, h util.Uint256) (*transaction.Transaction, uint32) { +func (e *Executor) GetTransaction(t *testing.T, h util.Uint256) (*transaction.Transaction, uint32) { var tx *transaction.Transaction var height uint32 require.Eventually(t, func() bool { @@ -213,22 +222,22 @@ func (e *executor) GetTransaction(t *testing.T, h util.Uint256) (*transaction.Tr return tx, height } -func (e *executor) getNextLine(t *testing.T) string { +func (e *Executor) GetNextLine(t *testing.T) string { line, err := e.Out.ReadString('\n') require.NoError(t, err) return strings.TrimSuffix(line, "\n") } -func (e *executor) checkNextLine(t *testing.T, expected string) { - line := e.getNextLine(t) - e.checkLine(t, line, expected) +func (e *Executor) CheckNextLine(t *testing.T, expected string) { + line := e.GetNextLine(t) + e.CheckLine(t, line, expected) } -func (e *executor) checkLine(t *testing.T, line, expected string) { +func (e *Executor) CheckLine(t *testing.T, line, expected string) { require.Regexp(t, expected, line) } -func (e *executor) checkEOF(t *testing.T) { +func (e *Executor) CheckEOF(t *testing.T) { _, err := e.Out.ReadString('\n') require.True(t, errors.Is(err, io.EOF)) } @@ -253,19 +262,19 @@ func checkExit(t *testing.T, ch <-chan int, code int) { } // RunWithError runs command and checks that is exits with error. -func (e *executor) RunWithError(t *testing.T, args ...string) { +func (e *Executor) RunWithError(t *testing.T, args ...string) { ch := setExitFunc() require.Error(t, e.run(args...)) checkExit(t, ch, 1) } // Run runs command and checks that there were no errors. -func (e *executor) Run(t *testing.T, args ...string) { +func (e *Executor) Run(t *testing.T, args ...string) { ch := setExitFunc() require.NoError(t, e.run(args...)) checkExit(t, ch, 0) } -func (e *executor) run(args ...string) error { +func (e *Executor) run(args ...string) error { e.Out.Reset() e.Err.Reset() input.Terminal = term.NewTerminal(input.ReadWriter{ @@ -278,7 +287,7 @@ func (e *executor) run(args ...string) error { return err } -func (e *executor) checkTxPersisted(t *testing.T, prefix ...string) (*transaction.Transaction, uint32) { +func (e *Executor) CheckTxPersisted(t *testing.T, prefix ...string) (*transaction.Transaction, uint32) { line, err := e.Out.ReadString('\n') require.NoError(t, err) @@ -297,7 +306,7 @@ func (e *executor) checkTxPersisted(t *testing.T, prefix ...string) (*transactio return tx, height } -func generateKeys(t *testing.T, n int) ([]*keys.PrivateKey, keys.PublicKeys) { +func GenerateKeys(t *testing.T, n int) ([]*keys.PrivateKey, keys.PublicKeys) { privs := make([]*keys.PrivateKey, n) pubs := make(keys.PublicKeys, n) for i := range privs { @@ -308,3 +317,45 @@ func generateKeys(t *testing.T, n int) ([]*keys.PrivateKey, keys.PublicKeys) { } return privs, pubs } + +func (e *Executor) CheckTxTestInvokeOutput(t *testing.T, scriptSize int) { + e.CheckNextLine(t, `Hash:\s+`) + e.CheckNextLine(t, `OnChain:\s+false`) + e.CheckNextLine(t, `ValidUntil:\s+\d+`) + e.CheckNextLine(t, `Signer:\s+\w+`) + e.CheckNextLine(t, `SystemFee:\s+(\d|\.)+`) + e.CheckNextLine(t, `NetworkFee:\s+(\d|\.)+`) + e.CheckNextLine(t, `Script:\s+\w+`) + e.CheckScriptDump(t, scriptSize) +} + +func (e *Executor) CheckScriptDump(t *testing.T, scriptSize int) { + e.CheckNextLine(t, `INDEX\s+`) + for i := 0; i < scriptSize; i++ { + e.CheckNextLine(t, `\d+\s+\w+`) + } +} + +func DeployContract(t *testing.T, e *Executor, inPath, configPath, wallet, address, pass string) util.Uint160 { + config.Version = "0.90.0-test" // Contracts are compiled and we want NEFs to not change from run to run. + tmpDir := t.TempDir() + nefName := filepath.Join(tmpDir, "contract.nef") + manifestName := filepath.Join(tmpDir, "contract.manifest.json") + e.Run(t, "neo-go", "contract", "compile", + "--in", inPath, + "--config", configPath, + "--out", nefName, "--manifest", manifestName) + e.In.WriteString(pass + "\r") + e.Run(t, "neo-go", "contract", "deploy", + "--rpc-endpoint", "http://"+e.RPC.Addr, + "--wallet", wallet, "--address", address, + "--force", + "--in", nefName, "--manifest", manifestName) + e.CheckTxPersisted(t, "Sent invocation transaction ") + line, err := e.Out.ReadString('\n') + require.NoError(t, err) + line = strings.TrimSpace(strings.TrimPrefix(line, "Contract: ")) + h, err := util.Uint160DecodeStringLE(line) + require.NoError(t, err) + return h +} diff --git a/pkg/wallet/regenerate_test.go b/pkg/wallet/regenerate_test.go index c8e1b0a66..5dfc919f8 100644 --- a/pkg/wallet/regenerate_test.go +++ b/pkg/wallet/regenerate_test.go @@ -183,7 +183,7 @@ func TestRegenerateCLITestwallet_NEO3(t *testing.T) { if !regenerate { return } - const walletPath = "../../cli/testdata/wallets/testwallet_NEO3.json" + const walletPath = "../../cli/wallet/testdata/testwallet_NEO3.json" pubs := getKeys(t) acc1 := getAccount(t, privnetWIFs[0], passwords[0]) @@ -211,8 +211,8 @@ func TestRegenerateCLIWallet1_solo(t *testing.T) { const ( walletPath = "../../cli/testdata/wallet1_solo.json" verifyWIF = "L3W8gi36Y3KPqyR54VJaE1agH9yPvW2hALNZy1BerDwWce9P9xEy" - verifyNEFPath = "../../cli/testdata/verify.nef" - verifyManifestPath = "../../cli/testdata/verify.manifest.json" + verifyNEFPath = "../../cli/smartcontract/testdata/verify.nef" + verifyManifestPath = "../../cli/smartcontract/testdata/verify.manifest.json" ) scrypt := keys.ScryptParams{N: 2, R: 1, P: 1}