neotest

package
v0.0.0-...-886a677 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 8, 2024 License: MIT Imports: 36 Imported by: 2

Documentation

Overview

Package neotest contains a framework for automated contract testing. It can be used to implement unit-tests for contracts in Go using regular Go conventions.

Usually it's used like this:

  • an instance of the blockchain is created using chain subpackage
  • the target contract is compiled using one of Compile* functions
  • and Executor is created for the blockchain
  • it's used to deploy a contract with DeployContract
  • CommitteeInvoker and/or ValidatorInvoker are then created to perform test invocations
  • if needed, NewAccount is used to create an appropriate number of accounts for the test

Higher-order methods provided in Executor and ContractInvoker hide the details of transaction creation for the most part, but there are lower-level methods as well that can be used for specific tasks.

It's recommended to have a separate folder/package for tests, because having them in the same package with the smart contract iself can lead to unxpected results if smart contract has any init() functions. If that's the case they will be compiled into the testing binary even when using package_test and their execution can affect tests. See https://github.com/epicchainlabs/epicchain-go/issues/3120 for details.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AddNetworkFee

func AddNetworkFee(t testing.TB, bc *core.Blockchain, tx *transaction.Transaction, signers ...Signer)

AddNetworkFee adds network fee to the transaction.

func AddSystemFee

func AddSystemFee(bc *core.Blockchain, tx *transaction.Transaction, sysFee int64)

AddSystemFee adds system fee to the transaction. If negative value specified, then system fee is defined by test invocation.

func NewDeployTxBy

func NewDeployTxBy(t testing.TB, bc *core.Blockchain, signer Signer, c *Contract, data any) *transaction.Transaction

NewDeployTxBy returns a new deployment tx for the contract signed by the specified signer.

func Nonce

func Nonce() uint32

Nonce returns a unique number that can be used as a nonce for new transactions.

func TestInvoke

func TestInvoke(bc *core.Blockchain, tx *transaction.Transaction) (*vm.VM, error)

TestInvoke creates a test VM with a dummy block and executes a transaction in it.

Types

type Contract

type Contract struct {
	Hash     util.Uint160
	NEF      *nef.File
	Manifest *manifest.Manifest
}

Contract contains contract info for deployment.

func CompileFile

func CompileFile(t testing.TB, sender util.Uint160, srcPath string, configPath string) *Contract

CompileFile compiles a contract from the file and returns its NEF, manifest and hash.

func CompileSource

func CompileSource(t testing.TB, sender util.Uint160, src io.Reader, opts *compiler.Options) *Contract

CompileSource compiles a contract from the reader and returns its NEF, manifest and hash.

type ContractInvoker

type ContractInvoker struct {
	*Executor
	Hash    util.Uint160
	Signers []Signer
}

ContractInvoker is a client for a specific contract.

func (*ContractInvoker) Invoke

func (c *ContractInvoker) Invoke(t testing.TB, result any, method string, args ...any) util.Uint256

Invoke invokes the method with the args, persists the transaction and checks the result. Returns transaction hash.

func (*ContractInvoker) InvokeAndCheck

func (c *ContractInvoker) InvokeAndCheck(t testing.TB, checkResult func(t testing.TB, stack []stackitem.Item), method string, args ...any) util.Uint256

InvokeAndCheck invokes the method with the args, persists the transaction and checks the result using the provided function. It returns the transaction hash.

func (*ContractInvoker) InvokeFail

func (c *ContractInvoker) InvokeFail(t testing.TB, message string, method string, args ...any) util.Uint256

InvokeFail invokes the method with the args, persists the transaction and checks the error message. It returns the transaction hash.

func (*ContractInvoker) InvokeWithFeeFail

func (c *ContractInvoker) InvokeWithFeeFail(t testing.TB, message string, sysFee int64, method string, args ...any) util.Uint256

InvokeWithFeeFail is like InvokeFail but sets the custom system fee for the transaction.

func (*ContractInvoker) PrepareInvoke

func (c *ContractInvoker) PrepareInvoke(t testing.TB, method string, args ...any) *transaction.Transaction

PrepareInvoke creates a new invocation transaction.

func (*ContractInvoker) PrepareInvokeNoSign

func (c *ContractInvoker) PrepareInvokeNoSign(t testing.TB, method string, args ...any) *transaction.Transaction

PrepareInvokeNoSign creates a new unsigned invocation transaction.

func (*ContractInvoker) TestInvoke

func (c *ContractInvoker) TestInvoke(t testing.TB, method string, args ...any) (*vm.Stack, error)

TestInvoke creates test VM and invokes the method with the args.

func (*ContractInvoker) TestInvokeScript

func (c *ContractInvoker) TestInvokeScript(t testing.TB, script []byte, signers []Signer, validUntilBlock ...uint32) (*vm.Stack, error)

TestInvokeScript creates test VM and invokes the script with the args and signers.

func (*ContractInvoker) WithSigners

