1 /***
2 * Copyright 2003-2010 Terracotta, Inc.
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
17 package net.sf.ehcache;
18
19 import static junit.framework.Assert.assertSame;
20 import static org.junit.Assert.assertEquals;
21 import static org.junit.Assert.assertFalse;
22 import static org.junit.Assert.assertNotNull;
23 import static org.junit.Assert.assertNull;
24 import static org.junit.Assert.assertTrue;
25 import static org.junit.Assert.fail;
26
27 import java.io.ByteArrayInputStream;
28 import java.io.Serializable;
29 import java.util.ArrayList;
30 import java.util.Collection;
31 import java.util.Date;
32 import java.util.HashMap;
33 import java.util.List;
34 import java.util.Map;
35 import java.util.Random;
36 import java.util.Vector;
37 import java.util.concurrent.ExecutionException;
38 import java.util.concurrent.ExecutorService;
39 import java.util.concurrent.Executors;
40 import java.util.concurrent.Future;
41 import java.util.concurrent.TimeUnit;
42 import java.util.concurrent.atomic.AtomicLong;
43
44 import net.sf.ehcache.bootstrap.BootstrapCacheLoader;
45 import net.sf.ehcache.config.CacheConfiguration;
46 import net.sf.ehcache.event.CacheEventListener;
47 import net.sf.ehcache.event.RegisteredEventListeners;
48 import net.sf.ehcache.exceptionhandler.ExceptionHandlingDynamicCacheProxy;
49 import net.sf.ehcache.loader.CacheLoader;
50 import net.sf.ehcache.loader.CountingCacheLoader;
51 import net.sf.ehcache.loader.ExceptionThrowingLoader;
52 import net.sf.ehcache.store.MemoryStoreEvictionPolicy;
53 import net.sf.ehcache.store.compound.CompoundStore;
54
55 import org.junit.After;
56 import org.junit.Ignore;
57 import org.junit.Test;
58 import org.slf4j.Logger;
59 import org.slf4j.LoggerFactory;
60
61 /***
62 * Tests for a Cache
63 * <p/>
64 * Since expiration is rounded on seconds, we need to at least go up to the last
65 * millisecond before the next second in many of the tests
66 *
67 * @author Greg Luck, Claus Ibsen
68 * @version $Id: CacheTest.java 2539 2010-07-02 10:58:13Z alexsnaps $
69 */
70 public class CacheTest extends AbstractCacheTest {
71
72 private static final Logger LOG = LoggerFactory.getLogger(CacheTest.class.getName());
73
74
75 /***
76 * teardown
77 */
78 @Override
79 @After
80 public void tearDown() throws Exception {
81 super.tearDown();
82 }
83
84 /***
85 * Gets the sample cache 1
86 */
87 protected Ehcache getSampleCache1() {
88 Cache cache = manager.getCache("sampleCache1");
89 return cache;
90 }
91
92 /***
93 * Creates a cache
94 *
95 * @return
96 */
97 protected Ehcache createTestCache() {
98 Cache cache = new Cache("test4", 1000, true, true, 0, 0);
99 manager.addCache(cache);
100 return cache;
101 }
102
103 /***
104 * Checks we cannot use a cache after shutdown
105 */
106 @Test
107 public void testUseCacheAfterManagerShutdown() throws CacheException {
108 Ehcache cache = getSampleCache1();
109 manager.shutdown();
110 Element element = new Element("key", "value");
111 try {
112 cache.getSize();
113 fail();
114 } catch (IllegalStateException e) {
115 assertEquals("The sampleCache1 Cache is not alive.", e.getMessage());
116 }
117 try {
118 cache.put(element);
119 fail();
120 } catch (IllegalStateException e) {
121 assertEquals("The sampleCache1 Cache is not alive.", e.getMessage());
122 }
123 try {
124 cache.get("key");
125 fail();
126 } catch (IllegalStateException e) {
127 assertEquals("The sampleCache1 Cache is not alive.", e.getMessage());
128 }
129
130 }
131
132 /***
133 * Test multiple calls to dispose is not a problem
134 */
135 @Test
136 public void testMultipleDispose() {
137 Ehcache cache = new Cache("testCache", 1, true, false, 5, 2);
138 manager.addCache(cache);
139 cache.dispose();
140
141 for (int i = 0; i < 10; i++) {
142 cache.dispose();
143 }
144 }
145
146
147 /***
148 * Checks we cannot use a cache outside the manager
149 */
150 @Test
151 public void testUseCacheOutsideManager() throws CacheException {
152
153 Cache cache = new Cache("testCache", 1, true, false, 5, 2);
154 Element element = new Element("key", "value");
155 try {
156 cache.getSize();
157 fail();
158 } catch (IllegalStateException e) {
159 assertEquals("The testCache Cache is not alive.", e.getMessage());
160 }
161 try {
162 cache.put(element);
163 fail();
164 } catch (IllegalStateException e) {
165 assertEquals("The testCache Cache is not alive.", e.getMessage());
166 }
167 try {
168 cache.get("key");
169 fail();
170 } catch (IllegalStateException e) {
171 assertEquals("The testCache Cache is not alive.", e.getMessage());
172 }
173 }
174
175 /***
176 * Checks when and how we can set the cache name.
177 */
178 @Test
179 public void testSetCacheName() throws CacheException {
180
181 Ehcache cache = new Cache("testCache", 1, true, false, 5, 2);
182
183 try {
184 cache.setName(null);
185 fail();
186 } catch (IllegalArgumentException e) {
187
188 }
189
190 cache.setName("name/with/slash");
191
192 manager.addCache(cache);
193 try {
194 cache.setName("trying_to_change_name_after_initialised");
195 fail();
196 } catch (IllegalStateException e) {
197
198 }
199 }
200
201
202 /***
203 * Test using a cache which has been removed and replaced.
204 */
205 @Test
206 public void testStaleCacheReference() throws CacheException {
207 manager.addCache("test");
208 Ehcache cache = manager.getCache("test");
209 assertNotNull(cache);
210 cache.put(new Element("key1", "value1"));
211
212 assertEquals("value1", cache.get("key1").getObjectValue());
213 manager.removeCache("test");
214 manager.addCache("test");
215
216 try {
217 cache.get("key1");
218 fail();
219 } catch (IllegalStateException e) {
220 assertEquals("The test Cache is not alive.", e.getMessage());
221 }
222 }
223
224 /***
225 * Tests getting the cache name
226 *
227 * @throws Exception
228 */
229 @Test
230 public void testCacheName() throws Exception {
231 manager.addCache("test");
232 Ehcache cache = manager.getCache("test");
233 assertEquals("test", cache.getName());
234 assertEquals(Status.STATUS_ALIVE, cache.getStatus());
235 }
236
237
238 /***
239 * Tests getting the cache name
240 *
241 * @throws Exception
242 */
243 @Test
244 public void testCacheWithNoIdle() throws Exception {
245 Ehcache cache = manager.getCache("sampleCacheNoIdle");
246 assertEquals("sampleCacheNoIdle", cache.getName());
247 assertEquals(Status.STATUS_ALIVE, cache.getStatus());
248 assertEquals(0, cache.getCacheConfiguration().getTimeToIdleSeconds());
249 }
250
251 /***
252 * Test expiry based on time to live
253 * <cache name="sampleCacheNoIdle"
254 * maxElementsInMemory="1000"
255 * eternal="false"
256 * timeToLiveSeconds="5"
257 * overflowToDisk="false"
258 * />
259 */
260 @Test
261 public void testExpiryBasedOnTimeToLiveWhenNoIdle() throws Exception {
262
263 Ehcache cache = manager.getCache("sampleCacheNoIdle");
264 cache.put(new Element("key1", "value1"));
265 cache.put(new Element("key2", "value1"));
266 assertNotNull(cache.get("key1"));
267 assertNotNull(cache.get("key2"));
268
269
270 Thread.sleep(2999);
271 assertNotNull(cache.get("key1"));
272 assertNotNull(cache.get("key2"));
273
274
275 Thread.sleep(5999);
276 assertNull(cache.get("key1"));
277 assertNull(cache.get("key2"));
278 }
279
280
281 /***
282 * Tests that the version and lastUpdate get upped for each put.
283 * <cache name="sampleCacheNoIdle"
284 * maxElementsInMemory="1000"
285 * eternal="false"
286 * timeToLiveSeconds="5"
287 * overflowToDisk="false"
288 * />
289 */
290 @Test
291 public void testLastUpdate() throws Exception {
292
293 Ehcache cache = manager.getCache("sampleCache1");
294 long beforeElementCreation = System.currentTimeMillis();
295
296 Thread.sleep(10);
297 cache.put(new Element("key1", "value1"));
298 Element element = cache.get("key1");
299 assertTrue(element.getCreationTime() >= beforeElementCreation);
300 LOG.info("version: " + element.getVersion());
301 LOG.info("creationTime: " + element.getCreationTime());
302 LOG.info("lastUpdateTime: " + element.getLastUpdateTime());
303 assertEquals(0, element.getLastUpdateTime());
304
305 cache.put(new Element("key1", "value1"));
306 element = cache.get("key1");
307 LOG.info("version: " + element.getVersion());
308 LOG.info("creationTime: " + element.getCreationTime());
309 LOG.info("lastUpdateTime: " + element.getLastUpdateTime());
310
311 cache.put(new Element("key1", "value1"));
312 element = cache.get("key1");
313 LOG.info("version: " + element.getVersion());
314 LOG.info("creationTime: " + element.getCreationTime());
315 LOG.info("lastUpdateTime: " + element.getLastUpdateTime());
316 }
317
318
319 /***
320 * When to search the disk store
321 */
322 @Test
323 public void testOverflowToDiskAndDiskPersistent() throws Exception {
324 Ehcache cache = manager.getCache("sampleIdlingExpiringCache");
325
326 for (int i = 0; i < 1001; i++) {
327 cache.put(new Element("key" + i, "value1"));
328 }
329
330 assertNotNull(cache.get("key0"));
331
332 for (int i = 0; i < 1001; i++) {
333 cache.put(new Element("key" + i, "value1"));
334 assertNotNull(cache.get("key" + i));
335 }
336 }
337
338
339 /***
340 * Test expiry based on time to live for a cache with config
341 * <cache name="sampleCacheNoIdle"
342 * maxElementsInMemory="1000"
343 * eternal="false"
344 * timeToLiveSeconds="5"
345 * overflowToDisk="false"
346 * />
347 * <p/>
348 * where an Elment override is set on TTL
349 */
350 @Test
351 public void testExpiryBasedOnTimeToLiveWhenNoIdleElementOverride() throws Exception {
352
353 Ehcache cache = manager.getCache("sampleCacheNoIdle");
354 Element element1 = new Element("key1", "value1");
355 element1.setTimeToLive(3);
356 cache.put(element1);
357
358 Element element2 = new Element("key2", "value1");
359 element2.setTimeToLive(3);
360 cache.put(element2);
361 assertNotNull(cache.get("key1"));
362 assertNotNull(cache.get("key2"));
363
364
365 Thread.sleep(1999);
366 assertNotNull(cache.get("key1"));
367 assertNotNull(cache.get("key2"));
368
369
370 Thread.sleep(4999);
371 assertNull(cache.get("key1"));
372 assertNull(cache.get("key2"));
373 }
374
375 /***
376 * Test expiry based on time to live for a cache with config
377 * <cache name="sampleCacheNoIdle"
378 * maxElementsInMemory="1000"
379 * eternal="false"
380 * timeToLiveSeconds="5"
381 * overflowToDisk="false"
382 * />
383 * <p/>
384 * where an Element override is set on TTL
385 */
386 @Test
387 public void testExpiryBasedOnTimeToIdleElementOverride() throws Exception {
388
389 Ehcache cache = manager.getCache("sampleCacheNoIdle");
390 assertEquals(30, cache.getCacheConfiguration().getDiskSpoolBufferSizeMB());
391 Element element1 = new Element("key1", "value1");
392 element1.setTimeToIdle(1);
393 cache.put(element1);
394
395 Element element2 = new Element("key2", "value1");
396 element2.setTimeToIdle(1);
397 cache.put(element2);
398 assertNotNull(cache.get("key1"));
399 assertNotNull(cache.get("key2"));
400
401
402 Thread.sleep(1999);
403 assertNull(cache.get("key1"));
404 assertNull(cache.get("key2"));
405
406 }
407
408
409 /***
410 * Test expiry based on time to live for a cache with config
411 * <cache name="sampleCacheNoIdle"
412 * maxElementsInMemory="1000"
413 * eternal="false"
414 * timeToLiveSeconds="5"
415 * overflowToDisk="false"
416 * />
417 * <p/>
418 * where an Elment override is set on TTL
419 */
420 @Test
421 public void testExpiryBasedEternalElementOverride() throws Exception {
422
423 Ehcache cache = manager.getCache("sampleCacheNoIdle");
424 Element element1 = new Element("key1", "value1");
425 element1.setEternal(true);
426 cache.put(element1);
427
428 Element element2 = new Element("key2", "value1");
429 element2.setEternal(true);
430 cache.put(element2);
431 assertNotNull(cache.get("key1"));
432 assertNotNull(cache.get("key2"));
433
434 Thread.sleep(5999);
435 assertNotNull(cache.get("key1"));
436 assertNotNull(cache.get("key2"));
437
438 }
439
440 /***
441 * Test expiry based on time to live. Even though eternal is false, because there are no
442 * expiry or idle times, it is eternal.
443 * <cache name="sampleCacheNotEternalButNoIdleOrExpiry"
444 * maxElementsInMemory="1000"
445 * eternal="false"
446 * overflowToDisk="false"
447 * />
448 */
449 @Test
450 public void testExpirySampleCacheNotEternalButNoIdleOrExpiry() throws Exception {
451
452 Ehcache cache = manager.getCache("sampleCacheNotEternalButNoIdleOrExpiry");
453 cache.put(new Element("key1", "value1"));
454 cache.put(new Element("key2", "value1"));
455 assertNotNull(cache.get("key1"));
456 assertNotNull(cache.get("key2"));
457
458
459 Thread.sleep(2999);
460 assertNotNull(cache.get("key1"));
461 assertNotNull(cache.get("key2"));
462
463
464 Thread.sleep(5999);
465 assertNotNull(cache.get("key1"));
466 assertNotNull(cache.get("key2"));
467 }
468
469
470 /***
471 * Test overflow to disk = false
472 */
473 @Test
474 public void testNoOverflowToDisk() throws Exception {
475
476 Cache cache = new Cache("test", 1, false, true, 5, 2);
477 manager.addCache(cache);
478 cache.put(new Element("key1", "value1"));
479 cache.put(new Element("key2", "value1"));
480 assertNull(cache.get("key1"));
481 assertNotNull(cache.get("key2"));
482 }
483
484
485 /***
486 * Test Caches with persistent stores dispose properly. Tests:
487 * <ol>
488 * <li>No exceptions are thrown on dispose
489 * <li>You cannot re add a cache after it has been disposed and removed
490 * <li>You can create a new cache with the same name
491 * </ol>
492 */
493 @Test
494 public void testCreateAddDisposeAdd() throws CacheException {
495 Cache cache = new Cache("test2", 1, true, true, 0, 0, true, 120);
496 manager.addCache(cache);
497 cache.put(new Element("key1", "value1"));
498 cache.put(new Element("key2", "value1"));
499 int sizeFromGetSize = cache.getSize();
500 int sizeFromKeys = cache.getKeys().size();
501 assertEquals(sizeFromGetSize, sizeFromKeys);
502 assertEquals(2, cache.getSize());
503
504 cache.dispose();
505 manager.removeCache("test2");
506
507
508 try {
509 manager.addCache(cache);
510 fail();
511 } catch (CacheException e) {
512
513 }
514
515
516 Cache cache2 = new Cache("test2", 1, true, true, 0, 0, true, 120);
517 manager.addCache(cache2);
518 Ehcache cacheFromManager = manager.getCache("test2");
519 assertTrue(cacheFromManager.getStatus().equals(Status.STATUS_ALIVE));
520
521 }
522
523 /***
524 * Test expiry based on time to live
525 */
526 @Test
527 public void testExpiryBasedOnTimeToLive() throws Exception {
528
529 Cache cache = new Cache("test", 1, true, false, 3, 0);
530 manager.addCache(cache);
531 cache.put(new Element("key1", "value1"));
532 cache.put(new Element("key2", "value1"));
533
534
535 assertNotNull(cache.get("key1"));
536 assertNotNull(cache.get("key2"));
537 Thread.sleep(1020);
538
539 assertNotNull(cache.get("key1"));
540 assertNotNull(cache.get("key2"));
541 Thread.sleep(1020);
542
543 assertNotNull(cache.get("key1"));
544 assertNotNull(cache.get("key2"));
545 Thread.sleep(1959);
546 assertNull(cache.get("key1"));
547 assertNull(cache.get("key2"));
548 }
549
550
551 /***
552 * Tests that a cache created from defaults will expire as per
553 * the default expiry policy.
554 *
555 * @throws Exception
556 */
557 @Test
558 public void testExpiryBasedOnTimeToLiveForDefault() throws Exception {
559 String name = "ThisIsACacheWhichIsNotConfiguredAndWillThereforeUseDefaults";
560 Ehcache cache = null;
561 CacheManager manager = CacheManager.getInstance();
562 cache = manager.getCache(name);
563 if (cache == null) {
564 LOG.warn("Could not find configuration for " + name
565 + ". Configuring using the defaultCache settings.");
566 manager.addCache(name);
567 cache = manager.getCache(name);
568 }
569
570 cache.put(new Element("key1", "value1"));
571 cache.put(new Element("key2", "value1"));
572
573
574 assertNotNull(cache.get("key1"));
575 assertNotNull(cache.get("key2"));
576 Thread.sleep(10999);
577 assertNull(cache.get("key1"));
578 assertNull(cache.get("key2"));
579
580
581 }
582
583
584 /***
585 * Test expiry based on time to live.
586 * <p/>
587 * Elements are put quietly back into the cache after being cloned.
588 * The elements should expire as if the putQuiet had not happened.
589 */
590 @Test
591 public void testExpiryBasedOnTimeToLiveAfterPutQuiet() throws Exception {
592
593 Cache cache = new Cache("test", 1, true, false, 5, 2);
594 manager.addCache(cache);
595 cache.put(new Element("key1", "value1"));
596 cache.put(new Element("key2", "value1"));
597
598 Element element1 = cache.get("key1");
599 Element element2 = cache.get("key2");
600 assertNotNull(element1);
601 assertNotNull(element2);
602
603
604 Thread.sleep(2999);
605
606 cache.putQuiet((Element) element2.clone());
607 cache.putQuiet((Element) element2.clone());
608 Thread.sleep(3000);
609 assertNull(cache.get("key1"));
610 assertNull(cache.get("key2"));
611 }
612
613 /***
614 * Test expiry based on time to live
615 */
616 @Test
617 public void testNoIdleOrExpiryBasedOnTimeToLiveForEternal() throws Exception {
618
619 Cache cache = new Cache("test", 1, true, true, 5, 2);
620 manager.addCache(cache);
621 cache.put(new Element("key1", "value1"));
622 cache.put(new Element("key2", "value1"));
623
624
625 assertNotNull(cache.get("key1"));
626 assertNotNull(cache.get("key2"));
627
628
629 Thread.sleep(2999);
630 assertNotNull(cache.get("key1"));
631 assertNotNull(cache.get("key2"));
632
633
634 Thread.sleep(3999);
635 assertNotNull(cache.get("key1"));
636 assertNotNull(cache.get("key2"));
637 }
638
639 /***
640 * Test expiry based on time to idle.
641 */
642 @Test
643 public void testExpiryBasedOnTimeToIdle() throws Exception {
644
645 Cache cache = new Cache("test", 1, true, false, 6, 2);
646 manager.addCache(cache);
647 cache.put(new Element("key1", "value1"));
648 cache.put(new Element("key2", "value1"));
649
650
651 Element element1 = cache.get("key1");
652 Element element2 = cache.get("key2");
653 assertNotNull(element1);
654 assertNotNull(element2);
655 Thread.sleep(3000);
656 assertNull(cache.get("key1"));
657 assertNull(cache.get("key2"));
658
659
660 cache.put(new Element("key1", "value1"));
661 cache.put(new Element("key2", "value1"));
662 Thread.sleep(1000);
663 assertNotNull(cache.get("key1"));
664 assertNotNull(cache.get("key2"));
665
666 Thread.sleep(3000);
667 assertNull(cache.get("key1"));
668 assertNull(cache.get("key2"));
669 }
670
671
672 /***
673 * Test expiry based on time to idle.
674 */
675 @Test
676 public void testExpiryBasedOnTimeToIdleAfterPutQuiet() throws Exception {
677
678 Cache cache = new Cache("test", 1, true, false, 5, 3);
679 manager.addCache(cache);
680 cache.put(new Element("key1", "value1"));
681 cache.put(new Element("key2", "value1"));
682
683
684 Element element1 = cache.get("key1");
685 Element element2 = cache.get("key2");
686 assertNotNull(element1);
687 assertNotNull(element2);
688
689
690 Thread.sleep(1050);
691 element1 = cache.getQuiet("key1");
692 element2 = cache.getQuiet("key2");
693 Thread.sleep(2949);
694 assertNull(cache.getQuiet("key1"));
695 assertNull(cache.getQuiet("key2"));
696
697
698 cache.putQuiet((Element) element1.clone());
699 cache.putQuiet((Element) element2.clone());
700 assertNull(cache.get("key1"));
701 element2 = cache.get("key2");
702 assertNull(element2);
703 }
704
705 /***
706 * Test element statistics, including get and getQuiet
707 * eternal="false"
708 * timeToIdleSeconds="5"
709 * timeToLiveSeconds="10"
710 * overflowToDisk="true"
711 */
712 @Test
713 public void testElementStatistics() throws Exception {
714
715 Cache cache = new Cache("test", 1, true, false, 5, 2);
716 manager.addCache(cache);
717
718 cache.setStatisticsEnabled(true);
719
720 cache.put(new Element("key1", "value1"));
721 cache.put(new Element("key2", "value1"));
722
723 Element element1 = cache.get("key1");
724 assertEquals("Should be one", 1, element1.getHitCount());
725 element1 = cache.getQuiet("key1");
726 assertEquals("Should be one", 1, element1.getHitCount());
727 element1 = cache.get("key1");
728 assertEquals("Should be two", 2, element1.getHitCount());
729 }
730
731 /***
732 * Test cache statistics, including get and getQuiet
733 */
734 @Test
735 public void testCacheStatistics() throws Exception {
736
737 Cache cache = new Cache("test", 1, true, false, 5, 2);
738 manager.addCache(cache);
739
740 cache.setStatisticsEnabled(true);
741
742 cache.put(new Element("key1", "value1"));
743 cache.put(new Element("key2", "value1"));
744
745 Element element1 = cache.get("key1");
746 assertEquals("Should be one", 1, element1.getHitCount());
747 assertEquals("Should be one", 1, cache.getStatistics().getCacheHits());
748 element1 = cache.getQuiet("key1");
749 assertEquals("Should be one", 1, element1.getHitCount());
750 assertEquals("Should be one", 1, cache.getStatistics().getCacheHits());
751 element1 = cache.get("key1");
752 assertEquals("Should be two", 2, element1.getHitCount());
753 assertEquals("Should be two", 2, cache.getStatistics().getCacheHits());
754
755
756 assertEquals("Should be 0", 0, cache.getStatistics().getCacheMisses());
757 cache.get("doesnotexist");
758 assertEquals("Should be 1", 1, cache.getStatistics().getCacheMisses());
759
760
761 }
762
763 /***
764 * Checks that getQuiet works how we expect it to
765 *
766 * @throws Exception
767 */
768 @Test
769 public void testGetQuietAndPutQuiet() throws Exception {
770
771 Cache cache = new Cache("test", 1, true, false, 5, 2);
772 manager.addCache(cache);
773
774 cache.setStatisticsEnabled(true);
775
776 cache.put(new Element("key1", "value1"));
777 cache.put(new Element("key2", "value1"));
778
779 Element element1 = cache.get("key1");
780 long lastAccessedElement1 = element1.getLastAccessTime();
781 long hitCountElement1 = element1.getHitCount();
782 assertEquals("Should be two", 1, element1.getHitCount());
783 assertEquals(1L, cache.getStatistics().getCacheHits());
784
785 element1 = cache.getQuiet("key1");
786 element1 = cache.getQuiet("key1");
787 assertEquals(1L, cache.getStatistics().getCacheHits());
788 Element clonedElement1 = (Element) element1.clone();
789 cache.putQuiet(clonedElement1);
790 element1 = cache.getQuiet("key1");
791 assertEquals("last access time should be unchanged",
792 lastAccessedElement1, element1.getLastAccessTime());
793 assertEquals("hit count should be unchanged",
794 hitCountElement1, element1.getHitCount());
795 element1 = cache.get("key1");
796 assertEquals("Should be two", 2, element1.getHitCount());
797 }
798
799 /***
800 * Test size with put and remove.
801 * <p/>
802 * It checks that size makes sense, and also that getKeys.size() matches getSize()
803 */
804 @Test
805 public void testSizeWithPutAndRemove() throws Exception {
806
807 Cache cache = new Cache("test2", 1, true, true, 0, 0);
808 manager.addCache(cache);
809 cache.put(new Element("key1", "value1"));
810 cache.put(new Element("key2", "value1"));
811 int sizeFromGetSize = cache.getSize();
812 int sizeFromKeys = cache.getKeys().size();
813 assertEquals(sizeFromGetSize, sizeFromKeys);
814 assertEquals(2, cache.getSize());
815 cache.put(new Element("key1", "value1"));
816 cache.put(new Element("key1", "value1"));
817
818
819 assertEquals(cache.getSize(), cache.getKeys().size());
820 assertEquals(2, cache.getSize());
821
822 cache.remove("key1");
823 assertEquals(cache.getSize(), cache.getKeys().size());
824 assertEquals(1, cache.getSize());
825 cache.remove("key2");
826 assertEquals(cache.getSize(), cache.getKeys().size());
827 assertEquals(0, cache.getSize());
828
829
830 cache.removeAll();
831 Object object1 = new Object();
832 Object object2 = new Object();
833 cache.put(new Element(object1, null));
834 cache.put(new Element(object2, null));
835
836 assertEquals(1, cache.getSize());
837 Element nullValueElement = cache.get(object2);
838 assertNull(nullValueElement.getValue());
839 assertNull(nullValueElement.getObjectValue());
840
841 }
842
843 /***
844 * Test getKeys after expiry
845 * <p/>
846 * Makes sure that if an element is expired, its key should also be expired
847 */
848 @Test
849 public void testGetKeysAfterExpiry() throws Exception {
850
851 Cache cache = new Cache("test2", 1, true, false, 1, 0);
852 manager.addCache(cache);
853 String key1 = "key1";
854 cache.put(new Element(key1, "value1"));
855 cache.put(new Element("key2", "value1"));
856
857 assertEquals(cache.getSize(), cache.getKeys().size());
858
859 assertEquals(2, cache.getSize());
860 String keyFromDisk = (String) cache.get(key1).getObjectKey();
861 assertEquals(key1, keyFromDisk);
862 Thread.sleep(1999);
863 assertEquals(2, cache.getKeys().size());
864
865 assertEquals(0, cache.getKeysWithExpiryCheck().size());
866 }
867
868
869 /***
870 * Answers the question of whether key references are preserved as elements are written to disk.
871 * This is not a mandatory part of the API. If this test breaks in future it should be removed.
872 */
873 @Test
874 public void testKeysEqualsEquals() throws Exception {
875
876 Cache cache = new Cache("test2", 0, true, false, 1, 0);
877 manager.addCache(cache);
878 String key1 = "key1";
879 cache.put(new Element(key1, "value1"));
880 cache.put(new Element("key2", "value1"));
881 String keyFromDisk = (String) cache.get(key1).getObjectKey();
882 assertTrue(key1 == keyFromDisk);
883 }
884
885 /***
886 * Test size after multiple calls, with put and remove
887 */
888 @Test
889 public void testSizeMultipleCallsWithPutAndRemove() throws Exception {
890
891 Cache cache = new Cache("test3", 1, true, true, 0, 0);
892 manager.addCache(cache);
893 cache.put(new Element("key1", "value1"));
894 cache.put(new Element("key2", "value1"));
895
896
897 assertEquals(2, cache.getSize());
898 assertEquals(2, cache.getSize());
899 assertEquals(2, cache.getSize());
900 assertEquals(2, cache.getSize());
901 assertEquals(2, cache.getSize());
902 cache.remove("key1");
903 assertEquals(1, cache.getSize());
904 assertEquals(1, cache.getSize());
905 assertEquals(1, cache.getSize());
906 assertEquals(1, cache.getSize());
907 assertEquals(1, cache.getSize());
908 cache.remove("key2");
909 assertEquals(0, cache.getSize());
910 assertEquals(0, cache.getSize());
911 assertEquals(0, cache.getSize());
912 assertEquals(0, cache.getSize());
913 assertEquals(0, cache.getSize());
914 }
915
916
917 /***
918 * Expire elements and verify size is correct.
919 */
920 @Test
921 public void testGetSizeAfterExpiry() throws Exception {
922
923 Cache cache = new Cache("test", 1, true, false, 1, 0);
924 manager.addCache(cache);
925 cache.put(new Element("key1", "value1"));
926 cache.put(new Element("key2", "value1"));
927
928
929 Thread.sleep(1999);
930 assertEquals(null, cache.get("key1"));
931 assertEquals(null, cache.get("key2"));
932
933 assertEquals(0, cache.getSize());
934 }
935
936 /***
937 * Test create and access times
938 */
939 @Test
940 public void testAccessTimes() throws Exception {
941
942 Cache cache = new Cache("test", 5, true, false, 5, 2);
943 assertEquals(Status.STATUS_UNINITIALISED, cache.getStatus());
944 manager.addCache(cache);
945 Element newElement = new Element("key1", "value1");
946 long creationTime = newElement.getCreationTime();
947 assertTrue(newElement.getCreationTime() > (System.currentTimeMillis() - 500));
948 assertTrue(newElement.getHitCount() == 0);
949 assertTrue(newElement.getLastAccessTime() == 0);
950
951 cache.put(newElement);
952
953 Element element = cache.get("key1");
954 assertNotNull(element);
955 assertEquals(creationTime, element.getCreationTime());
956 assertTrue(element.getLastAccessTime() != 0);
957 assertTrue(element.getHitCount() == 1);
958
959
960 cache.put(element);
961 element = cache.get("key1");
962 assertEquals(creationTime, element.getCreationTime());
963 assertTrue(element.getLastAccessTime() != 0);
964 assertTrue(element.getHitCount() == 1);
965 }
966
967 /***
968 * Tests initialisation failures
969 */
970 @Test
971 public void testInitialiseFailures() {
972 try {
973 Cache cache = new Cache("testInitialiseFailures2", 1, false, false, 5, 1);
974 cache.initialise();
975
976 cache.initialise();
977 fail("Should have thrown IllegalArgumentException");
978 } catch (IllegalStateException e) {
979
980 }
981 }
982
983 /***
984 * Nulls should be ignored
985 *
986 * @throws Exception
987 */
988 @Test
989 public void testNullPuts() throws Exception {
990 Cache cache = new Cache("testPutFailures", 1, false, false, 5, 1);
991 manager.addCache(cache);
992
993 cache.put(null);
994 cache.put(null, false);
995 cache.putQuiet(null);
996 cache.putQuiet(new Element(null, null));
997
998
999 cache.put(new Element(null, "dog"));
1000 cache.put(new Element(null, null));
1001
1002
1003 cache.putQuiet(new Element(null, "dog"));
1004 cache.putQuiet(new Element(null, null));
1005 }
1006
1007
1008 /***
1009 * Tests cache, memory store and disk store sizes from config
1010 */
1011 @Test
1012 public void testSizes() throws Exception {
1013 Ehcache cache = getSampleCache1();
1014
1015 assertEquals(0, cache.getMemoryStoreSize());
1016
1017 for (int i = 0; i < 10010; i++) {
1018 cache.put(new Element("key" + i, "value1"));
1019 }
1020
1021 Thread.sleep(1000);
1022
1023 assertEquals(10010, cache.getSize());
1024 assertEquals(10000, cache.getMemoryStoreSize());
1025 assertEquals(10, cache.getDiskStoreSize());
1026
1027
1028 Thread.sleep(15);
1029 cache.put(new Element(new Object(), Object.class));
1030
1031 Thread.sleep(1000);
1032
1033 assertEquals(10011, cache.getSize());
1034 assertEquals(11, cache.getDiskStoreSize());
1035 assertEquals(10000, cache.getMemoryStoreSize());
1036 assertEquals(10000, cache.getMemoryStoreSize());
1037 assertEquals(10000, cache.getMemoryStoreSize());
1038 assertEquals(10000, cache.getMemoryStoreSize());
1039
1040
1041 cache.remove("key4");
1042 cache.remove("key3");
1043
1044 assertEquals(10009, cache.getSize());
1045
1046
1047
1048
1049
1050 cache.removeAll();
1051 assertEquals(0, cache.getSize());
1052 assertEquals(0, cache.getMemoryStoreSize());
1053 assertEquals(0, cache.getDiskStoreSize());
1054
1055 }
1056
1057
1058
1059
1060 public void testSizesContinuous() throws Exception {
1061 while (true) {
1062 testFlushWhenOverflowToDisk();
1063 }
1064 }
1065
1066
1067 /***
1068 * Tests flushing the cache, with the default, which is to clear
1069 * <p/>
1070 * Note: Which element gets evicted is probabilistic. 1.5 and earlier were deterministic. Thus
1071 * the variation in what gets into the DiskStore.
1072 *
1073 * @throws Exception
1074 */
1075 @Test
1076 public void testFlushWhenOverflowToDisk() throws Exception {
1077 if (manager.getCache("testFlushWhenOverflowToDisk") == null) {
1078 manager.addCache(new Cache("testFlushWhenOverflowToDisk", 50, true, false, 100, 200, true, 120));
1079 }
1080 Cache cache = manager.getCache("testFlushWhenOverflowToDisk");
1081 cache.removeAll();
1082
1083 assertEquals(0, cache.getMemoryStoreSize());
1084 assertEquals(0, cache.getDiskStoreSize());
1085
1086
1087 for (int i = 0; i < 100; i++) {
1088 cache.put(new Element("" + i, new Date()));
1089 }
1090
1091 Thread.sleep(200);
1092
1093 for (int i = 0; i < 100; i++) {
1094 cache.get("" + i);
1095 }
1096 assertEquals(50, cache.getMemoryStoreSize());
1097 assertEquals(100, cache.getDiskStoreSize());
1098 assertEquals(100, cache.getSize());
1099
1100
1101
1102 cache.put(new Element("key", new String("sdf")));
1103 cache.put(new Element("key2", new String("fdgdf")));
1104 cache.put(new Element("key1", "value"));
1105
1106
1107 Thread.sleep(200);
1108 cache.get("key1");
1109
1110 assertEquals(103, cache.getSize());
1111 assertEquals(50, cache.getMemoryStoreSize());
1112 assertEquals(103, cache.getDiskStoreSize());
1113
1114
1115
1116 cache.put(new Element(null, null));
1117 cache.put(new Element(null, null));
1118
1119 assertEquals(103, cache.getSize());
1120 assertEquals(50, cache.getMemoryStoreSize());
1121 assertEquals(103, cache.getDiskStoreSize());
1122
1123
1124 cache.put(new Element("nullValue", null));
1125
1126 Thread.sleep(200);
1127
1128 LOG.info("Size: " + cache.getDiskStoreSize());
1129
1130 assertEquals(50, cache.getMemoryStoreSize());
1131 assertEquals(104, cache.getDiskStoreSize());
1132
1133 cache.flush();
1134 Thread.sleep(200);
1135
1136 assertEquals(0, cache.getMemoryStoreSize());
1137
1138 assertEquals(104, cache.getDiskStoreSize());
1139
1140 cache.removeAll();
1141
1142 }
1143
1144 @Test
1145 public void testFlushWithoutClear() throws InterruptedException {
1146
1147 CacheManager cacheManager = CacheManager.create(AbstractCacheTest.TEST_CONFIG_DIR + "ehcache.xml");
1148 Cache cache = cacheManager.getCache("SimplePageCachingFilter");
1149 cache.removeAll();
1150 for (int i = 0; i < 100; i++) {
1151 cache.put(new Element("" + i, new Date()));
1152 }
1153
1154 Thread.sleep(200);
1155
1156 for (int i = 0; i < 100; i++) {
1157 cache.get("" + i);
1158 }
1159
1160 assertEquals(10, cache.getMemoryStoreSize());
1161 assertEquals(100, cache.getDiskStoreSize());
1162
1163 cache.flush();
1164 Thread.sleep(200);
1165
1166 assertEquals(10, cache.getMemoryStoreSize());
1167 assertEquals(100, cache.getDiskStoreSize());
1168 cacheManager.shutdown();
1169
1170 }
1171
1172 @Test
1173 public void testFlushWithClear() throws InterruptedException {
1174
1175 CacheManager cacheManager = CacheManager.create(AbstractCacheTest.TEST_CONFIG_DIR + "ehcache.xml");
1176 Cache cache = cacheManager.getCache("SimplePageFragmentCachingFilter");
1177 cache.removeAll();
1178 for (int i = 0; i < 100; i++) {
1179 cache.put(new Element("" + i, new Date()));
1180 }
1181
1182 Thread.sleep(200);
1183
1184 for (int i = 0; i < 100; i++) {
1185 cache.get("" + i);
1186 }
1187
1188 assertEquals(10, cache.getMemoryStoreSize());
1189 assertEquals(100, cache.getDiskStoreSize());
1190
1191 cache.flush();
1192 Thread.sleep(200);
1193
1194 assertEquals(0, cache.getMemoryStoreSize());
1195 assertEquals(100, cache.getDiskStoreSize());
1196 cacheManager.shutdown();
1197
1198 }
1199
1200
1201 /***
1202 * Shows the effect of jamming large amounts of puts into a cache that overflows to disk.
1203 * The DiskStore should cause puts to back off and avoid an out of memory error.
1204 */
1205 @Test
1206 public void testBehaviourOnDiskStoreBackUp() throws Exception {
1207 Cache cache = new Cache("testGetMemoryStoreSize", 1000, true, false, 100, 200, false, 0);
1208 manager.addCache(cache);
1209
1210 assertEquals(0, cache.getMemoryStoreSize());
1211
1212 Element a = null;
1213 int i = 0;
1214 try {
1215 for (; i < 150000; i++) {
1216 String key = i + "";
1217 String value = key;
1218 a = new Element(key, value + "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD");
1219 cache.put(a);
1220 }
1221 } catch (OutOfMemoryError e) {
1222 LOG.info("OutOfMemoryError: " + e.getMessage() + " " + i);
1223 fail();
1224 }
1225 }
1226
1227
1228 /***
1229 * Tests using elements with null values. They should work as normal.
1230 *
1231 * @throws Exception
1232 */
1233 @Test
1234 public void testElementWithNullValue() throws Exception {
1235 Cache cache = new Cache("testElementWithNullValue", 10, false, false, 100, 200);
1236 manager.addCache(cache);
1237
1238 Object key1 = new Object();
1239 Element element = new Element(key1, null);
1240 cache.put(element);
1241 assertNotNull(cache.get(key1));
1242 assertNotNull(cache.getQuiet(key1));
1243 assertSame(element, cache.get(key1));
1244 assertSame(element, cache.getQuiet(key1));
1245 assertNull(cache.get(key1).getObjectValue());
1246 assertNull(cache.getQuiet(key1).getObjectValue());
1247
1248 assertEquals(false, cache.isExpired(element));
1249 }
1250
1251
1252 /***
1253 * Tests put works correctly for Elements with overriden TTL
1254 *
1255 * @throws Exception
1256 */
1257 @Test
1258 public void testPutWithOverriddenTTLAndTTI() throws Exception {
1259 Cache cache = new Cache("testElementWithNullValue", 10, false, false, 1, 1);
1260 manager.addCache(cache);
1261
1262 Object key = new Object();
1263 Element element = new Element(key, "value");
1264 element.setTimeToLive(3);
1265 cache.put(element);
1266 Thread.sleep(1050);
1267 assertNotNull(cache.get(key));
1268 assertSame(element, cache.get(key));
1269
1270 Element element2 = new Element(key, "value");
1271 cache.put(element2);
1272 Thread.sleep(1999);
1273 assertNull(cache.get(key));
1274
1275 Element element3 = new Element(key, "value");
1276 element3.setTimeToLive(5);
1277 cache.put(element3);
1278 Thread.sleep(1999);
1279 assertSame(element3, cache.get(key));
1280
1281 }
1282
1283
1284 /***
1285 * Tests putQuiet works correctly for Elements with overriden TTL
1286 *
1287 * @throws Exception
1288 */
1289 @Test
1290 public void testPutQuietWithOverriddenTTLAndTTI() throws Exception {
1291 Cache cache = new Cache("testElementWithNullValue", 10, false, false, 1, 1);
1292 manager.addCache(cache);
1293
1294 Object key = new Object();
1295 Element element = new Element(key, "value");
1296 element.setTimeToLive(3);
1297 cache.putQuiet(element);
1298 Thread.sleep(1050);
1299 assertNotNull(cache.get(key));
1300 assertSame(element, cache.get(key));
1301
1302 Element element2 = new Element(key, "value");
1303 cache.putQuiet(element2);
1304 Thread.sleep(1999);
1305 assertNull(cache.get(key));
1306
1307 Element element3 = new Element(key, "value");
1308 element3.setTimeToLive(5);
1309 cache.putQuiet(element3);
1310 Thread.sleep(1999);
1311 assertSame(element3, cache.get(key));
1312
1313 }
1314
1315
1316 /***
1317 * Tests using elements with null values. They should work as normal.
1318 *
1319 * @throws Exception
1320 */
1321 @Test
1322 public void testNonSerializableElement() throws Exception {
1323 Cache cache = new Cache("testElementWithNonSerializableValue", 1, true, false, 100, 200);
1324 manager.addCache(cache);
1325
1326 Element element1 = new Element("key1", new Object());
1327 Element element2 = new Element("key2", new Object());
1328 cache.put(element1);
1329 cache.put(element2);
1330
1331
1332 if (cache.get("key1") == null) {
1333 assertNotNull(cache.get("key2"));
1334 } else {
1335 assertNull(cache.get("key2"));
1336 }
1337 }
1338
1339
1340 /***
1341 * Tests serialization of Serializable classes with null values.
1342 *
1343 * @throws Exception
1344 */
1345 @Test
1346 public void testNullCollectionsAreSerializable() throws Exception {
1347 Cache cache = new Cache("testElementWithNonSerializableValue", 1, true, false, 100, 200);
1348 manager.addCache(cache);
1349 ArrayList arrayList = null;
1350
1351 Element element1 = new Element("key1", arrayList);
1352 Element element2 = new Element("key2", arrayList);
1353 cache.put(element1);
1354 cache.put(element2);
1355
1356
1357 Element element = cache.get("key1");
1358 assertNotNull(element);
1359 assertNull(element.getValue());
1360
1361
1362 assertNotNull(cache.get("key2"));
1363 }
1364
1365
1366 /***
1367 * Tests what happens when an Element throws an Error on serialization. This mimics
1368 * what a nasty error like OutOfMemoryError could do.
1369 * <p/>
1370 * Before a change to the SpoolAndExpiryThread to handle this situation this test failed and generated the following log message.
1371 * Jun 28, 2006 7:17:16 PM net.sf.ehcache.store.DiskStore put
1372 * SEVERE: testThreadKillerCache: Elements cannot be written to disk store because the spool thread has died.
1373 *
1374 * @throws Exception
1375 */
1376 @Test
1377 public void testSpoolThreadHandlesThreadKiller() throws Exception {
1378 Cache cache = new Cache("testThreadKiller", 0, true, false, 100, 200);
1379 manager.addCache(cache);
1380
1381 Element elementThreadKiller = new Element("key", new ThreadKiller());
1382 cache.put(elementThreadKiller);
1383 Thread.sleep(2999);
1384 Element element1 = new Element("key1", "one");
1385 Element element2 = new Element("key2", "two");
1386 cache.put(element1);
1387 cache.put(element2);
1388
1389 Thread.sleep(2999);
1390
1391 assertNotNull(cache.get("key1"));
1392 assertNotNull(cache.get("key2"));
1393 }
1394
1395 /***
1396 * Tests disk store and memory store size
1397 *
1398 * @throws Exception
1399 */
1400 @Test
1401 public void testGetDiskStoreSize() throws Exception {
1402 Cache cache = new Cache("testGetDiskStoreSize", 1, true, false, 100, 200);
1403 manager.addCache(cache);
1404 assertEquals(0, cache.getDiskStoreSize());
1405
1406 cache.put(new Element("key1", "value1"));
1407 assertEquals(0, cache.getDiskStoreSize());
1408 assertEquals(1, cache.getSize());
1409
1410 cache.put(new Element("key2", "value2"));
1411 assertEquals(2, cache.getSize());
1412 assertEquals(1, cache.getDiskStoreSize());
1413 assertEquals(1, cache.getMemoryStoreSize());
1414
1415 cache.put(new Element("key3", "value3"));
1416 cache.put(new Element("key4", "value4"));
1417 assertEquals(4, cache.getSize());
1418 assertEquals(3, cache.getDiskStoreSize());
1419 assertEquals(1, cache.getMemoryStoreSize());
1420
1421
1422 assertTrue(((CompoundStore) cache.getStore()).unretrievedGet("key4") instanceof Element);
1423 cache.remove("key4");
1424 assertEquals(3, cache.getSize());
1425 assertEquals(3, cache.getDiskStoreSize());
1426 assertEquals(0, cache.getMemoryStoreSize());
1427
1428
1429 assertFalse(((CompoundStore) cache.getStore()).unretrievedGet("key1") instanceof Element);
1430 cache.remove("key1");
1431 assertEquals(2, cache.getSize());
1432 assertEquals(2, cache.getDiskStoreSize());
1433 assertEquals(0, cache.getMemoryStoreSize());
1434
1435
1436 cache.put(new Element("key5", "value5"));
1437 assertEquals(3, cache.getSize());
1438 assertEquals(2, cache.getDiskStoreSize());
1439 assertEquals(1, cache.getMemoryStoreSize());
1440
1441
1442 cache.removeAll();
1443 assertEquals(0, cache.getSize());
1444 assertEquals(0, cache.getDiskStoreSize());
1445 assertEquals(0, cache.getMemoryStoreSize());
1446
1447
1448 cache.put(new Element(new Object(), new Object()));
1449 cache.put(new Element(new Object(), new Object()));
1450 cache.put(new Element(new Object(), new Object()));
1451
1452 Thread.sleep(200);
1453
1454 assertEquals(1, cache.getSize());
1455 assertEquals(0, cache.getDiskStoreSize());
1456 assertEquals(1, cache.getMemoryStoreSize());
1457
1458 }
1459
1460 /***
1461 * Tests that attempting to clone a cache fails with the right exception.
1462 *
1463 * @throws Exception
1464 */
1465 @Test
1466 public void testCloneFailures() throws Exception {
1467 Cache cache = new Cache("testGetMemoryStore", 10, false, false, 100, 200);
1468 manager.addCache(cache);
1469 try {
1470 cache.clone();
1471 fail("Should have thrown CloneNotSupportedException");
1472 } catch (CloneNotSupportedException e) {
1473
1474 }
1475 }
1476
1477
1478 /***
1479 * Tests that the toString() method works.
1480 */
1481 @Test
1482 public void testToString() {
1483 Ehcache cache = new Cache("testGetMemoryStore", 10, false, false, 100, 200);
1484 assertTrue(cache.toString().indexOf("testGetMemoryStore") > -1);
1485 assertEquals(410, cache.toString().length());
1486 }
1487
1488
1489 /***
1490 * When does equals mean the same thing as == ?
1491 *
1492 * @throws CacheException
1493 * @throws InterruptedException
1494 */
1495 @Test
1496 public void testEquals() throws CacheException, InterruptedException {
1497 Cache cache = new Cache("cache", 1, true, false, 100, 200, false, 1);
1498 manager.addCache(cache);
1499
1500 Element element1 = new Element("1", new Date());
1501 Element element2 = new Element("2", new Date());
1502 cache.put(element1);
1503 cache.put(element2);
1504
1505
1506 Element elementFromStore = cache.get("2");
1507 assertEquals(element2, elementFromStore);
1508 assertTrue(element2 == elementFromStore);
1509
1510
1511 Thread.sleep(300);
1512
1513
1514 Element elementFromDiskStore = cache.get("1");
1515 assertEquals(element1, elementFromDiskStore);
1516 assertTrue(element1 != elementFromDiskStore);
1517 }
1518
1519 /***
1520 * When does equals mean the same thing as == ?
1521 *
1522 * @throws CacheException
1523 * @throws InterruptedException
1524 */
1525 @Test
1526 public void testIsKeyInCache() throws CacheException, InterruptedException {
1527 Cache cache = new Cache("cache", 1, true, false, 100, 200, false, 1);
1528 manager.addCache(cache);
1529
1530 Element element1 = new Element("1", new Date());
1531 Element element2 = new Element("2", new Date());
1532 cache.put(element1);
1533 cache.put(element2);
1534
1535 assertTrue(cache.isKeyInCache("1"));
1536 assertTrue(cache.isKeyInCache("2"));
1537 assertFalse(cache.isKeyInCache(null));
1538 }
1539
1540 /***
1541 * Tests the uniqueness of the GUID
1542 */
1543 @Test
1544 public void testGuid() {
1545 Ehcache cache1 = new Cache("testGetMemoryStore", 10, false, false, 100, 200);
1546 Ehcache cache2 = new Cache("testGetMemoryStore", 10, false, false, 100, 200);
1547 String guid1 = cache1.getGuid();
1548 String guid2 = cache2.getGuid();
1549 assertEquals(cache1.getName(), cache2.getName());
1550 assertTrue(!guid1.equals(guid2));
1551
1552 }
1553
1554
1555 /***
1556 * Does the Object API work?
1557 */
1558 @Test
1559 public void testAPIObjectCompatibility() {
1560 Cache cache = new Cache("test", 5, true, false, 5, 2);
1561 manager.addCache(cache);
1562
1563 Object objectKey = new Object();
1564 Object objectValue = new Object();
1565 Element objectElement = new Element(objectKey, objectValue);
1566 cache.put(objectElement);
1567
1568
1569 Element retrievedElement = cache.get(objectKey);
1570 assertNotNull(retrievedElement);
1571 try {
1572 retrievedElement.getObjectValue();
1573 } catch (CacheException e) {
1574
1575 }
1576
1577
1578 retrievedElement = cache.get(objectKey);
1579 assertEquals(objectElement, retrievedElement);
1580
1581
1582 retrievedElement = cache.get(objectKey);
1583 assertEquals(objectValue, retrievedElement.getObjectValue());
1584
1585 }
1586
1587
1588 /***
1589 * Does the Serializable API work?
1590 */
1591 @Test
1592 public void testAPISerializableCompatibility() {
1593 Cache cache = new Cache("test", 5, true, false, 5, 2);
1594 manager.addCache(cache);
1595
1596
1597 Serializable key = new String();
1598 Element objectElement = new Element(key, new String());
1599 cache.put(objectElement);
1600 Object retrievedObject = cache.get(key);
1601 assertEquals(retrievedObject, objectElement);
1602
1603
1604 assertEquals(objectElement, retrievedObject);
1605 }
1606
1607 /***
1608 * Test issues reported.
1609 */
1610 @Test
1611 public void testDiskStoreFlorian() throws InterruptedException {
1612 manager.shutdown();
1613
1614 byte[] config = ("<ehcache> \n" +
1615 "<diskStore path=\"java.io.tmpdir\"/> \n" +
1616 "<defaultCache \n" +
1617 " maxElementsInMemory=\"10000\" \n" +
1618 " eternal=\"false\" \n" +
1619 " timeToIdleSeconds=\"120\" \n" +
1620 " timeToLiveSeconds=\"120\" \n" +
1621 " overflowToDisk=\"true\" \n" +
1622 " diskPersistent=\"false\" \n" +
1623 " diskExpiryThreadIntervalSeconds=\"120\" \n" +
1624 " memoryStoreEvictionPolicy=\"LRU\" \n" +
1625 " /> " +
1626 "\n" +
1627 "<cache name=\"testCache\" \n" +
1628 " maxElementsInMemory=\"20000\" \n" +
1629 " eternal=\"false\" \n" +
1630 " overflowToDisk=\"false\" \n" +
1631 " timeToIdleSeconds=\"300\" \n" +
1632 " timeToLiveSeconds=\"600\" \n" +
1633 " diskPersistent=\"false\" \n" +
1634 " diskExpiryThreadIntervalSeconds=\"1\" \n" +
1635 " memoryStoreEvictionPolicy=\"LFU\" \n" +
1636 "/> \n" +
1637 "<cache name=\"test2Cache\" \n" +
1638 " maxElementsInMemory=\"20000\" \n" +
1639 " eternal=\"false\" \n" +
1640 " overflowToDisk=\"true\" \n" +
1641 " timeToIdleSeconds=\"300\" \n" +
1642 " timeToLiveSeconds=\"600\" \n" +
1643 " diskPersistent=\"false\" \n" +
1644 " diskExpiryThreadIntervalSeconds=\"1\" \n" +
1645 " memoryStoreEvictionPolicy=\"LFU\" \n" +
1646 "/> \n" +
1647 "</ehcache> ").getBytes();
1648
1649
1650 CacheManager cacheManager = new CacheManager(new ByteArrayInputStream(config));
1651 Cache cache = new Cache("test3cache", 20000, false, true, 50, 30);
1652
1653 cacheManager.addCache(cache);
1654
1655
1656 for (int i = 0; i < 25000; i++) {
1657 cache.put(new Element(i + "", "value"));
1658
1659 }
1660 assertEquals(20000, cache.getSize());
1661
1662 }
1663
1664
1665
1666
1667 /***
1668 * Tests added from 1606323 Elements not stored in memory or on disk. This was supposedly
1669 * a bug but works.
1670 * This test passes.
1671 *
1672 * @throws Exception
1673 */
1674 @Test
1675 public void testTimeToLive15552000() throws Exception {
1676 long timeToLiveSeconds = 15552000;
1677 doRunTest(timeToLiveSeconds);
1678 }
1679
1680 /***
1681 * This test passes.
1682 *
1683 * @throws Exception
1684 */
1685 @Test
1686 public void testTimeToLive604800() throws Exception {
1687 long timeToLiveSeconds = 604800;
1688 doRunTest(timeToLiveSeconds);
1689 }
1690
1691 private void doRunTest(long timeToLiveSeconds) {
1692 String name = "memoryAndDiskCache";
1693 int maxElementsInMemory = 1000;
1694 MemoryStoreEvictionPolicy memoryStoreEvictionPolicy = MemoryStoreEvictionPolicy.LRU;
1695 boolean overflowToDisk = true;
1696 String diskStorePath = "java.io.tmp.dir/cache";
1697 boolean eternal = false;
1698 long timeToIdleSeconds = 0;
1699 boolean diskPersistent = true;
1700 long diskExpiryThreadIntervalSeconds = 3600;
1701 RegisteredEventListeners registeredEventListeners = null;
1702 BootstrapCacheLoader bootstrapCacheLoader = null;
1703
1704 Cache memoryAndDisk = new Cache(
1705 name,
1706 maxElementsInMemory,
1707 memoryStoreEvictionPolicy,
1708 overflowToDisk,
1709 diskStorePath,
1710 eternal,
1711 timeToLiveSeconds,
1712 timeToIdleSeconds,
1713 diskPersistent,
1714 diskExpiryThreadIntervalSeconds,
1715 registeredEventListeners,
1716 bootstrapCacheLoader);
1717
1718 this.manager.addCache(memoryAndDisk);
1719
1720 String key = "test";
1721 Object value = "value";
1722
1723 memoryAndDisk.put(new Element(key, value));
1724
1725 assertTrue(memoryAndDisk.isElementInMemory(key));
1726 }
1727
1728 /***
1729 * Tests get from a finalize method, following a mailing list post from Felix Satyaputr
1730 *
1731 * @throws InterruptedException
1732 */
1733 @Test
1734 public void testGetQuietFromFinalize() throws InterruptedException {
1735
1736
1737 final Cache cache = new Cache("test", 1, true, false, 5, 2);
1738 manager.addCache(cache);
1739
1740 cache.put(new Element("key", "value"));
1741 cache.put(new Element("key2", "value"));
1742 cache.put(new Element("key3", "value"));
1743 cache.put(new Element("key4", "value"));
1744 cache.put(new Element("key5", "value"));
1745
1746
1747 Thread.sleep(200);
1748
1749 createTestObject();
1750
1751
1752 System.gc();
1753 Thread.sleep(200);
1754 System.gc();
1755
1756
1757 }
1758
1759 private void createTestObject() {
1760 new TestObject();
1761 }
1762
1763
1764 /***
1765 * A class with a finalize implementation.
1766 */
1767 class TestObject {
1768
1769 /***
1770 * Override the Object finalize method
1771 */
1772 @Override
1773 protected void finalize() throws Throwable {
1774 manager.getCache("test").getQuiet("key");
1775 LOG.info("finalize run from thread " + Thread.currentThread().getName());
1776 super.finalize();
1777 }
1778 }
1779
1780
1781 @Test
1782 public void testGetWithLoader() {
1783
1784 /***
1785 *
1786 */
1787 class TestCacheLoader implements CacheLoader {
1788
1789
1790 public Object load(Object key, Object argument) throws CacheException {
1791 LOG.info("load1 " + key);
1792 return key;
1793 }
1794
1795 public Map loadAll(Collection keys, Object argument) throws CacheException {
1796 return null;
1797 }
1798
1799
1800 public String getName() {
1801 return null;
1802 }
1803
1804 public CacheLoader clone(Ehcache cache) throws CloneNotSupportedException {
1805 return null;
1806 }
1807
1808 public void init() {
1809
1810 }
1811
1812 public void dispose() throws CacheException {
1813
1814 }
1815
1816 public Status getStatus() {
1817 return null;
1818 }
1819
1820 public Object load(Object o) throws CacheException {
1821 LOG.info("load2 " + o + " " + o.getClass());
1822 if (o.equals("c")) {
1823 return null;
1824 }
1825 return o;
1826 }
1827
1828 public Map loadAll(Collection collection) throws CacheException {
1829 return null;
1830 }
1831
1832
1833 }
1834
1835 Cache cache = manager.getCache("sampleCache1");
1836 cache.registerCacheLoader(new TestCacheLoader());
1837
1838
1839 Element element = cache.get("a");
1840 assertNull(element);
1841
1842 element = cache.getWithLoader("b", null, null);
1843 assertNotNull(element);
1844
1845
1846 element = cache.getWithLoader("c", null, null);
1847 assertNull(element);
1848 }
1849
1850 /***
1851 * Tests the async load with a single item
1852 */
1853 @Test
1854 public void testAsynchronousLoad() throws InterruptedException, ExecutionException {
1855
1856 CountingCacheLoader countingCacheLoader = new CountingCacheLoader();
1857 Cache cache = manager.getCache("sampleCache1");
1858 cache.registerCacheLoader(countingCacheLoader);
1859 ExecutorService executorService = cache.getExecutorService();
1860
1861 Future future = cache.asynchronousLoad("key1", null, null);
1862
1863 Object object = future.get();
1864 assertTrue(future.isDone());
1865 assertNull(object);
1866
1867 assertFalse(executorService.isShutdown());
1868
1869 assertEquals(1, cache.getSize());
1870 assertEquals(1, countingCacheLoader.getLoadCounter());
1871 }
1872
1873 /***
1874 * Tests the async load with a single item
1875 */
1876 @Test
1877 public void testGetWithLoaderException() {
1878 Cache cache = manager.getCache("sampleCache1");
1879 cache.registerCacheLoader(new ExceptionThrowingLoader());
1880 try {
1881 cache.getWithLoader("key1", null, null);
1882 fail();
1883 } catch (CacheException e) {
1884
1885 }
1886 }
1887
1888
1889 /***
1890 * Tests the loadAll async method
1891 */
1892 @Test
1893 public void testAsynchronousLoadAll() throws InterruptedException, ExecutionException {
1894
1895 CountingCacheLoader countingCacheLoader = new CountingCacheLoader();
1896 Cache cache = manager.getCache("sampleCache1");
1897 cache.registerCacheLoader(countingCacheLoader);
1898 ExecutorService executorService = cache.getExecutorService();
1899
1900 List keys = new ArrayList();
1901 for (int i = 0; i < 1000; i++) {
1902 keys.add(Integer.valueOf(i));
1903 }
1904
1905 Future future = cache.asynchronousLoadAll(keys, null);
1906 assertFalse(future.isDone());
1907
1908 Object object = future.get();
1909 assertTrue(future.isDone());
1910 assertNull(object);
1911
1912 assertFalse(executorService.isShutdown());
1913
1914 assertEquals(1000, cache.getSize());
1915 assertEquals(1000, countingCacheLoader.getLoadAllCounter());
1916 }
1917
1918 /***
1919 * Tests programmatically disabling and enabling a cache
1920 */
1921 @Test
1922 public void testEnableAndDisable() throws Exception {
1923 Ehcache cache = manager.getCache("sampleCacheNoIdle");
1924 cache.put(new Element("key1put", "value1"));
1925 cache.put(new Element("key1putQuiet", "value1"));
1926 assertFalse(cache.isDisabled());
1927 assertNotNull(cache.get("key1put"));
1928 assertNotNull(cache.get("key1putQuiet"));
1929
1930
1931 cache.setDisabled(true);
1932
1933 assertTrue(cache.isDisabled());
1934 assertNull(cache.get("key1put"));
1935 assertNull(cache.get("key1putQuiet"));
1936
1937 cache.put(new Element("key2put", "value1"));
1938 cache.put(new Element("key2putQuiet", "value1"));
1939 assertNull(cache.get("key2put"));
1940 assertNull(cache.get("key2putQuiet"));
1941 }
1942
1943
1944 /***
1945 * Run testConcurrentPutsAreConsistent() repeatedly for 50 times to shake out issues that happen rarely.
1946 */
1947 @Test
1948 public void testConcurrentPutsAreConsistentRepeatedly() throws InterruptedException {
1949 for (int i = 0; i < 20; i++) {
1950 manager.removalAll();
1951 testConcurrentPutsAreConsistent();
1952 }
1953 }
1954
1955 /***
1956 * Shows a consistency problem as reported against 1.6.0.
1957 * <p/>
1958 * Does not happen when not using DiskStore
1959 * Putting synchronized on put/get on cache fixes it
1960 * Only happens when the Element is retrieved from the DiskStore. Debugging shows
1961 * that the problem is caused by puts not getting through or coming in the wrong order
1962 * Putting synchronized on MemoryStore.put() fixes the issue. That is the applied fix.
1963 * <p/>
1964 * The exact cause is unknown but the behaviour of ConcurrentHashMap is suspected.
1965 */
1966 @Test
1967 public void testConcurrentPutsAreConsistent() throws InterruptedException {
1968 Cache cache = new Cache("someName", 100, true, true, 0, 0);
1969 manager.addCache(cache);
1970
1971 cache.setStatisticsEnabled(true);
1972
1973 ExecutorService executor = Executors.newFixedThreadPool(10);
1974
1975 for (int i = 0; i < 5000; i++) {
1976 executor.execute(new CacheTestRunnable(cache, String.valueOf(i)));
1977 }
1978 executor.shutdown();
1979 executor.awaitTermination(10, TimeUnit.SECONDS);
1980
1981 assertEquals("Failures: ", 0, CacheTestRunnable.FAILURES.size());
1982 assertEquals(5000, cache.getStatistics().getCacheHits());
1983
1984 }
1985
1986 /***
1987 * A runnable that sets 5 times in a row then calls get and checks it is the last value set
1988 */
1989 private static final class CacheTestRunnable implements Runnable {
1990 static final List FAILURES = new ArrayList();
1991
1992 private Ehcache cache;
1993 private String key;
1994
1995 private CacheTestRunnable(Ehcache cache, String key) {
1996 this.cache = cache;
1997 this.key = key;
1998 }
1999
2000 public void run() {
2001 setValue("new value");
2002 setValue("new value2");
2003 setValue("new value3");
2004 setValue("new value4");
2005 setValue("new value5");
2006
2007 Element element = cache.get(key);
2008 String value = element.getValue().toString();
2009 boolean result = value.equals("new value5");
2010 if (!result) {
2011 LOG.info("key is: " + key + " value: " + value + " version: " + element.getVersion());
2012 FAILURES.add("key is: " + key + " value: " + value);
2013 }
2014 }
2015
2016 private void setValue(String valueToSet) {
2017 cache.put(new Element(key, valueToSet));
2018 }
2019
2020 }
2021
2022 /***
2023 * test cache clones do not have same statistics
2024 *
2025 * @throws Exception
2026 */
2027 @Test
2028 public void testCloneCompleteness() throws Exception {
2029 Cache cache = new Cache("testGetMemoryStore", 10, false, false, 100,
2030 200);
2031 Cache clone = cache.clone();
2032 clone.setName("testGetMemoryStoreClone");
2033 manager.addCache(cache);
2034 manager.addCache(clone);
2035
2036 cache.setStatisticsEnabled(true);
2037 clone.setStatisticsEnabled(true);
2038
2039 assertFalse(cache.getGuid().equals(clone.getGuid()));
2040
2041
2042
2043 cache.get("notFoundKey");
2044 assertEquals(1, cache.getStatistics().getCacheMisses());
2045 assertEquals(0, clone.getStatistics().getCacheMisses());
2046 }
2047
2048
2049 /***
2050 * Checks that notification only happens once when clearOnFlush is false i.e.
2051 * The impact of this is that there will be one copy in each store.
2052 */
2053 @Test
2054 public void testRemoveListenersCalledOnce() {
2055 Cache cache = manager.getCache("sampleCache1");
2056 RemoveCountingListener l = new RemoveCountingListener();
2057 cache.getCacheEventNotificationService().registerListener(l);
2058
2059 cache.getCacheConfiguration().setDiskPersistent(true);
2060 cache.getCacheConfiguration().setClearOnFlush(false);
2061
2062 Element element = new Element("foo", "bar", 1L);
2063
2064 cache.put(element);
2065
2066 cache.flush();
2067
2068 cache.remove("foo");
2069
2070 assertEquals(1, l.count);
2071 assertSame(element, l.element);
2072
2073 }
2074
2075 /***
2076 * test listener
2077 */
2078 private static class RemoveCountingListener implements CacheEventListener {
2079
2080 private int count;
2081 private Element element;
2082
2083 public void notifyElementRemoved(Ehcache cache, Element element)
2084 throws CacheException {
2085 count++;
2086 this.element = element;
2087 }
2088
2089 public void dispose() {
2090
2091 }
2092
2093 public void notifyElementEvicted(Ehcache cache, Element element) {
2094
2095 }
2096
2097 public void notifyElementExpired(Ehcache cache, Element element) {
2098
2099 }
2100
2101 public void notifyElementPut(Ehcache cache, Element element)
2102 throws CacheException {
2103
2104 }
2105
2106 public void notifyElementUpdated(Ehcache cache, Element element)
2107 throws CacheException {
2108 }
2109
2110 public void notifyRemoveAll(Ehcache cache) {
2111
2112 }
2113
2114 @Override
2115 public Object clone() throws CloneNotSupportedException {
2116 return super.clone();
2117 }
2118 }
2119
2120 /***
2121 * Checks that TTL of Long.MAX_VALUE means value never expires.
2122 * See EHC-432.
2123 */
2124 @Test
2125 public void testMaxLongTTLIsEternal() {
2126 long maxLiveTime = Long.MAX_VALUE;
2127
2128 final Cache cache = new Cache("bla", 5000, false, false, maxLiveTime, 0);
2129 final CacheManager cacheManager = CacheManager.create();
2130
2131 cacheManager.addCache(cache);
2132
2133 Element e = new Element("key", "bla");
2134 cache.put(e);
2135
2136
2137
2138
2139
2140 Element e2 = cache.get("key");
2141 assertNotNull(e2);
2142 }
2143
2144 /***
2145 * Checks that TTL of Integer.MAX_VALUE means value never expires.
2146 * See EHC-432.
2147 */
2148 @Test
2149 public void testMaxIntegerTTLIsEternal() {
2150 long maxLiveTime = Integer.MAX_VALUE;
2151
2152 final Cache cache = new Cache("bla", 5000, false, false, maxLiveTime, 0);
2153 final CacheManager cacheManager = CacheManager.create();
2154
2155 cacheManager.addCache(cache);
2156
2157 Element e = new Element("key", "bla");
2158 cache.put(e);
2159
2160
2161
2162
2163
2164 Element e2 = cache.get("key");
2165 assertNotNull(e2);
2166 }
2167
2168 /***
2169 * Versioning is broken when updates are done. If an Element constructor specifying a version is used, it should
2170 * be preserved. If not the version should start at one and then be incremented.
2171 *
2172 * todo This test fails. When the implementation is corrected it will pass. This test is therefore currently marked @Ignore
2173 *
2174 * See EHC-666
2175 */
2176 @Test
2177 @Ignore
2178 public void testVersioningShouldBePreserved() {
2179
2180 CacheManager cacheManager = CacheManager.getInstance();
2181 cacheManager.addCache(new Cache("mltest", 50, MemoryStoreEvictionPolicy.LRU, true, null, true, 0, 0, false, 120, null, null, 0, 2, false));
2182 Cache cache = cacheManager.getCache("mltest");
2183
2184 Element a = new Element("a key", "a value", 1L);
2185 cache.put(a);
2186 Element aAfter = cache.get("a key");
2187 assertEquals(1L, aAfter.getVersion());
2188
2189 LOG.info("Element after first put with specific version." + aAfter);
2190
2191
2192 Element b = new Element("a key", "a value");
2193 cache.put(b);
2194 Element bAfter = cache.get("a key");
2195 assertFalse(1L == bAfter.getVersion());
2196 LOG.info("Element after second put. No version." + bAfter);
2197
2198
2199 Element c = new Element("a key", "a value", 3L);
2200 cache.put(c);
2201 LOG.info("Element after third put with specific version." + cache.get("a key"));
2202 Element cAfter = cache.get("a key");
2203 assertEquals(3L, cAfter.getVersion());
2204
2205 }
2206
2207 }
2208