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