func (c *ContractInvoker) WithSigners(signers ...Signer) *ContractInvoker

WithSigners creates a new client with the provided signer.

type Executor

type Executor struct {
	Chain         *core.Blockchain
	Validator     Signer
	Committee     Signer
	CommitteeHash util.Uint160
	Contracts     map[string]*Contract
}

Executor is a wrapper over chain state.

func NewExecutor

func NewExecutor(t testing.TB, bc *core.Blockchain, validator, committee Signer) *Executor

NewExecutor creates a new executor instance from the provided blockchain and committee.

func (*Executor) AddBlockCheckHalt

func (e *Executor) AddBlockCheckHalt(t testing.TB, txs ...*transaction.Transaction) *block.Block

AddBlockCheckHalt is a convenient wrapper over AddBlock and CheckHalt.

func (*Executor) AddNewBlock

func (e *Executor) AddNewBlock(t testing.TB, txs ...*transaction.Transaction) *block.Block

AddNewBlock creates a new block from the provided transactions and adds it on the bc.

func (*Executor) CheckFault

func (e *Executor) CheckFault(t testing.TB, h util.Uint256, s string)

CheckFault checks that the transaction is persisted with FAULT state. The raised exception is also checked to contain the s as a substring.

func (*Executor) CheckGASBalance

func (e *Executor) CheckGASBalance(t testing.TB, acc util.Uint160, expected *big.Int)

CheckGASBalance ensures that the provided account owns the specified amount of GAS.

func (*Executor) CheckHalt

func (e *Executor) CheckHalt(t testing.TB, h util.Uint256, stack ...stackitem.Item) *state.AppExecResult

CheckHalt checks that the transaction is persisted with HALT state.

func (*Executor) CheckTxNotificationEvent

func (e *Executor) CheckTxNotificationEvent(t testing.TB, h util.Uint256, index int, expected state.NotificationEvent)

CheckTxNotificationEvent checks that the specified event was emitted at the specified position during transaction script execution. Negative index corresponds to backwards enumeration.

func (*Executor) CommitteeInvoker

func (e *Executor) CommitteeInvoker(h util.Uint160) *ContractInvoker

CommitteeInvoker creates a new ContractInvoker for the contract with hash h and a committee multisignature signer.

func (*Executor) ContractHash

func (e *Executor) ContractHash(t testing.TB, id int32) util.Uint160

ContractHash returns a contract hash by the ID.

func (*Executor) DeployContract

func (e *Executor) DeployContract(t testing.TB, c *Contract, data any) util.Uint256

DeployContract compiles and deploys a contract to the bc. It also checks that the precalculated contract hash matches the actual one. data is an optional argument to `_deploy`. It returns the hash of the deploy transaction.

func (*Executor) DeployContractBy

func (e *Executor) DeployContractBy(t testing.TB, signer Signer, c *Contract, data any) util.Uint256

DeployContractBy compiles and deploys a contract to the bc using the provided signer. It also checks that the precalculated contract hash matches the actual one. data is an optional argument to `_deploy`. It returns the hash of the deploy transaction.

func (*Executor) DeployContractCheckFAULT

func (e *Executor) DeployContractCheckFAULT(t testing.TB, c *Contract, data any, errMessage string)

DeployContractCheckFAULT compiles and deploys a contract to the bc using the validator account. It checks that the deploy transaction FAULTed with the specified error.

func (*Executor) EnsureGASBalance

func (e *Executor) EnsureGASBalance(t testing.TB, acc util.Uint160, isOk func(balance *big.Int) bool)

EnsureGASBalance ensures that the provided account owns the amount of GAS that satisfies the provided condition.

func (*Executor) GenerateNewBlocks

func (e *Executor) GenerateNewBlocks(t testing.TB, count int) []*block.Block

GenerateNewBlocks adds the specified number of empty blocks to the chain.

func (*Executor) GetBlockByIndex

func (e *Executor) GetBlockByIndex(t testing.TB, idx uint32) *block.Block

GetBlockByIndex returns a block by the specified index.

func (*Executor) GetTransaction

func (e *Executor) GetTransaction(t testing.TB, h util.Uint256) (*transaction.Transaction, uint32)

GetTransaction returns a transaction and its height by the specified hash.

func (*Executor) GetTxExecResult

func (e *Executor) GetTxExecResult(t testing.TB, h util.Uint256) *state.AppExecResult

GetTxExecResult returns application execution results for the specified transaction.

func (*Executor) InvokeScript

func (e *Executor) InvokeScript(t testing.TB, script []byte, signers []Signer) util.Uint256

InvokeScript adds a transaction with the specified script to the chain and returns its hash. It does no faults check.

func (*Executor) InvokeScriptCheckFAULT

func (e *Executor) InvokeScriptCheckFAULT(t testing.TB, script []byte, signers []Signer, errMessage string) util.Uint256

InvokeScriptCheckFAULT adds a transaction with the specified script to the chain and checks if it's FAULTed with the specified error.

