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 }