Program: 132335
Project: 132335
Buggy source:
@Test public void testDefectiveEntries() throws Exception {
  File logFile=new File(testdir + "String_Node_Str");
  int[] offsets=new int[100];
  final AtomicInteger count=new AtomicInteger(0);
  SyncListener sl=new SyncListener(){
    public void synced(    LogEntry entry){
synchronized (entry) {
        count.incrementAndGet();
        entry.notifyAll();
      }
    }
    public void failed(    LogEntry entry,    Exception ex){
synchronized (entry) {
        count.incrementAndGet();
        entry.notifyAll();
      }
    }
  }
;
  LogEntry e=null;
  for (int i=0; i < 100; i++) {
    String pl="String_Node_Str" + (i + 1);
    ReusableBuffer plb=ReusableBuffer.wrap(pl.getBytes());
    e=new LogEntry(plb,sl,LogEntry.PAYLOAD_TYPE_INSERT);
    l.append(e);
    if (i < 99)     offsets[i + 1]=offsets[i] + LogEntry.headerLength + e.getPayload().remaining();
  }
synchronized (e) {
    if (count.get() < 100)     e.wait(1000);
  }
  e.free();
  System.out.println("String_Node_Str");
  try {
    l.lockLogger();
    l.switchLogFile(false);
  }
  finally {
    l.unlockLogger();
  }
  File tmpFile=new File(testdir + "String_Node_Str");
  FSUtils.copyTree(logFile,tmpFile);
  RandomAccessFile raf=new RandomAccessFile(tmpFile.getAbsolutePath(),"String_Node_Str");
  raf.seek(Integer.SIZE / 8);
  raf.writeInt(999999);
  raf.close();
  DiskLogFile f=new DiskLogFile(tmpFile.getAbsolutePath());
  assertFalse(f.hasNext());
  tmpFile.delete();
  FSUtils.copyTree(logFile,tmpFile);
  raf=new RandomAccessFile(tmpFile.getAbsoluteFile(),"String_Node_Str");
  raf.writeInt(2);
  raf.close();
  f=new DiskLogFile(tmpFile.getAbsolutePath());
  assertFalse(f.hasNext());
  tmpFile.delete();
  FSUtils.copyTree(logFile,tmpFile);
  raf=new RandomAccessFile(tmpFile.getAbsolutePath(),"String_Node_Str");
  raf.seek(offsets[50]);
  raf.writeInt(79);
  raf.close();
  f=new DiskLogFile(tmpFile.getAbsolutePath());
  for (int i=0; i < 50; i++) {
    LogEntry next=f.next();
    assertNotNull(next);
    next.free();
  }
  assertFalse(f.hasNext());
  tmpFile.delete();
  FSUtils.copyTree(logFile,tmpFile);
  raf=new RandomAccessFile(tmpFile.getAbsolutePath(),"String_Node_Str");
  raf.seek(offsets[50]);
  raf.writeInt(-122);
  raf.close();
  f=new DiskLogFile(tmpFile.getAbsolutePath());
  for (int i=0; i < 50; i++) {
    LogEntry next=f.next();
    assertNotNull(next);
    next.free();
  }
  assertFalse(f.hasNext());
  tmpFile.delete();
  FSUtils.copyTree(logFile,tmpFile);
  raf=new RandomAccessFile(tmpFile.getAbsolutePath(),"String_Node_Str");
  raf.getChannel().truncate(offsets[99] + 5);
  raf.close();
  f=new DiskLogFile(tmpFile.getAbsolutePath());
  for (int i=0; i < 99; i++) {
    LogEntry next=f.next();
    assertNotNull(next);
    next.free();
  }
  assertFalse(f.hasNext());
  logFile.delete();
  FSUtils.copyTree(tmpFile,logFile);
  tmpFile.delete();
  l.shutdown();
  l=new DiskLogger(testdir,1,200,SyncMode.FSYNC,0,0,null);
  l.start();
  e=null;
  for (int i=99; i < 120; i++) {
    String pl="String_Node_Str" + (i + 1);
    ReusableBuffer plb=ReusableBuffer.wrap(pl.getBytes());
    e=new LogEntry(plb,sl,LogEntry.PAYLOAD_TYPE_INSERT);
    l.append(e);
  }
synchronized (e) {
    if (count.get() < 121)     e.wait(1000);
  }
  e.free();
  File[] logFiles=new File(testdir).listFiles();
  DiskLogIterator it=new DiskLogIterator(logFiles,null);
  for (int i=0; i < 120; i++) {
    LogEntry next=it.next();
    assertNotNull(next);
    next.free();
  }
  assertFalse(it.hasNext());
}

