Commit b00a3d12 authored by Adrian Sutton's avatar Adrian Sutton

Add test for GetAllClaims

parent 16d65a68
......@@ -2,6 +2,7 @@ package contracts
import (
"context"
"math"
"math/big"
"testing"
......@@ -99,13 +100,68 @@ func TestGetClaim(t *testing.T) {
}, status)
}
func TestGetAllClaims(t *testing.T) {
stubRpc, game := setup(t)
claim0 := faultTypes.Claim{
ClaimData: faultTypes.ClaimData{
Value: common.Hash{0xaa},
Position: faultTypes.NewPositionFromGIndex(big.NewInt(1)),
},
Countered: true,
Clock: 1234,
ContractIndex: 0,
ParentContractIndex: math.MaxUint32,
}
claim1 := faultTypes.Claim{
ClaimData: faultTypes.ClaimData{
Value: common.Hash{0xab},
Position: faultTypes.NewPositionFromGIndex(big.NewInt(2)),
},
Countered: true,
Clock: 4455,
ContractIndex: 1,
ParentContractIndex: 0,
}
claim2 := faultTypes.Claim{
ClaimData: faultTypes.ClaimData{
Value: common.Hash{0xbb},
Position: faultTypes.NewPositionFromGIndex(big.NewInt(6)),
},
Countered: false,
Clock: 7777,
ContractIndex: 2,
ParentContractIndex: 1,
}
expectedClaims := []faultTypes.Claim{claim0, claim1, claim2}
stubRpc.SetResponse(methodClaimCount, nil, []interface{}{big.NewInt(int64(len(expectedClaims)))})
for _, claim := range expectedClaims {
expectGetClaim(stubRpc, claim)
}
claims, err := game.GetAllClaims(context.Background())
require.NoError(t, err)
require.Equal(t, expectedClaims, claims)
}
func expectGetClaim(stubRpc *test.AbiBasedRpc, claim faultTypes.Claim) {
stubRpc.SetResponse(
methodClaim,
[]interface{}{big.NewInt(int64(claim.ContractIndex))},
[]interface{}{
uint32(claim.ParentContractIndex),
claim.Countered,
claim.Value,
claim.Position.ToGIndex(),
big.NewInt(int64(claim.Clock)),
})
}
func setup(t *testing.T) (*test.AbiBasedRpc, *FaultDisputeGameContract) {
fdgAbi, err := bindings.FaultDisputeGameMetaData.GetAbi()
require.NoError(t, err)
address := common.HexToAddress("0x24112842371dFC380576ebb09Ae16Cb6B6caD7CB")
stubRpc := test.NewAbiBasedRpc(t, fdgAbi, address)
caller := batching.NewMultiCaller(stubRpc, 100)
caller := batching.NewMultiCaller(stubRpc, 1)
game, err := NewFaultDisputeGameContract(address, caller)
require.NoError(t, err)
return stubRpc, game
......
......@@ -3,6 +3,7 @@ package test
import (
"context"
"encoding/json"
"fmt"
"testing"
"github.com/ethereum/go-ethereum/accounts/abi"
......@@ -10,24 +11,33 @@ import (
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/rpc"
"github.com/stretchr/testify/require"
"golang.org/x/exp/slices"
)
type expectedCall struct {
args []interface{}
packedArgs []byte
outputs []interface{}
}
func (e *expectedCall) String() string {
return fmt.Sprintf("{args: %v, outputs: %v}", e.args, e.outputs)
}
type AbiBasedRpc struct {
t *testing.T
abi *abi.ABI
addr common.Address
expectedArgs map[string][]interface{}
outputs map[string][]interface{}
expectedCalls map[string][]*expectedCall
}
func NewAbiBasedRpc(t *testing.T, contractAbi *abi.ABI, addr common.Address) *AbiBasedRpc {
return &AbiBasedRpc{
t: t,
abi: contractAbi,
addr: addr,
expectedArgs: make(map[string][]interface{}),
outputs: make(map[string][]interface{}),
t: t,
abi: contractAbi,
addr: addr,
expectedCalls: make(map[string][]*expectedCall),
}
}
......@@ -38,8 +48,15 @@ func (l *AbiBasedRpc) SetResponse(method string, expected []interface{}, output
if output == nil {
output = []interface{}{}
}
l.expectedArgs[method] = expected
l.outputs[method] = output
abiMethod, ok := l.abi.Methods[method]
require.Truef(l.t, ok, "No method: %v", method)
packedArgs, err := abiMethod.Inputs.Pack(expected...)
require.NoErrorf(l.t, err, "Invalid expected arguments for method %v: %v", method, expected)
l.expectedCalls[method] = append(l.expectedCalls[method], &expectedCall{
args: expected,
packedArgs: packedArgs,
outputs: output,
})
}
func (l *AbiBasedRpc) BatchCallContext(_ context.Context, b []rpc.BatchElem) error {
......@@ -58,17 +75,24 @@ func (l *AbiBasedRpc) CallContext(_ context.Context, out interface{}, method str
abiMethod, err := l.abi.MethodById(data[0:4])
require.NoError(l.t, err)
args, err = abiMethod.Inputs.Unpack(data[4:])
argData := data[4:]
args, err = abiMethod.Inputs.Unpack(argData)
require.NoError(l.t, err)
require.Len(l.t, args, len(abiMethod.Inputs))
expectedArgs, ok := l.expectedArgs[abiMethod.Name]
expectedCalls, ok := l.expectedCalls[abiMethod.Name]
require.Truef(l.t, ok, "Unexpected call to %v", abiMethod.Name)
require.EqualValues(l.t, expectedArgs, args, "Unexpected args")
var call *expectedCall
for _, candidate := range expectedCalls {
if slices.Equal(candidate.packedArgs, argData) {
call = candidate
break
}
}
require.NotNilf(l.t, call, "No expected calls to %v with arguments: %v\nExpected calls: %v", abiMethod.Name, args, expectedCalls)
outputs, ok := l.outputs[abiMethod.Name]
require.True(l.t, ok)
output, err := abiMethod.Outputs.Pack(outputs...)
require.NoError(l.t, err)
output, err := abiMethod.Outputs.Pack(call.outputs...)
require.NoErrorf(l.t, err, "Invalid outputs for method %v: %v", abiMethod.Name, call.outputs)
// I admit I do not understand Go reflection.
// So leverage json.Unmarshal to set the out value correctly.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment