@@ -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
+ rlsServer , _ := rlstest .SetupFakeRLSServer (t , nil )
293
+ overrideAdaptiveThrottler (t , neverThrottlingThrottler ())
294
+
295
+ // Build the RLS config without a default target.
296
+ rlsConfig := buildBasicRLSConfigWithChildPolicy (t , t .Name (), rlsServer .Address )
297
+
298
+ // Start a test backend, and setup the fake RLS server to return this as a
299
+ // target in the RLS response.
300
+ testBackendCh , testBackendAddress := startBackend (t )
301
+ rlsServer .SetResponseCallback (func (context.Context , * rlspb.RouteLookupRequest ) * rlstest.RouteLookupResponse {
302
+ return & rlstest.RouteLookupResponse {Resp : & rlspb.RouteLookupResponse {Targets : []string {testBackendAddress }}}
303
+ })
304
+
305
+ // Register a manual resolver and push the RLS service config through it.
306
+ r := startManualResolverWithConfig (t , rlsConfig )
307
+
308
+ tmr := stats .NewTestMetricsRecorder (t )
309
+ // Dial the backend.
310
+ cc , err := grpc .Dial (r .Scheme ()+ ":///" , grpc .WithResolvers (r ), grpc .WithTransportCredentials (insecure .NewCredentials ()), grpc .WithStatsHandler (tmr ))
311
+ if err != nil {
312
+ t .Fatalf ("grpc.Dial() failed: %v" , err )
313
+ }
314
+ defer cc .Close ()
315
+
316
+ // Make an RPC and ensure it gets routed to the test backend.
317
+ ctx , cancel := context .WithTimeout (context .Background (), defaultTestTimeout )
318
+ defer cancel ()
319
+ makeTestRPCAndExpectItToReachBackend (ctx , t , cc , testBackendCh )
320
+ tmr .AssertDataForMetric ("grpc.lb.rls.target_picks" , 1 )
321
+ tmr .AssertNoDataForMetric ("grpc.lb.rls.failed_picks" )
322
+ tmr .AssertNoDataForMetric ("grpc.lb.rls.default_target_picks" )
323
+ }
324
+
325
+ // Test_RLSFailedPicksMetric tests the failed picks metric. It configures an RLS
326
+ // Balancer to fail a pick with unavailable, and makes an RPC on a Channel
327
+ // containing this RLS Balancer. This test then asserts a failed picks metric is
328
+ // emitted, and default target pick or target pick metric is not emitted.
329
+ func (s ) Test_RLSFailedPicksMetric (t * testing.T ) {
330
+ // Start an RLS server and set the throttler to never throttle requests.
331
+ rlsServer , _ := rlstest .SetupFakeRLSServer (t , nil )
332
+ overrideAdaptiveThrottler (t , neverThrottlingThrottler ())
333
+
334
+ // Build an RLS config without a default target.
335
+ rlsConfig := buildBasicRLSConfigWithChildPolicy (t , t .Name (), rlsServer .Address )
336
+
337
+ // Register a manual resolver and push the RLS service config through it.
338
+ r := startManualResolverWithConfig (t , rlsConfig )
339
+
340
+ // attach a test metric recorder to channel, but also need to verify labels...
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