github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/engine/access/rpc/connection/grpc_compression_benchmark_test.go (about)

     1  package connection
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  
     7  	"github.com/stretchr/testify/assert"
     8  	testifymock "github.com/stretchr/testify/mock"
     9  
    10  	"google.golang.org/grpc/encoding/gzip"
    11  
    12  	"github.com/onflow/flow-go/engine/common/grpc/compressor/deflate"
    13  	"github.com/onflow/flow-go/engine/common/grpc/compressor/snappy"
    14  	"github.com/onflow/flow-go/engine/common/rpc/convert"
    15  	"github.com/onflow/flow-go/model/flow"
    16  	"github.com/onflow/flow-go/module/metrics"
    17  	"github.com/onflow/flow-go/utils/grpcutils"
    18  	"github.com/onflow/flow-go/utils/unittest"
    19  
    20  	"github.com/onflow/flow/protobuf/go/flow/execution"
    21  )
    22  
    23  // BenchmarkWithGzipCompression benchmarks the gRPC request to execution nodes using gzip compressor.
    24  func BenchmarkWithGzipCompression(b *testing.B) {
    25  	runBenchmark(b, gzip.Name)
    26  }
    27  
    28  // BenchmarkWithSnappyCompression benchmarks the gRPC request to execution nodes using snappy compressor.
    29  func BenchmarkWithSnappyCompression(b *testing.B) {
    30  	runBenchmark(b, snappy.Name)
    31  }
    32  
    33  // BenchmarkWithDeflateCompression benchmarks the gRPC request to execution nodes using deflate compressor.
    34  func BenchmarkWithDeflateCompression(b *testing.B) {
    35  	runBenchmark(b, deflate.Name)
    36  }
    37  
    38  // runBenchmark is a helper function that performs the benchmarking for different compressors.
    39  func runBenchmark(b *testing.B, compressorName string) {
    40  	// create an execution node
    41  	en := new(executionNode)
    42  	en.start(b)
    43  	defer en.stop(b)
    44  
    45  	blockHeaders := getHeaders(5)
    46  	exeResults := make([]*execution.GetEventsForBlockIDsResponse_Result, len(blockHeaders))
    47  	for i := 0; i < len(blockHeaders); i++ {
    48  		exeResults[i] = &execution.GetEventsForBlockIDsResponse_Result{
    49  			BlockId:     convert.IdentifierToMessage(blockHeaders[i].ID()),
    50  			BlockHeight: blockHeaders[i].Height,
    51  			Events:      convert.EventsToMessages(getEvents(10)),
    52  		}
    53  	}
    54  	expectedEventsResponse := &execution.GetEventsForBlockIDsResponse{
    55  		Results: exeResults,
    56  	}
    57  
    58  	blockIDs := make([]flow.Identifier, len(blockHeaders))
    59  	for i, header := range blockHeaders {
    60  		blockIDs[i] = header.ID()
    61  	}
    62  	eventsReq := &execution.GetEventsForBlockIDsRequest{
    63  		BlockIds: convert.IdentifiersToMessages(blockIDs),
    64  		Type:     string(flow.EventAccountCreated),
    65  	}
    66  
    67  	en.handler.On("GetEventsForBlockIDs", testifymock.Anything, testifymock.Anything).
    68  		Return(expectedEventsResponse, nil)
    69  
    70  	// create the factory
    71  	connectionFactory := new(ConnectionFactoryImpl)
    72  	// set the execution grpc port
    73  	connectionFactory.ExecutionGRPCPort = en.port
    74  
    75  	// set metrics reporting
    76  	connectionFactory.AccessMetrics = metrics.NewNoopCollector()
    77  	connectionFactory.Manager = NewManager(
    78  		unittest.Logger(),
    79  		connectionFactory.AccessMetrics,
    80  		nil,
    81  		grpcutils.DefaultMaxMsgSize,
    82  		CircuitBreakerConfig{},
    83  		compressorName,
    84  	)
    85  
    86  	proxyConnectionFactory := ProxyConnectionFactory{
    87  		ConnectionFactory: connectionFactory,
    88  		targetAddress:     en.listener.Addr().String(),
    89  	}
    90  
    91  	// get an execution API client
    92  	client, _, err := proxyConnectionFactory.GetExecutionAPIClient("foo")
    93  	assert.NoError(b, err)
    94  
    95  	ctx := context.Background()
    96  	b.ResetTimer()
    97  	// make the call to the execution node
    98  	for i := 0; i < b.N; i++ {
    99  		_, err := client.GetEventsForBlockIDs(ctx, eventsReq)
   100  		assert.NoError(b, err)
   101  	}
   102  }
   103  
   104  // getEvents generates a slice of flow events with a specified length.
   105  func getEvents(n int) []flow.Event {
   106  	events := make([]flow.Event, n)
   107  	for i := range events {
   108  		events[i] = flow.Event{Type: flow.EventAccountCreated}
   109  	}
   110  	return events
   111  }
   112  
   113  // getHeaders generates a slice of flow headers with a specified length.
   114  func getHeaders(n int) []*flow.Header {
   115  	headers := make([]*flow.Header, n)
   116  	for i := range headers {
   117  		b := unittest.BlockFixture()
   118  		headers[i] = b.Header
   119  
   120  	}
   121  	return headers
   122  }