1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.pool2;
19
20 import static org.junit.jupiter.api.Assertions.assertEquals;
21 import static org.junit.jupiter.api.Assertions.assertNotNull;
22 import static org.junit.jupiter.api.Assertions.assertThrows;
23 import static org.junit.jupiter.api.Assertions.fail;
24
25 import java.lang.reflect.InvocationHandler;
26 import java.lang.reflect.Method;
27 import java.lang.reflect.Proxy;
28 import java.util.ArrayList;
29 import java.util.Arrays;
30 import java.util.Collection;
31 import java.util.Collections;
32 import java.util.HashSet;
33 import java.util.List;
34 import java.util.Map;
35 import java.util.Set;
36 import java.util.TimerTask;
37
38 import org.apache.commons.pool2.impl.DefaultPooledObject;
39 import org.apache.commons.pool2.impl.GenericKeyedObjectPool;
40 import org.apache.commons.pool2.impl.GenericObjectPool;
41 import org.apache.commons.pool2.impl.TestGenericKeyedObjectPool;
42 import org.junit.jupiter.api.Test;
43 import org.opentest4j.AssertionFailedError;
44
45
46
47
48
49
50 public class TestPoolUtils {
51
52 private static class MethodCallLogger implements InvocationHandler {
53 private final List<String> calledMethods;
54
55 MethodCallLogger(final List<String> calledMethods) {
56 this.calledMethods = calledMethods;
57 }
58
59 @Override
60 public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
61 if (calledMethods == null) {
62 return null;
63 }
64 calledMethods.add(method.getName());
65 if (boolean.class.equals(method.getReturnType())) {
66 return Boolean.FALSE;
67 }
68 if (int.class.equals(method.getReturnType())) {
69 return Integer.valueOf(0);
70 }
71 if (long.class.equals(method.getReturnType())) {
72 return Long.valueOf(0);
73 }
74 if (Object.class.equals(method.getReturnType())) {
75 return new Object();
76 }
77 if (PooledObject.class.equals(method.getReturnType())) {
78 return new DefaultPooledObject<>(new Object());
79 }
80 return null;
81 }
82 }
83
84
85 private static final int CHECK_PERIOD = 300;
86
87
88 private static final int CHECK_COUNT = 4;
89
90
91 private static final int CHECK_SLEEP_PERIOD = CHECK_PERIOD * (CHECK_COUNT - 1) + CHECK_PERIOD / 2;
92
93 @SuppressWarnings("unchecked")
94 private static <T> T createProxy(final Class<T> clazz, final InvocationHandler handler) {
95 return (T) Proxy.newProxyInstance(clazz.getClassLoader(), new Class[] { clazz }, handler);
96 }
97
98 private static <T> T createProxy(final Class<T> clazz, final List<String> logger) {
99 return createProxy(clazz, new MethodCallLogger(logger));
100 }
101
102 private static List<String> invokeEveryMethod(final KeyedObjectPool<Object, Object> kop) throws Exception {
103 kop.addObject(null);
104 kop.borrowObject(null);
105 kop.clear();
106 kop.clear(null);
107 kop.close();
108 kop.getKeys();
109 kop.getNumActive();
110 kop.getNumActive(null);
111 kop.getNumIdle();
112 kop.getNumIdle(null);
113 kop.invalidateObject(null, new Object());
114 kop.returnObject(null, new Object());
115 kop.toString();
116
117 return Arrays.asList("addObject", "borrowObject", "clear", "clear", "close", "getKeys", "getNumActive", "getNumActive", "getNumIdle", "getNumIdle",
118 "invalidateObject", "returnObject", "toString");
119 }
120
121 private static <K, V> List<String> invokeEveryMethod(final KeyedPooledObjectFactory<K, V> kpof) throws Exception {
122 kpof.activateObject(null, null);
123 kpof.destroyObject(null, null);
124 kpof.makeObject(null);
125 kpof.passivateObject(null, null);
126 kpof.validateObject(null, null);
127 kpof.toString();
128
129 return Arrays.asList("activateObject", "destroyObject", "makeObject", "passivateObject", "validateObject", "toString");
130 }
131
132 private static List<String> invokeEveryMethod(final ObjectPool<Object> op) throws Exception {
133 op.addObject();
134 op.borrowObject();
135 op.clear();
136 op.close();
137 op.getNumActive();
138 op.getNumIdle();
139 op.invalidateObject(new Object());
140 op.returnObject(new Object());
141 op.toString();
142
143 return Arrays.asList("addObject", "borrowObject", "clear", "close", "getNumActive", "getNumIdle", "invalidateObject",
144 "returnObject", "toString");
145 }
146
147 private static <T> List<String> invokeEveryMethod(final PooledObjectFactory<T> pof) throws Exception {
148 pof.activateObject(null);
149 pof.destroyObject(null);
150 pof.makeObject();
151 pof.passivateObject(null);
152 pof.validateObject(null);
153 pof.toString();
154
155 return Arrays.asList("activateObject", "destroyObject", "makeObject", "passivateObject", "validateObject", "toString");
156 }
157
158 @Test
159 public void testCheckMinIdleKeyedObjectPool() throws InterruptedException {
160 assertThrows(IllegalArgumentException.class, () -> PoolUtils.checkMinIdle(null, new Object(), 1, 1),
161 "PoolUtils.checkMinIdle(KeyedObjectPool,Object,int,long) must not allow null pool.");
162 try (@SuppressWarnings("unchecked")
163 final KeyedObjectPool<Object, Object> pool = createProxy(KeyedObjectPool.class, (List<String>) null)) {
164 assertThrows(IllegalArgumentException.class, () -> PoolUtils.checkMinIdle(pool, (Object) null, 1, 1),
165 "PoolUtils.checkMinIdle(KeyedObjectPool,Object,int,long) must not accept null keys.");
166 }
167 try (@SuppressWarnings("unchecked")
168 final KeyedObjectPool<Object, Object> pool = createProxy(KeyedObjectPool.class, (List<String>) null)) {
169 assertThrows(IllegalArgumentException.class, () -> PoolUtils.checkMinIdle(pool, new Object(), -1, 1),
170 "PoolUtils.checkMinIdle(KeyedObjectPool,Object,int,long) must not accept negative min idle values.");
171 }
172
173 final List<String> calledMethods = new ArrayList<>();
174 final Object key = new Object();
175
176
177 @SuppressWarnings("unchecked")
178 final KeyedPooledObjectFactory<Object, Object> kpof = createProxy(KeyedPooledObjectFactory.class, calledMethods);
179 try (final KeyedObjectPool<Object, Object> kop = new GenericKeyedObjectPool<>(kpof)) {
180 PoolUtils.checkMinIdle(kop, key, 2, 100);
181 Thread.sleep(400);
182 assertEquals(2, kop.getNumIdle(key));
183 assertEquals(2, kop.getNumIdle());
184 }
185 int makeObjectCount = 0;
186 for (String methodName : calledMethods) {
187 if ("makeObject".equals(methodName)) {
188 makeObjectCount++;
189 }
190 }
191 assertEquals(2, makeObjectCount, "makeObject should have been called two time");
192
193
194 AssertionFailedError afe = null;
195 int triesLeft = 3;
196 do {
197 afe = null;
198 try {
199 calledMethods.clear();
200 try (@SuppressWarnings("unchecked")
201 final KeyedObjectPool<Object, Object> pool = createProxy(KeyedObjectPool.class, calledMethods)) {
202
203 final TimerTask task = PoolUtils.checkMinIdle(pool, key, 1, CHECK_PERIOD);
204
205 Thread.sleep(CHECK_SLEEP_PERIOD);
206 task.cancel();
207 task.toString();
208
209 final List<String> expectedMethods = new ArrayList<>();
210 for (int i = 0; i < CHECK_COUNT; i++) {
211 expectedMethods.add("getNumIdle");
212 expectedMethods.add("addObject");
213 }
214 expectedMethods.add("toString");
215 assertEquals(expectedMethods, calledMethods);
216 }
217 } catch (final AssertionFailedError e) {
218 afe = e;
219 }
220 } while (--triesLeft > 0 && afe != null);
221 if (afe != null) {
222 throw afe;
223 }
224 }
225
226 @Test
227 public void testCheckMinIdleKeyedObjectPoolKeys() throws InterruptedException {
228
229 AssertionFailedError afe = null;
230 int triesLeft = 3;
231 do {
232 afe = null;
233 final List<String> calledMethods = new ArrayList<>();
234 try (@SuppressWarnings("unchecked")
235 final KeyedObjectPool<String, Object> pool = createProxy(KeyedObjectPool.class, calledMethods)) {
236 final Collection<String> keys = new ArrayList<>(2);
237 keys.add("one");
238 keys.add("two");
239
240 final Map<String, TimerTask> tasks = PoolUtils.checkMinIdle(pool, keys, 1, CHECK_PERIOD);
241
242 Thread.sleep(CHECK_SLEEP_PERIOD);
243 for (final TimerTask task : tasks.values()) {
244 task.cancel();
245 }
246
247 final List<String> expectedMethods = new ArrayList<>();
248 for (int i = 0; i < CHECK_COUNT * keys.size(); i++) {
249 expectedMethods.add("getNumIdle");
250 expectedMethods.add("addObject");
251 }
252 assertEquals(expectedMethods, calledMethods);
253 } catch (final AssertionFailedError e) {
254 afe = e;
255 }
256 } while (--triesLeft > 0 && afe != null);
257 if (afe != null) {
258 throw afe;
259 }
260 }
261
262 @Test
263 public void testCheckMinIdleKeyedObjectPoolKeysNulls() {
264 try (@SuppressWarnings("unchecked")
265 final KeyedObjectPool<Object, Object> pool = createProxy(KeyedObjectPool.class, (List<String>) null)) {
266 assertThrows(IllegalArgumentException.class, () -> PoolUtils.checkMinIdle(pool, (Collection<?>) null, 1, 1),
267 "PoolUtils.checkMinIdle(KeyedObjectPool,Collection,int,long) must not accept null keys.");
268 }
269
270 try (@SuppressWarnings("unchecked")
271 final KeyedObjectPool<Object, Object> pool = createProxy(KeyedObjectPool.class, (List<String>) null)) {
272 PoolUtils.checkMinIdle(pool, (Collection<?>) Collections.emptyList(), 1, 1);
273 } catch (final IllegalArgumentException iae) {
274 fail("PoolUtils.checkMinIdle(KeyedObjectPool,Collection,int,long) must accept empty lists.");
275 }
276 }
277
278 @Test
279 public void testCheckMinIdleObjectPool() throws InterruptedException {
280 assertThrows(IllegalArgumentException.class, () -> PoolUtils.checkMinIdle(null, 1, 1),
281 "PoolUtils.checkMinIdle(ObjectPool,,) must not allow null pool.");
282 try (@SuppressWarnings("unchecked")
283 final ObjectPool<Object> pool = createProxy(ObjectPool.class, (List<String>) null)) {
284 assertThrows(IllegalArgumentException.class, () -> PoolUtils.checkMinIdle(pool, -1, 1),
285 "PoolUtils.checkMinIdle(ObjectPool,,) must not accept negative min idle values.");
286 }
287
288 final List<String> calledMethods = new ArrayList<>();
289
290
291 @SuppressWarnings("unchecked")
292 final PooledObjectFactory<Object> pof = createProxy(PooledObjectFactory.class, calledMethods);
293 try (final ObjectPool<Object> op = new GenericObjectPool<>(pof)) {
294 PoolUtils.checkMinIdle(op, 2, 100);
295 Thread.sleep(1000);
296 assertEquals(2, op.getNumIdle());
297 }
298 int makeObjectCount = 0;
299 for (String methodName : calledMethods) {
300 if ("makeObject".equals(methodName)) {
301 makeObjectCount++;
302 }
303 }
304 assertEquals(2, makeObjectCount, "makeObject should have been called two time");
305
306
307 AssertionFailedError afe = null;
308 int triesLeft = 3;
309 do {
310 afe = null;
311 try {
312 calledMethods.clear();
313 try (@SuppressWarnings("unchecked")
314 final ObjectPool<Object> pool = createProxy(ObjectPool.class, calledMethods)) {
315 final TimerTask task = PoolUtils.checkMinIdle(pool, 1, CHECK_PERIOD);
316
317 Thread.sleep(CHECK_SLEEP_PERIOD);
318 task.cancel();
319 task.toString();
320
321 final List<String> expectedMethods = new ArrayList<>();
322 for (int i = 0; i < CHECK_COUNT; i++) {
323 expectedMethods.add("getNumIdle");
324 expectedMethods.add("addObject");
325 }
326 expectedMethods.add("toString");
327 assertEquals(expectedMethods, calledMethods);
328 }
329 } catch (final AssertionFailedError e) {
330 afe = e;
331 }
332 } while (--triesLeft > 0 && afe != null);
333 if (afe != null) {
334 throw afe;
335 }
336 }
337
338 @Test
339 public void testCheckRethrow() {
340 try {
341 PoolUtils.checkRethrow(new Exception());
342 } catch (final Throwable t) {
343 fail("PoolUtils.checkRethrow(Throwable) must rethrow only ThreadDeath and VirtualMachineError.");
344 }
345 try {
346 PoolUtils.checkRethrow(new ThreadDeath());
347 fail("PoolUtils.checkRethrow(Throwable) must rethrow ThreadDeath.");
348 } catch (final ThreadDeath td) {
349
350 } catch (final Throwable t) {
351 fail("PoolUtils.checkRethrow(Throwable) must rethrow only ThreadDeath and VirtualMachineError.");
352 }
353 try {
354 PoolUtils.checkRethrow(new InternalError());
355 fail("PoolUtils.checkRethrow(Throwable) must rethrow VirtualMachineError.");
356 } catch (final VirtualMachineError td) {
357
358 } catch (final Throwable t) {
359 fail("PoolUtils.checkRethrow(Throwable) must rethrow only ThreadDeath and VirtualMachineError.");
360 }
361 }
362
363 @Test
364 public void testErodingObjectPoolDefaultFactor() {
365 try (@SuppressWarnings("unchecked")
366 final ObjectPool<Object> internalPool = createProxy(ObjectPool.class, (arg0, arg1, arg2) -> null);
367 final ObjectPool<Object> pool = PoolUtils.erodingPool(internalPool)) {
368 final String expectedToString = "ErodingObjectPool{factor=ErodingFactor{factor=1.0, idleHighWaterMark=1}, pool=" +
369 internalPool + "}";
370
371
372 assertEquals(expectedToString, pool.toString());
373 }
374 }
375
376 @Test
377 public void testErodingPerKeyKeyedObjectPool() throws Exception {
378 assertThrows(IllegalArgumentException.class, () -> PoolUtils.erodingPool((KeyedObjectPool<Object, Object>) null, 1f, true),
379 "PoolUtils.erodingPool(KeyedObjectPool) must not allow a null pool.");
380
381 assertThrows(IllegalArgumentException.class, () -> PoolUtils.erodingPool((KeyedObjectPool<Object, Object>) null, 0f, true),
382 "PoolUtils.erodingPool(ObjectPool, float, boolean) must not allow a non-positive factor.");
383
384 assertThrows(IllegalArgumentException.class, () -> PoolUtils.erodingPool((KeyedObjectPool<Object, Object>) null, 1f, true),
385 "PoolUtils.erodingPool(KeyedObjectPool, float, boolean) must not allow a null pool.");
386
387 final List<String> calledMethods = new ArrayList<>();
388 final InvocationHandler handler = new MethodCallLogger(calledMethods) {
389 @Override
390 public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
391 Object o = super.invoke(proxy, method, args);
392 if (o instanceof Integer) {
393
394 o = Integer.valueOf(1);
395 }
396 return o;
397 }
398 };
399
400
401 final float factor = 0.01f;
402 try (@SuppressWarnings("unchecked")
403 final KeyedObjectPool<Object, Object> pool = PoolUtils.erodingPool(createProxy(KeyedObjectPool.class, handler), factor, true)) {
404
405 final List<String> expectedMethods = new ArrayList<>();
406 assertEquals(expectedMethods, calledMethods);
407
408 final Object key = "key";
409
410 Object o = pool.borrowObject(key);
411 expectedMethods.add("borrowObject");
412
413 assertEquals(expectedMethods, calledMethods);
414
415 pool.returnObject(key, o);
416 expectedMethods.add("returnObject");
417 assertEquals(expectedMethods, calledMethods);
418
419 for (int i = 0; i < 5; i++) {
420 o = pool.borrowObject(key);
421 expectedMethods.add("borrowObject");
422
423 Thread.sleep(50);
424
425 pool.returnObject(key, o);
426 expectedMethods.add("returnObject");
427
428 assertEquals(expectedMethods, calledMethods);
429
430 expectedMethods.clear();
431 calledMethods.clear();
432 }
433
434 Thread.sleep(10000);
435
436 o = pool.borrowObject(key);
437 expectedMethods.add("borrowObject");
438 pool.returnObject(key, o);
439 expectedMethods.add("getNumIdle");
440 expectedMethods.add("invalidateObject");
441 assertEquals(expectedMethods, calledMethods);
442
443 final String expectedToString = "ErodingPerKeyKeyedObjectPool{factor=" + factor + ", keyedPool=null}";
444 assertEquals(expectedToString, pool.toString());
445 }
446 }
447
448 @Test
449 public void testErodingPoolKeyedObjectPool() throws Exception {
450 assertThrows(IllegalArgumentException.class, () -> PoolUtils.erodingPool((KeyedObjectPool<Object, Object>) null),
451 "PoolUtils.erodingPool(KeyedObjectPool) must not allow a null pool.");
452
453 assertThrows(IllegalArgumentException.class, () -> PoolUtils.erodingPool((KeyedObjectPool<Object, Object>) null, 1f),
454 "PoolUtils.erodingPool(KeyedObjectPool, float) must not allow a null pool.");
455
456 assertThrows(IllegalArgumentException.class, () -> PoolUtils.erodingPool((KeyedObjectPool<Object, Object>) null, 1f, true),
457 "PoolUtils.erodingPool(KeyedObjectPool, float, boolean) must not allow a null pool.");
458
459 final List<String> calledMethods = new ArrayList<>();
460 final InvocationHandler handler = new MethodCallLogger(calledMethods) {
461 @Override
462 public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
463 Object o = super.invoke(proxy, method, args);
464 if (o instanceof Integer) {
465
466 o = Integer.valueOf(1);
467 }
468 return o;
469 }
470 };
471
472 assertThrows(IllegalArgumentException.class, () -> PoolUtils.erodingPool(createProxy(KeyedObjectPool.class, handler), 0f),
473 "PoolUtils.erodingPool(ObjectPool, float) must not allow a non-positive factor.");
474
475 assertThrows(IllegalArgumentException.class, () -> PoolUtils.erodingPool(createProxy(KeyedObjectPool.class, handler), 0f, false),
476 "PoolUtils.erodingPool(ObjectPool, float, boolean) must not allow a non-positive factor.");
477
478
479 final float factor = 0.01f;
480 final List<String> expectedMethods = new ArrayList<>();
481 try (@SuppressWarnings("unchecked")
482 final KeyedObjectPool<Object, Object> pool = PoolUtils.erodingPool(createProxy(KeyedObjectPool.class, handler), factor)) {
483
484 assertEquals(expectedMethods, calledMethods);
485
486 final Object key = "key";
487
488 pool.addObject(key);
489 expectedMethods.add("addObject");
490
491 Object o = pool.borrowObject(key);
492 expectedMethods.add("borrowObject");
493
494 assertEquals(expectedMethods, calledMethods);
495
496 pool.returnObject(key, o);
497 expectedMethods.add("returnObject");
498 assertEquals(expectedMethods, calledMethods);
499
500
501 assertEquals(1, pool.getNumActive());
502 expectedMethods.add("getNumActive");
503 assertEquals(1, pool.getNumIdle());
504 expectedMethods.add("getNumIdle");
505
506 for (int i = 0; i < 5; i++) {
507 o = pool.borrowObject(key);
508 expectedMethods.add("borrowObject");
509
510 Thread.sleep(50);
511
512 pool.returnObject(key, o);
513 expectedMethods.add("returnObject");
514
515 assertEquals(expectedMethods, calledMethods);
516
517 expectedMethods.clear();
518 calledMethods.clear();
519 }
520
521 Thread.sleep(10000);
522
523 o = pool.borrowObject(key);
524 expectedMethods.add("borrowObject");
525 pool.returnObject(key, o);
526 expectedMethods.add("getNumIdle");
527 expectedMethods.add("invalidateObject");
528 pool.clear();
529 }
530 expectedMethods.add("clear");
531 expectedMethods.add("close");
532 assertEquals(expectedMethods, calledMethods);
533 }
534
535 @Test
536 public void testErodingPoolKeyedObjectPoolDefaultFactor() {
537 try (@SuppressWarnings("unchecked")
538 final KeyedObjectPool<Object, Object> internalPool = createProxy(KeyedObjectPool.class,
539 (arg0, arg1, arg2) -> null);
540 final KeyedObjectPool<Object, Object> pool = PoolUtils.erodingPool(internalPool)) {
541 final String expectedToString = "ErodingKeyedObjectPool{factor=ErodingFactor{factor=1.0, idleHighWaterMark=1}, keyedPool=" +
542 internalPool + "}";
543
544
545 assertEquals(expectedToString, pool.toString());
546 }
547 }
548
549 @Test
550 public void testErodingPoolObjectPool() throws Exception {
551 assertThrows(IllegalArgumentException.class, () -> PoolUtils.erodingPool((ObjectPool<Object>) null),
552 "PoolUtils.erodingPool(ObjectPool) must not allow a null pool.");
553
554 assertThrows(IllegalArgumentException.class, () -> PoolUtils.erodingPool((ObjectPool<Object>) null, 1f),
555 "PoolUtils.erodingPool(ObjectPool, float) must not allow a null pool.");
556
557 final List<String> calledMethods = new ArrayList<>();
558 final InvocationHandler handler = new MethodCallLogger(calledMethods) {
559 @Override
560 public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
561 Object o = super.invoke(proxy, method, args);
562 if (o instanceof Integer) {
563
564 o = Integer.valueOf(1);
565 }
566 return o;
567 }
568 };
569
570 assertThrows(IllegalArgumentException.class, () -> PoolUtils.erodingPool(createProxy(ObjectPool.class, handler), -1f),
571 "PoolUtils.erodingPool(ObjectPool, float) must not allow a non-positive factor.");
572
573
574 final float factor = 0.01f;
575 final List<String> expectedMethods = new ArrayList<>();
576 try (@SuppressWarnings("unchecked")
577 final ObjectPool<Object> pool = PoolUtils.erodingPool(createProxy(ObjectPool.class, handler), factor)) {
578
579 assertEquals(expectedMethods, calledMethods);
580
581 pool.addObject();
582 expectedMethods.add("addObject");
583
584 Object o = pool.borrowObject();
585 expectedMethods.add("borrowObject");
586
587 assertEquals(expectedMethods, calledMethods);
588
589 pool.returnObject(o);
590 expectedMethods.add("returnObject");
591 assertEquals(expectedMethods, calledMethods);
592
593
594 assertEquals(1, pool.getNumActive());
595 expectedMethods.add("getNumActive");
596 assertEquals(1, pool.getNumIdle());
597 expectedMethods.add("getNumIdle");
598
599 for (int i = 0; i < 5; i++) {
600 o = pool.borrowObject();
601 expectedMethods.add("borrowObject");
602
603 Thread.sleep(50);
604
605 pool.returnObject(o);
606 expectedMethods.add("returnObject");
607
608 assertEquals(expectedMethods, calledMethods);
609
610 expectedMethods.clear();
611 calledMethods.clear();
612 }
613
614 Thread.sleep(10000);
615
616 o = pool.borrowObject();
617 expectedMethods.add("borrowObject");
618 pool.returnObject(o);
619 expectedMethods.add("getNumIdle");
620 expectedMethods.add("invalidateObject");
621 pool.clear();
622 }
623 expectedMethods.add("clear");
624 expectedMethods.add("close");
625 assertEquals(expectedMethods, calledMethods);
626 }
627
628 @Test
629 public void testJavaBeanInstantiation() {
630 assertNotNull(new PoolUtils());
631 }
632
633 @SuppressWarnings("deprecation")
634 @Test
635 public void testPrefillKeyedObjectPool() throws Exception {
636 assertThrows(IllegalArgumentException.class, () -> PoolUtils.prefill(null, new Object(), 1),
637 "PoolUtils.prefill(KeyedObjectPool,Object,int) must not accept null pool.");
638
639 try (final KeyedObjectPool<Object, String> pool = new GenericKeyedObjectPool<>(new TestGenericKeyedObjectPool.SimpleFactory<>())) {
640 assertThrows(IllegalArgumentException.class, () -> PoolUtils.prefill(pool, (Object) null, 1),
641 "PoolUtils.prefill(KeyedObjectPool,Object,int) must not accept null key.");
642 }
643
644 final List<String> calledMethods = new ArrayList<>();
645 try (@SuppressWarnings("unchecked")
646 final KeyedObjectPool<Object, Object> pool = createProxy(KeyedObjectPool.class, calledMethods)) {
647
648 PoolUtils.prefill(pool, new Object(), 0);
649 final List<String> expectedMethods = new ArrayList<>();
650 expectedMethods.add("addObjects");
651 assertEquals(expectedMethods, calledMethods);
652
653 calledMethods.clear();
654 PoolUtils.prefill(pool, new Object(), 3);
655 assertEquals(expectedMethods, calledMethods);
656 }
657 }
658
659 @SuppressWarnings("deprecation")
660 @Test
661 public void testPrefillKeyedObjectPoolCollection() throws Exception {
662 try (@SuppressWarnings("unchecked")
663 final KeyedObjectPool<String, String> pool = createProxy(KeyedObjectPool.class, (List<String>) null)) {
664 assertThrows(IllegalArgumentException.class, () -> PoolUtils.prefill(pool, (Collection<String>) null, 1),
665 "PoolUtils.prefill(KeyedObjectPool,Collection,int) must not accept null keys.");
666 }
667
668 final List<String> calledMethods = new ArrayList<>();
669 try (@SuppressWarnings("unchecked")
670 final KeyedObjectPool<String, Object> pool = createProxy(KeyedObjectPool.class, calledMethods)) {
671
672 final Set<String> keys = new HashSet<>();
673 PoolUtils.prefill(pool, keys, 0);
674 final List<String> expectedMethods = new ArrayList<>();
675 expectedMethods.add("addObjects");
676 assertEquals(expectedMethods, calledMethods);
677
678 calledMethods.clear();
679 keys.add("one");
680 keys.add("two");
681 keys.add("three");
682 final int count = 3;
683 PoolUtils.prefill(pool, keys, count);
684 assertEquals(expectedMethods, calledMethods);
685 }
686 }
687
688 @SuppressWarnings("deprecation")
689 @Test
690 public void testPrefillObjectPool() throws Exception {
691 assertThrows(IllegalArgumentException.class, () -> PoolUtils.prefill(null, 1), "PoolUtils.prefill(ObjectPool,int) must not allow null pool.");
692
693 final List<String> calledMethods = new ArrayList<>();
694 try (@SuppressWarnings("unchecked")
695 final ObjectPool<Object> pool = createProxy(ObjectPool.class, calledMethods)) {
696
697 PoolUtils.prefill(pool, 0);
698 final List<String> expectedMethods = new ArrayList<>();
699 expectedMethods.add("addObjects");
700 assertEquals(expectedMethods, calledMethods);
701
702 calledMethods.clear();
703 PoolUtils.prefill(pool, 3);
704 assertEquals(expectedMethods, calledMethods);
705 }
706 }
707
708 @Test
709 public void testSynchronizedPoolableFactoryKeyedPooledObjectFactory() throws Exception {
710 assertThrows(IllegalArgumentException.class,
711 () -> PoolUtils.synchronizedKeyedPooledFactory((KeyedPooledObjectFactory<Object, Object>) null),
712 "PoolUtils.synchronizedPoolableFactory(KeyedPooledObjectFactory) must not allow a null factory.");
713
714 final List<String> calledMethods = new ArrayList<>();
715 @SuppressWarnings("unchecked")
716 final KeyedPooledObjectFactory<Object, Object> kpof = createProxy(KeyedPooledObjectFactory.class, calledMethods);
717
718 final KeyedPooledObjectFactory<Object, Object> skpof = PoolUtils.synchronizedKeyedPooledFactory(kpof);
719 final List<String> expectedMethods = invokeEveryMethod(skpof);
720 assertEquals(expectedMethods, calledMethods);
721
722
723 }
724
725 @Test
726 public void testSynchronizedPoolableFactoryPoolableObjectFactory() throws Exception {
727 assertThrows(IllegalArgumentException.class, () -> PoolUtils.synchronizedPooledFactory((PooledObjectFactory<Object>) null),
728 "PoolUtils.synchronizedPoolableFactory(PoolableObjectFactory) must not allow a null factory.");
729
730 final List<String> calledMethods = new ArrayList<>();
731 @SuppressWarnings("unchecked")
732 final PooledObjectFactory<Object> pof = createProxy(PooledObjectFactory.class, calledMethods);
733
734 final PooledObjectFactory<Object> spof = PoolUtils.synchronizedPooledFactory(pof);
735 final List<String> expectedMethods = invokeEveryMethod(spof);
736 assertEquals(expectedMethods, calledMethods);
737
738
739 }
740
741 @Test
742 public void testSynchronizedPoolKeyedObjectPool() throws Exception {
743 assertThrows(IllegalArgumentException.class, () -> PoolUtils.synchronizedPool((KeyedObjectPool<Object, Object>) null),
744 "PoolUtils.synchronizedPool(KeyedObjectPool) must not allow a null pool.");
745
746 final List<String> calledMethods = new ArrayList<>();
747 try (@SuppressWarnings("unchecked")
748 final KeyedObjectPool<Object, Object> kop = createProxy(KeyedObjectPool.class, calledMethods);
749 final KeyedObjectPool<Object, Object> skop = PoolUtils.synchronizedPool(kop)) {
750 final List<String> expectedMethods = invokeEveryMethod(skop);
751 assertEquals(expectedMethods, calledMethods);
752 }
753
754
755 }
756
757 @Test
758 public void testSynchronizedPoolObjectPool() throws Exception {
759 assertThrows(IllegalArgumentException.class, () -> PoolUtils.synchronizedPool((ObjectPool<Object>) null),
760 "PoolUtils.synchronizedPool(ObjectPool) must not allow a null pool.");
761
762 final List<String> calledMethods = new ArrayList<>();
763 try (@SuppressWarnings("unchecked")
764 final ObjectPool<Object> op = createProxy(ObjectPool.class, calledMethods); final ObjectPool<Object> sop = PoolUtils.synchronizedPool(op)) {
765 final List<String> expectedMethods = invokeEveryMethod(sop);
766 assertEquals(expectedMethods, calledMethods);
767
768
769 }
770 }
771
772
773
774
775 @Test
776 public void testTimerHolder() {
777 final PoolUtils.TimerHolder h = new PoolUtils.TimerHolder();
778 assertNotNull(h);
779 assertNotNull(PoolUtils.TimerHolder.MIN_IDLE_TIMER);
780 }
781 }