11d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/* 21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2009 The Guava Authors 31d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 41d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License"); 51d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * you may not use this file except in compliance with the License. 61d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * You may obtain a copy of the License at 71d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 81d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * http://www.apache.org/licenses/LICENSE-2.0 91d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Unless required by applicable law or agreed to in writing, software 111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * distributed under the License is distributed on an "AS IS" BASIS, 121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * See the License for the specific language governing permissions and 141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * limitations under the License. 151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpackage com.google.common.cache; 181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.cache.TestingCacheLoaders.constantLoader; 201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.cache.TestingCacheLoaders.identityLoader; 211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.cache.TestingRemovalListeners.countingRemovalListener; 221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.cache.TestingRemovalListeners.nullRemovalListener; 231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.cache.TestingRemovalListeners.queuingRemovalListener; 241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.cache.TestingWeighers.constantWeigher; 251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static java.util.concurrent.TimeUnit.NANOSECONDS; 261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static java.util.concurrent.TimeUnit.SECONDS; 271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.GwtCompatible; 291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.GwtIncompatible; 301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Ticker; 311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.cache.TestingRemovalListeners.CountingRemovalListener; 321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.cache.TestingRemovalListeners.QueuingRemovalListener; 331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.collect.Maps; 341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.collect.Sets; 351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.testing.NullPointerTester; 361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 370888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport junit.framework.TestCase; 380888a09821a98ac0680fad765217302858e70fa4Paul Duffin 391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Map; 401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Random; 411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Set; 421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.concurrent.CountDownLatch; 431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.concurrent.ExecutorService; 441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.concurrent.Executors; 451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.concurrent.TimeUnit; 461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.concurrent.atomic.AtomicBoolean; 471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.concurrent.atomic.AtomicInteger; 481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/** 501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Unit tests for CacheBuilder. 511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@GwtCompatible(emulated = true) 531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpublic class CacheBuilderTest extends TestCase { 541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testNewBuilder() { 561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheLoader<Object, Integer> loader = constantLoader(1); 571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LoadingCache<String, Integer> cache = CacheBuilder.newBuilder() 591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .removalListener(countingRemovalListener()) 601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .build(loader); 611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(Integer.valueOf(1), cache.getUnchecked("one")); 631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, cache.size()); 641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testInitialCapacity_negative() { 671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheBuilder<Object, Object> builder = new CacheBuilder<Object, Object>(); 681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert builder.initialCapacity(-1); 701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert fail(); 711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (IllegalArgumentException expected) {} 721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testInitialCapacity_setTwice() { 751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheBuilder<Object, Object> builder = new CacheBuilder<Object, Object>().initialCapacity(16); 761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // even to the same value is not allowed 781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert builder.initialCapacity(16); 791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert fail(); 801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (IllegalStateException expected) {} 811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible("CacheTesting") 841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testInitialCapacity_small() { 851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LoadingCache<?, ?> cache = CacheBuilder.newBuilder() 861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .initialCapacity(5) 871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .build(identityLoader()); 881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<?, ?> map = CacheTesting.toLocalCache(cache); 891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(4, map.segments.length); 911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(2, map.segments[0].table.length()); 921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(2, map.segments[1].table.length()); 931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(2, map.segments[2].table.length()); 941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(2, map.segments[3].table.length()); 951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible("CacheTesting") 981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testInitialCapacity_smallest() { 991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LoadingCache<?, ?> cache = CacheBuilder.newBuilder() 1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .initialCapacity(0) 1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .build(identityLoader()); 1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<?, ?> map = CacheTesting.toLocalCache(cache); 1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(4, map.segments.length); 1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // 1 is as low as it goes, not 0. it feels dirty to know this/test this. 1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, map.segments[0].table.length()); 1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, map.segments[1].table.length()); 1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, map.segments[2].table.length()); 1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, map.segments[3].table.length()); 1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testInitialCapacity_large() { 1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheBuilder.newBuilder().initialCapacity(Integer.MAX_VALUE); 1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // that the builder didn't blow up is enough; 1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // don't actually create this monster! 1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testConcurrencyLevel_zero() { 1191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheBuilder<Object, Object> builder = new CacheBuilder<Object, Object>(); 1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert builder.concurrencyLevel(0); 1221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert fail(); 1231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (IllegalArgumentException expected) {} 1241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testConcurrencyLevel_setTwice() { 1271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheBuilder<Object, Object> builder = new CacheBuilder<Object, Object>().concurrencyLevel(16); 1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // even to the same value is not allowed 1301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert builder.concurrencyLevel(16); 1311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert fail(); 1321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (IllegalStateException expected) {} 1331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible("CacheTesting") 1361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testConcurrencyLevel_small() { 1371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LoadingCache<?, ?> cache = CacheBuilder.newBuilder() 1381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .concurrencyLevel(1) 1391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .build(identityLoader()); 1401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<?, ?> map = CacheTesting.toLocalCache(cache); 1411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, map.segments.length); 1421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testConcurrencyLevel_large() { 1451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheBuilder.newBuilder().concurrencyLevel(Integer.MAX_VALUE); 1461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // don't actually build this beast 1471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testMaximumSize_negative() { 1501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheBuilder<Object, Object> builder = new CacheBuilder<Object, Object>(); 1511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 1521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert builder.maximumSize(-1); 1531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert fail(); 1541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (IllegalArgumentException expected) {} 1551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testMaximumSize_setTwice() { 1581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheBuilder<Object, Object> builder = new CacheBuilder<Object, Object>().maximumSize(16); 1591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 1601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // even to the same value is not allowed 1611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert builder.maximumSize(16); 1621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert fail(); 1631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (IllegalStateException expected) {} 1641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible("maximumWeight") 1671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testMaximumSize_andWeight() { 1681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheBuilder<Object, Object> builder = new CacheBuilder<Object, Object>().maximumSize(16); 1691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 1701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert builder.maximumWeight(16); 1711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert fail(); 1721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (IllegalStateException expected) {} 1731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible("maximumWeight") 1761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testMaximumWeight_negative() { 1771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheBuilder<Object, Object> builder = new CacheBuilder<Object, Object>(); 1781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 1791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert builder.maximumWeight(-1); 1801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert fail(); 1811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (IllegalArgumentException expected) {} 1821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible("maximumWeight") 1851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testMaximumWeight_setTwice() { 1861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheBuilder<Object, Object> builder = new CacheBuilder<Object, Object>().maximumWeight(16); 1871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 1881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // even to the same value is not allowed 1891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert builder.maximumWeight(16); 1901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert fail(); 1911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (IllegalStateException expected) {} 1921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 1931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert builder.maximumSize(16); 1941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert fail(); 1951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (IllegalStateException expected) {} 1961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible("maximumWeight") 1991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testMaximumWeight_withoutWeigher() { 2001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheBuilder<Object, Object> builder = new CacheBuilder<Object, Object>() 2011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .maximumWeight(1); 2021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 2031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert builder.build(identityLoader()); 2041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert fail(); 2051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (IllegalStateException expected) {} 2061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible("weigher") 2091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testWeigher_withoutMaximumWeight() { 2101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheBuilder<Object, Object> builder = new CacheBuilder<Object, Object>() 2111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .weigher(constantWeigher(42)); 2121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 2131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert builder.build(identityLoader()); 2141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert fail(); 2151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (IllegalStateException expected) {} 2161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible("weigher") 2191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testWeigher_withMaximumSize() { 2201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 2211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheBuilder<Object, Object> builder = new CacheBuilder<Object, Object>() 2221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .weigher(constantWeigher(42)) 2231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .maximumSize(1); 2241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert fail(); 2251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (IllegalStateException expected) {} 2261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 2271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheBuilder<Object, Object> builder = new CacheBuilder<Object, Object>() 2281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .maximumSize(1) 2291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .weigher(constantWeigher(42)); 2301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert fail(); 2311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (IllegalStateException expected) {} 2321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible("weakKeys") 2351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testKeyStrengthSetTwice() { 2361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheBuilder<Object, Object> builder1 = new CacheBuilder<Object, Object>().weakKeys(); 2371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 2381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert builder1.weakKeys(); 2391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert fail(); 2401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (IllegalStateException expected) {} 2411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible("weakValues") 2441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testValueStrengthSetTwice() { 2451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheBuilder<Object, Object> builder1 = new CacheBuilder<Object, Object>().weakValues(); 2461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 2471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert builder1.weakValues(); 2481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert fail(); 2491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (IllegalStateException expected) {} 2501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 2511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert builder1.softValues(); 2521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert fail(); 2531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (IllegalStateException expected) {} 2541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheBuilder<Object, Object> builder2 = new CacheBuilder<Object, Object>().softValues(); 2561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 2571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert builder2.softValues(); 2581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert fail(); 2591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (IllegalStateException expected) {} 2601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 2611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert builder2.weakValues(); 2621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert fail(); 2631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (IllegalStateException expected) {} 2641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testTimeToLive_negative() { 2671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheBuilder<Object, Object> builder = new CacheBuilder<Object, Object>(); 2681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 2691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert builder.expireAfterWrite(-1, SECONDS); 2701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert fail(); 2711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (IllegalArgumentException expected) {} 2721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testTimeToLive_small() { 2751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheBuilder.newBuilder() 2761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .expireAfterWrite(1, NANOSECONDS) 2771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .build(identityLoader()); 2781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // well, it didn't blow up. 2791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testTimeToLive_setTwice() { 2821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheBuilder<Object, Object> builder = 2831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert new CacheBuilder<Object, Object>().expireAfterWrite(3600, SECONDS); 2841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 2851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // even to the same value is not allowed 2861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert builder.expireAfterWrite(3600, SECONDS); 2871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert fail(); 2881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (IllegalStateException expected) {} 2891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testTimeToIdle_negative() { 2921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheBuilder<Object, Object> builder = new CacheBuilder<Object, Object>(); 2931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 2941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert builder.expireAfterAccess(-1, SECONDS); 2951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert fail(); 2961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (IllegalArgumentException expected) {} 2971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testTimeToIdle_small() { 3001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheBuilder.newBuilder() 3011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .expireAfterAccess(1, NANOSECONDS) 3021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .build(identityLoader()); 3031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // well, it didn't blow up. 3041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testTimeToIdle_setTwice() { 3071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheBuilder<Object, Object> builder = 3081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert new CacheBuilder<Object, Object>().expireAfterAccess(3600, SECONDS); 3091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 3101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // even to the same value is not allowed 3111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert builder.expireAfterAccess(3600, SECONDS); 3121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert fail(); 3131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (IllegalStateException expected) {} 3141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testTimeToIdleAndToLive() { 3171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheBuilder.newBuilder() 3181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .expireAfterWrite(1, NANOSECONDS) 3191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .expireAfterAccess(1, NANOSECONDS) 3201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .build(identityLoader()); 3211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // well, it didn't blow up. 3221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible("refreshAfterWrite") 3251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testRefresh_zero() { 3261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheBuilder<Object, Object> builder = new CacheBuilder<Object, Object>(); 3271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 3281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert builder.refreshAfterWrite(0, SECONDS); 3291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert fail(); 3301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (IllegalArgumentException expected) {} 3311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible("refreshAfterWrite") 3341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testRefresh_setTwice() { 3351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheBuilder<Object, Object> builder = 3361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert new CacheBuilder<Object, Object>().refreshAfterWrite(3600, SECONDS); 3371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 3381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // even to the same value is not allowed 3391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert builder.refreshAfterWrite(3600, SECONDS); 3401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert fail(); 3411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (IllegalStateException expected) {} 3421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testTicker_setTwice() { 3451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Ticker testTicker = Ticker.systemTicker(); 3461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheBuilder<Object, Object> builder = 3471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert new CacheBuilder<Object, Object>().ticker(testTicker); 3481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 3491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // even to the same instance is not allowed 3501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert builder.ticker(testTicker); 3511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert fail(); 3521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (IllegalStateException expected) {} 3531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testRemovalListener_setTwice() { 3561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert RemovalListener<Object, Object> testListener = nullRemovalListener(); 3571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheBuilder<Object, Object> builder = 3581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert new CacheBuilder<Object, Object>().removalListener(testListener); 3591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 3601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // even to the same instance is not allowed 3611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert builder = builder.removalListener(testListener); 3621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert fail(); 3631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (IllegalStateException expected) {} 3641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3667dd252788645e940eada959bdde927426e2531c9Paul Duffin @GwtIncompatible("CacheTesting") 3671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testNullCache() { 3681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CountingRemovalListener<Object, Object> listener = countingRemovalListener(); 3691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LoadingCache<Object, Object> nullCache = new CacheBuilder<Object, Object>() 3701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .maximumSize(0) 3711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .removalListener(listener) 3721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .build(identityLoader()); 3731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(0, nullCache.size()); 3741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object key = new Object(); 3751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(key, nullCache.getUnchecked(key)); 3761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, listener.getCount()); 3771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(0, nullCache.size()); 3781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheTesting.checkEmpty(nullCache.asMap()); 3791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3817dd252788645e940eada959bdde927426e2531c9Paul Duffin @GwtIncompatible("QueuingRemovalListener") 3821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testRemovalNotification_clear() throws InterruptedException { 3841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // If a clear() happens while a computation is pending, we should not get a removal 3851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // notification. 3861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final AtomicBoolean shouldWait = new AtomicBoolean(false); 3881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final CountDownLatch computingLatch = new CountDownLatch(1); 3891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheLoader<String, String> computingFunction = new CacheLoader<String, String>() { 3901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public String load(String key) throws InterruptedException { 3911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (shouldWait.get()) { 3921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert computingLatch.await(); 3931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return key; 3951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 3971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert QueuingRemovalListener<String, String> listener = queuingRemovalListener(); 3981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final LoadingCache<String, String> cache = CacheBuilder.newBuilder() 4001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .concurrencyLevel(1) 4011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .removalListener(listener) 4021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .build(computingFunction); 4031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // seed the map, so its segment's count > 0 4051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert cache.getUnchecked("a"); 4061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert shouldWait.set(true); 4071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final CountDownLatch computationStarted = new CountDownLatch(1); 4091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final CountDownLatch computationComplete = new CountDownLatch(1); 4101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert new Thread(new Runnable() { 4111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void run() { 4121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert computationStarted.countDown(); 4131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert cache.getUnchecked("b"); 4141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert computationComplete.countDown(); 4151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }).start(); 4171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // wait for the computingEntry to be created 4191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert computationStarted.await(); 4201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert cache.invalidateAll(); 4211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // let the computation proceed 4221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert computingLatch.countDown(); 4231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // don't check cache.size() until we know the get("b") call is complete 4241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert computationComplete.await(); 4251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // At this point, the listener should be holding the seed value (a -> a), and the map should 4271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // contain the computed value (b -> b), since the clear() happened before the computation 4281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // completed. 4291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, listener.size()); 4301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert RemovalNotification<String, String> notification = listener.remove(); 4311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals("a", notification.getKey()); 4321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals("a", notification.getValue()); 4331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, cache.size()); 4341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals("b", cache.getUnchecked("b")); 4351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // "Basher tests", where we throw a bunch of stuff at a LoadingCache and check basic invariants. 4381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 4401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * This is a less carefully-controlled version of {@link #testRemovalNotification_clear} - this is 4411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * a black-box test that tries to create lots of different thread-interleavings, and asserts that 4421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * each computation is affected by a call to {@code clear()} (and therefore gets passed to the 4431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * removal listener), or else is not affected by the {@code clear()} (and therefore exists in the 4441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * cache afterward). 4451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 4467dd252788645e940eada959bdde927426e2531c9Paul Duffin @GwtIncompatible("QueuingRemovalListener") 4471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testRemovalNotification_clear_basher() throws InterruptedException { 4491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // If a clear() happens close to the end of computation, one of two things should happen: 4501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // - computation ends first: the removal listener is called, and the cache does not contain the 4511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // key/value pair 4521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // - clear() happens first: the removal listener is not called, and the cache contains the pair 4531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert AtomicBoolean computationShouldWait = new AtomicBoolean(); 4541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CountDownLatch computationLatch = new CountDownLatch(1); 4551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert QueuingRemovalListener<String, String> listener = queuingRemovalListener(); 4561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final LoadingCache <String, String> cache = CacheBuilder.newBuilder() 4571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .removalListener(listener) 4581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .concurrencyLevel(20) 4591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .build( 4601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert new DelayingIdentityLoader<String>(computationShouldWait, computationLatch)); 4611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int nThreads = 100; 4631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int nTasks = 1000; 4641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int nSeededEntries = 100; 4651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<String> expectedKeys = Sets.newHashSetWithExpectedSize(nTasks + nSeededEntries); 4661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // seed the map, so its segments have a count>0; otherwise, clear() won't visit the in-progress 4671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // entries 4681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 0; i < nSeededEntries; i++) { 4691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert String s = "b" + i; 4701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert cache.getUnchecked(s); 4711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert expectedKeys.add(s); 4721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert computationShouldWait.set(true); 4741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final AtomicInteger computedCount = new AtomicInteger(); 4761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ExecutorService threadPool = Executors.newFixedThreadPool(nThreads); 4771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final CountDownLatch tasksFinished = new CountDownLatch(nTasks); 4781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 0; i < nTasks; i++) { 4791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final String s = "a" + i; 4801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert threadPool.submit(new Runnable() { 4811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void run() { 4821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert cache.getUnchecked(s); 4831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert computedCount.incrementAndGet(); 4841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert tasksFinished.countDown(); 4851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }); 4871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert expectedKeys.add(s); 4881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert computationLatch.countDown(); 4911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // let some computations complete 4921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert while (computedCount.get() < nThreads) { 4931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Thread.yield(); 4941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert cache.invalidateAll(); 4961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert tasksFinished.await(); 4971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // Check all of the removal notifications we received: they should have had correctly-associated 4991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // keys and values. (An earlier bug saw removal notifications for in-progress computations, 5001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // which had real keys with null values.) 5011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<String, String> removalNotifications = Maps.newHashMap(); 5021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (RemovalNotification<String, String> notification : listener) { 5031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert removalNotifications.put(notification.getKey(), notification.getValue()); 5041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals("Unexpected key/value pair passed to removalListener", 5051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert notification.getKey(), notification.getValue()); 5061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // All of the seed values should have been visible, so we should have gotten removal 5091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // notifications for all of them. 5101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 0; i < nSeededEntries; i++) { 5111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals("b" + i, removalNotifications.get("b" + i)); 5121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // Each of the values added to the map should either still be there, or have seen a removal 5151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // notification. 5161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(expectedKeys, Sets.union(cache.asMap().keySet(), removalNotifications.keySet())); 5171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(Sets.intersection(cache.asMap().keySet(), removalNotifications.keySet()).isEmpty()); 5181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 5211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Calls get() repeatedly from many different threads, and tests that all of the removed entries 5221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * (removed because of size limits or expiration) trigger appropriate removal notifications. 5231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 5247dd252788645e940eada959bdde927426e2531c9Paul Duffin @GwtIncompatible("QueuingRemovalListener") 5251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testRemovalNotification_get_basher() throws InterruptedException { 5277dd252788645e940eada959bdde927426e2531c9Paul Duffin int nTasks = 1000; 5281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int nThreads = 100; 5291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final int getsPerTask = 1000; 5301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final int nUniqueKeys = 10000; 5311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Random random = new Random(); // Randoms.insecureRandom(); 5321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert QueuingRemovalListener<String, String> removalListener = queuingRemovalListener(); 5341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final AtomicInteger computeCount = new AtomicInteger(); 5351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final AtomicInteger exceptionCount = new AtomicInteger(); 5361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final AtomicInteger computeNullCount = new AtomicInteger(); 5371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheLoader<String, String> countingIdentityLoader = 5381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert new CacheLoader<String, String>() { 5391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public String load(String key) throws InterruptedException { 5401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int behavior = random.nextInt(4); 5411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (behavior == 0) { // throw an exception 5421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert exceptionCount.incrementAndGet(); 5431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new RuntimeException("fake exception for test"); 5441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else if (behavior == 1) { // return null 5451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert computeNullCount.incrementAndGet(); 5461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return null; 5471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else if (behavior == 2) { // slight delay before returning 5481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Thread.sleep(5); 5491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert computeCount.incrementAndGet(); 5501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return key; 5511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else { 5521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert computeCount.incrementAndGet(); 5531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return key; 5541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 5571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final LoadingCache<String, String> cache = CacheBuilder.newBuilder() 5587dd252788645e940eada959bdde927426e2531c9Paul Duffin .recordStats() 5591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .concurrencyLevel(2) 5601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .expireAfterWrite(100, TimeUnit.MILLISECONDS) 5611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .removalListener(removalListener) 5621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .maximumSize(5000) 5631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .build(countingIdentityLoader); 5641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ExecutorService threadPool = Executors.newFixedThreadPool(nThreads); 5661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 0; i < nTasks; i++) { 5671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert threadPool.submit(new Runnable() { 5681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void run() { 5691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int j = 0; j < getsPerTask; j++) { 5701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 5711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert cache.getUnchecked("key" + random.nextInt(nUniqueKeys)); 5721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (RuntimeException e) { 5731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }); 5771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert threadPool.shutdown(); 5801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert threadPool.awaitTermination(300, TimeUnit.SECONDS); 5811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // Since we're not doing any more cache operations, and the cache only expires/evicts when doing 5831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // other operations, the cache and the removal queue won't change from this point on. 5841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // Verify that each received removal notification was valid 5861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (RemovalNotification<String, String> notification : removalListener) { 5871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals("Invalid removal notification", notification.getKey(), notification.getValue()); 5881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheStats stats = cache.stats(); 5911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(removalListener.size(), stats.evictionCount()); 5921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(computeCount.get(), stats.loadSuccessCount()); 5931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(exceptionCount.get() + computeNullCount.get(), stats.loadExceptionCount()); 5941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // each computed value is still in the cache, or was passed to the removal listener 5951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(computeCount.get(), cache.size() + removalListener.size()); 5961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible("NullPointerTester") 5991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testNullParameters() throws Exception { 6001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert NullPointerTester tester = new NullPointerTester(); 6011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheBuilder<Object, Object> builder = new CacheBuilder<Object, Object>(); 6021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert tester.testAllPublicInstanceMethods(builder); 6031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible("CacheTesting") 6061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testSizingDefaults() { 6071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LoadingCache<?, ?> cache = CacheBuilder.newBuilder().build(identityLoader()); 6081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<?, ?> map = CacheTesting.toLocalCache(cache); 6091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(4, map.segments.length); // concurrency level 6101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(4, map.segments[0].table.length()); // capacity / conc level 6111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible("CountDownLatch") 6141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static final class DelayingIdentityLoader<T> extends CacheLoader<T, T> { 6151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private final AtomicBoolean shouldWait; 6161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private final CountDownLatch delayLatch; 6171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert DelayingIdentityLoader(AtomicBoolean shouldWait, CountDownLatch delayLatch) { 6191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.shouldWait = shouldWait; 6201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.delayLatch = delayLatch; 6211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public T load(T key) throws InterruptedException { 6241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (shouldWait.get()) { 6251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert delayLatch.await(); 6261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return key; 6281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert} 631