ben-manes / caffeine

Test files should contain tests JAVA-W1088
Anti-pattern
Minor
16 occurrences in this check
20/**
21 * @author [email protected] (Ben Manes)
22 */
23public final class TestWeigher implements Weigher<Integer, Integer> {24  @Override public int weigh(Integer key, Integer value) {25    return 0;26  }27}
24/**
25 * @author [email protected] (Ben Manes)
26 */
27public final class TestScheduler implements Scheduler {2829  @Override30  public Future<?> schedule(Executor executor, Runnable command, long delay, TimeUnit unit) {31    return Scheduler.disabledScheduler().schedule(executor, command, delay, unit);32  }33}
20/**
21 * @author [email protected] (Ben Manes)
22 */
23public final class TestExpiry implements Expiry<Integer, Integer> {2425  @Override26  public long expireAfterCreate(Integer key, Integer value, long currentTime) {27    return Long.MAX_VALUE;28  }2930  @Override31  public long expireAfterUpdate(Integer key, Integer value,32      long currentTime, long currentDuration) {33    return Long.MAX_VALUE;34  }3536  @Override37  public long expireAfterRead(Integer key, Integer value, long currentTime, long currentDuration) {38    return Long.MAX_VALUE;39  }40}
20/**
21 * @author [email protected] (Ben Manes)
22 */
23public final class TestExecutor implements Executor {24  @Override public void execute(Runnable command) {25    command.run();26  }27}
23/**
24 * @author [email protected] (Ben Manes)
25 */
26public final class TestCacheWriter implements CacheWriter<Integer, Integer> {27  @Override public void write(Cache.Entry<? extends Integer, ? extends Integer> entry) {}28  @Override public void writeAll(29      Collection<Cache.Entry<? extends Integer, ? extends Integer>> entries) {}30  @Override public void delete(Object key) {}31  @Override public void deleteAll(Collection<?> keys) {}32}
22/**
23 * @author [email protected] (Ben Manes)
24 */
25public final class TestCacheLoader implements CacheLoader<Integer, Integer> {26  @Override public Integer load(Integer key) {27    return null;28  }29  @SuppressWarnings("ReturnsNullCollection")30  @Override public Map<Integer, Integer> loadAll(Iterable<? extends Integer> keys) {31    return null;32  }33}
20/**
21 * @author [email protected] (Ben Manes)
22 */
23public final class TestCacheEntryListener implements CacheEntryListener<Integer, Integer> {}
21/**
22 * @author [email protected] (Ben Manes)
23 */
24public final class TestCacheEntryEventFilter implements CacheEntryEventFilter<Integer, Integer> {25  @Override public boolean evaluate(CacheEntryEvent<? extends Integer, ? extends Integer> event) {26    return false;27  }28}
21 *
22 * @author Charles Fry
23 */
24public class TestingWeighers {2526  /**27   * Returns a {@link Weigher} that returns the given {@code constant} for every request.28   */29  static Weigher<Object, Object> constantWeigher(int constant) {30    return new ConstantWeigher(constant);31  }3233  /**34   * Returns a {@link Weigher} that uses the integer key as the weight.35   */36  static Weigher<Integer, Object> intKeyWeigher() {37    return new IntKeyWeigher();38  }3940  /**41   * Returns a {@link Weigher} that uses the integer value as the weight.42   */43  static Weigher<Object, Integer> intValueWeigher() {44    return new IntValueWeigher();45  }4647  static final class ConstantWeigher implements Weigher<Object, Object> {48    private final int constant;4950    ConstantWeigher(int constant) {51      this.constant = constant;52    }5354    @Override55    public int weigh(Object key, Object value) {56      return constant;57    }58  }5960  static final class IntKeyWeigher implements Weigher<Integer, Object> {61    @Override62    public int weigh(Integer key, Object value) {63      return key;64    }65  }6667  static final class IntValueWeigher implements Weigher<Object, Integer> {68    @Override69    public int weigh(Object key, Integer value) {70      return value;71    }72  }7374}
 29 * @author mike nonemacher
 30 */
 31@GwtCompatible(emulated = true)
 32class TestingRemovalListeners { 33 34  /** 35   * Returns a new no-op {@code RemovalListener}. 36   */ 37  static <K, V> NullRemovalListener<K, V> nullRemovalListener() { 38    return new NullRemovalListener<K, V>(); 39  } 40 41  /** 42   * Type-inferring factory method for creating a {@link QueuingRemovalListener}. 43   */ 44  @GwtIncompatible("ConcurrentLinkedQueue") 45  static <K, V> QueuingRemovalListener<K, V> queuingRemovalListener() { 46    return new QueuingRemovalListener<K,V>(); 47  } 48 49  /** 50   * Type-inferring factory method for creating a {@link CountingRemovalListener}. 51   */ 52  static <K, V> CountingRemovalListener<K, V> countingRemovalListener() { 53    return new CountingRemovalListener<K,V>(); 54  } 55 56  /** 57   * {@link RemovalListener} that adds all {@link RemovalNotification} objects to a queue. 58   */ 59  @GwtIncompatible("ConcurrentLinkedQueue") 60  static class QueuingRemovalListener<K, V> 61      extends ConcurrentLinkedQueue<RemovalNotification<K, V>> implements RemovalListener<K, V> { 62    private static final long serialVersionUID = 1L; 63 64    @Override 65    public void onRemoval(K key, V value, RemovalCause cause) { 66      add(RemovalNotification.create(key, value, 67          com.google.common.cache.RemovalCause.valueOf(cause.name()))); 68    } 69  } 70 71  /** 72   * {@link RemovalListener} that counts each {@link RemovalNotification} it receives, and provides 73   * access to the most-recently received one. 74   */ 75  static class CountingRemovalListener<K, V> implements RemovalListener<K, V> { 76    private final AtomicInteger count = new AtomicInteger(); 77    private volatile RemovalNotification<K, V> lastNotification; 78 79    @Override 80    public void onRemoval(K key, V value, RemovalCause cause) { 81      count.incrementAndGet(); 82      lastNotification = RemovalNotification.create(key, value, 83          com.google.common.cache.RemovalCause.valueOf(cause.name())); 84    } 85 86    public int getCount() { 87      return count.get(); 88    } 89 90    public K getLastEvictedKey() { 91      return lastNotification.getKey(); 92    } 93 94    public V getLastEvictedValue() { 95      return lastNotification.getValue(); 96    } 97 98    public RemovalNotification<K, V> getLastNotification() { 99      return lastNotification;100    }101  }102103  /**104   * No-op {@link RemovalListener}.105   */106  static class NullRemovalListener<K, V> implements RemovalListener<K, V> {107    @Override108    public void onRemoval(K key, V value, RemovalCause cause) {}109  }110}
 36 * @author mike nonemacher
 37 */
 38@GwtCompatible(emulated = true)
 39public class TestingCacheLoaders { 40 41  /** 42   * Returns a {@link CacheLoader} that implements a naive {@link CacheLoader#loadAll}, delegating 43   * {@link CacheLoader#load} calls to {@code loader}. 44   */ 45  public static <K, V> CacheLoader<K, V> bulkLoader(final CacheLoader<K, V> loader) { 46    checkNotNull(loader); 47    return new CacheLoader<K, V>() { 48      @Override 49      public V load(K key) throws Exception { 50        return loader.load(key); 51      } 52 53      @Override 54      public Map<K, V> loadAll(Iterable<? extends K> keys) throws Exception { 55        Map<K, V> result = Maps.newHashMap(); // allow nulls 56        for (K key : keys) { 57          result.put(key, load(key)); 58        } 59        return result; 60      } 61    }; 62  } 63 64  /** 65   * Returns a {@link CacheLoader} that returns the given {@code constant} for every request. 66   */ 67  static <K, V> ConstantLoader<K, V> constantLoader(@Nullable V constant) { 68    return new ConstantLoader<K, V>(constant); 69  } 70 71  /** 72   * Returns a {@link CacheLoader} that returns the given {@code constant} for every request. 73   */ 74  static IncrementingLoader incrementingLoader() { 75    return new IncrementingLoader(); 76  } 77 78  /** 79   * Returns a {@link CacheLoader} that throws the given error for every request. 80   */ 81  static <K, V> CacheLoader<K, V> errorLoader(final Error e) { 82    checkNotNull(e); 83    return new CacheLoader<K, V>() { 84      @Override 85      public V load(K key) { 86        throw e; 87      } 88    }; 89  } 90 91  /** 92   * Returns a {@link CacheLoader} that throws the given exception for every request. 93   */ 94  static <K, V> CacheLoader<K, V> exceptionLoader(final Exception e) { 95    checkNotNull(e); 96    return new CacheLoader<K, V>() { 97      @Override 98      public V load(K key) throws Exception { 99        throw e;100      }101    };102  }103104  /**105   * Returns a {@link CacheLoader} that returns the key for every request.106   */107  public static <T> IdentityLoader<T> identityLoader() {108    return new IdentityLoader<T>();109  }110111  /**112   * Returns a {@code new Object()} for every request, and increments a counter for every request.113   * The count is accessible via {@link #getCount}.114   */115  static class CountingLoader extends CacheLoader<Object, Object> {116    private final AtomicInteger count = new AtomicInteger();117118    @Override119    public Object load(Object from) {120      count.incrementAndGet();121      return new Object();122    }123124    public int getCount() {125      return count.get();126    }127  }128129  static final class ConstantLoader<K, V> extends CacheLoader<K, V> {130    private final V constant;131132    ConstantLoader(V constant) {133      this.constant = constant;134    }135136    @Override137    public V load(K key) {138      return constant;139    }140  }141142  /**143   * Returns a {@code new Object()} for every request, and increments a counter for every request.144   * An {@code Integer} loader that returns the key for {@code load} requests, and increments the145   * old value on {@code reload} requests. The load counts are accessible via {@link #getLoadCount}146   * and {@link #getReloadCount}.147   */148  static class IncrementingLoader extends CacheLoader<Integer, Integer> {149    private final AtomicInteger countLoad = new AtomicInteger();150    private final AtomicInteger countReload = new AtomicInteger();151152    @Override153    @CanIgnoreReturnValue154    public Integer load(Integer key) {155      countLoad.incrementAndGet();156      return key;157    }158159    @GwtIncompatible("reload")160    @Override161    public ListenableFuture<Integer> reload(Integer key, Integer oldValue) {162      countReload.incrementAndGet();163      return Futures.immediateFuture(oldValue + 1);164    }165166    public int getLoadCount() {167      return countLoad.get();168    }169170    public int getReloadCount() {171      return countReload.get();172    }173  }174175  public static final class IdentityLoader<T> extends CacheLoader<T, T> implements Serializable {176    private static final long serialVersionUID = 1L;177178    @CanIgnoreReturnValue179    @Override public T load(T key) {180      return key;181    }182  }183}
 26 * @author Charles Fry
 27 */
 28@SuppressWarnings("JUnit3FloatingPointComparisonWithoutDelta")
 29public class CacheStatsTest extends TestCase { 30 31  public void testEmpty() { 32    CacheStats stats = CacheStats.of(0, 0, 0, 0, 0, 0, 0); 33    assertEquals(0, stats.requestCount()); 34    assertEquals(0, stats.hitCount()); 35    assertEquals(1.0, stats.hitRate()); 36    assertEquals(0, stats.missCount()); 37    assertEquals(0.0, stats.missRate()); 38    assertEquals(0, stats.loadSuccessCount()); 39    assertEquals(0, stats.loadFailureCount()); 40    assertEquals(0.0, stats.loadFailureRate()); 41    assertEquals(0, stats.loadCount()); 42    assertEquals(0, stats.totalLoadTime()); 43    assertEquals(0.0, stats.averageLoadPenalty()); 44    assertEquals(0, stats.evictionCount()); 45  } 46 47  public void testSingle() { 48    CacheStats stats = CacheStats.of(11, 13, 17, 19, 23, 27, 54); 49    assertEquals(24, stats.requestCount()); 50    assertEquals(11, stats.hitCount()); 51    assertEquals(11.0/24, stats.hitRate()); 52    assertEquals(13, stats.missCount()); 53    assertEquals(13.0/24, stats.missRate()); 54    assertEquals(17, stats.loadSuccessCount()); 55    assertEquals(19, stats.loadFailureCount()); 56    assertEquals(19.0/36, stats.loadFailureRate()); 57    assertEquals(17 + 19, stats.loadCount()); 58    assertEquals(23, stats.totalLoadTime()); 59    assertEquals(23.0/(17 + 19), stats.averageLoadPenalty()); 60    assertEquals(27, stats.evictionCount()); 61    assertEquals(54, stats.evictionWeight()); 62  } 63 64  public void testMinus() { 65    CacheStats one = CacheStats.of(11, 13, 17, 19, 23, 27, 54); 66    CacheStats two = CacheStats.of(53, 47, 43, 41, 37, 31, 62); 67 68    CacheStats diff = two.minus(one); 69    assertEquals(76, diff.requestCount()); 70    assertEquals(42, diff.hitCount()); 71    assertEquals(42.0/76, diff.hitRate()); 72    assertEquals(34, diff.missCount()); 73    assertEquals(34.0/76, diff.missRate()); 74    assertEquals(26, diff.loadSuccessCount()); 75    assertEquals(22, diff.loadFailureCount()); 76    assertEquals(22.0/48, diff.loadFailureRate()); 77    assertEquals(26 + 22, diff.loadCount()); 78    assertEquals(14, diff.totalLoadTime()); 79    assertEquals(14.0/(26 + 22), diff.averageLoadPenalty()); 80    assertEquals(4, diff.evictionCount()); 81    assertEquals(8, diff.evictionWeight()); 82 83    assertEquals(CacheStats.of(0, 0, 0, 0, 0, 0, 0), one.minus(two)); 84  } 85 86  public void testPlus() { 87    CacheStats one = CacheStats.of(11, 13, 15, 13, 11, 9, 18); 88    CacheStats two = CacheStats.of(53, 47, 41, 39, 37, 35, 70); 89 90    CacheStats sum = two.plus(one); 91    assertEquals(124, sum.requestCount()); 92    assertEquals(64, sum.hitCount()); 93    assertEquals(64.0/124, sum.hitRate()); 94    assertEquals(60, sum.missCount()); 95    assertEquals(60.0/124, sum.missRate()); 96    assertEquals(56, sum.loadSuccessCount()); 97    assertEquals(52, sum.loadFailureCount()); 98    assertEquals(52.0/108, sum.loadFailureRate()); 99    assertEquals(56 + 52, sum.loadCount());100    assertEquals(48, sum.totalLoadTime());101    assertEquals(48.0/(56 + 52), sum.averageLoadPenalty());102    assertEquals(44, sum.evictionCount());103    assertEquals(88, sum.evictionWeight());104105    assertEquals(sum, one.plus(two));106  }107108  public void testPlusLarge() {109    CacheStats maxCacheStats =110        CacheStats.of(111            Long.MAX_VALUE,112            Long.MAX_VALUE,113            Long.MAX_VALUE,114            Long.MAX_VALUE,115            Long.MAX_VALUE,116            Long.MAX_VALUE,117            Long.MAX_VALUE);118    CacheStats smallCacheStats = CacheStats.of(1, 1, 1, 1, 1, 1, 1);119120    CacheStats sum = smallCacheStats.plus(maxCacheStats);121    assertEquals(Long.MAX_VALUE, sum.requestCount());122    assertEquals(Long.MAX_VALUE, sum.hitCount());123    assertEquals(1.0, sum.hitRate());124    assertEquals(Long.MAX_VALUE, sum.missCount());125    assertEquals(1.0, sum.missRate());126    assertEquals(Long.MAX_VALUE, sum.loadSuccessCount());127    assertEquals(Long.MAX_VALUE, sum.loadFailureCount());128    assertEquals(1.0, sum.loadFailureRate());129    assertEquals(Long.MAX_VALUE, sum.loadCount());130    assertEquals(Long.MAX_VALUE, sum.totalLoadTime());131    assertEquals(1.0, sum.averageLoadPenalty());132    assertEquals(Long.MAX_VALUE, sum.evictionCount());133    assertEquals(Long.MAX_VALUE, sum.evictionWeight());134135    assertEquals(sum, maxCacheStats.plus(smallCacheStats));136  }137}
 38 * @author mike nonemacher
 39 */
 40@SuppressWarnings("MapEntry")
 41public class CacheReferencesTest extends TestCase { 42 43  private static final CacheLoader<Key,String> KEY_TO_STRING_LOADER = 44      new CacheLoader<Key, String>() { 45        @Override public String load(Key key) { 46          return key.toString(); 47        } 48      }; 49 50  private CacheBuilderFactory factoryWithAllKeyStrengths() { 51    return new CacheBuilderFactory() 52        .withKeyStrengths(ImmutableSet.of(STRONG, Strength.WEAK)) 53        .withValueStrengths(ImmutableSet.of(STRONG, Strength.WEAK, Strength.SOFT)); 54  } 55 56  private Iterable<LoadingCache<Key, String>> caches() { 57    CacheBuilderFactory factory = factoryWithAllKeyStrengths(); 58    return Iterables.transform(factory.buildAllPermutations(), 59        new Function<Caffeine<Object, Object>, LoadingCache<Key, String>>() { 60          @Override public LoadingCache<Key, String> apply(Caffeine<Object, Object> builder) { 61            return CaffeinatedGuava.build(builder, KEY_TO_STRING_LOADER); 62          } 63        }); 64  } 65 66  public void testContainsKeyAndValue() { 67    for (LoadingCache<Key, String> cache : caches()) { 68      // maintain strong refs so these won't be collected, regardless of cache's key/value strength 69      Key key = new Key(1); 70      String value = key.toString(); 71      assertSame(value, cache.getUnchecked(key)); 72      assertTrue(cache.asMap().containsKey(key)); 73      assertTrue(cache.asMap().containsValue(value)); 74      assertEquals(1, cache.size()); 75    } 76  } 77 78  public void testClear() { 79    for (LoadingCache<Key, String> cache : caches()) { 80      Key key = new Key(1); 81      String value = key.toString(); 82      assertSame(value, cache.getUnchecked(key)); 83      assertFalse(cache.asMap().isEmpty()); 84      cache.invalidateAll(); 85      assertEquals(0, cache.size()); 86      assertTrue(cache.asMap().isEmpty()); 87      assertFalse(cache.asMap().containsKey(key)); 88      assertFalse(cache.asMap().containsValue(value)); 89    } 90  } 91 92  public void testKeySetEntrySetValues() { 93    for (LoadingCache<Key, String> cache : caches()) { 94      Key key1 = new Key(1); 95      String value1 = key1.toString(); 96      Key key2 = new Key(2); 97      String value2 = key2.toString(); 98      assertSame(value1, cache.getUnchecked(key1)); 99      assertSame(value2, cache.getUnchecked(key2));100      assertEquals(ImmutableSet.of(key1, key2), cache.asMap().keySet());101      assertThat(cache.asMap().values()).containsExactly(value1, value2);102      assertEquals(ImmutableSet.of(immutableEntry(key1, value1), immutableEntry(key2, value2)),103          cache.asMap().entrySet());104    }105  }106107  public void testInvalidate() {108    for (LoadingCache<Key, String> cache : caches()) {109      Key key1 = new Key(1);110      String value1 = key1.toString();111      Key key2 = new Key(2);112      String value2 = key2.toString();113      assertSame(value1, cache.getUnchecked(key1));114      assertSame(value2, cache.getUnchecked(key2));115      cache.invalidate(key1);116      assertFalse(cache.asMap().containsKey(key1));117      assertTrue(cache.asMap().containsKey(key2));118      assertEquals(1, cache.size());119      assertEquals(ImmutableSet.of(key2), cache.asMap().keySet());120      assertThat(cache.asMap().values()).contains(value2);121      assertEquals(ImmutableSet.of(immutableEntry(key2, value2)), cache.asMap().entrySet());122    }123  }124125  // A simple type whose .toString() will return the same value each time, but without maintaining126  // a strong reference to that value.127  static class Key {128    private final int value;129    private WeakReference<String> toString;130131    Key(int value) {132      this.value = value;133    }134135    @Override public synchronized String toString() {136      String s;137      if (toString != null) {138        s = toString.get();139        if (s != null) {140          return s;141        }142      }143      s = Integer.toString(value);144      toString = new WeakReference<String>(s);145      return s;146    }147  }148}
 27/**
 28 * @author Charles Fry
 29 */
 30public class CacheManualTest extends TestCase { 31 32  public void testGetIfPresent() { 33    Cache<Object, Object> cache = CaffeinatedGuava.build(Caffeine.newBuilder().recordStats()); 34    CacheStats stats = cache.stats(); 35    assertEquals(0, stats.missCount()); 36    assertEquals(0, stats.loadSuccessCount()); 37    assertEquals(0, stats.loadExceptionCount()); 38    assertEquals(0, stats.hitCount()); 39 40    Object one = new Object(); 41    Object two = new Object(); 42 43    assertNull(cache.getIfPresent(one)); 44    stats = cache.stats(); 45    assertEquals(1, stats.missCount()); 46    assertEquals(0, stats.loadSuccessCount()); 47    assertEquals(0, stats.loadExceptionCount()); 48    assertEquals(0, stats.hitCount()); 49    assertNull(cache.asMap().get(one)); 50    assertFalse(cache.asMap().containsKey(one)); 51    assertFalse(cache.asMap().containsValue(two)); 52 53    assertNull(cache.getIfPresent(two)); 54    stats = cache.stats(); 55    assertEquals(2, stats.missCount()); 56    assertEquals(0, stats.loadSuccessCount()); 57    assertEquals(0, stats.loadExceptionCount()); 58    assertEquals(0, stats.hitCount()); 59    assertNull(cache.asMap().get(two)); 60    assertFalse(cache.asMap().containsKey(two)); 61    assertFalse(cache.asMap().containsValue(one)); 62 63    cache.put(one, two); 64 65    assertSame(two, cache.getIfPresent(one)); 66    stats = cache.stats(); 67    assertEquals(2, stats.missCount()); 68    assertEquals(0, stats.loadSuccessCount()); 69    assertEquals(0, stats.loadExceptionCount()); 70    assertEquals(1, stats.hitCount()); 71    assertSame(two, cache.asMap().get(one)); 72    assertTrue(cache.asMap().containsKey(one)); 73    assertTrue(cache.asMap().containsValue(two)); 74 75    assertNull(cache.getIfPresent(two)); 76    stats = cache.stats(); 77    assertEquals(3, stats.missCount()); 78    assertEquals(0, stats.loadSuccessCount()); 79    assertEquals(0, stats.loadExceptionCount()); 80    assertEquals(1, stats.hitCount()); 81    assertNull(cache.asMap().get(two)); 82    assertFalse(cache.asMap().containsKey(two)); 83    assertFalse(cache.asMap().containsValue(one)); 84 85    cache.put(two, one); 86 87    assertSame(two, cache.getIfPresent(one)); 88    stats = cache.stats(); 89    assertEquals(3, stats.missCount()); 90    assertEquals(0, stats.loadSuccessCount()); 91    assertEquals(0, stats.loadExceptionCount()); 92    assertEquals(2, stats.hitCount()); 93    assertSame(two, cache.asMap().get(one)); 94    assertTrue(cache.asMap().containsKey(one)); 95    assertTrue(cache.asMap().containsValue(two)); 96 97    assertSame(one, cache.getIfPresent(two)); 98    stats = cache.stats(); 99    assertEquals(3, stats.missCount());100    assertEquals(0, stats.loadSuccessCount());101    assertEquals(0, stats.loadExceptionCount());102    assertEquals(3, stats.hitCount());103    assertSame(one, cache.asMap().get(two));104    assertTrue(cache.asMap().containsKey(two));105    assertTrue(cache.asMap().containsValue(one));106  }107108  public void testGetAllPresent() {109    Cache<Integer, Integer> cache = CaffeinatedGuava.build(Caffeine.newBuilder().recordStats());110    CacheStats stats = cache.stats();111    assertEquals(0, stats.missCount());112    assertEquals(0, stats.loadSuccessCount());113    assertEquals(0, stats.loadExceptionCount());114    assertEquals(0, stats.hitCount());115116    assertEquals(ImmutableMap.of(), cache.getAllPresent(ImmutableList.<Integer>of()));117    stats = cache.stats();118    assertEquals(0, stats.missCount());119    assertEquals(0, stats.loadSuccessCount());120    assertEquals(0, stats.loadExceptionCount());121    assertEquals(0, stats.hitCount());122123    assertEquals(ImmutableMap.of(), cache.getAllPresent(asList(1, 2, 3)));124    stats = cache.stats();125    assertEquals(3, stats.missCount());126    assertEquals(0, stats.loadSuccessCount());127    assertEquals(0, stats.loadExceptionCount());128    assertEquals(0, stats.hitCount());129130    cache.put(2, 22);131132    assertEquals(ImmutableMap.of(2, 22), cache.getAllPresent(asList(1, 2, 3)));133    stats = cache.stats();134    assertEquals(5, stats.missCount());135    assertEquals(0, stats.loadSuccessCount());136    assertEquals(0, stats.loadExceptionCount());137    assertEquals(1, stats.hitCount());138139    cache.put(3, 33);140141    assertEquals(ImmutableMap.of(2, 22, 3, 33), cache.getAllPresent(asList(1, 2, 3)));142    stats = cache.stats();143    assertEquals(6, stats.missCount());144    assertEquals(0, stats.loadSuccessCount());145    assertEquals(0, stats.loadExceptionCount());146    assertEquals(3, stats.hitCount());147148    cache.put(1, 11);149150    assertEquals(ImmutableMap.of(1, 11, 2, 22, 3, 33), cache.getAllPresent(asList(1, 2, 3)));151    stats = cache.stats();152    assertEquals(6, stats.missCount());153    assertEquals(0, stats.loadSuccessCount());154    assertEquals(0, stats.loadExceptionCount());155    assertEquals(6, stats.hitCount());156  }157158}
 28 *
 29 * @author Charles Fry
 30 */
 31public class AbstractCacheTest extends TestCase { 32 33  public void testEmptySimpleStats() { 34    StatsCounter counter = new ConcurrentStatsCounter(); 35    CacheStats stats = counter.snapshot(); 36    assertEquals(0, stats.requestCount()); 37    assertEquals(0, stats.hitCount()); 38    assertEquals(1.0, stats.hitRate(), 0.0); 39    assertEquals(0, stats.missCount()); 40    assertEquals(0.0, stats.missRate(), 0.0); 41    assertEquals(0, stats.loadSuccessCount()); 42    assertEquals(0, stats.loadFailureCount()); 43    assertEquals(0, stats.loadCount()); 44    assertEquals(0, stats.totalLoadTime()); 45    assertEquals(0.0, stats.averageLoadPenalty(), 0.0); 46    assertEquals(0, stats.evictionCount()); 47  } 48 49  public void testSingleSimpleStats() { 50    StatsCounter counter = new ConcurrentStatsCounter(); 51    for (int i = 0; i < 11; i++) { 52      counter.recordHits(1); 53    } 54    for (int i = 0; i < 13; i++) { 55      counter.recordLoadSuccess(i); 56    } 57    for (int i = 0; i < 17; i++) { 58      counter.recordLoadFailure(i); 59    } 60    for (int i = 0; i < 23; i++) { 61      counter.recordMisses(1); 62    } 63    for (int i = 0; i < 27; i++) { 64      counter.recordEviction(1, RemovalCause.SIZE); 65    } 66    CacheStats stats = counter.snapshot(); 67    int requestCount = 11 + 23; 68    assertEquals(requestCount, stats.requestCount()); 69    assertEquals(11, stats.hitCount()); 70    assertEquals(11.0 / requestCount, stats.hitRate(), 0.0); 71    int missCount = 23; 72    assertEquals(missCount, stats.missCount()); 73    assertEquals(((double) missCount) / requestCount, stats.missRate(), 0.0); 74    assertEquals(13, stats.loadSuccessCount()); 75    assertEquals(17, stats.loadFailureCount()); 76    assertEquals(13 + 17, stats.loadCount()); 77    assertEquals(214, stats.totalLoadTime()); 78    assertEquals(214.0 / (13 + 17), stats.averageLoadPenalty(), 0.0); 79    assertEquals(27, stats.evictionCount()); 80  } 81 82  public void testSimpleStatsOverflow() { 83    StatsCounter counter = new ConcurrentStatsCounter(); 84    counter.recordLoadSuccess(Long.MAX_VALUE); 85    counter.recordLoadSuccess(1); 86    CacheStats stats = counter.snapshot(); 87    assertEquals(Long.MAX_VALUE, stats.totalLoadTime()); 88  } 89 90  public void testSimpleStatsIncrementBy() { 91    long totalLoadTime = 0; 92 93    ConcurrentStatsCounter counter1 = new ConcurrentStatsCounter(); 94    for (int i = 0; i < 11; i++) { 95      counter1.recordHits(1); 96    } 97    for (int i = 0; i < 13; i++) { 98      counter1.recordLoadSuccess(i); 99      totalLoadTime += i;100    }101    for (int i = 0; i < 17; i++) {102      counter1.recordLoadFailure(i);103      totalLoadTime += i;104    }105    for (int i = 0; i < 19; i++) {106      counter1.recordMisses(1);107    }108    for (int i = 0; i < 23; i++) {109      counter1.recordEviction(1, RemovalCause.SIZE);110    }111112    ConcurrentStatsCounter counter2 = new ConcurrentStatsCounter();113    for (int i = 0; i < 27; i++) {114      counter2.recordHits(1);115    }116    for (int i = 0; i < 31; i++) {117      counter2.recordLoadSuccess(i);118      totalLoadTime += i;119    }120    for (int i = 0; i < 37; i++) {121      counter2.recordLoadFailure(i);122      totalLoadTime += i;123    }124    for (int i = 0; i < 41; i++) {125      counter2.recordMisses(1);126    }127    for (int i = 0; i < 43; i++) {128      counter1.recordEviction(1, RemovalCause.SIZE);129    }130131    counter1.incrementBy(counter2);132    assertEquals(CacheStats.of(38, 60, 44, 54, totalLoadTime, 66, 66), counter1.snapshot());133  }134}
 36 *
 37 * @author [email protected] (Wim Deblauwe)
 38 */
 39public final class WriteBehindCacheWriterTest { 40 41  @Test 42  public void singleKey() { 43    var writerCalled = new AtomicBoolean(); 44 45    // Given this cache... 46    var writer = new WriteBehindCacheWriter.Builder<Integer, ZonedDateTime>() 47        .coalesce(BinaryOperator.maxBy(ZonedDateTime::compareTo)) 48        .writeAction(entries -> writerCalled.set(true)) 49        .bufferTime(Duration.ofSeconds(1)) 50        .build(); 51    Cache<Integer, ZonedDateTime> cache = Caffeine.newBuilder().build(); 52 53    // When this cache update happens... 54    cache.asMap().computeIfAbsent(1, key -> { 55      var value = ZonedDateTime.now(); 56      writer.accept(key, value); 57      return value; 58    }); 59 60    // Then the write behind action is called 61    await().untilTrue(writerCalled); 62  } 63 64  @Test 65  public void multipleKeys() { 66    var numberOfEntries = new AtomicInteger(); 67 68    // Given this cache... 69    var writer = new WriteBehindCacheWriter.Builder<Integer, ZonedDateTime>() 70        .writeAction(entries -> numberOfEntries.addAndGet(entries.size())) 71        .coalesce(BinaryOperator.maxBy(ZonedDateTime::compareTo)) 72        .bufferTime(Duration.ofSeconds(1)) 73        .build(); 74    Cache<Integer, ZonedDateTime> cache = Caffeine.newBuilder().build(); 75 76    // When these cache updates happen... 77    for (int i = 1; i <= 3; i++) { 78      cache.asMap().computeIfAbsent(i, key -> { 79        var value = ZonedDateTime.now(); 80        writer.accept(key, value); 81        return value; 82      }); 83    } 84 85    // Then the write behind action gets 3 entries to write 86    await().untilAtomic(numberOfEntries, is(3)); 87  } 88 89  @Test 90  public void singleKey_mostRecent() { 91    var timeInWriteBehind = new AtomicReference<ZonedDateTime>(); 92    var numberOfEntries = new AtomicInteger(); 93 94    // Given this cache... 95    var writer = new WriteBehindCacheWriter.Builder<Long, ZonedDateTime>() 96        .coalesce(BinaryOperator.maxBy(ZonedDateTime::compareTo)) 97        .bufferTime(Duration.ofSeconds(1)) 98        .writeAction(entries -> { 99          // We might get here before the cache has been written to,100          // so just wait for the next time we are called101          if (entries.isEmpty()) {102            return;103          }104105          var zonedDateTime = entries.values().iterator().next();106          timeInWriteBehind.set(zonedDateTime);107          numberOfEntries.set(entries.size());108        }).build();109    Cache<Long, ZonedDateTime> cache = Caffeine.newBuilder().build();110111    // When these cache updates happen...112    var latest = ZonedDateTime.now().truncatedTo(DAYS);113    for (int i = 0; i < 4; i++) {114      latest = latest.plusNanos(200);115116      var value = latest;117      cache.asMap().compute(1L, (key, oldValue) -> {118        writer.accept(key, value);119        return value;120      });121    }122123    // Then the write behind action gets 1 entry to write with the most recent time124    await().untilAtomic(numberOfEntries, is(1));125    await().untilAtomic(timeInWriteBehind, is(latest));126  }127}