frostfs-contract/commonclient/waiter_test.go
Vladimir Domnich 5f956751d4 [#120] Add waiter to frostfsid client
Signed-off-by: Vladimir Domnich <v.domnich@yadro.com>
2024-10-22 12:40:40 +03:00

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