@Test
  public void updateRecordTest() {
    LogSegmentName logSegmentName = StoreTestUtils.getRandomLogSegmentName(null);
    long size = Utils.getRandomLong(TestUtils.RANDOM, 1000);
    long offset = Utils.getRandomLong(TestUtils.RANDOM, 1000);
    long expiresAtMs = Utils.getRandomLong(TestUtils.RANDOM, 1000000);
    long operationTimeAtMs = Utils.getRandomLong(TestUtils.RANDOM, 1000000);
    long expectedOperationTimeMs = Utils.getTimeInMsToTheNearestSec(operationTimeAtMs);
    short accountId = Utils.getRandomShort(TestUtils.RANDOM);
    short containerId = Utils.getRandomShort(TestUtils.RANDOM);
    short lifeVersion = (short) 0;
    IndexValue value =
        getIndexValue(size, new Offset(logSegmentName, offset), expiresAtMs, operationTimeAtMs, accountId, containerId,
            lifeVersion, version);
    long originalMsgOffset = Utils.getRandomLong(TestUtils.RANDOM, 1000);
    long originalMsgSize = Utils.getRandomLong(TestUtils.RANDOM, 1000);

    long expectedOffset;
    long expectedSize;
    long expectedOriginalMsgOffset;
    for (IndexValue.Flags flag : IndexValue.Flags.values()) {
      // update in the same log segment
      IndexValue newValue = new IndexValue(logSegmentName, value.getBytes(), version);
      newValue.setFlag(flag);

      Offset originalMsgOff = new Offset(logSegmentName, originalMsgOffset);
      if (flag.equals(IndexValue.Flags.Delete_Index)) {
        expectedOffset = originalMsgOffset;
        expectedSize = originalMsgSize;
        expectedOriginalMsgOffset = offset;

        newValue.setNewOffset(originalMsgOff);
        newValue.setNewSize(originalMsgSize);
      } else {
        expectedOffset = offset;
        expectedSize = size;
        expectedOriginalMsgOffset = originalMsgOffset;

        newValue.setOriginalMessageOffset(originalMsgOff);
      }
      verifyIndexValue(newValue, logSegmentName, expectedSize, expectedOffset, EnumSet.of(flag), expiresAtMs,
          expectedOriginalMsgOffset, expectedOperationTimeMs, accountId, containerId, lifeVersion);

      // original message offset cleared
      newValue.clearOriginalMessageOffset();
      verifyIndexValue(newValue, logSegmentName, expectedSize, expectedOffset, EnumSet.of(flag), expiresAtMs,
          IndexValue.UNKNOWN_ORIGINAL_MESSAGE_OFFSET, expectedOperationTimeMs, accountId, containerId, lifeVersion);

      newValue = new IndexValue(logSegmentName, value.getBytes(), version);
      LogSegmentName newLogSegmentName = logSegmentName.getNextPositionName();
      LogSegmentName expectedLogSegmentName;
      // update not in the same log segment
      newValue.setFlag(flag);
      originalMsgOff = new Offset(newLogSegmentName, originalMsgOffset);
      if (flag.equals(IndexValue.Flags.Delete_Index)) {
        expectedLogSegmentName = newLogSegmentName;
        // no need to set the other "expected" because they have already been set
        newValue.setNewOffset(originalMsgOff);
        newValue.setNewSize(originalMsgSize);
      } else {
        expectedLogSegmentName = logSegmentName;
        newValue.setOriginalMessageOffset(originalMsgOff);
      }
      verifyIndexValue(newValue, expectedLogSegmentName, expectedSize, expectedOffset, EnumSet.of(flag), expiresAtMs,
          IndexValue.UNKNOWN_ORIGINAL_MESSAGE_OFFSET, expectedOperationTimeMs, accountId, containerId, lifeVersion);
    }

    // clearFlag() test
    IndexValue newValue = new IndexValue(logSegmentName, value.getBytes(), version);
    // set two flags
    newValue.setFlag(IndexValue.Flags.Ttl_Update_Index);
    newValue.setFlag(IndexValue.Flags.Delete_Index);
    verifyIndexValue(newValue, logSegmentName, size, offset,
        EnumSet.of(IndexValue.Flags.Ttl_Update_Index, IndexValue.Flags.Delete_Index), expiresAtMs, offset,
        expectedOperationTimeMs, accountId, containerId, lifeVersion);
    // clear the delete flag
    newValue.clearFlag(IndexValue.Flags.Delete_Index);
    verifyIndexValue(newValue, logSegmentName, size, offset, EnumSet.of(IndexValue.Flags.Ttl_Update_Index), expiresAtMs,
        offset, expectedOperationTimeMs, accountId, containerId, lifeVersion);
    // clear again (to check that it does not cause problems)
    newValue.clearFlag(IndexValue.Flags.Delete_Index);
    // clear the ttl update flag
    newValue.clearFlag(IndexValue.Flags.Ttl_Update_Index);
    verifyIndexValue(newValue, logSegmentName, size, offset, EnumSet.noneOf(IndexValue.Flags.class), expiresAtMs,
        offset, expectedOperationTimeMs, accountId, containerId, lifeVersion);
  }
Tests an {@link IndexValue} that is representative of a update index entry value. Tests both when the update
value is in the same log segment and a different one.
ambry-store/src/test/java/com/github/ambry/store/IndexValueTest.java