View Javadoc

1   /***
2    *  Copyright 2003-2010 Terracotta, Inc.
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License");
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License.
15   */
16  
17  package net.sf.ehcache.statistics;
18  
19  import static org.junit.Assert.assertEquals;
20  import static org.junit.Assert.assertFalse;
21  import static org.junit.Assert.assertNotNull;
22  import static org.junit.Assert.assertTrue;
23  import static org.junit.Assert.fail;
24  
25  import java.util.Random;
26  
27  import net.sf.ehcache.AbstractCacheTest;
28  import net.sf.ehcache.Cache;
29  import net.sf.ehcache.Ehcache;
30  import net.sf.ehcache.Element;
31  import net.sf.ehcache.Statistics;
32  
33  import org.junit.Test;
34  
35  /***
36   * Tests for the statistics class
37   *
38   * @author Abhishek Sanoujam
39   * @version $Id: CacheUsageStatisticsTest.java 1221 2009-09-25 17:29:35Z asingh
40   *          $
41   */
42  public class LiveCacheStatisticsTest extends AbstractCacheTest {
43  
44  
45      /***
46       * test enable disable
47       */
48      @Test
49      public void testEnableDisable() {
50          Cache cache = new Cache("test", 1, true, false, 5, 2);
51          manager.addCache(cache);
52  
53          cache.setStatisticsEnabled(true);
54          assertTrue(cache.isStatisticsEnabled());
55          assertFalse(cache.isSampledStatisticsEnabled());
56  
57          cache.setStatisticsEnabled(false);
58          assertFalse(cache.isStatisticsEnabled());
59          assertFalse(cache.isSampledStatisticsEnabled());
60  
61          // enabling sampled enables both
62          cache.setSampledStatisticsEnabled(true);
63          assertTrue(cache.isStatisticsEnabled());
64          assertTrue(cache.isSampledStatisticsEnabled());
65  
66          cache.setSampledStatisticsEnabled(false);
67          assertTrue(cache.isStatisticsEnabled());
68          assertFalse(cache.isSampledStatisticsEnabled());
69  
70          // enable sampled again
71          cache.setSampledStatisticsEnabled(true);
72          assertTrue(cache.isStatisticsEnabled());
73          assertTrue(cache.isSampledStatisticsEnabled());
74  
75          // disabling live disables sampled too
76          cache.setStatisticsEnabled(false);
77          assertFalse(cache.isStatisticsEnabled());
78          assertFalse(cache.isSampledStatisticsEnabled());
79      }
80  
81      /***
82       * Test statistics enabling/disabling/clearing
83       *
84       * @throws InterruptedException
85       */
86      @Test
87      public void testCacheUsageStatistics() throws InterruptedException {
88          // Set size so the second element overflows to disk.
89          Cache cache = new Cache("test", 1, true, false, 5, 2);
90          manager.addCache(cache);
91  
92          cache.setStatisticsEnabled(true);
93          doTestCacheUsageStatistics(cache, true);
94  
95          // test enable/disable statistics
96          cache.setStatisticsEnabled(false);
97          doTestCacheUsageStatistics(cache, false);
98  
99          assertEquals(Statistics.STATISTICS_ACCURACY_BEST_EFFORT, cache
100                 .getLiveCacheStatistics().getStatisticsAccuracy());
101         assertEquals("Best Effort", cache.getLiveCacheStatistics()
102                 .getStatisticsAccuracyDescription());
103 
104     }
105 
106     /***
107      * Test statistics directly. Tests
108      * - cacheHitCount
109      * - onDiskHitCount
110      * - inMemoryHitCount
111      * - cacheMissCount
112      * - size
113      * - inMemorySize
114      * - onDiskSize
115      * - clearing statistics
116      * - average get time
117      *
118      */
119     public void doTestCacheUsageStatistics(Cache cache,
120             boolean statisticsEnabled) throws InterruptedException {
121 
122         cache.put(new Element("key1", "value1"));
123         cache.put(new Element("key2", "value1"));
124         // key1 should be in the Disk Store
125         cache.get("key1");
126 
127         LiveCacheStatistics statistics = cache.getLiveCacheStatistics();
128         if (statisticsEnabled) {
129             assertEquals(1, statistics.getCacheHitCount());
130             assertEquals(1, statistics.getOnDiskHitCount());
131             assertEquals(0, statistics.getInMemoryHitCount());
132             assertEquals(0, statistics.getCacheMissCount());
133             assertEquals(2, statistics.getSize());
134             assertEquals(1, statistics.getInMemorySize());
135             assertEquals(1, statistics.getOnDiskSize());
136         } else {
137             assertEquals(0, statistics.getCacheHitCount());
138             assertEquals(0, statistics.getOnDiskHitCount());
139             assertEquals(0, statistics.getInMemoryHitCount());
140             assertEquals(0, statistics.getCacheMissCount());
141             assertEquals(0, statistics.getSize());
142             assertEquals(0, statistics.getInMemorySize());
143             assertEquals(0, statistics.getOnDiskSize());
144         }
145 
146         // key 1 should now be in the LruMemoryStore
147         cache.get("key1");
148 
149         statistics = cache.getLiveCacheStatistics();
150         if (statisticsEnabled) {
151             assertEquals(2, statistics.getCacheHitCount());
152             assertEquals(1, statistics.getOnDiskHitCount());
153             assertEquals(1, statistics.getInMemoryHitCount());
154             assertEquals(0, statistics.getCacheMissCount());
155         } else {
156             assertEquals(0, statistics.getCacheHitCount());
157             assertEquals(0, statistics.getOnDiskHitCount());
158             assertEquals(0, statistics.getInMemoryHitCount());
159             assertEquals(0, statistics.getCacheMissCount());
160         }
161 
162         // Let the idle expire
163         Thread.sleep(6000);
164 
165         // key 1 should now be expired
166         cache.get("key1");
167         statistics = cache.getLiveCacheStatistics();
168         if (statisticsEnabled) {
169             assertEquals(2, statistics.getCacheHitCount());
170             assertEquals(1, statistics.getOnDiskHitCount());
171             assertEquals(1, statistics.getInMemoryHitCount());
172             assertEquals(1, statistics.getCacheMissCount());
173         } else {
174             assertEquals(0, statistics.getCacheHitCount());
175             assertEquals(0, statistics.getOnDiskHitCount());
176             assertEquals(0, statistics.getInMemoryHitCount());
177             assertEquals(0, statistics.getCacheMissCount());
178         }
179 
180         // key 2 should also be expired
181         cache.get("key1");
182         statistics = cache.getLiveCacheStatistics();
183         if (statisticsEnabled) {
184             assertEquals(2, statistics.getCacheHitCount());
185             assertEquals(1, statistics.getOnDiskHitCount());
186             assertEquals(1, statistics.getInMemoryHitCount());
187             assertEquals(2, statistics.getCacheMissCount());
188         } else {
189             assertEquals(0, statistics.getCacheHitCount());
190             assertEquals(0, statistics.getOnDiskHitCount());
191             assertEquals(0, statistics.getInMemoryHitCount());
192             assertEquals(0, statistics.getCacheMissCount());
193         }
194 
195         cache.clearStatistics();
196         // everything should be zero now
197         assertEquals(0, statistics.getCacheHitCount());
198         assertEquals(0, statistics.getOnDiskHitCount());
199         assertEquals(0, statistics.getInMemoryHitCount());
200         assertEquals(0, statistics.getCacheMissCount());
201 
202         assertNotNull(statistics.toString());
203     }
204 
205     /***
206      * Test average get time
207      *
208      * @throws InterruptedException
209      */
210     @Test
211     public void testAverageGetTime() throws InterruptedException {
212         Cache cache = new Cache("test", 0, true, false, 5, 2);
213         manager.addCache(cache);
214         cache.setStatisticsEnabled(true);
215         doTestAverageGetTime(cache, true);
216 
217         // test enable/disable statistics
218         cache.setStatisticsEnabled(false);
219         doTestAverageGetTime(cache, false);
220     }
221 
222     /***
223      * Tests average get time
224      */
225     public void doTestAverageGetTime(Cache cache, boolean statsEnabled) {
226         LiveCacheStatistics statistics = cache.getLiveCacheStatistics();
227         float averageGetTime = statistics.getAverageGetTimeMillis();
228         assertTrue(0 == statistics.getAverageGetTimeMillis());
229 
230         for (int i = 0; i < 10000; i++) {
231             cache.put(new Element("" + i, "value1"));
232         }
233         cache.put(new Element("key1", "value1"));
234         cache.put(new Element("key2", "value1"));
235         for (int i = 0; i < 110000; i++) {
236             cache.get("" + i);
237         }
238 
239         statistics = cache.getLiveCacheStatistics();
240         averageGetTime = statistics.getAverageGetTimeMillis();
241         if (statsEnabled) {
242             assertTrue(averageGetTime >= .000001);
243         } else {
244             assertTrue(0 == averageGetTime);
245         }
246         cache.clearStatistics();
247         assertTrue(0 == statistics.getAverageGetTimeMillis());
248     }
249 
250     /***
251      * Test cache eviction/expiry stats
252      *
253      * @throws InterruptedException
254      */
255     @Test
256     public void testEvictionStatistics() throws InterruptedException {
257         doTestEvictionStatistics(true);
258 
259         doTestEvictionStatistics(false);
260     }
261 
262     /***
263      * Tests eviction statistics
264      * - evictedCount
265      * - missCountNotFound
266      * - missCountExpired
267      * - missCount
268      * - expiredCount
269      * - size
270      */
271     public void doTestEvictionStatistics(boolean statsEnabled)
272             throws InterruptedException {
273         // run 5 times with random total and capacity values
274         Random rand = new Random();
275         int min = 100;
276         for (int loop = 0; loop < 5; loop++) {
277             int a = rand.nextInt(10000) + min;
278             int b = rand.nextInt(10000) + min;
279             if (a == b) {
280                 a += min;
281             }
282             int total = Math.max(a, b);
283             int capacity = Math.min(a, b);
284             Ehcache ehcache = new net.sf.ehcache.Cache("test-" + statsEnabled
285                     + "-" + loop, capacity, false, false, 2, 2);
286             manager.addCache(ehcache);
287             ehcache.setStatisticsEnabled(statsEnabled);
288 
289             LiveCacheStatistics statistics = ehcache.getLiveCacheStatistics();
290             assertEquals(0, statistics.getEvictedCount());
291 
292             for (int i = 0; i < total; i++) {
293                 ehcache.put(new Element("" + i, "value1"));
294             }
295             if (statsEnabled) {
296                 assertEquals(total - capacity, statistics.getEvictedCount());
297             } else {
298                 assertEquals(0, statistics.getEvictedCount());
299             }
300 
301             Thread.sleep(3010);
302 
303             // expiries do not count as eviction
304             if (statsEnabled) {
305                 assertEquals(total - capacity, statistics.getEvictedCount());
306             } else {
307                 assertEquals(0, statistics.getEvictedCount());
308             }
309 
310             // no expiration till a get is tried
311             assertEquals(0, statistics.getCacheMissCount());
312             assertEquals(0, statistics.getCacheMissCountExpired());
313             assertEquals(0, statistics.getExpiredCount());
314             assertEquals(0, statistics.getCacheMissCount());
315 
316             for (int i = 0; i < total; i++) {
317                 ehcache.get("" + i);
318             }
319 
320             if (statsEnabled) {
321                 assertEquals(total, statistics.getCacheMissCount());
322                 assertEquals(capacity, statistics.getCacheMissCountExpired());
323                 assertEquals(capacity, statistics.getExpiredCount());
324                 assertEquals(total, statistics.getCacheMissCount());
325                 assertEquals(0, statistics.getSize());
326             } else {
327                 assertEquals(0, statistics.getCacheMissCount());
328                 assertEquals(0, statistics.getCacheMissCountExpired());
329                 assertEquals(0, statistics.getExpiredCount());
330                 assertEquals(0, statistics.getCacheMissCount());
331                 assertEquals(0, statistics.getSize());
332             }
333 
334             ehcache.clearStatistics();
335 
336             assertEquals(0, statistics.getCacheMissCount());
337             assertEquals(0, statistics.getCacheMissCountExpired());
338             assertEquals(0, statistics.getExpiredCount());
339             assertEquals(0, statistics.getCacheMissCount());
340             assertEquals(0, statistics.getSize());
341         }
342 
343     }
344 
345     /***
346      * Test element put/update/remove
347      * - putCount
348      * - updateCount
349      * - removeCount
350      */
351     @Test
352     public void testPutUpdateRemoveStats() throws InterruptedException {
353         doTestElementUpdateRemove(true);
354 
355         doTestElementUpdateRemove(false);
356     }
357 
358     public void doTestElementUpdateRemove(boolean statsEnabled)
359             throws InterruptedException {
360         Random rand = new Random();
361         int min = 100;
362         for (int loop = 0; loop < 5; loop++) {
363             int total = rand.nextInt(10000) + min;
364 
365             // always ensure enough capacity. Otherwise cannot predict
366             // updateCount with eviction (based on capacity)
367             Ehcache ehcache = new net.sf.ehcache.Cache("test-" + statsEnabled
368                     + "-" + loop, total + 1, false, false, 1200, 1200);
369             manager.addCache(ehcache);
370             ehcache.setStatisticsEnabled(statsEnabled);
371 
372             LiveCacheStatistics statistics = ehcache.getLiveCacheStatistics();
373 
374             assertEquals(0, statistics.getEvictedCount());
375             assertEquals(0, statistics.getPutCount());
376             assertEquals(0, statistics.getRemovedCount());
377             assertEquals(0, statistics.getUpdateCount());
378 
379             for (int i = 0; i < total; i++) {
380                 ehcache.put(new Element("" + i, "value1"));
381             }
382             if (statsEnabled) {
383                 assertEquals(total, statistics.getPutCount());
384                 assertEquals(0, statistics.getEvictedCount());
385                 assertEquals(total, statistics.getSize());
386                 assertEquals(0, statistics.getUpdateCount());
387                 assertEquals(0, statistics.getRemovedCount());
388             } else {
389                 assertEquals(0, statistics.getPutCount());
390                 assertEquals(0, statistics.getEvictedCount());
391                 assertEquals(0, statistics.getSize());
392                 assertEquals(0, statistics.getRemovedCount());
393                 assertEquals(0, statistics.getUpdateCount());
394             }
395 
396             // minimum 1 update
397             int updates = rand.nextInt(total - 1) + 1;
398             assertTrue(updates >= 1);
399             for (int i = 0; i < updates; i++) {
400                 ehcache.put(new Element("" + i, "value1"));
401             }
402             if (statsEnabled) {
403                 assertEquals(total, statistics.getSize());
404                 assertEquals(updates, statistics.getUpdateCount());
405                 assertEquals(total, statistics.getPutCount());
406                 assertEquals(0, statistics.getEvictedCount());
407                 assertEquals(0, statistics.getRemovedCount());
408             } else {
409                 assertEquals(0, statistics.getSize());
410                 assertEquals(0, statistics.getPutCount());
411                 assertEquals(0, statistics.getRemovedCount());
412                 assertEquals(0, statistics.getEvictedCount());
413                 assertEquals(0, statistics.getUpdateCount());
414             }
415 
416             // minimum 1 remove
417             int remove = rand.nextInt(total - 1) + 1;
418             assertTrue(updates >= 1);
419             for (int i = 0; i < remove; i++) {
420                 ehcache.remove("" + i);
421             }
422             if (statsEnabled) {
423                 assertEquals(total - remove, statistics.getSize());
424                 assertEquals(updates, statistics.getUpdateCount());
425                 assertEquals(remove, statistics.getRemovedCount());
426                 assertEquals(total, statistics.getPutCount());
427                 assertEquals(0, statistics.getEvictedCount());
428             } else {
429                 assertEquals(0, statistics.getSize());
430                 assertEquals(0, statistics.getPutCount());
431                 assertEquals(0, statistics.getRemovedCount());
432                 assertEquals(0, statistics.getEvictedCount());
433                 assertEquals(0, statistics.getUpdateCount());
434             }
435 
436             ehcache.clearStatistics();
437 
438             assertEquals(0, statistics.getPutCount());
439             assertEquals(0, statistics.getRemovedCount());
440             assertEquals(0, statistics.getEvictedCount());
441             assertEquals(0, statistics.getUpdateCount());
442         }
443 
444     }
445 
446     /***
447      * CacheStatistics should always be sensible when the cache has not
448      * started.
449      */
450     @Test
451     public void testCacheAlive() {
452         Cache cache = new Cache("test", 1, true, false, 5, 2);
453         String string = cache.toString();
454         assertTrue(string.contains("test"));
455         try {
456             LiveCacheStatistics statistics = cache.getLiveCacheStatistics();
457             fail();
458         } catch (IllegalStateException e) {
459             assertEquals("The test Cache is not alive.", e.getMessage());
460         }
461         // initialize cache now
462         manager.addCache(cache);
463         LiveCacheStatistics statistics = cache.getLiveCacheStatistics();
464         assertEquals(0, statistics.getCacheHitCount());
465     }
466 
467 }