/** Ensures that that all the pending work is performed (Guava limits work per cycle). */ private static void awaitFullCleanup(Cache<?, ?> cache) { for (;;) { long size = cache.estimatedSize(); cache.cleanUp(); if (size == cache.estimatedSize()) { break; } } } }
@Test(dataProvider = "caches") @CacheSpec(implementation = Implementation.Caffeine, maximumSize = Maximum.FULL, weigher = CacheWeigher.COLLECTION, population = Population.EMPTY, keys = ReferenceType.STRONG, values = ReferenceType.STRONG) public void replaceConditionally_sameWeight( Cache<String, List<Integer>> cache, CacheContext context, Eviction<?, ?> eviction) { cache.putAll(ImmutableMap.of("a", asList(1, 2, 3), "b", asList(1))); assertThat(cache.asMap().replace("a", asList(1, 2, 3), asList(4, 5, 6)), is(true)); assertThat(cache.estimatedSize(), is(2L)); assertThat(eviction.weightedSize().getAsLong(), is(4L)); }
@Test(dataProvider = "caches") @CacheSpec(implementation = Implementation.Caffeine, maximumSize = Maximum.FULL, weigher = CacheWeigher.COLLECTION, population = Population.EMPTY, keys = ReferenceType.STRONG, values = ReferenceType.STRONG) public void remove(Cache<String, List<Integer>> cache, CacheContext context, Eviction<?, ?> eviction) { cache.putAll(ImmutableMap.of("a", asList(1, 2, 3), "b", asList(1))); assertThat(cache.asMap().remove("a"), is(asList(1, 2, 3))); assertThat(cache.estimatedSize(), is(1L)); assertThat(eviction.weightedSize().getAsLong(), is(1L)); }
@Test(dataProvider = "caches") @CacheSpec(implementation = Implementation.Caffeine, maximumSize = Maximum.FULL, weigher = CacheWeigher.COLLECTION, population = Population.EMPTY, keys = ReferenceType.STRONG, values = ReferenceType.STRONG) public void removeConditionally_fails( Cache<String, List<Integer>> cache, CacheContext context, Eviction<?, ?> eviction) { cache.putAll(ImmutableMap.of("a", asList(1, 2, 3), "b", asList(1))); assertThat(cache.asMap().remove("a", asList(-1, -2, -3)), is(false)); assertThat(cache.estimatedSize(), is(2L)); assertThat(eviction.weightedSize().getAsLong(), is(4L)); }
@Test(dataProvider = "caches") @CacheSpec(implementation = Implementation.Caffeine, maximumSize = Maximum.FULL, weigher = CacheWeigher.COLLECTION, population = Population.EMPTY, keys = ReferenceType.STRONG, values = ReferenceType.STRONG) public void put(Cache<String, List<Integer>> cache, CacheContext context, Eviction<?, ?> eviction) { cache.put("a", asList(1, 2, 3)); assertThat(cache.estimatedSize(), is(1L)); assertThat(eviction.weightedSize().getAsLong(), is(3L)); }
@Test(dataProvider = "caches") @CacheSpec(implementation = Implementation.Caffeine, maximumSize = Maximum.FULL, weigher = CacheWeigher.COLLECTION, population = Population.EMPTY, keys = ReferenceType.STRONG, values = ReferenceType.STRONG) public void replace_changeWeight(Cache<String, List<Integer>> cache, CacheContext context, Eviction<?, ?> eviction) { cache.putAll(ImmutableMap.of("a", asList(1, 2, 3), "b", asList(1))); cache.asMap().replace("a", asList(-1, -2, -3, -4)); assertThat(cache.estimatedSize(), is(2L)); assertThat(eviction.weightedSize().getAsLong(), is(5L)); }
@Test(dataProvider = "caches") @CacheSpec(implementation = Implementation.Caffeine, maximumSize = Maximum.FULL, weigher = CacheWeigher.COLLECTION, population = Population.EMPTY, keys = ReferenceType.STRONG, values = ReferenceType.STRONG) public void invalidateAll(Cache<String, List<Integer>> cache, CacheContext context, Eviction<?, ?> eviction) { cache.putAll(ImmutableMap.of("a", asList(1, 2, 3), "b", asList(1))); cache.invalidateAll(); assertThat(cache.estimatedSize(), is(0L)); assertThat(eviction.weightedSize().getAsLong(), is(0L)); }
@Test(dataProvider = "caches") @CacheSpec(implementation = Implementation.Caffeine, maximumSize = Maximum.FULL, weigher = CacheWeigher.TEN) public void weightedSize(Cache<Integer, Integer> cache, CacheContext context, Eviction<Integer, Integer> eviction) { long weightedSize = 0; for (Integer key : cache.asMap().keySet()) { weightedSize += eviction.weightOf(key).getAsInt(); } assertThat(weightedSize, is(eviction.weightedSize().getAsLong())); assertThat(eviction.weightedSize().getAsLong(), is(10 * cache.estimatedSize())); }
@Test(dataProvider = "caches") @CacheSpec(implementation = Implementation.Caffeine, maximumSize = Maximum.FULL, removalListener = Listener.REJECTING) public void maximumSize_increase_max(Cache<Integer, Integer> cache, CacheContext context, Eviction<Integer, Integer> eviction) { eviction.setMaximum(Long.MAX_VALUE); assertThat(cache.estimatedSize(), is(context.initialSize())); assertThat(eviction.getMaximum(), is(Long.MAX_VALUE - Integer.MAX_VALUE)); // impl detail }
@CheckNoWriter @Test(dataProvider = "caches") @CacheSpec(removalListener = { Listener.DEFAULT, Listener.REJECTING }) public void put_insert_failure_before(AsyncCache<Integer, Integer> cache, CacheContext context) { CompletableFuture<Integer> failedFuture = CompletableFuture.completedFuture(null); failedFuture.completeExceptionally(new IllegalStateException()); cache.put(context.absentKey(), failedFuture); assertThat(cache.getIfPresent(context.absentKey()), is(nullValue())); assertThat(cache.synchronous().estimatedSize(), is(context.initialSize())); }
@Test(dataProvider = "caches") @CacheSpec(population = { Population.SINGLETON, Population.PARTIAL, Population.FULL }, mustExpireWithAnyOf = { AFTER_ACCESS, AFTER_WRITE, VARIABLE }, expiry = { CacheExpiry.DISABLED, CacheExpiry.CREATE, CacheExpiry.WRITE, CacheExpiry.ACCESS }, expireAfterAccess = {Expire.DISABLED, Expire.ONE_MINUTE}, expireAfterWrite = {Expire.DISABLED, Expire.ONE_MINUTE}, expiryTime = Expire.ONE_MINUTE) public void estimatedSize(Cache<Integer, Integer> cache, CacheContext context) { context.ticker().advance(1, TimeUnit.MINUTES); assertThat(cache.estimatedSize(), is(context.initialSize())); }
@CheckNoWriter @CheckNoStats @Test(dataProvider = "caches") @CacheSpec(removalListener = { Listener.DEFAULT, Listener.REJECTING }) public void estimatedSize(Cache<Integer, Integer> cache, CacheContext context) { assertThat(cache.estimatedSize(), is(context.initialSize())); }
@CheckNoWriter @Test(dataProvider = "caches") @CacheSpec(population = { Population.SINGLETON, Population.FULL }, removalListener = { Listener.DEFAULT, Listener.REJECTING }) public void put_replace_failure_before(AsyncCache<Integer, Integer> cache, CacheContext context) { CompletableFuture<Integer> failedFuture = CompletableFuture.completedFuture(null); failedFuture.completeExceptionally(new IllegalStateException()); cache.put(context.middleKey(), failedFuture); assertThat(cache.getIfPresent(context.absentKey()), is(nullValue())); assertThat(cache.synchronous().estimatedSize(), is(context.initialSize() - 1)); }
@CheckNoWriter @Test(dataProvider = "caches") @CacheSpec(population = { Population.SINGLETON, Population.FULL }, removalListener = { Listener.DEFAULT, Listener.REJECTING }) public void put_replace_failure_after(AsyncCache<Integer, Integer> cache, CacheContext context) { CompletableFuture<Integer> failedFuture = CompletableFuture.completedFuture(null); cache.put(context.middleKey(), failedFuture); failedFuture.completeExceptionally(new IllegalStateException()); assertThat(cache.getIfPresent(context.absentKey()), is(nullValue())); assertThat(cache.synchronous().estimatedSize(), is(context.initialSize() - 1)); }
@Test(dataProvider = "caches") @CacheSpec(implementation = Implementation.Caffeine, maximumSize = Maximum.FULL, removalListener = { Listener.DEFAULT, Listener.REJECTING }) public void maximumSize_increase(Cache<Integer, Integer> cache, CacheContext context, Eviction<Integer, Integer> eviction) { eviction.setMaximum(2 * context.maximumWeightOrSize()); assertThat(cache.estimatedSize(), is(context.initialSize())); assertThat(eviction.getMaximum(), is(2 * context.maximumWeightOrSize())); }
@CheckNoWriter @CheckNoStats @Test(dataProvider = "caches") @CacheSpec(removalListener = { Listener.DEFAULT, Listener.REJECTING }) public void putAll_empty(Cache<Integer, Integer> cache, CacheContext context) { cache.putAll(new HashMap<>()); assertThat(cache.estimatedSize(), is(context.initialSize())); }
@Test(dataProvider = "caches") @CacheSpec(population = { Population.SINGLETON, Population.PARTIAL, Population.FULL }) public void invalidateAll_full(Cache<Integer, Integer> cache, CacheContext context) { cache.invalidateAll(context.original().keySet()); assertThat(cache.estimatedSize(), is(0L)); assertThat(cache, hasRemovalNotifications(context, context.original().size(), RemovalCause.EXPLICIT)); verifyWriter(context, (verifier, writer) -> { verifier.deletedAll(context.original(), RemovalCause.EXPLICIT); }); }
@CheckNoWriter @CheckNoStats @Test(dataProvider = "caches") @CacheSpec(removalListener = { Listener.DEFAULT, Listener.REJECTING }) public void invalidate_absent(Cache<Integer, Integer> cache, CacheContext context) { cache.invalidate(context.absentKey()); assertThat(cache.estimatedSize(), is(context.initialSize())); }
@Test(dataProvider = "caches") @CacheSpec(implementation = Implementation.Caffeine, mustExpireWithAnyOf = AFTER_WRITE, expireAfterWrite = Expire.ONE_MINUTE) public void setExpiresAfter(Cache<Integer, Integer> cache, CacheContext context, @ExpireAfterWrite Expiration<Integer, Integer> expireAfterWrite) { expireAfterWrite.setExpiresAfter(2, TimeUnit.MINUTES); assertThat(expireAfterWrite.getExpiresAfter(TimeUnit.MINUTES), is(2L)); context.ticker().advance(90, TimeUnit.SECONDS); cache.cleanUp(); assertThat(cache.estimatedSize(), is(context.initialSize())); }
@Test(dataProvider = "caches") @CacheSpec(removalListener = { Listener.DEFAULT, Listener.REJECTING }) public void put_insert(AsyncCache<Integer, Integer> cache, CacheContext context) { CompletableFuture<Integer> value = CompletableFuture.completedFuture(context.absentValue()); cache.put(context.absentKey(), value); assertThat(cache.synchronous().estimatedSize(), is(context.initialSize() + 1)); assertThat(context, both(hasMissCount(0)).and(hasHitCount(0))); assertThat(context, both(hasLoadSuccessCount(1)).and(hasLoadFailureCount(0))); assertThat(cache.synchronous().getIfPresent(context.absentKey()), is(context.absentValue())); }