lotus/chain/events/tscache_test.go
Darko Brdareski 79453663b3
feat: Add additional test annotations ()
* Annotate api,proxy_util,blockstore_badger, policy tests

* Annotate splitstore: bsbadger / markset

* Annotate splitstore feature

* Annotate union/timed blockstore tests

* Annotate openrpc, diff_adt tests

* Annotate error,drand,events tests

* Annotate predicates_test

* Fix annotations

* Annotate tscache, gen tests

* Annotate fundmanager test

* Annotate repub and selection tests

* Annotate statetree_test

* Annotate forks_test

* Annotate searchwait_test.go

* Fix duplicated @@ symbols

* Annotate chain stmgr/store tests

* Annotate more (types) tests

* More tests annotated

* Annotate conformance chaos actor tests

* Annotate more integration tests

* Annotate journal system tests

* Annotate more tests.

* Annotate gas,head buffer behaviors

* Fix markset annotations

* doc: test annotations for the markets dagstore wrapper

* Annotate miner_api test in dagstore

* Annotate more test files

* Remove bad annotations from fsrepo

* Annotate wdpost system

* Remove bad annotations

* Renamce "conformance" to "chaos_actor" tests

* doc: stm annotations for blockheader & election proof tests

* Annotate remaining "A" tests

* annotate: stm for error_test

* memrepo_test.go

* Annotate "b" file tests

* message_test.go

* doc: stm annotate for fsrepo_test

* Annotate "c" file tests

* Annotate "D" test files

* message_test.go

* doc: stm annotate for chain, node/config & client

* docs: stm annotate node_test

* Annotate u,v,wl tests

* doc: stm annotations for various test files

* Annotate "T" test files

* doc: stm annotate for proxy_util_test & policy_test

* doc: stm annotate for various tests

* doc: final few stm annotations

* Add mempool unit tests

* Add two more memPool Add tests

* Update submodules

* Add check function tests

* Add stm annotations, refactor test helper

* Annotate api,proxy_util,blockstore_badger, policy tests

* Annotate splitstore: bsbadger / markset

solving merge conflicts

* Annotate splitstore feature

* Annotate union/timed blockstore tests

* Annotate openrpc, diff_adt tests

* Annotate error,drand,events tests

* Annotate predicates_test

* Fix annotations

* Annotate tscache, gen tests

* Annotate fundmanager test

* Annotate statetree_test

* Annotate forks_test

* Annotate searchwait_test.go

* Fix duplicated @@ symbols

* Annotate chain stmgr/store tests

* Annotate more (types) tests

* More tests annotated

* Annotate conformance chaos actor tests

* Annotate more integration tests

* Annotate journal system tests

* Annotate more tests.

* Annotate gas,head buffer behaviors

solve merge conflict

* Fix markset annotations

* Annotate miner_api test in dagstore

* Annotate more test files

* doc: test annotations for the markets dagstore wrapper

* Annotate wdpost system

* Renamce "conformance" to "chaos_actor" tests

* Annotate remaining "A" tests

* doc: stm annotations for blockheader & election proof tests

* annotate: stm for error_test

* Annotate "b" file tests

* memrepo_test.go

* Annotate "c" file tests

* message_test.go

* Annotate "D" test files

* doc: stm annotate for fsrepo_test

* Annotate u,v,wl tests

* message_test.go

* doc: stm annotate for chain, node/config & client

* docs: stm annotate node_test

* Annotate "T" test files

* doc: stm annotations for various test files

* Add mempool unit tests

solve merge conflict

* doc: stm annotate for proxy_util_test & policy_test

* doc: stm annotate for various tests

* doc: final few stm annotations

* Add two more memPool Add tests

* Update submodules

* Add check function tests

solve conflict

* Add stm annotations, refactor test helper

solve merge conflict

* Change CLI test kinds to "unit"

* Fix double merged test

* Fix ccupgrade_test merge

* Fix lint issues

* Add stm annotation to types_Test

* Test vectors submodule

* Add file annotation to burn_test

