Program: 37652
Project: 37652
Buggy source:
/** 
 * This tests what happens if we ask to consume from an offset that is invalid (does not exist). Here's what we setup: 2 partitions, produce 4 messages into each. Start a consumer, asking to start at: offset 2 for partition 1, (recorded completed offset = 1) offset 21 for partition 2. (recorded completed offset = 20) Offset 20 does not exist for partition 2, this will raise an exception which by the underlying kafka consumer.  This exception should be handled internally resetting the offset on partition 2 to the earliest available (which happens to be 0). We then consume and expect to receive messages: partition 0 -> messages 2,3      (because we started at offset 2) partition 1 -> messages 0,1,2,3  (because we got reset to earliest) This test also validates that for non-reset partitions, that it does not lose any messages.
 */
@Test public void testWhatHappensIfOffsetIsInvalidShouldResetSmallest(){
  this.topicName="String_Node_Str" + System.currentTimeMillis();
  final int numberOfPartitions=2;
  final int numberOfMsgsPerPartition=4;
  final int numberOfExpectedMessages=6;
  final ConsumerPartition topicPartition0=new ConsumerPartition(topicName,0);
  final ConsumerPartition topicPartition1=new ConsumerPartition(topicName,1);
  final long partition0StartingOffset=1L;
  final long partition1StartingOffset=20L;
  kafkaTestServer.createTopic(topicName,numberOfPartitions);
  produceRecords(numberOfMsgsPerPartition,0);
  produceRecords(numberOfMsgsPerPartition,1);
  Map<String,Object> config=getDefaultConfig(topicName);
  PersistenceAdapter persistenceAdapter=new InMemoryPersistenceAdapter();
  persistenceAdapter.open(Maps.newHashMap());
  persistenceAdapter.persistConsumerState("String_Node_Str",0,partition0StartingOffset);
  persistenceAdapter.persistConsumerState("String_Node_Str",1,partition1StartingOffset);
  Consumer consumer=new Consumer();
  consumer.open(config,getDefaultVSpoutId(),getDefaultConsumerCohortDefinition(),persistenceAdapter,null);
  ConsumerState consumerState=consumer.getCurrentState();
  assertEquals("String_Node_Str",(Long)partition0StartingOffset,consumerState.getOffsetForNamespaceAndPartition(topicPartition0));
  assertEquals("String_Node_Str",(Long)partition1StartingOffset,consumerState.getOffsetForNamespaceAndPartition(topicPartition1));
  final Set<String> expectedValues=Sets.newHashSet("String_Node_Str","String_Node_Str","String_Node_Str","String_Node_Str","String_Node_Str","String_Node_Str");
  List<Record> records=Lists.newArrayList();
  Record consumerRecord;
  int attempts=0;
  do {
    consumerRecord=consumer.nextRecord();
    if (consumerRecord != null) {
      logger.info("String_Node_Str",consumerRecord.getOffset(),consumerRecord.getPartition());
      records.add(consumerRecord);
      expectedValues.remove("String_Node_Str" + consumerRecord.getPartition() + "String_Node_Str"+ consumerRecord.getOffset());
    }
 else {
      attempts++;
    }
  }
 while (attempts <= 2);
  logger.info("String_Node_Str",records.size());
  assertEquals("String_Node_Str",numberOfExpectedMessages,records.size());
  assertTrue("String_Node_Str",expectedValues.isEmpty());
  for (int x=0; x < 2; x++) {
    assertNull("String_Node_Str",consumer.nextRecord());
  }
  consumerState=consumer.getCurrentState();
  assertEquals("String_Node_Str",(Long)partition0StartingOffset,consumerState.getOffsetForNamespaceAndPartition(topicPartition0));
  assertEquals("String_Node_Str",(Long)(-1L),consumerState.getOffsetForNamespaceAndPartition(topicPartition1));
}

Fixed version (ground truth):
/** 
 * This tests what happens if we ask to consume from an offset that is invalid (does not exist). Here's what we setup: 2 partitions, produce 4 messages into each. Start a consumer, asking to start at: offset 2 for partition 1, (recorded completed offset = 1) offset 21 for partition 2. (recorded completed offset = 20) Offset 20 does not exist for partition 2, this will raise an exception which by the underlying kafka consumer.  This exception should be handled internally resetting the offset on partition 2 to the earliest available (which happens to be 0). We then consume and expect to receive messages: partition 0 -> messages 2,3      (because we started at offset 2) partition 1 -> messages 0,1,2,3  (because we got reset to earliest) This test also validates that for non-reset partitions, that it does not lose any messages.
 */
@Test public void testWhatHappensIfOffsetIsInvalidShouldResetSmallest(){
  this.topicName="String_Node_Str" + System.currentTimeMillis();
  final int numberOfPartitions=2;
  final int numberOfMsgsPerPartition=4;
  final int numberOfExpectedMessages=6;
  final ConsumerPartition topicPartition0=new ConsumerPartition(topicName,0);
  final ConsumerPartition topicPartition1=new ConsumerPartition(topicName,1);
  final long partition0StartingOffset=1L;
  final long partition1StartingOffset=20L;
  kafkaTestServer.createTopic(topicName,numberOfPartitions);
  produceRecords(numberOfMsgsPerPartition,0);
  produceRecords(numberOfMsgsPerPartition,1);
  Map<String,Object> config=getDefaultConfig(topicName);
  PersistenceAdapter persistenceAdapter=new InMemoryPersistenceAdapter();
  persistenceAdapter.open(Maps.newHashMap());
  persistenceAdapter.persistConsumerState("String_Node_Str",0,partition0StartingOffset);
  persistenceAdapter.persistConsumerState("String_Node_Str",1,partition1StartingOffset);
  Consumer consumer=new Consumer();
  consumer.open(config,getDefaultVSpoutId(),getDefaultConsumerCohortDefinition(),persistenceAdapter,null);
  ConsumerState consumerState=consumer.getCurrentState();
  assertEquals("String_Node_Str",(Long)partition0StartingOffset,consumerState.getOffsetForNamespaceAndPartition(topicPartition0));
  assertEquals("String_Node_Str",(Long)partition1StartingOffset,consumerState.getOffsetForNamespaceAndPartition(topicPartition1));
  final Set<String> expectedValues=Sets.newHashSet("String_Node_Str","String_Node_Str","String_Node_Str","String_Node_Str","String_Node_Str","String_Node_Str","String_Node_Str");
  List<Record> records=Lists.newArrayList();
  Record consumerRecord;
  int attempts=0;
  do {
    consumerRecord=consumer.nextRecord();
    if (consumerRecord != null) {
      logger.info("String_Node_Str",consumerRecord.getOffset(),consumerRecord.getPartition());
      records.add(consumerRecord);
      expectedValues.remove("String_Node_Str" + consumerRecord.getPartition() + "String_Node_Str"+ consumerRecord.getOffset());
    }
 else {
      attempts++;
    }
  }
 while (attempts <= 2);
  logger.info("String_Node_Str",records.size());
  assertEquals("String_Node_Str",numberOfExpectedMessages + 1,records.size());
  assertTrue("String_Node_Str",expectedValues.isEmpty());
  for (int x=0; x < 2; x++) {
    assertNull("String_Node_Str",consumer.nextRecord());
  }
  consumerState=consumer.getCurrentState();
  assertEquals("String_Node_Str",(Long)partition0StartingOffset,consumerState.getOffsetForNamespaceAndPartition(topicPartition0));
  assertEquals("String_Node_Str",(Long)(-1L),consumerState.getOffsetForNamespaceAndPartition(topicPartition1));
  consumer.close();
}