github.com/koko1123/flow-go-1@v0.29.6/engine/access/state_stream/api_test.go (about) 1 package state_stream 2 3 import ( 4 "bytes" 5 "context" 6 "math/rand" 7 "testing" 8 "time" 9 10 "github.com/ipfs/go-datastore" 11 dssync "github.com/ipfs/go-datastore/sync" 12 "github.com/stretchr/testify/assert" 13 "github.com/stretchr/testify/require" 14 "github.com/stretchr/testify/suite" 15 16 "github.com/koko1123/flow-go-1/engine/common/rpc/convert" 17 "github.com/koko1123/flow-go-1/ledger" 18 "github.com/koko1123/flow-go-1/ledger/common/testutils" 19 "github.com/koko1123/flow-go-1/module/blobs" 20 "github.com/koko1123/flow-go-1/module/executiondatasync/execution_data" 21 storagemock "github.com/koko1123/flow-go-1/storage/mock" 22 "github.com/koko1123/flow-go-1/utils/unittest" 23 ) 24 25 type Suite struct { 26 suite.Suite 27 28 headers *storagemock.Headers 29 seals *storagemock.Seals 30 results *storagemock.ExecutionResults 31 } 32 33 func TestHandler(t *testing.T) { 34 suite.Run(t, new(Suite)) 35 } 36 37 func (suite *Suite) SetupTest() { 38 rand.Seed(time.Now().UnixNano()) 39 suite.headers = storagemock.NewHeaders(suite.T()) 40 suite.seals = storagemock.NewSeals(suite.T()) 41 suite.results = storagemock.NewExecutionResults(suite.T()) 42 } 43 44 func (suite *Suite) TestGetExecutionDataByBlockID() { 45 46 // create the handler with the mock 47 bs := blobs.NewBlobstore(dssync.MutexWrap(datastore.NewMapDatastore())) 48 eds := execution_data.NewExecutionDataStore(bs, execution_data.DefaultSerializer) 49 client := New(suite.headers, suite.seals, suite.results, eds) 50 51 // mock parameters 52 ctx := context.Background() 53 blockHeader := unittest.BlockHeaderFixture() 54 55 seals := unittest.BlockSealsFixture(1)[0] 56 results := unittest.ExecutionResultFixture() 57 numChunks := 5 58 minSerializedSize := 5 * execution_data.DefaultMaxBlobSize 59 chunks := make([]*execution_data.ChunkExecutionData, numChunks) 60 61 for i := 0; i < numChunks; i++ { 62 chunks[i] = generateChunkExecutionData(suite.T(), uint64(minSerializedSize)) 63 } 64 65 execData := &execution_data.BlockExecutionData{ 66 BlockID: blockHeader.ID(), 67 ChunkExecutionDatas: chunks, 68 } 69 70 execDataRes, err := convert.BlockExecutionDataToMessage(execData) 71 require.Nil(suite.T(), err) 72 73 suite.headers.On("ByBlockID", blockHeader.ID()).Return(blockHeader, nil) 74 suite.seals.On("FinalizedSealForBlock", blockHeader.ID()).Return(seals, nil) 75 suite.results.On("ByID", seals.ResultID).Return(results, nil) 76 suite.Run("happy path TestGetExecutionDataByBlockID success", func() { 77 resID, err := eds.AddExecutionData(ctx, execData) 78 assert.NoError(suite.T(), err) 79 results.ExecutionDataID = resID 80 res, err := client.GetExecutionDataByBlockID(ctx, blockHeader.ID()) 81 assert.Equal(suite.T(), execDataRes, res) 82 assert.NoError(suite.T(), err) 83 }) 84 85 suite.Run("missing exec data for TestGetExecutionDataByBlockID failure", func() { 86 results.ExecutionDataID = unittest.IdentifierFixture() 87 execDataRes, err := client.GetExecutionDataByBlockID(ctx, blockHeader.ID()) 88 assert.Nil(suite.T(), execDataRes) 89 var blobNotFoundError *execution_data.BlobNotFoundError 90 assert.ErrorAs(suite.T(), err, &blobNotFoundError) 91 }) 92 93 suite.headers.AssertExpectations(suite.T()) 94 suite.seals.AssertExpectations(suite.T()) 95 suite.results.AssertExpectations(suite.T()) 96 } 97 98 func generateChunkExecutionData(t *testing.T, minSerializedSize uint64) *execution_data.ChunkExecutionData { 99 ced := &execution_data.ChunkExecutionData{ 100 TrieUpdate: testutils.TrieUpdateFixture(1, 1, 8), 101 } 102 103 size := 1 104 105 for { 106 buf := &bytes.Buffer{} 107 require.NoError(t, execution_data.DefaultSerializer.Serialize(buf, ced)) 108 if buf.Len() >= int(minSerializedSize) { 109 return ced 110 } 111 112 v := make([]byte, size) 113 _, _ = rand.Read(v) 114 115 k, err := ced.TrieUpdate.Payloads[0].Key() 116 require.NoError(t, err) 117 118 ced.TrieUpdate.Payloads[0] = ledger.NewPayload(k, v) 119 size *= 2 120 } 121 }