Co-authored-by: Nikola Divic <divicnikola@gmail.com>
Co-authored-by: TheMenko <themenkoprojects@gmail.com>
2022-03-16 18:37:34 +01:00

217 lines
6.1 KiB
Go

//stm: #unit
package events
import (
"context"
"testing"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/crypto"
"github.com/ipfs/go-cid"
"github.com/stretchr/testify/require"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/chain/types"
)
type tsCacheAPIFailOnStorageCall struct {
t *testing.T
}
func (tc *tsCacheAPIFailOnStorageCall) ChainGetTipSetAfterHeight(ctx context.Context, epoch abi.ChainEpoch, key types.TipSetKey) (*types.TipSet, error) {
tc.t.Fatal("storage call")
return &types.TipSet{}, nil
}
func (tc *tsCacheAPIFailOnStorageCall) ChainGetTipSetByHeight(ctx context.Context, epoch abi.ChainEpoch, key types.TipSetKey) (*types.TipSet, error) {
tc.t.Fatal("storage call")
return &types.TipSet{}, nil
}
func (tc *tsCacheAPIFailOnStorageCall) ChainHead(ctx context.Context) (*types.TipSet, error) {
tc.t.Fatal("storage call")
return &types.TipSet{}, nil
}
func (tc *tsCacheAPIFailOnStorageCall) ChainGetTipSet(ctx context.Context, tsk types.TipSetKey) (*types.TipSet, error) {
tc.t.Fatal("storage call")
return &types.TipSet{}, nil
}
type cacheHarness struct {
t *testing.T
miner address.Address
tsc *tipSetCache
height abi.ChainEpoch
}
func newCacheharness(t *testing.T) *cacheHarness {
a, err := address.NewFromString("t00")
require.NoError(t, err)
h := &cacheHarness{
t: t,
tsc: newTSCache(&tsCacheAPIFailOnStorageCall{t: t}, 50),
height: 75,
miner: a,
}
h.addWithParents(nil)
return h
}
func (h *cacheHarness) addWithParents(parents []cid.Cid) {
ts, err := types.NewTipSet([]*types.BlockHeader{{
Miner: h.miner,
Height: h.height,
ParentStateRoot: dummyCid,
Messages: dummyCid,
ParentMessageReceipts: dummyCid,
BlockSig: &crypto.Signature{Type: crypto.SigTypeBLS},
BLSAggregate: &crypto.Signature{Type: crypto.SigTypeBLS},
Parents: parents,
}})
require.NoError(h.t, err)
require.NoError(h.t, h.tsc.add(ts))
h.height++
}
func (h *cacheHarness) add() {
last, err := h.tsc.ChainHead(context.Background())
require.NoError(h.t, err)
h.addWithParents(last.Cids())
}
func (h *cacheHarness) revert() {
best, err := h.tsc.ChainHead(context.Background())
require.NoError(h.t, err)
err = h.tsc.revert(best)
require.NoError(h.t, err)
h.height--
}
func (h *cacheHarness) skip(n abi.ChainEpoch) {
h.height += n
}
func TestTsCache(t *testing.T) {
//stm: @EVENTS_CACHE_GET_CHAIN_HEAD_001, @EVENTS_CACHE_GET_001, @EVENTS_CACHE_ADD_001
h := newCacheharness(t)
for i := 0; i < 9000; i++ {
if i%90 > 60 {
h.revert()
} else {
h.add()
}
}
}
func TestTsCacheNulls(t *testing.T) {
//stm: @EVENTS_CACHE_GET_CHAIN_HEAD_001, @EVENTS_CACHE_GET_CHAIN_TIPSET_BEFORE_001, @EVENTS_CACHE_GET_CHAIN_TIPSET_AFTER_001
//stm: @EVENTS_CACHE_GET_001, @EVENTS_CACHE_ADD_001
ctx := context.Background()
h := newCacheharness(t)
h.add()
h.add()
h.add()
h.skip(5)
h.add()
h.add()
best, err := h.tsc.ChainHead(ctx)
require.NoError(t, err)
require.Equal(t, h.height-1, best.Height())
ts, err := h.tsc.ChainGetTipSetByHeight(ctx, h.height-1, types.EmptyTSK)
require.NoError(t, err)
require.Equal(t, h.height-1, ts.Height())
ts, err = h.tsc.ChainGetTipSetByHeight(ctx, h.height-2, types.EmptyTSK)
require.NoError(t, err)
require.Equal(t, h.height-2, ts.Height())
// Should skip the nulls and walk back to the last tipset.
ts, err = h.tsc.ChainGetTipSetByHeight(ctx, h.height-3, types.EmptyTSK)
require.NoError(t, err)
require.Equal(t, h.height-8, ts.Height())
ts, err = h.tsc.ChainGetTipSetByHeight(ctx, h.height-8, types.EmptyTSK)
require.NoError(t, err)
require.Equal(t, h.height-8, ts.Height())
best, err = h.tsc.ChainHead(ctx)
require.NoError(t, err)
require.NoError(t, h.tsc.revert(best))
best, err = h.tsc.ChainHead(ctx)
require.NoError(t, err)
require.NoError(t, h.tsc.revert(best))
best, err = h.tsc.ChainHead(ctx)
require.NoError(t, err)
require.Equal(t, h.height-8, best.Height())
h.skip(50)
h.add()
ts, err = h.tsc.ChainGetTipSetByHeight(ctx, h.height-1, types.EmptyTSK)
require.NoError(t, err)
require.Equal(t, h.height-1, ts.Height())
}
type tsCacheAPIStorageCallCounter struct {
t *testing.T
chainGetTipSetByHeight int
chainGetTipSetAfterHeight int
chainGetTipSet int
chainHead int
}
func (tc *tsCacheAPIStorageCallCounter) ChainGetTipSetByHeight(ctx context.Context, epoch abi.ChainEpoch, key types.TipSetKey) (*types.TipSet, error) {
tc.chainGetTipSetByHeight++
return &types.TipSet{}, nil
}
func (tc *tsCacheAPIStorageCallCounter) ChainGetTipSetAfterHeight(ctx context.Context, epoch abi.ChainEpoch, key types.TipSetKey) (*types.TipSet, error) {
tc.chainGetTipSetAfterHeight++
return &types.TipSet{}, nil
}
func (tc *tsCacheAPIStorageCallCounter) ChainHead(ctx context.Context) (*types.TipSet, error) {
tc.chainHead++
return &types.TipSet{}, nil
}
func (tc *tsCacheAPIStorageCallCounter) ChainGetTipSet(ctx context.Context, tsk types.TipSetKey) (*types.TipSet, error) {
tc.chainGetTipSet++
return &types.TipSet{}, nil
}
func TestTsCacheEmpty(t *testing.T) {
//stm: @EVENTS_CACHE_GET_CHAIN_HEAD_001
// Calling best on an empty cache should just call out to the chain API
callCounter := &tsCacheAPIStorageCallCounter{t: t}
tsc := newTSCache(callCounter, 50)
_, err := tsc.ChainHead(context.Background())
require.NoError(t, err)
require.Equal(t, 1, callCounter.chainHead)
}
func TestTsCacheSkip(t *testing.T) {
//stm: @EVENTS_CACHE_GET_CHAIN_HEAD_001, @EVENTS_CACHE_GET_001, @EVENTS_CACHE_ADD_001
h := newCacheharness(t)
ts, err := types.NewTipSet([]*types.BlockHeader{{
Miner: h.miner,
Height: h.height,
ParentStateRoot: dummyCid,
Messages: dummyCid,
ParentMessageReceipts: dummyCid,
BlockSig: &crypto.Signature{Type: crypto.SigTypeBLS},
BLSAggregate: &crypto.Signature{Type: crypto.SigTypeBLS},
// With parents that don't match the last block.
Parents: nil,
}})
require.NoError(h.t, err)
err = h.tsc.add(ts)
require.Error(t, err)
}