@@ -26,11 +26,13 @@ import (
26
26
"time"
27
27
28
28
"google.golang.org/grpc"
29
+ "google.golang.org/grpc/balancer"
29
30
"google.golang.org/grpc/codes"
30
31
"google.golang.org/grpc/credentials/insecure"
31
32
"google.golang.org/grpc/internal/grpcsync"
32
33
"google.golang.org/grpc/internal/stubserver"
33
34
rlstest "google.golang.org/grpc/internal/testutils/rls"
35
+ "google.golang.org/grpc/internal/testutils/stats"
34
36
"google.golang.org/grpc/metadata"
35
37
"google.golang.org/grpc/status"
36
38
"google.golang.org/protobuf/types/known/durationpb"
@@ -246,6 +248,115 @@ func (s) TestPick_DataCacheMiss_PendingEntryExists(t *testing.T) {
246
248
}
247
249
}
248
250
251
+ // Test_RLSDefaultTargetPicksMetric tests the default target picks metric. It
252
+ // configures an RLS Balancer which specifies to route to the default target in
253
+ // the RLS Configuration, and makes an RPC on a Channel containing this RLS
254
+ // Balancer. This test then asserts a default target picks metric is emitted,
255
+ // and target pick or failed pick metric is not emitted.
256
+ func (s ) Test_RLSDefaultTargetPicksMetric (t * testing.T ) {
257
+ // Start an RLS server and set the throttler to always throttle requests.
258
+ rlsServer , _ := rlstest .SetupFakeRLSServer (t , nil )
259
+ overrideAdaptiveThrottler (t , alwaysThrottlingThrottler ())
260
+
261
+ // Build RLS service config with a default target.
262
+ rlsConfig := buildBasicRLSConfigWithChildPolicy (t , t .Name (), rlsServer .Address )
263
+ defBackendCh , defBackendAddress := startBackend (t )
264
+ rlsConfig .RouteLookupConfig .DefaultTarget = defBackendAddress
265
+
266
+ // Register a manual resolver and push the RLS service config through it.
267
+ r := startManualResolverWithConfig (t , rlsConfig )
268
+
269
+ tmr := stats .NewTestMetricsRecorder (t )
270
+ cc , err := grpc .Dial (r .Scheme ()+ ":///" , grpc .WithResolvers (r ), grpc .WithTransportCredentials (insecure .NewCredentials ()), grpc .WithStatsHandler (tmr ))
271
+ if err != nil {
272
+ t .Fatalf ("grpc.Dial() failed: %v" , err )
273
+ }
274
+ defer cc .Close ()
275
+
276
+ // Make an RPC and ensure it gets routed to the default target.
277
+ ctx , cancel := context .WithTimeout (context .Background (), defaultTestTimeout )
278
+ defer cancel ()
279
+ makeTestRPCAndExpectItToReachBackend (ctx , t , cc , defBackendCh )
280
+
281
+ tmr .AssertDataForMetric ("grpc.lb.rls.default_target_picks" , 1 )
282
+ tmr .AssertNoDataForMetric ("grpc.lb.rls.failed_picks" )
283
+ tmr .AssertNoDataForMetric ("grpc.lb.rls.target_picks" )
284
+ }
285
+
286
+ // Test_RLSTargetPicksMetric tests the target picks metric. It configures an RLS
287
+ // Balancer which specifies to route to a target through a RouteLookupResponse,
288
+ // and makes an RPC on a Channel containing this RLS Balancer. This test then
289
+ // asserts a target picks metric is emitted, and default target pick or failed
290
+ // pick metric is not emitted.
291
+ func (s ) Test_RLSTargetPicksMetric (t * testing.T ) {
292
+ // Start an RLS server and set the throttler to never throttle requests.
293
+ rlsServer , _ := rlstest .SetupFakeRLSServer (t , nil )
294
+ overrideAdaptiveThrottler (t , neverThrottlingThrottler ())
295
+
296
+ // Build the RLS config without a default target.
297
+ rlsConfig := buildBasicRLSConfigWithChildPolicy (t , t .Name (), rlsServer .Address )
298
+
299
+ // Start a test backend, and setup the fake RLS server to return this as a
300
+ // target in the RLS response.
301
+ testBackendCh , testBackendAddress := startBackend (t )
302
+ rlsServer .SetResponseCallback (func (context.Context , * rlspb.RouteLookupRequest ) * rlstest.RouteLookupResponse {
303
+ return & rlstest.RouteLookupResponse {Resp : & rlspb.RouteLookupResponse {Targets : []string {testBackendAddress }}}
304
+ })
305
+
306
+ // Register a manual resolver and push the RLS service config through it.
307
+ r := startManualResolverWithConfig (t , rlsConfig )
308
+
309
+ tmr := stats .NewTestMetricsRecorder (t )
310
+ // Dial the backend.
311
+ cc , err := grpc .Dial (r .Scheme ()+ ":///" , grpc .WithResolvers (r ), grpc .WithTransportCredentials (insecure .NewCredentials ()), grpc .WithStatsHandler (tmr ))
312
+ if err != nil {
313
+ t .Fatalf ("grpc.Dial() failed: %v" , err )
314
+ }
315
+ defer cc .Close ()
316
+
317
+ // Make an RPC and ensure it gets routed to the test backend.
318
+ ctx , cancel := context .WithTimeout (context .Background (), defaultTestTimeout )
319
+ defer cancel ()
320
+ makeTestRPCAndExpectItToReachBackend (ctx , t , cc , testBackendCh )
321
+ tmr .AssertDataForMetric ("grpc.lb.rls.target_picks" , 1 )
322
+ tmr .AssertNoDataForMetric ("grpc.lb.rls.failed_picks" )
323
+ tmr .AssertNoDataForMetric ("grpc.lb.rls.default_target_picks" )
324
+ }
325
+
326
+ // Test_RLSFailedPicksMetric tests the failed picks metric. It configures an RLS
327
+ // Balancer to fail a pick with unavailable, and makes an RPC on a Channel
328
+ // containing this RLS Balancer. This test then asserts a failed picks metric is
329
+ // emitted, and default target pick or target pick metric is not emitted.
330
+ func (s ) Test_RLSFailedPicksMetric (t * testing.T ) {
331
+ // Start an RLS server and set the throttler to never throttle requests.
332
+ rlsServer , _ := rlstest .SetupFakeRLSServer (t , nil )
333
+ overrideAdaptiveThrottler (t , neverThrottlingThrottler ())
334
+
335
+ // Build an RLS config without a default target.
336
+ rlsConfig := buildBasicRLSConfigWithChildPolicy (t , t .Name (), rlsServer .Address )
337
+
338
+ // Register a manual resolver and push the RLS service config through it.
339
+ r := startManualResolverWithConfig (t , rlsConfig )
340
+
341
+ tmr := stats .NewTestMetricsRecorder (t )
342
+ // Dial the backend.
343
+ cc , err := grpc .Dial (r .Scheme ()+ ":///" , grpc .WithResolvers (r ), grpc .WithTransportCredentials (insecure .NewCredentials ()), grpc .WithStatsHandler (tmr ))
344
+ if err != nil {
345
+ t .Fatalf ("grpc.Dial() failed: %v" , err )
346
+ }
347
+ defer cc .Close ()
348
+
349
+ // Make an RPC and expect it to fail with deadline exceeded error. We use a
350
+ // smaller timeout to ensure that the test doesn't run very long.
351
+ ctx , cancel := context .WithTimeout (context .Background (), defaultTestShortTimeout )
352
+ defer cancel ()
353
+ makeTestRPCAndVerifyError (ctx , t , cc , codes .Unavailable , errors .New ("RLS response's target list does not contain any entries for key" ))
354
+
355
+ tmr .AssertDataForMetric ("grpc.lb.rls.failed_picks" , 1 )
356
+ tmr .AssertNoDataForMetric ("grpc.lb.rls.target_picks" )
357
+ tmr .AssertNoDataForMetric ("grpc.lb.rls.default_target_picks" )
358
+ }
359
+
249
360
// Test verifies the scenario where there is a matching entry in the data cache
250
361
// which is valid and there is no pending request. The pick is expected to be
251
362
// delegated to the child policy.
@@ -256,7 +367,6 @@ func (s) TestPick_DataCacheHit_NoPendingEntry_ValidEntry(t *testing.T) {
256
367
257
368
// Build the RLS config without a default target.
258
369
rlsConfig := buildBasicRLSConfigWithChildPolicy (t , t .Name (), rlsServer .Address )
259
-
260
370
// Start a test backend, and setup the fake RLS server to return this as a
261
371
// target in the RLS response.
262
372
testBackendCh , testBackendAddress := startBackend (t )
@@ -881,3 +991,41 @@ func TestIsFullMethodNameValid(t *testing.T) {
881
991
})
882
992
}
883
993
}
994
+
995
+ // Tests the conversion of the child pickers error to the pick result attribute.
996
+ func (s ) TestChildPickResultError (t * testing.T ) {
997
+ tests := []struct {
998
+ name string
999
+ err error
1000
+ want string
1001
+ }{
1002
+ {
1003
+ name : "nil" ,
1004
+ err : nil ,
1005
+ want : "complete" ,
1006
+ },
1007
+ {
1008
+ name : "errNoSubConnAvailable" ,
1009
+ err : balancer .ErrNoSubConnAvailable ,
1010
+ want : "queue" ,
1011
+ },
1012
+ {
1013
+ name : "status error" ,
1014
+ err : status .Error (codes .Unimplemented , "unimplemented" ),
1015
+ want : "drop" ,
1016
+ },
1017
+ {
1018
+ name : "other error" ,
1019
+ err : errors .New ("some error" ),
1020
+ want : "fail" ,
1021
+ },
1022
+ }
1023
+
1024
+ for _ , test := range tests {
1025
+ t .Run (test .name , func (t * testing.T ) {
1026
+ if got := errToPickResult (test .err ); got != test .want {
1027
+ t .Fatalf ("errToPickResult(%q) = %v, want %v" , test .err , got , test .want )
1028
+ }
1029
+ })
1030
+ }
1031
+ }
0 commit comments