@Test
  public void testModifiedBucketCacheFileTime() throws Exception {
    HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
    Path testDir = TEST_UTIL.getDataTestDir();
    TEST_UTIL.getTestFileSystem().mkdirs(testDir);
    Configuration conf = HBaseConfiguration.create();
    // Disables the persister thread by setting its interval to MAX_VALUE
    conf.setLong(BUCKETCACHE_PERSIST_INTERVAL_KEY, Long.MAX_VALUE);
    BucketCache bucketCache = null;
    try {
      bucketCache = new BucketCache("file:" + testDir + "/bucket.cache", capacitySize,
        constructedBlockSize, constructedBlockSizes, writeThreads, writerQLen,
        testDir + "/bucket.persistence", DEFAULT_ERROR_TOLERATION_DURATION, conf);
      assertTrue(bucketCache.waitForCacheInitialization(10000));
      long usedSize = bucketCache.getAllocator().getUsedSize();
      assertEquals(0, usedSize);

      Pair<String, Long> myPair = new Pair<>();

      CacheTestUtils.HFileBlockPair[] blocks =
        CacheTestUtils.generateHFileBlocks(constructedBlockSize, 1);
      // Add blocks
      for (CacheTestUtils.HFileBlockPair block : blocks) {
        cacheAndWaitUntilFlushedToBucket(bucketCache, block.getBlockName(), block.getBlock());
      }
      usedSize = bucketCache.getAllocator().getUsedSize();
      assertNotEquals(0, usedSize);
      long blockCount = bucketCache.backingMap.size();
      assertNotEquals(0, blockCount);
      // persist cache to file
      bucketCache.shutdown();

      // modified bucket cache file LastModifiedTime
      final java.nio.file.Path file =
        FileSystems.getDefault().getPath(testDir.toString(), "bucket.cache");
      Files.setLastModifiedTime(file, FileTime.from(Instant.now().plusMillis(1_000)));
      // can't restore cache from file
      bucketCache = new BucketCache("file:" + testDir + "/bucket.cache", capacitySize,
        constructedBlockSize, constructedBlockSizes, writeThreads, writerQLen,
        testDir + "/bucket.persistence", DEFAULT_ERROR_TOLERATION_DURATION, conf);
      assertTrue(bucketCache.waitForCacheInitialization(10000));
      waitPersistentCacheValidation(conf, bucketCache);
      assertEquals(usedSize, bucketCache.getAllocator().getUsedSize());
      assertEquals(blockCount, bucketCache.backingMap.size());
    } finally {
      if (bucketCache != null) {
        bucketCache.shutdown();
      }
    }
    TEST_UTIL.cleanupTestDir();
  }
Test whether BucketCache is started normally after modifying the cache file's last modified
time. First Start BucketCache and add some blocks, then shutdown BucketCache and persist cache
to file. Then Restart BucketCache after modify cache file's last modified time. HBASE-XXXX has
modified persistence cache such that now we store extra 8 bytes at the end of each block in the
cache, representing the nanosecond time the block has been cached. So in the event the cache
file has failed checksum verification during loading time, we go through all the cached blocks
in the cache map and validate the cached time long between what is in the map and the cache
file. If that check fails, we pull the cache key entry out of the map. Since in this test we
are only modifying the access time to induce a checksum error, the cache file content is still
valid and the extra verification should validate that all cache keys in the map are still
recoverable from the cache.
@throws Exception the exception
hbase-server/src/test/java/org/apache/hadoop/hbase/io/hfile/bucket/TestVerifyBucketCacheFile.java