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