github.com/koko1123/flow-go-1@v0.29.6/module/jobqueue/sealed_header_reader_test.go (about) 1 package jobqueue_test 2 3 import ( 4 "testing" 5 6 "github.com/dgraph-io/badger/v3" 7 "github.com/stretchr/testify/assert" 8 "github.com/stretchr/testify/require" 9 10 "github.com/koko1123/flow-go-1/model/flow" 11 "github.com/koko1123/flow-go-1/module/jobqueue" 12 synctest "github.com/koko1123/flow-go-1/module/state_synchronization/requester/unittest" 13 "github.com/koko1123/flow-go-1/storage" 14 "github.com/koko1123/flow-go-1/utils/unittest" 15 ) 16 17 // TestSealedBlockHeaderReader evaluates that block reader correctly reads stored finalized blocks from the blocks storage and 18 // protocol state. 19 func TestSealedBlockHeaderReader(t *testing.T) { 20 RunWithReader(t, 10, func(reader *jobqueue.SealedBlockHeaderReader, blocks []*flow.Block) { 21 // the last block seals its parent 22 lastSealedBlock := blocks[len(blocks)-2] 23 24 // head of the reader is the last sealed block 25 head, err := reader.Head() 26 assert.NoError(t, err) 27 assert.Equal(t, lastSealedBlock.Header.Height, head, "head does not match last sealed block") 28 29 // retrieved blocks from block reader should be the same as the original blocks stored in it. 30 // all except the last block should be sealed 31 lastIndex := len(blocks) 32 for _, expected := range blocks[:lastIndex-1] { 33 index := expected.Header.Height 34 job, err := reader.AtIndex(index) 35 assert.NoError(t, err) 36 37 retrieved, err := jobqueue.JobToBlockHeader(job) 38 assert.NoError(t, err) 39 assert.Equal(t, expected.ID(), retrieved.ID()) 40 } 41 42 // ensure the last block returns a NotFound error 43 job, err := reader.AtIndex(uint64(lastIndex)) 44 assert.Nil(t, job) 45 assert.ErrorIs(t, err, storage.ErrNotFound) 46 }) 47 } 48 49 // RunWithReader is a test helper that sets up a block reader. 50 // It also provides a chain of specified number of finalized blocks ready to read by block reader, i.e., the protocol state is extended with the 51 // chain of blocks and the blocks are stored in blocks storage. 52 func RunWithReader( 53 t *testing.T, 54 blockCount int, 55 withBlockReader func(*jobqueue.SealedBlockHeaderReader, []*flow.Block), 56 ) { 57 require.Equal(t, blockCount%2, 0, "block count for this test should be even") 58 unittest.RunWithBadgerDB(t, func(db *badger.DB) { 59 60 blocks := make([]*flow.Block, blockCount) 61 blocksByHeight := make(map[uint64]*flow.Block, blockCount) 62 63 var seals []*flow.Header 64 parent := unittest.GenesisFixture().Header 65 for i := 0; i < blockCount; i++ { 66 seals = []*flow.Header{parent} 67 height := uint64(i) + 1 68 69 blocks[i] = unittest.BlockWithParentAndSeals(parent, seals) 70 blocksByHeight[height] = blocks[i] 71 72 parent = blocks[i].Header 73 } 74 75 snapshot := synctest.MockProtocolStateSnapshot(synctest.WithHead(seals[0])) 76 state := synctest.MockProtocolState(synctest.WithSealedSnapshot(snapshot)) 77 headerStorage := synctest.MockBlockHeaderStorage(synctest.WithByHeight(blocksByHeight)) 78 79 reader := jobqueue.NewSealedBlockHeaderReader(state, headerStorage) 80 81 withBlockReader(reader, blocks) 82 }) 83 }