1   /**
2    *  Copyright 2003-2007 Greg Luck
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;
18  
19  import org.apache.commons.logging.Log;
20  import org.apache.commons.logging.LogFactory;
21  
22  import java.io.IOException;
23  import java.io.ByteArrayOutputStream;
24  import java.io.ObjectOutputStream;
25  import java.io.ByteArrayInputStream;
26  import java.io.ObjectInputStream;
27  
28  /**
29   * Tests for the statistics class
30   *
31   * @author Greg Luck
32   * @version $Id: StatisticsTest.java 512 2007-07-10 09:18:45Z gregluck $
33   */
34  public class StatisticsTest extends AbstractCacheTest {
35  
36  
37      private static final Log LOG = LogFactory.getLog(StatisticsTest.class.getName());
38  
39      /**
40       * Test statistics directly from Cache
41       */
42      public void testStatistics() throws InterruptedException {
43          //Set size so the second element overflows to disk.
44          Cache cache = new Cache("test", 1, true, false, 5, 2);
45          manager.addCache(cache);
46          cache.put(new Element("key1", "value1"));
47          cache.put(new Element("key2", "value1"));
48  
49          //key1 should be in the Disk Store
50          cache.get("key1");
51          assertEquals(1, cache.getHitCount());
52          assertEquals(1, cache.getDiskStoreHitCount());
53          assertEquals(0, cache.getMemoryStoreHitCount());
54          assertEquals(0, cache.getMissCountExpired());
55          assertEquals(0, cache.getMissCountNotFound());
56  
57          //key 1 should now be in the LruMemoryStore
58          cache.get("key1");
59          assertEquals(2, cache.getHitCount());
60          assertEquals(1, cache.getDiskStoreHitCount());
61          assertEquals(1, cache.getMemoryStoreHitCount());
62          assertEquals(0, cache.getMissCountExpired());
63          assertEquals(0, cache.getMissCountNotFound());
64  
65          //Let the idle expire
66          Thread.sleep(5020);
67  
68          //key 1 should now be expired
69          cache.get("key1");
70          assertEquals(2, cache.getHitCount());
71          assertEquals(1, cache.getDiskStoreHitCount());
72          assertEquals(1, cache.getMemoryStoreHitCount());
73          assertEquals(1, cache.getMissCountExpired());
74          assertEquals(1, cache.getMissCountNotFound());
75      }
76  
77  
78      /**
79       * Test statistics directly from Statistics Object
80       */
81      public void testStatisticsFromStatisticsObject() throws InterruptedException {
82          //Set size so the second element overflows to disk.
83          Cache cache = new Cache("test", 1, true, false, 5, 2);
84          manager.addCache(cache);
85  
86  
87          cache.put(new Element("key1", "value1"));
88          cache.put(new Element("key2", "value1"));
89          //key1 should be in the Disk Store
90          cache.get("key1");
91  
92          Statistics statistics = cache.getStatistics();
93          assertEquals(1, statistics.getCacheHits());
94          assertEquals(1, statistics.getOnDiskHits());
95          assertEquals(0, statistics.getInMemoryHits());
96          assertEquals(0, statistics.getCacheMisses());
97  
98          //key 1 should now be in the LruMemoryStore
99          cache.get("key1");
100 
101         statistics = cache.getStatistics();
102         assertEquals(2, statistics.getCacheHits());
103         assertEquals(1, statistics.getOnDiskHits());
104         assertEquals(1, statistics.getInMemoryHits());
105         assertEquals(0, statistics.getCacheMisses());
106 
107         //Let the idle expire
108         Thread.sleep(5020);
109 
110         //key 1 should now be expired
111         cache.get("key1");
112         statistics = cache.getStatistics();
113         assertEquals(2, statistics.getCacheHits());
114         assertEquals(1, statistics.getOnDiskHits());
115         assertEquals(1, statistics.getInMemoryHits());
116         assertEquals(2, statistics.getCacheMisses());
117 
118         assertNotNull(statistics.toString());
119     }
120 
121 
122     /**
123      * Test statistics directly from Statistics Object
124      */
125     public void testClearStatistics() throws InterruptedException {
126         //Set size so the second element overflows to disk.
127         Cache cache = new Cache("test", 1, true, false, 5, 2);
128         manager.addCache(cache);
129 
130 
131         cache.put(new Element("key1", "value1"));
132         cache.put(new Element("key2", "value1"));
133         //key1 should be in the Disk Store
134         cache.get("key1");
135 
136         Statistics statistics = cache.getStatistics();
137         assertEquals(1, statistics.getCacheHits());
138         assertEquals(1, statistics.getOnDiskHits());
139         assertEquals(0, statistics.getInMemoryHits());
140         assertEquals(0, statistics.getCacheMisses());
141 
142         //clear stats
143         statistics.clearStatistics();
144         statistics = cache.getStatistics();
145         assertEquals(0, statistics.getCacheHits());
146         assertEquals(0, statistics.getOnDiskHits());
147         assertEquals(0, statistics.getInMemoryHits());
148         assertEquals(0, statistics.getCacheMisses());
149     }
150 
151 
152     /**
153      * CacheStatistics should always be sensible when the cache has not started.
154      */
155     public void testCacheStatisticsDegradesElegantlyWhenCacheDisposed() {
156         Cache cache = new Cache("test", 1, true, false, 5, 2);
157         try {
158             Statistics statistics = cache.getStatistics();
159             fail();
160         } catch (IllegalStateException e) {
161             assertEquals("The test Cache is not alive.", e.getMessage());
162         }
163 
164     }
165 
166 
167     /**
168      * We want to be able to use Statistics as a value object.
169      * We need to do some magic with the refernence held to Cache
170      */
171     public void testSerialization() throws IOException, ClassNotFoundException {
172 
173         Cache cache = new Cache("test", 1, true, false, 5, 2);
174         manager.addCache(cache);
175 
176         cache.put(new Element("key1", "value1"));
177         cache.put(new Element("key2", "value1"));
178         cache.get("key1");
179         cache.get("key1");
180 
181         Statistics statistics = cache.getStatistics();
182         assertEquals(2, statistics.getCacheHits());
183         assertEquals(1, statistics.getOnDiskHits());
184         assertEquals(1, statistics.getInMemoryHits());
185         assertEquals(0, statistics.getCacheMisses());
186         assertEquals(Statistics.STATISTICS_ACCURACY_BEST_EFFORT, statistics.getStatisticsAccuracy());
187         statistics.clearStatistics();
188 
189 
190         ByteArrayOutputStream bout = new ByteArrayOutputStream();
191         ObjectOutputStream oos = new ObjectOutputStream(bout);
192         oos.writeObject(statistics);
193         byte[] serializedValue = bout.toByteArray();
194         oos.close();
195         Statistics afterDeserializationStatistics = null;
196         ByteArrayInputStream bin = new ByteArrayInputStream(serializedValue);
197         ObjectInputStream ois = new ObjectInputStream(bin);
198         afterDeserializationStatistics = (Statistics) ois.readObject();
199         ois.close();
200 
201         //Check after Serialization
202         assertEquals(2, afterDeserializationStatistics.getCacheHits());
203         assertEquals(1, afterDeserializationStatistics.getOnDiskHits());
204         assertEquals(1, afterDeserializationStatistics.getInMemoryHits());
205         assertEquals(0, afterDeserializationStatistics.getCacheMisses());
206         assertEquals(Statistics.STATISTICS_ACCURACY_BEST_EFFORT, statistics.getStatisticsAccuracy());
207         statistics.clearStatistics();
208 
209     }
210 
211 
212     /**
213      * What happens when a long larger than int max value is cast to an int?
214      * <p/>
215      * The answer is that negative numbers are reported. The cast value is incorrect.
216      */
217     public void testIntOverflow() {
218 
219         long value = Integer.MAX_VALUE;
220         value += Integer.MAX_VALUE;
221         value += 5;
222         LOG.info("" + value);
223         int valueAsInt = (int) value;
224         LOG.info("" + valueAsInt);
225         assertEquals(3, valueAsInt);
226 
227     }
228 
229 }