Skip to content

Commit

Permalink
Restore chain reader confidence levels tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ilija42 committed Jul 10, 2024
1 parent 6391d78 commit 3df55c8
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 69 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -251,10 +251,10 @@ func (it *fakeChainReaderInterfaceTester) SetTestStructLatestValue(t *testing.T,
fake.SetTestStructLatestValue(testStruct)
}

func (it *fakeChainReaderInterfaceTester) SetUintLatestValue(t *testing.T, val uint64) {
func (it *fakeChainReaderInterfaceTester) SetUintLatestValue(t *testing.T, val uint64, forCall ExpectedGetLatestValueArgs) {
fake, ok := it.impl.(*fakeChainReader)
assert.True(t, ok)
fake.SetUintLatestValue(val)
fake.SetUintLatestValue(val, forCall)
}

func (it *fakeChainReaderInterfaceTester) GenerateBlocksTillConfidenceLevel(t *testing.T, contractName, readName string, confidenceLevel primitives.ConfidenceLevel) {
Expand Down Expand Up @@ -311,7 +311,7 @@ func (f *fakeChainReader) SetTestStructLatestValue(ts *TestStruct) {
f.stored = append(f.stored, *ts)
}

func (f *fakeChainReader) SetUintLatestValue(val uint64) {
func (f *fakeChainReader) SetUintLatestValue(val uint64, _ ExpectedGetLatestValueArgs) {
f.lock.Lock()
defer f.lock.Unlock()
f.vals = append(f.vals, valConfidencePair{val: val, confidenceLevel: primitives.Unconfirmed})
Expand Down Expand Up @@ -374,10 +374,6 @@ func (f *fakeChainReader) GetLatestValue(_ context.Context, contractName, method
}
}
return types.ErrNotFound
} else if method == DifferentMethodReturningUint64 {
r := returnVal.(*uint64)
*r = AnyDifferentValueToReadWithoutAnArgument
return nil
} else if method != MethodTakingLatestParamsReturningTestStruct {
return errors.New("unknown method " + method)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ func (fakeTypeProvider) CreateContractType(_, itemType string, isEncode bool) (a
return &LatestParams{}, nil
}
return &TestStruct{}, nil
case MethodReturningUint64, DifferentMethodReturningUint64, MethodReturningAlterableUint64:
case MethodReturningUint64, MethodReturningAlterableUint64:
tmp := uint64(0)
return &tmp, nil
case MethodReturningUint64Slice:
Expand Down
123 changes: 62 additions & 61 deletions pkg/types/interfacetests/chain_reader_interface_tests.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@ import (
type ChainReaderInterfaceTester[T TestingT[T]] interface {
BasicTester[T]
GetChainReader(t T) types.ContractReader

// SetTestStructLatestValue is expected to return the same bound contract and method in the same test
// Any setup required for this should be done in Setup.
// The contract should take a LatestParams as the params and return the nth TestStruct set
SetTestStructLatestValue(t T, testStruct *TestStruct)
// SetUintLatestValue is expected to return the same bound contract and method in the same test
// Any setup required for this should be done in Setup.
// The contract should take a uint64 as the params and returns the same.
SetUintLatestValue(t T, val uint64)
// forCall is used to attach value to a call, this is useful in chain specific test since in chain agnostic tests we can just use hard coded readName constants.
SetUintLatestValue(t T, val uint64, forCall ExpectedGetLatestValueArgs)
TriggerEvent(t T, testStruct *TestStruct)
GetBindings(t T) []types.BoundContract
// GenerateBlocksTillConfidenceLevel raises confidence level to the provided level for a specific read.
Expand All @@ -39,7 +39,6 @@ const (
MethodTakingLatestParamsReturningTestStruct = "GetLatestValues"
MethodReturningUint64 = "GetPrimitiveValue"
MethodReturningAlterableUint64 = "GetAlterablePrimitiveValue"
DifferentMethodReturningUint64 = "GetDifferentPrimitiveValue"
MethodReturningUint64Slice = "GetSliceValue"
MethodReturningSeenStruct = "GetSeenStruct"
EventName = "SomeEvent"
Expand Down Expand Up @@ -95,40 +94,43 @@ func runChainReaderGetLatestValueInterfaceTests[T TestingT[T]](t T, tester Chain
assert.Equal(t, AnyValueToReadWithoutAnArgument, prim)
},
},
// EVM tests can't access past blocks
//{
// name: "Get latest value based on confidence level",
// test: func(t T) {
// ctx := tests.Context(t)
// cr := tester.GetChainReader(t)
// require.NoError(t, cr.Bind(ctx, tester.GetBindings(t)))
//
// var prim1 uint64
// tester.SetUintLatestValue(t, 10)
// require.Error(t, cr.GetLatestValue(ctx, AnyContractName, MethodReturningAlterableUint64, primitives.Finalized, nil, &prim1))
//
// tester.GenerateBlocksTillConfidenceLevel(t, AnyContractName, EventName, primitives.Finalized)
// tester.SetUintLatestValue(t, 20)
//
// require.NoError(t, cr.GetLatestValue(ctx, AnyContractName, MethodReturningAlterableUint64, primitives.Finalized, nil, &prim1))
// assert.Equal(t, uint64(10), prim1)
//
// var prim2 uint64
// require.NoError(t, cr.GetLatestValue(ctx, AnyContractName, MethodReturningAlterableUint64, primitives.Unconfirmed, nil, &prim2))
// assert.Equal(t, uint64(20), prim2)
// },
//},
{
name: "Get latest value allows a contract name to resolve different contracts internally",
name: "Get latest value based on confidence level",
test: func(t T) {
ctx := tests.Context(t)
cr := tester.GetChainReader(t)
require.NoError(t, cr.Bind(ctx, tester.GetBindings(t)))

var prim uint64
require.NoError(t, cr.GetLatestValue(ctx, AnyContractName, DifferentMethodReturningUint64, primitives.Unconfirmed, nil, &prim))
var returnVal1 uint64
callArgs := ExpectedGetLatestValueArgs{
ContractName: AnyContractName,
ReadName: MethodReturningAlterableUint64,
ConfidenceLevel: primitives.Unconfirmed,
Params: nil,
ReturnVal: &returnVal1,
}

assert.Equal(t, AnyDifferentValueToReadWithoutAnArgument, prim)
var prim1 uint64
tester.SetUintLatestValue(t, 10, callArgs)
require.Error(t, cr.GetLatestValue(ctx, callArgs.ContractName, callArgs.ReadName, primitives.Finalized, callArgs.Params, &prim1))

tester.GenerateBlocksTillConfidenceLevel(t, AnyContractName, MethodReturningAlterableUint64, primitives.Finalized)
require.NoError(t, cr.GetLatestValue(ctx, AnyContractName, MethodReturningAlterableUint64, primitives.Finalized, nil, &prim1))
assert.Equal(t, uint64(10), prim1)

var returnVal2 uint64
callArgs2 := ExpectedGetLatestValueArgs{
ContractName: AnyContractName,
ReadName: MethodReturningAlterableUint64,
ConfidenceLevel: primitives.Unconfirmed,
Params: nil,
ReturnVal: returnVal2,
}

var prim2 uint64
tester.SetUintLatestValue(t, 20, callArgs2)
require.NoError(t, cr.GetLatestValue(ctx, callArgs.ContractName, callArgs.ReadName, callArgs.ConfidenceLevel, callArgs.Params, &prim2))
assert.Equal(t, uint64(20), prim2)
},
},
{
Expand Down Expand Up @@ -203,37 +205,36 @@ func runChainReaderGetLatestValueInterfaceTests[T TestingT[T]](t T, tester Chain
}, tester.MaxWaitTimeForEvents(), time.Millisecond*10)
},
},
// EVM tests can't access past blocks
//{
// name: "Get latest event based on provided confidence level",
// test: func(t T) {
// ctx := tests.Context(t)
// cr := tester.GetChainReader(t)
// require.NoError(t, cr.Bind(ctx, tester.GetBindings(t)))
// ts1 := CreateTestStruct[T](2, tester)
// tester.TriggerEvent(t, &ts1)
//
// result := &TestStruct{}
// assert.Eventually(t, func() bool {
// err := cr.GetLatestValue(ctx, AnyContractName, EventName, primitives.Finalized, nil, &result)
// return err != nil && assert.ErrorContains(t, err, types.ErrNotFound.Error())
// }, tester.MaxWaitTimeForEvents(), time.Millisecond*10)
//
// tester.GenerateBlocksTillConfidenceLevel(t, AnyContractName, EventName, primitives.Finalized)
// ts2 := CreateTestStruct[T](3, tester)
// tester.TriggerEvent(t, &ts2)
//
// assert.Eventually(t, func() bool {
// err := cr.GetLatestValue(ctx, AnyContractName, EventName, primitives.Finalized, nil, &result)
// return err == nil && reflect.DeepEqual(result, &ts1)
// }, tester.MaxWaitTimeForEvents(), time.Millisecond*10)
//
// assert.Eventually(t, func() bool {
// err := cr.GetLatestValue(ctx, AnyContractName, EventName, primitives.Unconfirmed, nil, &result)
// return err == nil && reflect.DeepEqual(result, &ts2)
// }, tester.MaxWaitTimeForEvents(), time.Millisecond*10)
// },
//},
{
name: "Get latest event based on provided confidence level",
test: func(t T) {
ctx := tests.Context(t)
cr := tester.GetChainReader(t)
require.NoError(t, cr.Bind(ctx, tester.GetBindings(t)))
ts1 := CreateTestStruct[T](2, tester)
tester.TriggerEvent(t, &ts1)

result := &TestStruct{}
assert.Eventually(t, func() bool {
err := cr.GetLatestValue(ctx, AnyContractName, EventName, primitives.Finalized, nil, &result)
return err != nil && assert.ErrorContains(t, err, types.ErrNotFound.Error())
}, tester.MaxWaitTimeForEvents(), time.Millisecond*10)

tester.GenerateBlocksTillConfidenceLevel(t, AnyContractName, EventName, primitives.Finalized)
ts2 := CreateTestStruct[T](3, tester)
tester.TriggerEvent(t, &ts2)

assert.Eventually(t, func() bool {
err := cr.GetLatestValue(ctx, AnyContractName, EventName, primitives.Finalized, nil, &result)
return err == nil && reflect.DeepEqual(result, &ts1)
}, tester.MaxWaitTimeForEvents(), time.Millisecond*10)

assert.Eventually(t, func() bool {
err := cr.GetLatestValue(ctx, AnyContractName, EventName, primitives.Unconfirmed, nil, &result)
return err == nil && reflect.DeepEqual(result, &ts2)
}, tester.MaxWaitTimeForEvents(), time.Millisecond*10)
},
},
{
name: "Get latest value returns not found if event was never triggered",
test: func(t T) {
Expand Down
12 changes: 12 additions & 0 deletions pkg/types/interfacetests/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (

"github.com/smartcontractkit/libocr/commontypes"

"github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives"
"github.com/smartcontractkit/chainlink-common/pkg/utils/tests"
)

Expand Down Expand Up @@ -35,6 +36,17 @@ func runTests[T TestingT[T]](t T, tester BasicTester[T], tests []testcase[T]) {
}
}

type ExpectedGetLatestValueArgs struct {
ContractName, ReadName string
ConfidenceLevel primitives.ConfidenceLevel
Params, ReturnVal any
}

func (e ExpectedGetLatestValueArgs) String() string {
return fmt.Sprintf("ContractName: %s, ReadName: %s, ConfidenceLevel: %s, Params: %v, ReturnVal: %v",
e.ContractName, e.ReadName, e.ConfidenceLevel, e.Params, e.ReturnVal)
}

type InnerTestStruct struct {
I int
S string
Expand Down

0 comments on commit 3df55c8

Please sign in to comment.