forked from TrueCloudLab/neoneo-go
cli: add tests for NEP5 transfer
This commit is contained in:
parent
468f7ee650
commit
d30c7db49a
3 changed files with 78 additions and 0 deletions
|
@ -1,22 +1,28 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/cli/input"
|
"github.com/nspcc-dev/neo-go/cli/input"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/config"
|
"github.com/nspcc-dev/neo-go/pkg/config"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core"
|
"github.com/nspcc-dev/neo-go/pkg/core"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/storage"
|
"github.com/nspcc-dev/neo-go/pkg/core/storage"
|
||||||
|
"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/address"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/network"
|
"github.com/nspcc-dev/neo-go/pkg/network"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpc/server"
|
"github.com/nspcc-dev/neo-go/pkg/rpc/server"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
"go.uber.org/zap/zaptest"
|
"go.uber.org/zap/zaptest"
|
||||||
|
"golang.org/x/crypto/ssh/terminal"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -42,6 +48,8 @@ type executor struct {
|
||||||
Out *bytes.Buffer
|
Out *bytes.Buffer
|
||||||
// Err contains command errors.
|
// Err contains command errors.
|
||||||
Err *bytes.Buffer
|
Err *bytes.Buffer
|
||||||
|
// In contains command input.
|
||||||
|
In *bytes.Buffer
|
||||||
}
|
}
|
||||||
|
|
||||||
func newTestChain(t *testing.T) (*core.Blockchain, *server.Server, *network.Server) {
|
func newTestChain(t *testing.T) (*core.Blockchain, *server.Server, *network.Server) {
|
||||||
|
@ -72,9 +80,13 @@ func newExecutor(t *testing.T, needChain bool) *executor {
|
||||||
CLI: newApp(),
|
CLI: newApp(),
|
||||||
Out: bytes.NewBuffer(nil),
|
Out: bytes.NewBuffer(nil),
|
||||||
Err: bytes.NewBuffer(nil),
|
Err: bytes.NewBuffer(nil),
|
||||||
|
In: bytes.NewBuffer(nil),
|
||||||
}
|
}
|
||||||
e.CLI.Writer = e.Out
|
e.CLI.Writer = e.Out
|
||||||
e.CLI.ErrWriter = e.Err
|
e.CLI.ErrWriter = e.Err
|
||||||
|
rw := bufio.NewReadWriter(bufio.NewReader(e.In), bufio.NewWriter(ioutil.Discard))
|
||||||
|
require.Nil(t, input.Terminal) // check that tests clean up properly
|
||||||
|
input.Terminal = terminal.NewTerminal(rw, "")
|
||||||
if needChain {
|
if needChain {
|
||||||
e.Chain, e.RPC, e.NetSrv = newTestChain(t)
|
e.Chain, e.RPC, e.NetSrv = newTestChain(t)
|
||||||
}
|
}
|
||||||
|
@ -94,6 +106,20 @@ 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 {
|
||||||
|
var tx *transaction.Transaction
|
||||||
|
require.Eventually(t, func() bool {
|
||||||
|
var height uint32
|
||||||
|
var err error
|
||||||
|
tx, height, err = e.Chain.GetTransaction(h)
|
||||||
|
return err == nil && height != 0
|
||||||
|
}, time.Second*2, time.Millisecond*100, "too long time waiting for block")
|
||||||
|
return tx
|
||||||
|
}
|
||||||
|
|
||||||
func (e *executor) checkNextLine(t *testing.T, expected string) {
|
func (e *executor) checkNextLine(t *testing.T, expected string) {
|
||||||
line, err := e.Out.ReadString('\n')
|
line, err := e.Out.ReadString('\n')
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
|
@ -1,10 +1,16 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"math/big"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestNEP5Balance(t *testing.T) {
|
func TestNEP5Balance(t *testing.T) {
|
||||||
|
@ -44,3 +50,45 @@ func TestNEP5Balance(t *testing.T) {
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestNEP5Transfer(t *testing.T) {
|
||||||
|
w, err := wallet.NewWalletFromFile("testdata/testwallet.json")
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer w.Close()
|
||||||
|
|
||||||
|
e := newExecutor(t, true)
|
||||||
|
defer e.Close(t)
|
||||||
|
args := []string{
|
||||||
|
"neo-go", "wallet", "nep5", "transfer",
|
||||||
|
"--unittest",
|
||||||
|
"--rpc-endpoint", "http://" + e.RPC.Addr,
|
||||||
|
"--wallet", validatorWallet,
|
||||||
|
"--from", validatorAddr,
|
||||||
|
"--to", w.Accounts[0].Address,
|
||||||
|
"--token", "neo",
|
||||||
|
"--amount", "1",
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run("InvalidPassword", func(t *testing.T) {
|
||||||
|
e.In.WriteString("onetwothree\r")
|
||||||
|
e.RunWithError(t, args...)
|
||||||
|
e.In.Reset()
|
||||||
|
})
|
||||||
|
|
||||||
|
e.In.WriteString("one\r")
|
||||||
|
e.Run(t, args...)
|
||||||
|
line, err := e.Out.ReadString('\n')
|
||||||
|
require.NoError(t, err)
|
||||||
|
h, err := util.Uint256DecodeStringLE(strings.TrimSpace(line))
|
||||||
|
require.NoError(t, err, "can't decode tx hash: %s", line)
|
||||||
|
|
||||||
|
tx := e.GetTransaction(t, h)
|
||||||
|
aer, err := e.Chain.GetAppExecResult(tx.Hash())
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, vm.HaltState, aer.VMState)
|
||||||
|
|
||||||
|
sh, err := address.StringToUint160(w.Accounts[0].Address)
|
||||||
|
require.NoError(t, err)
|
||||||
|
b, _ := e.Chain.GetGoverningTokenBalance(sh)
|
||||||
|
require.Equal(t, big.NewInt(1), b)
|
||||||
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ var RPC = []cli.Flag{
|
||||||
cli.BoolFlag{Name: "privnet, p"},
|
cli.BoolFlag{Name: "privnet, p"},
|
||||||
cli.BoolFlag{Name: "mainnet, m"},
|
cli.BoolFlag{Name: "mainnet, m"},
|
||||||
cli.BoolFlag{Name: "testnet, t"},
|
cli.BoolFlag{Name: "testnet, t"},
|
||||||
|
cli.BoolFlag{Name: "unittest", Hidden: true},
|
||||||
}
|
}
|
||||||
|
|
||||||
var errNoEndpoint = errors.New("no RPC endpoint specified, use option '--" + RPCEndpointFlag + "' or '-r'")
|
var errNoEndpoint = errors.New("no RPC endpoint specified, use option '--" + RPCEndpointFlag + "' or '-r'")
|
||||||
|
@ -51,6 +52,9 @@ func GetNetwork(ctx *cli.Context) netmode.Magic {
|
||||||
if ctx.Bool("mainnet") {
|
if ctx.Bool("mainnet") {
|
||||||
net = netmode.MainNet
|
net = netmode.MainNet
|
||||||
}
|
}
|
||||||
|
if ctx.Bool("unittest") {
|
||||||
|
net = netmode.UnitTestNet
|
||||||
|
}
|
||||||
return net
|
return net
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue