Java 类io.grpc.LoadBalancer.Helper 实例源码

项目:grpc-java    文件:ManagedChannelImplTest.java   
@Test
public void loadBalancerThrowsInHandleResolvedAddresses() {
  RuntimeException ex = new RuntimeException("simulated");
  // Delay the success of name resolution until allResolved() is called
  FakeNameResolverFactory nameResolverFactory = new FakeNameResolverFactory(false);
  createChannel(nameResolverFactory, NO_INTERCEPTOR);

  verify(mockLoadBalancerFactory).newLoadBalancer(any(Helper.class));
  doThrow(ex).when(mockLoadBalancer).handleResolvedAddressGroups(
      Matchers.<List<EquivalentAddressGroup>>anyObject(), any(Attributes.class));

  // NameResolver returns addresses.
  nameResolverFactory.allResolved();

  // The LoadBalancer will receive the error that it has thrown.
  verify(mockLoadBalancer).handleNameResolutionError(statusCaptor.capture());
  Status status = statusCaptor.getValue();
  assertSame(Status.Code.INTERNAL, status.getCode());
  assertSame(ex, status.getCause());
}
项目:grpc-java    文件:ManagedChannelImplTest.java   
@Test
public void getState_withRequestConnect() {
  createChannel(
      new FakeNameResolverFactory(false), NO_INTERCEPTOR, false /* requestConnection */,
      ManagedChannelImpl.IDLE_TIMEOUT_MILLIS_DISABLE);

  assertEquals(IDLE, channel.getState(false));
  verify(mockLoadBalancerFactory, never()).newLoadBalancer(any(Helper.class));

  // call getState() with requestConnection = true
  assertEquals(IDLE, channel.getState(true));
  ArgumentCaptor<Helper> helperCaptor = ArgumentCaptor.forClass(null);
  verify(mockLoadBalancerFactory).newLoadBalancer(helperCaptor.capture());
  helper = helperCaptor.getValue();

  helper.updateBalancingState(CONNECTING, mockPicker);
  assertEquals(CONNECTING, channel.getState(false));
  assertEquals(CONNECTING, channel.getState(true));
  verifyNoMoreInteractions(mockLoadBalancerFactory);
}
项目:grpc-java    文件:ManagedChannelImplTest.java   
@Test
public void idleTimeoutAndReconnect() {
  long idleTimeoutMillis = 2000L;
  createChannel(
      new FakeNameResolverFactory(true), NO_INTERCEPTOR, true /* request connection*/,
      idleTimeoutMillis);

  timer.forwardNanos(TimeUnit.MILLISECONDS.toNanos(idleTimeoutMillis));
  assertEquals(IDLE, channel.getState(true /* request connection */));

  ArgumentCaptor<Helper> helperCaptor = ArgumentCaptor.forClass(Helper.class);
  // Two times of requesting connection will create loadBalancer twice.
  verify(mockLoadBalancerFactory, times(2)).newLoadBalancer(helperCaptor.capture());
  Helper helper2 = helperCaptor.getValue();

  // Updating on the old helper (whose balancer has been shutdown) does not change the channel
  // state.
  helper.updateBalancingState(CONNECTING, mockPicker);
  assertEquals(IDLE, channel.getState(false));

  helper2.updateBalancingState(CONNECTING, mockPicker);
  assertEquals(CONNECTING, channel.getState(false));
}
项目:grpc-java    文件:ManagedChannelImplIdlenessTest.java   
@Test
public void updateSubchannelAddresses_newAddressConnects() {
  ClientCall<String, Integer> call = channel.newCall(method, CallOptions.DEFAULT);
  call.start(mockCallListener, new Metadata()); // Create LB
  ArgumentCaptor<Helper> helperCaptor = ArgumentCaptor.forClass(null);
  verify(mockLoadBalancerFactory).newLoadBalancer(helperCaptor.capture());
  Helper helper = helperCaptor.getValue();
  Subchannel subchannel = helper.createSubchannel(servers.get(0), Attributes.EMPTY);

  subchannel.requestConnection();
  MockClientTransportInfo t0 = newTransports.poll();
  t0.listener.transportReady();

  helper.updateSubchannelAddresses(subchannel, servers.get(1));

  subchannel.requestConnection();
  MockClientTransportInfo t1 = newTransports.poll();
  t1.listener.transportReady();
}
项目:grpc-java    文件:ManagedChannelImplIdlenessTest.java   
@Test
public void updateSubchannelAddresses_existingAddressDoesNotConnect() {
  ClientCall<String, Integer> call = channel.newCall(method, CallOptions.DEFAULT);
  call.start(mockCallListener, new Metadata()); // Create LB
  ArgumentCaptor<Helper> helperCaptor = ArgumentCaptor.forClass(null);
  verify(mockLoadBalancerFactory).newLoadBalancer(helperCaptor.capture());
  Helper helper = helperCaptor.getValue();
  Subchannel subchannel = helper.createSubchannel(servers.get(0), Attributes.EMPTY);

  subchannel.requestConnection();
  MockClientTransportInfo t0 = newTransports.poll();
  t0.listener.transportReady();

  List<SocketAddress> changedList = new ArrayList<SocketAddress>(servers.get(0).getAddresses());
  changedList.add(new FakeSocketAddress("aDifferentServer"));
  helper.updateSubchannelAddresses(subchannel, new EquivalentAddressGroup(changedList));

  subchannel.requestConnection();
  assertNull(newTransports.poll());
}
项目:grpc-java    文件:ManagedChannelImplIdlenessTest.java   
@Test
public void updateOobChannelAddresses_newAddressConnects() {
  ClientCall<String, Integer> call = channel.newCall(method, CallOptions.DEFAULT);
  call.start(mockCallListener, new Metadata()); // Create LB
  ArgumentCaptor<Helper> helperCaptor = ArgumentCaptor.forClass(null);
  verify(mockLoadBalancerFactory).newLoadBalancer(helperCaptor.capture());
  Helper helper = helperCaptor.getValue();
  ManagedChannel oobChannel = helper.createOobChannel(servers.get(0), "localhost");

  oobChannel.newCall(method, CallOptions.DEFAULT).start(mockCallListener, new Metadata());
  MockClientTransportInfo t0 = newTransports.poll();
  t0.listener.transportReady();

  helper.updateOobChannelAddresses(oobChannel, servers.get(1));

  oobChannel.newCall(method, CallOptions.DEFAULT).start(mockCallListener, new Metadata());
  MockClientTransportInfo t1 = newTransports.poll();
  t1.listener.transportReady();
}
项目:grpc-java    文件:ManagedChannelImplIdlenessTest.java   
@Test
public void updateOobChannelAddresses_existingAddressDoesNotConnect() {
  ClientCall<String, Integer> call = channel.newCall(method, CallOptions.DEFAULT);
  call.start(mockCallListener, new Metadata()); // Create LB
  ArgumentCaptor<Helper> helperCaptor = ArgumentCaptor.forClass(null);
  verify(mockLoadBalancerFactory).newLoadBalancer(helperCaptor.capture());
  Helper helper = helperCaptor.getValue();
  ManagedChannel oobChannel = helper.createOobChannel(servers.get(0), "localhost");

  oobChannel.newCall(method, CallOptions.DEFAULT).start(mockCallListener, new Metadata());
  MockClientTransportInfo t0 = newTransports.poll();
  t0.listener.transportReady();

  List<SocketAddress> changedList = new ArrayList<SocketAddress>(servers.get(0).getAddresses());
  changedList.add(new FakeSocketAddress("aDifferentServer"));
  helper.updateOobChannelAddresses(oobChannel, new EquivalentAddressGroup(changedList));

  oobChannel.newCall(method, CallOptions.DEFAULT).start(mockCallListener, new Metadata());
  assertNull(newTransports.poll());
}
项目:grpc-java    文件:GrpclbState.java   
GrpclbState(
    Helper helper,
    TimeProvider time,
    ScheduledExecutorService timerService,
    LogId logId) {
  this.helper = checkNotNull(helper, "helper");
  this.time = checkNotNull(time, "time provider");
  this.timerService = checkNotNull(timerService, "timerService");
  this.serviceName = checkNotNull(helper.getAuthority(), "helper returns null authority");
  this.logId = checkNotNull(logId, "logId");
}
项目:grpc-java    文件:GrpclbLoadBalancerTest.java   
private List<Subchannel> fallbackTestVerifyUseOfBalancerBackendLists(
    InOrder inOrder, Helper helper, List<ServerEntry> servers) {
  ArrayList<EquivalentAddressGroup> addrs = new ArrayList<EquivalentAddressGroup>();
  ArrayList<String> tokens = new ArrayList<String>();
  for (ServerEntry server : servers) {
    addrs.add(new EquivalentAddressGroup(server.addr));
    tokens.add(server.token);
  }
  return fallbackTestVerifyUseOfBackendLists(inOrder, helper, addrs, tokens);
}
项目:grpc-java    文件:ManagedChannelImplTest.java   
@Before
public void setUp() throws Exception {
  MockitoAnnotations.initMocks(this);
  expectedUri = new URI(target);
  when(mockLoadBalancerFactory.newLoadBalancer(any(Helper.class))).thenReturn(mockLoadBalancer);
  transports = TestUtils.captureTransports(mockTransportFactory);
  when(mockTransportFactory.getScheduledExecutorService())
      .thenReturn(timer.getScheduledExecutorService());
  when(executorPool.getObject()).thenReturn(executor.getScheduledExecutorService());
  when(oobExecutorPool.getObject()).thenReturn(oobExecutor.getScheduledExecutorService());
}
项目:grpc-java    文件:ManagedChannelImplTest.java   
@Test
public void nameResolverReturnsEmptySubLists() {
  String errorDescription = "NameResolver returned an empty list";

  // Pass a FakeNameResolverFactory with an empty list
  createChannel(new FakeNameResolverFactory(), NO_INTERCEPTOR);

  // LoadBalancer received the error
  verify(mockLoadBalancerFactory).newLoadBalancer(any(Helper.class));
  verify(mockLoadBalancer).handleNameResolutionError(statusCaptor.capture());
  Status status = statusCaptor.getValue();
  assertSame(Status.Code.UNAVAILABLE, status.getCode());
  assertEquals(errorDescription, status.getDescription());
}
项目:grpc-java    文件:ManagedChannelImplTest.java   
@Test
public void channelsAndSubchannels_instrumented_state() throws Exception {
  createChannel(new FakeNameResolverFactory(true), NO_INTERCEPTOR);

  ArgumentCaptor<Helper> helperCaptor = ArgumentCaptor.forClass(null);
  verify(mockLoadBalancerFactory).newLoadBalancer(helperCaptor.capture());
  helper = helperCaptor.getValue();

  assertEquals(IDLE, getStats(channel).state);
  helper.updateBalancingState(CONNECTING, mockPicker);
  assertEquals(CONNECTING, getStats(channel).state);

  AbstractSubchannel subchannel =
      (AbstractSubchannel) helper.createSubchannel(addressGroup, Attributes.EMPTY);

  assertEquals(IDLE, getStats(subchannel).state);
  subchannel.requestConnection();
  assertEquals(CONNECTING, getStats(subchannel).state);

  MockClientTransportInfo transportInfo = transports.poll();

  assertEquals(CONNECTING, getStats(subchannel).state);
  transportInfo.listener.transportReady();
  assertEquals(READY, getStats(subchannel).state);

  assertEquals(CONNECTING, getStats(channel).state);
  helper.updateBalancingState(READY, mockPicker);
  assertEquals(READY, getStats(channel).state);

  channel.shutdownNow();
  assertEquals(SHUTDOWN, getStats(channel).state);
  assertEquals(SHUTDOWN, getStats(subchannel).state);
}
项目:grpc-java    文件:ManagedChannelImplIdlenessTest.java   
@Test
public void newCallExitsIdleness() throws Exception {
  ClientCall<String, Integer> call = channel.newCall(method, CallOptions.DEFAULT);
  call.start(mockCallListener, new Metadata());

  verify(mockLoadBalancerFactory).newLoadBalancer(any(Helper.class));

  verify(mockNameResolver).start(nameResolverListenerCaptor.capture());
  // Simulate new address resolved to make sure the LoadBalancer is correctly linked to
  // the NameResolver.
  nameResolverListenerCaptor.getValue().onAddresses(servers, Attributes.EMPTY);
  verify(mockLoadBalancer).handleResolvedAddressGroups(servers, Attributes.EMPTY);
}
项目:grpc-java    文件:ManagedChannelImplIdlenessTest.java   
@Test
public void newCallRefreshesIdlenessTimer() throws Exception {
  // First call to exit the initial idleness, then immediately cancel the call.
  ClientCall<String, Integer> call = channel.newCall(method, CallOptions.DEFAULT);
  call.start(mockCallListener, new Metadata());
  call.cancel("For testing", null);

  // Verify that we have exited the idle mode
  verify(mockLoadBalancerFactory).newLoadBalancer(any(Helper.class));
  assertFalse(channel.inUseStateAggregator.isInUse());

  // Move closer to idleness, but not yet.
  timer.forwardTime(IDLE_TIMEOUT_SECONDS - 1, TimeUnit.SECONDS);
  verify(mockLoadBalancer, never()).shutdown();
  assertFalse(channel.inUseStateAggregator.isInUse());

  // A new call would refresh the timer
  call = channel.newCall(method, CallOptions.DEFAULT);
  call.start(mockCallListener, new Metadata());
  call.cancel("For testing", null);
  assertFalse(channel.inUseStateAggregator.isInUse());

  // ... so that passing the same length of time will not trigger idle mode
  timer.forwardTime(IDLE_TIMEOUT_SECONDS - 1, TimeUnit.SECONDS);
  verify(mockLoadBalancer, never()).shutdown();
  assertFalse(channel.inUseStateAggregator.isInUse());

  // ... until the time since last call has reached the timeout
  timer.forwardTime(1, TimeUnit.SECONDS);
  verify(mockLoadBalancer).shutdown();
  assertFalse(channel.inUseStateAggregator.isInUse());

  // Drain the app executor, which runs the call listeners
  verify(mockCallListener, never()).onClose(any(Status.class), any(Metadata.class));
  assertEquals(2, executor.runDueTasks());
  verify(mockCallListener, times(2)).onClose(any(Status.class), any(Metadata.class));
}
项目:saluki    文件:GrpcRouteRoundRobinLbFactory.java   
@Override
public LoadBalancer newLoadBalancer(Helper helper) {
  return new GrpcRoundRobinLoadBalancer(helper);
}
项目:saluki    文件:GrpcRouteRoundRobinLbFactory.java   
GrpcRoundRobinLoadBalancer(Helper helper) {
  this.helper = checkNotNull(helper, "helper");
}
项目:grpc-java    文件:GrpclbLoadBalancerTest.java   
private List<Subchannel> fallbackTestVerifyUseOfFallbackBackendLists(
    InOrder inOrder, Helper helper, List<EquivalentAddressGroup> addrs) {
  return fallbackTestVerifyUseOfBackendLists(inOrder, helper, addrs, null);
}
项目:grpc-java    文件:ManagedChannelImplTest.java   
private void createChannel(
    NameResolver.Factory nameResolverFactory, List<ClientInterceptor> interceptors,
    boolean requestConnection, long idleTimeoutMillis) {
  class Builder extends AbstractManagedChannelImplBuilder<Builder> {
    Builder(String target) {
      super(target);
    }

    @Override protected ClientTransportFactory buildTransportFactory() {
      throw new UnsupportedOperationException();
    }

    @Override protected Attributes getNameResolverParams() {
      return NAME_RESOLVER_PARAMS;
    }

    @Override public Builder usePlaintext(boolean b) {
      throw new UnsupportedOperationException();
    }
  }

  Builder builder = new Builder(target)
      .nameResolverFactory(nameResolverFactory)
      .loadBalancerFactory(mockLoadBalancerFactory)
      .userAgent(userAgent);
  builder.executorPool = executorPool;
  builder.idleTimeoutMillis = idleTimeoutMillis;
  builder.binlogProvider = binlogProvider;
  checkState(channel == null);
  channel = new ManagedChannelImpl(
      builder, mockTransportFactory, new FakeBackoffPolicyProvider(),
      oobExecutorPool, timer.getStopwatchSupplier(), interceptors, GrpcUtil.NOOP_PROXY_DETECTOR,
      channelStatsFactory);

  if (requestConnection) {
    // Force-exit the initial idle-mode
    channel.exitIdleMode();
    assertEquals(
        idleTimeoutMillis == ManagedChannelImpl.IDLE_TIMEOUT_MILLIS_DISABLE ? 0 : 1,
        timer.numPendingTasks());

    ArgumentCaptor<Helper> helperCaptor = ArgumentCaptor.forClass(null);
    verify(mockLoadBalancerFactory).newLoadBalancer(helperCaptor.capture());
    helper = helperCaptor.getValue();
  }
}
项目:grpc-java    文件:ManagedChannelImplTest.java   
@Test
public void noMoreCallbackAfterLoadBalancerShutdown() {
  FakeNameResolverFactory nameResolverFactory = new FakeNameResolverFactory(true);
  Status resolutionError = Status.UNAVAILABLE.withDescription("Resolution failed");
  createChannel(nameResolverFactory, NO_INTERCEPTOR);

  FakeNameResolverFactory.FakeNameResolver resolver = nameResolverFactory.resolvers.get(0);
  verify(mockLoadBalancerFactory).newLoadBalancer(any(Helper.class));
  verify(mockLoadBalancer).handleResolvedAddressGroups(
      eq(Arrays.asList(addressGroup)), eq(Attributes.EMPTY));

  Subchannel subchannel1 = helper.createSubchannel(addressGroup, Attributes.EMPTY);
  Subchannel subchannel2 = helper.createSubchannel(addressGroup, Attributes.EMPTY);
  subchannel1.requestConnection();
  subchannel2.requestConnection();
  verify(mockTransportFactory, times(2)).newClientTransport(
      any(SocketAddress.class), any(String.class), any(String.class), any(ProxyParameters.class));
  MockClientTransportInfo transportInfo1 = transports.poll();
  MockClientTransportInfo transportInfo2 = transports.poll();

  // LoadBalancer receives all sorts of callbacks
  transportInfo1.listener.transportReady();
  verify(mockLoadBalancer, times(2))
      .handleSubchannelState(same(subchannel1), stateInfoCaptor.capture());
  assertSame(CONNECTING, stateInfoCaptor.getAllValues().get(0).getState());
  assertSame(READY, stateInfoCaptor.getAllValues().get(1).getState());

  verify(mockLoadBalancer)
      .handleSubchannelState(same(subchannel2), stateInfoCaptor.capture());
  assertSame(CONNECTING, stateInfoCaptor.getValue().getState());

  resolver.listener.onError(resolutionError);
  verify(mockLoadBalancer).handleNameResolutionError(resolutionError);

  verifyNoMoreInteractions(mockLoadBalancer);

  channel.shutdown();
  verify(mockLoadBalancer).shutdown();

  // No more callback should be delivered to LoadBalancer after it's shut down
  transportInfo2.listener.transportReady();
  resolver.listener.onError(resolutionError);
  resolver.resolved();
  verifyNoMoreInteractions(mockLoadBalancer);
}
项目:grpc-java    文件:ManagedChannelImplIdlenessTest.java   
@Before
public void setUp() {
  MockitoAnnotations.initMocks(this);
  when(mockLoadBalancerFactory.newLoadBalancer(any(Helper.class))).thenReturn(mockLoadBalancer);
  when(mockNameResolver.getServiceAuthority()).thenReturn(AUTHORITY);
  when(mockNameResolverFactory
      .newNameResolver(any(URI.class), any(Attributes.class)))
      .thenReturn(mockNameResolver);
  when(mockTransportFactory.getScheduledExecutorService())
      .thenReturn(timer.getScheduledExecutorService());

  class Builder extends AbstractManagedChannelImplBuilder<Builder> {
    Builder(String target) {
      super(target);
    }

    @Override protected ClientTransportFactory buildTransportFactory() {
      throw new UnsupportedOperationException();
    }

    @Override public Builder usePlaintext(boolean b) {
      throw new UnsupportedOperationException();
    }
  }

  Builder builder = new Builder("fake://target")
      .nameResolverFactory(mockNameResolverFactory)
      .loadBalancerFactory(mockLoadBalancerFactory)
      .idleTimeout(IDLE_TIMEOUT_SECONDS, TimeUnit.SECONDS)
      .userAgent(USER_AGENT);
  builder.executorPool = executorPool;
  channel = new ManagedChannelImpl(
      builder, mockTransportFactory, new FakeBackoffPolicyProvider(),
      oobExecutorPool, timer.getStopwatchSupplier(),
      Collections.<ClientInterceptor>emptyList(),
      GrpcUtil.NOOP_PROXY_DETECTOR, CallTracer.getDefaultFactory());
  newTransports = TestUtils.captureTransports(mockTransportFactory);

  for (int i = 0; i < 2; i++) {
    ArrayList<SocketAddress> addrs = Lists.newArrayList();
    for (int j = 0; j < 2; j++) {
      addrs.add(new FakeSocketAddress("servergroup" + i + "server" + j));
    }
    servers.add(new EquivalentAddressGroup(addrs));
  }
  verify(mockNameResolverFactory).newNameResolver(any(URI.class), any(Attributes.class));
  // Verify the initial idleness
  verify(mockLoadBalancerFactory, never()).newLoadBalancer(any(Helper.class));
  verify(mockTransportFactory, never()).newClientTransport(
      any(SocketAddress.class), anyString(), anyString(), any(ProxyParameters.class));
  verify(mockNameResolver, never()).start(any(NameResolver.Listener.class));
}
项目:grpc-java    文件:ManagedChannelImplIdlenessTest.java   
@Test
public void realTransportsHoldsOffIdleness() throws Exception {
  final EquivalentAddressGroup addressGroup = servers.get(1);

  // Start a call, which goes to delayed transport
  ClientCall<String, Integer> call = channel.newCall(method, CallOptions.DEFAULT);
  call.start(mockCallListener, new Metadata());

  // Verify that we have exited the idle mode
  ArgumentCaptor<Helper> helperCaptor = ArgumentCaptor.forClass(null);
  verify(mockLoadBalancerFactory).newLoadBalancer(helperCaptor.capture());
  Helper helper = helperCaptor.getValue();
  assertTrue(channel.inUseStateAggregator.isInUse());

  // Assume LoadBalancer has received an address, then create a subchannel.
  Subchannel subchannel = helper.createSubchannel(addressGroup, Attributes.EMPTY);
  subchannel.requestConnection();
  MockClientTransportInfo t0 = newTransports.poll();
  t0.listener.transportReady();

  SubchannelPicker mockPicker = mock(SubchannelPicker.class);
  when(mockPicker.pickSubchannel(any(PickSubchannelArgs.class)))
      .thenReturn(PickResult.withSubchannel(subchannel));
  helper.updateBalancingState(READY, mockPicker);
  // Delayed transport creates real streams in the app executor
  executor.runDueTasks();

  // Delayed transport exits in-use, while real transport has not entered in-use yet.
  assertFalse(channel.inUseStateAggregator.isInUse());

  // Now it's in-use
  t0.listener.transportInUse(true);
  assertTrue(channel.inUseStateAggregator.isInUse());

  // As long as the transport is in-use, the channel won't go idle.
  timer.forwardTime(IDLE_TIMEOUT_SECONDS * 2, TimeUnit.SECONDS);
  assertTrue(channel.inUseStateAggregator.isInUse());

  t0.listener.transportInUse(false);
  assertFalse(channel.inUseStateAggregator.isInUse());
  // And allow the channel to go idle.
  timer.forwardTime(IDLE_TIMEOUT_SECONDS - 1, TimeUnit.SECONDS);
  verify(mockLoadBalancer, never()).shutdown();
  timer.forwardTime(1, TimeUnit.SECONDS);
  verify(mockLoadBalancer).shutdown();
}
项目:grpc-java    文件:ManagedChannelImplIdlenessTest.java   
@Test
public void oobTransportDoesNotAffectIdleness() {
  // Start a call, which goes to delayed transport
  ClientCall<String, Integer> call = channel.newCall(method, CallOptions.DEFAULT);
  call.start(mockCallListener, new Metadata());

  // Verify that we have exited the idle mode
  ArgumentCaptor<Helper> helperCaptor = ArgumentCaptor.forClass(null);
  verify(mockLoadBalancerFactory).newLoadBalancer(helperCaptor.capture());
  Helper helper = helperCaptor.getValue();

  // Fail the RPC
  SubchannelPicker failingPicker = mock(SubchannelPicker.class);
  when(failingPicker.pickSubchannel(any(PickSubchannelArgs.class)))
      .thenReturn(PickResult.withError(Status.UNAVAILABLE));
  helper.updateBalancingState(TRANSIENT_FAILURE, failingPicker);
  executor.runDueTasks();
  verify(mockCallListener).onClose(same(Status.UNAVAILABLE), any(Metadata.class));

  // ... so that the channel resets its in-use state
  assertFalse(channel.inUseStateAggregator.isInUse());

  // Now make an RPC on an OOB channel
  ManagedChannel oob = helper.createOobChannel(servers.get(0), "oobauthority");
  verify(mockTransportFactory, never())
      .newClientTransport(any(SocketAddress.class), same("oobauthority"), same(USER_AGENT),
          same(NO_PROXY));
  ClientCall<String, Integer> oobCall = oob.newCall(method, CallOptions.DEFAULT);
  oobCall.start(mockCallListener2, new Metadata());
  verify(mockTransportFactory)
      .newClientTransport(any(SocketAddress.class), same("oobauthority"), same(USER_AGENT),
          same(NO_PROXY));
  MockClientTransportInfo oobTransportInfo = newTransports.poll();
  assertEquals(0, newTransports.size());
  // The OOB transport reports in-use state
  oobTransportInfo.listener.transportInUse(true);

  // But it won't stop the channel from going idle
  verify(mockLoadBalancer, never()).shutdown();
  timer.forwardTime(IDLE_TIMEOUT_SECONDS, TimeUnit.SECONDS);
  verify(mockLoadBalancer).shutdown();
}