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