TestConfigUpdate_ControlChannel tests the scenario where a config update changes the RLS server name. Verifies that the new control channel is created and the old one is closed.
(t *testing.T)
| 58 | // changes the RLS server name. Verifies that the new control channel is created |
| 59 | // and the old one is closed. |
| 60 | func (s) TestConfigUpdate_ControlChannel(t *testing.T) { |
| 61 | // Start two RLS servers. |
| 62 | lis1 := testutils.NewListenerWrapper(t, nil) |
| 63 | rlsServer1, rlsReqCh1 := rlstest.SetupFakeRLSServer(t, lis1) |
| 64 | lis2 := testutils.NewListenerWrapper(t, nil) |
| 65 | rlsServer2, rlsReqCh2 := rlstest.SetupFakeRLSServer(t, lis2) |
| 66 | |
| 67 | // Build RLS service config with the RLS server pointing to the first one. |
| 68 | // Set a very low value for maxAge to ensure that the entry expires soon. |
| 69 | rlsConfig := buildBasicRLSConfigWithChildPolicy(t, t.Name(), rlsServer1.Address) |
| 70 | rlsConfig.RouteLookupConfig.MaxAge = durationpb.New(defaultTestShortTimeout) |
| 71 | |
| 72 | // Start a couple of test backends, and set up the fake RLS servers to return |
| 73 | // these as a target in the RLS response. |
| 74 | backendCh1, backendAddress1 := startBackend(t) |
| 75 | rlsServer1.SetResponseCallback(func(_ context.Context, _ *rlspb.RouteLookupRequest) *rlstest.RouteLookupResponse { |
| 76 | return &rlstest.RouteLookupResponse{Resp: &rlspb.RouteLookupResponse{Targets: []string{backendAddress1}}} |
| 77 | }) |
| 78 | backendCh2, backendAddress2 := startBackend(t) |
| 79 | rlsServer2.SetResponseCallback(func(context.Context, *rlspb.RouteLookupRequest) *rlstest.RouteLookupResponse { |
| 80 | return &rlstest.RouteLookupResponse{Resp: &rlspb.RouteLookupResponse{Targets: []string{backendAddress2}}} |
| 81 | }) |
| 82 | |
| 83 | // Register a manual resolver and push the RLS service config through it. |
| 84 | r := startManualResolverWithConfig(t, rlsConfig) |
| 85 | |
| 86 | cc, err := grpc.NewClient(r.Scheme()+":///", grpc.WithResolvers(r), grpc.WithTransportCredentials(insecure.NewCredentials())) |
| 87 | if err != nil { |
| 88 | t.Fatalf("Failed to create gRPC client: %v", err) |
| 89 | } |
| 90 | defer cc.Close() |
| 91 | |
| 92 | // Make an RPC and ensure it gets routed to the test backend. |
| 93 | ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) |
| 94 | defer cancel() |
| 95 | makeTestRPCAndExpectItToReachBackend(ctx, t, cc, backendCh1) |
| 96 | |
| 97 | // Ensure a connection is established to the first RLS server. |
| 98 | val, err := lis1.NewConnCh.Receive(ctx) |
| 99 | if err != nil { |
| 100 | t.Fatal("Timeout expired when waiting for LB policy to create control channel") |
| 101 | } |
| 102 | conn1 := val.(*testutils.ConnWrapper) |
| 103 | |
| 104 | // Make sure an RLS request is sent out. |
| 105 | verifyRLSRequest(t, rlsReqCh1, true) |
| 106 | |
| 107 | // Change lookup_service field of the RLS config to point to the second one. |
| 108 | rlsConfig.RouteLookupConfig.LookupService = rlsServer2.Address |
| 109 | |
| 110 | // Push the config update through the manual resolver. |
| 111 | scJSON, err := rlsConfig.ServiceConfigJSON() |
| 112 | if err != nil { |
| 113 | t.Fatal(err) |
| 114 | } |
| 115 | sc := internal.ParseServiceConfig.(func(string) *serviceconfig.ParseResult)(scJSON) |
| 116 | r.UpdateState(resolver.State{ServiceConfig: sc}) |
| 117 |
nothing calls this directly
no test coverage detected