@Test
  public void testMiddleRangeCompactionGetCompactionDetails() throws Exception {
    long logSegmentCount = blobStore.capacityInBytes / blobStore.segmentCapacity;
    // the test is designed to use for 10 log segments.
    assertEquals(logSegmentCount, 10);
    long middleRangeCompactionInterval = 60 * 60 * 24 * 1000; // 1 day
    Properties benefitBasedCompactionProperties = new Properties();
    // set the interval to not zero, it enabled the "middle range compaction"
    benefitBasedCompactionProperties.setProperty("store.stats.based.middle.range.compaction.interval.in.ms",
        Long.toString(middleRangeCompactionInterval));
    setupBlobStore(benefitBasedCompactionProperties);
    blobStore.logSegmentsNotInJournal = CompactionPolicyTest.generateRandomLogSegmentName((int) logSegmentCount);

    // the first run is not middle range compaction since we stagger the first middle range compaction on the same disk.
    // it's the existing stats based compaction.
    int[] expectedCandidateIndex = {5, 6};
    double[] validPercentage = new double[]{0.9, 0.8, 0.5, 0.3, 0.2, 0.1, 0.1, 0.2, 0.4, 0.7};
    verifyMiddleRangeCompactionDetails(blobStore.logSegmentsNotInJournal, validPercentage, expectedCandidateIndex);

    /**
     * test the middle range compaction
     */
    // by default, "store.max.log.segment.valid.data.percentage.to.qualify.compaction" = 30%
    // case 1: compaction the middle range. the valid size threshold is 0.3
    ((MockTime) time).sleep(middleRangeCompactionInterval * 2 + 1);
    validPercentage = new double[]{0.9, 0.8, 0.5, 0.3, 0.2, 0.1, 0.1, 0.2, 0.4, 0.7};
    expectedCandidateIndex = new int[]{3, 4, 5, 6, 7};
    verifyMiddleRangeCompactionDetails(blobStore.logSegmentsNotInJournal, validPercentage, expectedCandidateIndex);

    // case 2: only one log segment has valid size less than the threshold.
    // middle range compaction won't run. Fall back to the stats based compaction.
    ((MockTime) time).sleep(middleRangeCompactionInterval * 2 + 1);
    validPercentage = new double[]{0.9, 0.8, 0.5, 0.4, 0.6, 0.6, 0.3, 0.5, 0.7, 0.8};
    expectedCandidateIndex = new int[]{5, 6, 7};
    verifyMiddleRangeCompactionDetails(blobStore.logSegmentsNotInJournal, validPercentage, expectedCandidateIndex);

    // case 3: no log segment has valid size less than the threshold.
    // middle range compaction won't run. Fall back to the stats based compaction.
    ((MockTime) time).sleep(middleRangeCompactionInterval * 2 + 1);
    validPercentage = new double[]{0.9, 0.8, 0.5, 0.4, 0.6, 0.6, 0.4, 0.5, 0.7, 0.8};
    expectedCandidateIndex = new int[]{3, 4, 5, 6};
    verifyMiddleRangeCompactionDetails(blobStore.logSegmentsNotInJournal, validPercentage, expectedCandidateIndex);
  }
Test the middle range compaction
@throws StoreException, InterruptedException
ambry-store/src/test/java/com/github/ambry/store/StatsBasedCompactionPolicyTest.java