1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.google.common.cache;
18
19 import static com.google.common.cache.CacheBuilderSpec.parse;
20 import static com.google.common.cache.TestingWeighers.constantWeigher;
21
22 import com.google.common.base.Suppliers;
23 import com.google.common.cache.LocalCache.Strength;
24 import com.google.common.testing.EqualsTester;
25
26 import junit.framework.TestCase;
27
28 import java.util.concurrent.TimeUnit;
29
30
31
32
33
34
35
36 public 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
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
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
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
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
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
169 }
170 }
171
172 public void testParse_repeatedKeyStrength() {
173 try {
174 parse("weakKeys, weakKeys");
175 fail("Expected exception");
176 } catch (IllegalArgumentException expected) {
177
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
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
224 }
225 }
226
227 public void testParse_repeatedValueStrength() {
228 try {
229 parse("softValues, softValues");
230 fail("Expected exception");
231 } catch (IllegalArgumentException expected) {
232
233 }
234
235 try {
236 parse("softValues, weakValues");
237 fail("Expected exception");
238 } catch (IllegalArgumentException expected) {
239
240 }
241
242 try {
243 parse("weakValues, softValues");
244 fail("Expected exception");
245 } catch (IllegalArgumentException expected) {
246
247 }
248
249 try {
250 parse("weakValues, weakValues");
251 fail("Expected exception");
252 } catch (IllegalArgumentException expected) {
253
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
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
354 }
355 }
356
357 public void testParse_recordStats() {
358 CacheBuilderSpec spec = parse("recordStats");
359 assertTrue(spec.recordStats);
360 assertCacheBuilderEquivalence(CacheBuilder.newBuilder().recordStats(), CacheBuilder.from(spec));
361 }
362
363 public void testParse_recordStatsValueSpecified() {
364 try {
365 parse("recordStats=True");
366 fail("Expected exception");
367 } catch (IllegalArgumentException expected) {
368
369 }
370 }
371
372 public void testParse_recordStatsRepeated() {
373 try {
374 parse("recordStats,recordStats");
375 fail("Expected exception");
376 } catch (IllegalArgumentException expected) {
377
378 }
379 }
380
381 public void testParse_accessExpirationAndWriteExpiration() {
382 CacheBuilderSpec spec = parse("expireAfterAccess=10s,expireAfterWrite=9m");
383 assertEquals(TimeUnit.MINUTES, spec.writeExpirationTimeUnit);
384 assertEquals(9L, spec.writeExpirationDuration);
385 assertEquals(TimeUnit.SECONDS, spec.accessExpirationTimeUnit);
386 assertEquals(10L, spec.accessExpirationDuration);
387 assertCacheBuilderEquivalence(
388 CacheBuilder.newBuilder()
389 .expireAfterAccess(10L, TimeUnit.SECONDS)
390 .expireAfterWrite(9L, TimeUnit.MINUTES),
391 CacheBuilder.from(spec));
392 }
393
394 public void testParse_multipleKeys() {
395 CacheBuilderSpec spec = parse("initialCapacity=10,maximumSize=20,concurrencyLevel=30,"
396 + "weakKeys,weakValues,expireAfterAccess=10m,expireAfterWrite=1h");
397 assertEquals(10, spec.initialCapacity.intValue());
398 assertEquals(20, spec.maximumSize.intValue());
399 assertNull(spec.maximumWeight);
400 assertEquals(30, spec.concurrencyLevel.intValue());
401 assertEquals(Strength.WEAK, spec.keyStrength);
402 assertEquals(Strength.WEAK, spec.valueStrength);
403 assertEquals(TimeUnit.HOURS, spec.writeExpirationTimeUnit);
404 assertEquals(TimeUnit.MINUTES, spec.accessExpirationTimeUnit);
405 assertEquals(1L, spec.writeExpirationDuration);
406 assertEquals(10L, spec.accessExpirationDuration);
407 CacheBuilder<?, ?> expected = CacheBuilder.newBuilder()
408 .initialCapacity(10)
409 .maximumSize(20)
410 .concurrencyLevel(30)
411 .weakKeys()
412 .weakValues()
413 .expireAfterAccess(10L, TimeUnit.MINUTES)
414 .expireAfterWrite(1L, TimeUnit.HOURS);
415 assertCacheBuilderEquivalence(expected, CacheBuilder.from(spec));
416 }
417
418 public void testParse_whitespaceAllowed() {
419 CacheBuilderSpec spec = parse(" initialCapacity=10,\nmaximumSize=20,\t\r"
420 + "weakKeys \t ,softValues \n , \r expireAfterWrite \t = 15s\n\n");
421 assertEquals(10, spec.initialCapacity.intValue());
422 assertEquals(20, spec.maximumSize.intValue());
423 assertNull(spec.maximumWeight);
424 assertNull(spec.concurrencyLevel);
425 assertEquals(Strength.WEAK, spec.keyStrength);
426 assertEquals(Strength.SOFT, spec.valueStrength);
427 assertEquals(TimeUnit.SECONDS, spec.writeExpirationTimeUnit);
428 assertEquals(15L, spec.writeExpirationDuration);
429 assertNull(spec.accessExpirationTimeUnit);
430 CacheBuilder<?, ?> expected = CacheBuilder.newBuilder()
431 .initialCapacity(10)
432 .maximumSize(20)
433 .weakKeys()
434 .softValues()
435 .expireAfterWrite(15L, TimeUnit.SECONDS);
436 assertCacheBuilderEquivalence(expected, CacheBuilder.from(spec));
437 }
438
439 public void testParse_unknownKey() {
440 try {
441 parse("foo=17");
442 fail("Expected exception");
443 } catch (IllegalArgumentException expected) {
444
445 }
446 }
447
448 public void testParse_extraCommaIsInvalid() {
449 try {
450 parse("weakKeys,");
451 fail("Expected exception");
452 } catch (IllegalArgumentException expected) {
453
454 }
455
456 try {
457 parse(",weakKeys");
458 fail("Expected exception");
459 } catch (IllegalArgumentException expected) {
460
461 }
462
463 try {
464 parse("weakKeys,,softValues");
465 fail("Expected exception");
466 } catch (IllegalArgumentException expected) {
467
468 }
469 }
470
471 public void testEqualsAndHashCode() {
472 new EqualsTester()
473 .addEqualityGroup(parse(""), parse(""))
474 .addEqualityGroup(parse("concurrencyLevel=7"), parse("concurrencyLevel=7"))
475 .addEqualityGroup(parse("concurrencyLevel=15"), parse("concurrencyLevel=15"))
476 .addEqualityGroup(parse("initialCapacity=7"), parse("initialCapacity=7"))
477 .addEqualityGroup(parse("initialCapacity=15"), parse("initialCapacity=15"))
478 .addEqualityGroup(parse("maximumSize=7"), parse("maximumSize=7"))
479 .addEqualityGroup(parse("maximumSize=15"), parse("maximumSize=15"))
480 .addEqualityGroup(parse("maximumWeight=7"), parse("maximumWeight=7"))
481 .addEqualityGroup(parse("maximumWeight=15"), parse("maximumWeight=15"))
482 .addEqualityGroup(parse("expireAfterAccess=60s"), parse("expireAfterAccess=1m"))
483 .addEqualityGroup(parse("expireAfterAccess=60m"), parse("expireAfterAccess=1h"))
484 .addEqualityGroup(parse("expireAfterWrite=60s"), parse("expireAfterWrite=1m"))
485 .addEqualityGroup(parse("expireAfterWrite=60m"), parse("expireAfterWrite=1h"))
486 .addEqualityGroup(parse("weakKeys"), parse("weakKeys"))
487 .addEqualityGroup(parse("softValues"), parse("softValues"))
488 .addEqualityGroup(parse("weakValues"), parse("weakValues"))
489 .addEqualityGroup(parse("recordStats"), parse("recordStats"))
490 .testEquals();
491 }
492
493 public void testMaximumWeight_withWeigher() {
494 CacheBuilder<Object, Object> builder = CacheBuilder.from(parse("maximumWeight=9000"));
495 builder
496 .weigher(constantWeigher(42))
497 .build(CacheLoader.from(Suppliers.ofInstance(null)));
498 }
499
500 public void testMaximumWeight_withoutWeigher() {
501 CacheBuilder<Object, Object> builder = CacheBuilder.from(parse("maximumWeight=9000"));
502 try {
503 builder.build(CacheLoader.from(Suppliers.ofInstance(null)));
504 fail();
505 } catch (IllegalStateException expected) {}
506 }
507
508 public void testMaximumSize_withWeigher() {
509 CacheBuilder<Object, Object> builder = CacheBuilder.from(parse("maximumSize=9000"));
510 builder
511 .weigher(constantWeigher(42))
512 .build(CacheLoader.from(Suppliers.ofInstance(null)));
513 }
514
515 public void testMaximumSize_withoutWeigher() {
516 CacheBuilder<Object, Object> builder = CacheBuilder.from(parse("maximumSize=9000"));
517 builder.build(CacheLoader.from(Suppliers.ofInstance(null)));
518 }
519
520 public void testDisableCaching() {
521
522
523 CacheBuilder<Object, Object> builder = CacheBuilder.from(CacheBuilderSpec.disableCaching());
524 Object key = new Object();
525 Object value = new Object();
526 LoadingCache<Object, Object> cache = builder.build(
527 CacheLoader.from(Suppliers.ofInstance(value)));
528 assertSame(value, cache.getUnchecked(key));
529 assertEquals(0, cache.size());
530 assertFalse(cache.asMap().containsKey(key));
531 }
532
533 public void testCacheBuilderFrom_string() {
534 CacheBuilder<?, ?> fromString = CacheBuilder.from(
535 "initialCapacity=10,maximumSize=20,concurrencyLevel=30,"
536 + "weakKeys,weakValues,expireAfterAccess=10m");
537 CacheBuilder<?, ?> expected = CacheBuilder.newBuilder()
538 .initialCapacity(10)
539 .maximumSize(20)
540 .concurrencyLevel(30)
541 .weakKeys()
542 .weakValues()
543 .expireAfterAccess(10L, TimeUnit.MINUTES);
544 assertCacheBuilderEquivalence(expected, fromString);
545 }
546
547 private static void assertCacheBuilderEquivalence(CacheBuilder<?, ?> a, CacheBuilder<?, ?> b) {
548 assertEquals("concurrencyLevel", a.concurrencyLevel, b.concurrencyLevel);
549 assertEquals("expireAfterAccessNanos", a.expireAfterAccessNanos, b.expireAfterAccessNanos);
550 assertEquals("expireAfterWriteNanos", a.expireAfterWriteNanos, b.expireAfterWriteNanos);
551 assertEquals("initialCapacity", a.initialCapacity, b.initialCapacity);
552 assertEquals("maximumSize", a.maximumSize, b.maximumSize);
553 assertEquals("maximumWeight", a.maximumWeight, b.maximumWeight);
554 assertEquals("refreshNanos", a.refreshNanos, b.refreshNanos);
555 assertEquals("keyEquivalence", a.keyEquivalence, b.keyEquivalence);
556 assertEquals("keyStrength", a.keyStrength, b.keyStrength);
557 assertEquals("removalListener", a.removalListener, b.removalListener);
558 assertEquals("weigher", a.weigher, b.weigher);
559 assertEquals("valueEquivalence", a.valueEquivalence, b.valueEquivalence);
560 assertEquals("valueStrength", a.valueStrength, b.valueStrength);
561 assertEquals("statsCounterSupplier", a.statsCounterSupplier, b.statsCounterSupplier);
562 assertEquals("ticker", a.ticker, b.ticker);
563 assertEquals("recordStats", a.isRecordingStats(), b.isRecordingStats());
564 }
565 }