Commit b00a3d12 authored by Adrian Sutton's avatar Adrian Sutton

Add test for GetAllClaims

parent 16d65a68
...@@ -2,6 +2,7 @@ package contracts ...@@ -2,6 +2,7 @@ package contracts
import ( import (
"context" "context"
"math"
"math/big" "math/big"
"testing" "testing"
...@@ -99,13 +100,68 @@ func TestGetClaim(t *testing.T) { ...@@ -99,13 +100,68 @@ func TestGetClaim(t *testing.T) {
}, status) }, 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) { func setup(t *testing.T) (*test.AbiBasedRpc, *FaultDisputeGameContract) {
fdgAbi, err := bindings.FaultDisputeGameMetaData.GetAbi() fdgAbi, err := bindings.FaultDisputeGameMetaData.GetAbi()
require.NoError(t, err) require.NoError(t, err)
address := common.HexToAddress("0x24112842371dFC380576ebb09Ae16Cb6B6caD7CB") address := common.HexToAddress("0x24112842371dFC380576ebb09Ae16Cb6B6caD7CB")
stubRpc := test.NewAbiBasedRpc(t, fdgAbi, address) stubRpc := test.NewAbiBasedRpc(t, fdgAbi, address)
caller := batching.NewMultiCaller(stubRpc, 100) caller := batching.NewMultiCaller(stubRpc, 1)
game, err := NewFaultDisputeGameContract(address, caller) game, err := NewFaultDisputeGameContract(address, caller)
require.NoError(t, err) require.NoError(t, err)
return stubRpc, game return stubRpc, game
......
...@@ -3,6 +3,7 @@ package test ...@@ -3,6 +3,7 @@ package test
import ( import (
"context" "context"
"encoding/json" "encoding/json"
"fmt"
"testing" "testing"
"github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/accounts/abi"
...@@ -10,24 +11,33 @@ import ( ...@@ -10,24 +11,33 @@ import (
"github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/rpc"
"github.com/stretchr/testify/require" "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 { type AbiBasedRpc struct {
t *testing.T t *testing.T
abi *abi.ABI abi *abi.ABI
addr common.Address addr common.Address
expectedArgs map[string][]interface{} expectedCalls map[string][]*expectedCall
outputs map[string][]interface{}
} }
func NewAbiBasedRpc(t *testing.T, contractAbi *abi.ABI, addr common.Address) *AbiBasedRpc { func NewAbiBasedRpc(t *testing.T, contractAbi *abi.ABI, addr common.Address) *AbiBasedRpc {
return &AbiBasedRpc{ return &AbiBasedRpc{
t: t, t: t,
abi: contractAbi, abi: contractAbi,
addr: addr, addr: addr,
expectedArgs: make(map[string][]interface{}), expectedCalls: make(map[string][]*expectedCall),
outputs: make(map[string][]interface{}),
} }
} }
...@@ -38,8 +48,15 @@ func (l *AbiBasedRpc) SetResponse(method string, expected []interface{}, output ...@@ -38,8 +48,15 @@ func (l *AbiBasedRpc) SetResponse(method string, expected []interface{}, output
if output == nil { if output == nil {
output = []interface{}{} output = []interface{}{}
} }
l.expectedArgs[method] = expected abiMethod, ok := l.abi.Methods[method]
l.outputs[method] = output 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 { func (l *AbiBasedRpc) BatchCallContext(_ context.Context, b []rpc.BatchElem) error {
...@@ -58,17 +75,24 @@ func (l *AbiBasedRpc) CallContext(_ context.Context, out interface{}, method str ...@@ -58,17 +75,24 @@ func (l *AbiBasedRpc) CallContext(_ context.Context, out interface{}, method str
abiMethod, err := l.abi.MethodById(data[0:4]) abiMethod, err := l.abi.MethodById(data[0:4])
require.NoError(l.t, err) 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.NoError(l.t, err)
require.Len(l.t, args, len(abiMethod.Inputs)) 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.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] output, err := abiMethod.Outputs.Pack(call.outputs...)
require.True(l.t, ok) require.NoErrorf(l.t, err, "Invalid outputs for method %v: %v", abiMethod.Name, call.outputs)
output, err := abiMethod.Outputs.Pack(outputs...)
require.NoError(l.t, err)
// I admit I do not understand Go reflection. // I admit I do not understand Go reflection.
// So leverage json.Unmarshal to set the out value correctly. // 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