### Question:
NettyClientHandler extends AbstractNettyHandler { @Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { try { logger.fine("Network channel is closed"); Status status = Status.UNAVAILABLE.withDescription("Network closed for unknown reason"); lifecycleManager.notifyShutdown(status); try { cancelPing(lifecycleManager.getShutdownThrowable()); connection().forEachActiveStream(new Http2StreamVisitor() { @Override public boolean visit(Http2Stream stream) throws Http2Exception { NettyClientStream.TransportState clientStream = clientStream(stream); if (clientStream != null) { clientStream.transportReportStatus( lifecycleManager.getShutdownStatus(), false, new Metadata()); } return true; } }); } finally { lifecycleManager.notifyTerminated(status); } } finally { super.channelInactive(ctx); if (keepAliveManager != null) { keepAliveManager.onTransportTermination(); } } } private  NettyClientHandler(
      Http2ConnectionDecoder decoder,
      StreamBufferingEncoder encoder,
      Http2Settings settings,
      ClientTransportLifecycleManager lifecycleManager,
      KeepAliveManager keepAliveManager,
      Supplier<Stopwatch> stopwatchFactory,
      final Runnable tooManyPingsRunnable,
      TransportTracer transportTracer,
      Attributes eagAttributes,
      String authority); @Override void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise); @Override void close(ChannelHandlerContext ctx, ChannelPromise promise); @Override void channelInactive(ChannelHandlerContext ctx); @Override void handleProtocolNegotiationCompleted(
      Attributes attributes, InternalChannelz.Security securityInfo); @Override Attributes getEagAttributes(); @Override String getAuthority();  }### Answer:
@Test public void channelShutdownShouldCancelBufferedStreams() throws Exception { receiveMaxConcurrentStreams(0); ChannelFuture future = enqueue(newCreateStreamCommand(grpcHeaders, streamTransportState)); handler().channelInactive(ctx()); assertTrue(future.isDone()); assertFalse(future.isSuccess()); verify(mockKeepAliveManager, times(1)).onTransportTermination(); verifyNoMoreInteractions(mockKeepAliveManager); }
@Test public void ping_failsWhenChannelCloses() throws Exception { PingCallbackImpl callback = new PingCallbackImpl(); sendPing(callback); assertEquals(0, callback.invocationCount); handler().channelInactive(ctx()); assertEquals(1, callback.invocationCount); assertTrue(callback.failureCause instanceof StatusException); assertEquals(Status.Code.UNAVAILABLE, ((StatusException) callback.failureCause).getStatus().getCode()); assertEquals(1, transportTracer.getStats().keepAlivesSent); }