private List<MessageInfo> getCuratedSingleSegmentRecoveryInfos() throws StoreException {
    List<MessageInfo> infos = new ArrayList<>();
    state.appendToLog(5 * CuratedLogIndexState.DELETE_RECORD_SIZE + 4 * CuratedLogIndexState.PUT_RECORD_SIZE
        + 5 * TTL_UPDATE_RECORD_SIZE);
    // 1 TTL update for a PUT not in the infos (won't be deleted)
    MockId idToUpdate = state.getIdToTtlUpdateFromLogSegment(state.log.getFirstSegment());
    infos.add(
        new MessageInfo(idToUpdate, CuratedLogIndexState.TTL_UPDATE_RECORD_SIZE, false, true, idToUpdate.getAccountId(),
            idToUpdate.getContainerId(), state.time.milliseconds()));
    state.ttlUpdatedKeys.add(idToUpdate);
    // 1 TTL update for a PUT not in the infos (will be deleted)
    MockId idToUpdateAndDelete = state.getIdToDeleteFromLogSegment(state.log.getFirstSegment(), false);
    infos.add(new MessageInfo(idToUpdateAndDelete, CuratedLogIndexState.TTL_UPDATE_RECORD_SIZE, false, true,
        idToUpdateAndDelete.getAccountId(), idToUpdateAndDelete.getContainerId(), state.time.milliseconds()));
    state.ttlUpdatedKeys.add(idToUpdateAndDelete);
    // 1 DELETE for a PUT not in the infos
    // ttl updated is false because when the delete record is read, the MessageInfo constructed will not know if there
    // has been a ttl update
    infos.add(new MessageInfo(idToUpdateAndDelete, CuratedLogIndexState.DELETE_RECORD_SIZE, true, false,
        idToUpdateAndDelete.getAccountId(), idToUpdateAndDelete.getContainerId(), state.time.milliseconds()));
    // 1 DELETE for a PUT + ttl update not in the infos
    MockId idToDelete = state.getIdToDeleteFromLogSegment(state.log.getFirstSegment(), true);
    // ttl updated is false because when the delete record is read, the MessageInfo constructed will not know if there
    // has been a ttl update
    infos.add(
        new MessageInfo(idToDelete, CuratedLogIndexState.DELETE_RECORD_SIZE, true, false, idToDelete.getAccountId(),
            idToDelete.getContainerId(), state.time.milliseconds()));
    // 3 PUT
    MockId idToCreateUpdateAndDelete = state.getUniqueId();
    short accountId = idToCreateUpdateAndDelete.getAccountId();
    short containerId = idToCreateUpdateAndDelete.getContainerId();
    infos.add(new MessageInfo(idToCreateUpdateAndDelete, CuratedLogIndexState.PUT_RECORD_SIZE, accountId, containerId,
        Utils.Infinite_Time));
    MockId idToCreateAndUpdate = state.getUniqueId();
    infos.add(
        new MessageInfo(idToCreateAndUpdate, CuratedLogIndexState.PUT_RECORD_SIZE, idToCreateAndUpdate.getAccountId(),
            idToCreateAndUpdate.getContainerId(), state.time.milliseconds()));
    MockId id = state.getUniqueId();
    infos.add(new MessageInfo(id, CuratedLogIndexState.PUT_RECORD_SIZE, id.getAccountId(), id.getContainerId(),
        Utils.Infinite_Time));
    // 1 TTL update for a PUT in the infos (will get deleted)
    infos.add(
        new MessageInfo(idToCreateUpdateAndDelete, CuratedLogIndexState.TTL_UPDATE_RECORD_SIZE, false, true, accountId,
            containerId, state.time.milliseconds()));
    state.ttlUpdatedKeys.add(idToCreateUpdateAndDelete);
    // 1 DELETE for a PUT + ttl update in the infos
    infos.add(
        new MessageInfo(idToCreateUpdateAndDelete, CuratedLogIndexState.DELETE_RECORD_SIZE, true, false, accountId,
            containerId, state.time.milliseconds()));
    // 1 TTL update for a PUT in the infos (won't get deleted)
    infos.add(new MessageInfo(idToCreateAndUpdate, CuratedLogIndexState.TTL_UPDATE_RECORD_SIZE, false, true,
        idToCreateAndUpdate.getAccountId(), idToCreateAndUpdate.getContainerId(), state.time.milliseconds()));
    state.ttlUpdatedKeys.add(idToCreateAndUpdate);
    // 1 expired PUT
    id = state.getUniqueId();
    infos.add(new MessageInfo(id, CuratedLogIndexState.PUT_RECORD_SIZE, 0, id.getAccountId(), id.getContainerId(),
        Utils.Infinite_Time));
    // 1 delete for PUT that does not exist in the index
    id = state.getUniqueId();
    infos.add(new MessageInfo(id, CuratedLogIndexState.DELETE_RECORD_SIZE, true, false, id.getAccountId(),
        id.getContainerId(), state.time.milliseconds()));
    // 1 ttl update for a PUT that does not exist in the index (because compaction has cleaned the PUT)
    id = state.getUniqueId();
    infos.add(new MessageInfo(id, CuratedLogIndexState.TTL_UPDATE_RECORD_SIZE, false, true, id.getAccountId(),
        id.getContainerId(), state.time.milliseconds()));
    // a delete for the TTL update above (compaction can only clean if there was a delete - so there will never be JUST
    // a TTL update)
    // ttl updated is false because when the delete record is read, the MessageInfo constructed will not know if there
    // has been a ttl update
    infos.add(new MessageInfo(id, CuratedLogIndexState.DELETE_RECORD_SIZE, true, false, id.getAccountId(),
        id.getContainerId(), state.time.milliseconds()));

    if (addUndeletes) {
      // There are 5 UNDELETE  2 DELETE  2 TTL_UPDATE  1 PUT
      state.appendToLog(
          5 * UNDELETE_RECORD_SIZE + 2 * DELETE_RECORD_SIZE + 2 * TTL_UPDATE_RECORD_SIZE + PUT_RECORD_SIZE);
      // 1 UNDELETE for a compacted PUT and DELETE
      id = state.getUniqueId();
      infos.add(
          new MessageInfo(id, UNDELETE_RECORD_SIZE, false, false, true, Utils.Infinite_Time, null, id.getAccountId(),
              id.getContainerId(), state.time.milliseconds(), (short) 1));
      // 1 DELETE for the undelete above
      infos.add(
          new MessageInfo(id, DELETE_RECORD_SIZE, true, false, false, Utils.Infinite_Time, null, id.getAccountId(),
              id.getContainerId(), state.time.milliseconds(), (short) 1));

      // 1 PUT (will be expired when recovering)
      id = state.getUniqueId();
      infos.add(
          new MessageInfo(id, PUT_RECORD_SIZE, 0, id.getAccountId(), id.getContainerId(), state.time.milliseconds()));
      // 1 DELETE and UNDELETE for this id
      infos.add(new MessageInfo(id, DELETE_RECORD_SIZE, true, false, id.getAccountId(), id.getContainerId(),
          state.time.milliseconds()));
      infos.add(
          new MessageInfo(id, UNDELETE_RECORD_SIZE, false, false, true, Utils.Infinite_Time, null, id.getAccountId(),
              id.getContainerId(), state.time.milliseconds(), (short) 1));
      // 1 TTL update for this id
      infos.add(
          new MessageInfo(id, TTL_UPDATE_RECORD_SIZE, false, true, false, Utils.Infinite_Time, null, id.getAccountId(),
              id.getContainerId(), state.time.milliseconds(), (short) 1));
      state.ttlUpdatedKeys.add(id);

      // 1 UNDELETE for DELETE (not ttlupdate) not in infos
      id = null;
      for (MockId mockId : state.deletedKeys) {
        if (!state.ttlUpdatedKeys.contains(mockId) && !state.getExpectedValue(mockId, false).isTtlUpdate()) {
          id = mockId;
          break;
        }
      }
      assertNotNull(id);
      infos.add(
          new MessageInfo(id, UNDELETE_RECORD_SIZE, false, false, true, Utils.Infinite_Time, null, id.getAccountId(),
              id.getContainerId(), state.time.milliseconds(), (short) 1));
      // 1 TTL update
      infos.add(
          new MessageInfo(id, TTL_UPDATE_RECORD_SIZE, false, true, false, Utils.Infinite_Time, null, id.getAccountId(),
              id.getContainerId(), state.time.milliseconds(), (short) 1));
      state.ttlUpdatedKeys.add(id);

      // 1 UNDELETE for DELETE (ttlupdated) not in infos
      id = null;
      for (MockId mockId : state.deletedKeys) {
        if (state.ttlUpdatedKeys.contains(mockId)) {
          id = mockId;
          break;
        }
      }
      assertNotNull(id);
      infos.add(
          new MessageInfo(id, UNDELETE_RECORD_SIZE, false, false, true, Utils.Infinite_Time, null, id.getAccountId(),
              id.getContainerId(), state.time.milliseconds(), (short) 1));

      // 1 UNDELETE for UNDELETE not in infos
      id = state.undeletedKeys.iterator().next();
      short lifeVersion = (short) (state.getExpectedValue(id, false).getLifeVersion() + 1);
      infos.add(
          new MessageInfo(id, UNDELETE_RECORD_SIZE, false, false, true, Utils.Infinite_Time, null, id.getAccountId(),
              id.getContainerId(), state.time.milliseconds(), lifeVersion));
    }
    return infos;
  }
Creates a few curated recovery entries. For understanding the created entries, please read the source code which is
annotated with comments.
@return curated recovery entries.
@throws StoreException
ambry-store/src/test/java/com/github/ambry/store/IndexTest.java