Package com.linkedin.databus.client.consumer

Source Code of com.linkedin.databus.client.consumer.TestMultiConsumerCallback$SomeApplicationException

package com.linkedin.databus.client.consumer;
/*
*
* Copyright 2013 LinkedIn Corp. All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.easymock.EasyMock;
import org.easymock.IAnswer;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;

import com.linkedin.databus.client.SingleSourceSCN;
import com.linkedin.databus.client.pub.ConsumerCallbackResult;
import com.linkedin.databus.client.pub.DatabusCombinedConsumer;
import com.linkedin.databus.client.pub.DatabusStreamConsumer;
import com.linkedin.databus.client.pub.mbean.ConsumerCallbackStats;
import com.linkedin.databus.client.pub.mbean.UnifiedClientStats;
import com.linkedin.databus.core.DbusEvent;
import com.linkedin.databus.core.DbusEventBuffer;
import com.linkedin.databus.core.DbusEventBuffer.AllocationPolicy;
import com.linkedin.databus.core.DbusEventBuffer.QueuePolicy;
import com.linkedin.databus.core.DbusEventKey;
import com.linkedin.databus.core.util.IdNamePair;
import com.linkedin.databus2.test.TestUtil;


public class TestMultiConsumerCallback
{
  public static final String MODULE = TestMultiConsumerCallback.class.getName();
  public static final Logger LOG = Logger.getLogger(MODULE);

  private DbusEventBuffer.Config _generic100KBufferConfig;
  private DbusEventBuffer.StaticConfig _generic100KBufferStaticConfig;

  static
  {
    TestUtil.setupLogging(true, "/tmp/TestMultiConsumerCallback.txt", Level.OFF);
  }

  private void initMockStreamConsumer3EventFullLifecycle(DatabusStreamConsumer mockConsumer,
                                                         DbusEvent event1,
                                                         DbusEvent event2,
                                                         DbusEvent event3,
                                                         Hashtable<Long, AtomicInteger> keyCounts)
  {
    EasyMock.makeThreadSafe(mockConsumer, true);
     EasyMock.expect(mockConsumer.onStartConsumption()).andAnswer(
         new LoggedAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG,
             "startConsumption() called"));
     EasyMock.expect(mockConsumer.onStartDataEventSequence(null)).andAnswer(
         new LoggedAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG,
             "startDataEventSequence() called"));
     EasyMock.expect(mockConsumer.onStartSource("source1", null)).andAnswer(
         new LoggedAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG,
             "startDataEventSequence() called"));
     EasyMock.expect(mockConsumer.onDataEvent(event1, null)).andAnswer(
         new EventCountingAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS,
             keyCounts.get(1L)));
     EasyMock.expect(mockConsumer.onEndSource("source1", null)).andAnswer(
         new LoggedAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG,
             "endDataEventSequence() called")).times(0, 1);
     EasyMock.expect(mockConsumer.onStartSource("source3", null)).andAnswer(
         new LoggedAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG,
             "startDataEventSequence() called"));
     EasyMock.expect(mockConsumer.onDataEvent(event2, null)).andAnswer(
         new EventCountingAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS,
             keyCounts.get(2L)));
     EasyMock.expect(mockConsumer.onDataEvent(event3, null)).andAnswer(
         new EventCountingAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS,
             keyCounts.get(3L)));
     EasyMock.expect(mockConsumer.onEndSource("source3", null)).andAnswer(
         new LoggedAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG,
             "endDataEventSequence() called"));
     EasyMock.expect(mockConsumer.onEndDataEventSequence(null)).andAnswer(
         new LoggedAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG,
             "endDataEventSequence() called"));
     EasyMock.expect(mockConsumer.onStopConsumption()).andAnswer(
         new LoggedAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG,
             "stopConsumption() called"));
     EasyMock.replay(mockConsumer);
  }

  private void initMockExceptionStreamConsumer3EventFullLifecycle(
      DatabusStreamConsumer mockConsumer,
      DbusEvent event1,
      DbusEvent event2,
      DbusEvent event3,
      Hashtable<Long, AtomicInteger> keyCounts,
      Throwable exception)
  {
    EasyMock.makeThreadSafe(mockConsumer, true);
    EasyMock.expect(mockConsumer.onStartConsumption()).andAnswer(new LoggedAnswer<ConsumerCallbackResult>(
        ConsumerCallbackResult.SUCCESS,
        LOG,
        Level.DEBUG,
        "startConsumption() called"));
    EasyMock.expect(mockConsumer.onStartDataEventSequence(null)).andAnswer(
        new LoggedAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG, "startDataEventSequence() called"));
    EasyMock.expect(mockConsumer.onStartSource("source1", null)).andAnswer(
        new LoggedAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG, "startSource() called"));
//    EasyMock.expect(mockConsumer.onDataEvent(event1, null)).andAnswer(
//        new EventCountingAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.ERROR, keyCounts.get(1L)));
    EasyMock.expect(mockConsumer.onDataEvent(event1, null)).andAnswer(new ExceptionAnswer<ConsumerCallbackResult>(exception));
//        new ExceptionAnswer<ConsumerCallbackResult>(new LoggedAnswer<ConsumerCallbackResult>(
//            ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG, "onEvent() called")));
    EasyMock.expect(mockConsumer.onEndSource("source1", null)).andAnswer(new LoggedAnswer<ConsumerCallbackResult>(
        ConsumerCallbackResult.SUCCESS,
        LOG,
        Level.DEBUG,
        "endSource() called")).times(0, 1);
    EasyMock.expect(mockConsumer.onStartSource("source3", null)).andAnswer(
        new LoggedAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG, "startSource() called"));
    EasyMock.expect(mockConsumer.onDataEvent(event2, null)).andAnswer(
        new EventCountingAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, keyCounts.get(2L)));
    EasyMock.expect(mockConsumer.onDataEvent(event3, null)).andAnswer(
        new EventCountingAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, keyCounts.get(3L)));
    EasyMock.expect(mockConsumer.onEndSource("source3", null)).andAnswer(
        new LoggedAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG, "endSource() called"));
    EasyMock.expect(mockConsumer.onEndDataEventSequence(null)).andAnswer(
        new LoggedAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG, "endDataEventSequence() called"));
    EasyMock.expect(mockConsumer.onStopConsumption()).andAnswer(
        new LoggedAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG, "stopConsumption() called"));
    EasyMock.replay(mockConsumer);
  }

  private void initMockFailingStreamConsumer3EventFullLifecycle(
      DatabusStreamConsumer mockConsumer,
      DbusEvent event1,
      DbusEvent event2,
      DbusEvent event3,
      Hashtable<Long, AtomicInteger> keyCounts)
  {
    EasyMock.makeThreadSafe(mockConsumer, true);
     EasyMock.expect(mockConsumer.onStartConsumption()).andAnswer(
         new LoggedAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG, "startConsumption() called"));
     EasyMock.expect(mockConsumer.onStartDataEventSequence(null)).andAnswer(
         new LoggedAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG, "startDataEventSequence() called"));
     EasyMock.expect(mockConsumer.onStartSource("source1", null)).andAnswer(
         new LoggedAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG, "startDataEventSequence() called"));
     EasyMock.expect(mockConsumer.onDataEvent(event1, null)).andAnswer(
         new EventCountingAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.ERROR, keyCounts.get(1L)));
     EasyMock.expect(mockConsumer.onEndSource("source1", null)).andAnswer(
         new LoggedAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG, "endDataEventSequence() called")).times(0, 1);
     EasyMock.expect(mockConsumer.onStartSource("source3", null)).andAnswer(
         new LoggedAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG, "startDataEventSequence() called"));
     EasyMock.expect(mockConsumer.onDataEvent(event2, null)).andAnswer(new EventCountingAnswer<ConsumerCallbackResult>(
         ConsumerCallbackResult.SUCCESS,
         keyCounts.get(2L)));
     EasyMock.expect(mockConsumer.onDataEvent(event3, null)).andAnswer(
         new EventCountingAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, keyCounts.get(3L)));
     EasyMock.expect(mockConsumer.onEndSource("source3", null)).andAnswer(
         new LoggedAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG, "endDataEventSequence() called"));
     EasyMock.expect(mockConsumer.onEndDataEventSequence(null)).andAnswer(
         new LoggedAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG, "endDataEventSequence() called"));
     EasyMock.expect(mockConsumer.onStopConsumption()).andAnswer(
         new LoggedAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG, "stopConsumption() called"));
     EasyMock.replay(mockConsumer);
  }

  private void initMockStreamConsumer3OptEventFullLifecycle(DatabusStreamConsumer mockConsumer,
                                                         DbusEvent event1,
                                                         DbusEvent event2,
                                                         DbusEvent event3,
                                                         Hashtable<Long, AtomicInteger> keyCounts)
  {
    EasyMock.makeThreadSafe(mockConsumer, true);
     EasyMock.expect(mockConsumer.onStartConsumption()).andAnswer(
         new LoggedAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG,
             "startConsumption() called"));
     EasyMock.expect(mockConsumer.onStartDataEventSequence(null)).andAnswer(
         new LoggedAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG,
             "startDataEventSequence() called"));
     EasyMock.expect(mockConsumer.onStartSource("source1", null)).andAnswer(
         new LoggedAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG,
             "startDataEventSequence() called"));
     EasyMock.expect(mockConsumer.onDataEvent(event1, null)).andAnswer(new EventCountingAnswer<ConsumerCallbackResult>(
         ConsumerCallbackResult.SUCCESS,
         keyCounts.get(1L))).anyTimes();
     EasyMock.expect(mockConsumer.onEndSource("source1", null)).andAnswer(new LoggedAnswer<ConsumerCallbackResult>(
         ConsumerCallbackResult.SUCCESS,
         LOG,
         Level.DEBUG,
         "endDataEventSequence() called"));
     EasyMock.expect(mockConsumer.onStartSource("source3", null)).andAnswer(
         new LoggedAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG,
             "startDataEventSequence() called"));
     EasyMock.expect(mockConsumer.onDataEvent(event2, null)).andAnswer(new EventCountingAnswer<ConsumerCallbackResult>(
         ConsumerCallbackResult.SUCCESS,
         keyCounts.get(2L))).anyTimes();
     /*EasyMock.expect(mockConsumer.dataEvent(event3, null)).andAnswer(
         new EventCountingAnswer<Boolean>(true, keyCounts.get(3L))).anyTimes();*/
     EasyMock.expect(mockConsumer.onEndSource("source3", null)).andAnswer(
         new LoggedAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG,
             "endDataEventSequence() called"));
     EasyMock.expect(mockConsumer.onEndDataEventSequence(null)).andAnswer(
         new LoggedAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG,
             "endDataEventSequence() called"));
     EasyMock.expect(mockConsumer.onStopConsumption()).andAnswer(
         new LoggedAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG,
             "stopConsumption() called"));
     EasyMock.replay(mockConsumer);
  }

  private void initMockFailingStreamConsumer3OptEventFullLifecycle(
      DatabusStreamConsumer mockConsumer,
      DbusEvent event1,
      DbusEvent event2,
      DbusEvent event3,
      Hashtable<Long, AtomicInteger> keyCounts)
  {
    EasyMock.makeThreadSafe(mockConsumer, true);
     EasyMock.expect(mockConsumer.onStartConsumption()).andAnswer(
         new LoggedAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG, "startConsumption() called"));
     EasyMock.expect(mockConsumer.onStartDataEventSequence(null)).andAnswer(
         new LoggedAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG, "startDataEventSequence() called"));
     EasyMock.expect(mockConsumer.onStartSource("source1", null)).andAnswer(
         new LoggedAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG, "startDataEventSequence() called"));
     EasyMock.expect(mockConsumer.onDataEvent(event1, null)).andAnswer(
         new EventCountingAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.ERROR, keyCounts.get(1L))).anyTimes();
     EasyMock.expect(mockConsumer.onEndSource("source1", null)).andAnswer(new LoggedAnswer<ConsumerCallbackResult>(
         ConsumerCallbackResult.SUCCESS,
         LOG,
         Level.DEBUG,
         "endDataEventSequence() called")).times(0, 1);
     EasyMock.expect(mockConsumer.onStartSource("source3", null)).andAnswer(
         new LoggedAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG, "startDataEventSequence() called"));
     EasyMock.expect(mockConsumer.onDataEvent(event2, null)).andAnswer(
         new EventCountingAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, keyCounts.get(2L))).anyTimes();
     /*EasyMock.expect(mockConsumer.dataEvent(event3, null)).andAnswer(
         new EventCountingAnswer<Boolean>(true, keyCounts.get(3L))).anyTimes();*/
     EasyMock.expect(mockConsumer.onEndSource("source3", null)).andAnswer(
         new LoggedAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG, "endDataEventSequence() called"));
     EasyMock.expect(mockConsumer.onEndDataEventSequence(null)).andAnswer(
         new LoggedAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG, "endDataEventSequence() called"));
     EasyMock.expect(mockConsumer.onStopConsumption()).andAnswer(
         new LoggedAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG, "stopConsumption() called"));
     EasyMock.replay(mockConsumer);
  }

  private void initBufferWithEvents(DbusEventBuffer eventsBuf,
                                    long keyBase,
                                    int numEvents,
                                    short srcId,
                                    Hashtable<Long, AtomicInteger> keyCounts)
  {
    for (long i = 0; i < numEvents; ++i)
    {
      try {
        eventsBuf.appendEvent(new DbusEventKey(keyBase + i), (short) 0, (short)1, (short)0, srcId,
                              new byte[16], "value1".getBytes("UTF-8"), false);
      } catch (UnsupportedEncodingException e) {
        //ignore
      }
      keyCounts.put(keyBase + i, new AtomicInteger(0));
    }
  }

  private void assert3EventFullLifecycle(MultiConsumerCallback callback,
                                         DbusEvent event1, DbusEvent event2, DbusEvent event3)
  {
    assert ConsumerCallbackResult.isSuccess(callback.onStartConsumption()) : "startConsumption() failed";
    assert ConsumerCallbackResult.isSuccess(callback.onStartDataEventSequence(null)) : "startDataEventSequence() failed";
    assert ConsumerCallbackResult.isSuccess(callback.onStartSource("source1", null)) : "startSource(source1) failed";
    assert ConsumerCallbackResult.isSuccess(callback.onDataEvent(event1, null)) : "dataEvent() failed";
    assert ConsumerCallbackResult.isSuccess(callback.onEndSource("source1", null)) : "endsSource(source1) failed";
    assert ConsumerCallbackResult.isSuccess(callback.onStartSource("source3", null)) : "startSource(source3) failed";
    assert ConsumerCallbackResult.isSuccess(callback.onDataEvent(event2, null)) : "dataEvent() failed";
    assert ConsumerCallbackResult.isSuccess(callback.onDataEvent(event3, null)) : "dataEvent() failed";
    assert ConsumerCallbackResult.isSuccess(callback.onEndSource("source3", null)) : "endsSource(source3) failed";
    assert ConsumerCallbackResult.isSuccess(callback.onEndDataEventSequence(null)) : "endDataEventSequence() failed";
    assert ConsumerCallbackResult.isSuccess(callback.onStopConsumption()) : "stopConsumption() failed";
  }

  private void assert3EventFullLifecycleWithFailure(
      MultiConsumerCallback callback,
      DbusEvent event1, DbusEvent event2, DbusEvent event3)
  {
    assert ConsumerCallbackResult.isSuccess(callback.onStartConsumption()) : "startConsumption() failed";
    assert ConsumerCallbackResult.isSuccess(callback.onStartDataEventSequence(null)) : "startDataEventSequence() failed";
    assert ConsumerCallbackResult.isSuccess(callback.onStartSource("source1", null)) : "startSource(source1) failed";
    boolean dataEventSuccess = !ConsumerCallbackResult.isSuccess(callback.onDataEvent(event1, null));
    boolean endSourceSuccess = ConsumerCallbackResult.isSuccess(callback.onEndSource("source1", null));
    //either onDataEvent should fail immediately or the next (barrier) call will
    assert (!dataEventSuccess || !endSourceSuccess) : "dataEvent() failed";
    assert ConsumerCallbackResult.isSuccess(callback.onStartSource("source3", null)) : "startSource(source3) failed";
    assert ConsumerCallbackResult.isSuccess(callback.onDataEvent(event2, null)) : "dataEvent() failed";
    assert ConsumerCallbackResult.isSuccess(callback.onDataEvent(event3, null)) : "dataEvent() failed";
    assert ConsumerCallbackResult.isSuccess(callback.onEndSource("source3", null)) : "endsSource(source3) failed";
    assert ConsumerCallbackResult.isSuccess(callback.onEndDataEventSequence(null)) : "endDataEventSequence() failed";
    assert ConsumerCallbackResult.isSuccess(callback.onStopConsumption()) : "stopConsumption() failed";
  }

  @Test
  public void testPerf() throws Exception
  {
    LOG.info("\n\nstarting testPerf()");

    List<String> sources = new ArrayList<String>();
    Map<Long, IdNamePair> sourcesMap = new HashMap<Long, IdNamePair>();
    for (int i = 1; i <= 3; ++i)
    {
      IdNamePair sourcePair = new IdNamePair((long)i, "source" + i);
      sources.add(sourcePair.getName());
      sourcesMap.put(sourcePair.getId(), sourcePair);
    }

    Hashtable<Long, AtomicInteger> keyCounts = new Hashtable<Long, AtomicInteger>();

    DbusEventBuffer eventsBuf = new DbusEventBuffer(_generic100KBufferStaticConfig);
    eventsBuf.start(0);
    eventsBuf.startEvents();
    initBufferWithEvents(eventsBuf, 1, 1, (short)1, keyCounts);
    initBufferWithEvents(eventsBuf, 2, 2, (short)3, keyCounts);
    eventsBuf.endEvents(100L);

    DbusEventBuffer.DbusEventIterator iter = eventsBuf.acquireIterator("myIter1");
    assert iter.hasNext() : "unable to read event";
    iter.next();
    DbusEvent event1 = iter.next();

    DatabusStreamConsumer logConsumer = new LoggingConsumer();
    SelectingDatabusCombinedConsumer sdccLogConsumer = new SelectingDatabusCombinedConsumer(logConsumer);

    DatabusV2ConsumerRegistration consumerReg =
        new DatabusV2ConsumerRegistration(sdccLogConsumer, sources, null);
    ConsumerCallbackStats consumerStatsCollector = new ConsumerCallbackStats(1, "test","test", true,false, null);
    UnifiedClientStats unifiedStatsCollector = new UnifiedClientStats(1, "test","test.unified");

    List<DatabusV2ConsumerRegistration> allRegistrations =
        Arrays.asList(consumerReg);
    ThreadPoolExecutor executor = (ThreadPoolExecutor)Executors.newCachedThreadPool();
    MultiConsumerCallback callback =
        new MultiConsumerCallback(
            allRegistrations,
            executor,
            60000,
            new StreamConsumerCallbackFactory(consumerStatsCollector, unifiedStatsCollector),
            consumerStatsCollector,
            unifiedStatsCollector,
            null,
            null);
    callback.setSourceMap(sourcesMap);

    callback.onStartConsumption();
    callback.onStartDataEventSequence(new SingleSourceSCN(1, 1));
    for (int i = 0; i < 10000; ++i)
    {
      callback.onDataEvent(event1, null);
    }
    callback.onEndDataEventSequence(new SingleSourceSCN(1, 1));
    callback.onStopConsumption();

    System.out.println("max threads=" + executor.getLargestPoolSize() + " task count=" + executor.getTaskCount());
    System.out.println("dataEventsReceived=" + consumerStatsCollector.getNumDataEventsReceived() +
                       " sysEventsReceived=" + consumerStatsCollector.getNumSysEventsReceived()  +
                       " dataEventsProcessed=" + consumerStatsCollector.getNumDataEventsProcessed() +
                       " latencyEventsProcessed=" + consumerStatsCollector.getLatencyEventsProcessed());
    long dataEvents = consumerStatsCollector.getNumDataEventsReceived();
    assert(consumerStatsCollector.getNumDataEventsProcessed()==dataEvents);

  }

  @Test(groups = {"small", "functional"})
  public void test1StreamConsumerHappyPath()
  {
    LOG.info("\n\nstarting test1StreamConsumerHappyPath()");

    Hashtable<Long, AtomicInteger> keyCounts = new Hashtable<Long, AtomicInteger>();

    DbusEventBuffer eventsBuf = new DbusEventBuffer(_generic100KBufferStaticConfig);
    eventsBuf.start(0);
    eventsBuf.startEvents();
    initBufferWithEvents(eventsBuf, 1, 1, (short)1, keyCounts);
    initBufferWithEvents(eventsBuf, 2, 2, (short) 3, keyCounts);
    eventsBuf.endEvents(100L);

    DatabusStreamConsumer mockConsumer = EasyMock.createStrictMock(DatabusStreamConsumer.class);
    SelectingDatabusCombinedConsumer sdccMockConsumer = new SelectingDatabusCombinedConsumer(mockConsumer);

    List<String> sources = new ArrayList<String>();
    Map<Long, IdNamePair> sourcesMap = new HashMap<Long, IdNamePair>();
    for (int i = 1; i <= 3; ++i)
    {
      IdNamePair sourcePair = new IdNamePair((long)i, "source" + i);
      sources.add(sourcePair.getName());
      sourcesMap.put(sourcePair.getId(), sourcePair);
    }

    DatabusV2ConsumerRegistration consumerReg =
        new DatabusV2ConsumerRegistration(sdccMockConsumer, sources, null);

    List<DatabusV2ConsumerRegistration> allRegistrations =
        Arrays.asList(consumerReg);
    MultiConsumerCallback callback =
        new MultiConsumerCallback(
            allRegistrations,
            Executors.newCachedThreadPool(),
            60000,
            new StreamConsumerCallbackFactory(null, null),
            null,
            null,
            null,
            null);
    callback.setSourceMap(sourcesMap);

    DbusEventBuffer.DbusEventIterator iter = eventsBuf.acquireIterator("myIter1");
    assert iter.hasNext() : "unable to read event";
    DbusEvent event1 = iter.next();
    assert iter.hasNext() : "unable to read event";
    DbusEvent event2 = iter.next();
    assert iter.hasNext() : "unable to read event";
    DbusEvent event3 = iter.next();

    initMockStreamConsumer3EventFullLifecycle(mockConsumer, event1, event2, event3, keyCounts);

    assert3EventFullLifecycle(callback, event1, event2, event3);

    EasyMock.verify(mockConsumer);
    assert keyCounts.get(1L).get() == 1 : "invalid number of event(1) calls: " + keyCounts.get(1L).get();
    assert keyCounts.get(2L).get() == 1 : "invalid number of event(2) calls:" + keyCounts.get(2L).get();
    assert keyCounts.get(3L).get() == 1 : "invalid number of event(3) calls:" + keyCounts.get(3L).get();
  }

  @Test(groups = {"small", "functional"})
  public void test1StreamConsumerCallFailure()
  {
    LOG.info("\n\nstarting test1StreamConsumerCallFailure()");

    Hashtable<Long, AtomicInteger> keyCounts = new Hashtable<Long, AtomicInteger>();

    DbusEventBuffer eventsBuf = new DbusEventBuffer(_generic100KBufferStaticConfig);
    eventsBuf.start(0);
    eventsBuf.startEvents();
    initBufferWithEvents(eventsBuf, 1, 1, (short)1, keyCounts);
    initBufferWithEvents(eventsBuf, 2, 2, (short)3, keyCounts);
    eventsBuf.endEvents(100L);

    DatabusStreamConsumer mockConsumer = EasyMock.createStrictMock(DatabusStreamConsumer.class);
    SelectingDatabusCombinedConsumer sdccMockConsumer = new SelectingDatabusCombinedConsumer(mockConsumer);

    List<String> sources = new ArrayList<String>();
    Map<Long, IdNamePair> sourcesMap = new HashMap<Long, IdNamePair>();
    for (int i = 1; i <= 3; ++i)
    {
      IdNamePair sourcePair = new IdNamePair((long)i, "source" + i);
      sources.add(sourcePair.getName());
      sourcesMap.put(sourcePair.getId(), sourcePair);
    }

    DatabusV2ConsumerRegistration consumerReg =
        new DatabusV2ConsumerRegistration(sdccMockConsumer, sources, null);

    List<DatabusV2ConsumerRegistration> allRegistrations =
        Arrays.asList(consumerReg);
    MultiConsumerCallback callback =
        new MultiConsumerCallback(
            allRegistrations,
            Executors.newCachedThreadPool(),
            1000,
            new StreamConsumerCallbackFactory(null, null),
            null,
            null,
            null,
            null);
    callback.setSourceMap(sourcesMap);

    DbusEventBuffer.DbusEventIterator iter = eventsBuf.acquireIterator("myIter1");
    assert iter.hasNext() : "unable to read event";
    DbusEvent event1 = iter.next();
    assert iter.hasNext() : "unable to read event";
    DbusEvent event2 = iter.next();
    assert iter.hasNext() : "unable to read event";
    DbusEvent event3 = iter.next();

    initMockFailingStreamConsumer3EventFullLifecycle(mockConsumer, event1, event2, event3, keyCounts);

    assert3EventFullLifecycleWithFailure(callback, event1, event2, event3);

    EasyMock.verify(mockConsumer);
    assert keyCounts.get(1L).get() == 1 : "invalid number of event(1) calls: " + keyCounts.get(1L).get();
    assert keyCounts.get(2L).get() == 1 : "invalid number of event(2) calls:" + keyCounts.get(2L).get();
    assert keyCounts.get(3L).get() == 1 : "invalid number of event(3) calls:" + keyCounts.get(3L).get();
  }

  // Test the cases where the application throws some random exception (or times out), and make
  // sure we field it correctly and return ERROR.
  @Test(groups = {"small", "functional"})
  public void testConsumersWithException()
  {
    LOG.info("\n\nstarting testConsumersWithException()");

    testConsumersWithException(new SomeApplicationException());
    testConsumersWithException(new TimeoutException("Application timed out processing some call but refused to field it"));
  }

  private void testConsumersWithException(Throwable exception)
  {
    Hashtable<Long, AtomicInteger> keyCounts = new Hashtable<Long, AtomicInteger>();

    DbusEventBuffer eventsBuf = new DbusEventBuffer(_generic100KBufferStaticConfig);
    eventsBuf.start(0);
    eventsBuf.startEvents();
    initBufferWithEvents(eventsBuf, 1, 1, (short)1, keyCounts);
    initBufferWithEvents(eventsBuf, 2, 2, (short)3, keyCounts);
    eventsBuf.endEvents(100L);

    DatabusStreamConsumer mockConsumer = EasyMock.createStrictMock(DatabusStreamConsumer.class);
    SelectingDatabusCombinedConsumer sdccMockConsumer = new SelectingDatabusCombinedConsumer(mockConsumer);

    List<String> sources = new ArrayList<String>();
    Map<Long, IdNamePair> sourcesMap = new HashMap<Long, IdNamePair>();
    for (int i = 1; i <= 3; ++i)
    {
      IdNamePair sourcePair = new IdNamePair((long)i, "source" + i);
      sources.add(sourcePair.getName());
      sourcesMap.put(sourcePair.getId(), sourcePair);
    }

    DatabusV2ConsumerRegistration consumerReg =
        new DatabusV2ConsumerRegistration(sdccMockConsumer, sources, null);

    List<DatabusV2ConsumerRegistration> allRegistrations =
        Arrays.asList(consumerReg);
    MultiConsumerCallback callback =
        new MultiConsumerCallback(
            allRegistrations,
            Executors.newCachedThreadPool(),
            1000,
            new StreamConsumerCallbackFactory(null, null),
            null,
            null,
            null,
            null);
    callback.setSourceMap(sourcesMap);

    DbusEventBuffer.DbusEventIterator iter = eventsBuf.acquireIterator("myIter1");
    assert iter.hasNext() : "unable to read event";
    DbusEvent event1 = iter.next();
    assert iter.hasNext() : "unable to read event";
    DbusEvent event2 = iter.next();
    assert iter.hasNext() : "unable to read event";
    DbusEvent event3 = iter.next();

    initMockExceptionStreamConsumer3EventFullLifecycle(mockConsumer, event1, event2, event3, keyCounts, exception);

    assert3EventFullLifecycleWithFailure(callback, event1, event2, event3);

    EasyMock.verify(mockConsumer);
//    assert keyCounts.get(1L).get() == 1 : "invalid number of event(1) calls: " + keyCounts.get(1L).get();
    assert keyCounts.get(2L).get() == 1 : "invalid number of event(2) calls:" + keyCounts.get(2L).get();
    assert keyCounts.get(3L).get() == 1 : "invalid number of event(3) calls:" + keyCounts.get(3L).get();
  }

  @Test(groups = {"small", "functional"})
  public void test3IndependentStreamConsumersHappyPath()
  {
    LOG.info("\n\nstarting test3IndependentStreamConsumersHappyPath()");

    Hashtable<Long, AtomicInteger> keyCounts = new Hashtable<Long, AtomicInteger>();

    DbusEventBuffer eventsBuf = new DbusEventBuffer(_generic100KBufferStaticConfig);
    eventsBuf.start(0);
    eventsBuf.startEvents();
    initBufferWithEvents(eventsBuf, 1, 1, (short)1, keyCounts);
    initBufferWithEvents(eventsBuf, 2, 2, (short)3, keyCounts);
    eventsBuf.endEvents(100L);

    DatabusStreamConsumer mockConsumer1 = EasyMock.createStrictMock("consumer1",
                                                                    DatabusStreamConsumer.class);
    SelectingDatabusCombinedConsumer sdccMockConsumer1 = new SelectingDatabusCombinedConsumer(mockConsumer1);
    EasyMock.makeThreadSafe(mockConsumer1, true);

    DatabusStreamConsumer mockConsumer2 = EasyMock.createStrictMock("consumer2",
                                                                    DatabusStreamConsumer.class);
    SelectingDatabusCombinedConsumer sdccMockConsumer2 = new SelectingDatabusCombinedConsumer(mockConsumer2);
    EasyMock.makeThreadSafe(mockConsumer2, true);

    DatabusStreamConsumer mockConsumer3 = EasyMock.createStrictMock("consumer3",
                                                                    DatabusStreamConsumer.class);
    SelectingDatabusCombinedConsumer sdccMockConsumer3 = new SelectingDatabusCombinedConsumer(mockConsumer3);
    EasyMock.makeThreadSafe(mockConsumer3, true);

    List<String> sources = new ArrayList<String>();
    Map<Long, IdNamePair> sourcesMap = new HashMap<Long, IdNamePair>();
    for (int i = 1; i <= 3; ++i)
    {
      IdNamePair sourcePair = new IdNamePair((long)i, "source" + i);
      sources.add(sourcePair.getName());
      sourcesMap.put(sourcePair.getId(), sourcePair);
    }

    DatabusV2ConsumerRegistration consumerReg1 =
        new DatabusV2ConsumerRegistration(sdccMockConsumer1, sources, null);
    DatabusV2ConsumerRegistration consumerReg2 =
      new DatabusV2ConsumerRegistration(sdccMockConsumer2, sources, null);
    DatabusV2ConsumerRegistration consumerReg3 =
      new DatabusV2ConsumerRegistration(sdccMockConsumer3, sources, null);

    List<DatabusV2ConsumerRegistration> allRegistrations =
        Arrays.asList(consumerReg1, consumerReg2, consumerReg3);
    MultiConsumerCallback callback =
        new MultiConsumerCallback(
            allRegistrations,
            Executors.newCachedThreadPool(),
            1000,
            new StreamConsumerCallbackFactory(null, null),
            null,
            null,
            null,
            null);
    callback.setSourceMap(sourcesMap);

    DbusEventBuffer.DbusEventIterator iter = eventsBuf.acquireIterator("myIter1");
    assert iter.hasNext() : "unable to read event";
    DbusEvent event1 = iter.next();
    assert iter.hasNext() : "unable to read event";
    DbusEvent event2 = iter.next();
    assert iter.hasNext() : "unable to read event";
    DbusEvent event3 = iter.next();

    initMockStreamConsumer3EventFullLifecycle(mockConsumer1, event1, event2, event3, keyCounts);
    initMockStreamConsumer3EventFullLifecycle(mockConsumer2, event1, event2, event3, keyCounts);
    initMockStreamConsumer3EventFullLifecycle(mockConsumer3, event1, event2, event3, keyCounts);

    assert3EventFullLifecycle(callback, event1, event2, event3);

    EasyMock.verify(mockConsumer1);
    EasyMock.verify(mockConsumer2);
    EasyMock.verify(mockConsumer3);

    assert keyCounts.get(1L).get() == 3 : "invalid number of event(1) calls: " + keyCounts.get(1L).get();
    assert keyCounts.get(2L).get() == 3 : "invalid number of event(2) calls:" + keyCounts.get(2L).get();
    assert keyCounts.get(3L).get() == 3 : "invalid number of event(3) calls:" + keyCounts.get(3L).get();
  }

  @Test(groups = {"small", "functional"})
  public void test3IndependentStreamConsumersWithFailure()
  {
    LOG.info("\n\nstarting test3IndependentStreamConsumersWithFailure()");

    Hashtable<Long, AtomicInteger> keyCounts = new Hashtable<Long, AtomicInteger>();

    DbusEventBuffer eventsBuf = new DbusEventBuffer(_generic100KBufferStaticConfig);
    eventsBuf.start(0);
    eventsBuf.startEvents();
    initBufferWithEvents(eventsBuf, 1, 1, (short)1, keyCounts);
    initBufferWithEvents(eventsBuf, 2, 2, (short)3, keyCounts);
    eventsBuf.endEvents(100L);

    DatabusStreamConsumer mockConsumer1 = EasyMock.createStrictMock("consumer1",
                                                                    DatabusStreamConsumer.class);
    EasyMock.makeThreadSafe(mockConsumer1, true);
    DatabusStreamConsumer mockConsumer2 = EasyMock.createStrictMock("consumer2",
                                                                    DatabusStreamConsumer.class);
    EasyMock.makeThreadSafe(mockConsumer2, true);
    DatabusStreamConsumer mockConsumer3 = EasyMock.createStrictMock("consumer3",
                                                                    DatabusStreamConsumer.class);
    EasyMock.makeThreadSafe(mockConsumer3, true);

    SelectingDatabusCombinedConsumer sdccMockConsumer1 = new SelectingDatabusCombinedConsumer(mockConsumer1);
    SelectingDatabusCombinedConsumer sdccMockConsumer2 = new SelectingDatabusCombinedConsumer(mockConsumer2);
    SelectingDatabusCombinedConsumer sdccMockConsumer3 = new SelectingDatabusCombinedConsumer(mockConsumer3);

    List<String> sources = new ArrayList<String>();
    Map<Long, IdNamePair> sourcesMap = new HashMap<Long, IdNamePair>();
    for (int i = 1; i <= 3; ++i)
    {
      IdNamePair sourcePair = new IdNamePair((long)i, "source" + i);
      sources.add(sourcePair.getName());
      sourcesMap.put(sourcePair.getId(), sourcePair);
    }

    DatabusV2ConsumerRegistration consumerReg1 =
        new DatabusV2ConsumerRegistration(sdccMockConsumer1, sources, null);
    DatabusV2ConsumerRegistration consumerReg2 =
      new DatabusV2ConsumerRegistration(sdccMockConsumer2, sources, null);
    DatabusV2ConsumerRegistration consumerReg3 =
      new DatabusV2ConsumerRegistration(sdccMockConsumer3, sources, null);

    List<DatabusV2ConsumerRegistration> allRegistrations =
        Arrays.asList(consumerReg1, consumerReg2, consumerReg3);
    MultiConsumerCallback callback =
        new MultiConsumerCallback(
            allRegistrations,
            Executors.newCachedThreadPool(),
            1000,
            new StreamConsumerCallbackFactory(null, null),
            null,
            null,
            null,
            null);
    callback.setSourceMap(sourcesMap);

    DbusEventBuffer.DbusEventIterator iter = eventsBuf.acquireIterator("myIter1");
    assert iter.hasNext() : "unable to read event";
    DbusEvent event1 = iter.next();
    assert iter.hasNext() : "unable to read event";
    DbusEvent event2 = iter.next();
    assert iter.hasNext() : "unable to read event";
    DbusEvent event3 = iter.next();

    initMockStreamConsumer3EventFullLifecycle(mockConsumer1, event1, event2, event3, keyCounts);
    initMockFailingStreamConsumer3EventFullLifecycle(mockConsumer2, event1, event2, event3, keyCounts);
    initMockStreamConsumer3EventFullLifecycle(mockConsumer3, event1, event2, event3, keyCounts);

    assert3EventFullLifecycleWithFailure(callback, event1, event2, event3);

    EasyMock.verify(mockConsumer1);
    EasyMock.verify(mockConsumer2);
    EasyMock.verify(mockConsumer3);

    assert keyCounts.get(1L).get() == 3 : "invalid number of event(1) calls: " + keyCounts.get(1L).get();
    assert keyCounts.get(2L).get() == 3 : "invalid number of event(2) calls:" + keyCounts.get(2L).get();
    assert keyCounts.get(3L).get() == 3 : "invalid number of event(3) calls:" + keyCounts.get(3L).get();
  }

  @Test(groups = {"small", "functional"})
  public void test3GroupedStreamConsumersHappyPath()
  {
    LOG.info("\n\nstarting test3GroupedStreamConsumersHappyPath()");

    Hashtable<Long, AtomicInteger> keyCounts = new Hashtable<Long, AtomicInteger>();

    DbusEventBuffer eventsBuf = new DbusEventBuffer(_generic100KBufferStaticConfig);
    eventsBuf.start(0);
    eventsBuf.startEvents();
    initBufferWithEvents(eventsBuf, 1, 1, (short)1, keyCounts);
    initBufferWithEvents(eventsBuf, 2, 2, (short)3, keyCounts);
    eventsBuf.endEvents(100L);

    DatabusStreamConsumer mockConsumer1 = EasyMock.createStrictMock("consumer1",
                                                                    DatabusStreamConsumer.class);
    EasyMock.makeThreadSafe(mockConsumer1, true);
    DatabusStreamConsumer mockConsumer2 = EasyMock.createStrictMock("consumer2",
                                                                    DatabusStreamConsumer.class);
    EasyMock.makeThreadSafe(mockConsumer2, true);
    DatabusStreamConsumer mockConsumer3 = EasyMock.createStrictMock("consumer3",
                                                                    DatabusStreamConsumer.class);
    EasyMock.makeThreadSafe(mockConsumer3, true);

    DatabusCombinedConsumer sdccMockConsumer1 = new SelectingDatabusCombinedConsumer(mockConsumer1);
    DatabusCombinedConsumer sdccMockConsumer2 = new SelectingDatabusCombinedConsumer(mockConsumer2);
    DatabusCombinedConsumer sdccMockConsumer3 = new SelectingDatabusCombinedConsumer(mockConsumer3);

    List<String> sources = new ArrayList<String>();
    Map<Long, IdNamePair> sourcesMap = new HashMap<Long, IdNamePair>();
    for (int i = 1; i <= 3; ++i)
    {
      IdNamePair sourcePair = new IdNamePair((long)i, "source" + i);
      sources.add(sourcePair.getName());
      sourcesMap.put(sourcePair.getId(), sourcePair);
    }

    DatabusV2ConsumerRegistration consumerReg1 =
        new DatabusV2ConsumerRegistration(
            Arrays.asList(sdccMockConsumer1, sdccMockConsumer2, sdccMockConsumer3), sources, null);

    List<DatabusV2ConsumerRegistration> allRegistrations =
        Arrays.asList(consumerReg1);
    MultiConsumerCallback callback =
        new MultiConsumerCallback(
            allRegistrations,
            Executors.newCachedThreadPool(),
            1000,
            new StreamConsumerCallbackFactory(null, null),
            null,
            null,
            null,
            null);
    callback.setSourceMap(sourcesMap);

    DbusEventBuffer.DbusEventIterator iter = eventsBuf.acquireIterator("myIter1");
    assert iter.hasNext() : "unable to read event";
    DbusEvent event1 = iter.next();
    assert iter.hasNext() : "unable to read event";
    DbusEvent event2 = iter.next();
    assert iter.hasNext() : "unable to read event";
    DbusEvent event3 = iter.next();

    initMockStreamConsumer3OptEventFullLifecycle(mockConsumer1, event1, event2, event3, keyCounts);
    initMockStreamConsumer3OptEventFullLifecycle(mockConsumer2, event1, event2, event3, keyCounts);
    initMockStreamConsumer3OptEventFullLifecycle(mockConsumer3, event1, event2, event3, keyCounts);

    assert3EventFullLifecycle(callback, event1, event2, event3);

    EasyMock.verify(mockConsumer1);
    EasyMock.verify(mockConsumer2);
    EasyMock.verify(mockConsumer3);

    assert (keyCounts.get(1L).get() + keyCounts.get(2L).get() + keyCounts.get(3L).get()) == 3
           : "invalid number of calls: " + keyCounts.get(1L).get() + "," + keyCounts.get(2L).get()
           + "," + keyCounts.get(3L).get();
  }

  @Test(groups = {"small", "functional"})
  public void test3GroupedStreamConsumersWithFailure()
  {
    LOG.info("\n\nstarting test3GroupedStreamConsumersWithFailure()");

    Hashtable<Long, AtomicInteger> keyCounts = new Hashtable<Long, AtomicInteger>();

    DbusEventBuffer eventsBuf = new DbusEventBuffer(_generic100KBufferStaticConfig);
    eventsBuf.start(0);
    eventsBuf.startEvents();
    initBufferWithEvents(eventsBuf, 1, 1, (short)1, keyCounts);
    initBufferWithEvents(eventsBuf, 2, 2, (short)3, keyCounts);
    eventsBuf.endEvents(100L);

    DatabusStreamConsumer mockConsumer1 = EasyMock.createStrictMock("consumer1",
                                                                    DatabusStreamConsumer.class);
    EasyMock.makeThreadSafe(mockConsumer1, true);
    DatabusStreamConsumer mockConsumer2 = EasyMock.createStrictMock("consumer2",
                                                                    DatabusStreamConsumer.class);
    EasyMock.makeThreadSafe(mockConsumer2, true);
    DatabusStreamConsumer mockConsumer3 = EasyMock.createStrictMock("consumer3",
                                                                    DatabusStreamConsumer.class);
    EasyMock.makeThreadSafe(mockConsumer3, true);

    DatabusCombinedConsumer sdccMockConsumer1 = new SelectingDatabusCombinedConsumer(mockConsumer1);
    DatabusCombinedConsumer sdccMockConsumer2 = new SelectingDatabusCombinedConsumer(mockConsumer2);
    DatabusCombinedConsumer sdccMockConsumer3 = new SelectingDatabusCombinedConsumer(mockConsumer3);

    List<String> sources = new ArrayList<String>();
    Map<Long, IdNamePair> sourcesMap = new HashMap<Long, IdNamePair>();
    for (int i = 1; i <= 3; ++i)
    {
      IdNamePair sourcePair = new IdNamePair((long)i, "source" + i);
      sources.add(sourcePair.getName());
      sourcesMap.put(sourcePair.getId(), sourcePair);
    }

    DatabusV2ConsumerRegistration consumerReg1 =
        new DatabusV2ConsumerRegistration(
            Arrays.asList(sdccMockConsumer1, sdccMockConsumer2, sdccMockConsumer3), sources, null);

    List<DatabusV2ConsumerRegistration> allRegistrations =
        Arrays.asList(consumerReg1);
    MultiConsumerCallback callback =
        new MultiConsumerCallback(
            allRegistrations,
            Executors.newCachedThreadPool(),
            1000,
            new StreamConsumerCallbackFactory(null, null),
            null,
            null,
            null,
            null);
    callback.setSourceMap(sourcesMap);

    DbusEventBuffer.DbusEventIterator iter = eventsBuf.acquireIterator("myIter1");
    assert iter.hasNext() : "unable to read event";
    DbusEvent event1 = iter.next();
    assert iter.hasNext() : "unable to read event";
    DbusEvent event2 = iter.next();
    assert iter.hasNext() : "unable to read event";
    DbusEvent event3 = iter.next();

    initMockFailingStreamConsumer3OptEventFullLifecycle(mockConsumer1, event1, event2, event3,
                                                        keyCounts);
    initMockFailingStreamConsumer3OptEventFullLifecycle(mockConsumer2, event1, event2, event3,
                                                        keyCounts);
    initMockFailingStreamConsumer3OptEventFullLifecycle(mockConsumer3, event1, event2, event3,
                                                        keyCounts);

    assert3EventFullLifecycleWithFailure(callback, event1, event2, event3);

    EasyMock.verify(mockConsumer1);
    EasyMock.verify(mockConsumer2);
    EasyMock.verify(mockConsumer3);

    assert (keyCounts.get(1L).get() + keyCounts.get(2L).get() + keyCounts.get(3L).get()) == 3
           : "invalid number of calls: " + keyCounts.get(1L).get() + "," + keyCounts.get(2L).get()
           + "," + keyCounts.get(3L).get();
  }

  @Test
  public void test1ConsumerTimeout()
  {
    LOG.info("\n\nstarting test1ConsumerTimeout()");

    //create dummy events
    Hashtable<Long, AtomicInteger> keyCounts = new Hashtable<Long, AtomicInteger>();

    DbusEventBuffer eventsBuf = new DbusEventBuffer(_generic100KBufferStaticConfig);
    eventsBuf.start(0);
    eventsBuf.startEvents();
    initBufferWithEvents(eventsBuf, 1, 2, (short)1, keyCounts);
    initBufferWithEvents(eventsBuf, 3, 1, (short)2, keyCounts);
    eventsBuf.endEvents(100L);

    DbusEventBuffer.DbusEventIterator iter = eventsBuf.acquireIterator("myIter1");
    Assert.assertTrue(iter.hasNext(), "unable to read event");
    iter.next(); //skip over the first system event
    Assert.assertTrue(iter.hasNext(), "unable to read event");
    DbusEvent event1 = iter.next().createCopy();
    Assert.assertTrue(iter.hasNext(), "unable to read event");
    DbusEvent event2 = iter.next().createCopy();
    Assert.assertTrue(iter.hasNext(), "unable to read event");
    DbusEvent event3 = iter.next().createCopy();

    //make up some sources
    List<String> sources = new ArrayList<String>();
    Map<Long, IdNamePair> sourcesMap = new HashMap<Long, IdNamePair>();
    for (int i = 1; i <= 3; ++i)
    {
      IdNamePair sourcePair = new IdNamePair((long)i, "source" + i);
      sources.add(sourcePair.getName());
      sourcesMap.put(sourcePair.getId(), sourcePair);
    }

    //create the consumer mock up
    DatabusStreamConsumer mockConsumer1 = EasyMock.createStrictMock("consumer1",
                                                                    DatabusStreamConsumer.class);
    SelectingDatabusCombinedConsumer sdccMockConsumer1 = new SelectingDatabusCombinedConsumer(mockConsumer1);
    EasyMock.makeThreadSafe(mockConsumer1, true);

    DatabusV2ConsumerRegistration consumerReg =
        new DatabusV2ConsumerRegistration(sdccMockConsumer1, sources, null);

    EasyMock.expect(mockConsumer1.onStartConsumption()).andAnswer(
        new SleepingAnswer<ConsumerCallbackResult>(new LoggedAnswer<ConsumerCallbackResult>(
            ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG, "startConsumption() called"),
            150));
    EasyMock.expect(mockConsumer1.onStartDataEventSequence(null)).andAnswer(
        new SleepingAnswer<ConsumerCallbackResult>(new LoggedAnswer<ConsumerCallbackResult>(
            ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG, "onStartDataEventSequence() called"),
            110));
    EasyMock.expect(mockConsumer1.onStartSource("source1", null)).andAnswer(
        new SleepingAnswer<ConsumerCallbackResult>(
            new LoggedAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, LOG,
                                                     Level.DEBUG,
                                                     "onStartSource() called"),
            40));
    EasyMock.expect(mockConsumer1.onDataEvent(event1, null)).andAnswer(
        new SleepingAnswer<ConsumerCallbackResult>(
            new LoggedAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG,
                                                    "onDataEvet(1) called"),
           50));
    EasyMock.expect(mockConsumer1.onDataEvent(event2, null)).andAnswer(
        new SleepingAnswer<ConsumerCallbackResult>(
            new LoggedAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG,
                                                    "onDataEvet(2) called"),
           210));
    EasyMock.expect(mockConsumer1.onDataEvent(event1, null)).andAnswer(
        new SleepingAnswer<ConsumerCallbackResult>(
            new LoggedAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG,
                                                     "onDataEvet(1) called"),
            40));
    EasyMock.expect(mockConsumer1.onEndSource("source1", null)).andAnswer(
        new SleepingAnswer<ConsumerCallbackResult>(
            new LoggedAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG,
                                                     "onStartSource() called"),
            50));
    EasyMock.replay(mockConsumer1);
    ConsumerCallbackStats consumerStatsCollector = new ConsumerCallbackStats(1, "test","test", true,false, null);
    UnifiedClientStats unifiedStatsCollector = new UnifiedClientStats(1, "test","test.unified");

    //Create and fire up callbacks
    List<DatabusV2ConsumerRegistration> allRegistrations =
        Arrays.asList(consumerReg);
    MultiConsumerCallback callback =
        new MultiConsumerCallback(
            allRegistrations,
            Executors.newCachedThreadPool(),
            100,
            new StreamConsumerCallbackFactory(consumerStatsCollector, unifiedStatsCollector),
            consumerStatsCollector,
            unifiedStatsCollector,
            null,
            null);
    callback.setSourceMap(sourcesMap);

    ConsumerCallbackResult startConsumptionRes = callback.onStartConsumption();
    Assert.assertTrue(ConsumerCallbackResult.isFailure(startConsumptionRes),
                      "startConsumption() failed");
    ConsumerCallbackResult startWindowRes = callback.onStartDataEventSequence(null);
    Assert.assertTrue(ConsumerCallbackResult.isFailure(startWindowRes),
                      "startDataEventSequence() failed");
    ConsumerCallbackResult startSourceRes = callback.onStartSource("source1", null);
    Assert.assertTrue(ConsumerCallbackResult.isSuccess(startSourceRes),
                      "startSources(source1) succeeded");
    ConsumerCallbackResult event1Res = callback.onDataEvent(event1, null);
    Assert.assertTrue(ConsumerCallbackResult.isSuccess(event1Res),
                      "onDataEvent(1) succeeded");
    ConsumerCallbackResult event2Res = callback.onDataEvent(event2, null);
    Assert.assertTrue(ConsumerCallbackResult.isSuccess(event2Res),
                       "onDataEvent(2) queued up");
    ConsumerCallbackResult event3Res = callback.onDataEvent(event1, null);
    Assert.assertTrue(ConsumerCallbackResult.isSuccess(event3Res),
                      "onDataEvent(1) queued up");
    ConsumerCallbackResult endSourceRes = callback.onEndSource("source1", null);
    Assert.assertTrue(ConsumerCallbackResult.isFailure(endSourceRes),
                       "onEndSource fails because of timeout in onDataEvent(2)");

    EasyMock.reset(mockConsumer1);
    EasyMock.makeThreadSafe(mockConsumer1, true);
    EasyMock.expect(mockConsumer1.onStartSource("source2", null)).andAnswer(
        new SleepingAnswer<ConsumerCallbackResult>(
            new LoggedAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG,
                                                     "onStartSource() called"),
            150)).times(0, 1);
    EasyMock.expect(mockConsumer1.onDataEvent(event3, null)).andAnswer(
        new SleepingAnswer<ConsumerCallbackResult>(
            new LoggedAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG,
                                                     "onDataEvet(3) called"),
        40));
    EasyMock.expect(mockConsumer1.onEndSource("source2", null)).andAnswer(
        new SleepingAnswer<ConsumerCallbackResult>(
            new LoggedAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG,
                                                     "onStartSource() called"),
        60));
    EasyMock.replay(mockConsumer1);


    startSourceRes = callback.onStartSource("source2", null);
    Assert.assertTrue(ConsumerCallbackResult.isFailure(startSourceRes),
        "startSources(source2) fails");

    event1Res = callback.onDataEvent(event3, null);
    Assert.assertTrue(ConsumerCallbackResult.isSuccess(event1Res),
                      "onDataEvent(3) succeeded");
    endSourceRes = callback.onEndSource("source2", null);
    Assert.assertTrue(ConsumerCallbackResult.isSuccess(endSourceRes),
                       "onEndSource succeeds");

    long eventsErrProcessed = consumerStatsCollector.getNumErrorsProcessed();
    long totalEvents  = consumerStatsCollector.getNumEventsReceived();
    long totalEventsProcessed = consumerStatsCollector.getNumEventsProcessed();

    System.out.println("eventsReceived = " + consumerStatsCollector.getNumEventsReceived() + " eventsProcessed=" + consumerStatsCollector.getNumEventsProcessed());
    System.out.println("eventsErrProcessed =" + consumerStatsCollector.getNumErrorsProcessed() + " eventsErrReceived=" + consumerStatsCollector.getNumErrorsReceived()
                       + " totalEvents=" + consumerStatsCollector.getNumEventsReceived() + " totalEventsProcessed=" + totalEventsProcessed);

    //FIXME
    Assert.assertTrue(totalEvents >= totalEventsProcessed+eventsErrProcessed);
    Assert.assertTrue(eventsErrProcessed > 0);
    Assert.assertTrue(totalEventsProcessed < totalEvents);

    //NOTE: We don't verify because all the canceled callbacks are not detected by EasyMock
    //EasyMock.verify(mockConsumer1);
  }


  @Test
  public void test2ConsumerTimeout()
  {
    Logger log = Logger.getLogger("TestMultiConsumerCallback.test2ConsumerTimeout");

    //Logger.getRootLogger().setLevel(Level.INFO);
    log.info("\n\nstarting test2ConsumerTimeout()");

    log.info("create dummy events");
    Hashtable<Long, AtomicInteger> keyCounts = new Hashtable<Long, AtomicInteger>();

    DbusEventBuffer eventsBuf = new DbusEventBuffer(_generic100KBufferStaticConfig);
    eventsBuf.start(0);
    eventsBuf.startEvents();
    initBufferWithEvents(eventsBuf, 1, 2, (short)1, keyCounts);
    initBufferWithEvents(eventsBuf, 3, 1, (short)2, keyCounts);
    eventsBuf.endEvents(100L);

    DbusEventBuffer.DbusEventIterator iter = eventsBuf.acquireIterator("myIter1");
    Assert.assertTrue(iter.hasNext(), "unable to read event");
    iter.next(); //skip over the first system event
    Assert.assertTrue(iter.hasNext(), "unable to read event");
    DbusEvent event1 = iter.next().createCopy();
    Assert.assertTrue(iter.hasNext(), "unable to read event");
    DbusEvent event2 = iter.next().createCopy();
    Assert.assertTrue(iter.hasNext(), "unable to read event");


    log.info("make up some sources");
    List<String> sources = new ArrayList<String>();
    Map<Long, IdNamePair> sourcesMap = new HashMap<Long, IdNamePair>();
    for (int i = 1; i <= 3; ++i)
    {
      IdNamePair sourcePair = new IdNamePair((long)i, "source" + i);
      sources.add(sourcePair.getName());
      sourcesMap.put(sourcePair.getId(), sourcePair);
    }

    log.info("create the consumer mock up");
    DatabusStreamConsumer mockConsumer1 = EasyMock.createStrictMock("consumer1",
                                                                    DatabusStreamConsumer.class);
    SelectingDatabusCombinedConsumer sdccMockConsumer1 = new SelectingDatabusCombinedConsumer(mockConsumer1);
    EasyMock.makeThreadSafe(mockConsumer1, true);

    DatabusV2ConsumerRegistration consumerReg =
        new DatabusV2ConsumerRegistration(sdccMockConsumer1, sources, null);

    EasyMock.expect(mockConsumer1.onStartConsumption()).andAnswer(
        new SleepingAnswer<ConsumerCallbackResult>(new LoggedAnswer<ConsumerCallbackResult>(
            ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG, "startConsumption() called"),
            1));
    EasyMock.expect(mockConsumer1.onStartDataEventSequence(null)).andAnswer(
        new SleepingAnswer<ConsumerCallbackResult>(new LoggedAnswer<ConsumerCallbackResult>(
            ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG, "onStartDataEventSequence() called"),
            1));
    EasyMock.expect(mockConsumer1.onStartSource("source1", null)).andAnswer(
        new SleepingAnswer<ConsumerCallbackResult>(
            new LoggedAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, LOG,
                                                     Level.DEBUG,
                                                     "onStartSource() called"),
            1));
    EasyMock.expect(mockConsumer1.onDataEvent(event1, null)).andAnswer(
        new SleepingAnswer<ConsumerCallbackResult>(
            new LoggedAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG,
                                                    "onDataEvet(1) called"),
           1));
    EasyMock.expect(mockConsumer1.onDataEvent(event2, null)).andAnswer(
        new SleepingAnswer<ConsumerCallbackResult>(
            new LoggedAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG,
                                                    "onDataEvet(2) called"),
           1));
    EasyMock.expect(mockConsumer1.onDataEvent(event1, null)).andAnswer(
        new SleepingAnswer<ConsumerCallbackResult>(
            new LoggedAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG,
                                                     "onDataEvet(1) called"),
            1));
    EasyMock.expect(mockConsumer1.onEndSource("source1", null)).andAnswer(
        new SleepingAnswer<ConsumerCallbackResult>(
            new LoggedAnswer<ConsumerCallbackResult>(ConsumerCallbackResult.SUCCESS, LOG, Level.DEBUG,
                                                     "onStartSource() called"),
            1));
    EasyMock.replay(mockConsumer1);
    ConsumerCallbackStats consumerStatsCollector = new ConsumerCallbackStats(1, "test","test", true,false, null);
    UnifiedClientStats unifiedStatsCollector = new UnifiedClientStats(1, "test","test.unified");

    log.info("Create and fire up callbacks");
    List<DatabusV2ConsumerRegistration> allRegistrations =
        Arrays.asList(consumerReg);
    TimingOutMultiConsumerCallback callback =
        new TimingOutMultiConsumerCallback(
            allRegistrations,
            Executors.newCachedThreadPool(),
            300,
            new StreamConsumerCallbackFactory(consumerStatsCollector, unifiedStatsCollector),
            consumerStatsCollector,
            unifiedStatsCollector,
            3);
    callback.setSourceMap(sourcesMap);

    ConsumerCallbackResult startConsumptionRes = callback.onStartConsumption();
    Assert.assertTrue(ConsumerCallbackResult.isSuccess(startConsumptionRes),
                      "startConsumption() succeeded: " + startConsumptionRes);
    ConsumerCallbackResult startWindowRes = callback.onStartDataEventSequence(null);
    Assert.assertTrue(ConsumerCallbackResult.isSuccess(startWindowRes),
                      "startDataEventSequence() succeeded");
    ConsumerCallbackResult startSourceRes = callback.onStartSource("source1", null);
    Assert.assertTrue(ConsumerCallbackResult.isSuccess(startSourceRes),
                      "startSources(source1) succeeded");
    ConsumerCallbackResult event1Res = callback.onDataEvent(event1, null);
    Assert.assertTrue(ConsumerCallbackResult.isSuccess(event1Res),
                      "onDataEvent(1) succeeded");
    ConsumerCallbackResult event2Res = callback.onDataEvent(event2, null);
    Assert.assertTrue(ConsumerCallbackResult.isSuccess(event2Res),
                       "onDataEvent(2) queued up");
    ConsumerCallbackResult event3Res = callback.onDataEvent(event1, null);
    Assert.assertTrue(ConsumerCallbackResult.isSuccess(event3Res),
                      "onDataEvent(1) queued up");
    ConsumerCallbackResult endSourceRes = callback.onEndSource("source1", null);
    Assert.assertTrue(ConsumerCallbackResult.isFailure(endSourceRes),
                       "onEndSource fails because of timeout in onDataEvent(2)");

    EasyMock.reset(mockConsumer1);
    log.info("test2ConsumerTimeout: end");
  }
  @BeforeMethod
  public void beforeMethod()
  {
  }

  @AfterMethod
  public void afterMethod()
  {
  }

  @BeforeClass
  public void beforeClass() throws Exception
  {
    _generic100KBufferConfig = new DbusEventBuffer.Config();
    _generic100KBufferConfig.setAllocationPolicy(AllocationPolicy.HEAP_MEMORY.toString());
    _generic100KBufferConfig.setMaxSize(100000);
    _generic100KBufferConfig.setQueuePolicy(QueuePolicy.BLOCK_ON_WRITE.toString());
    _generic100KBufferConfig.setEnableScnIndex(false);

    _generic100KBufferStaticConfig = _generic100KBufferConfig.build();
  }

  @AfterClass
  public void afterClass()
  {
  }

  @BeforeTest
  public void beforeTest()
  {
  }

  @AfterTest
  public void afterTest()
  {
  }

  @BeforeSuite
  public void beforeSuite()
  {
  }

  @AfterSuite
  public void afterSuite()
  {
  }


  class EventCountingAnswer<T> implements IAnswer<T>
  {
    private final T _result;
    private final AtomicInteger _keyCounter;

    public EventCountingAnswer(T result, AtomicInteger keyCounter)
    {
      super();
      _result = result;
      _keyCounter = keyCounter;
    }


    @Override
    public T answer() throws Throwable
    {
      _keyCounter.incrementAndGet();
      return _result;
    }
  }

  class TimingOutMultiConsumerCallback extends MultiConsumerCallback
  {

    private int _failOnCall;

    public TimingOutMultiConsumerCallback(
        List<DatabusV2ConsumerRegistration> consumers,
        ExecutorService executorService, long timeBudgetMs,
        ConsumerCallbackFactory<DatabusCombinedConsumer> callbackFactory,
        ConsumerCallbackStats consumerStats,
        UnifiedClientStats unifiedClientStats,
        int errorCallNumber) {
      super(consumers, executorService, timeBudgetMs, callbackFactory, consumerStats, unifiedClientStats, null, null);
      _failOnCall = errorCallNumber;
    }


    public TimingOutMultiConsumerCallback(
        List<DatabusV2ConsumerRegistration> consumers,
        ExecutorService executorService, long timeBudgetMs,
        ConsumerCallbackFactory<DatabusCombinedConsumer> callbackFactory,
        int errorCallNumber) {
      super(consumers, executorService, timeBudgetMs, callbackFactory);
      _failOnCall = errorCallNumber;
    }

    @Override
    protected long getEstimatedTimeout(long timeBudget,
           long curTime,
           TimestampedFuture<ConsumerCallbackResult> top )
    {
      _failOnCall--;

      if (_failOnCall == -1 )
        return 0;
      return super.getEstimatedTimeout(timeBudget, curTime, top);
    }

    public void setFailOnCall(int failOnCall)
    {
      _failOnCall = failOnCall;
    }
  }

  class LoggedAnswer<T> implements IAnswer<T>
  {
    private final Logger _logger;
    private final T _result;
    private final Level _level;
    private final String _message;

    public LoggedAnswer(T result, Logger logger, Level level, String message)
    {
      super();
      _result = result;
      _level = level;
      _message = message;
      _logger = logger;
    }


    @Override
    public T answer() throws Throwable
    {
      _logger.log(_level, _message);
      return _result;
    }

  }

  class SleepingAnswer<T> implements IAnswer<T>
  {
    private final IAnswer<T> _delegate;
    private final long _sleepMs;
    private final T _defaultResult;

    public SleepingAnswer(IAnswer<T> delegate, long sleepMs)
    {
      _delegate = delegate;
      _sleepMs = sleepMs;
      _defaultResult = null;
    }

    public SleepingAnswer(T defaultResult, long sleepMs)
    {
      _delegate = null;
      _sleepMs = sleepMs;
      _defaultResult = defaultResult;
    }

    @Override
    public T answer() throws Throwable
    {
      try {Thread.sleep(_sleepMs); } catch (InterruptedException ie) {}
      return null == _delegate ? _defaultResult : _delegate.answer();
    }
  }

  class ExceptionAnswer<T> implements IAnswer<T>
  {
    private final Throwable _exception;
    public ExceptionAnswer(Throwable exception) {
      _exception = exception;
    }

    @Override
    public T answer() throws Throwable
    {
      throw _exception;
    }
  }

  class SomeApplicationException extends RuntimeException {
    SomeApplicationException() {
      super("Some Application Exception");
    }
  }
}
TOP

Related Classes of com.linkedin.databus.client.consumer.TestMultiConsumerCallback$SomeApplicationException

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.