Fixed version (ground truth):
@Test public void testDefectiveEntries() throws Exception {
  File logFile=new File(testdir + "String_Node_Str");
  int[] offsets=new int[100];
  final AtomicInteger count=new AtomicInteger(0);
  SyncListener sl=new SyncListener(){
    public void synced(    LogEntry entry){
synchronized (entry) {
        count.incrementAndGet();
        entry.notifyAll();
      }
    }
    public void failed(    LogEntry entry,    Exception ex){
synchronized (entry) {
        count.incrementAndGet();
        entry.notifyAll();
      }
    }
  }
;
  LogEntry e=null;
  for (int i=0; i < 100; i++) {
    String pl="String_Node_Str" + (i + 1);
    ReusableBuffer plb=ReusableBuffer.wrap(pl.getBytes());
    e=new LogEntry(plb,sl,LogEntry.PAYLOAD_TYPE_INSERT);
    l.append(e);
    if (i < 99)     offsets[i + 1]=offsets[i] + LogEntry.headerLength + e.getPayload().remaining();
  }
synchronized (e) {
    if (count.get() < 100)     e.wait(1000);
  }
  e.free();
  System.out.println("String_Node_Str");
  try {
    l.lockLogger();
    l.switchLogFile(false);
  }
  finally {
    l.unlockLogger();
  }
  File tmpFile=new File(testdir + "String_Node_Str");
  copyFile(logFile,tmpFile);
  RandomAccessFile raf=new RandomAccessFile(tmpFile.getAbsolutePath(),"String_Node_Str");
  raf.seek(Integer.SIZE / 8);
  raf.writeInt(999999);
  raf.close();
  DiskLogFile f=new DiskLogFile(tmpFile.getAbsolutePath());
  assertFalse(f.hasNext());
  f.close();
  assertTrue(tmpFile.delete());
  copyFile(logFile,tmpFile);
  raf=new RandomAccessFile(tmpFile.getAbsoluteFile(),"String_Node_Str");
  raf.writeInt(2);
  raf.close();
  f=new DiskLogFile(tmpFile.getAbsolutePath());
  assertFalse(f.hasNext());
  f.close();
  assertTrue(tmpFile.delete());
  copyFile(logFile,tmpFile);
  raf=new RandomAccessFile(tmpFile.getAbsolutePath(),"String_Node_Str");
  raf.seek(offsets[50]);
  raf.writeInt(79);
  raf.close();
  f=new DiskLogFile(tmpFile.getAbsolutePath());
  for (int i=0; i < 50; i++) {
    LogEntry next=f.next();
    assertNotNull(next);
    next.free();
  }
  assertFalse(f.hasNext());
  f.close();
  assertTrue(tmpFile.delete());
  copyFile(logFile,tmpFile);
  raf=new RandomAccessFile(tmpFile.getAbsolutePath(),"String_Node_Str");
  raf.seek(offsets[50]);
  raf.writeInt(-122);
  raf.close();
  f=new DiskLogFile(tmpFile.getAbsolutePath());
  for (int i=0; i < 50; i++) {
    LogEntry next=f.next();
    assertNotNull(next);
    next.free();
  }
  assertFalse(f.hasNext());
  f.close();
  assertTrue(tmpFile.delete());
  copyFile(logFile,tmpFile);
  raf=new RandomAccessFile(tmpFile.getAbsolutePath(),"String_Node_Str");
  raf.getChannel().truncate(offsets[99] + 5);
  raf.close();
  f=new DiskLogFile(tmpFile.getAbsolutePath());
  for (int i=0; i < 99; i++) {
    LogEntry next=f.next();
    assertNotNull(next);
    next.free();
  }
  assertFalse(f.hasNext());
  f.close();
  logFile.delete();
  copyFile(tmpFile,logFile);
  tmpFile.delete();
  l.shutdown();
  l=new DiskLogger(testdir,1,200,SyncMode.FSYNC,0,0,null);
  l.start();
  e=null;
  for (int i=99; i < 120; i++) {
    String pl="String_Node_Str" + (i + 1);
    ReusableBuffer plb=ReusableBuffer.wrap(pl.getBytes());
    e=new LogEntry(plb,sl,LogEntry.PAYLOAD_TYPE_INSERT);
    l.append(e);
  }
synchronized (e) {
    if (count.get() < 121)     e.wait(1000);
  }
  e.free();
  File[] logFiles=new File(testdir).listFiles();
  DiskLogIterator it=new DiskLogIterator(logFiles,null);
  for (int i=0; i < 120; i++) {
    LogEntry next=it.next();
    assertNotNull(next);
    next.free();
  }
  assertFalse(it.hasNext());
}