1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package net.sf.ehcache.constructs.blocking;
18
19 import net.sf.ehcache.Ehcache;
20 import net.sf.ehcache.Element;
21 import net.sf.ehcache.StopWatch;
22 import net.sf.ehcache.CacheTest;
23 import net.sf.ehcache.Status;
24 import net.sf.ehcache.Cache;
25 import org.apache.commons.logging.Log;
26 import org.apache.commons.logging.LogFactory;
27
28 import java.io.Serializable;
29 import java.util.ArrayList;
30 import java.util.HashMap;
31 import java.util.List;
32 import java.util.Map;
33
34
35
36
37
38
39
40
41 public class BlockingCacheTest extends CacheTest {
42 private static final Log LOG = LogFactory.getLog(BlockingCacheTest.class.getName());
43 private BlockingCache blockingCache;
44
45
46
47
48 protected void setUp() throws Exception {
49 super.setUp();
50 Ehcache cache = manager.getCache("sampleIdlingExpiringCache");
51 blockingCache = new BlockingCache(cache);
52 }
53
54
55
56
57 protected void tearDown() throws Exception {
58 if (manager.getStatus() == Status.STATUS_ALIVE) {
59 blockingCache.removeAll();
60 }
61 super.tearDown();
62 }
63
64
65
66
67 public void testAddEntry() throws Exception {
68 final String key = "key";
69 final String value = "value";
70 Element element = new Element(key, value);
71
72
73 assertEquals(0, blockingCache.getKeys().size());
74
75
76 blockingCache.put(new Element(key, value));
77
78
79 assertEquals(1, blockingCache.getKeys().size());
80 assertTrue(blockingCache.getKeys().contains(key));
81 final Element returnedElement = blockingCache.get(key);
82 assertEquals(element, returnedElement);
83
84 }
85
86
87
88
89 public void testGetEntries() throws Exception {
90 Ehcache cache = blockingCache.getCache();
91 for (int i = 0; i < 100; i++) {
92 cache.put(new Element(new Integer(i), "value" + i));
93 }
94 List keys = blockingCache.getKeys();
95 List elements = new ArrayList();
96 for (int i = 0; i < keys.size(); i++) {
97 Object key = keys.get(i);
98 elements.add(blockingCache.get(key));
99 }
100 assertEquals(100, elements.size());
101 Map map = new HashMap();
102 for (int i = 0; i < elements.size(); i++) {
103 Element element = (Element) elements.get(i);
104 map.put(element.getObjectKey(), element.getObjectValue());
105 }
106 for (int i = 0; i < 100; i++) {
107 Serializable value = (Serializable) map.get(new Integer(i));
108 assertEquals("value" + i, value);
109 }
110 }
111
112
113
114
115 public void testAddMissingEntry() throws Exception {
116 Element element = new Element("key", "value");
117
118
119 assertNull(blockingCache.get("key"));
120
121
122 blockingCache.put(element);
123
124
125 assertEquals(1, blockingCache.getKeys().size());
126 assertEquals(element, blockingCache.get("key"));
127
128 }
129
130
131
132
133
134 public void testSecondThreadActuallyBlocks() throws Exception {
135 Element element = new Element("key", "value");
136 final List threadResults = new ArrayList();
137
138
139 assertNull(blockingCache.get("key"));
140
141 Thread secondThread = new Thread() {
142 public void run() {
143 threadResults.add(blockingCache.get("key"));
144 }
145 };
146 secondThread.start();
147 assertEquals(0, threadResults.size());
148
149
150 blockingCache.put(element);
151 Thread.sleep(30);
152 assertEquals(1, threadResults.size());
153 assertEquals(element, threadResults.get(0));
154
155
156 assertEquals(1, blockingCache.getKeys().size());
157 assertEquals(element, blockingCache.get("key"));
158 }
159
160
161
162
163 public void testUnknownEntry() throws Exception {
164
165 assertNull(blockingCache.get("key"));
166
167 blockingCache.put(new Element("key", null));
168 assertEquals(0, blockingCache.getKeys().size());
169 }
170
171
172
173
174 public void testRemoveEntry() throws Exception {
175 Element element = new Element("key", "value");
176
177
178 blockingCache.put(element);
179 assertEquals(element, blockingCache.get("key"));
180
181
182 blockingCache.put(new Element("key", null));
183 assertEquals(0, blockingCache.getKeys().size());
184
185 }
186
187
188
189
190 public void testClear() throws Exception {
191 Ehcache cache = manager.getCache("sampleCacheNotEternalButNoIdleOrExpiry");
192 blockingCache = new BlockingCache(cache);
193
194 blockingCache.put(new Element("key1", "value1"));
195 blockingCache.put(new Element("key2", "value2"));
196 blockingCache.put(new Element("key3", "value2"));
197 assertEquals(3, blockingCache.getKeys().size());
198
199
200 blockingCache.removeAll();
201 assertEquals(0, blockingCache.getKeys().size());
202 }
203
204
205
206
207
208
209 public void testThrashBlockingCache() throws Exception {
210 Ehcache cache = manager.getCache("sampleCache1");
211 blockingCache = new BlockingCache(cache);
212 long duration = thrashCache(blockingCache, 50, 500L, 1000L);
213 LOG.debug("Thrash Duration:" + duration);
214 }
215
216
217
218
219
220
221 public void testThrashBlockingCacheTinyTimeout() throws Exception {
222 Ehcache cache = manager.getCache("sampleCache1");
223 blockingCache = new BlockingCache(cache);
224 blockingCache.setTimeoutMillis(1);
225 long duration = 0;
226 try {
227 duration = thrashCache(blockingCache, 50, 400L, 1000L);
228 fail();
229 } catch (Exception e) {
230 assertEquals(LockTimeoutException.class, e.getCause().getClass());
231 }
232 LOG.debug("Thrash Duration:" + duration);
233 }
234
235
236
237
238
239 public void testThrashBlockingCacheReasonableTimeout() throws Exception {
240 Ehcache cache = manager.getCache("sampleCache1");
241 blockingCache = new BlockingCache(cache);
242 blockingCache.setTimeoutMillis((int) (400 * StopWatch.getSpeedAdjustmentFactor()));
243 long duration = thrashCache(blockingCache, 50, 400L, (long) (1000L * StopWatch.getSpeedAdjustmentFactor()));
244 LOG.debug("Thrash Duration:" + duration);
245 }
246
247
248
249
250
251 private long thrashCache(final BlockingCache cache, final int numberOfThreads,
252 final long liveness, final long retrievalTime) throws Exception {
253 StopWatch stopWatch = new StopWatch();
254
255
256 final List executables = new ArrayList();
257 for (int i = 0; i < numberOfThreads; i++) {
258 final Executable executable = new Executable() {
259 public void execute() throws Exception {
260 for (int i = 0; i < 10; i++) {
261 final String key = "key" + i;
262 Object value = cache.get(key);
263 checkLiveness(cache, liveness);
264 if (value == null) {
265 cache.put(new Element(key, "value" + i));
266 }
267
268 checkRetrievalOnKnownKey(cache, retrievalTime, key);
269 }
270 }
271 };
272 executables.add(executable);
273 }
274
275 runThreads(executables);
276 cache.removeAll();
277 return stopWatch.getElapsedTime();
278 }
279
280
281
282
283
284
285
286
287
288 private void checkLiveness(BlockingCache cache, long liveness) {
289 StopWatch stopWatch = new StopWatch();
290 cache.liveness();
291 long measuredLiveness = stopWatch.getElapsedTime();
292 assertTrue("liveness is " + measuredLiveness + " but should be less than " + liveness + "ms",
293 measuredLiveness < liveness);
294 }
295
296
297
298
299
300
301
302
303
304 private void checkRetrievalOnKnownKey(BlockingCache cache, long requiredRetrievalTime, Serializable key)
305 throws LockTimeoutException {
306 StopWatch stopWatch = new StopWatch();
307 cache.get(key);
308 long measuredRetrievalTime = stopWatch.getElapsedTime();
309 assertTrue("Retrieval time on known key is " + measuredRetrievalTime
310 + " but should be less than " + requiredRetrievalTime + "ms",
311 measuredRetrievalTime < requiredRetrievalTime);
312 }
313
314
315
316
317 protected Ehcache createTestCache() {
318 Ehcache cache = super.createTestCache();
319 return new BlockingCache(cache);
320 }
321
322
323
324
325 protected Ehcache getSampleCache1() {
326 Cache cache = manager.getCache("sampleCache1");
327 manager.replaceCacheWithDecoratedCache(cache, new BlockingCache(cache));
328 return manager.getEhcache("sampleCache1");
329 }
330
331
332
333
334 public void testInstrumented() throws Exception {
335 super.testSizes();
336 }
337 }
338