1 package org.apache.commons.jcs;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.Serializable;
23 import java.util.ArrayList;
24 import java.util.List;
25
26 import junit.framework.TestCase;
27
28 import org.apache.commons.jcs.access.CacheAccess;
29 import org.apache.commons.jcs.engine.stats.behavior.IStatElement;
30 import org.apache.commons.jcs.engine.stats.behavior.IStats;
31 import org.apache.commons.logging.Log;
32 import org.apache.commons.logging.LogFactory;
33
34
35
36
37
38
39 public class JCSThrashTest
40 extends TestCase
41 {
42
43 private static final Log LOG = LogFactory.getLog( JCSThrashTest.class.getName() );
44
45
46
47
48 protected CacheAccess<String, Serializable> jcs;
49
50
51
52
53 public static void main( String[] args )
54 {
55 junit.textui.TestRunner.run( JCSThrashTest.class );
56 }
57
58
59
60
61 public JCSThrashTest( String arg0 )
62 {
63 super( arg0 );
64 }
65
66
67
68
69
70 @Override
71 protected void setUp()
72 throws Exception
73 {
74 super.setUp();
75 JCS.setConfigFilename( "/TestThrash.ccf" );
76 jcs = JCS.getInstance( "testcache" );
77 }
78
79
80
81
82 @Override
83 protected void tearDown()
84 throws Exception
85 {
86 super.tearDown();
87 jcs.clear();
88 jcs.dispose();
89 }
90
91
92
93
94
95 public void testPut()
96 throws Exception
97 {
98 final String value = "value";
99 final String key = "key";
100
101
102 assertEquals( 0, getListSize() );
103
104 assertNull( jcs.get( key ) );
105
106 jcs.put( key, value );
107
108
109 LOG.info( "jcs.getStats(): " + jcs.getStatistics() );
110 assertEquals( 1, getListSize() );
111 assertNotNull( jcs.get( key ) );
112 assertEquals( value, jcs.get( key ) );
113 }
114
115
116
117
118
119 public void testRemove()
120 throws Exception
121 {
122 jcs.put( "key1", "value1" );
123 assertEquals( 1, getListSize() );
124
125 jcs.remove( "key1" );
126 assertEquals( 0, getListSize() );
127
128 jcs.put( "key2", "value2" );
129 jcs.put( "key3", "value3" );
130 assertEquals( 2, getListSize() );
131
132 jcs.remove( "key2" );
133 assertEquals( 1, getListSize() );
134
135
136 jcs.remove( "key4" );
137 assertEquals( 1, getListSize() );
138 }
139
140
141
142
143
144
145 public void testForMemoryLeaks()
146 throws Exception
147 {
148 long differenceMemoryCache = thrashCache();
149 LOG.info( "Memory Difference is: " + differenceMemoryCache );
150 assertTrue( differenceMemoryCache < 500000 );
151
152
153 }
154
155
156
157
158
159 protected long thrashCache()
160 throws Exception
161 {
162 long startingSize = measureMemoryUse();
163 LOG.info( "Memory Used is: " + startingSize );
164
165 final String value = "value";
166 final String key = "key";
167
168
169 jcs.put( key, value );
170
171
172 final List<Executable> executables = new ArrayList<Executable>();
173 for ( int i = 0; i < 15; i++ )
174 {
175 final JCSThrashTest.Executable executable = new JCSThrashTest.Executable()
176 {
177 @Override
178 public void execute()
179 throws Exception
180 {
181 for ( int j = 0; j < 500; j++ )
182 {
183 final String keyj = "key" + j;
184 jcs.get( keyj );
185 }
186 jcs.get( "key" );
187 }
188 };
189 executables.add( executable );
190 }
191
192
193
194 for ( int i = 0; i < 15; i++ )
195 {
196 final JCSThrashTest.Executable executable = new JCSThrashTest.Executable()
197 {
198 @Override
199 public void execute()
200 throws Exception
201 {
202
203
204 for ( int j = 0; j < 500; j++ )
205 {
206
207 final String keyj = "key" + j;
208 byte[] valuej = new byte[10000];
209 jcs.put( keyj, valuej );
210 }
211 }
212 };
213 executables.add( executable );
214 }
215
216 runThreads( executables );
217 jcs.clear();
218
219 long finishingSize = measureMemoryUse();
220 LOG.info( "Memory Used is: " + finishingSize );
221 return finishingSize - startingSize;
222 }
223
224
225
226
227
228
229
230 protected void runThreads( final List<Executable> executables )
231 throws Exception
232 {
233
234 final long endTime = System.currentTimeMillis() + 10000;
235 final Throwable[] errors = new Throwable[1];
236
237
238 final Thread[] threads = new Thread[executables.size()];
239 for ( int i = 0; i < threads.length; i++ )
240 {
241 final JCSThrashTest.Executable executable = executables.get( i );
242 threads[i] = new Thread()
243 {
244 @Override
245 public void run()
246 {
247 try
248 {
249
250 while ( System.currentTimeMillis() < endTime )
251 {
252 executable.execute();
253 }
254 }
255 catch ( Throwable t )
256 {
257
258 errors[0] = t;
259 }
260 }
261 };
262 threads[i].start();
263 }
264
265
266 for ( int i = 0; i < threads.length; i++ )
267 {
268 threads[i].join();
269 }
270
271
272 if ( errors[0] != null )
273 {
274 throw new Exception( "Test thread failed.", errors[0] );
275 }
276 }
277
278
279
280
281
282
283
284 protected long measureMemoryUse()
285 throws InterruptedException
286 {
287 System.gc();
288 Thread.sleep( 3000 );
289 System.gc();
290 return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
291 }
292
293
294
295
296 protected interface Executable
297 {
298
299
300
301
302 void execute()
303 throws Exception;
304 }
305
306
307
308
309 private int getListSize()
310 {
311 final String listSize = "List Size";
312 final String lruMemoryCache = "LRU Memory Cache";
313 String result = "0";
314 List<IStats> istats = jcs.getStatistics().getAuxiliaryCacheStats();
315 for ( IStats istat : istats )
316 {
317 List<IStatElement<?>> statElements = istat.getStatElements();
318 if ( lruMemoryCache.equals( istat.getTypeName() ) )
319 {
320 for ( IStatElement<?> statElement : statElements )
321 {
322 if ( listSize.equals( statElement.getName() ) )
323 {
324 result = statElement.getData().toString();
325 break;
326 }
327 }
328 }
329 }
330 return Integer.parseInt( result );
331 }
332 }