View Javadoc
1   package org.apache.commons.jcs.auxiliary.disk.indexed;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.IOException;
23  import java.util.HashSet;
24  import java.util.Map;
25  import java.util.Set;
26  
27  import org.apache.commons.jcs.auxiliary.MockCacheEventLogger;
28  import org.apache.commons.jcs.auxiliary.disk.DiskTestObject;
29  import org.apache.commons.jcs.engine.CacheElement;
30  import org.apache.commons.jcs.engine.ElementAttributes;
31  import org.apache.commons.jcs.engine.behavior.ICacheElement;
32  import org.apache.commons.jcs.engine.behavior.IElementAttributes;
33  import org.apache.commons.jcs.engine.control.group.GroupAttrName;
34  import org.apache.commons.jcs.engine.control.group.GroupId;
35  import org.apache.commons.jcs.utils.timing.SleepUtil;
36  
37  import junit.framework.TestCase;
38  
39  /**
40   * Tests for common functionality.
41   * <p>
42   *
43   * @author Aaron Smuts
44   */
45  public abstract class IndexDiskCacheUnitTestAbstract extends TestCase
46  {
47      public abstract IndexedDiskCacheAttributes getCacheAttributes();
48  
49      /**
50       * Simply verify that we can put items in the disk cache and retrieve them.
51       *
52       * @throws IOException
53       */
54      public void testSimplePutAndGet() throws IOException
55      {
56          IndexedDiskCacheAttributes cattr = getCacheAttributes();
57          cattr.setCacheName("testSimplePutAndGet");
58          cattr.setMaxKeySize(1000);
59          cattr.setDiskPath("target/test-sandbox/IndexDiskCacheUnitTest");
60          IndexedDiskCache<String, String> disk = new IndexedDiskCache<String, String>(cattr);
61  
62          disk.processRemoveAll();
63  
64          int cnt = 999;
65          for (int i = 0; i < cnt; i++)
66          {
67              IElementAttributes eAttr = new ElementAttributes();
68              eAttr.setIsSpool(true);
69              ICacheElement<String, String> element = new CacheElement<String, String>("testSimplePutAndGet", "key:" + i, "data:" + i);
70              element.setElementAttributes(eAttr);
71              disk.processUpdate(element);
72          }
73  
74          for (int i = 0; i < cnt; i++)
75          {
76              ICacheElement<String, String> element = disk.processGet("key:" + i);
77              assertNotNull("Should have received an element.", element);
78              assertEquals("Element is wrong.", "data:" + i, element.getVal());
79          }
80  
81          // Test that getMultiple returns all the expected values
82          Set<String> keys = new HashSet<String>();
83          for (int i = 0; i < cnt; i++)
84          {
85              keys.add("key:" + i);
86          }
87  
88          Map<String, ICacheElement<String, String>> elements = disk.getMultiple(keys);
89          for (int i = 0; i < cnt; i++)
90          {
91              ICacheElement<String, String> element = elements.get("key:" + i);
92              assertNotNull("element " + i + ":key is missing", element);
93              assertEquals("value key:" + i, "data:" + i, element.getVal());
94          }
95          // System.out.println( disk.getStats() );
96      }
97  
98      /**
99       * Add some items to the disk cache and then remove them one by one.
100      *
101      * @throws IOException
102      */
103     public void testRemoveItems() throws IOException
104     {
105         IndexedDiskCacheAttributes cattr = getCacheAttributes();
106         cattr.setCacheName("testRemoveItems");
107         cattr.setMaxKeySize(100);
108         cattr.setDiskPath("target/test-sandbox/IndexDiskCacheUnitTest");
109         IndexedDiskCache<String, String> disk = new IndexedDiskCache<String, String>(cattr);
110 
111         disk.processRemoveAll();
112 
113         int cnt = 25;
114         for (int i = 0; i < cnt; i++)
115         {
116             IElementAttributes eAttr = new ElementAttributes();
117             eAttr.setIsSpool(true);
118             ICacheElement<String, String> element = new CacheElement<String, String>("testRemoveItems", "key:" + i, "data:" + i);
119             element.setElementAttributes(eAttr);
120             disk.processUpdate(element);
121         }
122 
123         // remove each
124         for (int i = 0; i < cnt; i++)
125         {
126             disk.remove("key:" + i);
127             ICacheElement<String, String> element = disk.processGet("key:" + i);
128             assertNull("Should not have received an element.", element);
129         }
130     }
131 
132     /**
133      * Verify that we don't override the largest item.
134      * <p>
135      *
136      * @throws IOException
137      */
138 
139     /**
140      * Verify that the overlap check returns true when there are no overlaps.
141      */
142     public void testCheckForDedOverlaps_noOverlap()
143     {
144         // SETUP
145         IndexedDiskCacheAttributes cattr = getCacheAttributes();
146         cattr.setCacheName("testCheckForDedOverlaps_noOverlap");
147         cattr.setDiskPath("target/test-sandbox/UnitTest");
148         IndexedDiskCache<String, String> disk = new IndexedDiskCache<String, String>(cattr);
149 
150         int numDescriptors = 5;
151         int pos = 0;
152         IndexedDiskElementDescriptor[] sortedDescriptors = new IndexedDiskElementDescriptor[numDescriptors];
153         for (int i = 0; i < numDescriptors; i++)
154         {
155             IndexedDiskElementDescriptor descriptor = new IndexedDiskElementDescriptor(pos, i * 2);
156             pos = pos + (i * 2) + IndexedDisk.HEADER_SIZE_BYTES;
157             sortedDescriptors[i] = descriptor;
158         }
159 
160         // DO WORK
161         boolean result = disk.checkForDedOverlaps(sortedDescriptors);
162 
163         // VERIFY
164         assertTrue("There should be no overlap. it should be ok", result);
165     }
166 
167     /**
168      * Verify that the overlap check returns false when there are overlaps.
169      */
170     public void testCheckForDedOverlaps_overlaps()
171     {
172         // SETUP
173         IndexedDiskCacheAttributes cattr = getCacheAttributes();
174         cattr.setCacheName("testCheckForDedOverlaps_overlaps");
175         cattr.setDiskPath("target/test-sandbox/UnitTest");
176         IndexedDiskCache<String, String> disk = new IndexedDiskCache<String, String>(cattr);
177 
178         int numDescriptors = 5;
179         int pos = 0;
180         IndexedDiskElementDescriptor[] sortedDescriptors = new IndexedDiskElementDescriptor[numDescriptors];
181         for (int i = 0; i < numDescriptors; i++)
182         {
183             IndexedDiskElementDescriptor descriptor = new IndexedDiskElementDescriptor(pos, i * 2);
184             // don't add the header + IndexedDisk.RECORD_HEADER;
185             pos = pos + (i * 2);
186             sortedDescriptors[i] = descriptor;
187         }
188 
189         // DO WORK
190         boolean result = disk.checkForDedOverlaps(sortedDescriptors);
191 
192         // VERIFY
193         assertFalse("There should be overlaps. it should be not ok", result);
194     }
195 
196     /**
197      * Verify that the file size is as expected.
198      * <p>
199      *
200      * @throws IOException
201      * @throws InterruptedException
202      */
203     public void testFileSize() throws IOException, InterruptedException
204     {
205         // SETUP
206         IndexedDiskCacheAttributes cattr = getCacheAttributes();
207         cattr.setCacheName("testFileSize");
208         cattr.setDiskPath("target/test-sandbox/UnitTest");
209         IndexedDiskCache<Integer, DiskTestObject> disk = new IndexedDiskCache<Integer, DiskTestObject>(cattr);
210 
211         int numberToInsert = 20;
212         int bytes = 24;
213         ICacheElement<Integer, DiskTestObject>[] elements = DiskTestObjectUtil.createCacheElementsWithTestObjects(numberToInsert,
214             bytes, cattr.getCacheName());
215 
216         for (int i = 0; i < elements.length; i++)
217         {
218             disk.processUpdate(elements[i]);
219         }
220 
221         Thread.yield();
222         Thread.sleep(100);
223         Thread.yield();
224 
225         long expectedSize = DiskTestObjectUtil.totalSize(elements, numberToInsert);
226         long resultSize = disk.getDataFileSize();
227 
228         // System.out.println( "testFileSize stats " + disk.getStats() );
229 
230         assertEquals("Wrong file size", expectedSize, resultSize);
231     }
232 
233     /**
234      * Verify that items are added to the recycle bin on removal.
235      * <p>
236      *
237      * @throws IOException
238      * @throws InterruptedException
239      */
240     public void testRecyleBinSize() throws IOException, InterruptedException
241     {
242         // SETUP
243         int numberToInsert = 20;
244 
245         IndexedDiskCacheAttributes cattr = getCacheAttributes();
246         cattr.setCacheName("testRecyleBinSize");
247         cattr.setDiskPath("target/test-sandbox/UnitTest");
248         cattr.setOptimizeAtRemoveCount(numberToInsert);
249         cattr.setMaxKeySize(numberToInsert * 2);
250         cattr.setMaxPurgatorySize(numberToInsert);
251         IndexedDiskCache<Integer, DiskTestObject> disk = new IndexedDiskCache<Integer, DiskTestObject>(cattr);
252 
253         int bytes = 1;
254         ICacheElement<Integer, DiskTestObject>[] elements = DiskTestObjectUtil.createCacheElementsWithTestObjects(numberToInsert,
255             bytes, cattr.getCacheName());
256 
257         for (int i = 0; i < elements.length; i++)
258         {
259             disk.processUpdate(elements[i]);
260         }
261 
262         Thread.yield();
263         Thread.sleep(100);
264         Thread.yield();
265 
266         // remove half
267         int numberToRemove = elements.length / 2;
268         for (int i = 0; i < numberToRemove; i++)
269         {
270             disk.processRemove(elements[i].getKey());
271         }
272 
273         // verify that the recycle bin has the correct amount.
274         assertEquals("The recycle bin should have the number removed.", numberToRemove, disk.getRecyleBinSize());
275     }
276 
277     /**
278      * Verify that items of the same size use recycle bin spots. Setup the recycle bin by removing
279      * some items. Add some of the same size. Verify that the recycle count is the number added.
280      * <p>
281      *
282      * @throws IOException
283      * @throws InterruptedException
284      */
285     public void testRecyleBinUsage() throws IOException, InterruptedException
286     {
287         // SETUP
288         int numberToInsert = 20;
289 
290         IndexedDiskCacheAttributes cattr = getCacheAttributes();
291         cattr.setCacheName("testRecyleBinUsage");
292         cattr.setDiskPath("target/test-sandbox/UnitTest");
293         cattr.setOptimizeAtRemoveCount(numberToInsert);
294         cattr.setMaxKeySize(numberToInsert * 2);
295         cattr.setMaxPurgatorySize(numberToInsert);
296         IndexedDiskCache<Integer, DiskTestObject> disk = new IndexedDiskCache<Integer, DiskTestObject>(cattr);
297 
298         // we will reuse these
299         int bytes = 1;
300         ICacheElement<Integer, DiskTestObject>[] elements = DiskTestObjectUtil.createCacheElementsWithTestObjects(numberToInsert,
301             bytes, cattr.getCacheName());
302 
303         // Add some to the disk
304         for (int i = 0; i < elements.length; i++)
305         {
306             disk.processUpdate(elements[i]);
307         }
308 
309         Thread.yield();
310         Thread.sleep(100);
311         Thread.yield();
312 
313         // remove half of those added
314         int numberToRemove = elements.length / 2;
315         for (int i = 0; i < numberToRemove; i++)
316         {
317             disk.processRemove(elements[i].getKey());
318         }
319 
320         // verify that the recycle bin has the correct amount.
321         assertEquals("The recycle bin should have the number removed.", numberToRemove, disk.getRecyleBinSize());
322 
323         // add half as many as we removed. These should all use spots in the recycle bin.
324         int numberToAdd = numberToRemove / 2;
325         for (int i = 0; i < numberToAdd; i++)
326         {
327             disk.processUpdate(elements[i]);
328         }
329 
330         // verify that we used the correct number of spots
331         assertEquals("The recycle bin should have the number removed." + disk.getStats(), numberToAdd, disk.getRecyleCount());
332     }
333 
334     /**
335      * Verify that the data size is as expected after a remove and after a put that should use the
336      * spots.
337      * <p>
338      *
339      * @throws IOException
340      * @throws InterruptedException
341      */
342     public void testBytesFreeSize() throws IOException, InterruptedException
343     {
344         // SETUP
345         IndexedDiskCacheAttributes cattr = getCacheAttributes();
346         cattr.setCacheName("testBytesFreeSize");
347         cattr.setDiskPath("target/test-sandbox/UnitTest");
348         IndexedDiskCache<Integer, DiskTestObject> disk = new IndexedDiskCache<Integer, DiskTestObject>(cattr);
349 
350         int numberToInsert = 20;
351         int bytes = 24;
352         ICacheElement<Integer, DiskTestObject>[] elements = DiskTestObjectUtil.createCacheElementsWithTestObjects(numberToInsert,
353             bytes, cattr.getCacheName());
354 
355         for (int i = 0; i < elements.length; i++)
356         {
357             disk.processUpdate(elements[i]);
358         }
359 
360         Thread.yield();
361         Thread.sleep(100);
362         Thread.yield();
363 
364         // remove half of those added
365         int numberToRemove = elements.length / 2;
366         for (int i = 0; i < numberToRemove; i++)
367         {
368             disk.processRemove(elements[i].getKey());
369         }
370 
371         long expectedSize = DiskTestObjectUtil.totalSize(elements, numberToRemove);
372         long resultSize = disk.getBytesFree();
373 
374         // System.out.println( "testBytesFreeSize stats " + disk.getStats() );
375 
376         assertEquals("Wrong bytes free size" + disk.getStats(), expectedSize, resultSize);
377 
378         // add half as many as we removed. These should all use spots in the recycle bin.
379         int numberToAdd = numberToRemove / 2;
380         for (int i = 0; i < numberToAdd; i++)
381         {
382             disk.processUpdate(elements[i]);
383         }
384 
385         long expectedSize2 = DiskTestObjectUtil.totalSize(elements, numberToAdd);
386         long resultSize2 = disk.getBytesFree();
387         assertEquals("Wrong bytes free size" + disk.getStats(), expectedSize2, resultSize2);
388     }
389 
390     /**
391      * Add some items to the disk cache and then remove them one by one.
392      * <p>
393      *
394      * @throws IOException
395      */
396     public void testRemove_PartialKey() throws IOException
397     {
398         IndexedDiskCacheAttributes cattr = getCacheAttributes();
399         cattr.setCacheName("testRemove_PartialKey");
400         cattr.setMaxKeySize(100);
401         cattr.setDiskPath("target/test-sandbox/IndexDiskCacheUnitTest");
402         IndexedDiskCache<String, String> disk = new IndexedDiskCache<String, String>(cattr);
403 
404         disk.processRemoveAll();
405 
406         int cnt = 25;
407         for (int i = 0; i < cnt; i++)
408         {
409             IElementAttributes eAttr = new ElementAttributes();
410             eAttr.setIsSpool(true);
411             ICacheElement<String, String> element = new CacheElement<String, String>("testRemove_PartialKey", i + ":key", "data:"
412                 + i);
413             element.setElementAttributes(eAttr);
414             disk.processUpdate(element);
415         }
416 
417         // verif each
418         for (int i = 0; i < cnt; i++)
419         {
420             ICacheElement<String, String> element = disk.processGet(i + ":key");
421             assertNotNull("Shoulds have received an element.", element);
422         }
423 
424         // remove each
425         for (int i = 0; i < cnt; i++)
426         {
427             disk.remove(i + ":");
428             ICacheElement<String, String> element = disk.processGet(i + ":key");
429             assertNull("Should not have received an element.", element);
430         }
431         // https://issues.apache.org/jira/browse/JCS-67
432         assertEquals("Recylenbin should not have more elements than we removed. Check for JCS-67", cnt, disk.getRecyleBinSize());
433     }
434 
435     /**
436      * Verify that group members are removed if we call remove with a group.
437      *
438      * @throws IOException
439      */
440     public void testRemove_Group() throws IOException
441     {
442         // SETUP
443         IndexedDiskCacheAttributes cattr = getCacheAttributes();
444         cattr.setCacheName("testRemove_Group");
445         cattr.setMaxKeySize(100);
446         cattr.setDiskPath("target/test-sandbox/IndexDiskCacheUnitTest");
447         IndexedDiskCache<GroupAttrName<String>, String> disk = new IndexedDiskCache<GroupAttrName<String>, String>(cattr);
448 
449         disk.processRemoveAll();
450 
451         String cacheName = "testRemove_Group_Region";
452         String groupName = "testRemove_Group";
453 
454         int cnt = 25;
455         for (int i = 0; i < cnt; i++)
456         {
457             GroupAttrName<String> groupAttrName = getGroupAttrName(cacheName, groupName, i + ":key");
458             CacheElement<GroupAttrName<String>, String> element = new CacheElement<GroupAttrName<String>, String>(cacheName,
459                 groupAttrName, "data:" + i);
460 
461             IElementAttributes eAttr = new ElementAttributes();
462             eAttr.setIsSpool(true);
463             element.setElementAttributes(eAttr);
464 
465             disk.processUpdate(element);
466         }
467 
468         // verify each
469         for (int i = 0; i < cnt; i++)
470         {
471             GroupAttrName<String> groupAttrName = getGroupAttrName(cacheName, groupName, i + ":key");
472             ICacheElement<GroupAttrName<String>, String> element = disk.processGet(groupAttrName);
473             assertNotNull("Should have received an element.", element);
474         }
475 
476         // DO WORK
477         // remove the group
478         disk.remove(getGroupAttrName(cacheName, groupName, null));
479 
480         for (int i = 0; i < cnt; i++)
481         {
482             GroupAttrName<String> groupAttrName = getGroupAttrName(cacheName, groupName, i + ":key");
483             ICacheElement<GroupAttrName<String>, String> element = disk.processGet(groupAttrName);
484 
485             // VERIFY
486             assertNull("Should not have received an element.", element);
487         }
488 
489     }
490 
491     /**
492      * Internal method used for group functionality.
493      * <p>
494      *
495      * @param cacheName
496      * @param group
497      * @param name
498      * @return GroupAttrName
499      */
500     private GroupAttrName<String> getGroupAttrName(String cacheName, String group, String name)
501     {
502         GroupId gid = new GroupId(cacheName, group);
503         return new GroupAttrName<String>(gid, name);
504     }
505 
506     /**
507      * Verify event log calls.
508      * <p>
509      *
510      * @throws Exception
511      */
512     public void testUpdate_EventLogging_simple() throws Exception
513     {
514         // SETUP
515         IndexedDiskCacheAttributes cattr = getCacheAttributes();
516         cattr.setCacheName("testUpdate_EventLogging_simple");
517         cattr.setMaxKeySize(100);
518         cattr.setDiskPath("target/test-sandbox/IndexDiskCacheUnitTestCEL");
519         IndexedDiskCache<String, String> diskCache = new IndexedDiskCache<String, String>(cattr);
520         diskCache.processRemoveAll();
521 
522         MockCacheEventLogger cacheEventLogger = new MockCacheEventLogger();
523         diskCache.setCacheEventLogger(cacheEventLogger);
524 
525         ICacheElement<String, String> item = new CacheElement<String, String>("region", "key", "value");
526 
527         // DO WORK
528         diskCache.update(item);
529 
530         SleepUtil.sleepAtLeast(200);
531 
532         // VERIFY
533         assertEquals("Start should have been called.", 1, cacheEventLogger.startICacheEventCalls);
534         assertEquals("End should have been called.", 1, cacheEventLogger.endICacheEventCalls);
535     }
536 
537     /**
538      * Verify event log calls.
539      * <p>
540      *
541      * @throws Exception
542      */
543     public void testGet_EventLogging_simple() throws Exception
544     {
545         // SETUP
546         IndexedDiskCacheAttributes cattr = getCacheAttributes();
547         cattr.setCacheName("testGet_EventLogging_simple");
548         cattr.setMaxKeySize(100);
549         cattr.setDiskPath("target/test-sandbox/IndexDiskCacheUnitTestCEL");
550         IndexedDiskCache<String, String> diskCache = new IndexedDiskCache<String, String>(cattr);
551         diskCache.processRemoveAll();
552 
553         MockCacheEventLogger cacheEventLogger = new MockCacheEventLogger();
554         diskCache.setCacheEventLogger(cacheEventLogger);
555 
556         // DO WORK
557         diskCache.get("key");
558 
559         // VERIFY
560         assertEquals("Start should have been called.", 1, cacheEventLogger.startICacheEventCalls);
561         assertEquals("End should have been called.", 1, cacheEventLogger.endICacheEventCalls);
562     }
563 
564     /**
565      * Verify event log calls.
566      * <p>
567      *
568      * @throws Exception
569      */
570     public void testGetMultiple_EventLogging_simple() throws Exception
571     {
572         // SETUP
573         IndexedDiskCacheAttributes cattr = getCacheAttributes();
574         cattr.setCacheName("testGetMultiple_EventLogging_simple");
575         cattr.setMaxKeySize(100);
576         cattr.setDiskPath("target/test-sandbox/IndexDiskCacheUnitTestCEL");
577         IndexedDiskCache<String, String> diskCache = new IndexedDiskCache<String, String>(cattr);
578         diskCache.processRemoveAll();
579 
580         MockCacheEventLogger cacheEventLogger = new MockCacheEventLogger();
581         diskCache.setCacheEventLogger(cacheEventLogger);
582 
583         Set<String> keys = new HashSet<String>();
584         keys.add("junk");
585 
586         // DO WORK
587         diskCache.getMultiple(keys);
588 
589         // VERIFY
590         // 1 for get multiple and 1 for get.
591         assertEquals("Start should have been called.", 2, cacheEventLogger.startICacheEventCalls);
592         assertEquals("End should have been called.", 2, cacheEventLogger.endICacheEventCalls);
593     }
594 
595     /**
596      * Verify event log calls.
597      * <p>
598      *
599      * @throws Exception
600      */
601     public void testRemove_EventLogging_simple() throws Exception
602     {
603         // SETUP
604         IndexedDiskCacheAttributes cattr = getCacheAttributes();
605         cattr.setCacheName("testRemoveAll_EventLogging_simple");
606         cattr.setMaxKeySize(100);
607         cattr.setDiskPath("target/test-sandbox/IndexDiskCacheUnitTestCEL");
608         IndexedDiskCache<String, String> diskCache = new IndexedDiskCache<String, String>(cattr);
609         diskCache.processRemoveAll();
610 
611         MockCacheEventLogger cacheEventLogger = new MockCacheEventLogger();
612         diskCache.setCacheEventLogger(cacheEventLogger);
613 
614         // DO WORK
615         diskCache.remove("key");
616 
617         // VERIFY
618         assertEquals("Start should have been called.", 1, cacheEventLogger.startICacheEventCalls);
619         assertEquals("End should have been called.", 1, cacheEventLogger.endICacheEventCalls);
620     }
621 
622     /**
623      * Verify event log calls.
624      * <p>
625      *
626      * @throws Exception
627      */
628     public void testRemoveAll_EventLogging_simple() throws Exception
629     {
630         // SETUP
631         IndexedDiskCacheAttributes cattr = getCacheAttributes();
632         cattr.setCacheName("testRemoveAll_EventLogging_simple");
633         cattr.setMaxKeySize(100);
634         cattr.setDiskPath("target/test-sandbox/IndexDiskCacheUnitTestCEL");
635         IndexedDiskCache<String, String> diskCache = new IndexedDiskCache<String, String>(cattr);
636         diskCache.processRemoveAll();
637 
638         MockCacheEventLogger cacheEventLogger = new MockCacheEventLogger();
639         diskCache.setCacheEventLogger(cacheEventLogger);
640 
641         // DO WORK
642         diskCache.remove("key");
643 
644         // VERIFY
645         assertEquals("Start should have been called.", 1, cacheEventLogger.startICacheEventCalls);
646         assertEquals("End should have been called.", 1, cacheEventLogger.endICacheEventCalls);
647     }
648 
649     /**
650      * Test the basic get matching.
651      * <p>
652      *
653      * @throws Exception
654      */
655     public void testPutGetMatching_SmallWait() throws Exception
656     {
657         // SETUP
658         int items = 200;
659 
660         String cacheName = "testPutGetMatching_SmallWait";
661         IndexedDiskCacheAttributes cattr = getCacheAttributes();
662         cattr.setCacheName(cacheName);
663         cattr.setMaxKeySize(100);
664         cattr.setDiskPath("target/test-sandbox/IndexDiskCacheUnitTest");
665         IndexedDiskCache<String, String> diskCache = new IndexedDiskCache<String, String>(cattr);
666 
667         // DO WORK
668         for (int i = 0; i <= items; i++)
669         {
670             diskCache.update(new CacheElement<String, String>(cacheName, i + ":key", cacheName + " data " + i));
671         }
672         Thread.sleep(500);
673 
674         Map<String, ICacheElement<String, String>> matchingResults = diskCache.getMatching("1.8.+");
675 
676         // VERIFY
677         assertEquals("Wrong number returned", 10, matchingResults.size());
678         // System.out.println( "matchingResults.keySet() " + matchingResults.keySet() );
679         // System.out.println( "\nAFTER TEST \n" + diskCache.getStats() );
680     }
681 
682     /**
683      * Test the basic get matching. With no wait this will all come from purgatory.
684      * <p>
685      *
686      * @throws Exception
687      */
688     public void testPutGetMatching_NoWait() throws Exception
689     {
690         // SETUP
691         int items = 200;
692 
693         String cacheName = "testPutGetMatching_NoWait";
694         IndexedDiskCacheAttributes cattr = getCacheAttributes();
695         cattr.setCacheName(cacheName);
696         cattr.setMaxKeySize(100);
697         cattr.setDiskPath("target/test-sandbox/IndexDiskCacheUnitTest");
698         IndexedDiskCache<String, String> diskCache = new IndexedDiskCache<String, String>(cattr);
699 
700         // DO WORK
701         for (int i = 0; i <= items; i++)
702         {
703             diskCache.update(new CacheElement<String, String>(cacheName, i + ":key", cacheName + " data " + i));
704         }
705 
706         Map<String, ICacheElement<String, String>> matchingResults = diskCache.getMatching("1.8.+");
707 
708         // VERIFY
709         assertEquals("Wrong number returned", 10, matchingResults.size());
710         // System.out.println( "matchingResults.keySet() " + matchingResults.keySet() );
711         // System.out.println( "\nAFTER TEST \n" + diskCache.getStats() );
712     }
713 
714     /**
715      * Verify that the block disk cache can handle utf encoded strings.
716      * <p>
717      *
718      * @throws Exception
719      */
720     public void testUTF8String() throws Exception
721     {
722         String string = "IÒtÎrn‚tiÙn‡lizÊti¯n";
723         StringBuilder sb = new StringBuilder();
724         sb.append(string);
725         for (int i = 0; i < 4; i++)
726         {
727             sb.append(sb.toString()); // big string
728         }
729         string = sb.toString();
730 
731         // System.out.println( "The string contains " + string.length() + " characters" );
732 
733         String cacheName = "testUTF8String";
734 
735         IndexedDiskCacheAttributes cattr = getCacheAttributes();
736         cattr.setCacheName(cacheName);
737         cattr.setMaxKeySize(100);
738         cattr.setDiskPath("target/test-sandbox/IndexDiskCacheUnitTest");
739         IndexedDiskCache<String, String> diskCache = new IndexedDiskCache<String, String>(cattr);
740 
741         // DO WORK
742         diskCache.update(new CacheElement<String, String>(cacheName, "x", string));
743 
744         // VERIFY
745         assertNotNull(diskCache.get("x"));
746         Thread.sleep(1000);
747         ICacheElement<String, String> afterElement = diskCache.get("x");
748         assertNotNull(afterElement);
749         // System.out.println( "afterElement = " + afterElement );
750         String after = afterElement.getVal();
751 
752         assertNotNull(after);
753         assertEquals("wrong string after retrieval", string, after);
754     }
755 
756     /**
757      * Verify that the block disk cache can handle utf encoded strings.
758      * <p>
759      *
760      * @throws Exception
761      */
762     public void testUTF8ByteArray() throws Exception
763     {
764         String string = "IÒtÎrn‚tiÙn‡lizÊti¯n";
765         StringBuilder sb = new StringBuilder();
766         sb.append(string);
767         for (int i = 0; i < 4; i++)
768         {
769             sb.append(sb.toString()); // big string
770         }
771         string = sb.toString();
772         // System.out.println( "The string contains " + string.length() + " characters" );
773         String UTF8 = "UTF-8";
774         byte[] bytes = string.getBytes(UTF8);
775 
776         String cacheName = "testUTF8ByteArray";
777 
778         IndexedDiskCacheAttributes cattr = getCacheAttributes();
779         cattr.setCacheName(cacheName);
780         cattr.setMaxKeySize(100);
781         cattr.setDiskPath("target/test-sandbox/IndexDiskCacheUnitTest");
782         IndexedDiskCache<String, byte[]> diskCache = new IndexedDiskCache<String, byte[]>(cattr);
783 
784         // DO WORK
785         diskCache.update(new CacheElement<String, byte[]>(cacheName, "x", bytes));
786 
787         // VERIFY
788         assertNotNull(diskCache.get("x"));
789         Thread.sleep(1000);
790         ICacheElement<String, byte[]> afterElement = diskCache.get("x");
791         assertNotNull(afterElement);
792         // System.out.println( "afterElement = " + afterElement );
793         byte[] after = afterElement.getVal();
794 
795         assertNotNull(after);
796         assertEquals("wrong bytes after retrieval", string, new String(after, UTF8));
797     }
798 
799     /**
800      * Verify the item makes it to disk.
801      * <p>
802      *
803      * @throws IOException
804      */
805     public void testProcessUpdate_Simple() throws IOException
806     {
807         // SETUP
808         String cacheName = "testProcessUpdate_Simple";
809         IndexedDiskCacheAttributes cattr = getCacheAttributes();
810         cattr.setCacheName(cacheName);
811         cattr.setMaxKeySize(100);
812         cattr.setDiskPath("target/test-sandbox/IndexDiskCacheUnitTest");
813         IndexedDiskCache<String, String> diskCache = new IndexedDiskCache<String, String>(cattr);
814 
815         String key = "myKey";
816         String value = "myValue";
817         ICacheElement<String, String> ce = new CacheElement<String, String>(cacheName, key, value);
818 
819         // DO WORK
820         diskCache.processUpdate(ce);
821         ICacheElement<String, String> result = diskCache.processGet(key);
822 
823         // VERIFY
824         assertNotNull("Should have a result", result);
825         long fileSize = diskCache.getDataFileSize();
826         assertTrue("File should be greater than 0", fileSize > 0);
827     }
828 
829     /**
830      * Verify the item makes it to disk.
831      * <p>
832      *
833      * @throws IOException
834      */
835     public void testProcessUpdate_SameKeySameSize() throws IOException
836     {
837         // SETUP
838         String cacheName = "testProcessUpdate_SameKeySameSize";
839         IndexedDiskCacheAttributes cattr = getCacheAttributes();
840         cattr.setCacheName(cacheName);
841         cattr.setMaxKeySize(100);
842         cattr.setDiskPath("target/test-sandbox/IndexDiskCacheUnitTest");
843         IndexedDiskCache<String, String> diskCache = new IndexedDiskCache<String, String>(cattr);
844 
845         String key = "myKey";
846         String value = "myValue";
847         ICacheElement<String, String> ce1 = new CacheElement<String, String>(cacheName, key, value);
848 
849         // DO WORK
850         diskCache.processUpdate(ce1);
851         long fileSize1 = diskCache.getDataFileSize();
852 
853         // DO WORK
854         ICacheElement<String, String> ce2 = new CacheElement<String, String>(cacheName, key, value);
855         diskCache.processUpdate(ce2);
856         ICacheElement<String, String> result = diskCache.processGet(key);
857 
858         // VERIFY
859         assertNotNull("Should have a result", result);
860         long fileSize2 = diskCache.getDataFileSize();
861         assertEquals("File should be the same", fileSize1, fileSize2);
862         int binSize = diskCache.getRecyleBinSize();
863         assertEquals("Should be nothing in the bin.", 0, binSize);
864     }
865 
866     /**
867      * Verify the item makes it to disk.
868      * <p>
869      *
870      * @throws IOException
871      */
872     public void testProcessUpdate_SameKeySmallerSize() throws IOException
873     {
874         // SETUP
875         String cacheName = "testProcessUpdate_SameKeySmallerSize";
876         IndexedDiskCacheAttributes cattr = getCacheAttributes();
877         cattr.setCacheName(cacheName);
878         cattr.setMaxKeySize(100);
879         cattr.setDiskPath("target/test-sandbox/IndexDiskCacheUnitTest");
880         IndexedDiskCache<String, String> diskCache = new IndexedDiskCache<String, String>(cattr);
881 
882         String key = "myKey";
883         String value = "myValue";
884         String value2 = "myValu";
885         ICacheElement<String, String> ce1 = new CacheElement<String, String>(cacheName, key, value);
886 
887         // DO WORK
888         diskCache.processUpdate(ce1);
889         long fileSize1 = diskCache.getDataFileSize();
890 
891         // DO WORK
892         ICacheElement<String, String> ce2 = new CacheElement<String, String>(cacheName, key, value2);
893         diskCache.processUpdate(ce2);
894         ICacheElement<String, String> result = diskCache.processGet(key);
895 
896         // VERIFY
897         assertNotNull("Should have a result", result);
898         long fileSize2 = diskCache.getDataFileSize();
899         assertEquals("File should be the same", fileSize1, fileSize2);
900         int binSize = diskCache.getRecyleBinSize();
901         assertEquals("Should be nothing in the bin.", 0, binSize);
902     }
903 
904     /**
905      * Verify that the old slot gets in the recycle bin.
906      * <p>
907      *
908      * @throws IOException
909      */
910     public void testProcessUpdate_SameKeyBiggerSize() throws IOException
911     {
912         // SETUP
913         String cacheName = "testProcessUpdate_SameKeyBiggerSize";
914         IndexedDiskCacheAttributes cattr = getCacheAttributes();
915         cattr.setCacheName(cacheName);
916         cattr.setMaxKeySize(100);
917         cattr.setDiskPath("target/test-sandbox/IndexDiskCacheUnitTest");
918         IndexedDiskCache<String, String> diskCache = new IndexedDiskCache<String, String>(cattr);
919 
920         String key = "myKey";
921         String value = "myValue";
922         String value2 = "myValue2";
923         ICacheElement<String, String> ce1 = new CacheElement<String, String>(cacheName, key, value);
924 
925         // DO WORK
926         diskCache.processUpdate(ce1);
927         long fileSize1 = diskCache.getDataFileSize();
928 
929         // DO WORK
930         ICacheElement<String, String> ce2 = new CacheElement<String, String>(cacheName, key, value2);
931         diskCache.processUpdate(ce2);
932         ICacheElement<String, String> result = diskCache.processGet(key);
933 
934         // VERIFY
935         assertNotNull("Should have a result", result);
936         long fileSize2 = diskCache.getDataFileSize();
937         assertTrue("File should be greater.", fileSize1 < fileSize2);
938         int binSize = diskCache.getRecyleBinSize();
939         assertEquals("Should be one in the bin.", 1, binSize);
940     }
941 
942     public void testLoadFromDisk() throws Exception
943     {
944         for (int i = 0; i < 15; i++)
945         { // usually after 2 time it fails
946             oneLoadFromDisk();
947         }
948     }
949 
950     public void oneLoadFromDisk() throws Exception
951     {
952         // initialize object to be stored
953         String string = "IÒtÎrn‚tiÙn‡lizÊti¯n";
954         StringBuilder sb = new StringBuilder();
955         sb.append(string);
956         for (int i = 0; i < 4; i++)
957         {
958             sb.append(sb.toString()); // big string
959         }
960         string = sb.toString();
961 
962         // initialize cache
963         String cacheName = "testLoadFromDisk";
964         IndexedDiskCacheAttributes cattr = getCacheAttributes();
965         cattr.setCacheName(cacheName);
966         cattr.setMaxKeySize(100);
967         cattr.setDiskPath("target/test-sandbox/BlockDiskCacheUnitTest");
968         IndexedDiskCache<String, String> diskCache = new IndexedDiskCache<String, String>(cattr);
969 
970         // DO WORK
971         for (int i = 0; i < 50; i++)
972         {
973             diskCache.update(new CacheElement<String, String>(cacheName, "x" + i, string));
974         }
975         // Thread.sleep(1000);
976         // VERIFY
977         diskCache.dispose();
978         // Thread.sleep(1000);
979 
980         diskCache = new IndexedDiskCache<String, String>(cattr);
981 
982         for (int i = 0; i < 50; i++)
983         {
984             ICacheElement<String, String> afterElement = diskCache.get("x" + i);
985             assertNotNull("Missing element from cache. Cache size: " + diskCache.getSize() + " element: x" + i, afterElement);
986             assertEquals("wrong string after retrieval", string, afterElement.getVal());
987         }
988     }
989 }