@Test
  public void changeIndexSegmentsTest() throws StoreException {
    ConcurrentSkipListMap<Offset, IndexSegment> indexes = state.index.getIndexSegments();
    Set<Offset> saved = indexes.clone().keySet();

    Map<Offset, IndexSegment> toRemoveOne = new HashMap<>();
    Set<Offset> toRetainOne = new HashSet<>();

    partitionIndexSegments(toRemoveOne, toRetainOne);

    // remove the first batch without adding anything
    state.index.changeIndexSegments(Collections.emptyList(), toRemoveOne.keySet());
    assertEquals("Offsets in index do not match expected", toRetainOne, state.index.getIndexSegments().keySet());
    // make sure persist does not throw errors
    state.index.persistIndex();

    Map<Offset, IndexSegment> toRemoveTwo = new HashMap<>();
    Set<Offset> toRetainTwo = new HashSet<>();

    partitionIndexSegments(toRemoveTwo, toRetainTwo);

    // remove the second batch and add the batch that was removed earlier
    toRetainTwo.addAll(toRemoveOne.keySet());
    List<File> filesToAdd = new ArrayList<>();
    for (IndexSegment indexSegment : toRemoveOne.values()) {
      filesToAdd.add(indexSegment.getFile());
    }
    state.index.changeIndexSegments(filesToAdd, toRemoveTwo.keySet());
    assertEquals("Offsets in index do not match expected", toRetainTwo, state.index.getIndexSegments().keySet());
    // make sure persist does not throw errors
    state.index.persistIndex();

    // add the second batch that was removed
    filesToAdd.clear();
    for (IndexSegment indexSegment : toRemoveTwo.values()) {
      filesToAdd.add(indexSegment.getFile());
    }
    state.index.changeIndexSegments(filesToAdd, Collections.emptySet());
    assertEquals("Offsets in index do not match expected", saved, state.index.getIndexSegments().keySet());
    // make sure persist does not throw errors
    state.index.persistIndex();

    // error case
    // try to remove the last segment (its offset is in the journal)
    try {
      state.index.changeIndexSegments(Collections.emptyList(), Collections.singleton(state.referenceIndex.lastKey()));
      fail("Should have failed to remove index segment because start offset is past the first offset in the journal");
    } catch (IllegalArgumentException e) {
      // expected. Nothing to do.
    }

    // add an entry into the journal for the very first offset in the index
    state.index.journal.addEntry(state.logOrder.firstKey(), state.logOrder.firstEntry().getValue().getFirst());
    // remove the first index segment
    IndexSegment firstSegment = state.index.getIndexSegments().remove(state.index.getIndexSegments().firstKey());
    // try to add it back and it should result in an error
    try {
      state.index.changeIndexSegments(Collections.singletonList(firstSegment.getFile()), Collections.emptySet());
      fail("Should have failed to add index segment because its end offset is past the first offset in the journal");
    } catch (IllegalArgumentException e) {
      // expected. Nothing to do.
    }
  }
Tests {@link PersistentIndex#changeIndexSegments(List, Set)} for good and bad cases.
@throws StoreException
ambry-store/src/test/java/com/github/ambry/store/IndexTest.java