@Test
 public void testFailoverGood() throws Exception {
   AbstractClientConnectionFactory factory1 = mock(AbstractClientConnectionFactory.class);
   AbstractClientConnectionFactory factory2 = mock(AbstractClientConnectionFactory.class);
   List<AbstractClientConnectionFactory> factories =
       new ArrayList<AbstractClientConnectionFactory>();
   factories.add(factory1);
   factories.add(factory2);
   TcpConnectionSupport conn1 = makeMockConnection();
   TcpConnectionSupport conn2 = makeMockConnection();
   when(factory1.getConnection()).thenReturn(conn1);
   when(factory2.getConnection()).thenReturn(conn2);
   when(factory1.isActive()).thenReturn(true);
   when(factory2.isActive()).thenReturn(true);
   doThrow(new IOException("fail")).when(conn1).send(Mockito.any(Message.class));
   doAnswer(
           new Answer<Object>() {
             public Object answer(InvocationOnMock invocation) throws Throwable {
               return null;
             }
           })
       .when(conn2)
       .send(Mockito.any(Message.class));
   FailoverClientConnectionFactory failoverFactory =
       new FailoverClientConnectionFactory(factories);
   failoverFactory.start();
   GenericMessage<String> message = new GenericMessage<String>("foo");
   failoverFactory.getConnection().send(message);
   Mockito.verify(conn2).send(message);
 }
 @Test(expected = IOException.class)
 public void testFailoverConnectNone() throws Exception {
   AbstractClientConnectionFactory factory1 = mock(AbstractClientConnectionFactory.class);
   AbstractClientConnectionFactory factory2 = mock(AbstractClientConnectionFactory.class);
   List<AbstractClientConnectionFactory> factories =
       new ArrayList<AbstractClientConnectionFactory>();
   factories.add(factory1);
   factories.add(factory2);
   when(factory1.getConnection()).thenThrow(new IOException("fail"));
   when(factory2.getConnection()).thenThrow(new IOException("fail"));
   when(factory1.isActive()).thenReturn(true);
   when(factory2.isActive()).thenReturn(true);
   FailoverClientConnectionFactory failoverFactory =
       new FailoverClientConnectionFactory(factories);
   failoverFactory.start();
   GenericMessage<String> message = new GenericMessage<String>("foo");
   failoverFactory.getConnection().send(message);
 }
 @Test
 public void testOkAgainAfterCompleteFailure() throws Exception {
   AbstractClientConnectionFactory factory1 = mock(AbstractClientConnectionFactory.class);
   AbstractClientConnectionFactory factory2 = mock(AbstractClientConnectionFactory.class);
   List<AbstractClientConnectionFactory> factories =
       new ArrayList<AbstractClientConnectionFactory>();
   factories.add(factory1);
   factories.add(factory2);
   TcpConnectionSupport conn1 = makeMockConnection();
   TcpConnectionSupport conn2 = makeMockConnection();
   when(factory1.getConnection()).thenReturn(conn1);
   when(factory2.getConnection()).thenReturn(conn2);
   when(factory1.isActive()).thenReturn(true);
   when(factory2.isActive()).thenReturn(true);
   final AtomicInteger failCount = new AtomicInteger();
   doAnswer(
           new Answer<Object>() {
             @Override
             public Object answer(InvocationOnMock invocation) throws Throwable {
               if (failCount.incrementAndGet() < 3) {
                 throw new IOException("fail");
               }
               return null;
             }
           })
       .when(conn1)
       .send(Mockito.any(Message.class));
   doThrow(new IOException("fail")).when(conn2).send(Mockito.any(Message.class));
   FailoverClientConnectionFactory failoverFactory =
       new FailoverClientConnectionFactory(factories);
   failoverFactory.start();
   GenericMessage<String> message = new GenericMessage<String>("foo");
   try {
     failoverFactory.getConnection().send(message);
     fail("ExpectedFailure");
   } catch (IOException e) {
   }
   failoverFactory.getConnection().send(message);
   Mockito.verify(conn2).send(message);
   Mockito.verify(conn1, times(3)).send(message);
 }
 @Test(expected = IOException.class)
 public void testFailoverAllDead() throws Exception {
   AbstractClientConnectionFactory factory1 = mock(AbstractClientConnectionFactory.class);
   AbstractClientConnectionFactory factory2 = mock(AbstractClientConnectionFactory.class);
   List<AbstractClientConnectionFactory> factories =
       new ArrayList<AbstractClientConnectionFactory>();
   factories.add(factory1);
   factories.add(factory2);
   TcpConnectionSupport conn1 = makeMockConnection();
   TcpConnectionSupport conn2 = makeMockConnection();
   when(factory1.getConnection()).thenReturn(conn1);
   when(factory2.getConnection()).thenReturn(conn2);
   when(factory1.isActive()).thenReturn(true);
   when(factory2.isActive()).thenReturn(true);
   doThrow(new IOException("fail")).when(conn1).send(Mockito.any(Message.class));
   doThrow(new IOException("fail")).when(conn2).send(Mockito.any(Message.class));
   FailoverClientConnectionFactory failoverFactory =
       new FailoverClientConnectionFactory(factories);
   failoverFactory.start();
   GenericMessage<String> message = new GenericMessage<String>("foo");
   failoverFactory.getConnection().send(message);
   Mockito.verify(conn2).send(message);
 }
 @Test
 public void testFailoverAllDeadButOriginalOkAgain() throws Exception {
   AbstractClientConnectionFactory factory1 = mock(AbstractClientConnectionFactory.class);
   AbstractClientConnectionFactory factory2 = mock(AbstractClientConnectionFactory.class);
   List<AbstractClientConnectionFactory> factories =
       new ArrayList<AbstractClientConnectionFactory>();
   factories.add(factory1);
   factories.add(factory2);
   TcpConnectionSupport conn1 = makeMockConnection();
   TcpConnectionSupport conn2 = makeMockConnection();
   when(factory1.getConnection()).thenReturn(conn1);
   when(factory2.getConnection()).thenReturn(conn2);
   when(factory1.isActive()).thenReturn(true);
   when(factory2.isActive()).thenReturn(true);
   final AtomicBoolean failedOnce = new AtomicBoolean();
   doAnswer(
           new Answer<Object>() {
             @Override
             public Object answer(InvocationOnMock invocation) throws Throwable {
               if (!failedOnce.get()) {
                 failedOnce.set(true);
                 throw new IOException("fail");
               }
               return null;
             }
           })
       .when(conn1)
       .send(Mockito.any(Message.class));
   doThrow(new IOException("fail")).when(conn2).send(Mockito.any(Message.class));
   FailoverClientConnectionFactory failoverFactory =
       new FailoverClientConnectionFactory(factories);
   failoverFactory.start();
   GenericMessage<String> message = new GenericMessage<String>("foo");
   failoverFactory.getConnection().send(message);
   Mockito.verify(conn2).send(message);
   Mockito.verify(conn1, times(2)).send(message);
 }