@AdviseWith(adviceClasses = {PropsUtilAdvice.class})
  @Test
  public void testPrepareRequest() throws Exception {
    PropsUtilAdvice.setProps(
        PropsKeys.INTRABAND_MAILBOX_REAPER_THREAD_ENABLED, Boolean.FALSE.toString());
    PropsUtilAdvice.setProps(
        PropsKeys.INTRABAND_MAILBOX_STORAGE_LIFE, String.valueOf(Long.MAX_VALUE));

    Serializer serializer = new Serializer();

    serializer.writeString(_SERVLET_CONTEXT_NAME);
    serializer.writeObject(new SPIAgentRequest(_mockHttpServletRequest));

    Method depositMailMethod =
        ReflectionUtil.getDeclaredMethod(MailboxUtil.class, "depositMail", ByteBuffer.class);

    long receipt = (Long) depositMailMethod.invoke(null, serializer.toByteBuffer());

    byte[] data = new byte[8];

    BigEndianCodec.putLong(data, 0, receipt);

    HttpClientSPIAgent httpClientSPIAgent =
        new HttpClientSPIAgent(
            _spiConfiguration, new MockRegistrationReference(new MockIntraband()));

    MockHttpServletRequest mockHttpServletRequest = new MockHttpServletRequest();

    mockHttpServletRequest.setContent(data);

    HttpServletRequest httpServletRequest =
        httpClientSPIAgent.prepareRequest(mockHttpServletRequest);

    Assert.assertNotNull(httpServletRequest.getAttribute(WebKeys.SPI_AGENT_REQUEST));
  }
  @Test
  public void testPrepareResponse() throws UnknownHostException {
    HttpClientSPIAgent httpClientSPIAgent =
        new HttpClientSPIAgent(
            _spiConfiguration, new MockRegistrationReference(new MockIntraband()));

    MockHttpServletRequest mockHttpServletRequest = new MockHttpServletRequest();

    mockHttpServletRequest.setAttribute(WebKeys.SPI_AGENT_PORTLET, _portlet);

    MockHttpServletResponse mockHttpServletResponse = new MockHttpServletResponse();

    HttpServletResponse httpServletResponse =
        httpClientSPIAgent.prepareResponse(mockHttpServletRequest, mockHttpServletResponse);

    Assert.assertSame(
        mockHttpServletResponse,
        mockHttpServletRequest.getAttribute(WebKeys.SPI_AGENT_ORIGINAL_RESPONSE));
    Assert.assertNotNull(mockHttpServletRequest.getAttribute(WebKeys.SPI_AGENT_RESPONSE));

    Assert.assertSame(BufferCacheServletResponse.class, httpServletResponse.getClass());

    BufferCacheServletResponse bufferCacheServletResponse =
        (BufferCacheServletResponse) httpServletResponse;

    ServletResponse servletResponse = bufferCacheServletResponse.getResponse();

    Assert.assertSame(ReadOnlyServletResponse.class, servletResponse.getClass());

    ReadOnlyServletResponse readOnlyServletResponse = (ReadOnlyServletResponse) servletResponse;

    Assert.assertSame(mockHttpServletResponse, readOnlyServletResponse.getResponse());
  }
  @Test
  public void testInit() throws Exception {
    HttpClientSPIAgent httpClientSPIAgent =
        new HttpClientSPIAgent(
            _spiConfiguration, new MockRegistrationReference(new MockIntraband()));

    final AtomicBoolean throwException = new AtomicBoolean();

    SPI spi =
        new MockSPI() {

          @Override
          public void addServlet(
              String contextPath,
              String docBasePath,
              String mappingPattern,
              String servletClassName) {

            if (throwException.get()) {
              throw new RuntimeException();
            }

            Assert.assertEquals(HttpClientSPIAgent.SPI_AGENT_CONTEXT_PATH, contextPath);
            Assert.assertEquals(_spiConfiguration.getBaseDir(), docBasePath);
            Assert.assertEquals(HttpClientSPIAgent.MAPPING_PATTERN, mappingPattern);
            Assert.assertEquals(AcceptorServlet.class.getName(), servletClassName);
          }

          @Override
          public SPIConfiguration getSPIConfiguration() {
            return _spiConfiguration;
          }
        };

    httpClientSPIAgent.init(spi);

    throwException.set(true);

    try {
      httpClientSPIAgent.init(spi);

      Assert.fail();
    } catch (PortalResiliencyException pre) {
      Throwable throwable = pre.getCause();

      Assert.assertSame(RuntimeException.class, throwable.getClass());
    }
  }
  @Test
  public void testConsumeHttpResponseHead() throws Exception {

    // Wrong status line

    HttpClientSPIAgent httpClientSPIAgent =
        new HttpClientSPIAgent(
            _spiConfiguration, new MockRegistrationReference(new MockIntraband()));

    String wrongStatusLine = "Wrong status line";

    try {
      httpClientSPIAgent.consumeHttpResponseHead(
          new DataInputStream(
              new UnsyncByteArrayInputStream(wrongStatusLine.getBytes("US-ASCII"))));

      Assert.fail();
    } catch (IOException ioe) {
      Assert.assertEquals("Error status line: " + wrongStatusLine, ioe.getMessage());
    }

    // Wrong ending

    String responseContentWrongEnding = "HTTP/1.1 200 OK\n";

    Assert.assertFalse(
        httpClientSPIAgent.consumeHttpResponseHead(
            new DataInputStream(
                new UnsyncByteArrayInputStream(responseContentWrongEnding.getBytes("US-ASCII")))));

    // Keep alive

    String responseContentKeepAlive = "HTTP/1.1 200 OK\n\n";

    Assert.assertFalse(
        httpClientSPIAgent.consumeHttpResponseHead(
            new DataInputStream(
                new UnsyncByteArrayInputStream(responseContentKeepAlive.getBytes("US-ASCII")))));

    // Wrong close

    String responseContentWrongClose = "HTTP/1.1 200 OK\nconnection:wrong\n\n";

    Assert.assertFalse(
        httpClientSPIAgent.consumeHttpResponseHead(
            new DataInputStream(
                new UnsyncByteArrayInputStream(responseContentWrongClose.getBytes("US-ASCII")))));

    // Correct close

    String responseContentCorrectClose = "HTTP/1.1 200 OK\nkey:value\nconnection:close\n\n";

    Assert.assertTrue(
        httpClientSPIAgent.consumeHttpResponseHead(
            new DataInputStream(
                new UnsyncByteArrayInputStream(responseContentCorrectClose.getBytes("US-ASCII")))));
  }
  @Test
  public void testTransferResponse() throws Exception {

    // Exception

    MockRegistrationReference mockRegistrationReference =
        new MockRegistrationReference(new MockIntraband());

    HttpClientSPIAgent httpClientSPIAgent =
        new HttpClientSPIAgent(_spiConfiguration, mockRegistrationReference);

    MockHttpServletRequest mockHttpServletRequest = new MockHttpServletRequest();

    mockHttpServletRequest.setAttribute(
        WebKeys.SPI_AGENT_REQUEST, new SPIAgentRequest(_mockHttpServletRequest));

    RecordSPIAgentResponse recordSPIAgentResponse = new RecordSPIAgentResponse();

    mockHttpServletRequest.setAttribute(WebKeys.SPI_AGENT_RESPONSE, recordSPIAgentResponse);

    MockHttpServletResponse mockHttpServletResponse = new MockHttpServletResponse();

    mockHttpServletRequest.setAttribute(
        WebKeys.SPI_AGENT_ORIGINAL_RESPONSE, mockHttpServletResponse);

    Exception exception = new Exception();

    httpClientSPIAgent.transferResponse(
        mockHttpServletRequest,
        new BufferCacheServletResponse(new MockHttpServletResponse()),
        exception);

    Assert.assertNull(mockHttpServletRequest.getAttribute(WebKeys.SPI_AGENT_REQUEST));
    Assert.assertNull(mockHttpServletRequest.getAttribute(WebKeys.SPI_AGENT_RESPONSE));
    Assert.assertSame(exception, recordSPIAgentResponse.exception);
    Assert.assertNull(mockHttpServletRequest.getAttribute(WebKeys.SPI_AGENT_ORIGINAL_RESPONSE));
    Assert.assertEquals(8, mockHttpServletResponse.getContentLength());
    Assert.assertNull(recordSPIAgentResponse._request);
    Assert.assertNull(recordSPIAgentResponse._bufferCacheServletResponse);
    Assert.assertSame(mockRegistrationReference, recordSPIAgentResponse._registrationReference);
    Assert.assertSame(
        mockHttpServletResponse.getOutputStream(), recordSPIAgentResponse._outputStream);

    // Response

    SPIAgentRequest spiAgentRequest = new SPIAgentRequest(_mockHttpServletRequest);

    File tempFile = File.createTempFile(HttpClientSPIAgentTest.class.getName(), null);

    Assert.assertTrue(tempFile.exists());

    spiAgentRequest.requestBodyFile = tempFile;

    mockHttpServletRequest.setAttribute(WebKeys.SPI_AGENT_REQUEST, spiAgentRequest);

    recordSPIAgentResponse = new RecordSPIAgentResponse();

    mockHttpServletRequest.setAttribute(WebKeys.SPI_AGENT_RESPONSE, recordSPIAgentResponse);

    mockHttpServletResponse = new MockHttpServletResponse();

    mockHttpServletRequest.setAttribute(
        WebKeys.SPI_AGENT_ORIGINAL_RESPONSE, mockHttpServletResponse);

    BufferCacheServletResponse bufferCacheServletResponse =
        new BufferCacheServletResponse(new MockHttpServletResponse());

    httpClientSPIAgent.transferResponse(mockHttpServletRequest, bufferCacheServletResponse, null);

    Assert.assertFalse(tempFile.exists());
    Assert.assertNull(mockHttpServletRequest.getAttribute(WebKeys.SPI_AGENT_REQUEST));
    Assert.assertNull(mockHttpServletRequest.getAttribute(WebKeys.SPI_AGENT_RESPONSE));
    Assert.assertNull(recordSPIAgentResponse.exception);
    Assert.assertNull(mockHttpServletRequest.getAttribute(WebKeys.SPI_AGENT_ORIGINAL_RESPONSE));
    Assert.assertEquals(8, mockHttpServletResponse.getContentLength());
    Assert.assertSame(mockHttpServletRequest, recordSPIAgentResponse._request);
    Assert.assertSame(
        bufferCacheServletResponse, recordSPIAgentResponse._bufferCacheServletResponse);
    Assert.assertSame(mockRegistrationReference, recordSPIAgentResponse._registrationReference);
    Assert.assertSame(
        mockHttpServletResponse.getOutputStream(), recordSPIAgentResponse._outputStream);

    // Undeletable request body file

    spiAgentRequest = new SPIAgentRequest(_mockHttpServletRequest);

    tempFile = File.createTempFile(HttpClientSPIAgentTest.class.getName(), null);

    Assert.assertTrue(tempFile.exists());

    spiAgentRequest.requestBodyFile = tempFile;

    mockHttpServletRequest.setAttribute(WebKeys.SPI_AGENT_REQUEST, spiAgentRequest);

    recordSPIAgentResponse = new RecordSPIAgentResponse();

    mockHttpServletRequest.setAttribute(WebKeys.SPI_AGENT_RESPONSE, recordSPIAgentResponse);

    mockHttpServletResponse = new MockHttpServletResponse();

    mockHttpServletRequest.setAttribute(
        WebKeys.SPI_AGENT_ORIGINAL_RESPONSE, mockHttpServletResponse);

    bufferCacheServletResponse = new BufferCacheServletResponse(new MockHttpServletResponse());

    Assert.assertTrue(tempFile.delete());

    httpClientSPIAgent.transferResponse(mockHttpServletRequest, bufferCacheServletResponse, null);

    Class<?> clazz = Class.forName("java.io.DeleteOnExitHook");

    Field filesField = ReflectionUtil.getDeclaredField(clazz, "files");

    Set<String> files = (Set<String>) filesField.get(null);

    Assert.assertTrue(files.contains(tempFile.getPath()));
  }
  @Test
  public void testService() throws Exception {

    // Unable to borrow a socket

    HttpClientSPIAgent httpClientSPIAgent =
        new HttpClientSPIAgent(
            _spiConfiguration, new MockRegistrationReference(new MockIntraband()));

    try {
      httpClientSPIAgent.service(null, null);

      Assert.fail();
    } catch (PortalResiliencyException pre) {
      Throwable throwable = pre.getCause();

      Assert.assertSame(ConnectException.class, throwable.getClass());
    }

    // Unable to send, successfully close

    httpClientSPIAgent =
        new HttpClientSPIAgent(
            _spiConfiguration,
            new MockRegistrationReference(new DirectMailboxIntraBand(new IOException())));

    ServerSocketChannel serverSocketChannel =
        SocketUtil.createServerSocketChannel(
            InetAddressUtil.getLoopbackInetAddress(), _spiConfiguration.getConnectorPort(), null);

    serverSocketChannel.configureBlocking(true);

    SocketChannel socketChannel = SocketChannel.open(httpClientSPIAgent.socketAddress);

    Socket socket = socketChannel.socket();

    Queue<Socket> socketBlockingQueue = httpClientSPIAgent.socketBlockingQueue;

    socketBlockingQueue.add(socket);

    MockHttpServletRequest mockHttpServletRequest = new MockHttpServletRequest();

    mockHttpServletRequest.setAttribute(WebKeys.SPI_AGENT_PORTLET, _portlet);

    try {
      httpClientSPIAgent.service(mockHttpServletRequest, null);

      Assert.fail();
    } catch (PortalResiliencyException pre) {
      Throwable throwable = pre.getCause();

      Assert.assertSame(IOException.class, throwable.getClass());
    }

    ServerSocket serverSocket = serverSocketChannel.socket();

    closePeers(socket, serverSocket);

    // Unable to send, unable to close, without log

    List<LogRecord> logRecords =
        JDKLoggerTestUtil.configureJDKLogger(HttpClientSPIAgent.class.getName(), Level.OFF);

    socket =
        new Socket(InetAddressUtil.getLoopbackInetAddress(), _spiConfiguration.getConnectorPort());

    SocketImpl socketImpl = swapSocketImpl(socket, null);

    DirectMailboxIntraBand directMailboxIntraBand = new DirectMailboxIntraBand(new IOException());

    httpClientSPIAgent =
        new HttpClientSPIAgent(
            _spiConfiguration, new MockRegistrationReference(directMailboxIntraBand));

    socketBlockingQueue = httpClientSPIAgent.socketBlockingQueue;

    socketBlockingQueue.add(socket);

    try {
      httpClientSPIAgent.service(mockHttpServletRequest, null);

      Assert.fail();
    } catch (PortalResiliencyException pre) {
      Throwable throwable = pre.getCause();

      Assert.assertSame(IOException.class, throwable.getClass());
    }

    Assert.assertTrue(logRecords.isEmpty());

    swapSocketImpl(socket, socketImpl);

    closePeers(socket, serverSocket);

    // Unable to send, unable to close, with log

    logRecords =
        JDKLoggerTestUtil.configureJDKLogger(HttpClientSPIAgent.class.getName(), Level.WARNING);

    socket =
        new Socket(InetAddressUtil.getLoopbackInetAddress(), _spiConfiguration.getConnectorPort());

    socketImpl = swapSocketImpl(socket, null);

    directMailboxIntraBand = new DirectMailboxIntraBand(new IOException());

    httpClientSPIAgent =
        new HttpClientSPIAgent(
            _spiConfiguration, new MockRegistrationReference(directMailboxIntraBand));

    socketBlockingQueue = httpClientSPIAgent.socketBlockingQueue;

    socketBlockingQueue.add(socket);

    try {
      httpClientSPIAgent.service(mockHttpServletRequest, null);

      Assert.fail();
    } catch (PortalResiliencyException pre) {
      Throwable throwable = pre.getCause();

      Assert.assertSame(IOException.class, throwable.getClass());
    }

    Assert.assertEquals(1, logRecords.size());

    LogRecord logRecord = logRecords.get(0);

    Throwable throwable = logRecord.getThrown();

    Assert.assertSame(IOException.class, throwable.getClass());

    swapSocketImpl(socket, socketImpl);

    closePeers(socket, serverSocket);

    // Successfully send

    socketChannel = SocketChannel.open(httpClientSPIAgent.socketAddress);

    socketChannel.configureBlocking(true);

    httpClientSPIAgent =
        new HttpClientSPIAgent(
            _spiConfiguration, new MockRegistrationReference(new DirectMailboxIntraBand(null)));

    socketBlockingQueue = httpClientSPIAgent.socketBlockingQueue;

    socket = socketChannel.socket();

    socketBlockingQueue.add(socket);

    Serializer serializer = new Serializer();

    serializer.writeString(_SERVLET_CONTEXT_NAME);
    serializer.writeObject(new SPIAgentResponse(_SERVLET_CONTEXT_NAME));

    Method depositMailMethod =
        ReflectionUtil.getDeclaredMethod(MailboxUtil.class, "depositMail", ByteBuffer.class);

    long receipt = (Long) depositMailMethod.invoke(null, serializer.toByteBuffer());

    Socket remoteSocket = serverSocket.accept();

    OutputStream outputStream = remoteSocket.getOutputStream();

    outputStream.write("HTTP/1.1 200 OK\n\n".getBytes("US-ASCII"));

    byte[] receiptData = new byte[8];

    BigEndianCodec.putLong(receiptData, 0, receipt);

    outputStream.write(receiptData);

    outputStream.flush();

    httpClientSPIAgent.service(mockHttpServletRequest, new MockHttpServletResponse());

    socket.close();
    remoteSocket.close();
    serverSocket.close();
  }
  @Test
  public void testReturnSocket() throws Exception {

    // Force close, successfully

    ServerSocketChannel serverSocketChannel =
        SocketUtil.createServerSocketChannel(
            InetAddressUtil.getLoopbackInetAddress(), _spiConfiguration.getConnectorPort(), null);

    serverSocketChannel.configureBlocking(true);

    ServerSocket serverSocket = serverSocketChannel.socket();

    HttpClientSPIAgent httpClientSPIAgent =
        new HttpClientSPIAgent(
            new SPIConfiguration(
                null,
                null,
                serverSocket.getLocalPort(),
                _spiConfiguration.getBaseDir(),
                null,
                null,
                null),
            new MockRegistrationReference(new MockIntraband()));

    SocketChannel socketChannel = SocketChannel.open(httpClientSPIAgent.socketAddress);

    Socket socket = socketChannel.socket();

    httpClientSPIAgent.returnSocket(socket, true);

    Queue<Socket> socketBlockingQueue = httpClientSPIAgent.socketBlockingQueue;

    Assert.assertTrue(socketBlockingQueue.isEmpty());

    closePeers(socket, serverSocket);

    // Force close, failed without log

    List<LogRecord> logRecords =
        JDKLoggerTestUtil.configureJDKLogger(HttpClientSPIAgent.class.getName(), Level.OFF);

    socket =
        new Socket(InetAddressUtil.getLoopbackInetAddress(), _spiConfiguration.getConnectorPort());

    SocketImpl socketImpl = swapSocketImpl(socket, null);

    httpClientSPIAgent.returnSocket(socket, true);

    Assert.assertTrue(socketBlockingQueue.isEmpty());

    swapSocketImpl(socket, socketImpl);

    closePeers(socket, serverSocket);

    Assert.assertTrue(logRecords.isEmpty());

    // Force close, failed with log

    logRecords =
        JDKLoggerTestUtil.configureJDKLogger(HttpClientSPIAgent.class.getName(), Level.WARNING);

    socket =
        new Socket(InetAddressUtil.getLoopbackInetAddress(), _spiConfiguration.getConnectorPort());

    socketImpl = swapSocketImpl(socket, null);

    httpClientSPIAgent.returnSocket(socket, true);

    Assert.assertTrue(socketBlockingQueue.isEmpty());

    swapSocketImpl(socket, socketImpl);

    closePeers(socket, serverSocket);

    Assert.assertEquals(1, logRecords.size());

    LogRecord logRecord = logRecords.get(0);

    Throwable throwable = logRecord.getThrown();

    Assert.assertSame(IOException.class, throwable.getClass());

    // socket.isConnected()

    httpClientSPIAgent.returnSocket(new Socket(), false);

    Assert.assertTrue(socketBlockingQueue.isEmpty());

    // socket.isInputShutdown()

    socketChannel = SocketChannel.open(httpClientSPIAgent.socketAddress);

    socket = socketChannel.socket();

    socket.shutdownInput();

    httpClientSPIAgent.returnSocket(socket, false);

    Assert.assertTrue(socketBlockingQueue.isEmpty());

    closePeers(socket, serverSocket);

    // socket.isOutputShutdown()

    socketChannel = SocketChannel.open(httpClientSPIAgent.socketAddress);

    socket = socketChannel.socket();

    socket.shutdownOutput();

    httpClientSPIAgent.returnSocket(socket, false);

    Assert.assertTrue(socketBlockingQueue.isEmpty());

    closePeers(socket, serverSocket);

    // Successfully return

    socketChannel = SocketChannel.open(httpClientSPIAgent.socketAddress);

    socket = socketChannel.socket();

    httpClientSPIAgent.returnSocket(socket, false);

    Assert.assertEquals(1, socketBlockingQueue.size());
    Assert.assertSame(socket, socketBlockingQueue.poll());

    closePeers(socket, serverSocket);

    serverSocket.close();
  }
  @Test
  public void testDestroy() throws Exception {

    // Without log

    List<LogRecord> logRecords =
        JDKLoggerTestUtil.configureJDKLogger(HttpClientSPIAgent.class.getName(), Level.OFF);

    ServerSocketChannel serverSocketChannel =
        SocketUtil.createServerSocketChannel(
            InetAddressUtil.getLoopbackInetAddress(), _spiConfiguration.getConnectorPort(), null);

    serverSocketChannel.configureBlocking(true);

    ServerSocket serverSocket = serverSocketChannel.socket();

    Socket socket =
        new Socket(InetAddressUtil.getLoopbackInetAddress(), _spiConfiguration.getConnectorPort());

    SocketImpl socketImpl = swapSocketImpl(socket, null);

    HttpClientSPIAgent httpClientSPIAgent =
        new HttpClientSPIAgent(
            _spiConfiguration, new MockRegistrationReference(new MockIntraband()));

    Queue<Socket> socketBlockingQueue = httpClientSPIAgent.socketBlockingQueue;

    socketBlockingQueue.add(socket);

    httpClientSPIAgent.destroy();

    swapSocketImpl(socket, socketImpl);

    closePeers(socket, serverSocket);

    Assert.assertTrue(logRecords.isEmpty());

    // With log

    logRecords =
        JDKLoggerTestUtil.configureJDKLogger(HttpClientSPIAgent.class.getName(), Level.WARNING);

    httpClientSPIAgent =
        new HttpClientSPIAgent(
            _spiConfiguration, new MockRegistrationReference(new MockIntraband()));

    socketBlockingQueue = httpClientSPIAgent.socketBlockingQueue;

    socket =
        new Socket(InetAddressUtil.getLoopbackInetAddress(), _spiConfiguration.getConnectorPort());

    socketImpl = swapSocketImpl(socket, null);

    socketBlockingQueue.add(socket);

    httpClientSPIAgent.destroy();

    swapSocketImpl(socket, socketImpl);

    closePeers(socket, serverSocket);

    Assert.assertEquals(1, logRecords.size());

    LogRecord logRecord = logRecords.get(0);

    Throwable throwable = logRecord.getThrown();

    Assert.assertSame(IOException.class, throwable.getClass());

    serverSocket.close();
  }
  @Test
  public void testBorrowSocket() throws Exception {

    // Create on empty

    ServerSocketChannel serverSocketChannel =
        SocketUtil.createServerSocketChannel(
            InetAddressUtil.getLoopbackInetAddress(), _spiConfiguration.getConnectorPort(), null);

    serverSocketChannel.configureBlocking(true);

    ServerSocket serverSocket = serverSocketChannel.socket();

    SPIConfiguration spiConfiguration =
        new SPIConfiguration(
            null,
            null,
            serverSocket.getLocalPort(),
            _spiConfiguration.getBaseDir(),
            null,
            null,
            null);

    HttpClientSPIAgent httpClientSPIAgent =
        new HttpClientSPIAgent(
            spiConfiguration, new MockRegistrationReference(new MockIntraband()));

    Socket socket = httpClientSPIAgent.borrowSocket();

    closePeers(socket, serverSocket);

    // Clean up when closed

    Queue<Socket> socketBlockingQueue = httpClientSPIAgent.socketBlockingQueue;

    socketBlockingQueue.add(socket);

    socket = httpClientSPIAgent.borrowSocket();

    closePeers(socket, serverSocket);

    // Clean up not connected

    socketBlockingQueue.add(new Socket());

    socket = httpClientSPIAgent.borrowSocket();

    closePeers(socket, serverSocket);

    // Clean up when input is shutdown

    socket = httpClientSPIAgent.borrowSocket();

    socket.shutdownInput();

    socketBlockingQueue.add(socket);

    socket = httpClientSPIAgent.borrowSocket();

    closePeers(socket, serverSocket);

    socket = serverSocket.accept();

    socket.close();

    // Clean up when input is shutdown, failed without log

    List<LogRecord> logRecords =
        JDKLoggerTestUtil.configureJDKLogger(HttpClientSPIAgent.class.getName(), Level.OFF);

    socket =
        new Socket(InetAddressUtil.getLoopbackInetAddress(), _spiConfiguration.getConnectorPort());

    socket.shutdownInput();

    SocketImpl socketImpl = swapSocketImpl(socket, null);

    socketBlockingQueue.add(socket);

    socket = httpClientSPIAgent.borrowSocket();

    swapSocketImpl(socket, socketImpl);

    closePeers(socket, serverSocket);

    socket = serverSocket.accept();

    socket.close();

    Assert.assertTrue(logRecords.isEmpty());

    // Clean up when input is shutdown, failed with log

    logRecords =
        JDKLoggerTestUtil.configureJDKLogger(HttpClientSPIAgent.class.getName(), Level.WARNING);

    socket =
        new Socket(InetAddressUtil.getLoopbackInetAddress(), _spiConfiguration.getConnectorPort());

    socket.shutdownInput();

    socketImpl = swapSocketImpl(socket, null);

    socketBlockingQueue.add(socket);

    socket = httpClientSPIAgent.borrowSocket();

    swapSocketImpl(socket, socketImpl);

    closePeers(socket, serverSocket);

    socket = serverSocket.accept();

    socket.close();

    Assert.assertEquals(1, logRecords.size());

    LogRecord logRecord = logRecords.get(0);

    Throwable throwable = logRecord.getThrown();

    Assert.assertSame(IOException.class, throwable.getClass());

    // Clean up when output is shutdown()

    socket = httpClientSPIAgent.borrowSocket();

    socket.shutdownOutput();

    socketBlockingQueue.add(socket);

    socket = httpClientSPIAgent.borrowSocket();

    closePeers(socket, serverSocket);

    socket = serverSocket.accept();

    socket.close();

    // Reuse socket

    socket = httpClientSPIAgent.borrowSocket();

    socketBlockingQueue.add(socket);

    Assert.assertSame(socket, httpClientSPIAgent.borrowSocket());

    closePeers(socket, serverSocket);

    serverSocket.close();
  }
  @Test
  public void testTransferResponse() throws IOException {

    // Exception

    MockRegistrationReference mockRegistrationReference =
        new MockRegistrationReference(new MockIntraband());

    HttpClientSPIAgent httpClientSPIAgent =
        new HttpClientSPIAgent(_spiConfiguration, mockRegistrationReference);

    MockHttpServletRequest mockHttpServletRequest = new MockHttpServletRequest();

    mockHttpServletRequest.setAttribute(
        WebKeys.SPI_AGENT_REQUEST, new SPIAgentRequest(new MockHttpServletRequest()));

    RecordSPIAgentResponse recordSPIAgentResponse = new RecordSPIAgentResponse();

    mockHttpServletRequest.setAttribute(WebKeys.SPI_AGENT_RESPONSE, recordSPIAgentResponse);

    MockHttpServletResponse mockHttpServletResponse = new MockHttpServletResponse();

    mockHttpServletRequest.setAttribute(
        WebKeys.SPI_AGENT_ORIGINAL_RESPONSE, mockHttpServletResponse);

    Exception exception = new Exception();

    httpClientSPIAgent.transferResponse(
        mockHttpServletRequest,
        new BufferCacheServletResponse(new MockHttpServletResponse()),
        exception);

    Assert.assertNull(mockHttpServletRequest.getAttribute(WebKeys.SPI_AGENT_REQUEST));
    Assert.assertNull(mockHttpServletRequest.getAttribute(WebKeys.SPI_AGENT_RESPONSE));
    Assert.assertSame(exception, recordSPIAgentResponse.exception);
    Assert.assertNull(mockHttpServletRequest.getAttribute(WebKeys.SPI_AGENT_ORIGINAL_RESPONSE));
    Assert.assertEquals(8, mockHttpServletResponse.getContentLength());
    Assert.assertNull(recordSPIAgentResponse._request);
    Assert.assertNull(recordSPIAgentResponse._bufferCacheServletResponse);
    Assert.assertSame(mockRegistrationReference, recordSPIAgentResponse._registrationReference);
    Assert.assertSame(
        mockHttpServletResponse.getOutputStream(), recordSPIAgentResponse._outputStream);

    // Response

    mockHttpServletRequest.setAttribute(
        WebKeys.SPI_AGENT_REQUEST, new SPIAgentRequest(new MockHttpServletRequest()));

    recordSPIAgentResponse = new RecordSPIAgentResponse();

    mockHttpServletRequest.setAttribute(WebKeys.SPI_AGENT_RESPONSE, recordSPIAgentResponse);

    mockHttpServletResponse = new MockHttpServletResponse();

    mockHttpServletRequest.setAttribute(
        WebKeys.SPI_AGENT_ORIGINAL_RESPONSE, mockHttpServletResponse);

    BufferCacheServletResponse bufferCacheServletResponse =
        new BufferCacheServletResponse(new MockHttpServletResponse());

    httpClientSPIAgent.transferResponse(mockHttpServletRequest, bufferCacheServletResponse, null);

    Assert.assertNull(mockHttpServletRequest.getAttribute(WebKeys.SPI_AGENT_REQUEST));
    Assert.assertNull(mockHttpServletRequest.getAttribute(WebKeys.SPI_AGENT_RESPONSE));
    Assert.assertNull(recordSPIAgentResponse.exception);
    Assert.assertNull(mockHttpServletRequest.getAttribute(WebKeys.SPI_AGENT_ORIGINAL_RESPONSE));
    Assert.assertEquals(8, mockHttpServletResponse.getContentLength());
    Assert.assertSame(mockHttpServletRequest, recordSPIAgentResponse._request);
    Assert.assertSame(
        bufferCacheServletResponse, recordSPIAgentResponse._bufferCacheServletResponse);
    Assert.assertSame(mockRegistrationReference, recordSPIAgentResponse._registrationReference);
    Assert.assertSame(
        mockHttpServletResponse.getOutputStream(), recordSPIAgentResponse._outputStream);
  }