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  }