View Javadoc

1   package net.sf.ehcache;
2   
3   import static org.junit.Assert.assertEquals;
4   import static org.junit.Assert.assertFalse;
5   import static org.junit.Assert.assertNotNull;
6   import static org.junit.Assert.assertNull;
7   import static org.junit.Assert.assertTrue;
8   
9   import java.util.Date;
10  
11  import net.sf.ehcache.store.LegacyStoreWrapper;
12  
13  import org.junit.AfterClass;
14  import org.junit.BeforeClass;
15  import org.junit.Test;
16  import org.slf4j.Logger;
17  import org.slf4j.LoggerFactory;
18  
19  /***
20   * Does the cache tests using the classic LRUMemoryStore implementation.
21   *
22   * @author Greg Luck
23   */
24  public class CacheClassicLruMemoryStoreTest extends CacheTest {
25  
26      @BeforeClass
27      public static void enableHeapDump() {
28          setHeapDumpOnOutOfMemoryError(true);
29      }
30  
31      @AfterClass
32      public static void disableHeapDump() {
33          setHeapDumpOnOutOfMemoryError(false);
34      }
35  
36      private static final Logger LOG = LoggerFactory.getLogger(CacheClassicLruMemoryStoreTest.class.getName());
37  
38      @BeforeClass
39      public static void beforeClass() throws Exception {
40          System.setProperty(Cache.NET_SF_EHCACHE_USE_CLASSIC_LRU, "true");
41      }
42  
43  
44      @AfterClass
45      public static void afterClass() throws Exception {
46          System.setProperty(Cache.NET_SF_EHCACHE_USE_CLASSIC_LRU, "false");
47      }
48  
49      /***
50       * Tests flushing the cache, with the default, which is to clear
51       * <p/>
52       * Has different numbers because LRU works slightly differently
53       *
54       * @throws Exception
55       */
56      @Override
57      @Test
58      public void testFlushWhenOverflowToDisk() throws Exception {
59          if (manager.getCache("testFlushWhenOverflowToDisk") == null) {
60              manager.addCache(new Cache("testFlushWhenOverflowToDisk", 50, true, false, 100, 200, true, 120));
61          }
62          Cache cache = manager.getCache("testFlushWhenOverflowToDisk");
63          cache.removeAll();
64  
65          assertEquals(0, cache.getMemoryStoreSize());
66          assertEquals(0, cache.getDiskStoreSize());
67  
68  
69          for (int i = 0; i < 100; i++) {
70              cache.put(new Element("" + i, new Date()));
71              //hit
72              cache.get("" + i);
73          }
74          assertEquals(50, cache.getMemoryStoreSize());
75          assertEquals(50, cache.getDiskStoreSize());
76  
77  
78          cache.put(new Element("key", new Object()));
79          cache.put(new Element("key2", new Object()));
80          Object key = new Object();
81          cache.put(new Element(key, "value"));
82  
83          //get it and make sure it is mru
84          Thread.sleep(15);
85          cache.get(key);
86  
87          assertEquals(103, cache.getSize());
88          assertEquals(50, cache.getMemoryStoreSize());
89          assertEquals(53, cache.getDiskStoreSize());
90  
91  
92          //these "null" Elements are ignored and do not get put in
93          cache.put(new Element(null, null));
94          cache.put(new Element(null, null));
95  
96          assertEquals(103, cache.getSize());
97          assertEquals(50, cache.getMemoryStoreSize());
98          assertEquals(53, cache.getDiskStoreSize());
99  
100         //this one does
101         cache.put(new Element("nullValue", null));
102 
103         LOG.info("Size: " + cache.getDiskStoreSize());
104 
105         assertEquals(50, cache.getMemoryStoreSize());
106         assertEquals(54, cache.getDiskStoreSize());
107 
108         cache.flush();
109         assertEquals(0, cache.getMemoryStoreSize());
110         //Non Serializable Elements get discarded
111         assertEquals(101, cache.getDiskStoreSize());
112 
113         cache.removeAll();
114 
115     }
116 
117     @Override
118     @Test
119     public void testFlushWithoutClear() throws InterruptedException {
120 
121         CacheManager cacheManager = CacheManager.create(AbstractCacheTest.TEST_CONFIG_DIR + "ehcache.xml");
122         Cache cache = cacheManager.getCache("SimplePageCachingFilter");
123         cache.removeAll();
124         for (int i = 0; i < 100; i++) {
125             cache.put(new Element("" + i, new Date()));
126             //hit
127             cache.get("" + i);
128         }
129         assertEquals(10, cache.getMemoryStoreSize());
130         assertEquals(90, cache.getDiskStoreSize());
131 
132         cache.flush();
133         Thread.sleep(1000);
134 
135         assertEquals(10, cache.getMemoryStoreSize());
136         assertEquals(100, cache.getDiskStoreSize());
137         cacheManager.shutdown();
138 
139     }
140 
141     @Override
142     @Test
143     public void testFlushWithClear() throws InterruptedException {
144 
145         CacheManager cacheManager = CacheManager.create(AbstractCacheTest.TEST_CONFIG_DIR + "ehcache.xml");
146         Cache cache = cacheManager.getCache("SimplePageFragmentCachingFilter");
147         cache.removeAll();
148         for (int i = 0; i < 100; i++) {
149             cache.put(new Element("" + i, new Date()));
150             //hit
151             cache.get("" + i);
152         }
153         assertEquals(10, cache.getMemoryStoreSize());
154         assertEquals(90, cache.getDiskStoreSize());
155 
156         cache.flush();
157         Thread.sleep(1000);
158 
159         assertEquals(0, cache.getMemoryStoreSize());
160         assertEquals(100, cache.getDiskStoreSize());
161         cacheManager.shutdown();
162 
163     }
164 
165     /***
166      * Tests disk store and memory store size
167      * <p/>
168      * This is overridden because the classic LRU store uses different classes
169      */
170     @Test
171     @Override
172     public void testGetDiskStoreSize() throws Exception {
173         Cache cache = new Cache("testGetDiskStoreSize", 1, true, false, 100, 200);
174         manager.addCache(cache);
175         assertEquals(0, cache.getDiskStoreSize());
176 
177         cache.put(new Element("key1", "value1"));
178         assertEquals(0, cache.getDiskStoreSize());
179         assertEquals(1, cache.getSize());
180 
181         cache.put(new Element("key2", "value2"));
182         assertEquals(2, cache.getSize());
183         assertEquals(1, cache.getDiskStoreSize());
184         assertEquals(1, cache.getMemoryStoreSize());
185 
186         cache.put(new Element("key3", "value3"));
187         cache.put(new Element("key4", "value4"));
188         assertEquals(4, cache.getSize());
189         assertEquals(3, cache.getDiskStoreSize());
190         assertEquals(1, cache.getMemoryStoreSize());
191 
192         // remove last element inserted (is in memory store)
193 
194         assertTrue(((LegacyStoreWrapper) cache.getStore()).getMemoryStore().containsKey("key4"));
195         cache.remove("key4");
196         assertEquals(3, cache.getSize());
197         assertEquals(3, cache.getDiskStoreSize());
198         assertEquals(0, cache.getMemoryStoreSize());
199 
200         // remove key1 element
201         assertFalse(((LegacyStoreWrapper) cache.getStore()).getMemoryStore().containsKey("key1"));
202         cache.remove("key1");
203         assertEquals(2, cache.getSize());
204         assertEquals(2, cache.getDiskStoreSize());
205         assertEquals(0, cache.getMemoryStoreSize());
206 
207         // add another
208         cache.put(new Element("key5", "value5"));
209         assertEquals(3, cache.getSize());
210         assertEquals(2, cache.getDiskStoreSize());
211         assertEquals(1, cache.getMemoryStoreSize());
212 
213         // remove all
214         cache.removeAll();
215         assertEquals(0, cache.getSize());
216         assertEquals(0, cache.getDiskStoreSize());
217         assertEquals(0, cache.getMemoryStoreSize());
218 
219         //Check behaviour of NonSerializable objects
220         cache.put(new Element(new Object(), new Object()));
221         cache.put(new Element(new Object(), new Object()));
222         cache.put(new Element(new Object(), new Object()));
223         assertEquals(1, cache.getSize());
224         assertEquals(0, cache.getDiskStoreSize());
225         assertEquals(1, cache.getMemoryStoreSize());
226     }
227 
228     /***
229      * Tests cache, memory store and disk store sizes from config
230      */
231     @Override
232     @Test
233     public void testSizes() throws Exception {
234         Ehcache cache = getSampleCache1();
235 
236         assertEquals(0, cache.getMemoryStoreSize());
237         assertEquals(0, cache.getDiskStoreSize());
238 
239         for (int i = 0; i < 10010; i++) {
240             cache.put(new Element("key" + i, "value1"));
241         }
242 
243         Thread.sleep(1000);
244 
245         assertEquals(10010, cache.getSize());
246         assertEquals(10000, cache.getMemoryStoreSize());
247         assertEquals(10, cache.getDiskStoreSize());
248 
249         //NonSerializable
250         Thread.sleep(15);
251         cache.put(new Element(new Object(), Object.class));
252 
253         Thread.sleep(1000);
254 
255         assertEquals(10011, cache.getSize());
256         assertEquals(11, cache.getDiskStoreSize());
257         assertEquals(10000, cache.getMemoryStoreSize());
258         assertEquals(10000, cache.getMemoryStoreSize());
259         assertEquals(10000, cache.getMemoryStoreSize());
260         assertEquals(10000, cache.getMemoryStoreSize());
261 
262 
263         cache.remove("key4");
264         cache.remove("key3");
265 
266         assertEquals(10009, cache.getSize());
267         //cannot make any guarantees as no elements have been getted, and all are equally likely to be evicted.
268         //assertEquals(10000, cache.getMemoryStoreSize());
269         //assertEquals(9, cache.getDiskStoreSize());
270 
271 
272         Thread.sleep(1000);
273 
274         cache.removeAll();
275         assertEquals(0, cache.getSize());
276         assertEquals(0, cache.getMemoryStoreSize());
277         assertEquals(0, cache.getDiskStoreSize());
278 
279     }
280 
281     /***
282      * Tests that the toString() method works.
283      */
284     @Override
285     @Test
286     public void testToString() {
287         Ehcache cache = new Cache("testGetMemoryStore", 10, false, false, 100, 200);
288         assertTrue(cache.toString().indexOf("testGetMemoryStore") > -1);
289     }
290 
291     /***
292      * Test expiry based on time to idle.
293      */
294     @Override
295     @Test
296     public void testExpiryBasedOnTimeToIdleAfterPutQuiet() throws Exception {
297         //Set size so the second element overflows to disk.
298         Cache cache = new Cache("test", 1, true, false, 5, 3);
299         manager.addCache(cache);
300         cache.put(new Element("key1", "value1"));
301         cache.put(new Element("key2", "value1"));
302 
303         //Test time to idle
304         Element element1 = cache.get("key1");
305         Element element2 = cache.get("key2");
306         assertNotNull(element1);
307         assertNotNull(element2);
308 
309         //Now, getQuiet and check still times out 2 seconds after last get
310         Thread.sleep(1050);
311         element1 = cache.getQuiet("key1");
312         assertNotNull(element1);
313         element2 = cache.getQuiet("key2");
314         assertNotNull(element2);
315         Thread.sleep(2949);
316         assertNull(cache.getQuiet("key1"));
317         assertNull(cache.getQuiet("key2"));
318 
319         //Now put back in with putQuiet. Should be immediately expired
320         cache.putQuiet((Element) element1.clone());
321         cache.putQuiet((Element) element2.clone());
322         assertNull(cache.get("key1"));
323         element2 = cache.get("key2");
324         assertNull(element2);
325     }
326 
327     @Override
328     @Test
329     public void testSizeWithPutAndRemove() throws Exception {
330         //Set size so the second element overflows to disk.
331         Cache cache = new Cache("test2", 1, true, true, 0, 0);
332         manager.addCache(cache);
333         cache.put(new Element("key1", "value1"));
334         cache.put(new Element("key2", "value1"));
335         int sizeFromGetSize = cache.getSize();
336         int sizeFromKeys = cache.getKeys().size();
337         assertEquals(sizeFromGetSize, sizeFromKeys);
338         assertEquals(2, cache.getSize());
339         cache.put(new Element("key1", "value1"));
340         cache.put(new Element("key1", "value1"));
341 
342         //key1 should be in the Disk Store
343         assertEquals(cache.getSize(), cache.getKeys().size());
344         assertEquals(2, cache.getSize());
345         //there were two of these, so size will now be one
346         cache.remove("key1");
347         assertEquals(cache.getSize(), cache.getKeys().size());
348         assertEquals(1, cache.getSize());
349         cache.remove("key2");
350         assertEquals(cache.getSize(), cache.getKeys().size());
351         assertEquals(0, cache.getSize());
352 
353         //try null values
354         cache.removeAll();
355         Object object1 = new Object();
356         Object object2 = new Object();
357         cache.put(new Element(object1, null));
358         cache.put(new Element(object2, null));
359         // wait until the disk store flushed to disk
360         Thread.sleep(500);
361         //Cannot overflow therefore just one
362         try {
363             assertEquals(1, cache.getSize());
364         } catch (AssertionError e) {
365             //eviction failure
366             System.err.println(e + " - likely eviction failure: checking memory store");
367             assertEquals(2, cache.getMemoryStoreSize());
368         }
369         Element nullValueElement = cache.get(object2);
370         assertNull(nullValueElement.getValue());
371         assertNull(nullValueElement.getObjectValue());
372     }
373 
374 }