private void doFindEntriesSinceTest(StoreFindToken startToken, long maxTotalSizeOfEntries, Set<MockId> expectedKeys,
      StoreFindToken expectedEndToken) throws StoreException {
    FindInfo findInfo = state.index.findEntriesSince(startToken, maxTotalSizeOfEntries);
    StoreFindToken token = (StoreFindToken) findInfo.getFindToken();
    compareTokens(expectedEndToken, token);
    assertEquals("Returned token should have the right number of bytes read", expectedEndToken.getBytesRead(),
        token.getBytesRead());
    List<MessageInfo> infos = findInfo.getMessageEntries();
    Set<StoreKey> keysExamined = new HashSet<>();
    for (MessageInfo info : infos) {
      MockId id = (MockId) info.getStoreKey();
      IndexValue putValue = state.getExpectedValue(id, EnumSet.of(PersistentIndex.IndexEntryType.PUT), null);
      IndexValue ttlUpdateValue =
          state.getExpectedValue(id, EnumSet.of(PersistentIndex.IndexEntryType.TTL_UPDATE), null);
      IndexValue deleteValue = state.getExpectedValue(id, EnumSet.of(PersistentIndex.IndexEntryType.DELETE), null);
      IndexValue undeleteValue = state.getExpectedValue(id, EnumSet.of(PersistentIndex.IndexEntryType.UNDELETE), null);
      // size returned is hard to predict if the key has been updated - it depends on the locations of the PUT and
      // update entries and whether all or some of them are present in the return list. It is not useful to recompute
      // the situations here and check
      long expiresAtMs = undeleteValue != null ? undeleteValue.getExpiresAtMs()
          : deleteValue != null ? deleteValue.getExpiresAtMs()
              : ttlUpdateValue != null ? ttlUpdateValue.getExpiresAtMs() : putValue.getExpiresAtMs();
      short accountId = undeleteValue != null ? undeleteValue.getAccountId()
          : deleteValue != null ? deleteValue.getAccountId()
              : ttlUpdateValue != null ? ttlUpdateValue.getAccountId() : putValue.getAccountId();
      short containerId = undeleteValue != null ? undeleteValue.getContainerId()
          : deleteValue != null ? deleteValue.getContainerId()
              : ttlUpdateValue != null ? ttlUpdateValue.getContainerId() : putValue.getContainerId();
      long operationTimeMs = undeleteValue != null ? undeleteValue.getOperationTimeInMs()
          : deleteValue != null ? deleteValue.getOperationTimeInMs()
              : ttlUpdateValue != null ? ttlUpdateValue.getOperationTimeInMs() : putValue.getOperationTimeInMs();
      boolean isTtlUpdated = undeleteValue != null ? undeleteValue.isTtlUpdate()
          : deleteValue != null ? deleteValue.isTtlUpdate() : ttlUpdateValue != null;
      // if a key is updated, it doesn't matter if we reached the update record or not, the updated state will be
      // the one that is returned.
      if (undeleteValue != null || deleteValue != null) {
        // there is either delete or undelete
        IndexValue lastValue = state.getExpectedValue(id,
            EnumSet.of(PersistentIndex.IndexEntryType.DELETE, PersistentIndex.IndexEntryType.UNDELETE), null);
        assertEquals("Inconsistent delete state for key " + id, lastValue.isDelete(), info.isDeleted());
        assertEquals("Inconsistent undelete state for key " + id, lastValue.isUndelete(), info.isUndeleted());
      }
      assertEquals("Inconsistent TTL update state", isTtlUpdated, info.isTtlUpdated());
      assertEquals("Inconsistent expiresAtMs", expiresAtMs, info.getExpirationTimeInMs());
      assertEquals("Inconsistent accountId", accountId, info.getAccountId());
      assertEquals("Inconsistent containerId", containerId, info.getContainerId());
      assertEquals("Inconsistent operationTimeMs", operationTimeMs, info.getOperationTimeMs());
      keysExamined.add(info.getStoreKey());
    }
    assertEquals("All keys should be present", expectedKeys, keysExamined);
  }
Does the test for {@link PersistentIndex#findEntriesSince(FindToken, long)} and compares the token received to
the expected token. It also verifies that the index entries obtained are as expected.
@param startToken the {@link StoreFindToken} to provide to the function.
@param maxTotalSizeOfEntries the total size of entries to fetch
@param expectedKeys the keys expected in the returned entries.
@param expectedEndToken the {@link StoreFindToken} expected to be returned.
@throws StoreException
ambry-store/src/test/java/com/github/ambry/store/IndexTest.java