View Javadoc

1   /***
2    *  Copyright 2003-2008 Luck Consulting Pty Ltd
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 java.util.concurrent.ExecutionException;
20  import java.util.concurrent.ExecutorService;
21  import java.util.concurrent.Future;
22  import net.sf.ehcache.bootstrap.BootstrapCacheLoader;
23  import net.sf.ehcache.event.RegisteredEventListeners;
24  import net.sf.ehcache.exceptionhandler.ExceptionHandlingDynamicCacheProxy;
25  import net.sf.ehcache.loader.CountingCacheLoader;
26  import net.sf.ehcache.loader.ExceptionThrowingLoader;
27  import net.sf.ehcache.loader.CacheLoader;
28  import net.sf.ehcache.store.MemoryStoreEvictionPolicy;
29  
30  
31  
32  import java.io.ByteArrayInputStream;
33  import java.io.Serializable;
34  import java.util.ArrayList;
35  import java.util.Date;
36  import java.util.HashMap;
37  import java.util.List;
38  import java.util.Random;
39  import java.util.Collection;
40  import java.util.Map;
41  import java.util.logging.Logger;
42  
43  
44  /***
45   * Tests for a Cache
46   *
47   * @author Greg Luck, Claus Ibsen
48   * @version $Id: CacheTest.java 744 2008-08-16 20:10:49Z gregluck $
49   */
50  public class CacheTest extends AbstractCacheTest {
51  
52      private static final Logger LOG = Logger.getLogger(CacheTest.class.getName());
53  
54  
55      /***
56       * teardown
57       */
58      protected void tearDown() throws Exception {
59          super.tearDown();
60      }
61  
62      /***
63       * Gets the sample cache 1
64       */
65      protected Ehcache getSampleCache1() {
66          Cache cache = manager.getCache("sampleCache1");
67          return cache;
68      }
69  
70      /***
71       * Creates a cache
72       *
73       * @return
74       */
75      protected Ehcache createTestCache() {
76          Cache cache = new Cache("test4", 1000, true, true, 0, 0);
77          manager.addCache(cache);
78          return cache;
79      }
80  
81      /***
82       * Checks we cannot use a cache after shutdown
83       */
84      public void testUseCacheAfterManagerShutdown() throws CacheException {
85          Ehcache cache = getSampleCache1();
86          manager.shutdown();
87          Element element = new Element("key", "value");
88          try {
89              cache.getSize();
90              fail();
91          } catch (IllegalStateException e) {
92              assertEquals("The sampleCache1 Cache is not alive.", e.getMessage());
93          }
94          try {
95              cache.put(element);
96              fail();
97          } catch (IllegalStateException e) {
98              assertEquals("The sampleCache1 Cache is not alive.", e.getMessage());
99          }
100         try {
101             cache.get("key");
102             fail();
103         } catch (IllegalStateException e) {
104             assertEquals("The sampleCache1 Cache is not alive.", e.getMessage());
105         }
106         if (cache instanceof Cache) {
107             Cache castCache = (Cache) cache;
108             //ok to get stats
109             castCache.getHitCount();
110             castCache.getMemoryStoreHitCount();
111             castCache.getDiskStoreHitCount();
112             castCache.getMissCountExpired();
113             castCache.getMissCountNotFound();
114         }
115 
116     }
117 
118 
119     /***
120      * Checks we cannot use a cache outside the manager
121      */
122     public void testUseCacheOutsideManager() throws CacheException {
123         //Not put into manager.
124         Cache cache = new Cache("testCache", 1, true, false, 5, 2);
125         Element element = new Element("key", "value");
126         try {
127             cache.getSize();
128             fail();
129         } catch (IllegalStateException e) {
130             assertEquals("The testCache Cache is not alive.", e.getMessage());
131         }
132         try {
133             cache.put(element);
134             fail();
135         } catch (IllegalStateException e) {
136             assertEquals("The testCache Cache is not alive.", e.getMessage());
137         }
138         try {
139             cache.get("key");
140             fail();
141         } catch (IllegalStateException e) {
142             assertEquals("The testCache Cache is not alive.", e.getMessage());
143         }
144         //ok to get stats
145         cache.getHitCount();
146         cache.getMemoryStoreHitCount();
147         cache.getDiskStoreHitCount();
148         cache.getMissCountExpired();
149         cache.getMissCountNotFound();
150     }
151 
152     /***
153      * Checks when and how we can set the cache name.
154      */
155     public void testSetCacheName() throws CacheException {
156         //Not put into manager.
157         Ehcache cache = new Cache("testCache", 1, true, false, 5, 2);
158 
159         try {
160             cache.setName(null);
161             fail();
162         } catch (IllegalArgumentException e) {
163             //expected
164         }
165 
166         try {
167             cache.setName("illegal/name");
168             fail();
169         } catch (IllegalArgumentException e) {
170             //expected
171         }
172 
173         manager.addCache(cache);
174         try {
175             cache.setName("trying_to_change_name_after_initialised");
176             fail();
177         } catch (IllegalStateException e) {
178             //expected
179         }
180     }
181 
182 
183     /***
184      * Test using a cache which has been removed and replaced.
185      */
186     public void testStaleCacheReference() throws CacheException {
187         manager.addCache("test");
188         Ehcache cache = manager.getCache("test");
189         assertNotNull(cache);
190         cache.put(new Element("key1", "value1"));
191 
192         assertEquals("value1", cache.get("key1").getObjectValue());
193         manager.removeCache("test");
194         manager.addCache("test");
195 
196         try {
197             cache.get("key1");
198             fail();
199         } catch (IllegalStateException e) {
200             assertEquals("The test Cache is not alive.", e.getMessage());
201         }
202     }
203 
204     /***
205      * Tests getting the cache name
206      *
207      * @throws Exception
208      */
209     public void testCacheName() throws Exception {
210         manager.addCache("test");
211         Ehcache cache = manager.getCache("test");
212         assertEquals("test", cache.getName());
213         assertEquals(Status.STATUS_ALIVE, cache.getStatus());
214     }
215 
216 
217     /***
218      * Tests getting the cache name
219      *
220      * @throws Exception
221      */
222     public void testCacheWithNoIdle() throws Exception {
223         Ehcache cache = manager.getCache("sampleCacheNoIdle");
224         assertEquals("sampleCacheNoIdle", cache.getName());
225         assertEquals(Status.STATUS_ALIVE, cache.getStatus());
226         assertEquals(0, cache.getTimeToIdleSeconds());
227     }
228 
229     /***
230      * Test expiry based on time to live
231      * <cache name="sampleCacheNoIdle"
232      * maxElementsInMemory="1000"
233      * eternal="false"
234      * timeToLiveSeconds="5"
235      * overflowToDisk="false"
236      * />
237      */
238     public void testExpiryBasedOnTimeToLiveWhenNoIdle() throws Exception {
239         //Set size so the second element overflows to disk.
240         Ehcache cache = manager.getCache("sampleCacheNoIdle");
241         cache.put(new Element("key1", "value1"));
242         cache.put(new Element("key2", "value1"));
243         assertNotNull(cache.get("key1"));
244         assertNotNull(cache.get("key2"));
245 
246         //Test time to idle. Should not idle out because not specified
247         Thread.sleep(2000);
248         assertNotNull(cache.get("key1"));
249         assertNotNull(cache.get("key2"));
250 
251         //Test time to live.
252         Thread.sleep(5020);
253         assertNull(cache.get("key1"));
254         assertNull(cache.get("key2"));
255     }
256 
257 
258 
259     /***
260      * Tests that the version and lastUpdate get upped for each put.
261      * <cache name="sampleCacheNoIdle"
262      * maxElementsInMemory="1000"
263      * eternal="false"
264      * timeToLiveSeconds="5"
265      * overflowToDisk="false"
266      * />
267      */
268     public void testLastUpdate() throws Exception {
269         //Set size so the second element overflows to disk.
270         Ehcache cache = manager.getCache("sampleCache1");
271         long beforeElementCreation = System.currentTimeMillis();
272         //put in delay because time resolution is not exact on Windows
273         Thread.sleep(10);        
274         cache.put(new Element("key1", "value1"));
275         Element element = cache.get("key1");
276         assertTrue(element.getCreationTime() >= beforeElementCreation);
277         LOG.info("version: " + element.getVersion());
278         LOG.info("creationTime: " + element.getCreationTime());
279         LOG.info("lastUpdateTime: " + element.getLastUpdateTime());
280         assertEquals(0, element.getLastUpdateTime());
281 
282         cache.put(new Element("key1", "value1"));
283         element = cache.get("key1");
284         LOG.info("version: " + element.getVersion());
285         LOG.info("creationTime: " + element.getCreationTime());
286         LOG.info("lastUpdateTime: " + element.getLastUpdateTime());
287 
288         cache.put(new Element("key1", "value1"));
289         element = cache.get("key1");
290         LOG.info("version: " + element.getVersion());
291         LOG.info("creationTime: " + element.getCreationTime());
292         LOG.info("lastUpdateTime: " + element.getLastUpdateTime());
293     }
294 
295 
296     /***
297      * When to search the disk store
298      */
299     public void testOverflowToDiskAndDiskPersistent() throws Exception {
300         Ehcache cache = manager.getCache("sampleIdlingExpiringCache");
301 
302         for (int i = 0; i < 1001; i++) {
303             cache.put(new Element("key" + i, "value1"));
304         }
305 
306         assertNotNull(cache.get("key0"));
307 
308         for (int i = 0; i < 1001; i++) {
309             cache.put(new Element("key" + i, "value1"));
310             assertNotNull(cache.get("key" + i));
311         }
312     }
313 
314 
315     /***
316      * Test expiry based on time to live for a cache with config
317      * <cache name="sampleCacheNoIdle"
318      * maxElementsInMemory="1000"
319      * eternal="false"
320      * timeToLiveSeconds="5"
321      * overflowToDisk="false"
322      * />
323      * <p/>
324      * where an Elment override is set on TTL
325      */
326     public void testExpiryBasedOnTimeToLiveWhenNoIdleElementOverride() throws Exception {
327         //Set size so the second element overflows to disk.
328         Ehcache cache = manager.getCache("sampleCacheNoIdle");
329         Element element1 = new Element("key1", "value1");
330         element1.setTimeToLive(3);
331         cache.put(element1);
332 
333         Element element2 = new Element("key2", "value1");
334         element2.setTimeToLive(3);
335         cache.put(element2);
336         assertNotNull(cache.get("key1"));
337         assertNotNull(cache.get("key2"));
338 
339         //Test time to idle. Should not idle out because not specified
340         Thread.sleep(1000);
341         assertNotNull(cache.get("key1"));
342         assertNotNull(cache.get("key2"));
343 
344         //Test time to live.
345         Thread.sleep(4020);
346         assertNull(cache.get("key1"));
347         assertNull(cache.get("key2"));
348     }
349 
350     /***
351      * Test expiry based on time to live for a cache with config
352      * <cache name="sampleCacheNoIdle"
353      * maxElementsInMemory="1000"
354      * eternal="false"
355      * timeToLiveSeconds="5"
356      * overflowToDisk="false"
357      * />
358      * <p/>
359      * where an Elment override is set on TTL
360      */
361     public void testExpiryBasedOnTimeToIdleElementOverride() throws Exception {
362         //Set size so the second element overflows to disk.
363         Ehcache cache = manager.getCache("sampleCacheNoIdle");
364         assertEquals(30, cache.getCacheConfiguration().getDiskSpoolBufferSizeMB());
365         Element element1 = new Element("key1", "value1");
366         element1.setTimeToIdle(1);
367         cache.put(element1);
368 
369         Element element2 = new Element("key2", "value1");
370         element2.setTimeToIdle(1);
371         cache.put(element2);
372         assertNotNull(cache.get("key1"));
373         assertNotNull(cache.get("key2"));
374 
375         //Test time to idle. Should not idle out because not specified
376         Thread.sleep(1050);
377         assertNull(cache.get("key1"));
378         assertNull(cache.get("key2"));
379 
380     }
381 
382 
383     /***
384      * Test expiry based on time to live for a cache with config
385      * <cache name="sampleCacheNoIdle"
386      * maxElementsInMemory="1000"
387      * eternal="false"
388      * timeToLiveSeconds="5"
389      * overflowToDisk="false"
390      * />
391      * <p/>
392      * where an Elment override is set on TTL
393      */
394     public void testExpiryBasedEternalElementOverride() throws Exception {
395         //Set size so the second element overflows to disk.
396         Ehcache cache = manager.getCache("sampleCacheNoIdle");
397         Element element1 = new Element("key1", "value1");
398         element1.setEternal(true);
399         cache.put(element1);
400 
401         Element element2 = new Element("key2", "value1");
402         element2.setEternal(true);
403         cache.put(element2);
404         assertNotNull(cache.get("key1"));
405         assertNotNull(cache.get("key2"));
406 
407         Thread.sleep(5050);
408         assertNotNull(cache.get("key1"));
409         assertNotNull(cache.get("key2"));
410 
411     }
412 
413 
414     /***
415      * Test expiry based on time to live. Even though eternal is false, because there are no
416      * expiry or idle times, it is eternal.
417      * <cache name="sampleCacheNotEternalButNoIdleOrExpiry"
418      * maxElementsInMemory="1000"
419      * eternal="false"
420      * overflowToDisk="false"
421      * />
422      */
423     public void testExpirySampleCacheNotEternalButNoIdleOrExpiry() throws Exception {
424         //Set size so the second element overflows to disk.
425         Ehcache cache = manager.getCache("sampleCacheNotEternalButNoIdleOrExpiry");
426         cache.put(new Element("key1", "value1"));
427         cache.put(new Element("key2", "value1"));
428         assertNotNull(cache.get("key1"));
429         assertNotNull(cache.get("key2"));
430 
431         //Test time to idle. Should not idle out because not specified
432         Thread.sleep(2000);
433         assertNotNull(cache.get("key1"));
434         assertNotNull(cache.get("key2"));
435 
436         //Test time to live.
437         Thread.sleep(5020);
438         assertNotNull(cache.get("key1"));
439         assertNotNull(cache.get("key2"));
440     }
441 
442 
443     /***
444      * Test overflow to disk = false
445      */
446     public void testNoOverflowToDisk() throws Exception {
447         //Set size so the second element overflows to disk.
448         Cache cache = new Cache("test", 1, false, true, 5, 2);
449         manager.addCache(cache);
450         cache.put(new Element("key1", "value1"));
451         cache.put(new Element("key2", "value1"));
452         assertNull(cache.get("key1"));
453         assertNotNull(cache.get("key2"));
454     }
455 
456 
457     /***
458      * Performance tests for a range of Memory Store - Disk Store combinations.
459      * <p/>
460      * This demonstrates that a memory only store is approximately an order of magnitude
461      * faster than a disk only store.
462      * <p/>
463      * It also shows that double the performance of a Disk Only store can be obtained
464      * with a maximum memory size of only 1. Accordingly a Cache created without a
465      * maximum memory size of less than 1 will issue a warning.
466      * <p/>
467      * Threading changes were made in v1.41 of DiskStore. The before and after numbers are shown.
468      * <p/>
469      * This test also has a cache with a CacheExceptionHandler registered. The performance effect is not detectable.
470      */
471     public void testProportionMemoryAndDiskPerformance() throws Exception {
472         StopWatch stopWatch = new StopWatch();
473         long time = 0;
474 
475         //Memory only Typical 192ms
476         Cache memoryOnlyCache = new Cache("testMemoryOnly", 5000, false, false, 5, 2);
477         manager.addCache(memoryOnlyCache);
478         time = stopWatch.getElapsedTime();
479         for (int i = 0; i < 5000; i++) {
480             Integer key = new Integer(i);
481             memoryOnlyCache.put(new Element(new Integer(i), "value"));
482             memoryOnlyCache.get(key);
483         }
484         time = stopWatch.getElapsedTime();
485         LOG.info("Time for MemoryStore: " + time);
486         assertTrue("Time to put and get 5000 entries into MemoryStore", time < 300);
487 
488         //Memory only Typical 192ms
489         for (int j = 0; j < 10; j++) {
490             time = stopWatch.getElapsedTime();
491             for (int i = 0; i < 5000; i++) {
492                 Integer key = new Integer(i);
493                 memoryOnlyCache.put(new Element(new Integer(i), "value"));
494                 memoryOnlyCache.get(key);
495             }
496             time = stopWatch.getElapsedTime();
497             LOG.info("Time for MemoryStore: " + time);
498             assertTrue("Time to put and get 5000 entries into MemoryStore", time < 300);
499             Thread.sleep(500);
500         }
501 
502         //Memory only with ExceptionHandlingTypical 192ms
503         manager.replaceCacheWithDecoratedCache(memoryOnlyCache, ExceptionHandlingDynamicCacheProxy.createProxy(memoryOnlyCache));
504         Ehcache exceptionHandlingMemoryOnlyCache = manager.getEhcache("testMemoryOnly");
505         for (int j = 0; j < 10; j++) {
506             time = stopWatch.getElapsedTime();
507             for (int i = 0; i < 5000; i++) {
508                 Integer key = new Integer(i);
509                 exceptionHandlingMemoryOnlyCache.put(new Element(new Integer(i), "value"));
510                 exceptionHandlingMemoryOnlyCache.get(key);
511             }
512             time = stopWatch.getElapsedTime();
513             LOG.info("Time for exception handling MemoryStore: " + time);
514             assertTrue("Time to put and get 5000 entries into exception handling MemoryStore", time < 300);
515             Thread.sleep(500);
516         }
517 
518         //Set size so that all elements overflow to disk.
519         // 1245 ms v1.38 DiskStore
520         // 273 ms v1.42 DiskStore
521         Cache diskOnlyCache = new Cache("testDiskOnly", 0, true, false, 5, 2);
522         manager.addCache(diskOnlyCache);
523         time = stopWatch.getElapsedTime();
524         for (int i = 0; i < 5000; i++) {
525             Integer key = new Integer(i);
526             diskOnlyCache.put(new Element(key, "value"));
527             diskOnlyCache.get(key);
528         }
529         time = stopWatch.getElapsedTime();
530         LOG.info("Time for DiskStore: " + time);
531         assertTrue("Time to put and get 5000 entries into DiskStore was less than 2 sec", time < 2000);
532 
533         // 1 Memory, 999 Disk
534         // 591 ms v1.38 DiskStore
535         // 56 ms v1.42 DiskStore
536         Cache m1d999Cache = new Cache("m1d999Cache", 1, true, false, 5, 2);
537         manager.addCache(m1d999Cache);
538         time = stopWatch.getElapsedTime();
539         for (int i = 0; i < 5000; i++) {
540             Integer key = new Integer(i);
541             m1d999Cache.put(new Element(key, "value"));
542             m1d999Cache.get(key);
543         }
544         time = stopWatch.getElapsedTime();
545         LOG.info("Time for m1d999Cache: " + time);
546         assertTrue("Time to put and get 5000 entries into m1d999Cache", time < 2000);
547 
548         // 500 Memory, 500 Disk
549         // 669 ms v1.38 DiskStore
550         // 47 ms v1.42 DiskStore
551         Cache m500d500Cache = new Cache("m500d500Cache", 500, true, false, 5, 2);
552         manager.addCache(m500d500Cache);
553         time = stopWatch.getElapsedTime();
554         for (int i = 0; i < 5000; i++) {
555             Integer key = new Integer(i);
556             m500d500Cache.put(new Element(key, "value"));
557             m500d500Cache.get(key);
558         }
559         time = stopWatch.getElapsedTime();
560         LOG.info("Time for m500d500Cache: " + time);
561         assertTrue("Time to put and get 5000 entries into m500d500Cache", time < 2000);
562 
563     }
564 
565 
566     /***
567      * Test Caches with persistent stores dispose properly. Tests:
568      * <ol>
569      * <li>No exceptions are thrown on dispose
570      * <li>You cannot re add a cache after it has been disposed and removed
571      * <li>You can create a new cache with the same name
572      * </ol>
573      */
574     public void testCreateAddDisposeAdd() throws CacheException {
575         Cache cache = new Cache("test2", 1, true, true, 0, 0, true, 120);
576         manager.addCache(cache);
577         cache.put(new Element("key1", "value1"));
578         cache.put(new Element("key2", "value1"));
579         int sizeFromGetSize = cache.getSize();
580         int sizeFromKeys = cache.getKeys().size();
581         assertEquals(sizeFromGetSize, sizeFromKeys);
582         assertEquals(2, cache.getSize());
583         //package protected method, only available to tests. Called by teardown
584         cache.dispose();
585         manager.removeCache("test2");
586 
587 
588         try {
589             manager.addCache(cache);
590             fail();
591         } catch (CacheException e) {
592             //expected
593         }
594 
595         //Add a new cache with the same name as the disposed one.
596         Cache cache2 = new Cache("test2", 1, true, true, 0, 0, true, 120);
597         manager.addCache(cache2);
598         Ehcache cacheFromManager = manager.getCache("test2");
599         assertTrue(cacheFromManager.getStatus().equals(Status.STATUS_ALIVE));
600 
601     }
602 
603     /***
604      * Test expiry based on time to live
605      */
606     public void testExpiryBasedOnTimeToLive() throws Exception {
607         //Set size so the second element overflows to disk.
608         Cache cache = new Cache("test", 1, true, false, 3, 0);
609         manager.addCache(cache);
610         cache.put(new Element("key1", "value1"));
611         cache.put(new Element("key2", "value1"));
612 
613         //Test time to live
614         assertNotNull(cache.get("key1"));
615         assertNotNull(cache.get("key2"));
616         Thread.sleep(1020);
617         //Test time to live
618         assertNotNull(cache.get("key1"));
619         assertNotNull(cache.get("key2"));
620         Thread.sleep(1020);
621         //Test time to live
622         assertNotNull(cache.get("key1"));
623         assertNotNull(cache.get("key2"));
624         Thread.sleep(1020);
625         assertNull(cache.get("key1"));
626         assertNull(cache.get("key2"));
627     }
628 
629 
630     /***
631      * Tests that a cache created from defaults will expire as per
632      * the default expiry policy.
633      *
634      * @throws Exception
635      */
636     public void testExpiryBasedOnTimeToLiveForDefault() throws Exception {
637         String name = "ThisIsACacheWhichIsNotConfiguredAndWillThereforeUseDefaults";
638         Ehcache cache = null;
639         CacheManager manager = CacheManager.getInstance();
640         cache = manager.getCache(name);
641         if (cache == null) {
642             LOG.warning("Could not find configuration for " + name
643                     + ". Configuring using the defaultCache settings.");
644             manager.addCache(name);
645             cache = manager.getCache(name);
646         }
647 
648         cache.put(new Element("key1", "value1"));
649         cache.put(new Element("key2", "value1"));
650 
651         //Test time to live
652         assertNotNull(cache.get("key1"));
653         assertNotNull(cache.get("key2"));
654         Thread.sleep(10020);
655         assertNull(cache.get("key1"));
656         assertNull(cache.get("key2"));
657 
658 
659     }
660 
661 
662     /***
663      * Test expiry based on time to live.
664      * <p/>
665      * Elements are put quietly back into the cache after being cloned.
666      * The elements should expire as if the putQuiet had not happened.
667      */
668     public void testExpiryBasedOnTimeToLiveAfterPutQuiet() throws Exception {
669         //Set size so the second element overflows to disk.
670         Cache cache = new Cache("test", 1, true, false, 5, 2);
671         manager.addCache(cache);
672         cache.put(new Element("key1", "value1"));
673         cache.put(new Element("key2", "value1"));
674 
675         Element element1 = cache.get("key1");
676         Element element2 = cache.get("key2");
677         assertNotNull(element1);
678         assertNotNull(element2);
679 
680         //Test time to live
681         Thread.sleep(2020);
682         //Should not affect age
683         cache.putQuiet((Element) element2.clone());
684         cache.putQuiet((Element) element2.clone());
685         Thread.sleep(3020);
686         assertNull(cache.get("key1"));
687         assertNull(cache.get("key2"));
688     }
689 
690     /***
691      * Test expiry based on time to live
692      */
693     public void testNoIdleOrExpiryBasedOnTimeToLiveForEternal() throws Exception {
694         //Set size so the second element overflows to disk.
695         Cache cache = new Cache("test", 1, true, true, 5, 2);
696         manager.addCache(cache);
697         cache.put(new Element("key1", "value1"));
698         cache.put(new Element("key2", "value1"));
699 
700         //Test time to live
701         assertNotNull(cache.get("key1"));
702         assertNotNull(cache.get("key2"));
703 
704         //Check that we did not idle out
705         Thread.sleep(2020);
706         assertNotNull(cache.get("key1"));
707         assertNotNull(cache.get("key2"));
708 
709         //Check that we did not expire out
710         Thread.sleep(3020);
711         assertNotNull(cache.get("key1"));
712         assertNotNull(cache.get("key2"));
713     }
714 
715     /***
716      * Test expiry based on time to idle.
717      */
718     public void testExpiryBasedOnTimeToIdle() throws Exception {
719         //Set size so the second element overflows to disk.
720         Cache cache = new Cache("test", 1, true, false, 6, 2);
721         manager.addCache(cache);
722         cache.put(new Element("key1", "value1"));
723         cache.put(new Element("key2", "value1"));
724 
725         //Test time to idle
726         Element element1 = cache.get("key1");
727         Element element2 = cache.get("key2");
728         assertNotNull(element1);
729         assertNotNull(element2);
730         Thread.sleep(2050);
731         assertNull(cache.get("key1"));
732         assertNull(cache.get("key2"));
733 
734         //Test effect of get
735         cache.put(new Element("key1", "value1"));
736         cache.put(new Element("key2", "value1"));
737         Thread.sleep(1050);
738         assertNotNull(cache.get("key1"));
739         assertNotNull(cache.get("key2"));
740 
741         Thread.sleep(2050);
742         assertNull(cache.get("key1"));
743         assertNull(cache.get("key2"));
744     }
745 
746 
747     /***
748      * Test expiry based on time to idle.
749      */
750     public void testExpiryBasedOnTimeToIdleAfterPutQuiet() throws Exception {
751         //Set size so the second element overflows to disk.
752         Cache cache = new Cache("test", 1, true, false, 5, 3);
753         manager.addCache(cache);
754         cache.put(new Element("key1", "value1"));
755         cache.put(new Element("key2", "value1"));
756 
757         //Test time to idle
758         Element element1 = cache.get("key1");
759         Element element2 = cache.get("key2");
760         assertNotNull(element1);
761         assertNotNull(element2);
762 
763         //Now, getQuiet and check still times out 2 seconds after last get
764         Thread.sleep(1050);
765         element1 = cache.getQuiet("key1");
766         element2 = cache.getQuiet("key2");
767         Thread.sleep(2050);
768         assertNull(cache.getQuiet("key1"));
769         assertNull(cache.getQuiet("key2"));
770 
771         //Now put back in with putQuiet. Should be immediately expired
772         cache.putQuiet((Element) element1.clone());
773         cache.putQuiet((Element) element2.clone());
774         assertNull(cache.get("key1"));
775         element2 = cache.get("key2");
776         assertNull(element2);
777     }
778 
779     /***
780      * Test element statistics, including get and getQuiet
781      * eternal="false"
782      * timeToIdleSeconds="5"
783      * timeToLiveSeconds="10"
784      * overflowToDisk="true"
785      */
786     public void testElementStatistics() throws Exception {
787         //Set size so the second element overflows to disk.
788         Cache cache = new Cache("test", 1, true, false, 5, 2);
789         manager.addCache(cache);
790         cache.put(new Element("key1", "value1"));
791         cache.put(new Element("key2", "value1"));
792 
793         Element element1 = cache.get("key1");
794         assertEquals("Should be one", 1, element1.getHitCount());
795         element1 = cache.getQuiet("key1");
796         assertEquals("Should be one", 1, element1.getHitCount());
797         element1 = cache.get("key1");
798         assertEquals("Should be two", 2, element1.getHitCount());
799     }
800 
801     /***
802      * Test cache statistics, including get and getQuiet
803      */
804     public void testCacheStatistics() throws Exception {
805         //Set size so the second element overflows to disk.
806         Cache cache = new Cache("test", 1, true, false, 5, 2);
807         manager.addCache(cache);
808         cache.put(new Element("key1", "value1"));
809         cache.put(new Element("key2", "value1"));
810 
811         Element element1 = cache.get("key1");
812         assertEquals("Should be one", 1, element1.getHitCount());
813         assertEquals("Should be one", 1, cache.getHitCount());
814         element1 = cache.getQuiet("key1");
815         assertEquals("Should be one", 1, element1.getHitCount());
816         assertEquals("Should be one", 1, cache.getHitCount());
817         element1 = cache.get("key1");
818         assertEquals("Should be two", 2, element1.getHitCount());
819         assertEquals("Should be two", 2, cache.getHitCount());
820 
821 
822         assertEquals("Should be 0", 0, cache.getMissCountNotFound());
823         cache.get("doesnotexist");
824         assertEquals("Should be 1", 1, cache.getMissCountNotFound());
825 
826 
827     }
828 
829     /***
830      * Checks that getQuiet works how we expect it to
831      *
832      * @throws Exception
833      */
834     public void testGetQuietAndPutQuiet() throws Exception {
835         //Set size so the second element overflows to disk.
836         Cache cache = new Cache("test", 1, true, false, 5, 2);
837         manager.addCache(cache);
838         cache.put(new Element("key1", "value1"));
839         cache.put(new Element("key2", "value1"));
840 
841         Element element1 = cache.get("key1");
842         long lastAccessedElement1 = element1.getLastAccessTime();
843         long hitCountElement1 = element1.getHitCount();
844         assertEquals("Should be two", 1, element1.getHitCount());
845         assertEquals(1L, cache.getStatistics().getCacheHits());
846 
847         element1 = cache.getQuiet("key1");
848         element1 = cache.getQuiet("key1");
849         assertEquals(1L, cache.getStatistics().getCacheHits());
850         Element clonedElement1 = (Element) element1.clone();
851         cache.putQuiet(clonedElement1);
852         element1 = cache.getQuiet("key1");
853         assertEquals("last access time should be unchanged",
854                 lastAccessedElement1, element1.getLastAccessTime());
855         assertEquals("hit count should be unchanged",
856                 hitCountElement1, element1.getHitCount());
857         element1 = cache.get("key1");
858         assertEquals("Should be two", 2, element1.getHitCount());
859     }
860 
861     /***
862      * Test size with put and remove.
863      * <p/>
864      * It checks that size makes sense, and also that getKeys.size() matches getSize()
865      */
866     public void testSizeWithPutAndRemove() throws Exception {
867         //Set size so the second element overflows to disk.
868         Cache cache = new Cache("test2", 1, true, true, 0, 0);
869         manager.addCache(cache);
870         cache.put(new Element("key1", "value1"));
871         cache.put(new Element("key2", "value1"));
872         int sizeFromGetSize = cache.getSize();
873         int sizeFromKeys = cache.getKeys().size();
874         assertEquals(sizeFromGetSize, sizeFromKeys);
875         assertEquals(2, cache.getSize());
876         cache.put(new Element("key1", "value1"));
877         cache.put(new Element("key1", "value1"));
878 
879         //key1 should be in the Disk Store
880         assertEquals(cache.getSize(), cache.getKeys().size());
881         assertEquals(2, cache.getSize());
882         //there were two of these, so size will now be one
883         cache.remove("key1");
884         assertEquals(cache.getSize(), cache.getKeys().size());
885         assertEquals(1, cache.getSize());
886         cache.remove("key2");
887         assertEquals(cache.getSize(), cache.getKeys().size());
888         assertEquals(0, cache.getSize());
889 
890         //try null values
891         cache.put(new Element("nullValue1", null));
892         cache.put(new Element("nullValue2", null));
893         //Cannot overflow therefore just one
894         assertEquals(1, cache.getSize());
895         Element nullValueElement = cache.get("nullValue2");
896         assertNull(nullValueElement.getValue());
897         assertNull(nullValueElement.getObjectValue());
898 
899     }
900 
901     /***
902      * Test getKeys after expiry
903      * <p/>
904      * Makes sure that if an element is expired, its key should also be expired
905      */
906     public void testGetKeysAfterExpiry() throws Exception {
907         //Set size so the second element overflows to disk.
908         Cache cache = new Cache("test2", 1, true, false, 1, 0);
909         manager.addCache(cache);
910         String key1 = "key1";
911         cache.put(new Element(key1, "value1"));
912         cache.put(new Element("key2", "value1"));
913         //getSize uses getKeys().size(), so these should be the same
914         assertEquals(cache.getSize(), cache.getKeys().size());
915         //getKeys does not do an expiry check, so the expired elements are counted
916         assertEquals(2, cache.getSize());
917         String keyFromDisk = (String) cache.get(key1).getObjectKey();
918         assertTrue(key1 == keyFromDisk);
919         Thread.sleep(1050);
920         assertEquals(2, cache.getKeys().size());
921         //getKeysWithExpiryCheck does check and gives the correct answer of 0
922         assertEquals(0, cache.getKeysWithExpiryCheck().size());
923     }
924 
925 
926     /***
927      * Answers the question of whether key references are preserved as elements are written to disk.
928      * This is not a mandatory part of the API. If this test breaks in future it should be removed.
929      */
930     public void testKeysEqualsEquals() throws Exception {
931         //Set size so the second element overflows to disk.
932         Cache cache = new Cache("test2", 0, true, false, 1, 0);
933         manager.addCache(cache);
934         String key1 = "key1";
935         cache.put(new Element(key1, "value1"));
936         cache.put(new Element("key2", "value1"));
937         String keyFromDisk = (String) cache.get(key1).getObjectKey();
938         assertTrue(key1 == keyFromDisk);
939     }
940 
941     /***
942      * Test size after multiple calls, with put and remove
943      */
944     public void testSizeMultipleCallsWithPutAndRemove() throws Exception {
945         //Set size so the second element overflows to disk.
946         Cache cache = new Cache("test3", 1, true, true, 0, 0);
947         manager.addCache(cache);
948         cache.put(new Element("key1", "value1"));
949         cache.put(new Element("key2", "value1"));
950 
951         //key1 should be in the Disk Store
952         assertEquals(2, cache.getSize());
953         assertEquals(2, cache.getSize());
954         assertEquals(2, cache.getSize());
955         assertEquals(2, cache.getSize());
956         assertEquals(2, cache.getSize());
957         cache.remove("key1");
958         assertEquals(1, cache.getSize());
959         assertEquals(1, cache.getSize());
960         assertEquals(1, cache.getSize());
961         assertEquals(1, cache.getSize());
962         assertEquals(1, cache.getSize());
963         cache.remove("key2");
964         assertEquals(0, cache.getSize());
965         assertEquals(0, cache.getSize());
966         assertEquals(0, cache.getSize());
967         assertEquals(0, cache.getSize());
968         assertEquals(0, cache.getSize());
969     }
970 
971     /***
972      * Checks the expense of checking for duplicates
973      * Typical Results Duplicate Check: 8ms versus 3ms for No Duplicate Check
974      * <p/>
975      * 66ms for 1000, 6ms for no duplicate/expiry
976      * 187565 for 100000, where 500 is the in-memory size. 964ms without checking expiry. 134ms for getKeysNoDuplicateCheckTime
977      * 18795 for 100000, where 50000 is in-memory size. 873ms without checking expiry. 158ms for getKeysNoDuplicateCheckTime
978      */
979     public void testGetKeysPerformance() throws Exception {
980         //Set size so the second element overflows to disk.
981         Ehcache cache = createTestCache();
982 
983         for (int i = 0; i < 2000; i++) {
984             cache.put(new Element("key" + i, "value"));
985         }
986         //let the notifiers cool down
987         Thread.sleep(1000);
988         StopWatch stopWatch = new StopWatch();
989         List keys = cache.getKeys();
990         assertTrue("Should be 2000 keys. ", keys.size() == 2000);
991         long getKeysTime = stopWatch.getElapsedTime();
992         cache.getKeysNoDuplicateCheck();
993         long getKeysNoDuplicateCheckTime = stopWatch.getElapsedTime();
994         LOG.info("Time to get 1000 keys: With Duplicate Check: " + getKeysTime
995                 + " Without Duplicate Check: " + getKeysNoDuplicateCheckTime);
996         assertTrue("Getting keys took more than 150ms", getKeysTime < 100);
997     }
998 
999     /***
1000      * Checks the expense of checking in-memory size
1001      * 3467890 bytes in 1601ms for JDK1.4.2
1002      */
1003     public void testCalculateInMemorySizePerformanceAndReasonableness() throws Exception {
1004         //Set size so the second element overflows to disk.
1005         Ehcache cache = createTestCache();
1006 
1007         //Set up object graphs
1008         for (int i = 0; i < 1000; i++) {
1009             HashMap map = new HashMap(100);
1010             for (int j = 0; j < 100; j++) {
1011                 map.put("key" + j, new String[]{"adfdafs", "asdfdsafa", "sdfasdf"});
1012             }
1013             cache.put(new Element("key" + i, map));
1014         }
1015 
1016         StopWatch stopWatch = new StopWatch();
1017         long size = cache.calculateInMemorySize();
1018         assertTrue("Size is " + size + ". Check it for reasonableness.", size > 100000 && size < 5000000);
1019         long elapsed = stopWatch.getElapsedTime();
1020         LOG.info("In-memory size in bytes: " + size
1021                 + " time to calculate in ms: " + elapsed);
1022         assertTrue("Calculate memory size takes less than 3.5 seconds", elapsed < 3500);
1023     }
1024 
1025 
1026     /***
1027      * Expire elements and verify size is correct.
1028      */
1029     public void testGetSizeAfterExpiry() throws Exception {
1030         //Set size so the second element overflows to disk.
1031         Cache cache = new Cache("test", 1, true, false, 1, 0);
1032         manager.addCache(cache);
1033         cache.put(new Element("key1", "value1"));
1034         cache.put(new Element("key2", "value1"));
1035 
1036         //Let the idle expire
1037         Thread.sleep(1020);
1038         assertEquals(null, cache.get("key1"));
1039         assertEquals(null, cache.get("key2"));
1040 
1041         assertEquals(0, cache.getSize());
1042     }
1043 
1044     /***
1045      * Test create and access times
1046      */
1047     public void testAccessTimes() throws Exception {
1048         //Set size so the second element overflows to disk.
1049         Cache cache = new Cache("test", 5, true, false, 5, 2);
1050         assertEquals(Status.STATUS_UNINITIALISED, cache.getStatus());
1051         manager.addCache(cache);
1052         Element newElement = new Element("key1", "value1");
1053         long creationTime = newElement.getCreationTime();
1054         assertTrue(newElement.getCreationTime() > (System.currentTimeMillis() - 500));
1055         assertTrue(newElement.getHitCount() == 0);
1056         assertTrue(newElement.getLastAccessTime() == 0);
1057 
1058         cache.put(newElement);
1059 
1060         Element element = cache.get("key1");
1061         assertNotNull(element);
1062         assertEquals(creationTime, element.getCreationTime());
1063         assertTrue(element.getLastAccessTime() != 0);
1064         assertTrue(element.getHitCount() == 1);
1065 
1066         //Check that access statistics were reset but not creation time
1067         cache.put(element);
1068         element = cache.get("key1");
1069         assertEquals(creationTime, element.getCreationTime());
1070         assertTrue(element.getLastAccessTime() != 0);
1071         assertTrue(element.getHitCount() == 1);
1072     }
1073 
1074     /***
1075      * Tests initialisation failures
1076      */
1077     public void testInitialiseFailures() {
1078         try {
1079             Cache cache = new Cache("testInitialiseFailures2", 1, false, false, 5, 1);
1080             cache.initialise();
1081 
1082             cache.initialise();
1083             fail("Should have thrown IllegalArgumentException");
1084         } catch (IllegalStateException e) {
1085             //noop
1086         }
1087     }
1088 
1089     /***
1090      * Tests putting nulls throws correct exception
1091      *
1092      * @throws Exception
1093      */
1094     public void testPutFailures() throws Exception {
1095         Cache cache = new Cache("testPutFailures", 1, false, false, 5, 1);
1096         manager.addCache(cache);
1097 
1098         try {
1099             cache.put(null);
1100             fail("Should have thrown IllegalArgumentException");
1101         } catch (IllegalArgumentException e) {
1102             //noop
1103         }
1104 
1105         try {
1106             cache.putQuiet(null);
1107             fail("Should have thrown IllegalArgumentException");
1108         } catch (IllegalArgumentException e) {
1109             //noop
1110         }
1111 
1112         //Null Elements like this are OK
1113         cache.putQuiet(new Element(null, null));
1114     }
1115 
1116     /***
1117      * Tests cache, memory store and disk store sizes from config
1118      */
1119     public void testSizes() throws Exception {
1120         Ehcache cache = getSampleCache1();
1121 
1122         assertEquals(0, cache.getMemoryStoreSize());
1123 
1124         for (int i = 0; i < 10010; i++) {
1125             cache.put(new Element("key" + i, "value1"));
1126         }
1127         assertEquals(10010, cache.getSize());
1128         assertEquals(10000, cache.getMemoryStoreSize());
1129         assertEquals(10, cache.getDiskStoreSize());
1130 
1131         //NonSerializable
1132         cache.put(new Element(new Object(), Object.class));
1133 
1134         assertEquals(10011, cache.getSize());
1135         assertEquals(10000, cache.getMemoryStoreSize());
1136         assertEquals(11, cache.getDiskStoreSize());
1137 
1138 
1139         cache.remove("key4");
1140         cache.remove("key3");
1141 
1142         assertEquals(10009, cache.getSize());
1143         assertEquals(10000, cache.getMemoryStoreSize());
1144         assertEquals(9, cache.getDiskStoreSize());
1145 
1146 
1147         cache.removeAll();
1148         assertEquals(0, cache.getSize());
1149         assertEquals(0, cache.getMemoryStoreSize());
1150         assertEquals(0, cache.getDiskStoreSize());
1151 
1152     }
1153 
1154     /***
1155      * Tests flushing the cache
1156      *
1157      * @throws Exception
1158      */
1159     public void testFlushWhenOverflowToDisk() throws Exception {
1160         Cache cache = new Cache("testFlushWhenOverflowToDisk", 50, true, false, 100, 200, true, 120);
1161         manager.addCache(cache);
1162 //        cache.removeAll();
1163 
1164         assertEquals(0, cache.getMemoryStoreSize());
1165         assertEquals(0, cache.getDiskStoreSize());
1166 
1167 
1168         for (int i = 0; i < 100; i++) {
1169             cache.put(new Element("" + i, new Date()));
1170         }
1171         //Not spoolable, should get ignored
1172         cache.put(new Element("key", new Object()));
1173         cache.put(new Element(new Object(), new Object()));
1174         cache.put(new Element(new Object(), "value"));
1175 
1176         //these "null" Elements are keyed the same way and only count as one
1177         cache.put(new Element(null, null));
1178         cache.put(new Element(null, null));
1179 
1180         cache.put(new Element("nullValue", null));
1181 
1182         assertEquals(50, cache.getMemoryStoreSize());
1183         assertEquals(55, cache.getDiskStoreSize());
1184 
1185         cache.flush();
1186         assertEquals(0, cache.getMemoryStoreSize());
1187         //Non Serializable Elements get discarded
1188         assertEquals(100, cache.getDiskStoreSize());
1189 
1190         cache.removeAll();
1191 
1192     }
1193 
1194 
1195     /***
1196      * When flushing large MemoryStores, OutOfMemory issues can happen if we are
1197      * not careful to move each to Element to the DiskStore, rather than copy them all
1198      * and then delete them from the MemoryStore.
1199      * <p/>
1200      * This test manipulates a MemoryStore right on the edge of what can fit into the 64MB standard VM size.
1201      * An inefficient spool will cause an OutOfMemoryException.
1202      *
1203      * @throws Exception
1204      */
1205     public void testMemoryEfficiencyOfFlushWhenOverflowToDisk() throws Exception {
1206         Cache cache = new Cache("testGetMemoryStoreSize", 40000, true, false, 100, 200, false, 120);
1207         manager.addCache(cache);
1208         StopWatch stopWatch = new StopWatch();
1209 
1210         assertEquals(0, cache.getMemoryStoreSize());
1211 
1212         for (int i = 0; i < 80000; i++) {
1213             cache.put(new Element("" + i, new byte[480]));
1214         }
1215         LOG.info("Put time: " + stopWatch.getElapsedTime());
1216 
1217         assertEquals(40000, cache.getMemoryStoreSize());
1218         assertEquals(40000, cache.getDiskStoreSize());
1219 
1220         long beforeMemory = measureMemoryUse();
1221         stopWatch.getElapsedTime();
1222         //todo
1223         //cache.flush();
1224         LOG.info("Flush time: " + stopWatch.getElapsedTime());
1225 
1226         //It takes a while to write all the Elements to disk
1227         Thread.sleep(1000);
1228 
1229         long afterMemory = measureMemoryUse();
1230         long memoryIncrease = afterMemory - beforeMemory;
1231         assertTrue(memoryIncrease < 40000000);
1232 
1233         assertEquals(40000, cache.getMemoryStoreSize());
1234         assertEquals(40000, cache.getDiskStoreSize());
1235 
1236     }
1237 
1238     /***
1239      * Shows the effect of jamming large amounts of puts into a cache that overflows to disk.
1240      * The DiskStore should cause puts to back off and avoid an out of memory error.
1241      */
1242     public void testBehaviourOnDiskStoreBackUp() throws Exception {
1243         Cache cache = new Cache("testGetMemoryStoreSize", 10, true, false, 100, 200, false, 0);
1244         manager.addCache(cache);
1245 
1246         assertEquals(0, cache.getMemoryStoreSize());
1247 
1248         Element a = null;
1249         int i = 0;
1250         try {
1251             for (; i < 200000; i++) {
1252                 String key = i + "";
1253                 String value = key;
1254                 a = new Element(key, value + "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD");
1255                 cache.put(a);
1256             }
1257         } catch (OutOfMemoryError e) {
1258             LOG.info("OutOfMemoryError: " + e.getMessage() + " " + i);
1259             fail();
1260         }
1261     }
1262 
1263 
1264     /***
1265      * Tests using elements with null values. They should work as normal.
1266      *
1267      * @throws Exception
1268      */
1269     public void testElementWithNullValue() throws Exception {
1270         Cache cache = new Cache("testElementWithNullValue", 10, false, false, 100, 200);
1271         manager.addCache(cache);
1272 
1273         Object key1 = new Object();
1274         Element element = new Element(key1, null);
1275         cache.put(element);
1276         assertNotNull(cache.get(key1));
1277         assertNotNull(cache.getQuiet(key1));
1278         assertSame(element, cache.get(key1));
1279         assertSame(element, cache.getQuiet(key1));
1280         assertNull(cache.get(key1).getObjectValue());
1281         assertNull(cache.getQuiet(key1).getObjectValue());
1282 
1283         assertEquals(false, cache.isExpired(element));
1284     }
1285 
1286 
1287     /***
1288      * Tests put works correctly for Elements with overriden TTL
1289      *
1290      * @throws Exception
1291      */
1292     public void testPutWithOverriddenTTLAndTTI() throws Exception {
1293         Cache cache = new Cache("testElementWithNullValue", 10, false, false, 1, 1);
1294         manager.addCache(cache);
1295 
1296         Object key = new Object();
1297         Element element = new Element(key, "value");
1298         element.setTimeToLive(2);
1299         cache.put(element);
1300         Thread.sleep(1050);
1301         assertNotNull(cache.get(key));
1302         assertSame(element, cache.get(key));
1303 
1304 
1305         Element element2 = new Element(key, "value");
1306         cache.put(element2);
1307         Thread.sleep(1050);
1308         assertNull(cache.get(key));
1309 
1310         Element element3 = new Element(key, "value");
1311         element3.setTimeToLive(2);
1312         cache.put(element3);
1313         Thread.sleep(1500);
1314         assertSame(element3, cache.get(key));
1315 
1316     }
1317 
1318 
1319     /***
1320      * Tests putQuiet works correctly for Elements with overriden TTL
1321      *
1322      * @throws Exception
1323      */
1324     public void testPutQuietWithOverriddenTTLAndTTI() throws Exception {
1325         Cache cache = new Cache("testElementWithNullValue", 10, false, false, 1, 1);
1326         manager.addCache(cache);
1327 
1328         Object key = new Object();
1329         Element element = new Element(key, "value");
1330         element.setTimeToLive(2);
1331         cache.putQuiet(element);
1332         Thread.sleep(1050);
1333         assertNotNull(cache.get(key));
1334         assertSame(element, cache.get(key));
1335 
1336 
1337         Element element2 = new Element(key, "value");
1338         cache.putQuiet(element2);
1339         Thread.sleep(1050);
1340         assertNull(cache.get(key));
1341 
1342         Element element3 = new Element(key, "value");
1343         element3.setTimeToLive(2);
1344         cache.putQuiet(element3);
1345         Thread.sleep(1500);
1346         assertSame(element3, cache.get(key));
1347 
1348     }
1349 
1350 
1351     /***
1352      * Tests using elements with null values. They should work as normal.
1353      *
1354      * @throws Exception
1355      */
1356     public void testNonSerializableElement() throws Exception {
1357         Cache cache = new Cache("testElementWithNonSerializableValue", 1, true, false, 100, 200);
1358         manager.addCache(cache);
1359 
1360         Element element1 = new Element("key1", new Object());
1361         Element element2 = new Element("key2", new Object());
1362         cache.put(element1);
1363         cache.put(element2);
1364 
1365         //Removed because could not overflow
1366         assertNull(cache.get("key1"));
1367 
1368         //Second one should be in the MemoryStore and retrievable
1369         assertNotNull(cache.get("key2"));
1370     }
1371 
1372 
1373     /***
1374      * Tests what happens when an Element throws an Error on serialization. This mimics
1375      * what a nasty error like OutOfMemoryError could do.
1376      * <p/>
1377      * Before a change to the SpoolAndExpiryThread to handle this situation this test failed and generated the following log message.
1378      * Jun 28, 2006 7:17:16 PM net.sf.ehcache.store.DiskStore put
1379      * SEVERE: testThreadKillerCache: Elements cannot be written to disk store because the spool thread has died.
1380      *
1381      * @throws Exception
1382      */
1383     public void testSpoolThreadHandlesThreadKiller() throws Exception {
1384         Cache cache = new Cache("testThreadKiller", 1, true, false, 100, 200);
1385         manager.addCache(cache);
1386 
1387         Element elementThreadKiller = new Element("key", new ThreadKiller());
1388         cache.put(elementThreadKiller);
1389         Element element1 = new Element("key1", "one");
1390         Element element2 = new Element("key2", "two");
1391         cache.put(element1);
1392         cache.put(element2);
1393 
1394         Thread.sleep(2000);
1395 
1396         assertNotNull(cache.get("key1"));
1397         assertNotNull(cache.get("key2"));
1398     }
1399 
1400     /***
1401      * Tests disk store and memory store size
1402      *
1403      * @throws Exception
1404      */
1405     public void testGetDiskStoreSize() throws Exception {
1406         Cache cache = new Cache("testGetDiskStoreSize", 1, true, false, 100, 200);
1407         manager.addCache(cache);
1408         assertEquals(0, cache.getDiskStoreSize());
1409 
1410         cache.put(new Element("key1", "value1"));
1411         assertEquals(0, cache.getDiskStoreSize());
1412         assertEquals(1, cache.getSize());
1413 
1414         cache.put(new Element("key2", "value2"));
1415         assertEquals(2, cache.getSize());
1416         assertEquals(1, cache.getDiskStoreSize());
1417         assertEquals(1, cache.getMemoryStoreSize());
1418 
1419         cache.put(new Element("key3", "value3"));
1420         cache.put(new Element("key4", "value4"));
1421         assertEquals(4, cache.getSize());
1422         assertEquals(3, cache.getDiskStoreSize());
1423         assertEquals(1, cache.getMemoryStoreSize());
1424 
1425         // remove last element inserted (is in memory store)
1426         assertNotNull(cache.getMemoryStore().get("key4"));
1427         cache.remove("key4");
1428         assertEquals(3, cache.getSize());
1429         assertEquals(3, cache.getDiskStoreSize());
1430         assertEquals(0, cache.getMemoryStoreSize());
1431 
1432         // remove key1 element
1433         assertNotNull(cache.getDiskStore().get("key1"));
1434         cache.remove("key1");
1435         assertEquals(2, cache.getSize());
1436         assertEquals(2, cache.getDiskStoreSize());
1437         assertEquals(0, cache.getMemoryStoreSize());
1438 
1439         // add another
1440         cache.put(new Element("key5", "value5"));
1441         assertEquals(3, cache.getSize());
1442         assertEquals(2, cache.getDiskStoreSize());
1443         assertEquals(1, cache.getMemoryStoreSize());
1444 
1445         // remove all
1446         cache.removeAll();
1447         assertEquals(0, cache.getSize());
1448         assertEquals(0, cache.getDiskStoreSize());
1449         assertEquals(0, cache.getMemoryStoreSize());
1450 
1451         //Check behaviour of NonSerializable objects
1452         cache.put(new Element(new Object(), new Object()));
1453         cache.put(new Element(new Object(), new Object()));
1454         cache.put(new Element(new Object(), new Object()));
1455         assertEquals(1, cache.getSize());
1456         assertEquals(0, cache.getDiskStoreSize());
1457         assertEquals(1, cache.getMemoryStoreSize());
1458 
1459     }
1460 
1461     /***
1462      * Tests that attempting to clone a cache fails with the right exception.
1463      *
1464      * @throws Exception
1465      */
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             //noop
1474         }
1475     }
1476 
1477 
1478     /***
1479      * Tests that the toString() method works.
1480      */
1481     public void testToString() {
1482         Ehcache cache = new Cache("testGetMemoryStore", 10, false, false, 100, 200);
1483         assertTrue(cache.toString().indexOf("testGetMemoryStore") > -1);
1484         assertEquals(410, cache.toString().length());
1485     }
1486 
1487 
1488     /***
1489      * When does equals mean the same thing as == ?
1490      *
1491      * @throws CacheException
1492      * @throws InterruptedException
1493      */
1494     public void testEquals() throws CacheException, InterruptedException {
1495         Cache cache = new Cache("cache", 1, true, false, 100, 200, false, 1);
1496         manager.addCache(cache);
1497 
1498         Element element1 = new Element("1", new Date());
1499         Element element2 = new Element("2", new Date());
1500         cache.put(element1);
1501         cache.put(element2);
1502 
1503