View Javadoc
1   package org.apache.commons.jcs3.engine.control;
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.Arrays;
24  import java.util.Collections;
25  import java.util.HashMap;
26  import java.util.Map;
27  import java.util.Set;
28  
29  import org.apache.commons.jcs3.JCS;
30  import org.apache.commons.jcs3.access.CacheAccess;
31  import org.apache.commons.jcs3.access.exception.CacheException;
32  import org.apache.commons.jcs3.auxiliary.AbstractAuxiliaryCache;
33  import org.apache.commons.jcs3.auxiliary.AuxiliaryCacheAttributes;
34  import org.apache.commons.jcs3.engine.CacheElement;
35  import org.apache.commons.jcs3.engine.CacheStatus;
36  import org.apache.commons.jcs3.engine.CompositeCacheAttributes;
37  import org.apache.commons.jcs3.engine.ElementAttributes;
38  import org.apache.commons.jcs3.engine.behavior.ICacheElement;
39  import org.apache.commons.jcs3.engine.behavior.ICacheType.CacheType;
40  import org.apache.commons.jcs3.engine.behavior.ICompositeCacheAttributes;
41  import org.apache.commons.jcs3.engine.behavior.IElementAttributes;
42  import org.apache.commons.jcs3.engine.behavior.IElementSerializer;
43  import org.apache.commons.jcs3.engine.logging.behavior.ICacheEventLogger;
44  import org.apache.commons.jcs3.engine.stats.behavior.IStats;
45  
46  import junit.framework.TestCase;
47  
48  /**
49   * Tests of the disk usage settings for the CompositeCache.
50   */
51  public class CompositeCacheDiskUsageUnitTest
52      extends TestCase
53  {
54      private static final String CACHE_NAME = "testSpoolAllowed";
55  
56      /**
57       * Test setup
58       */
59      @Override
60      public void setUp()
61      {
62          JCS.setConfigFilename( "/TestDiskCacheUsagePattern.ccf" );
63      }
64  
65      /**
66       * Verify that the swap region is set to the correct pattern.
67       * <p>
68       * @throws CacheException
69       */
70      public void testSwapConfig()
71          throws CacheException
72      {
73          final CacheAccess<String, String> swap = JCS.getInstance( "Swap" );
74          assertEquals( ICompositeCacheAttributes.DiskUsagePattern.SWAP, swap.getCacheAttributes()
75              .getDiskUsagePattern() );
76      }
77  
78      /**
79       * Verify that the swap region is set to the correct pattern.
80       * <p>
81       * @throws CacheException
82       */
83      public void testUpdateConfig()
84          throws CacheException
85      {
86          final CacheAccess<String, String> swap = JCS.getInstance( "Update" );
87          assertEquals( ICompositeCacheAttributes.DiskUsagePattern.UPDATE, swap.getCacheAttributes()
88              .getDiskUsagePattern() );
89      }
90  
91      /**
92       * Setup a disk cache. Configure the disk usage pattern to swap. Call spool. Verify that the
93       * item is put to disk.
94       */
95      public void testSpoolAllowed()
96      {
97          // SETUP
98          final ICompositeCacheAttributes cattr = new CompositeCacheAttributes();
99          cattr.setCacheName(CACHE_NAME);
100         cattr.setDiskUsagePattern( ICompositeCacheAttributes.DiskUsagePattern.SWAP );
101 
102         final IElementAttributes attr = new ElementAttributes();
103 
104         final CompositeCache<String, String> cache = new CompositeCache<>( cattr, attr );
105 
106         final MockAuxCache<String, String> mock = new MockAuxCache<>();
107         mock.cacheType = CacheType.DISK_CACHE;
108         cache.setAuxCaches(Arrays.asList(mock));
109 
110         final ICacheElement<String, String> inputElement = new CacheElement<>( CACHE_NAME, "key", "value" );
111 
112         // DO WORK
113         cache.spoolToDisk( inputElement );
114 
115         // VERIFY
116         assertEquals( "Wrong number of calls to the disk cache update.", 1, mock.updateCount );
117         assertEquals( "Wrong element updated.", inputElement, mock.lastUpdatedItem );
118     }
119 
120     /**
121      * Setup a disk cache. Configure the disk usage pattern to not swap. Call spool. Verify that the
122      * item is not put to disk.
123      */
124     public void testSpoolNotAllowed()
125     {
126         // SETUP
127         final ICompositeCacheAttributes cattr = new CompositeCacheAttributes();
128         cattr.setCacheName(CACHE_NAME);
129         cattr.setDiskUsagePattern( ICompositeCacheAttributes.DiskUsagePattern.UPDATE );
130 
131         final IElementAttributes attr = new ElementAttributes();
132 
133         final CompositeCache<String, String> cache = new CompositeCache<>( cattr, attr );
134 
135         final MockAuxCache<String, String> mock = new MockAuxCache<>();
136         mock.cacheType = CacheType.DISK_CACHE;
137         cache.setAuxCaches(Arrays.asList(mock));
138 
139         final ICacheElement<String, String> inputElement = new CacheElement<>( CACHE_NAME, "key", "value" );
140 
141         // DO WORK
142         cache.spoolToDisk( inputElement );
143 
144         // VERIFY
145         assertEquals( "Wrong number of calls to the disk cache update.", 0, mock.updateCount );
146     }
147 
148     /**
149      * Setup a disk cache. Configure the disk usage pattern to UPDATE. Call updateAuxiliaries.
150      * Verify that the item is put to disk.
151      * <p>
152      * This tests that the items are put to disk on a normal put when the usage pattern is set
153      * appropriately.
154      * @throws IOException
155      */
156     public void testUpdateAllowed()
157         throws IOException
158     {
159         // SETUP
160         final ICompositeCacheAttributes cattr = new CompositeCacheAttributes();
161         cattr.setCacheName(CACHE_NAME);
162         cattr.setDiskUsagePattern( ICompositeCacheAttributes.DiskUsagePattern.UPDATE );
163 
164         final IElementAttributes attr = new ElementAttributes();
165 
166         final CompositeCache<String, String> cache = new CompositeCache<>( cattr, attr );
167 
168         final MockAuxCache<String, String> mock = new MockAuxCache<>();
169         mock.cacheType = CacheType.DISK_CACHE;
170         cache.setAuxCaches(Arrays.asList(mock));
171 
172         final ICacheElement<String, String> inputElement = new CacheElement<>( CACHE_NAME, "key", "value" );
173 
174         // DO WORK
175         cache.updateAuxiliaries( inputElement, true );
176 
177         // VERIFY
178         assertEquals( "Wrong number of calls to the disk cache update.", 1, mock.updateCount );
179         assertEquals( "Wrong element updated.", inputElement, mock.lastUpdatedItem );
180     }
181 
182     /**
183      * Setup a disk cache. Configure the disk usage pattern to UPDATE. Call updateAuxiliaries with
184      * local only set to false. Verify that the item is put to disk.
185      * <p>
186      * This tests that the items are put to disk on a normal put when the usage pattern is set
187      * appropriately. The local setting should have no impact on whether the item goes to disk.
188      * <p>
189      * @throws IOException
190      */
191     public void testUpdateAllowed_localFalse()
192         throws IOException
193     {
194         // SETUP
195         final ICompositeCacheAttributes cattr = new CompositeCacheAttributes();
196         cattr.setCacheName(CACHE_NAME);
197         cattr.setDiskUsagePattern( ICompositeCacheAttributes.DiskUsagePattern.UPDATE );
198 
199         final IElementAttributes attr = new ElementAttributes();
200 
201         final CompositeCache<String, String> cache = new CompositeCache<>( cattr, attr );
202 
203         final MockAuxCache<String, String> mock = new MockAuxCache<>();
204         mock.cacheType = CacheType.DISK_CACHE;
205         cache.setAuxCaches(Arrays.asList(mock));
206 
207         final ICacheElement<String, String> inputElement = new CacheElement<>( CACHE_NAME, "key", "value" );
208 
209         // DO WORK
210         cache.updateAuxiliaries( inputElement, false );
211 
212         // VERIFY
213         assertEquals( "Wrong number of calls to the disk cache update.", 1, mock.updateCount );
214         assertEquals( "Wrong element updated.", inputElement, mock.lastUpdatedItem );
215     }
216 
217     /**
218      * Setup a disk cache. Configure the disk usage pattern to SWAP. Call updateAuxiliaries. Verify
219      * that the item is not put to disk.
220      * <p>
221      * This tests that the items are not put to disk on a normal put when the usage pattern is set
222      * to SWAP.
223      * <p>
224      * @throws IOException
225      */
226     public void testUpdateNotAllowed()
227         throws IOException
228     {
229         // SETUP
230         final ICompositeCacheAttributes cattr = new CompositeCacheAttributes();
231         cattr.setCacheName(CACHE_NAME);
232         cattr.setDiskUsagePattern( ICompositeCacheAttributes.DiskUsagePattern.SWAP );
233 
234         final IElementAttributes attr = new ElementAttributes();
235 
236         final CompositeCache<String, String> cache = new CompositeCache<>( cattr, attr );
237 
238         final MockAuxCache<String, String> mock = new MockAuxCache<>();
239         mock.cacheType = CacheType.DISK_CACHE;
240         cache.setAuxCaches(Arrays.asList(mock));
241 
242         final ICacheElement<String, String> inputElement = new CacheElement<>( CACHE_NAME, "key", "value" );
243 
244         // DO WORK
245         cache.updateAuxiliaries( inputElement, true );
246 
247         // VERIFY
248         assertEquals( "Wrong number of calls to the disk cache update.", 0, mock.updateCount );
249     }
250 
251     /**
252      * Setup a disk cache. Configure the disk usage pattern to UPDATE. Call updateAuxiliaries.
253      * Verify that the item is put to disk.
254      * <p>
255      * This tests that the items are put to disk on a normal put when the usage pattern is set
256      * appropriately.
257      * @throws IOException
258      */
259     public void testUpdateAllowed_withOtherCaches()
260         throws IOException
261     {
262         // SETUP
263         final ICompositeCacheAttributes cattr = new CompositeCacheAttributes();
264         cattr.setCacheName(CACHE_NAME);
265         cattr.setDiskUsagePattern( ICompositeCacheAttributes.DiskUsagePattern.UPDATE );
266 
267         final IElementAttributes attr = new ElementAttributes();
268 
269         final CompositeCache<String, String> cache = new CompositeCache<>( cattr, attr );
270 
271         final MockAuxCache<String, String> mock = new MockAuxCache<>();
272         mock.cacheType = CacheType.DISK_CACHE;
273 
274         final MockAuxCache<String, String> mockLateral = new MockAuxCache<>();
275         mockLateral.cacheType = CacheType.LATERAL_CACHE;
276         cache.setAuxCaches(Arrays.asList(mock, mockLateral));
277 
278         final ICacheElement<String, String> inputElement = new CacheElement<>( CACHE_NAME, "key", "value" );
279 
280         // DO WORK
281         cache.updateAuxiliaries( inputElement, false );
282 
283         // VERIFY
284         assertEquals( "Wrong number of calls to the disk cache update.", 1, mock.updateCount );
285         assertEquals( "Wrong element updated.", inputElement, mock.lastUpdatedItem );
286 
287         assertEquals( "Wrong number of calls to the lateral cache update.", 1, mockLateral.updateCount );
288         assertEquals( "Wrong element updated with lateral.", inputElement, mockLateral.lastUpdatedItem );
289     }
290 
291     /**
292      * Used to test the disk cache functionality.
293      */
294     public static class MockAuxCache<K, V>
295         extends AbstractAuxiliaryCache<K, V>
296     {
297         /** The last item passed to update. */
298         public ICacheElement<K, V> lastUpdatedItem;
299 
300         /** The number of times update was called. */
301         public int updateCount;
302 
303         /** The type that should be returned from getCacheType. */
304         public CacheType cacheType = CacheType.DISK_CACHE;
305 
306         /** Resets counters and catchers. */
307         public void reset()
308         {
309             updateCount = 0;
310             lastUpdatedItem = null;
311         }
312 
313         /**
314          * @param ce
315          * @throws IOException
316          */
317         @Override
318         public void update( final ICacheElement<K, V> ce )
319             throws IOException
320         {
321             lastUpdatedItem = ce;
322             updateCount++;
323         }
324 
325         /**
326          * @param key
327          * @return ICacheElement
328          * @throws IOException
329          */
330         @Override
331         public ICacheElement<K, V> get( final K key )
332             throws IOException
333         {
334             return null;
335         }
336 
337         /**
338          * Gets multiple items from the cache based on the given set of keys.
339          * <p>
340          * @param keys
341          * @return a map of K key to ICacheElement&lt;K, V&gt; element, or an empty map if there is
342          *         no data in cache for any of these keys
343          */
344         @Override
345         public Map<K, ICacheElement<K, V>> getMultiple(final Set<K> keys)
346         {
347             return new HashMap<>();
348         }
349 
350         /**
351          * @param key
352          * @return false
353          * @throws IOException
354          */
355         @Override
356         public boolean remove( final K key )
357             throws IOException
358         {
359             return false;
360         }
361 
362         /** @throws IOException */
363         @Override
364         public void removeAll()
365             throws IOException
366         {
367             // noop
368         }
369 
370         /** @throws IOException */
371         @Override
372         public void dispose()
373             throws IOException
374         {
375             // noop
376         }
377 
378         /** @return 0 */
379         @Override
380         public int getSize()
381         {
382             return 0;
383         }
384 
385         /** @return 0 */
386         @Override
387         public CacheStatus getStatus()
388         {
389             return CacheStatus.ALIVE;
390         }
391 
392         /** @return null */
393         @Override
394         public String getCacheName()
395         {
396             return null;
397         }
398 
399         /**
400          * @return null
401          * @throws IOException
402          */
403         @Override
404         public Set<K> getKeySet( )
405             throws IOException
406         {
407             return null;
408         }
409 
410         /** @return null */
411         @Override
412         public IStats getStatistics()
413         {
414             return null;
415         }
416 
417         /** @return null */
418         @Override
419         public String getStats()
420         {
421             return null;
422         }
423 
424         /**
425          * Returns the setup cache type. This allows you to use this mock as multiple cache types.
426          * <p>
427          * @see org.apache.commons.jcs3.engine.behavior.ICacheType#getCacheType()
428          * @return cacheType
429          */
430         @Override
431         public CacheType getCacheType()
432         {
433             return cacheType;
434         }
435 
436         /**
437          * @return Returns the AuxiliaryCacheAttributes.
438          */
439         @Override
440         public AuxiliaryCacheAttributes getAuxiliaryCacheAttributes()
441         {
442             return null;
443         }
444 
445         /**
446          * @param cacheEventLogger
447          */
448         @Override
449         public void setCacheEventLogger( final ICacheEventLogger cacheEventLogger )
450         {
451             // TODO Auto-generated method stub
452 
453         }
454 
455         /**
456          * @param elementSerializer
457          */
458         @Override
459         public void setElementSerializer( final IElementSerializer elementSerializer )
460         {
461             // TODO Auto-generated method stub
462 
463         }
464 
465         /** @return null */
466         @Override
467         public String getEventLoggingExtraInfo()
468         {
469             // TODO Auto-generated method stub
470             return null;
471         }
472 
473         /**
474          * @param pattern
475          * @return Collections.EMPTY_MAP;
476          * @throws IOException
477          */
478         @Override
479         public Map<K, ICacheElement<K, V>> getMatching(final String pattern)
480             throws IOException
481         {
482             return Collections.emptyMap();
483         }
484 
485 
486     }
487 
488 }