@@ -8,13 +8,16 @@ package test
88
99import (
1010 "encoding/json"
11+ "os"
12+ "path/filepath"
1113 "testing"
1214 "time"
1315
1416 "github.com/hyperledger-labs/fabric-smart-client/integration/benchmark"
1517 benchviews "github.com/hyperledger-labs/fabric-smart-client/integration/benchmark/views"
1618 "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/grpc"
1719 "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/metrics/disabled"
20+ "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/view/grpc/client"
1821 "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/view/grpc/server"
1922 "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/view/grpc/server/protos"
2023 "github.com/hyperledger-labs/fabric-smart-client/platform/view/view"
@@ -23,12 +26,115 @@ import (
2326 "go.opentelemetry.io/otel/trace/noop"
2427)
2528
29+ // setupCrypto generates certificates and writes them to temporary files.
30+ // It returns the paths and a cleanup function to delete the files after the test.
31+ func setupCrypto (tb testing.TB ) (certPath , keyPath string ) {
32+ // 1. Call your helper to get PEM bytes
33+ keyPEM , certPEM , err := makeSelfSignedCert ()
34+ require .NoError (tb , err )
35+
36+ // 2. Create Temp Directory
37+ tmpDir := tb .TempDir ()
38+
39+ certPath = filepath .Join (tmpDir , "cert.pem" )
40+ keyPath = filepath .Join (tmpDir , "key.pem" )
41+
42+ // 3. Write the PEM bytes directly to files
43+ err = os .WriteFile (certPath , certPEM , 0644 )
44+ require .NoError (tb , err )
45+
46+ err = os .WriteFile (keyPath , keyPEM , 0600 )
47+ require .NoError (tb , err )
48+
49+ return certPath , keyPath
50+ }
51+
52+ // --- Option Types ---
53+
54+ type serverConfig struct {
55+ workload view.View
56+ signer client.SigningIdentity
57+ idProvider * benchmark.MockIdentityProvider
58+ }
59+
60+ type clientConfig struct {
61+ signer client.SigningIdentity
62+ }
63+
64+ type ServerOption func (tb testing.TB , c * serverConfig )
65+ type ClientOption func (tb testing.TB , c * clientConfig )
66+
67+ // --- Server Options ---
68+
69+ func WithCPUWorkload (n int ) ServerOption {
70+ return func (tb testing.TB , c * serverConfig ) {
71+ params := & benchviews.CPUParams {N : n }
72+ input , _ := json .Marshal (params )
73+ factory := & benchviews.CPUViewFactory {}
74+ v , err := factory .NewView (input )
75+ require .NoError (tb , err )
76+ c .workload = v
77+ }
78+ }
79+
80+ func WithECDSAWorkload () ServerOption {
81+ return func (tb testing.TB , c * serverConfig ) {
82+ params := & benchviews.ECDSASignParams {}
83+ input , _ := json .Marshal (params )
84+ factory := & benchviews.ECDSASignViewFactory {}
85+ v , err := factory .NewView (input )
86+ require .NoError (tb , err )
87+ c .workload = v
88+ }
89+ }
90+
91+ func WithServerMockSigner (id string ) ServerOption {
92+ return func (tb testing.TB , c * serverConfig ) {
93+ mIdentity := view .Identity (id )
94+ c .signer = & benchmark.MockSigner {
95+ SerializeFunc : func () ([]byte , error ) { return mIdentity .Bytes (), nil },
96+ SignFunc : func (b []byte ) ([]byte , error ) { return b , nil },
97+ }
98+ c .idProvider = & benchmark.MockIdentityProvider {DefaultSigner : mIdentity }
99+ }
100+ }
101+
102+ func WithServerECDSASigner (certPath , keyPath string ) ServerOption {
103+ return func (tb testing.TB , c * serverConfig ) {
104+ signer , err := client .NewX509SigningIdentity (certPath , keyPath )
105+ require .NoError (tb , err )
106+ c .signer = signer
107+ serialized , _ := signer .Serialize ()
108+ c .idProvider = & benchmark.MockIdentityProvider {DefaultSigner : view .Identity (serialized )}
109+ }
110+ }
111+
112+ // --- Client Options ---
113+
114+ func WithClientMockSigner (id string ) ClientOption {
115+ return func (tb testing.TB , c * clientConfig ) {
116+ mIdentity := view .Identity (id )
117+ c .signer = & benchmark.MockSigner {
118+ SerializeFunc : func () ([]byte , error ) { return mIdentity .Bytes (), nil },
119+ SignFunc : func (b []byte ) ([]byte , error ) { return b , nil },
120+ }
121+ }
122+ }
123+
124+ func WithClientECDSASigner (certPath , keyPath string ) ClientOption {
125+ return func (tb testing.TB , c * clientConfig ) {
126+ signer , err := client .NewX509SigningIdentity (certPath , keyPath )
127+ require .NoError (tb , err )
128+ c .signer = signer
129+ }
130+ }
131+
26132func BenchmarkGRPCSingleConnectionCPU (b * testing.B ) {
27- srvEndpoint := setupServer (b , "cpu" )
133+ srvEndpoint := setupServer (b , WithServerMockSigner ( "default-server-id" ), WithCPUWorkload ( 200000 ) )
28134 b .ResetTimer ()
29135
30136 // we share a single connection among all client goroutines
31- cli , closeF := setupClient (b , srvEndpoint )
137+ cli , closeF := setupClient (b , srvEndpoint , WithClientMockSigner ( "default-client-id" ) )
32138 defer closeF ()
33139
34140 b .RunParallel (func (pb * testing.PB ) {
@@ -42,12 +148,12 @@ func BenchmarkGRPCSingleConnectionCPU(b *testing.B) {
42148}
43149
44150func BenchmarkGRPCMultiConnectionCPU (b * testing.B ) {
45- srvEndpoint := setupServer (b , "cpu" )
151+ srvEndpoint := setupServer (b , WithServerMockSigner ( "default-server-id" ), WithCPUWorkload ( 200000 ) )
46152 b .ResetTimer ()
47153
48154 b .RunParallel (func (pb * testing.PB ) {
49155 // each goroutine gets its own client + connection
50- cli , closeF := setupClient (b , srvEndpoint )
156+ cli , closeF := setupClient (b , srvEndpoint , WithClientMockSigner ( "default-client-id" ) )
51157 defer closeF ()
52158
53159 for pb .Next () {
@@ -61,12 +167,47 @@ func BenchmarkGRPCMultiConnectionCPU(b *testing.B) {
61167}
62168
63169// --- ECDSA Workload Benchmarks ---
170+ func BenchmarkGRPCSingleConnectionECDSAWithMockSigner (b * testing.B ) {
171+ srvEndpoint := setupServer (b , WithECDSAWorkload (), WithServerMockSigner ("default-server-id" ))
172+ b .ResetTimer ()
173+
174+ cli , closeF := setupClient (b , srvEndpoint , WithClientMockSigner ("default-client-id" ))
175+ defer closeF ()
176+ b .RunParallel (func (pb * testing.PB ) {
177+ for pb .Next () {
178+ resp , err := cli .CallViewWithContext (b .Context (), "fid" , nil )
179+ require .NoError (b , err )
180+ require .NotNil (b , resp )
181+ }
182+ })
183+ benchmark .ReportTPS (b )
184+ }
64185
65- func BenchmarkGRPCSingleConnectionECDSA (b * testing.B ) {
66- srvEndpoint := setupServer (b , "ecdsa" )
186+ func BenchmarkGRPCMultiConnectionECDSAWithMockSigner (b * testing.B ) {
187+ srvEndpoint := setupServer (b , WithECDSAWorkload (), WithServerMockSigner ( "default-server-id" ) )
67188 b .ResetTimer ()
189+ b .RunParallel (func (pb * testing.PB ) {
190+ cli , closeF := setupClient (b , srvEndpoint , WithClientMockSigner ("default-client-id" ))
191+ defer closeF ()
68192
69- cli , closeF := setupClient (b , srvEndpoint )
193+ for pb .Next () {
194+ resp , err := cli .CallViewWithContext (b .Context (), "fid" , nil )
195+ require .NoError (b , err )
196+ require .NotNil (b , resp )
197+ }
198+ })
199+ benchmark .ReportTPS (b )
200+ }
201+
202+ // --- ECDSA Workload Benchmarks real gRPC crypto ---
203+
204+ func BenchmarkGRPCSingleConnectionECDSAWithECDSASigner (b * testing.B ) {
205+ cPath , kPath := setupCrypto (b )
206+
207+ srvEndpoint := setupServer (b , WithECDSAWorkload (), WithServerECDSASigner (cPath , kPath ))
208+ b .ResetTimer ()
209+
210+ cli , closeF := setupClient (b , srvEndpoint , WithClientECDSASigner (cPath , kPath ))
70211 defer closeF ()
71212 b .RunParallel (func (pb * testing.PB ) {
72213 for pb .Next () {
@@ -78,11 +219,13 @@ func BenchmarkGRPCSingleConnectionECDSA(b *testing.B) {
78219 benchmark .ReportTPS (b )
79220}
80221
81- func BenchmarkGRPCMultiConnectionECDSA (b * testing.B ) {
82- srvEndpoint := setupServer (b , "ecdsa" )
222+ func BenchmarkGRPCMultiConnectionECDSAWithECDSASigner (b * testing.B ) {
223+ cPath , kPath := setupCrypto (b )
224+
225+ srvEndpoint := setupServer (b , WithECDSAWorkload (), WithServerECDSASigner (cPath , kPath ))
83226 b .ResetTimer ()
84227 b .RunParallel (func (pb * testing.PB ) {
85- cli , closeF := setupClient (b , srvEndpoint )
228+ cli , closeF := setupClient (b , srvEndpoint , WithClientECDSASigner ( cPath , kPath ) )
86229 defer closeF ()
87230
88231 for pb .Next () {
@@ -94,23 +237,23 @@ func BenchmarkGRPCMultiConnectionECDSA(b *testing.B) {
94237 benchmark .ReportTPS (b )
95238}
96239
97- func setupServer (tb testing.TB , workloadType string ) string {
240+ func setupServer (tb testing.TB , opts ... ServerOption ) string {
98241 tb .Helper ()
99242
100- mDefaultIdentity := view .Identity ("server identity" )
101- mSigner := & benchmark.MockSigner {
102- SerializeFunc : func () ([]byte , error ) {
103- return mDefaultIdentity .Bytes (), nil
104- },
105- SignFunc : func (bytes []byte ) ([]byte , error ) {
106- return bytes , nil
107- },
243+ cfg := & serverConfig {}
244+ // Apply options
245+ for _ , opt := range opts {
246+ opt (tb , cfg )
108247 }
109- mIdentityProvider := & benchmark.MockIdentityProvider {DefaultSigner : mDefaultIdentity }
110- mSigService := & benchmark.MockSignerProvider {DefaultSigner : mSigner }
111248
249+ // Validate that the options successfully populated the config
250+ require .NotNil (tb , cfg .workload , "server workload was not configured by options" )
251+ require .NotNil (tb , cfg .signer , "server signer was not configured by options" )
252+ require .NotNil (tb , cfg .idProvider , "server identity provider was not configured by options" )
253+
254+ mSigService := & benchmark.MockSignerProvider {DefaultSigner : cfg .signer }
112255 // marshaller
113- tm , err := server .NewResponseMarshaler (mIdentityProvider , mSigService )
256+ tm , err := server .NewResponseMarshaler (cfg . idProvider , mSigService )
114257 require .NoError (tb , err )
115258 require .NotNil (tb , tm )
116259
@@ -133,28 +276,8 @@ func setupServer(tb testing.TB, workloadType string) string {
133276 srv , err := server .NewViewServiceServer (tm , & server.YesPolicyChecker {}, server .NewMetrics (& disabled.Provider {}), noop .NewTracerProvider ())
134277 require .NoError (tb , err )
135278 require .NotNil (tb , srv )
136-
137- var v view.View
138- switch workloadType {
139- case "cpu" :
140- parms := & benchviews.CPUParams {N : 200000 }
141- input , _ := json .Marshal (parms )
142- factory := & benchviews.CPUViewFactory {}
143- v , _ = factory .NewView (input )
144- case "ecdsa" :
145- parms := & benchviews.ECDSASignParams {}
146- input , _ := json .Marshal (parms )
147- factory := & benchviews.ECDSASignViewFactory {}
148- v , _ = factory .NewView (input )
149- default :
150- tb .Fatalf ("unknown workload type: %s" , workloadType )
151- }
152-
153279 // our view manager
154- vm := & benchmark.MockViewManager {Constructor : func () view.View {
155- return v
156- }}
157-
280+ vm := & benchmark.MockViewManager {Constructor : func () view.View { return cfg .workload }}
158281 // register view manager wit grpc impl
159282 server .InstallViewHandler (vm , srv , noop .NewTracerProvider ())
160283
@@ -170,19 +293,18 @@ func setupServer(tb testing.TB, workloadType string) string {
170293 return grpcSrv .Address ()
171294}
172295
173- func setupClient (tb testing.TB , srvEndpoint string ) (* benchmark.ViewClient , func ()) {
296+ func setupClient (tb testing.TB , srvEndpoint string , opts ... ClientOption ) (* benchmark.ViewClient , func ()) {
174297 tb .Helper ()
175298
176- mDefaultIdentity := view .Identity ("client identity" )
177- mSigner := & benchmark.MockSigner {
178- SerializeFunc : func () ([]byte , error ) {
179- return mDefaultIdentity .Bytes (), nil
180- },
181- SignFunc : func (bytes []byte ) ([]byte , error ) {
182- return bytes , nil
183- }}
299+ cfg := & clientConfig {}
300+ // Apply options
301+ for _ , opt := range opts {
302+ opt (tb , cfg )
303+ }
304+ // Validate that the signer is present before proceeding
305+ require .NotNil (tb , cfg .signer , "client signer was not configured by options" )
184306
185- signerIdentity , err := mSigner .Serialize ()
307+ signerIdentity , err := cfg . signer .Serialize ()
186308 require .NoError (tb , err )
187309
188310 grpcClient , err := grpc .NewGRPCClient (grpc.ClientConfig {
@@ -206,7 +328,7 @@ func setupClient(tb testing.TB, srvEndpoint string) (*benchmark.ViewClient, func
206328 require .NoError (tb , err )
207329
208330 cli := & benchmark.ViewClient {
209- SignF : mSigner .Sign ,
331+ SignF : cfg . signer .Sign ,
210332 Creator : signerIdentity ,
211333 TLSCertHash : tlsCertHash ,
212334 Client : protos .NewViewServiceClient (conn ),
0 commit comments