cli: move tests to subpackages

Refs. #2379, but not completely solves it, one package seriously outweights
others:

?       github.com/nspcc-dev/neo-go/cli [no test files]
ok      github.com/nspcc-dev/neo-go/cli/app     0.036s  coverage: 100.0% of statements
ok      github.com/nspcc-dev/neo-go/cli/cmdargs 0.011s  coverage: 60.8% of statements
ok      github.com/nspcc-dev/neo-go/cli/flags   0.009s  coverage: 97.7% of statements
?       github.com/nspcc-dev/neo-go/cli/input   [no test files]
ok      github.com/nspcc-dev/neo-go/cli/options 0.033s  coverage: 50.0% of statements
?       github.com/nspcc-dev/neo-go/cli/paramcontext    [no test files]
ok      github.com/nspcc-dev/neo-go/cli/query   2.155s  coverage: 45.3% of statements
ok      github.com/nspcc-dev/neo-go/cli/server  1.373s  coverage: 67.8% of statements
ok      github.com/nspcc-dev/neo-go/cli/smartcontract   8.819s  coverage: 94.3% of statements
ok      github.com/nspcc-dev/neo-go/cli/util    0.006s  coverage: 10.9% of statements
?       github.com/nspcc-dev/neo-go/cli/vm      [no test files]
ok      github.com/nspcc-dev/neo-go/cli/wallet  72.103s coverage: 88.2% of statements

Still a nice thing to have.
This commit is contained in:
Roman Khimov 2022-10-05 09:44:10 +03:00
parent 48567fbc61
commit 1ac60ada19
38 changed files with 633 additions and 593 deletions

41
cli/app/app.go Normal file
View file

@ -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
}

18
cli/app/main_test.go Normal file
View file

@ -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)
}

View file

@ -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
}

View file

@ -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)
}

View file

@ -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)

View file

@ -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")...)
})

View file

@ -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",

View file

@ -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)
})
}
}

View file

@ -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() {

View file

@ -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"

26
cli/util/util_test.go Normal file
View file

@ -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)
}

View file

@ -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)
}

View file

@ -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")
}

View file

@ -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)
}

View file

@ -1,4 +1,4 @@
package main
package wallet_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,17 @@ 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)
}

View file

@ -1,4 +1,4 @@
package main
package wallet_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",

View file

@ -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 {

View file

@ -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

View file

@ -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
}

View file

@ -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}