Tests the case where channel idleness is enabled by passing a small value for idle_timeout. Verifies that a READY channel with no RPCs moves to IDLE. Also verifies that a subsequent RPC on the IDLE channel kicks it out of IDLE.
(t *testing.T)
| 404 | // idle_timeout. Verifies that a READY channel with no RPCs moves to IDLE. Also |
| 405 | // verifies that a subsequent RPC on the IDLE channel kicks it out of IDLE. |
| 406 | func (s) TestChannelIdleness_Enabled_ExitIdleOnRPC(t *testing.T) { |
| 407 | closeCh := registerWrappedRoundRobinPolicy(t) |
| 408 | |
| 409 | // Start a test backend and set the bootstrap state of the resolver to |
| 410 | // include this address. This will ensure that when the resolver is |
| 411 | // restarted when exiting idle, it will push the same address to grpc again. |
| 412 | r := manual.NewBuilderWithScheme("whatever") |
| 413 | backend := stubserver.StartTestService(t, nil) |
| 414 | defer backend.Stop() |
| 415 | r.InitialState(resolver.State{Addresses: []resolver.Address{{Addr: backend.Address}}}) |
| 416 | |
| 417 | // Create a ClientConn with a short idle_timeout. |
| 418 | dopts := []grpc.DialOption{ |
| 419 | grpc.WithTransportCredentials(insecure.NewCredentials()), |
| 420 | grpc.WithResolvers(r), |
| 421 | grpc.WithIdleTimeout(defaultTestShortIdleTimeout), |
| 422 | grpc.WithDefaultServiceConfig(`{"loadBalancingConfig": [{"round_robin":{}}]}`), |
| 423 | } |
| 424 | cc, err := grpc.NewClient(r.Scheme()+":///test.server", dopts...) |
| 425 | if err != nil { |
| 426 | t.Fatalf("grpc.NewClient() failed: %v", err) |
| 427 | } |
| 428 | defer cc.Close() |
| 429 | cc.Connect() |
| 430 | // Verify that the ClientConn moves to READY. |
| 431 | ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) |
| 432 | defer cancel() |
| 433 | testutils.AwaitState(ctx, t, cc, connectivity.Ready) |
| 434 | |
| 435 | // Verify that the ClientConn moves to IDLE as there is no activity. |
| 436 | testutils.AwaitState(ctx, t, cc, connectivity.Idle) |
| 437 | |
| 438 | // Verify idleness related channelz events. |
| 439 | if err := channelzTraceEventFound(ctx, "entering idle mode"); err != nil { |
| 440 | t.Fatal(err) |
| 441 | } |
| 442 | |
| 443 | // Verify that the LB policy is closed. |
| 444 | select { |
| 445 | case <-ctx.Done(): |
| 446 | t.Fatal("Timeout waiting for LB policy to be closed after the channel enters IDLE") |
| 447 | case <-closeCh: |
| 448 | } |
| 449 | |
| 450 | // Make an RPC and ensure that it succeeds and moves the channel back to |
| 451 | // READY. |
| 452 | client := testgrpc.NewTestServiceClient(cc) |
| 453 | if _, err := client.EmptyCall(ctx, &testpb.Empty{}); err != nil { |
| 454 | t.Fatalf("EmptyCall RPC failed: %v", err) |
| 455 | } |
| 456 | testutils.AwaitState(ctx, t, cc, connectivity.Ready) |
| 457 | if err := channelzTraceEventFound(ctx, "exiting idle mode"); err != nil { |
| 458 | t.Fatal(err) |
| 459 | } |
| 460 | } |
| 461 | |
| 462 | // Tests the case where channel idleness is enabled by passing a small value for |
| 463 | // idle_timeout. Simulates a race between the idle timer firing and RPCs being |
nothing calls this directly
no test coverage detected