### Question:
SslHandler extends ByteToMessageDecoder implements ChannelOutboundHandler { @Deprecated public ChannelFuture close() { return closeOutbound(); } SslHandler(SSLEngine engine); @SuppressWarnings("deprecation")  SslHandler(SSLEngine engine, boolean startTls); @Deprecated  SslHandler(SSLEngine engine, Executor delegatedTaskExecutor); @Deprecated  SslHandler(SSLEngine engine, boolean startTls, Executor delegatedTaskExecutor); long getHandshakeTimeoutMillis(); void setHandshakeTimeout(long handshakeTimeout, TimeUnit unit); void setHandshakeTimeoutMillis(long handshakeTimeoutMillis); @UnstableApi final void setWrapDataSize(int wrapDataSize); @Deprecated long getCloseNotifyTimeoutMillis(); @Deprecated void setCloseNotifyTimeout(long closeNotifyTimeout, TimeUnit unit); @Deprecated void setCloseNotifyTimeoutMillis(long closeNotifyFlushTimeoutMillis); final long getCloseNotifyFlushTimeoutMillis(); final void setCloseNotifyFlushTimeout(long closeNotifyFlushTimeout, TimeUnit unit); final void setCloseNotifyFlushTimeoutMillis(long closeNotifyFlushTimeoutMillis); final long getCloseNotifyReadTimeoutMillis(); final void setCloseNotifyReadTimeout(long closeNotifyReadTimeout, TimeUnit unit); final void setCloseNotifyReadTimeoutMillis(long closeNotifyReadTimeoutMillis); SSLEngine engine(); String applicationProtocol(); Future<Channel> handshakeFuture(); @Deprecated ChannelFuture close(); @Deprecated ChannelFuture close(ChannelPromise promise); ChannelFuture closeOutbound(); ChannelFuture closeOutbound(final ChannelPromise promise); Future<Channel> sslCloseFuture(); @Override void handlerRemoved0(ChannelHandlerContext ctx); @Override void bind(ChannelHandlerContext ctx, SocketAddress localAddress, ChannelPromise promise); @Override void connect(ChannelHandlerContext ctx, SocketAddress remoteAddress, SocketAddress localAddress,
                        ChannelPromise promise); @Override void deregister(ChannelHandlerContext ctx, ChannelPromise promise); @Override void disconnect(final ChannelHandlerContext ctx,
                           final ChannelPromise promise); @Override void close(final ChannelHandlerContext ctx,
                      final ChannelPromise promise); @Override void read(ChannelHandlerContext ctx); @Override void write(final ChannelHandlerContext ctx, Object msg, ChannelPromise promise); @Override void flush(ChannelHandlerContext ctx); @Override void channelInactive(ChannelHandlerContext ctx); @Override void exceptionCaught(ChannelHandlerContext ctx, Throwable cause); static boolean isEncrypted(ByteBuf buffer); @Override void channelReadComplete(ChannelHandlerContext ctx); @Override void handlerAdded(final ChannelHandlerContext ctx); Future<Channel> renegotiate(); Future<Channel> renegotiate(final Promise<Channel> promise); @Override void channelActive(final ChannelHandlerContext ctx);  }### Answer:
@Test public void testReleaseSslEngine() throws Exception { assumeTrue(OpenSsl.isAvailable()); SelfSignedCertificate cert = new SelfSignedCertificate(); try { SslContext sslContext = SslContextBuilder.forServer(cert.certificate(), cert.privateKey()) .sslProvider(SslProvider.OPENSSL) .build(); try { SSLEngine sslEngine = sslContext.newEngine(ByteBufAllocator.DEFAULT); EmbeddedChannel ch = new EmbeddedChannel(new SslHandler(sslEngine)); assertEquals(1, ((ReferenceCounted) sslContext).refCnt()); assertEquals(1, ((ReferenceCounted) sslEngine).refCnt()); assertTrue(ch.finishAndReleaseAll()); ch.close().syncUninterruptibly(); assertEquals(1, ((ReferenceCounted) sslContext).refCnt()); assertEquals(0, ((ReferenceCounted) sslEngine).refCnt()); } finally { ReferenceCountUtil.release(sslContext); } } finally { cert.delete(); } }
@Test public void testOutboundClosedAfterChannelInactive() throws Exception { SslContext context = SslContextBuilder.forClient().build(); SSLEngine engine = context.newEngine(UnpooledByteBufAllocator.DEFAULT); EmbeddedChannel channel = new EmbeddedChannel(); assertFalse(channel.finish()); channel.pipeline().addLast(new SslHandler(engine)); assertFalse(engine.isOutboundDone()); channel.close().syncUninterruptibly(); assertTrue(engine.isOutboundDone()); }