@Test
  public void undeleteTargetIndexOnlyHasTtlUpdateTest() throws Exception {
    assumeTrue(withUndelete);
    refreshState(false, false, false);
    state.properties.put("store.index.max.number.of.inmem.elements", Integer.toString(5));
    state.initIndex(null);

    // Insert P, D, U in the first log segment
    long p1Expiration = state.time.milliseconds() + 1000 * Time.MsPerSec;
    IndexEntry p1 = state.addPutEntries(1, PUT_RECORD_SIZE, p1Expiration).get(0);
    state.addDeleteEntry((MockId) p1.getKey());
    state.addUndeleteEntry((MockId) p1.getKey());

    writeDataToMeetRequiredSegmentCount(1, null);
    // Now we are at second segment
    // Randomly insert a new put
    state.addPutEntries(1, PUT_RECORD_SIZE, Utils.Infinite_Time);
    state.makePermanent((MockId) p1.getKey(), false);
    state.addUndeleteEntry((MockId) p1.getKey(), (short) 2);

    writeDataToMeetRequiredSegmentCount(3, null);

    List<LogSegmentName> segmentsUnderCompaction = getLogSegments(1, 1);
    state.advanceTime(p1Expiration - state.time.milliseconds() + 1000);
    long deleteReferenceTimeMs = state.time.milliseconds();
    compactAndVerify(segmentsUnderCompaction, deleteReferenceTimeMs, false);

    state.reloadIndex(true, false);
    List<IndexValue> values = state.index.findAllIndexValuesForKey(p1.getKey(), null);
    assertNotNull(values);
    assertEquals(5, values.size());
    assertTrue(values.get(0).isUndelete());
    assertTrue(values.get(0).isTtlUpdate());
    assertEquals(Utils.Infinite_Time, values.get(0).getExpiresAtMs());
    assertEquals((short) 2, values.get(0).getLifeVersion());
    assertTrue(values.get(1).isTtlUpdate());
    assertEquals(Utils.Infinite_Time, values.get(1).getExpiresAtMs());
    assertEquals((short) 1, values.get(1).getLifeVersion());
  }
Test when log has P, D, U, T, U, but T and second U is in a separate segment under compaction
ambry-store/src/test/java/com/github/ambry/store/BlobStoreCompactorTest.java