@Test
 public void testEnlargePool() throws Exception {
   AbstractClientConnectionFactory factory = mock(AbstractClientConnectionFactory.class);
   when(factory.isRunning()).thenReturn(true);
   TcpConnectionSupport mockConn1 = makeMockConnection("conn1");
   TcpConnectionSupport mockConn2 = makeMockConnection("conn2");
   TcpConnectionSupport mockConn3 = makeMockConnection("conn3");
   TcpConnectionSupport mockConn4 = makeMockConnection("conn4");
   when(factory.getConnection()).thenReturn(mockConn1, mockConn2, mockConn3, mockConn4);
   CachingClientConnectionFactory cachingFactory = new CachingClientConnectionFactory(factory, 2);
   cachingFactory.start();
   TcpConnection conn1 = cachingFactory.getConnection();
   TcpConnection conn2 = cachingFactory.getConnection();
   assertNotSame(conn1, conn2);
   Semaphore semaphore =
       TestUtils.getPropertyValue(
           TestUtils.getPropertyValue(cachingFactory, "pool"), "permits", Semaphore.class);
   assertEquals(0, semaphore.availablePermits());
   cachingFactory.setPoolSize(4);
   TcpConnection conn3 = cachingFactory.getConnection();
   TcpConnection conn4 = cachingFactory.getConnection();
   assertEquals(0, semaphore.availablePermits());
   conn1.close();
   conn1.close();
   conn2.close();
   conn3.close();
   conn4.close();
   assertEquals(4, semaphore.availablePermits());
 }
 private CachingClientConnectionFactory createCCCFWith2Connections(
     TcpConnectionSupport conn1, TcpConnectionSupport conn2) throws Exception {
   AbstractClientConnectionFactory factory = mock(AbstractClientConnectionFactory.class);
   when(factory.isRunning()).thenReturn(true);
   when(factory.getConnection()).thenReturn(conn1, conn2);
   CachingClientConnectionFactory cccf = new CachingClientConnectionFactory(factory, 1);
   cccf.setConnectionWaitTimeout(1);
   cccf.start();
   return cccf;
 }
 private void testCloseOnTimeoutGuts(AbstractClientConnectionFactory cf) throws Exception {
   TestingUtilities.waitListening(serverCf, null);
   cf.setSoTimeout(100);
   CachingClientConnectionFactory cccf = new CachingClientConnectionFactory(cf, 1);
   cccf.start();
   TcpConnection connection = cccf.getConnection();
   int n = 0;
   while (n++ < 100 && connection.isOpen()) {
     Thread.sleep(100);
   }
   assertFalse(connection.isOpen());
   cccf.stop();
 }
 private void doTestCloseOnSendError(
     TcpConnection conn1, TcpConnection conn2, CachingClientConnectionFactory cccf)
     throws Exception {
   TcpConnection cached1 = cccf.getConnection();
   try {
     cached1.send(new GenericMessage<String>("foo"));
     fail("Expected IOException");
   } catch (IOException e) {
     assertEquals("Foo", e.getMessage());
   }
   // Before INT-3163 this failed with a timeout - connection not returned to pool after failure on
   // send()
   TcpConnection cached2 = cccf.getConnection();
   assertTrue(cached1.getConnectionId().contains(conn1.getConnectionId()));
   assertTrue(cached2.getConnectionId().contains(conn2.getConnectionId()));
 }
 @Test
 public void testReuse() throws Exception {
   AbstractClientConnectionFactory factory = mock(AbstractClientConnectionFactory.class);
   when(factory.isRunning()).thenReturn(true);
   TcpConnectionSupport mockConn1 = makeMockConnection("conn1");
   TcpConnectionSupport mockConn2 = makeMockConnection("conn2");
   when(factory.getConnection()).thenReturn(mockConn1).thenReturn(mockConn2);
   CachingClientConnectionFactory cachingFactory = new CachingClientConnectionFactory(factory, 2);
   cachingFactory.start();
   TcpConnection conn1 = cachingFactory.getConnection();
   assertEquals("Cached:" + mockConn1.toString(), conn1.toString());
   conn1.close();
   conn1 = cachingFactory.getConnection();
   assertEquals("Cached:" + mockConn1.toString(), conn1.toString());
   TcpConnection conn2 = cachingFactory.getConnection();
   assertEquals("Cached:" + mockConn2.toString(), conn2.toString());
   conn1.close();
   conn2.close();
 }
  @Test
  public void testCachedFailover() throws Exception {
    // Failover
    AbstractClientConnectionFactory factory1 = mock(AbstractClientConnectionFactory.class);
    AbstractClientConnectionFactory factory2 = mock(AbstractClientConnectionFactory.class);
    List<AbstractClientConnectionFactory> factories =
        new ArrayList<AbstractClientConnectionFactory>();
    factories.add(factory1);
    factories.add(factory2);
    TcpConnectionSupport mockConn1 = makeMockConnection();
    TcpConnectionSupport mockConn2 = makeMockConnection();
    when(factory1.getConnection()).thenReturn(mockConn1);
    when(factory2.getConnection()).thenReturn(mockConn2);
    when(factory1.isActive()).thenReturn(true);
    when(factory2.isActive()).thenReturn(true);
    doThrow(new IOException("fail")).when(mockConn1).send(Mockito.any(Message.class));
    doAnswer(
            new Answer<Object>() {
              @Override
              public Object answer(InvocationOnMock invocation) throws Throwable {
                return null;
              }
            })
        .when(mockConn2)
        .send(Mockito.any(Message.class));
    FailoverClientConnectionFactory failoverFactory =
        new FailoverClientConnectionFactory(factories);
    failoverFactory.start();

    // Cache
    CachingClientConnectionFactory cachingFactory =
        new CachingClientConnectionFactory(failoverFactory, 2);
    cachingFactory.start();
    TcpConnection conn1 = cachingFactory.getConnection();
    GenericMessage<String> message = new GenericMessage<String>("foo");
    conn1 = cachingFactory.getConnection();
    conn1.send(message);
    Mockito.verify(mockConn2).send(message);
  }
 @Test
 public void testStop() throws Exception {
   AbstractClientConnectionFactory factory = mock(AbstractClientConnectionFactory.class);
   when(factory.isRunning()).thenReturn(true);
   TcpConnectionSupport mockConn1 = makeMockConnection("conn1");
   TcpConnectionSupport mockConn2 = makeMockConnection("conn2");
   int i = 3;
   when(factory.getConnection())
       .thenReturn(mockConn1)
       .thenReturn(mockConn2)
       .thenReturn(makeMockConnection("conn" + (i++)));
   CachingClientConnectionFactory cachingFactory = new CachingClientConnectionFactory(factory, 2);
   cachingFactory.start();
   TcpConnection conn1 = cachingFactory.getConnection();
   assertEquals("Cached:" + mockConn1.toString(), conn1.toString());
   conn1.close();
   conn1 = cachingFactory.getConnection();
   assertEquals("Cached:" + mockConn1.toString(), conn1.toString());
   TcpConnection conn2 = cachingFactory.getConnection();
   assertEquals("Cached:" + mockConn2.toString(), conn2.toString());
   cachingFactory.stop();
   Answer<Object> answer =
       new Answer<Object>() {
         @Override
         public Object answer(InvocationOnMock invocation) throws Throwable {
           return null;
         }
       };
   doAnswer(answer).when(mockConn1).close();
   doAnswer(answer).when(mockConn2).close();
   when(factory.isRunning()).thenReturn(false);
   conn1.close();
   conn2.close();
   verify(mockConn1).close();
   verify(mockConn2).close();
   when(mockConn1.isOpen()).thenReturn(false);
   when(mockConn2.isOpen()).thenReturn(false);
   when(factory.isRunning()).thenReturn(true);
   TcpConnection conn3 = cachingFactory.getConnection();
   assertNotSame(
       TestUtils.getPropertyValue(conn1, "theConnection"),
       TestUtils.getPropertyValue(conn3, "theConnection"));
   assertNotSame(
       TestUtils.getPropertyValue(conn2, "theConnection"),
       TestUtils.getPropertyValue(conn3, "theConnection"));
 }
 @Test
 public void testReducePool() throws Exception {
   AbstractClientConnectionFactory factory = mock(AbstractClientConnectionFactory.class);
   when(factory.isRunning()).thenReturn(true);
   TcpConnectionSupport mockConn1 = makeMockConnection("conn1", true);
   TcpConnectionSupport mockConn2 = makeMockConnection("conn2", true);
   TcpConnectionSupport mockConn3 = makeMockConnection("conn3", true);
   TcpConnectionSupport mockConn4 = makeMockConnection("conn4", true);
   when(factory.getConnection())
       .thenReturn(mockConn1)
       .thenReturn(mockConn2)
       .thenReturn(mockConn3)
       .thenReturn(mockConn4);
   CachingClientConnectionFactory cachingFactory = new CachingClientConnectionFactory(factory, 4);
   cachingFactory.start();
   TcpConnection conn1 = cachingFactory.getConnection();
   TcpConnection conn2 = cachingFactory.getConnection();
   TcpConnection conn3 = cachingFactory.getConnection();
   TcpConnection conn4 = cachingFactory.getConnection();
   Semaphore semaphore =
       TestUtils.getPropertyValue(
           TestUtils.getPropertyValue(cachingFactory, "pool"), "permits", Semaphore.class);
   assertEquals(0, semaphore.availablePermits());
   conn1.close();
   assertEquals(1, semaphore.availablePermits());
   cachingFactory.setPoolSize(2);
   assertEquals(0, semaphore.availablePermits());
   assertEquals(3, cachingFactory.getActiveCount());
   conn2.close();
   assertEquals(0, semaphore.availablePermits());
   assertEquals(2, cachingFactory.getActiveCount());
   conn3.close();
   assertEquals(1, cachingFactory.getActiveCount());
   assertEquals(1, cachingFactory.getIdleCount());
   conn4.close();
   assertEquals(2, semaphore.availablePermits());
   assertEquals(0, cachingFactory.getActiveCount());
   assertEquals(2, cachingFactory.getIdleCount());
   verify(mockConn1).close();
   verify(mockConn2).close();
 }