136 lines
3.7 KiB
Go
136 lines
3.7 KiB
Go
|
package commonclient
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"fmt"
|
||
|
"testing"
|
||
|
|
||
|
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
|
||
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||
|
"github.com/nspcc-dev/neo-go/pkg/vm/vmstate"
|
||
|
"github.com/stretchr/testify/mock"
|
||
|
"github.com/stretchr/testify/require"
|
||
|
)
|
||
|
|
||
|
type mockWaiter struct {
|
||
|
mock.Mock
|
||
|
}
|
||
|
|
||
|
func (w *mockWaiter) successfulResult(txHash util.Uint256) *state.AppExecResult {
|
||
|
return &state.AppExecResult{
|
||
|
Container: txHash,
|
||
|
Execution: state.Execution{
|
||
|
Trigger: trigger.Application,
|
||
|
VMState: vmstate.Halt,
|
||
|
GasConsumed: 100500,
|
||
|
Stack: nil,
|
||
|
Events: nil,
|
||
|
FaultException: "",
|
||
|
},
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (w *mockWaiter) failedResult(txHash util.Uint256, exception string) *state.AppExecResult {
|
||
|
return &state.AppExecResult{
|
||
|
Container: txHash,
|
||
|
Execution: state.Execution{
|
||
|
Trigger: trigger.Application,
|
||
|
VMState: vmstate.Fault,
|
||
|
GasConsumed: 100500,
|
||
|
Stack: nil,
|
||
|
Events: nil,
|
||
|
FaultException: exception,
|
||
|
},
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (m *mockWaiter) Wait(h util.Uint256, vub uint32, err error) (*state.AppExecResult, error) {
|
||
|
args := m.Called(h, vub, err)
|
||
|
result := args.Get(0)
|
||
|
if result == nil {
|
||
|
return nil, args.Error(1)
|
||
|
}
|
||
|
return result.(*state.AppExecResult), args.Error(1)
|
||
|
}
|
||
|
|
||
|
func (m *mockWaiter) WaitAny(ctx context.Context, vub uint32, hashes ...util.Uint256) (*state.AppExecResult, error) {
|
||
|
args := m.Called(ctx, vub, hashes)
|
||
|
result := args.Get(0)
|
||
|
if result == nil {
|
||
|
return nil, args.Error(1)
|
||
|
}
|
||
|
return result.(*state.AppExecResult), args.Error(1)
|
||
|
}
|
||
|
|
||
|
func TestWaiter(t *testing.T) {
|
||
|
txHash := util.Uint256{}
|
||
|
vub := uint32(100)
|
||
|
|
||
|
t.Run("ignore already exists error", func(t *testing.T) {
|
||
|
sendErr := fmt.Errorf("transaction already exists")
|
||
|
mw := &mockWaiter{}
|
||
|
mw.On("Wait", txHash, vub, mock.Anything).Return(mw.successfulResult(txHash), nil)
|
||
|
|
||
|
waiter := NewWaiter(mw, WaiterOptions{IgnoreAlreadyExistsError: true})
|
||
|
_, err := waiter.Wait(txHash, vub, sendErr)
|
||
|
|
||
|
require.NoError(t, err)
|
||
|
})
|
||
|
|
||
|
t.Run("report already exists error", func(t *testing.T) {
|
||
|
sendErr := fmt.Errorf("transaction already exists")
|
||
|
mw := &mockWaiter{}
|
||
|
mw.On("Wait", txHash, vub, mock.Anything).Return(mw.successfulResult(txHash), nil)
|
||
|
|
||
|
waiter := NewWaiter(mw, WaiterOptions{IgnoreAlreadyExistsError: false})
|
||
|
_, err := waiter.Wait(txHash, vub, sendErr)
|
||
|
|
||
|
require.Error(t, err)
|
||
|
})
|
||
|
|
||
|
t.Run("report wait error when transaction error is ignored", func(t *testing.T) {
|
||
|
waitErr := fmt.Errorf("mock error")
|
||
|
mw := &mockWaiter{}
|
||
|
mw.On("Wait", txHash, vub, nil).Return(nil, waitErr)
|
||
|
|
||
|
waiter := NewWaiter(mw, WaiterOptions{VerifyExecResults: false})
|
||
|
_, err := waiter.Wait(txHash, vub, nil)
|
||
|
|
||
|
require.ErrorIs(t, err, waitErr)
|
||
|
})
|
||
|
|
||
|
t.Run("report wait error when transaction error is verified", func(t *testing.T) {
|
||
|
waitErr := fmt.Errorf("mock error")
|
||
|
mw := &mockWaiter{}
|
||
|
mw.On("Wait", txHash, vub, nil).Return(nil, waitErr)
|
||
|
|
||
|
waiter := NewWaiter(mw, WaiterOptions{VerifyExecResults: true})
|
||
|
_, err := waiter.Wait(txHash, vub, nil)
|
||
|
|
||
|
require.ErrorIs(t, err, waitErr)
|
||
|
})
|
||
|
|
||
|
t.Run("ignore error from transaction", func(t *testing.T) {
|
||
|
txError := "mock error"
|
||
|
mw := &mockWaiter{}
|
||
|
mw.On("Wait", txHash, vub, nil).Return(mw.failedResult(txHash, txError), nil)
|
||
|
|
||
|
waiter := NewWaiter(mw, WaiterOptions{VerifyExecResults: false})
|
||
|
_, err := waiter.Wait(txHash, vub, nil)
|
||
|
|
||
|
require.NoError(t, err)
|
||
|
})
|
||
|
|
||
|
t.Run("examine error from transaction", func(t *testing.T) {
|
||
|
txError := "mock error"
|
||
|
mw := &mockWaiter{}
|
||
|
mw.On("Wait", txHash, vub, nil).Return(mw.failedResult(txHash, txError), nil)
|
||
|
|
||
|
waiter := NewWaiter(mw, WaiterOptions{VerifyExecResults: true})
|
||
|
_, err := waiter.Wait(txHash, vub, nil)
|
||
|
|
||
|
require.ErrorContains(t, err, txError)
|
||
|
})
|
||
|
}
|