@Test
  public void testProactiveSweep() throws Exception {
    closeSweeperExecutorForTest();

    // Test that proactive sweeper thread does not get created if we turn the feature off
    HiveConf conf = new HiveConf();
    conf.setBoolVar(HiveConf.ConfVars.LLAP_IO_PROACTIVE_EVICTION_ENABLED, false);
    new DummyPolicy(conf);
    assertFalse(isProactiveEvictionSweeperThreadStarted());

    // Below here - testing with the feature turned on
    conf = new HiveConf();
    // NOTE: Choosing a too small value (<10ms) here can make this test case flaky
    long sweepIntervalInMs = 200;
    conf.setTimeVar(HiveConf.ConfVars.LLAP_IO_PROACTIVE_EVICTION_SWEEP_INTERVAL, sweepIntervalInMs,
        TimeUnit.MILLISECONDS);

    TestLowLevelLrfuCachePolicy.EvictionTracker evictionListener = new TestLowLevelLrfuCachePolicy.EvictionTracker();
    DummyPolicy policy = new DummyPolicy(conf);
    policy.setEvictionListener(evictionListener);
    LowLevelCacheMemoryManager mm = new LowLevelCacheMemoryManager(1024L, policy,
        LlapDaemonCacheMetrics.create("test", "1"));
    assertTrue(isProactiveEvictionSweeperThreadStarted());


    // Create buffers and insert them into dummy (but proactive eviction supporting) policy.
    LlapDataBuffer[] buffs = IntStream.range(0, 10).
        mapToObj(i -> LowLevelCacheImpl.allocateFake()).toArray(LlapDataBuffer[]::new);
    Arrays.stream(buffs).forEach(b -> policy.cache(b, null));

    // Marking buffers 0,1 in two mark events, but should be swept up together later
    buffs[0].markForEviction();
    mm.notifyProactiveEvictionMark();
    buffs[1].markForEviction();
    mm.notifyProactiveEvictionMark();

    // No buffers should be evicted right away just yet
    IntStream.range(0, 10).forEach(i -> assertBufferEvicted(false, false, buffs[i], evictionListener));

    // Buffers 0 and 1 should be invalidated after sweep interval time + some margin
    Thread.sleep(sweepIntervalInMs * 2);
    IntStream.range(0, 2).forEach(i -> assertBufferEvicted(true, true, buffs[i], evictionListener));
    IntStream.range(2, 10).forEach(i -> assertBufferEvicted(false, false, buffs[i], evictionListener));

    // Marking buffers 5,6,7,8,9 in one mark event
    IntStream.range(5, 10).forEach(i -> buffs[i].markForEviction());
    mm.notifyProactiveEvictionMark();
    Thread.sleep(sweepIntervalInMs * 2);

    // Buffers 2,3,4 should remain in cache policy
    IntStream.range(0, 2).forEach(i -> assertBufferEvicted(true, true, buffs[i], evictionListener));
    IntStream.range(2, 5).forEach(i -> assertBufferEvicted(false, false, buffs[i], evictionListener));
    IntStream.range(5, 10).forEach(i -> assertBufferEvicted(true, true, buffs[i], evictionListener));

    assertEquals(3, policy.purge());
    // Should have seen normal eviction for buffers 2,3,4 after purge
    IntStream.range(2, 5).forEach(i -> assertBufferEvicted(true, false, buffs[i], evictionListener));

    // Check that no unnecessary work was put on the policy - first 2 marks were swept together then the 3rd one later
    assertEquals(2, policy.proactiveEvictionSweepCount);
  }
Test cases for proactive LLAP cache eviction.
llap-server/src/test/org/apache/hadoop/hive/llap/cache/TestProactiveEviction.java