func (*Executor) InvokeScriptCheckHALT

func (e *Executor) InvokeScriptCheckHALT(t testing.TB, script []byte, signers []Signer, stack ...stackitem.Item)

InvokeScriptCheckHALT adds a transaction with the specified script to the chain and checks if it's HALTed with the specified items on stack.

func (*Executor) NativeHash

func (e *Executor) NativeHash(t testing.TB, name string) util.Uint160

NativeHash returns a native contract hash by the name.

func (*Executor) NativeID

func (e *Executor) NativeID(t testing.TB, name string) int32

NativeID returns a native contract ID by the name.

func (*Executor) NewAccount

func (e *Executor) NewAccount(t testing.TB, expectedGASBalance ...int64) Signer

NewAccount returns a new signer holding 100.0 GAS (or given amount is specified). This method advances the chain by one block with a transfer transaction.

func (*Executor) NewDeployTx

func (e *Executor) NewDeployTx(t testing.TB, bc *core.Blockchain, c *Contract, data any) *transaction.Transaction

NewDeployTx returns a new deployment tx for the contract signed by the committee.

func (*Executor) NewInvoker

func (e *Executor) NewInvoker(h util.Uint160, signers ...Signer) *ContractInvoker

NewInvoker creates a new ContractInvoker for the contract with hash h and the specified signers.

func (*Executor) NewTx

func (e *Executor) NewTx(t testing.TB, signers []Signer,
	hash util.Uint160, method string, args ...any) *transaction.Transaction

NewTx creates a new transaction which invokes the contract method. The transaction is signed by the signers.

func (*Executor) NewUnsignedBlock

func (e *Executor) NewUnsignedBlock(t testing.TB, txs ...*transaction.Transaction) *block.Block

NewUnsignedBlock creates a new unsigned block from txs.

func (*Executor) NewUnsignedTx

func (e *Executor) NewUnsignedTx(t testing.TB, hash util.Uint160, method string, args ...any) *transaction.Transaction

NewUnsignedTx creates a new unsigned transaction which invokes the method of the contract with the hash.

func (*Executor) PrepareInvocation

func (e *Executor) PrepareInvocation(t testing.TB, script []byte, signers []Signer, validUntilBlock ...uint32) *transaction.Transaction

PrepareInvocation creates a transaction with the specified script and signs it by the provided signer.

func (*Executor) PrepareInvocationNoSign

func (e *Executor) PrepareInvocationNoSign(t testing.TB, script []byte, validUntilBlock ...uint32) *transaction.Transaction

func (*Executor) SignBlock

func (e *Executor) SignBlock(b *block.Block) *block.Block

SignBlock add validators signature to b.

func (*Executor) SignTx

func (e *Executor) SignTx(t testing.TB, tx *transaction.Transaction, sysFee int64, signers ...Signer) *transaction.Transaction

SignTx signs a transaction using the provided signers.

func (*Executor) TopBlock

func (e *Executor) TopBlock(t testing.TB) *block.Block

TopBlock returns the block with the highest index.

func (*Executor) ValidatorInvoker

func (e *Executor) ValidatorInvoker(h util.Uint160) *ContractInvoker

ValidatorInvoker creates a new ContractInvoker for the contract with hash h and a validators multisignature signer.

type MultiSigner

type MultiSigner interface {
	Signer
	// Single returns a simple-signature signer for the n-th account in a list.
	Single(n int) SingleSigner
}

MultiSigner is an interface for multisignature signing account.

func NewMultiSigner

func NewMultiSigner(accs ...*wallet.Account) MultiSigner

NewMultiSigner returns a multi-signature signer for the provided account. It must contain at least as many accounts as needed to sign the script.

type Signer

type Signer interface {
	// Script returns a signer verification script.
	Script() []byte
	// ScriptHash returns a signer script hash.
	ScriptHash() util.Uint160
	// SignHashable returns an invocation script for signing an item.
	SignHashable(uint32, hash.Hashable) []byte
	// SignTx signs a transaction.
	SignTx(netmode.Magic, *transaction.Transaction) error
}

Signer is a generic interface which can be either a simple- or multi-signature signer.

type SingleSigner

type SingleSigner interface {
	Signer
	// Account returns the underlying account which can be used to
	// get a public key and/or sign arbitrary things.
	Account() *wallet.Account
}

SingleSigner is a generic interface for a simple one-signature signer.

func NewContractSigner

func NewContractSigner(h util.Uint160, getInvParams func(tx *transaction.Transaction) []any) SingleSigner

NewContractSigner returns a contract signer for the provided contract hash. getInvParams must return params to be used as invocation script for contract-based witness.

func NewSingleSigner

func NewSingleSigner(acc *wallet.Account) SingleSigner

NewSingleSigner creates a SingleSigner from the provided account. It has just one key, see NewMultiSigner for multisignature accounts.

Directories

Path Synopsis
Package chain contains functions creating new test blockchain instances.
Package chain contains functions creating new test blockchain instances.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL