google.golang.org/grpc@v1.72.2/balancer/rls/picker_test.go (about)

     1  /*
     2   *
     3   * Copyright 2021 gRPC authors.
     4   *
     5   * Licensed under the Apache License, Version 2.0 (the "License");
     6   * you may not use this file except in compliance with the License.
     7   * You may obtain a copy of the License at
     8   *
     9   *     http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   *
    17   */
    18  
    19  package rls
    20  
    21  import (
    22  	"context"
    23  	"errors"
    24  	"fmt"
    25  	"testing"
    26  	"time"
    27  
    28  	"google.golang.org/grpc"
    29  	"google.golang.org/grpc/balancer"
    30  	"google.golang.org/grpc/codes"
    31  	"google.golang.org/grpc/credentials/insecure"
    32  	"google.golang.org/grpc/internal/grpcsync"
    33  	"google.golang.org/grpc/internal/stubserver"
    34  	rlstest "google.golang.org/grpc/internal/testutils/rls"
    35  	"google.golang.org/grpc/internal/testutils/stats"
    36  	"google.golang.org/grpc/metadata"
    37  	"google.golang.org/grpc/status"
    38  	"google.golang.org/protobuf/types/known/durationpb"
    39  
    40  	rlspb "google.golang.org/grpc/internal/proto/grpc_lookup_v1"
    41  	testgrpc "google.golang.org/grpc/interop/grpc_testing"
    42  	testpb "google.golang.org/grpc/interop/grpc_testing"
    43  )
    44  
    45  // TestNoNonEmptyTargetsReturnsError tests the case where the RLS Server returns
    46  // a response with no non empty targets. This should be treated as an Control
    47  // Plane RPC failure, and thus fail Data Plane RPC's with an error with the
    48  // appropriate information specifying data plane sent a response with no non
    49  // empty targets.
    50  func (s) TestNoNonEmptyTargetsReturnsError(t *testing.T) {
    51  	// Setup RLS Server to return a response with an empty target string.
    52  	rlsServer, rlsReqCh := rlstest.SetupFakeRLSServer(t, nil)
    53  	rlsServer.SetResponseCallback(func(context.Context, *rlspb.RouteLookupRequest) *rlstest.RouteLookupResponse {
    54  		return &rlstest.RouteLookupResponse{Resp: &rlspb.RouteLookupResponse{}}
    55  	})
    56  
    57  	// Register a manual resolver and push the RLS service config through it.
    58  	rlsConfig := buildBasicRLSConfigWithChildPolicy(t, t.Name(), rlsServer.Address)
    59  	r := startManualResolverWithConfig(t, rlsConfig)
    60  
    61  	// Create new client.
    62  	cc, err := grpc.NewClient(r.Scheme()+":///", grpc.WithResolvers(r), grpc.WithTransportCredentials(insecure.NewCredentials()))
    63  	if err != nil {
    64  		t.Fatalf("Failed to create gRPC client: %v", err)
    65  	}
    66  	defer cc.Close()
    67  
    68  	// Make an RPC and expect it to fail with an error specifying RLS response's
    69  	// target list does not contain any non empty entries.
    70  	ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
    71  	defer cancel()
    72  	makeTestRPCAndVerifyError(ctx, t, cc, codes.Unavailable, errors.New("RLS response's target list does not contain any entries for key"))
    73  
    74  	// Make sure an RLS request is sent out. Even though the RLS Server will
    75  	// return no targets, the request should still hit the server.
    76  	verifyRLSRequest(t, rlsReqCh, true)
    77  }
    78  
    79  // Test verifies the scenario where there is no matching entry in the data cache
    80  // and no pending request either, and the ensuing RLS request is throttled.
    81  func (s) TestPick_DataCacheMiss_NoPendingEntry_ThrottledWithDefaultTarget(t *testing.T) {
    82  	// Start an RLS server and set the throttler to always throttle requests.
    83  	rlsServer, rlsReqCh := rlstest.SetupFakeRLSServer(t, nil)
    84  	overrideAdaptiveThrottler(t, alwaysThrottlingThrottler())
    85  
    86  	// Build RLS service config with a default target.
    87  	rlsConfig := buildBasicRLSConfigWithChildPolicy(t, t.Name(), rlsServer.Address)
    88  	defBackendCh, defBackendAddress := startBackend(t)
    89  	rlsConfig.RouteLookupConfig.DefaultTarget = defBackendAddress
    90  
    91  	// Register a manual resolver and push the RLS service config through it.
    92  	r := startManualResolverWithConfig(t, rlsConfig)
    93  
    94  	cc, err := grpc.NewClient(r.Scheme()+":///", grpc.WithResolvers(r), grpc.WithTransportCredentials(insecure.NewCredentials()))
    95  	if err != nil {
    96  		t.Fatalf("Failed to create gRPC client: %v", err)
    97  	}
    98  	defer cc.Close()
    99  
   100  	// Make an RPC and ensure it gets routed to the default target.
   101  	ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
   102  	defer cancel()
   103  	makeTestRPCAndExpectItToReachBackend(ctx, t, cc, defBackendCh)
   104  
   105  	// Make sure no RLS request is sent out.
   106  	verifyRLSRequest(t, rlsReqCh, false)
   107  }
   108  
   109  // Test verifies the scenario where there is no matching entry in the data cache
   110  // and no pending request either, and the ensuing RLS request is throttled.
   111  // There is no default target configured in the service config, so the RPC is
   112  // expected to fail with an RLS throttled error.
   113  func (s) TestPick_DataCacheMiss_NoPendingEntry_ThrottledWithoutDefaultTarget(t *testing.T) {
   114  	// Start an RLS server and set the throttler to always throttle requests.
   115  	rlsServer, rlsReqCh := rlstest.SetupFakeRLSServer(t, nil)
   116  	overrideAdaptiveThrottler(t, alwaysThrottlingThrottler())
   117  
   118  	// Build an RLS config without a default target.
   119  	rlsConfig := buildBasicRLSConfigWithChildPolicy(t, t.Name(), rlsServer.Address)
   120  
   121  	// Register a manual resolver and push the RLS service config through it.
   122  	r := startManualResolverWithConfig(t, rlsConfig)
   123  
   124  	// Create new client.
   125  	cc, err := grpc.NewClient(r.Scheme()+":///", grpc.WithResolvers(r), grpc.WithTransportCredentials(insecure.NewCredentials()))
   126  	if err != nil {
   127  		t.Fatalf("Failed to create gRPC client: %v", err)
   128  	}
   129  	defer cc.Close()
   130  
   131  	// Make an RPC and expect it to fail with RLS throttled error.
   132  	ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
   133  	defer cancel()
   134  	makeTestRPCAndVerifyError(ctx, t, cc, codes.Unavailable, errRLSThrottled)
   135  
   136  	// Make sure no RLS request is sent out.
   137  	verifyRLSRequest(t, rlsReqCh, false)
   138  }
   139  
   140  // Test verifies the scenario where there is no matching entry in the data cache
   141  // and no pending request either, and the ensuing RLS request is not throttled.
   142  // The RLS response does not contain any backends, so the RPC fails with a
   143  // unavailable error.
   144  func (s) TestPick_DataCacheMiss_NoPendingEntry_NotThrottled(t *testing.T) {
   145  	// Start an RLS server and set the throttler to never throttle requests.
   146  	rlsServer, rlsReqCh := rlstest.SetupFakeRLSServer(t, nil)
   147  	overrideAdaptiveThrottler(t, neverThrottlingThrottler())
   148  
   149  	// Build an RLS config without a default target.
   150  	rlsConfig := buildBasicRLSConfigWithChildPolicy(t, t.Name(), rlsServer.Address)
   151  
   152  	// Register a manual resolver and push the RLS service config through it.
   153  	r := startManualResolverWithConfig(t, rlsConfig)
   154  
   155  	// Create new client.
   156  	cc, err := grpc.NewClient(r.Scheme()+":///", grpc.WithResolvers(r), grpc.WithTransportCredentials(insecure.NewCredentials()))
   157  	if err != nil {
   158  		t.Fatalf("Failed to create gRPC client: %v", err)
   159  	}
   160  	defer cc.Close()
   161  
   162  	// Make an RPC and expect it to fail with deadline exceeded error. We use a
   163  	// smaller timeout to ensure that the test doesn't run very long.
   164  	ctx, cancel := context.WithTimeout(context.Background(), defaultTestShortTimeout)
   165  	defer cancel()
   166  	makeTestRPCAndVerifyError(ctx, t, cc, codes.Unavailable, errors.New("RLS response's target list does not contain any entries for key"))
   167  
   168  	// Make sure an RLS request is sent out.
   169  	verifyRLSRequest(t, rlsReqCh, true)
   170  }
   171  
   172  // Test verifies the scenario where there is no matching entry in the data
   173  // cache, but there is a pending request. So, we expect no RLS request to be
   174  // sent out. The pick should be queued and not delegated to the default target.
   175  func (s) TestPick_DataCacheMiss_PendingEntryExists(t *testing.T) {
   176  	tests := []struct {
   177  		name              string
   178  		withDefaultTarget bool
   179  	}{
   180  		{
   181  			name:              "withDefaultTarget",
   182  			withDefaultTarget: true,
   183  		},
   184  		{
   185  			name:              "withoutDefaultTarget",
   186  			withDefaultTarget: false,
   187  		},
   188  	}
   189  
   190  	for _, test := range tests {
   191  		t.Run(test.name, func(t *testing.T) {
   192  			// A unary interceptor which blocks the RouteLookup RPC on the fake
   193  			// RLS server until the test is done. The first RPC by the client
   194  			// will cause the LB policy to send out an RLS request. This will
   195  			// also lead to creation of a pending entry, and further RPCs by the
   196  			// client should not result in RLS requests being sent out.
   197  			rlsReqCh := make(chan struct{}, 1)
   198  			interceptor := func(ctx context.Context, _ any, _ *grpc.UnaryServerInfo, _ grpc.UnaryHandler) (resp any, err error) {
   199  				rlsReqCh <- struct{}{}
   200  				<-ctx.Done()
   201  				return nil, ctx.Err()
   202  			}
   203  
   204  			// Start an RLS server and set the throttler to never throttle.
   205  			rlsServer, _ := rlstest.SetupFakeRLSServer(t, nil, grpc.UnaryInterceptor(interceptor))
   206  			overrideAdaptiveThrottler(t, neverThrottlingThrottler())
   207  
   208  			// Build RLS service config with an optional default target.
   209  			rlsConfig := buildBasicRLSConfigWithChildPolicy(t, t.Name(), rlsServer.Address)
   210  			if test.withDefaultTarget {
   211  				_, defBackendAddress := startBackend(t)
   212  				rlsConfig.RouteLookupConfig.DefaultTarget = defBackendAddress
   213  			}
   214  
   215  			// Register a manual resolver and push the RLS service config
   216  			// through it.
   217  			r := startManualResolverWithConfig(t, rlsConfig)
   218  
   219  			// Create new client.
   220  			cc, err := grpc.NewClient(r.Scheme()+":///", grpc.WithResolvers(r), grpc.WithTransportCredentials(insecure.NewCredentials()))
   221  			if err != nil {
   222  				t.Fatalf("Failed to create gRPC client: %v", err)
   223  			}
   224  			defer cc.Close()
   225  
   226  			// Make an RPC that results in the RLS request being sent out. And
   227  			// since the RLS server is configured to block on the first request,
   228  			// this RPC will block until its context expires. This ensures that
   229  			// we have a pending cache entry for the duration of the test.
   230  			ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
   231  			defer cancel()
   232  			go func() {
   233  				client := testgrpc.NewTestServiceClient(cc)
   234  				client.EmptyCall(ctx, &testpb.Empty{})
   235  			}()
   236  
   237  			// Make sure an RLS request is sent out.
   238  			verifyRLSRequest(t, rlsReqCh, true)
   239  
   240  			// Make another RPC and expect it to fail the same way.
   241  			ctx, cancel = context.WithTimeout(context.Background(), defaultTestShortTimeout)
   242  			defer cancel()
   243  			makeTestRPCAndVerifyError(ctx, t, cc, codes.DeadlineExceeded, context.DeadlineExceeded)
   244  
   245  			// Make sure no RLS request is sent out this time around.
   246  			verifyRLSRequest(t, rlsReqCh, false)
   247  		})
   248  	}
   249  }
   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()
   270  	cc, err := grpc.NewClient(r.Scheme()+":///", grpc.WithResolvers(r), grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithStatsHandler(tmr))
   271  	if err != nil {
   272  		t.Fatalf("grpc.NewClient() 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  	if got, _ := tmr.Metric("grpc.lb.rls.default_target_picks"); got != 1 {
   282  		t.Fatalf("Unexpected data for metric %v, got: %v, want: %v", "grpc.lb.rls.default_target_picks", got, 1)
   283  	}
   284  	if _, ok := tmr.Metric("grpc.lb.rls.target_picks"); ok {
   285  		t.Fatalf("Data is present for metric %v", "grpc.lb.rls.target_picks")
   286  	}
   287  	if _, ok := tmr.Metric("grpc.lb.rls.failed_picks"); ok {
   288  		t.Fatalf("Data is present for metric %v", "grpc.lb.rls.failed_picks")
   289  	}
   290  }
   291  
   292  // Test_RLSTargetPicksMetric tests the target picks metric. It configures an RLS
   293  // Balancer which specifies to route to a target through a RouteLookupResponse,
   294  // and makes an RPC on a Channel containing this RLS Balancer. This test then
   295  // asserts a target picks metric is emitted, and default target pick or failed
   296  // pick metric is not emitted.
   297  func (s) Test_RLSTargetPicksMetric(t *testing.T) {
   298  	// Start an RLS server and set the throttler to never throttle requests.
   299  	rlsServer, _ := rlstest.SetupFakeRLSServer(t, nil)
   300  	overrideAdaptiveThrottler(t, neverThrottlingThrottler())
   301  
   302  	// Build the RLS config without a default target.
   303  	rlsConfig := buildBasicRLSConfigWithChildPolicy(t, t.Name(), rlsServer.Address)
   304  
   305  	// Start a test backend, and setup the fake RLS server to return this as a
   306  	// target in the RLS response.
   307  	testBackendCh, testBackendAddress := startBackend(t)
   308  	rlsServer.SetResponseCallback(func(context.Context, *rlspb.RouteLookupRequest) *rlstest.RouteLookupResponse {
   309  		return &rlstest.RouteLookupResponse{Resp: &rlspb.RouteLookupResponse{Targets: []string{testBackendAddress}}}
   310  	})
   311  
   312  	// Register a manual resolver and push the RLS service config through it.
   313  	r := startManualResolverWithConfig(t, rlsConfig)
   314  
   315  	tmr := stats.NewTestMetricsRecorder()
   316  	// Dial the backend.
   317  	cc, err := grpc.NewClient(r.Scheme()+":///", grpc.WithResolvers(r), grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithStatsHandler(tmr))
   318  	if err != nil {
   319  		t.Fatalf("grpc.NewClient() failed: %v", err)
   320  	}
   321  	defer cc.Close()
   322  
   323  	// Make an RPC and ensure it gets routed to the test backend.
   324  	ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
   325  	defer cancel()
   326  	makeTestRPCAndExpectItToReachBackend(ctx, t, cc, testBackendCh)
   327  	if got, _ := tmr.Metric("grpc.lb.rls.target_picks"); got != 1 {
   328  		t.Fatalf("Unexpected data for metric %v, got: %v, want: %v", "grpc.lb.rls.target_picks", got, 1)
   329  	}
   330  	if _, ok := tmr.Metric("grpc.lb.rls.default_target_picks"); ok {
   331  		t.Fatalf("Data is present for metric %v", "grpc.lb.rls.default_target_picks")
   332  	}
   333  	if _, ok := tmr.Metric("grpc.lb.rls.failed_picks"); ok {
   334  		t.Fatalf("Data is present for metric %v", "grpc.lb.rls.failed_picks")
   335  	}
   336  }
   337  
   338  // Test_RLSFailedPicksMetric tests the failed picks metric. It configures an RLS
   339  // Balancer to fail a pick with unavailable, and makes an RPC on a Channel
   340  // containing this RLS Balancer. This test then asserts a failed picks metric is
   341  // emitted, and default target pick or target pick metric is not emitted.
   342  func (s) Test_RLSFailedPicksMetric(t *testing.T) {
   343  	// Start an RLS server and set the throttler to never throttle requests.
   344  	rlsServer, _ := rlstest.SetupFakeRLSServer(t, nil)
   345  	overrideAdaptiveThrottler(t, neverThrottlingThrottler())
   346  
   347  	// Build an RLS config without a default target.
   348  	rlsConfig := buildBasicRLSConfigWithChildPolicy(t, t.Name(), rlsServer.Address)
   349  
   350  	// Register a manual resolver and push the RLS service config through it.
   351  	r := startManualResolverWithConfig(t, rlsConfig)
   352  
   353  	tmr := stats.NewTestMetricsRecorder()
   354  	// Dial the backend.
   355  	cc, err := grpc.NewClient(r.Scheme()+":///", grpc.WithResolvers(r), grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithStatsHandler(tmr))
   356  	if err != nil {
   357  		t.Fatalf("grpc.NewClient() failed: %v", err)
   358  	}
   359  	defer cc.Close()
   360  
   361  	// Make an RPC and expect it to fail with deadline exceeded error. We use a
   362  	// smaller timeout to ensure that the test doesn't run very long.
   363  	ctx, cancel := context.WithTimeout(context.Background(), defaultTestShortTimeout)
   364  	defer cancel()
   365  	makeTestRPCAndVerifyError(ctx, t, cc, codes.Unavailable, errors.New("RLS response's target list does not contain any entries for key"))
   366  
   367  	if got, _ := tmr.Metric("grpc.lb.rls.failed_picks"); got != 1 {
   368  		t.Fatalf("Unexpected data for metric %v, got: %v, want: %v", "grpc.lb.rls.failed_picks", got, 1)
   369  	}
   370  	if _, ok := tmr.Metric("grpc.lb.rls.target_picks"); ok {
   371  		t.Fatalf("Data is present for metric %v", "grpc.lb.rls.target_picks")
   372  	}
   373  	if _, ok := tmr.Metric("grpc.lb.rls.default_target_picks"); ok {
   374  		t.Fatalf("Data is present for metric %v", "grpc.lb.rls.default_target_picks")
   375  	}
   376  }
   377  
   378  // Test verifies the scenario where there is a matching entry in the data cache
   379  // which is valid and there is no pending request. The pick is expected to be
   380  // delegated to the child policy.
   381  func (s) TestPick_DataCacheHit_NoPendingEntry_ValidEntry(t *testing.T) {
   382  	// Start an RLS server and set the throttler to never throttle requests.
   383  	rlsServer, rlsReqCh := rlstest.SetupFakeRLSServer(t, nil)
   384  	overrideAdaptiveThrottler(t, neverThrottlingThrottler())
   385  
   386  	// Build the RLS config without a default target.
   387  	rlsConfig := buildBasicRLSConfigWithChildPolicy(t, t.Name(), rlsServer.Address)
   388  	// Start a test backend, and setup the fake RLS server to return this as a
   389  	// target in the RLS response.
   390  	testBackendCh, testBackendAddress := startBackend(t)
   391  	rlsServer.SetResponseCallback(func(context.Context, *rlspb.RouteLookupRequest) *rlstest.RouteLookupResponse {
   392  		return &rlstest.RouteLookupResponse{Resp: &rlspb.RouteLookupResponse{Targets: []string{testBackendAddress}}}
   393  	})
   394  
   395  	// Register a manual resolver and push the RLS service config through it.
   396  	r := startManualResolverWithConfig(t, rlsConfig)
   397  
   398  	// Create new client.
   399  	cc, err := grpc.NewClient(r.Scheme()+":///", grpc.WithResolvers(r), grpc.WithTransportCredentials(insecure.NewCredentials()))
   400  	if err != nil {
   401  		t.Fatalf("Failed to create gRPC client: %v", err)
   402  	}
   403  	defer cc.Close()
   404  
   405  	// Make an RPC and ensure it gets routed to the test backend.
   406  	ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
   407  	defer cancel()
   408  	makeTestRPCAndExpectItToReachBackend(ctx, t, cc, testBackendCh)
   409  
   410  	// Make sure an RLS request is sent out.
   411  	verifyRLSRequest(t, rlsReqCh, true)
   412  
   413  	// Make another RPC and expect it to find the target in the data cache.
   414  	makeTestRPCAndExpectItToReachBackend(ctx, t, cc, testBackendCh)
   415  
   416  	// Make sure no RLS request is sent out this time around.
   417  	verifyRLSRequest(t, rlsReqCh, false)
   418  }
   419  
   420  // Test verifies the scenario where there is a matching entry in the data cache
   421  // which is valid and there is no pending request. The pick is expected to be
   422  // delegated to the child policy.
   423  func (s) TestPick_DataCacheHit_NoPendingEntry_ValidEntry_WithHeaderData(t *testing.T) {
   424  	// Start an RLS server and set the throttler to never throttle requests.
   425  	rlsServer, _ := rlstest.SetupFakeRLSServer(t, nil)
   426  	overrideAdaptiveThrottler(t, neverThrottlingThrottler())
   427  
   428  	// Build the RLS config without a default target.
   429  	rlsConfig := buildBasicRLSConfigWithChildPolicy(t, t.Name(), rlsServer.Address)
   430  
   431  	// Start a test backend which expects the header data contents sent from the
   432  	// RLS server to be part of RPC metadata as X-Google-RLS-Data header.
   433  	const headerDataContents = "foo,bar,baz"
   434  	backend := &stubserver.StubServer{
   435  		EmptyCallF: func(ctx context.Context, _ *testpb.Empty) (*testpb.Empty, error) {
   436  			gotHeaderData := metadata.ValueFromIncomingContext(ctx, "x-google-rls-data")
   437  			if len(gotHeaderData) != 1 || gotHeaderData[0] != headerDataContents {
   438  				return nil, fmt.Errorf("got metadata in `X-Google-RLS-Data` is %v, want %s", gotHeaderData, headerDataContents)
   439  			}
   440  			return &testpb.Empty{}, nil
   441  		},
   442  	}
   443  	if err := backend.StartServer(); err != nil {
   444  		t.Fatalf("Failed to start backend: %v", err)
   445  	}
   446  	t.Logf("Started TestService backend at: %q", backend.Address)
   447  	defer backend.Stop()
   448  
   449  	// Setup the fake RLS server to return the above backend as a target in the
   450  	// RLS response. Also, populate the header data field in the response.
   451  	rlsServer.SetResponseCallback(func(context.Context, *rlspb.RouteLookupRequest) *rlstest.RouteLookupResponse {
   452  		return &rlstest.RouteLookupResponse{Resp: &rlspb.RouteLookupResponse{
   453  			Targets:    []string{backend.Address},
   454  			HeaderData: headerDataContents,
   455  		}}
   456  	})
   457  
   458  	// Register a manual resolver and push the RLS service config through it.
   459  	r := startManualResolverWithConfig(t, rlsConfig)
   460  
   461  	// Create new client.
   462  	cc, err := grpc.NewClient(r.Scheme()+":///", grpc.WithResolvers(r), grpc.WithTransportCredentials(insecure.NewCredentials()))
   463  	if err != nil {
   464  		t.Fatalf("Failed to create gRPC client: %v", err)
   465  	}
   466  	defer cc.Close()
   467  
   468  	// Make an RPC and ensure it gets routed to the test backend with the header
   469  	// data sent by the RLS server.
   470  	ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
   471  	defer cancel()
   472  	if _, err := testgrpc.NewTestServiceClient(cc).EmptyCall(ctx, &testpb.Empty{}); err != nil {
   473  		t.Fatalf("EmptyCall() RPC: %v", err)
   474  	}
   475  }
   476  
   477  // Test verifies the scenario where there is a matching entry in the data cache
   478  // which is stale and there is no pending request. The pick is expected to be
   479  // delegated to the child policy with a proactive cache refresh.
   480  func (s) TestPick_DataCacheHit_NoPendingEntry_StaleEntry(t *testing.T) {
   481  	// We expect the same pick behavior (i.e delegated to the child policy) for
   482  	// a proactive refresh whether the control channel is throttled or not.
   483  	tests := []struct {
   484  		name      string
   485  		throttled bool
   486  	}{
   487  		{
   488  			name:      "throttled",
   489  			throttled: true,
   490  		},
   491  		{
   492  			name:      "notThrottled",
   493  			throttled: false,
   494  		},
   495  	}
   496  
   497  	for _, test := range tests {
   498  		t.Run(test.name, func(t *testing.T) {
   499  			// Start an RLS server and setup the throttler appropriately.
   500  			rlsServer, rlsReqCh := rlstest.SetupFakeRLSServer(t, nil)
   501  			var throttler *fakeThrottler
   502  			firstRPCDone := grpcsync.NewEvent()
   503  			if test.throttled {
   504  				throttler = oneTimeAllowingThrottler(firstRPCDone)
   505  				overrideAdaptiveThrottler(t, throttler)
   506  			} else {
   507  				throttler = neverThrottlingThrottler()
   508  				overrideAdaptiveThrottler(t, throttler)
   509  			}
   510  
   511  			// Build the RLS config without a default target. Set the stale age
   512  			// to a very low value to force entries to become stale quickly.
   513  			rlsConfig := buildBasicRLSConfigWithChildPolicy(t, t.Name(), rlsServer.Address)
   514  			rlsConfig.RouteLookupConfig.MaxAge = durationpb.New(time.Minute)
   515  			rlsConfig.RouteLookupConfig.StaleAge = durationpb.New(defaultTestShortTimeout)
   516  
   517  			// Start a test backend, and setup the fake RLS server to return
   518  			// this as a target in the RLS response.
   519  			testBackendCh, testBackendAddress := startBackend(t)
   520  			rlsServer.SetResponseCallback(func(context.Context, *rlspb.RouteLookupRequest) *rlstest.RouteLookupResponse {
   521  				return &rlstest.RouteLookupResponse{Resp: &rlspb.RouteLookupResponse{Targets: []string{testBackendAddress}}}
   522  			})
   523  
   524  			// Register a manual resolver and push the RLS service config
   525  			// through it.
   526  			r := startManualResolverWithConfig(t, rlsConfig)
   527  
   528  			// Create new client.
   529  			cc, err := grpc.NewClient(r.Scheme()+":///", grpc.WithResolvers(r), grpc.WithTransportCredentials(insecure.NewCredentials()))
   530  			if err != nil {
   531  				t.Fatalf("Failed to create gRPC client: %v", err)
   532  			}
   533  			defer cc.Close()
   534  
   535  			// Make an RPC and ensure it gets routed to the test backend.
   536  			ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
   537  			defer cancel()
   538  			makeTestRPCAndExpectItToReachBackend(ctx, t, cc, testBackendCh)
   539  
   540  			// Make sure an RLS request is sent out.
   541  			verifyRLSRequest(t, rlsReqCh, true)
   542  			firstRPCDone.Fire()
   543  
   544  			// The cache entry has a large maxAge, but a small stateAge. We keep
   545  			// retrying until the cache entry becomes stale, in which case we expect a
   546  			// proactive cache refresh.
   547  			//
   548  			// If the control channel is not throttled, then we expect an RLS request
   549  			// to be sent out. If the control channel is throttled, we expect the fake
   550  			// throttler's channel to be signalled.
   551  			for {
   552  				// Make another RPC and expect it to find the target in the data cache.
   553  				makeTestRPCAndExpectItToReachBackend(ctx, t, cc, testBackendCh)
   554  
   555  				if !test.throttled {
   556  					select {
   557  					case <-time.After(defaultTestShortTimeout):
   558  						// Go back and retry the RPC.
   559  					case <-rlsReqCh:
   560  						return
   561  					}
   562  				} else {
   563  					select {
   564  					case <-time.After(defaultTestShortTimeout):
   565  						// Go back and retry the RPC.
   566  					case <-throttler.throttleCh:
   567  						return
   568  					}
   569  				}
   570  			}
   571  		})
   572  	}
   573  }
   574  
   575  // Test verifies scenarios where there is a matching entry in the data cache
   576  // which has expired and there is no pending request.
   577  func (s) TestPick_DataCacheHit_NoPendingEntry_ExpiredEntry(t *testing.T) {
   578  	tests := []struct {
   579  		name              string
   580  		throttled         bool
   581  		withDefaultTarget bool
   582  	}{
   583  		{
   584  			name:              "throttledWithDefaultTarget",
   585  			throttled:         true,
   586  			withDefaultTarget: true,
   587  		},
   588  		{
   589  			name:              "throttledWithoutDefaultTarget",
   590  			throttled:         true,
   591  			withDefaultTarget: false,
   592  		},
   593  		{
   594  			name:      "notThrottled",
   595  			throttled: false,
   596  		},
   597  	}
   598  
   599  	for _, test := range tests {
   600  		t.Run(test.name, func(t *testing.T) {
   601  			// Start an RLS server and setup the throttler appropriately.
   602  			rlsServer, rlsReqCh := rlstest.SetupFakeRLSServer(t, nil)
   603  			var throttler *fakeThrottler
   604  			firstRPCDone := grpcsync.NewEvent()
   605  			if test.throttled {
   606  				throttler = oneTimeAllowingThrottler(firstRPCDone)
   607  				overrideAdaptiveThrottler(t, throttler)
   608  			} else {
   609  				throttler = neverThrottlingThrottler()
   610  				overrideAdaptiveThrottler(t, throttler)
   611  			}
   612  
   613  			// Build the RLS config with a very low value for maxAge. This will
   614  			// ensure that cache entries become invalid very soon.
   615  			rlsConfig := buildBasicRLSConfigWithChildPolicy(t, t.Name(), rlsServer.Address)
   616  			rlsConfig.RouteLookupConfig.MaxAge = durationpb.New(defaultTestShortTimeout)
   617  
   618  			// Start a default backend if needed.
   619  			var defBackendCh chan struct{}
   620  			if test.withDefaultTarget {
   621  				var defBackendAddress string
   622  				defBackendCh, defBackendAddress = startBackend(t)
   623  				rlsConfig.RouteLookupConfig.DefaultTarget = defBackendAddress
   624  			}
   625  
   626  			// Start a test backend, and setup the fake RLS server to return
   627  			// this as a target in the RLS response.
   628  			testBackendCh, testBackendAddress := startBackend(t)
   629  			rlsServer.SetResponseCallback(func(context.Context, *rlspb.RouteLookupRequest) *rlstest.RouteLookupResponse {
   630  				return &rlstest.RouteLookupResponse{Resp: &rlspb.RouteLookupResponse{Targets: []string{testBackendAddress}}}
   631  			})
   632  
   633  			// Register a manual resolver and push the RLS service config
   634  			// through it.
   635  			r := startManualResolverWithConfig(t, rlsConfig)
   636  
   637  			// Create new client.
   638  			cc, err := grpc.NewClient(r.Scheme()+":///", grpc.WithResolvers(r), grpc.WithTransportCredentials(insecure.NewCredentials()))
   639  			if err != nil {
   640  				t.Fatalf("Failed to create gRPC client: %v", err)
   641  			}
   642  			defer cc.Close()
   643  
   644  			// Make an RPC and ensure it gets routed to the test backend.
   645  			ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
   646  			defer cancel()
   647  			makeTestRPCAndExpectItToReachBackend(ctx, t, cc, testBackendCh)
   648  
   649  			// Make sure an RLS request is sent out.
   650  			verifyRLSRequest(t, rlsReqCh, true)
   651  			firstRPCDone.Fire()
   652  
   653  			// Keep retrying the RPC until the cache entry expires. Expected behavior
   654  			// is dependent on the scenario being tested.
   655  			switch {
   656  			case test.throttled && test.withDefaultTarget:
   657  				makeTestRPCAndExpectItToReachBackend(ctx, t, cc, defBackendCh)
   658  				<-throttler.throttleCh
   659  			case test.throttled && !test.withDefaultTarget:
   660  				makeTestRPCAndVerifyError(ctx, t, cc, codes.Unavailable, errRLSThrottled)
   661  				<-throttler.throttleCh
   662  			case !test.throttled:
   663  				for {
   664  					// The backend to which the RPC is routed does not change after the
   665  					// cache entry expires because the control channel is not throttled.
   666  					// So, we need to keep retrying until the cache entry expires, at
   667  					// which point we expect an RLS request to be sent out and the RPC to
   668  					// get routed to the same testBackend.
   669  					makeTestRPCAndExpectItToReachBackend(ctx, t, cc, testBackendCh)
   670  					select {
   671  					case <-time.After(defaultTestShortTimeout):
   672  						// Go back and retry the RPC.
   673  					case <-rlsReqCh:
   674  						return
   675  					}
   676  				}
   677  			}
   678  		})
   679  	}
   680  }
   681  
   682  // Test verifies scenarios where there is a matching entry in the data cache
   683  // which has expired and is in backoff and there is no pending request.
   684  func (s) TestPick_DataCacheHit_NoPendingEntry_ExpiredEntryInBackoff(t *testing.T) {
   685  	tests := []struct {
   686  		name              string
   687  		withDefaultTarget bool
   688  	}{
   689  		{
   690  			name:              "withDefaultTarget",
   691  			withDefaultTarget: true,
   692  		},
   693  		{
   694  			name:              "withoutDefaultTarget",
   695  			withDefaultTarget: false,
   696  		},
   697  	}
   698  
   699  	for _, test := range tests {
   700  		t.Run(test.name, func(t *testing.T) {
   701  			// Start an RLS server and set the throttler to never throttle requests.
   702  			rlsServer, rlsReqCh := rlstest.SetupFakeRLSServer(t, nil)
   703  			overrideAdaptiveThrottler(t, neverThrottlingThrottler())
   704  
   705  			// Override the backoff strategy to return a large backoff which
   706  			// will make sure the date cache entry remains in backoff for the
   707  			// duration of the test.
   708  			origBackoffStrategy := defaultBackoffStrategy
   709  			defaultBackoffStrategy = &fakeBackoffStrategy{backoff: defaultTestTimeout}
   710  			defer func() { defaultBackoffStrategy = origBackoffStrategy }()
   711  
   712  			// Build the RLS config with a very low value for maxAge. This will
   713  			// ensure that cache entries become invalid very soon.
   714  			rlsConfig := buildBasicRLSConfigWithChildPolicy(t, t.Name(), rlsServer.Address)
   715  			rlsConfig.RouteLookupConfig.MaxAge = durationpb.New(defaultTestShortTimeout)
   716  
   717  			// Start a default backend if needed.
   718  			var defBackendCh chan struct{}
   719  			if test.withDefaultTarget {
   720  				var defBackendAddress string
   721  				defBackendCh, defBackendAddress = startBackend(t)
   722  				rlsConfig.RouteLookupConfig.DefaultTarget = defBackendAddress
   723  			}
   724  
   725  			// Start a test backend, and set up the fake RLS server to return this as
   726  			// a target in the RLS response.
   727  			testBackendCh, testBackendAddress := startBackend(t)
   728  			rlsServer.SetResponseCallback(func(context.Context, *rlspb.RouteLookupRequest) *rlstest.RouteLookupResponse {
   729  				return &rlstest.RouteLookupResponse{Resp: &rlspb.RouteLookupResponse{Targets: []string{testBackendAddress}}}
   730  			})
   731  
   732  			// Register a manual resolver and push the RLS service config through it.
   733  			r := startManualResolverWithConfig(t, rlsConfig)
   734  
   735  			// Create new client.
   736  			cc, err := grpc.NewClient(r.Scheme()+":///", grpc.WithResolvers(r), grpc.WithTransportCredentials(insecure.NewCredentials()))
   737  			if err != nil {
   738  				t.Fatalf("Failed to create gRPC client: %v", err)
   739  			}
   740  			defer cc.Close()
   741  
   742  			// Make an RPC and ensure it gets routed to the test backend.
   743  			ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
   744  			defer cancel()
   745  			makeTestRPCAndExpectItToReachBackend(ctx, t, cc, testBackendCh)
   746  
   747  			// Make sure an RLS request is sent out.
   748  			verifyRLSRequest(t, rlsReqCh, true)
   749  
   750  			// Set up the fake RLS server to return errors. This will push the cache
   751  			// entry into backoff.
   752  			var rlsLastErr = status.Error(codes.DeadlineExceeded, "last RLS request failed")
   753  			rlsServer.SetResponseCallback(func(context.Context, *rlspb.RouteLookupRequest) *rlstest.RouteLookupResponse {
   754  				return &rlstest.RouteLookupResponse{Err: rlsLastErr}
   755  			})
   756  
   757  			// Since the RLS server is now configured to return errors, this will push
   758  			// the cache entry into backoff. The pick will be delegated to the default
   759  			// backend if one exits, and will fail with the error returned by the RLS
   760  			// server otherwise.
   761  			if test.withDefaultTarget {
   762  				makeTestRPCAndExpectItToReachBackend(ctx, t, cc, defBackendCh)
   763  			} else {
   764  				makeTestRPCAndVerifyError(ctx, t, cc, codes.Unavailable, rlsLastErr)
   765  			}
   766  		})
   767  	}
   768  }
   769  
   770  // Test verifies scenarios where there is a matching entry in the data cache
   771  // which is stale and there is a pending request.
   772  func (s) TestPick_DataCacheHit_PendingEntryExists_StaleEntry(t *testing.T) {
   773  	tests := []struct {
   774  		name              string
   775  		withDefaultTarget bool
   776  	}{
   777  		{
   778  			name:              "withDefaultTarget",
   779  			withDefaultTarget: true,
   780  		},
   781  		{
   782  			name:              "withoutDefaultTarget",
   783  			withDefaultTarget: false,
   784  		},
   785  	}
   786  
   787  	for _, test := range tests {
   788  		t.Run(test.name, func(t *testing.T) {
   789  			// A unary interceptor which simply calls the underlying handler
   790  			// until the first client RPC is done. We want one client RPC to
   791  			// succeed to ensure that a data cache entry is created. For
   792  			// subsequent client RPCs which result in RLS requests, this
   793  			// interceptor blocks until the test's context expires. And since we
   794  			// configure the RLS LB policy with a really low value for max age,
   795  			// this allows us to simulate the condition where the it has an
   796  			// expired entry and a pending entry in the cache.
   797  			rlsReqCh := make(chan struct{}, 1)
   798  			firstRPCDone := grpcsync.NewEvent()
   799  			interceptor := func(ctx context.Context, req any, _ *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp any, err error) {
   800  				select {
   801  				case rlsReqCh <- struct{}{}:
   802  				default:
   803  				}
   804  				if firstRPCDone.HasFired() {
   805  					<-ctx.Done()
   806  					return nil, ctx.Err()
   807  				}
   808  				return handler(ctx, req)
   809  			}
   810  
   811  			// Start an RLS server and set the throttler to never throttle.
   812  			rlsServer, _ := rlstest.SetupFakeRLSServer(t, nil, grpc.UnaryInterceptor(interceptor))
   813  			overrideAdaptiveThrottler(t, neverThrottlingThrottler())
   814  
   815  			// Build RLS service config with an optional default target.
   816  			rlsConfig := buildBasicRLSConfigWithChildPolicy(t, t.Name(), rlsServer.Address)
   817  			if test.withDefaultTarget {
   818  				_, defBackendAddress := startBackend(t)
   819  				rlsConfig.RouteLookupConfig.DefaultTarget = defBackendAddress
   820  			}
   821  
   822  			// Low value for stale age to force entries to become stale quickly.
   823  			rlsConfig.RouteLookupConfig.MaxAge = durationpb.New(time.Minute)
   824  			rlsConfig.RouteLookupConfig.StaleAge = durationpb.New(defaultTestShortTimeout)
   825  
   826  			// Start a test backend, and setup the fake RLS server to return
   827  			// this as a target in the RLS response.
   828  			testBackendCh, testBackendAddress := startBackend(t)
   829  			rlsServer.SetResponseCallback(func(context.Context, *rlspb.RouteLookupRequest) *rlstest.RouteLookupResponse {
   830  				return &rlstest.RouteLookupResponse{Resp: &rlspb.RouteLookupResponse{Targets: []string{testBackendAddress}}}
   831  			})
   832  
   833  			// Register a manual resolver and push the RLS service config
   834  			// through it.
   835  			r := startManualResolverWithConfig(t, rlsConfig)
   836  
   837  			// Create new client.
   838  			cc, err := grpc.NewClient(r.Scheme()+":///", grpc.WithResolvers(r), grpc.WithTransportCredentials(insecure.NewCredentials()))
   839  			if err != nil {
   840  				t.Fatalf("Failed to create gRPC client: %v", err)
   841  			}
   842  			defer cc.Close()
   843  
   844  			// Make an RPC and ensure it gets routed to the test backend.
   845  			ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
   846  			defer cancel()
   847  			makeTestRPCAndExpectItToReachBackend(ctx, t, cc, testBackendCh)
   848  
   849  			// Make sure an RLS request is sent out.
   850  			verifyRLSRequest(t, rlsReqCh, true)
   851  			firstRPCDone.Fire()
   852  
   853  			// The cache entry has a large maxAge, but a small stateAge. We keep
   854  			// retrying until the cache entry becomes stale, in which case we expect a
   855  			// proactive cache refresh.
   856  			for {
   857  				makeTestRPCAndExpectItToReachBackend(ctx, t, cc, testBackendCh)
   858  
   859  				select {
   860  				case <-time.After(defaultTestShortTimeout):
   861  					// Go back and retry the RPC.
   862  				case <-rlsReqCh:
   863  					return
   864  				}
   865  			}
   866  		})
   867  	}
   868  }
   869  
   870  // Test verifies scenarios where there is a matching entry in the data cache
   871  // which is expired and there is a pending request.
   872  func (s) TestPick_DataCacheHit_PendingEntryExists_ExpiredEntry(t *testing.T) {
   873  	tests := []struct {
   874  		name              string
   875  		withDefaultTarget bool
   876  	}{
   877  		{
   878  			name:              "withDefaultTarget",
   879  			withDefaultTarget: true,
   880  		},
   881  		{
   882  			name:              "withoutDefaultTarget",
   883  			withDefaultTarget: false,
   884  		},
   885  	}
   886  
   887  	for _, test := range tests {
   888  		t.Run(test.name, func(t *testing.T) {
   889  			// A unary interceptor which simply calls the underlying handler
   890  			// until the first client RPC is done. We want one client RPC to
   891  			// succeed to ensure that a data cache entry is created. For
   892  			// subsequent client RPCs which result in RLS requests, this
   893  			// interceptor blocks until the test's context expires. And since we
   894  			// configure the RLS LB policy with a really low value for max age,
   895  			// this allows us to simulate the condition where the it has an
   896  			// expired entry and a pending entry in the cache.
   897  			rlsReqCh := make(chan struct{}, 1)
   898  			firstRPCDone := grpcsync.NewEvent()
   899  			interceptor := func(ctx context.Context, req any, _ *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp any, err error) {
   900  				select {
   901  				case rlsReqCh <- struct{}{}:
   902  				default:
   903  				}
   904  				if firstRPCDone.HasFired() {
   905  					<-ctx.Done()
   906  					return nil, ctx.Err()
   907  				}
   908  				return handler(ctx, req)
   909  			}
   910  
   911  			// Start an RLS server and set the throttler to never throttle.
   912  			rlsServer, _ := rlstest.SetupFakeRLSServer(t, nil, grpc.UnaryInterceptor(interceptor))
   913  			overrideAdaptiveThrottler(t, neverThrottlingThrottler())
   914  
   915  			// Build RLS service config with an optional default target.
   916  			rlsConfig := buildBasicRLSConfigWithChildPolicy(t, t.Name(), rlsServer.Address)
   917  			if test.withDefaultTarget {
   918  				_, defBackendAddress := startBackend(t)
   919  				rlsConfig.RouteLookupConfig.DefaultTarget = defBackendAddress
   920  			}
   921  			// Set a low value for maxAge to ensure cache entries expire soon.
   922  			rlsConfig.RouteLookupConfig.MaxAge = durationpb.New(defaultTestShortTimeout)
   923  
   924  			// Start a test backend, and setup the fake RLS server to return
   925  			// this as a target in the RLS response.
   926  			testBackendCh, testBackendAddress := startBackend(t)
   927  			rlsServer.SetResponseCallback(func(context.Context, *rlspb.RouteLookupRequest) *rlstest.RouteLookupResponse {
   928  				return &rlstest.RouteLookupResponse{Resp: &rlspb.RouteLookupResponse{Targets: []string{testBackendAddress}}}
   929  			})
   930  
   931  			// Register a manual resolver and push the RLS service config
   932  			// through it.
   933  			r := startManualResolverWithConfig(t, rlsConfig)
   934  
   935  			// Create new client.
   936  			cc, err := grpc.NewClient(r.Scheme()+":///", grpc.WithResolvers(r), grpc.WithTransportCredentials(insecure.NewCredentials()))
   937  			if err != nil {
   938  				t.Fatalf("Failed to create gRPC client: %v", err)
   939  			}
   940  			defer cc.Close()
   941  
   942  			// Make an RPC and ensure it gets routed to the test backend.
   943  			ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
   944  			defer cancel()
   945  			makeTestRPCAndExpectItToReachBackend(ctx, t, cc, testBackendCh)
   946  
   947  			// Make sure an RLS request is sent out.
   948  			verifyRLSRequest(t, rlsReqCh, true)
   949  			firstRPCDone.Fire()
   950  
   951  			// At this point, we have a cache entry with a small maxAge, and the
   952  			// RLS server is configured to block on further RLS requests. As we
   953  			// retry the RPC, at some point the cache entry would expire and
   954  			// force us to send an RLS request which would block on the server,
   955  			// giving us a pending cache entry for the duration of the test.
   956  			go func() {
   957  				for client := testgrpc.NewTestServiceClient(cc); ctx.Err() == nil; <-time.After(defaultTestShortTimeout) {
   958  					client.EmptyCall(ctx, &testpb.Empty{})
   959  				}
   960  			}()
   961  			verifyRLSRequest(t, rlsReqCh, true)
   962  
   963  			// Another RPC at this point should find the pending entry and be queued.
   964  			// But since we pass a small deadline, this RPC should fail with a
   965  			// deadline exceeded error since the pending request does not return until
   966  			// the test is done. And since we have a pending entry, we expect no RLS
   967  			// request to be sent out.
   968  			sCtx, sCancel := context.WithTimeout(ctx, defaultTestShortTimeout)
   969  			defer sCancel()
   970  			makeTestRPCAndVerifyError(sCtx, t, cc, codes.DeadlineExceeded, context.DeadlineExceeded)
   971  			verifyRLSRequest(t, rlsReqCh, false)
   972  		})
   973  	}
   974  }
   975  
   976  func TestIsFullMethodNameValid(t *testing.T) {
   977  	tests := []struct {
   978  		desc       string
   979  		methodName string
   980  		want       bool
   981  	}{
   982  		{
   983  			desc:       "does not start with a slash",
   984  			methodName: "service/method",
   985  			want:       false,
   986  		},
   987  		{
   988  			desc:       "does not contain a method",
   989  			methodName: "/service",
   990  			want:       false,
   991  		},
   992  		{
   993  			desc:       "path has more elements",
   994  			methodName: "/service/path/to/method",
   995  			want:       false,
   996  		},
   997  		{
   998  			desc:       "valid",
   999  			methodName: "/service/method",
  1000  			want:       true,
  1001  		},
  1002  	}
  1003  
  1004  	for _, test := range tests {
  1005  		t.Run(test.desc, func(t *testing.T) {
  1006  			if got := isFullMethodNameValid(test.methodName); got != test.want {
  1007  				t.Fatalf("isFullMethodNameValid(%q) = %v, want %v", test.methodName, got, test.want)
  1008  			}
  1009  		})
  1010  	}
  1011  }
  1012  
  1013  // Tests the conversion of the child pickers error to the pick result attribute.
  1014  func (s) TestChildPickResultError(t *testing.T) {
  1015  	tests := []struct {
  1016  		name string
  1017  		err  error
  1018  		want string
  1019  	}{
  1020  		{
  1021  			name: "nil",
  1022  			err:  nil,
  1023  			want: "complete",
  1024  		},
  1025  		{
  1026  			name: "errNoSubConnAvailable",
  1027  			err:  balancer.ErrNoSubConnAvailable,
  1028  			want: "queue",
  1029  		},
  1030  		{
  1031  			name: "status error",
  1032  			err:  status.Error(codes.Unimplemented, "unimplemented"),
  1033  			want: "drop",
  1034  		},
  1035  		{
  1036  			name: "other error",
  1037  			err:  errors.New("some error"),
  1038  			want: "fail",
  1039  		},
  1040  	}
  1041  
  1042  	for _, test := range tests {
  1043  		t.Run(test.name, func(t *testing.T) {
  1044  			if got := errToPickResult(test.err); got != test.want {
  1045  				t.Fatalf("errToPickResult(%q) = %v, want %v", test.err, got, test.want)
  1046  			}
  1047  		})
  1048  	}
  1049  }