@Test(timeout = 6_000L) public void testFragmentation() {
    MemoryBuffer[] dest = new MemoryBuffer[128];
    for (MemoryBuffer memoryBuffer : dest) {
      Assert.assertNull(memoryBuffer);
    }
    allocator.allocateMultiple(dest, 8, null);
    //all the cache is allocated with 8 X 128
    Assert.assertEquals(maxSize, ((LowLevelCacheMemoryManager) memoryManager).getCurrentUsedSize());

    for (int i = 0; i < dest.length; i++) {
      LlapDataBuffer buffer = (LlapDataBuffer) dest[i];
      // this is needed to make sure that the policy adds the buffers to the linked list as buffers ready to be evicted
      cachePolicy.notifyUnlock(buffer);
      // lock some buffers
      if (i % 2 == 0) {
        // lock the even buffers
        buffer.incRef();
      }
    }

    // purge the cache should lead to only evicting the unlocked buffers
    Assert.assertEquals(512, ((LowLevelCacheMemoryManager) memoryManager).purge());
    // After purge the used memory should be aligned to the amount of evicted items
    Assert.assertEquals(512, ((LowLevelCacheMemoryManager) memoryManager).getCurrentUsedSize());

    MemoryBuffer[] dest2 = new MemoryBuffer[1];
    Exception exception = null;
    try {
      allocator.allocateMultiple(dest2, 16, null);
    } catch (Allocator.AllocatorOutOfMemoryException e) {
      // we should fail since we have the extreme case where half of the leaf nodes are locked thus
      // maximum fragmentation case
      exception = e;
    }
    Assert.assertNotNull(exception);
    //We need to make sure that the failed allocation attempt undo the reserved memory.
    //https://issues.apache.org/jira/browse/HIVE-21689
    Assert.assertEquals(512, ((LowLevelCacheMemoryManager) memoryManager).getCurrentUsedSize());
    // unlock one buffer
    Assert.assertTrue(((LlapDataBuffer) dest[0]).isLocked());
    ((LlapDataBuffer) dest[0]).decRef();
    evictionTracker.clear();
    // this is needed since purge has removed the locked ones form the list, the assumption is that when we unlock
    // a buffer we notify the cache policy.
    cachePolicy.notifyUnlock((LlapDataBuffer) dest[0]);
    // we should be able to allocate after some extra eviction
    allocator.allocateMultiple(dest2, 16, null);
    //we have to see that we have force evicted something to make room for the new allocation
    Assert.assertTrue(evictionTracker.getEvicted().size() >= 1);
  }
Test case to ensure that deallocate it does merge small blocks into bigger ones.
llap-server/src/test/org/apache/hadoop/hive/llap/cache/TestCacheAllocationsEvictionsCycles.java