google.golang.org/grpc@v1.62.1/balancer/rls/balancer_test.go (about) 1 /* 2 * 3 * Copyright 2022 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 "encoding/json" 24 "errors" 25 "fmt" 26 "sync" 27 "testing" 28 "time" 29 30 "github.com/google/go-cmp/cmp" 31 "google.golang.org/grpc" 32 "google.golang.org/grpc/balancer" 33 "google.golang.org/grpc/balancer/rls/internal/test/e2e" 34 "google.golang.org/grpc/codes" 35 "google.golang.org/grpc/connectivity" 36 "google.golang.org/grpc/credentials" 37 "google.golang.org/grpc/credentials/insecure" 38 "google.golang.org/grpc/internal" 39 "google.golang.org/grpc/internal/balancer/stub" 40 rlspb "google.golang.org/grpc/internal/proto/grpc_lookup_v1" 41 internalserviceconfig "google.golang.org/grpc/internal/serviceconfig" 42 "google.golang.org/grpc/internal/testutils" 43 rlstest "google.golang.org/grpc/internal/testutils/rls" 44 "google.golang.org/grpc/metadata" 45 "google.golang.org/grpc/resolver" 46 "google.golang.org/grpc/resolver/manual" 47 "google.golang.org/grpc/serviceconfig" 48 "google.golang.org/grpc/testdata" 49 "google.golang.org/protobuf/types/known/durationpb" 50 ) 51 52 // TestConfigUpdate_ControlChannel tests the scenario where a config update 53 // changes the RLS server name. Verifies that the new control channel is created 54 // and the old one is closed. 55 func (s) TestConfigUpdate_ControlChannel(t *testing.T) { 56 // Start two RLS servers. 57 lis1 := testutils.NewListenerWrapper(t, nil) 58 rlsServer1, rlsReqCh1 := rlstest.SetupFakeRLSServer(t, lis1) 59 lis2 := testutils.NewListenerWrapper(t, nil) 60 rlsServer2, rlsReqCh2 := rlstest.SetupFakeRLSServer(t, lis2) 61 62 // Build RLS service config with the RLS server pointing to the first one. 63 // Set a very low value for maxAge to ensure that the entry expires soon. 64 rlsConfig := buildBasicRLSConfigWithChildPolicy(t, t.Name(), rlsServer1.Address) 65 rlsConfig.RouteLookupConfig.MaxAge = durationpb.New(defaultTestShortTimeout) 66 67 // Start a couple of test backends, and set up the fake RLS servers to return 68 // these as a target in the RLS response. 69 backendCh1, backendAddress1 := startBackend(t) 70 rlsServer1.SetResponseCallback(func(_ context.Context, req *rlspb.RouteLookupRequest) *rlstest.RouteLookupResponse { 71 return &rlstest.RouteLookupResponse{Resp: &rlspb.RouteLookupResponse{Targets: []string{backendAddress1}}} 72 }) 73 backendCh2, backendAddress2 := startBackend(t) 74 rlsServer2.SetResponseCallback(func(_ context.Context, req *rlspb.RouteLookupRequest) *rlstest.RouteLookupResponse { 75 return &rlstest.RouteLookupResponse{Resp: &rlspb.RouteLookupResponse{Targets: []string{backendAddress2}}} 76 }) 77 78 // Register a manual resolver and push the RLS service config through it. 79 r := startManualResolverWithConfig(t, rlsConfig) 80 81 cc, err := grpc.Dial(r.Scheme()+":///", grpc.WithResolvers(r), grpc.WithTransportCredentials(insecure.NewCredentials())) 82 if err != nil { 83 t.Fatalf("grpc.Dial() failed: %v", err) 84 } 85 defer cc.Close() 86 87 // Make an RPC and ensure it gets routed to the test backend. 88 ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) 89 defer cancel() 90 makeTestRPCAndExpectItToReachBackend(ctx, t, cc, backendCh1) 91 92 // Ensure a connection is established to the first RLS server. 93 val, err := lis1.NewConnCh.Receive(ctx) 94 if err != nil { 95 t.Fatal("Timeout expired when waiting for LB policy to create control channel") 96 } 97 conn1 := val.(*testutils.ConnWrapper) 98 99 // Make sure an RLS request is sent out. 100 verifyRLSRequest(t, rlsReqCh1, true) 101 102 // Change lookup_service field of the RLS config to point to the second one. 103 rlsConfig.RouteLookupConfig.LookupService = rlsServer2.Address 104 105 // Push the config update through the manual resolver. 106 scJSON, err := rlsConfig.ServiceConfigJSON() 107 if err != nil { 108 t.Fatal(err) 109 } 110 sc := internal.ParseServiceConfig.(func(string) *serviceconfig.ParseResult)(scJSON) 111 r.UpdateState(resolver.State{ServiceConfig: sc}) 112 113 // Ensure a connection is established to the second RLS server. 114 if _, err := lis2.NewConnCh.Receive(ctx); err != nil { 115 t.Fatal("Timeout expired when waiting for LB policy to create control channel") 116 } 117 118 // Ensure the connection to the old one is closed. 119 if _, err := conn1.CloseCh.Receive(ctx); err != nil { 120 t.Fatal("Timeout expired when waiting for LB policy to close control channel") 121 } 122 123 // Make an RPC and expect it to get routed to the second test backend through 124 // the second RLS server. 125 makeTestRPCAndExpectItToReachBackend(ctx, t, cc, backendCh2) 126 verifyRLSRequest(t, rlsReqCh2, true) 127 } 128 129 // TestConfigUpdate_ControlChannelWithCreds tests the scenario where a config 130 // update specified an RLS server name, and the parent ClientConn specifies 131 // transport credentials. The RLS server and the test backend are configured to 132 // accept those transport credentials. This test verifies that the parent 133 // channel credentials are correctly propagated to the control channel. 134 func (s) TestConfigUpdate_ControlChannelWithCreds(t *testing.T) { 135 serverCreds, err := credentials.NewServerTLSFromFile(testdata.Path("x509/server1_cert.pem"), testdata.Path("x509/server1_key.pem")) 136 if err != nil { 137 t.Fatalf("credentials.NewServerTLSFromFile(server1.pem, server1.key) = %v", err) 138 } 139 clientCreds, err := credentials.NewClientTLSFromFile(testdata.Path("x509/server_ca_cert.pem"), "") 140 if err != nil { 141 t.Fatalf("credentials.NewClientTLSFromFile(ca.pem) = %v", err) 142 } 143 144 // Start an RLS server with the wrapped listener and credentials. 145 lis := testutils.NewListenerWrapper(t, nil) 146 rlsServer, rlsReqCh := rlstest.SetupFakeRLSServer(t, lis, grpc.Creds(serverCreds)) 147 overrideAdaptiveThrottler(t, neverThrottlingThrottler()) 148 149 // Build RLS service config. 150 rlsConfig := buildBasicRLSConfigWithChildPolicy(t, t.Name(), rlsServer.Address) 151 152 // Start a test backend which uses the same credentials as the RLS server, 153 // and set up the fake RLS server to return this as the target in the RLS 154 // response. 155 backendCh, backendAddress := startBackend(t, grpc.Creds(serverCreds)) 156 rlsServer.SetResponseCallback(func(_ context.Context, req *rlspb.RouteLookupRequest) *rlstest.RouteLookupResponse { 157 return &rlstest.RouteLookupResponse{Resp: &rlspb.RouteLookupResponse{Targets: []string{backendAddress}}} 158 }) 159 160 // Register a manual resolver and push the RLS service config through it. 161 r := startManualResolverWithConfig(t, rlsConfig) 162 163 // Dial with credentials and expect the RLS server to receive the same. The 164 // server certificate used for the RLS server and the backend specifies a 165 // DNS SAN of "*.test.example.com". Hence we use a dial target which is a 166 // subdomain of the same here. 167 cc, err := grpc.Dial(r.Scheme()+":///rls.test.example.com", grpc.WithResolvers(r), grpc.WithTransportCredentials(clientCreds)) 168 if err != nil { 169 t.Fatalf("grpc.Dial() failed: %v", err) 170 } 171 defer cc.Close() 172 173 // Make an RPC and ensure it gets routed to the test backend. 174 ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) 175 defer cancel() 176 makeTestRPCAndExpectItToReachBackend(ctx, t, cc, backendCh) 177 178 // Make sure an RLS request is sent out. 179 verifyRLSRequest(t, rlsReqCh, true) 180 181 // Ensure a connection is established to the first RLS server. 182 if _, err := lis.NewConnCh.Receive(ctx); err != nil { 183 t.Fatal("Timeout expired when waiting for LB policy to create control channel") 184 } 185 } 186 187 // TestConfigUpdate_ControlChannelServiceConfig tests the scenario where RLS LB 188 // policy's configuration specifies the service config for the control channel 189 // via the `routeLookupChannelServiceConfig` field. This test verifies that the 190 // provided service config is applied for the control channel. 191 func (s) TestConfigUpdate_ControlChannelServiceConfig(t *testing.T) { 192 // Start an RLS server and set the throttler to never throttle requests. 193 rlsServer, rlsReqCh := rlstest.SetupFakeRLSServer(t, nil) 194 overrideAdaptiveThrottler(t, neverThrottlingThrottler()) 195 196 // Register a balancer to be used for the control channel, and set up a 197 // callback to get notified when the balancer receives a clientConn updates. 198 ccUpdateCh := testutils.NewChannel() 199 bf := &e2e.BalancerFuncs{ 200 UpdateClientConnState: func(cfg *e2e.RLSChildPolicyConfig) error { 201 if cfg.Backend != rlsServer.Address { 202 return fmt.Errorf("control channel LB policy received config with backend %q, want %q", cfg.Backend, rlsServer.Address) 203 } 204 ccUpdateCh.Replace(nil) 205 return nil 206 }, 207 } 208 controlChannelPolicyName := "test-control-channel-" + t.Name() 209 e2e.RegisterRLSChildPolicy(controlChannelPolicyName, bf) 210 t.Logf("Registered child policy with name %q", controlChannelPolicyName) 211 212 // Build RLS service config and set the `routeLookupChannelServiceConfig` 213 // field to a service config which uses the above balancer. 214 rlsConfig := buildBasicRLSConfigWithChildPolicy(t, t.Name(), rlsServer.Address) 215 rlsConfig.RouteLookupChannelServiceConfig = fmt.Sprintf(`{"loadBalancingConfig" : [{%q: {"backend": %q} }]}`, controlChannelPolicyName, rlsServer.Address) 216 217 // Start a test backend, and set up the fake RLS server to return this as a 218 // target in the RLS response. 219 backendCh, backendAddress := startBackend(t) 220 rlsServer.SetResponseCallback(func(_ context.Context, req *rlspb.RouteLookupRequest) *rlstest.RouteLookupResponse { 221 return &rlstest.RouteLookupResponse{Resp: &rlspb.RouteLookupResponse{Targets: []string{backendAddress}}} 222 }) 223 224 // Register a manual resolver and push the RLS service config through it. 225 r := startManualResolverWithConfig(t, rlsConfig) 226 227 cc, err := grpc.Dial(r.Scheme()+":///rls.test.example.com", grpc.WithResolvers(r), grpc.WithTransportCredentials(insecure.NewCredentials())) 228 if err != nil { 229 t.Fatalf("grpc.Dial() failed: %v", err) 230 } 231 defer cc.Close() 232 233 // Make an RPC and ensure it gets routed to the test backend. 234 ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) 235 defer cancel() 236 makeTestRPCAndExpectItToReachBackend(ctx, t, cc, backendCh) 237 238 // Make sure an RLS request is sent out. 239 verifyRLSRequest(t, rlsReqCh, true) 240 241 // Verify that the control channel is using the LB policy we injected via the 242 // routeLookupChannelServiceConfig field. 243 if _, err := ccUpdateCh.Receive(ctx); err != nil { 244 t.Fatalf("timeout when waiting for control channel LB policy to receive a clientConn update") 245 } 246 } 247 248 // TestConfigUpdate_DefaultTarget tests the scenario where a config update 249 // changes the default target. Verifies that RPCs get routed to the new default 250 // target after the config has been applied. 251 func (s) TestConfigUpdate_DefaultTarget(t *testing.T) { 252 // Start an RLS server and set the throttler to always throttle requests. 253 rlsServer, _ := rlstest.SetupFakeRLSServer(t, nil) 254 overrideAdaptiveThrottler(t, alwaysThrottlingThrottler()) 255 256 // Build RLS service config with a default target. 257 rlsConfig := buildBasicRLSConfigWithChildPolicy(t, t.Name(), rlsServer.Address) 258 backendCh1, backendAddress1 := startBackend(t) 259 rlsConfig.RouteLookupConfig.DefaultTarget = backendAddress1 260 261 // Register a manual resolver and push the RLS service config through it. 262 r := startManualResolverWithConfig(t, rlsConfig) 263 264 cc, err := grpc.Dial(r.Scheme()+":///", grpc.WithResolvers(r), grpc.WithTransportCredentials(insecure.NewCredentials())) 265 if err != nil { 266 t.Fatalf("grpc.Dial() failed: %v", err) 267 } 268 defer cc.Close() 269 270 // Make an RPC and ensure it gets routed to the default target. 271 ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) 272 defer cancel() 273 makeTestRPCAndExpectItToReachBackend(ctx, t, cc, backendCh1) 274 275 // Change default_target field of the RLS config. 276 backendCh2, backendAddress2 := startBackend(t) 277 rlsConfig.RouteLookupConfig.DefaultTarget = backendAddress2 278 279 // Push the config update through the manual resolver. 280 scJSON, err := rlsConfig.ServiceConfigJSON() 281 if err != nil { 282 t.Fatal(err) 283 } 284 sc := internal.ParseServiceConfig.(func(string) *serviceconfig.ParseResult)(scJSON) 285 r.UpdateState(resolver.State{ServiceConfig: sc}) 286 makeTestRPCAndExpectItToReachBackend(ctx, t, cc, backendCh2) 287 } 288 289 // TestConfigUpdate_ChildPolicyConfigs verifies that config changes which affect 290 // child policy configuration are propagated correctly. 291 func (s) TestConfigUpdate_ChildPolicyConfigs(t *testing.T) { 292 // Start an RLS server and set the throttler to never throttle requests. 293 rlsServer, rlsReqCh := rlstest.SetupFakeRLSServer(t, nil) 294 overrideAdaptiveThrottler(t, neverThrottlingThrottler()) 295 296 // Start a default backend and a test backend. 297 _, defBackendAddress := startBackend(t) 298 testBackendCh, testBackendAddress := startBackend(t) 299 300 // Set up the RLS server to respond with the test backend. 301 rlsServer.SetResponseCallback(func(_ context.Context, req *rlspb.RouteLookupRequest) *rlstest.RouteLookupResponse { 302 return &rlstest.RouteLookupResponse{Resp: &rlspb.RouteLookupResponse{Targets: []string{testBackendAddress}}} 303 }) 304 305 // Set up a test balancer callback to push configs received by child policies. 306 defBackendConfigsCh := make(chan *e2e.RLSChildPolicyConfig, 1) 307 testBackendConfigsCh := make(chan *e2e.RLSChildPolicyConfig, 1) 308 bf := &e2e.BalancerFuncs{ 309 UpdateClientConnState: func(cfg *e2e.RLSChildPolicyConfig) error { 310 switch cfg.Backend { 311 case defBackendAddress: 312 defBackendConfigsCh <- cfg 313 case testBackendAddress: 314 testBackendConfigsCh <- cfg 315 default: 316 t.Errorf("Received child policy configs for unknown target %q", cfg.Backend) 317 } 318 return nil 319 }, 320 } 321 322 // Register an LB policy to act as the child policy for RLS LB policy. 323 childPolicyName := "test-child-policy" + t.Name() 324 e2e.RegisterRLSChildPolicy(childPolicyName, bf) 325 t.Logf("Registered child policy with name %q", childPolicyName) 326 327 // Build RLS service config with default target. 328 rlsConfig := buildBasicRLSConfig(childPolicyName, rlsServer.Address) 329 rlsConfig.RouteLookupConfig.DefaultTarget = defBackendAddress 330 331 // Register a manual resolver and push the RLS service config through it. 332 r := startManualResolverWithConfig(t, rlsConfig) 333 334 cc, err := grpc.Dial(r.Scheme()+":///", grpc.WithResolvers(r), grpc.WithTransportCredentials(insecure.NewCredentials())) 335 if err != nil { 336 t.Fatalf("grpc.Dial() failed: %v", err) 337 } 338 defer cc.Close() 339 340 // At this point, the RLS LB policy should have received its config, and 341 // should have created a child policy for the default target. 342 ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) 343 defer cancel() 344 wantCfg := &e2e.RLSChildPolicyConfig{Backend: defBackendAddress} 345 select { 346 case <-ctx.Done(): 347 t.Fatal("Timed out when waiting for the default target child policy to receive its config") 348 case gotCfg := <-defBackendConfigsCh: 349 if !cmp.Equal(gotCfg, wantCfg) { 350 t.Fatalf("Default target child policy received config %+v, want %+v", gotCfg, wantCfg) 351 } 352 } 353 354 // Make an RPC and ensure it gets routed to the test backend. 355 makeTestRPCAndExpectItToReachBackend(ctx, t, cc, testBackendCh) 356 357 // Make sure an RLS request is sent out. 358 verifyRLSRequest(t, rlsReqCh, true) 359 360 // As part of handling the above RPC, the RLS LB policy should have created 361 // a child policy for the test target. 362 wantCfg = &e2e.RLSChildPolicyConfig{Backend: testBackendAddress} 363 select { 364 case <-ctx.Done(): 365 t.Fatal("Timed out when waiting for the test target child policy to receive its config") 366 case gotCfg := <-testBackendConfigsCh: 367 if !cmp.Equal(gotCfg, wantCfg) { 368 t.Fatalf("Test target child policy received config %+v, want %+v", gotCfg, wantCfg) 369 } 370 } 371 372 // Push an RLS config update with a change in the child policy config. 373 childPolicyBuilder := balancer.Get(childPolicyName) 374 childPolicyParser := childPolicyBuilder.(balancer.ConfigParser) 375 lbCfg, err := childPolicyParser.ParseConfig([]byte(`{"Random": "random"}`)) 376 if err != nil { 377 t.Fatal(err) 378 } 379 rlsConfig.ChildPolicy.Config = lbCfg 380 scJSON, err := rlsConfig.ServiceConfigJSON() 381 if err != nil { 382 t.Fatal(err) 383 } 384 sc := internal.ParseServiceConfig.(func(string) *serviceconfig.ParseResult)(scJSON) 385 r.UpdateState(resolver.State{ServiceConfig: sc}) 386 387 // Expect the child policy for the test backend to receive the update. 388 wantCfg = &e2e.RLSChildPolicyConfig{ 389 Backend: testBackendAddress, 390 Random: "random", 391 } 392 select { 393 case <-ctx.Done(): 394 t.Fatal("Timed out when waiting for the test target child policy to receive its config") 395 case gotCfg := <-testBackendConfigsCh: 396 if !cmp.Equal(gotCfg, wantCfg) { 397 t.Fatalf("Test target child policy received config %+v, want %+v", gotCfg, wantCfg) 398 } 399 } 400 401 // Expect the child policy for the default backend to receive the update. 402 wantCfg = &e2e.RLSChildPolicyConfig{ 403 Backend: defBackendAddress, 404 Random: "random", 405 } 406 select { 407 case <-ctx.Done(): 408 t.Fatal("Timed out when waiting for the default target child policy to receive its config") 409 case gotCfg := <-defBackendConfigsCh: 410 if !cmp.Equal(gotCfg, wantCfg) { 411 t.Fatalf("Default target child policy received config %+v, want %+v", gotCfg, wantCfg) 412 } 413 } 414 } 415 416 // TestConfigUpdate_ChildPolicyChange verifies that a child policy change is 417 // handled by closing the old balancer and creating a new one. 418 func (s) TestConfigUpdate_ChildPolicyChange(t *testing.T) { 419 // Start an RLS server and set the throttler to never throttle requests. 420 rlsServer, _ := rlstest.SetupFakeRLSServer(t, nil) 421 overrideAdaptiveThrottler(t, neverThrottlingThrottler()) 422 423 // Set up balancer callbacks. 424 configsCh1 := make(chan *e2e.RLSChildPolicyConfig, 1) 425 closeCh1 := make(chan struct{}, 1) 426 bf := &e2e.BalancerFuncs{ 427 UpdateClientConnState: func(cfg *e2e.RLSChildPolicyConfig) error { 428 configsCh1 <- cfg 429 return nil 430 }, 431 Close: func() { 432 closeCh1 <- struct{}{} 433 }, 434 } 435 436 // Register an LB policy to act as the child policy for RLS LB policy. 437 childPolicyName1 := "test-child-policy-1" + t.Name() 438 e2e.RegisterRLSChildPolicy(childPolicyName1, bf) 439 t.Logf("Registered child policy with name %q", childPolicyName1) 440 441 // Build RLS service config with a dummy default target. 442 const defaultBackend = "default-backend" 443 rlsConfig := buildBasicRLSConfig(childPolicyName1, rlsServer.Address) 444 rlsConfig.RouteLookupConfig.DefaultTarget = defaultBackend 445 446 // Register a manual resolver and push the RLS service config through it. 447 r := startManualResolverWithConfig(t, rlsConfig) 448 449 cc, err := grpc.Dial(r.Scheme()+":///", grpc.WithResolvers(r), grpc.WithTransportCredentials(insecure.NewCredentials())) 450 if err != nil { 451 t.Fatalf("grpc.Dial() failed: %v", err) 452 } 453 defer cc.Close() 454 455 // At this point, the RLS LB policy should have received its config, and 456 // should have created a child policy for the default target. 457 ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) 458 defer cancel() 459 wantCfg := &e2e.RLSChildPolicyConfig{Backend: defaultBackend} 460 select { 461 case <-ctx.Done(): 462 t.Fatal("Timed out when waiting for the first child policy to receive its config") 463 case gotCfg := <-configsCh1: 464 if !cmp.Equal(gotCfg, wantCfg) { 465 t.Fatalf("First child policy received config %+v, want %+v", gotCfg, wantCfg) 466 } 467 } 468 469 // Set up balancer callbacks for the second policy. 470 configsCh2 := make(chan *e2e.RLSChildPolicyConfig, 1) 471 bf = &e2e.BalancerFuncs{ 472 UpdateClientConnState: func(cfg *e2e.RLSChildPolicyConfig) error { 473 configsCh2 <- cfg 474 return nil 475 }, 476 } 477 478 // Register a second LB policy to act as the child policy for RLS LB policy. 479 childPolicyName2 := "test-child-policy-2" + t.Name() 480 e2e.RegisterRLSChildPolicy(childPolicyName2, bf) 481 t.Logf("Registered child policy with name %q", childPolicyName2) 482 483 // Push an RLS config update with a change in the child policy name. 484 rlsConfig.ChildPolicy = &internalserviceconfig.BalancerConfig{Name: childPolicyName2} 485 scJSON, err := rlsConfig.ServiceConfigJSON() 486 if err != nil { 487 t.Fatal(err) 488 } 489 sc := internal.ParseServiceConfig.(func(string) *serviceconfig.ParseResult)(scJSON) 490 r.UpdateState(resolver.State{ServiceConfig: sc}) 491 492 // The above update should result in the first LB policy being shutdown and 493 // the second LB policy receiving a config update. 494 select { 495 case <-ctx.Done(): 496 t.Fatal("Timed out when waiting for the first child policy to be shutdown") 497 case <-closeCh1: 498 } 499 500 select { 501 case <-ctx.Done(): 502 t.Fatal("Timed out when waiting for the second child policy to receive its config") 503 case gotCfg := <-configsCh2: 504 if !cmp.Equal(gotCfg, wantCfg) { 505 t.Fatalf("First child policy received config %+v, want %+v", gotCfg, wantCfg) 506 } 507 } 508 } 509 510 // TestConfigUpdate_BadChildPolicyConfigs tests the scenario where a config 511 // update is rejected by the child policy. Verifies that the child policy 512 // wrapper goes "lame" and the error from the child policy is reported back to 513 // the caller of the RPC. 514 func (s) TestConfigUpdate_BadChildPolicyConfigs(t *testing.T) { 515 // Start an RLS server and set the throttler to never throttle requests. 516 rlsServer, rlsReqCh := rlstest.SetupFakeRLSServer(t, nil) 517 overrideAdaptiveThrottler(t, neverThrottlingThrottler()) 518 519 // Set up the RLS server to respond with a bad target field which is expected 520 // to cause the child policy's ParseTarget to fail and should result in the LB 521 // policy creating a lame child policy wrapper. 522 rlsServer.SetResponseCallback(func(_ context.Context, req *rlspb.RouteLookupRequest) *rlstest.RouteLookupResponse { 523 return &rlstest.RouteLookupResponse{Resp: &rlspb.RouteLookupResponse{Targets: []string{e2e.RLSChildPolicyBadTarget}}} 524 }) 525 526 // Build RLS service config with a default target. This default backend is 527 // expected to be healthy (even though we don't attempt to route RPCs to it) 528 // and ensures that the overall connectivity state of the RLS LB policy is not 529 // TRANSIENT_FAILURE. This is required to make sure that the pick for the bad 530 // child policy actually gets delegated to the child policy picker. 531 rlsConfig := buildBasicRLSConfigWithChildPolicy(t, t.Name(), rlsServer.Address) 532 _, addr := startBackend(t) 533 rlsConfig.RouteLookupConfig.DefaultTarget = addr 534 535 // Register a manual resolver and push the RLS service config through it. 536 r := startManualResolverWithConfig(t, rlsConfig) 537 538 cc, err := grpc.Dial(r.Scheme()+":///", grpc.WithResolvers(r), grpc.WithTransportCredentials(insecure.NewCredentials())) 539 if err != nil { 540 t.Fatalf("grpc.Dial() failed: %v", err) 541 } 542 defer cc.Close() 543 544 // Make an RPC and ensure that if fails with the expected error. 545 ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) 546 defer cancel() 547 makeTestRPCAndVerifyError(ctx, t, cc, codes.Unavailable, e2e.ErrParseConfigBadTarget) 548 549 // Make sure an RLS request is sent out. 550 verifyRLSRequest(t, rlsReqCh, true) 551 } 552 553 // TestConfigUpdate_DataCacheSizeDecrease tests the scenario where a config 554 // update decreases the data cache size. Verifies that entries are evicted from 555 // the cache. 556 func (s) TestConfigUpdate_DataCacheSizeDecrease(t *testing.T) { 557 // Override the clientConn update hook to get notified. 558 clientConnUpdateDone := make(chan struct{}, 1) 559 origClientConnUpdateHook := clientConnUpdateHook 560 clientConnUpdateHook = func() { clientConnUpdateDone <- struct{}{} } 561 defer func() { clientConnUpdateHook = origClientConnUpdateHook }() 562 563 // Override the cache entry size func, and always return 1. 564 origEntrySizeFunc := computeDataCacheEntrySize 565 computeDataCacheEntrySize = func(cacheKey, *cacheEntry) int64 { return 1 } 566 defer func() { computeDataCacheEntrySize = origEntrySizeFunc }() 567 568 // Override the minEvictionDuration to ensure that when the config update 569 // reduces the cache size, the resize operation is not stopped because 570 // we find an entry whose minExpiryDuration has not elapsed. 571 origMinEvictDuration := minEvictDuration 572 minEvictDuration = time.Duration(0) 573 defer func() { minEvictDuration = origMinEvictDuration }() 574 575 // Start an RLS server and set the throttler to never throttle requests. 576 rlsServer, rlsReqCh := rlstest.SetupFakeRLSServer(t, nil) 577 overrideAdaptiveThrottler(t, neverThrottlingThrottler()) 578 579 // Register an LB policy to act as the child policy for RLS LB policy. 580 childPolicyName := "test-child-policy" + t.Name() 581 e2e.RegisterRLSChildPolicy(childPolicyName, nil) 582 t.Logf("Registered child policy with name %q", childPolicyName) 583 584 // Build RLS service config with header matchers. 585 rlsConfig := buildBasicRLSConfig(childPolicyName, rlsServer.Address) 586 587 // Start a couple of test backends, and set up the fake RLS server to return 588 // these as targets in the RLS response, based on request keys. 589 backendCh1, backendAddress1 := startBackend(t) 590 backendCh2, backendAddress2 := startBackend(t) 591 rlsServer.SetResponseCallback(func(ctx context.Context, req *rlspb.RouteLookupRequest) *rlstest.RouteLookupResponse { 592 if req.KeyMap["k1"] == "v1" { 593 return &rlstest.RouteLookupResponse{Resp: &rlspb.RouteLookupResponse{Targets: []string{backendAddress1}}} 594 } 595 if req.KeyMap["k2"] == "v2" { 596 return &rlstest.RouteLookupResponse{Resp: &rlspb.RouteLookupResponse{Targets: []string{backendAddress2}}} 597 } 598 return &rlstest.RouteLookupResponse{Err: errors.New("no keys in request metadata")} 599 }) 600 601 // Register a manual resolver and push the RLS service config through it. 602 r := startManualResolverWithConfig(t, rlsConfig) 603 604 cc, err := grpc.Dial(r.Scheme()+":///", grpc.WithResolvers(r), grpc.WithTransportCredentials(insecure.NewCredentials())) 605 if err != nil { 606 t.Fatalf("grpc.Dial() failed: %v", err) 607 } 608 defer cc.Close() 609 610 <-clientConnUpdateDone 611 612 // Make an RPC and ensure it gets routed to the first backend. 613 ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) 614 defer cancel() 615 ctxOutgoing := metadata.AppendToOutgoingContext(ctx, "n1", "v1") 616 makeTestRPCAndExpectItToReachBackend(ctxOutgoing, t, cc, backendCh1) 617 618 // Make sure an RLS request is sent out. 619 verifyRLSRequest(t, rlsReqCh, true) 620 621 // Make another RPC with a different set of headers. This will force the LB 622 // policy to send out a new RLS request, resulting in a new data cache 623 // entry. 624 ctxOutgoing = metadata.AppendToOutgoingContext(ctx, "n2", "v2") 625 makeTestRPCAndExpectItToReachBackend(ctxOutgoing, t, cc, backendCh2) 626 627 // Make sure an RLS request is sent out. 628 verifyRLSRequest(t, rlsReqCh, true) 629 630 // We currently have two cache entries. Setting the size to 1, will cause 631 // the entry corresponding to backend1 to be evicted. 632 rlsConfig.RouteLookupConfig.CacheSizeBytes = 1 633 634 // Push the config update through the manual resolver. 635 scJSON, err := rlsConfig.ServiceConfigJSON() 636 if err != nil { 637 t.Fatal(err) 638 } 639 sc := internal.ParseServiceConfig.(func(string) *serviceconfig.ParseResult)(scJSON) 640 r.UpdateState(resolver.State{ServiceConfig: sc}) 641 642 <-clientConnUpdateDone 643 644 // Make an RPC to match the cache entry which got evicted above, and expect 645 // an RLS request to be made to fetch the targets. 646 ctxOutgoing = metadata.AppendToOutgoingContext(ctx, "n1", "v1") 647 makeTestRPCAndExpectItToReachBackend(ctxOutgoing, t, cc, backendCh1) 648 649 // Make sure an RLS request is sent out. 650 verifyRLSRequest(t, rlsReqCh, true) 651 } 652 653 // TestDataCachePurging verifies that the LB policy periodically evicts expired 654 // entries from the data cache. 655 func (s) TestDataCachePurging(t *testing.T) { 656 // Override the frequency of the data cache purger to a small one. 657 origDataCachePurgeTicker := dataCachePurgeTicker 658 ticker := time.NewTicker(defaultTestShortTimeout) 659 defer ticker.Stop() 660 dataCachePurgeTicker = func() *time.Ticker { return ticker } 661 defer func() { dataCachePurgeTicker = origDataCachePurgeTicker }() 662 663 // Override the data cache purge hook to get notified. 664 dataCachePurgeDone := make(chan struct{}, 1) 665 origDataCachePurgeHook := dataCachePurgeHook 666 dataCachePurgeHook = func() { dataCachePurgeDone <- struct{}{} } 667 defer func() { dataCachePurgeHook = origDataCachePurgeHook }() 668 669 // Start an RLS server and set the throttler to never throttle requests. 670 rlsServer, rlsReqCh := rlstest.SetupFakeRLSServer(t, nil) 671 overrideAdaptiveThrottler(t, neverThrottlingThrottler()) 672 673 // Register an LB policy to act as the child policy for RLS LB policy. 674 childPolicyName := "test-child-policy" + t.Name() 675 e2e.RegisterRLSChildPolicy(childPolicyName, nil) 676 t.Logf("Registered child policy with name %q", childPolicyName) 677 678 // Build RLS service config with header matchers and lookupService pointing to 679 // the fake RLS server created above. Set a very low value for maxAge to 680 // ensure that the entry expires soon. 681 rlsConfig := buildBasicRLSConfig(childPolicyName, rlsServer.Address) 682 rlsConfig.RouteLookupConfig.MaxAge = durationpb.New(time.Millisecond) 683 684 // Start a test backend, and set up the fake RLS server to return this as a 685 // target in the RLS response. 686 backendCh, backendAddress := startBackend(t) 687 rlsServer.SetResponseCallback(func(_ context.Context, req *rlspb.RouteLookupRequest) *rlstest.RouteLookupResponse { 688 return &rlstest.RouteLookupResponse{Resp: &rlspb.RouteLookupResponse{Targets: []string{backendAddress}}} 689 }) 690 691 // Register a manual resolver and push the RLS service config through it. 692 r := startManualResolverWithConfig(t, rlsConfig) 693 694 cc, err := grpc.Dial(r.Scheme()+":///", grpc.WithResolvers(r), grpc.WithTransportCredentials(insecure.NewCredentials())) 695 if err != nil { 696 t.Fatalf("grpc.Dial() failed: %v", err) 697 } 698 defer cc.Close() 699 700 // Make an RPC and ensure it gets routed to the test backend. 701 ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) 702 defer cancel() 703 ctxOutgoing := metadata.AppendToOutgoingContext(ctx, "n1", "v1") 704 makeTestRPCAndExpectItToReachBackend(ctxOutgoing, t, cc, backendCh) 705 706 // Make sure an RLS request is sent out. 707 verifyRLSRequest(t, rlsReqCh, true) 708 709 // Make another RPC with different headers. This will force the LB policy to 710 // send out a new RLS request, resulting in a new data cache entry. 711 ctxOutgoing = metadata.AppendToOutgoingContext(ctx, "n2", "v2") 712 makeTestRPCAndExpectItToReachBackend(ctxOutgoing, t, cc, backendCh) 713 714 // Make sure an RLS request is sent out. 715 verifyRLSRequest(t, rlsReqCh, true) 716 717 // Wait for the data cache purging to happen before proceeding. 718 <-dataCachePurgeDone 719 720 // Perform the same RPCs again and verify that they result in RLS requests. 721 ctxOutgoing = metadata.AppendToOutgoingContext(ctx, "n1", "v1") 722 makeTestRPCAndExpectItToReachBackend(ctxOutgoing, t, cc, backendCh) 723 724 // Make sure an RLS request is sent out. 725 verifyRLSRequest(t, rlsReqCh, true) 726 727 // Make another RPC with different headers. This will force the LB policy to 728 // send out a new RLS request, resulting in a new data cache entry. 729 ctxOutgoing = metadata.AppendToOutgoingContext(ctx, "n2", "v2") 730 makeTestRPCAndExpectItToReachBackend(ctxOutgoing, t, cc, backendCh) 731 732 // Make sure an RLS request is sent out. 733 verifyRLSRequest(t, rlsReqCh, true) 734 } 735 736 // TestControlChannelConnectivityStateMonitoring tests the scenario where the 737 // control channel goes down and comes back up again and verifies that backoff 738 // state is reset for cache entries in this scenario. 739 func (s) TestControlChannelConnectivityStateMonitoring(t *testing.T) { 740 // Create a restartable listener which can close existing connections. 741 l, err := testutils.LocalTCPListener() 742 if err != nil { 743 t.Fatalf("net.Listen() failed: %v", err) 744 } 745 lis := testutils.NewRestartableListener(l) 746 747 // Start an RLS server with the restartable listener and set the throttler to 748 // never throttle requests. 749 rlsServer, rlsReqCh := rlstest.SetupFakeRLSServer(t, lis) 750 overrideAdaptiveThrottler(t, neverThrottlingThrottler()) 751 752 // Override the reset backoff hook to get notified. 753 resetBackoffDone := make(chan struct{}, 1) 754 origResetBackoffHook := resetBackoffHook 755 resetBackoffHook = func() { resetBackoffDone <- struct{}{} } 756 defer func() { resetBackoffHook = origResetBackoffHook }() 757 758 // Override the backoff strategy to return a large backoff which 759 // will make sure the date cache entry remains in backoff for the 760 // duration of the test. 761 origBackoffStrategy := defaultBackoffStrategy 762 defaultBackoffStrategy = &fakeBackoffStrategy{backoff: defaultTestTimeout} 763 defer func() { defaultBackoffStrategy = origBackoffStrategy }() 764 765 // Register an LB policy to act as the child policy for RLS LB policy. 766 childPolicyName := "test-child-policy" + t.Name() 767 e2e.RegisterRLSChildPolicy(childPolicyName, nil) 768 t.Logf("Registered child policy with name %q", childPolicyName) 769 770 // Build RLS service config with header matchers, and a very low value for 771 // maxAge to ensure that cache entries become invalid very soon. 772 rlsConfig := buildBasicRLSConfig(childPolicyName, rlsServer.Address) 773 rlsConfig.RouteLookupConfig.MaxAge = durationpb.New(defaultTestShortTimeout) 774 775 // Start a test backend, and set up the fake RLS server to return this as a 776 // target in the RLS response. 777 backendCh, backendAddress := startBackend(t) 778 rlsServer.SetResponseCallback(func(_ context.Context, req *rlspb.RouteLookupRequest) *rlstest.RouteLookupResponse { 779 return &rlstest.RouteLookupResponse{Resp: &rlspb.RouteLookupResponse{Targets: []string{backendAddress}}} 780 }) 781 782 // Register a manual resolver and push the RLS service config through it. 783 r := startManualResolverWithConfig(t, rlsConfig) 784 785 cc, err := grpc.Dial(r.Scheme()+":///", grpc.WithResolvers(r), grpc.WithTransportCredentials(insecure.NewCredentials())) 786 if err != nil { 787 t.Fatalf("grpc.Dial() failed: %v", err) 788 } 789 defer cc.Close() 790 791 // Make an RPC and ensure it gets routed to the test backend. 792 ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) 793 defer cancel() 794 makeTestRPCAndExpectItToReachBackend(ctx, t, cc, backendCh) 795 796 // Make sure an RLS request is sent out. 797 verifyRLSRequest(t, rlsReqCh, true) 798 799 // Stop the RLS server. 800 lis.Stop() 801 802 // Make another RPC similar to the first one. Since the above cache entry 803 // would have expired by now, this should trigger another RLS request. And 804 // since the RLS server is down, RLS request will fail and the cache entry 805 // will enter backoff, and we have overridden the default backoff strategy to 806 // return a value which will keep this entry in backoff for the whole duration 807 // of the test. 808 makeTestRPCAndVerifyError(ctx, t, cc, codes.Unavailable, nil) 809 810 // Restart the RLS server. 811 lis.Restart() 812 813 // When we closed the RLS server earlier, the existing transport to the RLS 814 // server would have closed, and the RLS control channel would have moved to 815 // TRANSIENT_FAILURE with a subConn backoff before moving to IDLE. This 816 // backoff will last for about a second. We need to keep retrying RPCs for the 817 // subConn to eventually come out of backoff and attempt to reconnect. 818 // 819 // Make this RPC with a different set of headers leading to the creation of 820 // a new cache entry and a new RLS request. This RLS request will also fail 821 // till the control channel comes moves back to READY. So, override the 822 // backoff strategy to perform a small backoff on this entry. 823 defaultBackoffStrategy = &fakeBackoffStrategy{backoff: defaultTestShortTimeout} 824 ctxOutgoing := metadata.AppendToOutgoingContext(ctx, "n1", "v1") 825 makeTestRPCAndExpectItToReachBackend(ctxOutgoing, t, cc, backendCh) 826 827 select { 828 case <-ctx.Done(): 829 t.Fatalf("Timed out waiting for resetBackoffDone") 830 case <-resetBackoffDone: 831 } 832 833 // The fact that the above RPC succeeded indicates that the control channel 834 // has moved back to READY. The connectivity state monitoring code should have 835 // realized this and should have reset all backoff timers (which in this case 836 // is the cache entry corresponding to the first RPC). Retrying that RPC now 837 // should succeed with an RLS request being sent out. 838 makeTestRPCAndExpectItToReachBackend(ctx, t, cc, backendCh) 839 verifyRLSRequest(t, rlsReqCh, true) 840 } 841 842 // testCCWrapper wraps a balancer.ClientConn and overrides UpdateState and 843 // stores all state updates pushed by the RLS LB policy. 844 type testCCWrapper struct { 845 balancer.ClientConn 846 847 mu sync.Mutex 848 states []balancer.State 849 } 850 851 func (t *testCCWrapper) UpdateState(bs balancer.State) { 852 t.mu.Lock() 853 t.states = append(t.states, bs) 854 t.mu.Unlock() 855 t.ClientConn.UpdateState(bs) 856 } 857 858 func (t *testCCWrapper) getStates() []balancer.State { 859 t.mu.Lock() 860 defer t.mu.Unlock() 861 862 states := make([]balancer.State, len(t.states)) 863 copy(states, t.states) 864 return states 865 } 866 867 // TestUpdateStatePauses tests the scenario where a config update received by 868 // the RLS LB policy results in multiple UpdateState calls from the child 869 // policies. This test verifies that picker updates are paused when the config 870 // update is being processed by RLS LB policy and its child policies. 871 // 872 // The test uses a wrapping balancer as the top-level LB policy on the channel. 873 // The wrapping balancer wraps an RLS LB policy as a child policy and forwards 874 // all calls to it. It also records the UpdateState() calls from the RLS LB 875 // policy and makes it available for inspection by the test. 876 // 877 // The test uses another wrapped balancer (which wraps a pickfirst balancer) as 878 // the child policy of the RLS LB policy. This balancer makes multiple 879 // UpdateState calls when handling an update from its parent in 880 // UpdateClientConnState. 881 func (s) TestUpdateStatePauses(t *testing.T) { 882 // Override the hook to get notified when UpdateClientConnState is done. 883 clientConnUpdateDone := make(chan struct{}, 1) 884 origClientConnUpdateHook := clientConnUpdateHook 885 clientConnUpdateHook = func() { clientConnUpdateDone <- struct{}{} } 886 defer func() { clientConnUpdateHook = origClientConnUpdateHook }() 887 888 // Register the top-level wrapping balancer which forwards calls to RLS. 889 topLevelBalancerName := t.Name() + "top-level" 890 var ccWrapper *testCCWrapper 891 stub.Register(topLevelBalancerName, stub.BalancerFuncs{ 892 Init: func(bd *stub.BalancerData) { 893 ccWrapper = &testCCWrapper{ClientConn: bd.ClientConn} 894 bd.Data = balancer.Get(Name).Build(ccWrapper, bd.BuildOptions) 895 }, 896 ParseConfig: func(sc json.RawMessage) (serviceconfig.LoadBalancingConfig, error) { 897 parser := balancer.Get(Name).(balancer.ConfigParser) 898 return parser.ParseConfig(sc) 899 }, 900 UpdateClientConnState: func(bd *stub.BalancerData, ccs balancer.ClientConnState) error { 901 bal := bd.Data.(balancer.Balancer) 902 return bal.UpdateClientConnState(ccs) 903 }, 904 Close: func(bd *stub.BalancerData) { 905 bal := bd.Data.(balancer.Balancer) 906 bal.Close() 907 }, 908 }) 909 910 // Register a child policy that wraps a pickfirst balancer and makes multiple calls 911 // to UpdateState when handling a config update in UpdateClientConnState. When 912 // this policy is used as a child policy of the RLS LB policy, it is expected 913 // that the latter suppress these updates and push a single picker update on the 914 // channel (after the config has been processed by all child policies). 915 childPolicyName := t.Name() + "child" 916 type childPolicyConfig struct { 917 serviceconfig.LoadBalancingConfig 918 Backend string // `json:"backend,omitempty"` 919 } 920 stub.Register(childPolicyName, stub.BalancerFuncs{ 921 Init: func(bd *stub.BalancerData) { 922 bd.Data = balancer.Get(grpc.PickFirstBalancerName).Build(bd.ClientConn, bd.BuildOptions) 923 }, 924 ParseConfig: func(sc json.RawMessage) (serviceconfig.LoadBalancingConfig, error) { 925 cfg := &childPolicyConfig{} 926 if err := json.Unmarshal(sc, cfg); err != nil { 927 return nil, err 928 } 929 return cfg, nil 930 }, 931 UpdateClientConnState: func(bd *stub.BalancerData, ccs balancer.ClientConnState) error { 932 bal := bd.Data.(balancer.Balancer) 933 bd.ClientConn.UpdateState(balancer.State{ConnectivityState: connectivity.Idle, Picker: &testutils.TestConstPicker{Err: balancer.ErrNoSubConnAvailable}}) 934 bd.ClientConn.UpdateState(balancer.State{ConnectivityState: connectivity.Connecting, Picker: &testutils.TestConstPicker{Err: balancer.ErrNoSubConnAvailable}}) 935 936 cfg := ccs.BalancerConfig.(*childPolicyConfig) 937 return bal.UpdateClientConnState(balancer.ClientConnState{ 938 ResolverState: resolver.State{Addresses: []resolver.Address{{Addr: cfg.Backend}}}, 939 }) 940 }, 941 }) 942 943 // Start an RLS server and set the throttler to never throttle requests. 944 rlsServer, rlsReqCh := rlstest.SetupFakeRLSServer(t, nil) 945 overrideAdaptiveThrottler(t, neverThrottlingThrottler()) 946 947 // Start a test backend and set the RLS server to respond with it. 948 testBackendCh, testBackendAddress := startBackend(t) 949 rlsServer.SetResponseCallback(func(_ context.Context, req *rlspb.RouteLookupRequest) *rlstest.RouteLookupResponse { 950 return &rlstest.RouteLookupResponse{Resp: &rlspb.RouteLookupResponse{Targets: []string{testBackendAddress}}} 951 }) 952 953 // Register a manual resolver and push the RLS service config through it. 954 r := manual.NewBuilderWithScheme("rls-e2e") 955 scJSON := fmt.Sprintf(` 956 { 957 "loadBalancingConfig": [ 958 { 959 "%s": { 960 "routeLookupConfig": { 961 "grpcKeybuilders": [{ 962 "names": [{"service": "grpc.testing.TestService"}] 963 }], 964 "lookupService": "%s", 965 "cacheSizeBytes": 1000 966 }, 967 "childPolicy": [{"%s": {}}], 968 "childPolicyConfigTargetFieldName": "Backend" 969 } 970 } 971 ] 972 }`, topLevelBalancerName, rlsServer.Address, childPolicyName) 973 sc := internal.ParseServiceConfig.(func(string) *serviceconfig.ParseResult)(scJSON) 974 r.InitialState(resolver.State{ServiceConfig: sc}) 975 976 cc, err := grpc.Dial(r.Scheme()+":///", grpc.WithResolvers(r), grpc.WithTransportCredentials(insecure.NewCredentials())) 977 if err != nil { 978 t.Fatalf("grpc.Dial() failed: %v", err) 979 } 980 defer cc.Close() 981 982 // Wait for the clientconn update to be processed by the RLS LB policy. 983 ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) 984 defer cancel() 985 select { 986 case <-ctx.Done(): 987 case <-clientConnUpdateDone: 988 } 989 990 // It is important to note that at this point no child policies have been 991 // created because we have not attempted any RPC so far. When we attempt an 992 // RPC (below), child policies will be created and their configs will be 993 // pushed to them. But this config update will not happen in the context of 994 // a config update on the parent. 995 996 // Make an RPC and ensure it gets routed to the test backend. 997 makeTestRPCAndExpectItToReachBackend(ctx, t, cc, testBackendCh) 998 999 // Make sure an RLS request is sent out. 1000 verifyRLSRequest(t, rlsReqCh, true) 1001 1002 // Wait for the control channel to become READY, before reading the states 1003 // out of the wrapping top-level balancer. 1004 // 1005 // makeTestRPCAndExpectItToReachBackend repeatedly sends RPCs with short 1006 // deadlines until one succeeds. See its docstring for details. 1007 // 1008 // The following sequence of events is possible: 1009 // 1. When the first RPC is attempted above, a pending cache entry is 1010 // created, an RLS request is sent out, and the pick is queued. The 1011 // channel is in CONNECTING state. 1012 // 2. When the RLS response arrives, the pending cache entry is moved to the 1013 // data cache, a child policy is created for the target specified in the 1014 // response and a new picker is returned. The channel is still in 1015 // CONNECTING, and retried pick is again queued. 1016 // 3. The child policy moves through the standard set of states, IDLE --> 1017 // CONNECTING --> READY. And for each of these state changes, a new 1018 // picker is sent on the channel. But the overall connectivity state of 1019 // the channel is still CONNECTING. 1020 // 4. Right around the time when the child policy becomes READY, the 1021 // deadline associated with the first RPC made by 1022 // makeTestRPCAndExpectItToReachBackend() could expire, and it could send 1023 // a new one. And because the internal state of the LB policy now 1024 // contains a child policy which is READY, this RPC will succeed. But the 1025 // RLS LB policy has yet to push a new picker on the channel. 1026 // 5. If we read the states seen by the top-level wrapping LB policy without 1027 // waiting for the channel to become READY, there is a possibility that we 1028 // might not see the READY state in there. And if that happens, we will 1029 // see two extra states in the last check made in the test, and thereby 1030 // the test would fail. Waiting for the channel to become READY here 1031 // ensures that the test does not flake because of this rare sequence of 1032 // events. 1033 testutils.AwaitState(ctx, t, cc, connectivity.Ready) 1034 1035 // Cache the state changes seen up to this point. 1036 states0 := ccWrapper.getStates() 1037 1038 // Push an updated service config. As mentioned earlier, the previous config 1039 // updates on the child policies did not happen in the context of a config 1040 // update on the parent. Hence, this update is required to force the 1041 // scenario which we are interesting in testing here, i.e child policies get 1042 // config updates as part of the parent policy getting its config update. 1043 scJSON = fmt.Sprintf(` 1044 { 1045 "loadBalancingConfig": [ 1046 { 1047 "%s": { 1048 "routeLookupConfig": { 1049 "grpcKeybuilders": [{ 1050 "names": [ 1051 {"service": "grpc.testing.TestService"}, 1052 {"service": "grpc.health.v1.Health"} 1053 ] 1054 }], 1055 "lookupService": "%s", 1056 "cacheSizeBytes": 1000 1057 }, 1058 "childPolicy": [{"%s": {}}], 1059 "childPolicyConfigTargetFieldName": "Backend" 1060 } 1061 } 1062 ] 1063 }`, topLevelBalancerName, rlsServer.Address, childPolicyName) 1064 sc = internal.ParseServiceConfig.(func(string) *serviceconfig.ParseResult)(scJSON) 1065 r.UpdateState(resolver.State{ServiceConfig: sc}) 1066 1067 // Wait for the clientconn update to be processed by the RLS LB policy. 1068 select { 1069 case <-ctx.Done(): 1070 case <-clientConnUpdateDone: 1071 } 1072 1073 // Even though the child policies used in this test make multiple calls to 1074 // UpdateState as part of handling their configs, we expect the RLS policy 1075 // to inhibit picker updates during this time frame, and send a single 1076 // picker once the config update is completely handled. 1077 states1 := ccWrapper.getStates() 1078 if len(states1) != len(states0)+1 { 1079 t.Fatalf("more than one state update seen. before %v, after %v", states0, states1) 1080 } 1081 }