CacheBuilderSpecTest.java revision 3c77433663281544363151bf284b0240dfd22a42
1/*
2 * Copyright (C) 2011 The Guava Authors
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.google.common.cache;
18
19import static com.google.common.cache.CacheBuilderSpec.parse;
20import static com.google.common.cache.TestingWeighers.constantWeigher;
21
22import com.google.common.base.Suppliers;
23import com.google.common.cache.LocalCache.Strength;
24import com.google.common.testing.EqualsTester;
25
26import junit.framework.TestCase;
27
28import java.util.concurrent.TimeUnit;
29
30/**
31 * Tests CacheBuilderSpec.
32 * TODO(user): tests of a few invalid input conditions, boundary conditions.
33 *
34 * @author Adam Winer
35 */
36public class CacheBuilderSpecTest extends TestCase {
37  public void testParse_empty() {
38    CacheBuilderSpec spec = parse("");
39    assertNull(spec.initialCapacity);
40    assertNull(spec.maximumSize);
41    assertNull(spec.maximumWeight);
42    assertNull(spec.concurrencyLevel);
43    assertNull(spec.keyStrength);
44    assertNull(spec.valueStrength);
45    assertNull(spec.writeExpirationTimeUnit);
46    assertNull(spec.accessExpirationTimeUnit);
47    assertCacheBuilderEquivalence(CacheBuilder.newBuilder(), CacheBuilder.from(spec));
48  }
49
50  public void testParse_initialCapacity() {
51    CacheBuilderSpec spec = parse("initialCapacity=10");
52    assertEquals(10, spec.initialCapacity.intValue());
53    assertNull(spec.maximumSize);
54    assertNull(spec.maximumWeight);
55    assertNull(spec.concurrencyLevel);
56    assertNull(spec.keyStrength);
57    assertNull(spec.valueStrength);
58    assertNull(spec.writeExpirationTimeUnit);
59    assertNull(spec.accessExpirationTimeUnit);
60    assertCacheBuilderEquivalence(
61        CacheBuilder.newBuilder().initialCapacity(10), CacheBuilder.from(spec));
62  }
63
64  public void testParse_initialCapacityRepeated() {
65    try {
66      parse("initialCapacity=10, initialCapacity=20");
67      fail("Expected exception");
68    } catch (IllegalArgumentException expected) {
69      // expected
70    }
71  }
72
73  public void testParse_maximumSize() {
74    CacheBuilderSpec spec = parse("maximumSize=9000");
75    assertNull(spec.initialCapacity);
76    assertEquals(9000, spec.maximumSize.longValue());
77    assertNull(spec.concurrencyLevel);
78    assertNull(spec.keyStrength);
79    assertNull(spec.valueStrength);
80    assertNull(spec.writeExpirationTimeUnit);
81    assertNull(spec.accessExpirationTimeUnit);
82    assertCacheBuilderEquivalence(
83        CacheBuilder.newBuilder().maximumSize(9000), CacheBuilder.from(spec));
84  }
85
86  public void testParse_maximumSizeRepeated() {
87    try {
88      parse("maximumSize=10, maximumSize=20");
89      fail("Expected exception");
90    } catch (IllegalArgumentException expected) {
91      // expected
92    }
93  }
94
95  public void testParse_maximumWeight() {
96    CacheBuilderSpec spec = parse("maximumWeight=9000");
97    assertNull(spec.initialCapacity);
98    assertEquals(9000, spec.maximumWeight.longValue());
99    assertNull(spec.concurrencyLevel);
100    assertNull(spec.keyStrength);
101    assertNull(spec.valueStrength);
102    assertNull(spec.writeExpirationTimeUnit);
103    assertNull(spec.accessExpirationTimeUnit);
104    assertCacheBuilderEquivalence(
105        CacheBuilder.newBuilder().maximumWeight(9000), CacheBuilder.from(spec));
106  }
107
108  public void testParse_maximumWeightRepeated() {
109    try {
110      parse("maximumWeight=10, maximumWeight=20");
111      fail("Expected exception");
112    } catch (IllegalArgumentException expected) {
113      // expected
114    }
115  }
116
117  public void testParse_maximumSizeAndMaximumWeight() {
118    try {
119      parse("maximumSize=10, maximumWeight=20");
120      fail("Expected exception");
121    } catch (IllegalArgumentException expected) {
122      // expected
123    }
124  }
125
126  public void testParse_concurrencyLevel() {
127    CacheBuilderSpec spec = parse("concurrencyLevel=32");
128    assertNull(spec.initialCapacity);
129    assertNull(spec.maximumSize);
130    assertNull(spec.maximumWeight);
131    assertEquals(32, spec.concurrencyLevel.intValue());
132    assertNull(spec.keyStrength);
133    assertNull(spec.valueStrength);
134    assertNull(spec.writeExpirationTimeUnit);
135    assertNull(spec.accessExpirationTimeUnit);
136    assertCacheBuilderEquivalence(
137        CacheBuilder.newBuilder().concurrencyLevel(32), CacheBuilder.from(spec));
138  }
139
140  public void testParse_concurrencyLevelRepeated() {
141    try {
142      parse("concurrencyLevel=10, concurrencyLevel=20");
143      fail("Expected exception");
144    } catch (IllegalArgumentException expected) {
145      // expected
146    }
147  }
148
149  public void testParse_weakKeys() {
150    CacheBuilderSpec spec = parse("weakKeys");
151    assertNull(spec.initialCapacity);
152    assertNull(spec.maximumSize);
153    assertNull(spec.maximumWeight);
154    assertNull(spec.concurrencyLevel);
155    assertEquals(Strength.WEAK, spec.keyStrength);
156    assertNull(spec.valueStrength);
157    assertNull(spec.writeExpirationTimeUnit);
158    assertNull(spec.accessExpirationTimeUnit);
159    assertCacheBuilderEquivalence(
160        CacheBuilder.newBuilder().weakKeys(), CacheBuilder.from(spec));
161  }
162
163  public void testParse_weakKeysCannotHaveValue() {
164    try {
165      parse("weakKeys=true");
166      fail("Expected exception");
167    } catch (IllegalArgumentException expected) {
168      // expected
169    }
170  }
171
172  public void testParse_repeatedKeyStrength() {
173    try {
174      parse("weakKeys, weakKeys");
175      fail("Expected exception");
176    } catch (IllegalArgumentException expected) {
177      // expected
178    }
179  }
180
181  public void testParse_softValues() {
182    CacheBuilderSpec spec = parse("softValues");
183    assertNull(spec.initialCapacity);
184    assertNull(spec.maximumSize);
185    assertNull(spec.maximumWeight);
186    assertNull(spec.concurrencyLevel);
187    assertNull(spec.keyStrength);
188    assertEquals(Strength.SOFT, spec.valueStrength);
189    assertNull(spec.writeExpirationTimeUnit);
190    assertNull(spec.accessExpirationTimeUnit);
191    assertCacheBuilderEquivalence(
192        CacheBuilder.newBuilder().softValues(), CacheBuilder.from(spec));
193  }
194
195  public void testParse_softValuesCannotHaveValue() {
196    try {
197      parse("softValues=true");
198      fail("Expected exception");
199    } catch (IllegalArgumentException expected) {
200      // expected
201    }
202  }
203
204  public void testParse_weakValues() {
205    CacheBuilderSpec spec = parse("weakValues");
206    assertNull(spec.initialCapacity);
207    assertNull(spec.maximumSize);
208    assertNull(spec.maximumWeight);
209    assertNull(spec.concurrencyLevel);
210    assertNull(spec.keyStrength);
211    assertEquals(Strength.WEAK, spec.valueStrength);
212    assertNull(spec.writeExpirationTimeUnit);
213    assertNull(spec.accessExpirationTimeUnit);
214    assertCacheBuilderEquivalence(
215        CacheBuilder.newBuilder().weakValues(), CacheBuilder.from(spec));
216  }
217
218  public void testParse_weakValuesCannotHaveValue() {
219    try {
220      parse("weakValues=true");
221      fail("Expected exception");
222    } catch (IllegalArgumentException expected) {
223      // expected
224    }
225  }
226
227  public void testParse_repeatedValueStrength() {
228    try {
229      parse("softValues, softValues");
230      fail("Expected exception");
231    } catch (IllegalArgumentException expected) {
232      // expected
233    }
234
235    try {
236      parse("softValues, weakValues");
237      fail("Expected exception");
238    } catch (IllegalArgumentException expected) {
239      // expected
240    }
241
242    try {
243      parse("weakValues, softValues");
244      fail("Expected exception");
245    } catch (IllegalArgumentException expected) {
246      // expected
247    }
248
249    try {
250      parse("weakValues, weakValues");
251      fail("Expected exception");
252    } catch (IllegalArgumentException expected) {
253      // expected
254    }
255  }
256
257  public void testParse_writeExpirationDays() {
258    CacheBuilderSpec spec = parse("expireAfterWrite=10d");
259    assertNull(spec.initialCapacity);
260    assertNull(spec.maximumSize);
261    assertNull(spec.maximumWeight);
262    assertNull(spec.concurrencyLevel);
263    assertNull(spec.keyStrength);
264    assertNull(spec.valueStrength);
265    assertEquals(TimeUnit.DAYS, spec.writeExpirationTimeUnit);
266    assertEquals(10L, spec.writeExpirationDuration);
267    assertNull(spec.accessExpirationTimeUnit);
268    assertCacheBuilderEquivalence(
269        CacheBuilder.newBuilder().expireAfterWrite(10L, TimeUnit.DAYS), CacheBuilder.from(spec));
270  }
271
272  public void testParse_writeExpirationHours() {
273    CacheBuilderSpec spec = parse("expireAfterWrite=150h");
274    assertEquals(TimeUnit.HOURS, spec.writeExpirationTimeUnit);
275    assertEquals(150L, spec.writeExpirationDuration);
276    assertCacheBuilderEquivalence(
277        CacheBuilder.newBuilder().expireAfterWrite(150L, TimeUnit.HOURS), CacheBuilder.from(spec));
278  }
279
280  public void testParse_writeExpirationMinutes() {
281    CacheBuilderSpec spec = parse("expireAfterWrite=10m");
282    assertEquals(TimeUnit.MINUTES, spec.writeExpirationTimeUnit);
283    assertEquals(10L, spec.writeExpirationDuration);
284    assertCacheBuilderEquivalence(
285        CacheBuilder.newBuilder().expireAfterWrite(10L, TimeUnit.MINUTES), CacheBuilder.from(spec));
286  }
287
288  public void testParse_writeExpirationSeconds() {
289    CacheBuilderSpec spec = parse("expireAfterWrite=10s");
290    assertEquals(TimeUnit.SECONDS, spec.writeExpirationTimeUnit);
291    assertEquals(10L, spec.writeExpirationDuration);
292    assertCacheBuilderEquivalence(
293        CacheBuilder.newBuilder().expireAfterWrite(10L, TimeUnit.SECONDS), CacheBuilder.from(spec));
294  }
295
296  public void testParse_writeExpirationRepeated() {
297    try {
298      parse(
299          "expireAfterWrite=10s,expireAfterWrite=10m");
300      fail("Expected exception");
301    } catch (IllegalArgumentException expected) {
302      // expected
303    }
304  }
305
306  public void testParse_accessExpirationDays() {
307    CacheBuilderSpec spec = parse("expireAfterAccess=10d");
308    assertNull(spec.initialCapacity);
309    assertNull(spec.maximumSize);
310    assertNull(spec.maximumWeight);
311    assertNull(spec.concurrencyLevel);
312    assertNull(spec.keyStrength);
313    assertNull(spec.valueStrength);
314    assertNull(spec.writeExpirationTimeUnit);
315    assertEquals(TimeUnit.DAYS, spec.accessExpirationTimeUnit);
316    assertEquals(10L, spec.accessExpirationDuration);
317    assertCacheBuilderEquivalence(
318        CacheBuilder.newBuilder().expireAfterAccess(10L, TimeUnit.DAYS), CacheBuilder.from(spec));
319  }
320
321  public void testParse_accessExpirationHours() {
322    CacheBuilderSpec spec = parse("expireAfterAccess=150h");
323    assertEquals(TimeUnit.HOURS, spec.accessExpirationTimeUnit);
324    assertEquals(150L, spec.accessExpirationDuration);
325    assertCacheBuilderEquivalence(
326        CacheBuilder.newBuilder().expireAfterAccess(150L, TimeUnit.HOURS), CacheBuilder.from(spec));
327  }
328
329  public void testParse_accessExpirationMinutes() {
330    CacheBuilderSpec spec = parse("expireAfterAccess=10m");
331    assertEquals(TimeUnit.MINUTES, spec.accessExpirationTimeUnit);
332    assertEquals(10L, spec.accessExpirationDuration);
333    assertCacheBuilderEquivalence(
334        CacheBuilder.newBuilder().expireAfterAccess(10L, TimeUnit.MINUTES),
335        CacheBuilder.from(spec));
336  }
337
338  public void testParse_accessExpirationSeconds() {
339    CacheBuilderSpec spec = parse("expireAfterAccess=10s");
340    assertEquals(TimeUnit.SECONDS, spec.accessExpirationTimeUnit);
341    assertEquals(10L, spec.accessExpirationDuration);
342    assertCacheBuilderEquivalence(
343        CacheBuilder.newBuilder().expireAfterAccess(10L, TimeUnit.SECONDS),
344        CacheBuilder.from(spec));
345  }
346
347  public void testParse_accessExpirationRepeated() {
348    try {
349      parse(
350          "expireAfterAccess=10s,expireAfterAccess=10m");
351      fail("Expected exception");
352    } catch (IllegalArgumentException expected) {
353      // expected
354    }
355  }
356
357  public void testParse_accessExpirationAndWriteExpiration() {
358    CacheBuilderSpec spec = parse("expireAfterAccess=10s,expireAfterWrite=9m");
359    assertEquals(TimeUnit.MINUTES, spec.writeExpirationTimeUnit);
360    assertEquals(9L, spec.writeExpirationDuration);
361    assertEquals(TimeUnit.SECONDS, spec.accessExpirationTimeUnit);
362    assertEquals(10L, spec.accessExpirationDuration);
363    assertCacheBuilderEquivalence(
364        CacheBuilder.newBuilder()
365          .expireAfterAccess(10L, TimeUnit.SECONDS)
366          .expireAfterWrite(9L, TimeUnit.MINUTES),
367        CacheBuilder.from(spec));
368  }
369
370  public void testParse_multipleKeys() {
371    CacheBuilderSpec spec = parse("initialCapacity=10,maximumSize=20,concurrencyLevel=30,"
372        + "weakKeys,weakValues,expireAfterAccess=10m,expireAfterWrite=1h");
373    assertEquals(10, spec.initialCapacity.intValue());
374    assertEquals(20, spec.maximumSize.intValue());
375    assertNull(spec.maximumWeight);
376    assertEquals(30, spec.concurrencyLevel.intValue());
377    assertEquals(Strength.WEAK, spec.keyStrength);
378    assertEquals(Strength.WEAK, spec.valueStrength);
379    assertEquals(TimeUnit.HOURS, spec.writeExpirationTimeUnit);
380    assertEquals(TimeUnit.MINUTES, spec.accessExpirationTimeUnit);
381    assertEquals(1L, spec.writeExpirationDuration);
382    assertEquals(10L, spec.accessExpirationDuration);
383    CacheBuilder expected = CacheBuilder.newBuilder()
384        .initialCapacity(10)
385        .maximumSize(20)
386        .concurrencyLevel(30)
387        .weakKeys()
388        .weakValues()
389        .expireAfterAccess(10L, TimeUnit.MINUTES)
390        .expireAfterWrite(1L, TimeUnit.HOURS);
391    assertCacheBuilderEquivalence(expected, CacheBuilder.from(spec));
392  }
393
394  public void testParse_whitespaceAllowed() {
395    CacheBuilderSpec spec = parse(" initialCapacity=10,\nmaximumSize=20,\t\r"
396        + "weakKeys \t ,softValues \n , \r  expireAfterWrite \t =  15s\n\n");
397    assertEquals(10, spec.initialCapacity.intValue());
398    assertEquals(20, spec.maximumSize.intValue());
399    assertNull(spec.maximumWeight);
400    assertNull(spec.concurrencyLevel);
401    assertEquals(Strength.WEAK, spec.keyStrength);
402    assertEquals(Strength.SOFT, spec.valueStrength);
403    assertEquals(TimeUnit.SECONDS, spec.writeExpirationTimeUnit);
404    assertEquals(15L, spec.writeExpirationDuration);
405    assertNull(spec.accessExpirationTimeUnit);
406    CacheBuilder expected = CacheBuilder.newBuilder()
407        .initialCapacity(10)
408        .maximumSize(20)
409        .weakKeys()
410        .softValues()
411        .expireAfterWrite(15L, TimeUnit.SECONDS);
412    assertCacheBuilderEquivalence(expected, CacheBuilder.from(spec));
413  }
414
415  public void testParse_unknownKey() {
416    try {
417      parse("foo=17");
418      fail("Expected exception");
419    } catch (IllegalArgumentException expected) {
420      // expected
421    }
422  }
423
424  public void testParse_extraCommaIsInvalid() {
425    try {
426      parse("weakKeys,");
427      fail("Expected exception");
428    } catch (IllegalArgumentException expected) {
429      // expected
430    }
431
432    try {
433      parse(",weakKeys");
434      fail("Expected exception");
435    } catch (IllegalArgumentException expected) {
436      // expected
437    }
438
439    try {
440      parse("weakKeys,,softValues");
441      fail("Expected exception");
442    } catch (IllegalArgumentException expected) {
443      // expected
444    }
445  }
446
447  public void testEqualsAndHashCode() {
448    new EqualsTester()
449        .addEqualityGroup(parse(""), parse(""))
450        .addEqualityGroup(parse("concurrencyLevel=7"), parse("concurrencyLevel=7"))
451        .addEqualityGroup(parse("concurrencyLevel=15"), parse("concurrencyLevel=15"))
452        .addEqualityGroup(parse("initialCapacity=7"), parse("initialCapacity=7"))
453        .addEqualityGroup(parse("initialCapacity=15"), parse("initialCapacity=15"))
454        .addEqualityGroup(parse("maximumSize=7"), parse("maximumSize=7"))
455        .addEqualityGroup(parse("maximumSize=15"), parse("maximumSize=15"))
456        .addEqualityGroup(parse("maximumWeight=7"), parse("maximumWeight=7"))
457        .addEqualityGroup(parse("maximumWeight=15"), parse("maximumWeight=15"))
458        .addEqualityGroup(parse("expireAfterAccess=60s"), parse("expireAfterAccess=1m"))
459        .addEqualityGroup(parse("expireAfterAccess=60m"), parse("expireAfterAccess=1h"))
460        .addEqualityGroup(parse("expireAfterWrite=60s"), parse("expireAfterWrite=1m"))
461        .addEqualityGroup(parse("expireAfterWrite=60m"), parse("expireAfterWrite=1h"))
462        .addEqualityGroup(parse("weakKeys"), parse("weakKeys"))
463        .addEqualityGroup(parse("softValues"), parse("softValues"))
464        .addEqualityGroup(parse("weakValues"), parse("weakValues"))
465        .testEquals();
466  }
467
468  public void testMaximumWeight_withWeigher() {
469    CacheBuilder<Object, Object> builder = CacheBuilder.from(parse("maximumWeight=9000"));
470    builder
471        .weigher(constantWeigher(42))
472        .build(CacheLoader.from(Suppliers.ofInstance(null)));
473  }
474
475  public void testMaximumWeight_withoutWeigher() {
476    CacheBuilder<Object, Object> builder = CacheBuilder.from(parse("maximumWeight=9000"));
477    try {
478      builder.build(CacheLoader.from(Suppliers.ofInstance(null)));
479      fail();
480    } catch (IllegalStateException expected) {}
481  }
482
483  public void testMaximumSize_withWeigher() {
484    CacheBuilder<Object, Object> builder = CacheBuilder.from(parse("maximumSize=9000"));
485    builder
486        .weigher(constantWeigher(42))
487        .build(CacheLoader.from(Suppliers.ofInstance(null)));
488  }
489
490  public void testMaximumSize_withoutWeigher() {
491    CacheBuilder<Object, Object> builder = CacheBuilder.from(parse("maximumSize=9000"));
492    builder.build(CacheLoader.from(Suppliers.ofInstance(null)));
493  }
494
495  public void testDisableCaching() {
496    // Functional test: assert that CacheBuilderSpec.disableCaching()
497    // disables caching.  It's irrelevant how it does so.
498    CacheBuilder<Object, Object> builder = CacheBuilder.from(CacheBuilderSpec.disableCaching());
499    Object key = new Object();
500    Object value = new Object();
501    LoadingCache<Object, Object> cache = builder.build(
502        CacheLoader.from(Suppliers.ofInstance(value)));
503    assertSame(value, cache.getUnchecked(key));
504    assertEquals(0, cache.size());
505    assertFalse(cache.asMap().containsKey(key));
506  }
507
508  public void testCacheBuilderFrom_string() {
509    CacheBuilder fromString = CacheBuilder.from(
510        "initialCapacity=10,maximumSize=20,concurrencyLevel=30,"
511        + "weakKeys,weakValues,expireAfterAccess=10m");
512    CacheBuilder expected = CacheBuilder.newBuilder()
513        .initialCapacity(10)
514        .maximumSize(20)
515        .concurrencyLevel(30)
516        .weakKeys()
517        .weakValues()
518        .expireAfterAccess(10L, TimeUnit.MINUTES);
519    assertCacheBuilderEquivalence(expected, fromString);
520  }
521
522  private static void assertCacheBuilderEquivalence(CacheBuilder a, CacheBuilder b) {
523    assertEquals("concurrencyLevel", a.concurrencyLevel, b.concurrencyLevel);
524    assertEquals("expireAfterAccessNanos", a.expireAfterAccessNanos, b.expireAfterAccessNanos);
525    assertEquals("expireAfterWriteNanos", a.expireAfterWriteNanos, b.expireAfterWriteNanos);
526    assertEquals("initialCapacity", a.initialCapacity, b.initialCapacity);
527    assertEquals("maximumSize", a.maximumSize, b.maximumSize);
528    assertEquals("maximumWeight", a.maximumWeight, b.maximumWeight);
529    assertEquals("refreshNanos", a.refreshNanos, b.refreshNanos);
530    assertEquals("keyEquivalence", a.keyEquivalence, b.keyEquivalence);
531    assertEquals("keyStrength", a.keyStrength, b.keyStrength);
532    assertEquals("removalListener", a.removalListener, b.removalListener);
533    assertEquals("weigher", a.weigher, b.weigher);
534    assertEquals("valueEquivalence", a.valueEquivalence, b.valueEquivalence);
535    assertEquals("valueStrength", a.valueStrength, b.valueStrength);
536    assertEquals("statsCounterSupplier", a.statsCounterSupplier, b.statsCounterSupplier);
537    assertEquals("ticker", a.ticker, b.ticker);
538  }
539}
540