@Test
  public void testTimeRangeResolutionWithStats() throws InterruptedException, StoreException {
    assumeTrue(bucketingEnabled);
    CountDownLatch scanStartedLatch = new CountDownLatch(1);
    MockThrottler mockThrottler = new MockThrottler(scanStartedLatch, new CountDownLatch(0));
    throttlers.put(BlobStoreStats.IO_SCHEDULER_JOB_TYPE, mockThrottler);
    long logSegmentForecastStartTimeMs = state.time.milliseconds();
    // advance time to ensure the log segment forecast start time is > 0
    state.advanceTime(20000);
    long logSegmentForecastEndTimeMs = 10 * BUCKET_SPAN_IN_MS + logSegmentForecastStartTimeMs;
    BlobStoreStats blobStoreStats = setupBlobStoreStats(10, 20000);
    // proceed only when the scan is started
    assertTrue("IndexScanner took too long to start", scanStartedLatch.await(5, TimeUnit.SECONDS));
    // ensure the scan is complete before proceeding
    verifyContainerStorageStatsAndGetTotalValidSize(blobStoreStats, state.time.milliseconds());
    int throttleCountBeforeRequests = mockThrottler.throttleCount.get();
    TimeRange timeRange = new TimeRange(logSegmentForecastStartTimeMs, Time.MsPerSec);
    assertEquals("Unexpected collection time", timeRange.getEndTimeInMs(),
        blobStoreStats.getValidDataSizeByLogSegment(timeRange).getFirst().longValue());
    timeRange = new TimeRange(logSegmentForecastEndTimeMs, Time.MsPerSec);
    assertEquals("Unexpected collection time", logSegmentForecastEndTimeMs - BUCKET_SPAN_IN_MS,
        blobStoreStats.getValidDataSizeByLogSegment(timeRange).getFirst().longValue());
    timeRange = new TimeRange((logSegmentForecastStartTimeMs + logSegmentForecastEndTimeMs) / 2, Time.MsPerSec);
    assertEquals("Unexpected collection time", timeRange.getEndTimeInMs(),
        blobStoreStats.getValidDataSizeByLogSegment(timeRange).getFirst().longValue());
    // time range end time is equal to the start of forecast range
    timeRange = new TimeRange(logSegmentForecastStartTimeMs - Time.MsPerSec, Time.MsPerSec);
    assertEquals("Unexpected collection time", timeRange.getEndTimeInMs(),
        blobStoreStats.getValidDataSizeByLogSegment(timeRange).getFirst().longValue());
    // all previous time range are inside the forecast range
    assertEquals("Throttle count mismatch from expected value", throttleCountBeforeRequests,
        mockThrottler.throttleCount.get());
    // time range start time is equal the end of forecast range (considered to be outside of forecast range)
    timeRange = new TimeRange(logSegmentForecastEndTimeMs + Time.MsPerSec, Time.MsPerSec);
    assertEquals("Unexpected collection time", timeRange.getEndTimeInMs(),
        blobStoreStats.getValidDataSizeByLogSegment(timeRange).getFirst().longValue());
    timeRange = new TimeRange(logSegmentForecastEndTimeMs + TimeUnit.SECONDS.toMillis(5), Time.MsPerSec);
    assertEquals("Unexpected collection time", timeRange.getEndTimeInMs(),
        blobStoreStats.getValidDataSizeByLogSegment(timeRange).getFirst().longValue());
    timeRange = new TimeRange(logSegmentForecastStartTimeMs - TimeUnit.SECONDS.toMillis(5), Time.MsPerSec);
    assertEquals("Unexpected collection time", timeRange.getEndTimeInMs(),
        blobStoreStats.getValidDataSizeByLogSegment(timeRange).getFirst().longValue());
    blobStoreStats.close();
  }
Test to verify {@link BlobStoreStats} is resolving the given {@link TimeRange} correctly and the appropriate action
is taken. That is, use the readily available {@link ScanResults} to answer the request or trigger a on demand scan.
Specifically the following cases are tested (plus cases when boundaries touch each other):
   [_______]  [_______]     [________]   [______]              [______]  <--- forecast range
 [___]      ,       [___] ,   [___]    ,         [___] , [___]           <--- given time range
@throws InterruptedException
ambry-store/src/test/java/com/github/ambry/store/BlobStoreStatsTest.java