1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.pool2;
18
19 import static org.junit.jupiter.api.Assertions.assertEquals;
20 import static org.junit.jupiter.api.Assertions.assertThrows;
21 import static org.junit.jupiter.api.Assertions.fail;
22
23 import java.util.ArrayList;
24 import java.util.List;
25 import java.util.NoSuchElementException;
26
27 import org.apache.commons.pool2.impl.DefaultPooledObject;
28 import org.apache.commons.pool2.impl.GenericKeyedObjectPool;
29 import org.junit.jupiter.api.AfterEach;
30 import org.junit.jupiter.api.Test;
31
32
33
34
35 public abstract class AbstractTestKeyedObjectPool {
36
37 protected static class FailingKeyedPooledObjectFactory implements KeyedPooledObjectFactory<Object, Object> {
38 private final List<MethodCall> methodCalls = new ArrayList<>();
39 private int count;
40 private boolean makeObjectFail;
41 private boolean activateObjectFail;
42 private boolean validateObjectFail;
43 private boolean passivateObjectFail;
44 private boolean destroyObjectFail;
45
46 public FailingKeyedPooledObjectFactory() {
47 }
48
49 @Override
50 public void activateObject(final Object key, final PooledObject<Object> obj) {
51 methodCalls.add(new MethodCall("activateObject", key, obj.getObject()));
52 if (activateObjectFail) {
53 throw new PrivateException("activateObject");
54 }
55 }
56
57 @Override
58 public void destroyObject(final Object key, final PooledObject<Object> obj) {
59 methodCalls.add(new MethodCall("destroyObject", key, obj.getObject()));
60 if (destroyObjectFail) {
61 throw new PrivateException("destroyObject");
62 }
63 }
64
65 public int getCurrentCount() {
66 return count;
67 }
68
69 public List<MethodCall> getMethodCalls() {
70 return methodCalls;
71 }
72
73 public boolean isActivateObjectFail() {
74 return activateObjectFail;
75 }
76
77 public boolean isDestroyObjectFail() {
78 return destroyObjectFail;
79 }
80
81 public boolean isMakeObjectFail() {
82 return makeObjectFail;
83 }
84
85 public boolean isPassivateObjectFail() {
86 return passivateObjectFail;
87 }
88
89 public boolean isValidateObjectFail() {
90 return validateObjectFail;
91 }
92
93 @Override
94 public PooledObject<Object> makeObject(final Object key) {
95 final MethodCall call = new MethodCall("makeObject", key);
96 methodCalls.add(call);
97 final int originalCount = this.count++;
98 if (makeObjectFail) {
99 throw new PrivateException("makeObject");
100 }
101
102
103 final Integer obj = Integer.valueOf(originalCount);
104 call.setReturned(obj);
105 return new DefaultPooledObject<>(obj);
106 }
107
108 @Override
109 public void passivateObject(final Object key, final PooledObject<Object> obj) {
110 methodCalls.add(new MethodCall("passivateObject", key, obj.getObject()));
111 if (passivateObjectFail) {
112 throw new PrivateException("passivateObject");
113 }
114 }
115
116 public void reset() {
117 count = 0;
118 getMethodCalls().clear();
119 setMakeObjectFail(false);
120 setActivateObjectFail(false);
121 setValidateObjectFail(false);
122 setPassivateObjectFail(false);
123 setDestroyObjectFail(false);
124 }
125
126 public void setActivateObjectFail(final boolean activateObjectFail) {
127 this.activateObjectFail = activateObjectFail;
128 }
129
130 public void setCurrentCount(final int count) {
131 this.count = count;
132 }
133
134 public void setDestroyObjectFail(final boolean destroyObjectFail) {
135 this.destroyObjectFail = destroyObjectFail;
136 }
137
138 public void setMakeObjectFail(final boolean makeObjectFail) {
139 this.makeObjectFail = makeObjectFail;
140 }
141
142 public void setPassivateObjectFail(final boolean passivateObjectFail) {
143 this.passivateObjectFail = passivateObjectFail;
144 }
145
146 public void setValidateObjectFail(final boolean validateObjectFail) {
147 this.validateObjectFail = validateObjectFail;
148 }
149
150 @Override
151 public boolean validateObject(final Object key, final PooledObject<Object> obj) {
152 final MethodCall call = new MethodCall("validateObject", key, obj.getObject());
153 methodCalls.add(call);
154 if (validateObjectFail) {
155 throw new PrivateException("validateObject");
156 }
157 final boolean r = true;
158 call.returned(Boolean.valueOf(r));
159 return r;
160 }
161 }
162
163 private static class TestFactory extends BaseKeyedPooledObjectFactory<Object, Object> {
164 @Override
165 public Object create(final Object key) {
166 return new Object();
167 }
168
169 @Override
170 public PooledObject<Object> wrap(final Object value) {
171 return new DefaultPooledObject<>(value);
172 }
173 }
174
175 protected static final String KEY = "key";
176
177 private KeyedObjectPool<Object, Object> pool;
178
179
180
181 private final Integer ZERO = Integer.valueOf(0);
182
183 private final Integer ONE = Integer.valueOf(1);
184
185 private void clear(final FailingKeyedPooledObjectFactory factory, final List<MethodCall> expectedMethods) {
186 factory.getMethodCalls().clear();
187 expectedMethods.clear();
188 }
189
190
191
192
193
194
195
196
197
198
199
200 protected abstract Object getNthObject(Object key, int n);
201
202 protected abstract boolean isFifo();
203
204 protected abstract boolean isLifo();
205
206
207
208
209
210
211
212
213
214
215
216
217 protected abstract <E extends Exception> KeyedObjectPool<Object, Object> makeEmptyPool(int minCapacity);
218
219
220
221
222
223
224
225
226
227
228
229 protected abstract <E extends Exception> KeyedObjectPool<Object, Object> makeEmptyPool(
230 KeyedPooledObjectFactory<Object, Object> factory);
231
232 protected abstract Object makeKey(int n);
233
234 private <E extends Exception> void reset(final KeyedObjectPool<Object, Object> pool,
235 final FailingKeyedPooledObjectFactory factory,
236 final List<MethodCall> expectedMethods) throws Exception {
237 pool.clear();
238 clear(factory, expectedMethods);
239 factory.reset();
240 }
241
242 @AfterEach
243 public void tearDown() {
244 pool = null;
245 }
246
247 @Test
248 public void testBaseAddObject() throws Exception {
249 try {
250 pool = makeEmptyPool(3);
251 } catch (final UnsupportedOperationException uoe) {
252 return;
253 }
254 final Object key = makeKey(0);
255 try {
256 assertEquals(0, pool.getNumIdle());
257 assertEquals(0, pool.getNumActive());
258 assertEquals(0, pool.getNumIdle(key));
259 assertEquals(0, pool.getNumActive(key));
260 pool.addObject(key);
261 assertEquals(1, pool.getNumIdle());
262 assertEquals(0, pool.getNumActive());
263 assertEquals(1, pool.getNumIdle(key));
264 assertEquals(0, pool.getNumActive(key));
265 final Object obj = pool.borrowObject(key);
266 assertEquals(getNthObject(key, 0), obj);
267 assertEquals(0, pool.getNumIdle());
268 assertEquals(1, pool.getNumActive());
269 assertEquals(0, pool.getNumIdle(key));
270 assertEquals(1, pool.getNumActive(key));
271 pool.returnObject(key, obj);
272 assertEquals(1, pool.getNumIdle());
273 assertEquals(0, pool.getNumActive());
274 assertEquals(1, pool.getNumIdle(key));
275 assertEquals(0, pool.getNumActive(key));
276 } catch (final UnsupportedOperationException e) {
277 return;
278 } finally {
279 pool.close();
280 }
281 }
282
283 @Test
284 public void testBaseBorrow() throws Exception {
285 try {
286 pool = makeEmptyPool(3);
287 } catch (final UnsupportedOperationException uoe) {
288 return;
289 }
290 final Object keya = makeKey(0);
291 final Object keyb = makeKey(1);
292 assertEquals(getNthObject(keya, 0), pool.borrowObject(keya), "1");
293 assertEquals(getNthObject(keyb, 0), pool.borrowObject(keyb), "2");
294 assertEquals(getNthObject(keyb, 1), pool.borrowObject(keyb), "3");
295 assertEquals(getNthObject(keya, 1), pool.borrowObject(keya), "4");
296 assertEquals(getNthObject(keyb, 2), pool.borrowObject(keyb), "5");
297 assertEquals(getNthObject(keya, 2), pool.borrowObject(keya), "6");
298 pool.close();
299 }
300
301 @Test
302 public void testBaseBorrowReturn() throws Exception {
303 try {
304 pool = makeEmptyPool(3);
305 } catch (final UnsupportedOperationException uoe) {
306 return;
307 }
308 final Object keya = makeKey(0);
309 Object obj0 = pool.borrowObject(keya);
310 assertEquals(getNthObject(keya, 0), obj0);
311 Object obj1 = pool.borrowObject(keya);
312 assertEquals(getNthObject(keya, 1), obj1);
313 Object obj2 = pool.borrowObject(keya);
314 assertEquals(getNthObject(keya, 2), obj2);
315 pool.returnObject(keya, obj2);
316 obj2 = pool.borrowObject(keya);
317 assertEquals(getNthObject(keya, 2), obj2);
318 pool.returnObject(keya, obj1);
319 obj1 = pool.borrowObject(keya);
320 assertEquals(getNthObject(keya, 1), obj1);
321 pool.returnObject(keya, obj0);
322 pool.returnObject(keya, obj2);
323 obj2 = pool.borrowObject(keya);
324 if (isLifo()) {
325 assertEquals(getNthObject(keya, 2), obj2);
326 }
327 if (isFifo()) {
328 assertEquals(getNthObject(keya, 0), obj2);
329 }
330 obj0 = pool.borrowObject(keya);
331 if (isLifo()) {
332 assertEquals(getNthObject(keya, 0), obj0);
333 }
334 if (isFifo()) {
335 assertEquals(getNthObject(keya, 2), obj0);
336 }
337 pool.close();
338 }
339
340 @Test
341 public void testBaseClear() throws Exception {
342 try {
343 pool = makeEmptyPool(3);
344 } catch (final UnsupportedOperationException uoe) {
345 return;
346 }
347 final Object keya = makeKey(0);
348 assertEquals(0, pool.getNumActive(keya));
349 assertEquals(0, pool.getNumIdle(keya));
350 final Object obj0 = pool.borrowObject(keya);
351 final Object obj1 = pool.borrowObject(keya);
352 assertEquals(2, pool.getNumActive(keya));
353 assertEquals(0, pool.getNumIdle(keya));
354 pool.returnObject(keya, obj1);
355 pool.returnObject(keya, obj0);
356 assertEquals(0, pool.getNumActive(keya));
357 assertEquals(2, pool.getNumIdle(keya));
358 pool.clear(keya);
359 assertEquals(0, pool.getNumActive(keya));
360 assertEquals(0, pool.getNumIdle(keya));
361 final Object obj2 = pool.borrowObject(keya);
362 assertEquals(getNthObject(keya, 2), obj2);
363 pool.close();
364 }
365
366 @Test
367 public void testBaseInvalidateObject() throws Exception {
368 try {
369 pool = makeEmptyPool(3);
370 } catch (final UnsupportedOperationException uoe) {
371 return;
372 }
373 final Object keya = makeKey(0);
374 assertEquals(0, pool.getNumActive(keya));
375 assertEquals(0, pool.getNumIdle(keya));
376 final Object obj0 = pool.borrowObject(keya);
377 final Object obj1 = pool.borrowObject(keya);
378 assertEquals(2, pool.getNumActive(keya));
379 assertEquals(0, pool.getNumIdle(keya));
380 pool.invalidateObject(keya, obj0);
381 assertEquals(1, pool.getNumActive(keya));
382 assertEquals(0, pool.getNumIdle(keya));
383 pool.invalidateObject(keya, obj1);
384 assertEquals(0, pool.getNumActive(keya));
385 assertEquals(0, pool.getNumIdle(keya));
386 pool.close();
387 }
388
389 @Test
390 public void testBaseNumActiveNumIdle() throws Exception {
391 try {
392 pool = makeEmptyPool(3);
393 } catch (final UnsupportedOperationException uoe) {
394 return;
395 }
396 final Object keya = makeKey(0);
397 assertEquals(0, pool.getNumActive(keya));
398 assertEquals(0, pool.getNumIdle(keya));
399 final Object obj0 = pool.borrowObject(keya);
400 assertEquals(1, pool.getNumActive(keya));
401 assertEquals(0, pool.getNumIdle(keya));
402 final Object obj1 = pool.borrowObject(keya);
403 assertEquals(2, pool.getNumActive(keya));
404 assertEquals(0, pool.getNumIdle(keya));
405 pool.returnObject(keya, obj1);
406 assertEquals(1, pool.getNumActive(keya));
407 assertEquals(1, pool.getNumIdle(keya));
408 pool.returnObject(keya, obj0);
409 assertEquals(0, pool.getNumActive(keya));
410 assertEquals(2, pool.getNumIdle(keya));
411
412 assertEquals(0, pool.getNumActive("xyzzy12345"));
413 assertEquals(0, pool.getNumIdle("xyzzy12345"));
414
415 pool.close();
416 }
417
418 @Test
419 public void testBaseNumActiveNumIdle2() throws Exception {
420 try {
421 pool = makeEmptyPool(6);
422 } catch (final UnsupportedOperationException uoe) {
423 return;
424 }
425 final Object keya = makeKey(0);
426 final Object keyb = makeKey(1);
427 assertEquals(0, pool.getNumActive());
428 assertEquals(0, pool.getNumIdle());
429 assertEquals(0, pool.getNumActive(keya));
430 assertEquals(0, pool.getNumIdle(keya));
431 assertEquals(0, pool.getNumActive(keyb));
432 assertEquals(0, pool.getNumIdle(keyb));
433
434 final Object objA0 = pool.borrowObject(keya);
435 final Object objB0 = pool.borrowObject(keyb);
436
437 assertEquals(2, pool.getNumActive());
438 assertEquals(0, pool.getNumIdle());
439 assertEquals(1, pool.getNumActive(keya));
440 assertEquals(0, pool.getNumIdle(keya));
441 assertEquals(1, pool.getNumActive(keyb));
442 assertEquals(0, pool.getNumIdle(keyb));
443
444 final Object objA1 = pool.borrowObject(keya);
445 final Object objB1 = pool.borrowObject(keyb);
446
447 assertEquals(4, pool.getNumActive());
448 assertEquals(0, pool.getNumIdle());
449 assertEquals(2, pool.getNumActive(keya));
450 assertEquals(0, pool.getNumIdle(keya));
451 assertEquals(2, pool.getNumActive(keyb));
452 assertEquals(0, pool.getNumIdle(keyb));
453
454 pool.returnObject(keya, objA0);
455 pool.returnObject(keyb, objB0);
456
457 assertEquals(2, pool.getNumActive());
458 assertEquals(2, pool.getNumIdle());
459 assertEquals(1, pool.getNumActive(keya));
460 assertEquals(1, pool.getNumIdle(keya));
461 assertEquals(1, pool.getNumActive(keyb));
462 assertEquals(1, pool.getNumIdle(keyb));
463
464 pool.returnObject(keya, objA1);
465 pool.returnObject(keyb, objB1);
466
467 assertEquals(0, pool.getNumActive());
468 assertEquals(4, pool.getNumIdle());
469 assertEquals(0, pool.getNumActive(keya));
470 assertEquals(2, pool.getNumIdle(keya));
471 assertEquals(0, pool.getNumActive(keyb));
472 assertEquals(2, pool.getNumIdle(keyb));
473
474 pool.close();
475 }
476
477 @Test
478 public void testClosedPoolBehavior() throws Exception {
479 final KeyedObjectPool<Object, Object> pool;
480 try {
481 pool = makeEmptyPool(new TestFactory());
482 } catch (final UnsupportedOperationException uoe) {
483 return;
484 }
485
486 final Object o1 = pool.borrowObject(KEY);
487 final Object o2 = pool.borrowObject(KEY);
488
489 pool.close();
490
491 assertThrows(IllegalStateException.class, () -> pool.addObject(KEY),
492 "A closed pool must throw an IllegalStateException when addObject is called.");
493
494 assertThrows(IllegalStateException.class, () -> pool.borrowObject(KEY),
495 "A closed pool must throw an IllegalStateException when borrowObject is called.");
496
497
498 assertEquals(0, pool.getNumIdle(KEY), "A closed pool shouldn't have any idle objects.");
499 assertEquals(0, pool.getNumIdle(), "A closed pool shouldn't have any idle objects.");
500 pool.getNumActive();
501 pool.getNumActive(KEY);
502 pool.returnObject(KEY, o1);
503 assertEquals(0, pool.getNumIdle(KEY),
504 "returnObject should not add items back into the idle object pool for a closed pool.");
505 assertEquals(0, pool.getNumIdle(),
506 "returnObject should not add items back into the idle object pool for a closed pool.");
507 pool.invalidateObject(KEY, o2);
508 pool.clear(KEY);
509 pool.clear();
510 pool.close();
511 }
512
513 @Test
514 public void testKPOFAddObjectUsage() throws Exception {
515 final FailingKeyedPooledObjectFactory factory = new FailingKeyedPooledObjectFactory();
516 final KeyedObjectPool<Object, Object> pool;
517 try {
518 pool = makeEmptyPool(factory);
519 } catch (final UnsupportedOperationException uoe) {
520 return;
521 }
522 final List<MethodCall> expectedMethods = new ArrayList<>();
523
524
525 pool.addObject(KEY);
526 expectedMethods.add(new MethodCall("makeObject", KEY).returned(ZERO));
527 expectedMethods.add(new MethodCall("passivateObject", KEY, ZERO));
528 assertEquals(expectedMethods, factory.getMethodCalls());
529
530
531 reset(pool, factory, expectedMethods);
532
533
534 factory.setMakeObjectFail(true);
535 assertThrows(PrivateException.class, () -> pool.addObject(KEY),
536 "Expected addObject to propagate makeObject exception.");
537 expectedMethods.add(new MethodCall("makeObject", KEY));
538 assertEquals(expectedMethods, factory.getMethodCalls());
539
540 clear(factory, expectedMethods);
541
542
543 factory.setMakeObjectFail(false);
544 factory.setPassivateObjectFail(true);
545 assertThrows(PrivateException.class, () -> pool.addObject(KEY),
546 "Expected addObject to propagate passivateObject exception.");
547 expectedMethods.add(new MethodCall("makeObject", KEY).returned(ONE));
548 expectedMethods.add(new MethodCall("passivateObject", KEY, ONE));
549 assertEquals(expectedMethods, factory.getMethodCalls());
550 pool.close();
551 }
552
553 @Test
554 public void testKPOFBorrowObjectUsages() throws Exception {
555 final FailingKeyedPooledObjectFactory factory = new FailingKeyedPooledObjectFactory();
556 final KeyedObjectPool<Object, Object> pool;
557 try {
558 pool = makeEmptyPool(factory);
559 } catch (final UnsupportedOperationException uoe) {
560 return;
561 }
562 final List<MethodCall> expectedMethods = new ArrayList<>();
563 Object obj;
564
565 if (pool instanceof GenericKeyedObjectPool) {
566 ((GenericKeyedObjectPool<Object, Object>) pool).setTestOnBorrow(true);
567 }
568
569
570
571
572 pool.addObject(KEY);
573 clear(factory, expectedMethods);
574 obj = pool.borrowObject(KEY);
575 expectedMethods.add(new MethodCall("activateObject", KEY, ZERO));
576 expectedMethods.add(new MethodCall("validateObject", KEY, ZERO).returned(Boolean.TRUE));
577 assertEquals(expectedMethods, factory.getMethodCalls());
578 pool.returnObject(KEY, obj);
579
580
581 reset(pool, factory, expectedMethods);
582
583
584 factory.setMakeObjectFail(true);
585 assertThrows(PrivateException.class, () -> pool.borrowObject(KEY),
586 "Expected borrowObject to propagate makeObject exception.");
587 expectedMethods.add(new MethodCall("makeObject", KEY));
588 assertEquals(expectedMethods, factory.getMethodCalls());
589
590
591
592 reset(pool, factory, expectedMethods);
593 pool.addObject(KEY);
594 clear(factory, expectedMethods);
595
596 factory.setActivateObjectFail(true);
597 expectedMethods.add(new MethodCall("activateObject", KEY, obj));
598 assertThrows(NoSuchElementException.class, () -> pool.borrowObject(KEY));
599
600
601 expectedMethods.add(new MethodCall("makeObject", KEY).returned(ONE));
602 expectedMethods.add(new MethodCall("activateObject", KEY, ONE));
603 AbstractTestObjectPool.removeDestroyObjectCall(factory.getMethodCalls());
604
605 assertEquals(expectedMethods, factory.getMethodCalls());
606
607
608
609 reset(pool, factory, expectedMethods);
610 pool.addObject(KEY);
611 clear(factory, expectedMethods);
612
613 factory.setValidateObjectFail(true);
614
615
616 assertThrows(NoSuchElementException.class, () -> pool.borrowObject(KEY));
617
618 expectedMethods.add(new MethodCall("activateObject", KEY, ZERO));
619 expectedMethods.add(new MethodCall("validateObject", KEY, ZERO));
620
621 expectedMethods.add(new MethodCall("makeObject", KEY).returned(ONE));
622 expectedMethods.add(new MethodCall("activateObject", KEY, ONE));
623 expectedMethods.add(new MethodCall("validateObject", KEY, ONE));
624 AbstractTestObjectPool.removeDestroyObjectCall(factory.getMethodCalls());
625 assertEquals(expectedMethods, factory.getMethodCalls());
626 pool.close();
627 }
628
629 @Test
630 public void testKPOFClearUsages() throws Exception {
631 final FailingKeyedPooledObjectFactory factory = new FailingKeyedPooledObjectFactory();
632 final KeyedObjectPool<Object, Object> pool;
633 try {
634 pool = makeEmptyPool(factory);
635 } catch (final UnsupportedOperationException uoe) {
636 return;
637 }
638 final List<MethodCall> expectedMethods = new ArrayList<>();
639
640
641 pool.addObjects(KEY, 5);
642 pool.clear();
643
644
645 reset(pool, factory, expectedMethods);
646 factory.setDestroyObjectFail(true);
647 pool.addObjects(KEY, 5);
648 pool.clear();
649 pool.close();
650 }
651
652 @Test
653 public void testKPOFCloseUsages() throws Exception {
654 final FailingKeyedPooledObjectFactory factory = new FailingKeyedPooledObjectFactory();
655 KeyedObjectPool<Object, Object> pool;
656 try {
657 pool = makeEmptyPool(factory);
658 } catch (final UnsupportedOperationException uoe) {
659 return;
660 }
661 final List<MethodCall> expectedMethods = new ArrayList<>();
662
663
664 pool.addObjects(KEY, 5);
665 pool.close();
666
667
668 try (final KeyedObjectPool<Object, Object> pool2 = makeEmptyPool(factory)) {
669 reset(pool2, factory, expectedMethods);
670 factory.setDestroyObjectFail(true);
671 pool2.addObjects(KEY, 5);
672 }
673 }
674
675 @Test
676 public void testKPOFInvalidateObjectUsages() throws Exception {
677 final FailingKeyedPooledObjectFactory factory = new FailingKeyedPooledObjectFactory();
678 final KeyedObjectPool<Object, Object> pool;
679 try {
680 pool = makeEmptyPool(factory);
681 } catch (final UnsupportedOperationException uoe) {
682 return;
683 }
684 final List<MethodCall> expectedMethods = new ArrayList<>();
685 Object obj;
686
687
688
689 obj = pool.borrowObject(KEY);
690 clear(factory, expectedMethods);
691
692
693 pool.invalidateObject(KEY, obj);
694 expectedMethods.add(new MethodCall("destroyObject", KEY, obj));
695 assertEquals(expectedMethods, factory.getMethodCalls());
696
697
698 reset(pool, factory, expectedMethods);
699 final Object obj2 = pool.borrowObject(KEY);
700 clear(factory, expectedMethods);
701 factory.setDestroyObjectFail(true);
702 assertThrows(PrivateException.class, () -> pool.invalidateObject(KEY, obj2),
703 "Expecting destroy exception to propagate");
704 Thread.sleep(250);
705 AbstractTestObjectPool.removeDestroyObjectCall(factory.getMethodCalls());
706 assertEquals(expectedMethods, factory.getMethodCalls());
707 pool.close();
708 }
709
710 @Test
711 public void testKPOFReturnObjectUsages() throws Exception {
712 final FailingKeyedPooledObjectFactory factory = new FailingKeyedPooledObjectFactory();
713 final KeyedObjectPool<Object, Object> pool;
714 try {
715 pool = makeEmptyPool(factory);
716 } catch (final UnsupportedOperationException uoe) {
717 return;
718 }
719 final List<MethodCall> expectedMethods = new ArrayList<>();
720 Object obj;
721
722
723 obj = pool.borrowObject(KEY);
724 clear(factory, expectedMethods);
725
726
727 pool.returnObject(KEY, obj);
728 expectedMethods.add(new MethodCall("passivateObject", KEY, obj));
729 assertEquals(expectedMethods, factory.getMethodCalls());
730
731
732 reset(pool, factory, expectedMethods);
733
734
735 pool.addObject(KEY);
736 pool.addObject(KEY);
737 pool.addObject(KEY);
738 assertEquals(3, pool.getNumIdle(KEY));
739 obj = pool.borrowObject(KEY);
740 obj = pool.borrowObject(KEY);
741 assertEquals(1, pool.getNumIdle(KEY));
742 assertEquals(2, pool.getNumActive(KEY));
743 clear(factory, expectedMethods);
744 factory.setPassivateObjectFail(true);
745 pool.returnObject(KEY, obj);
746 expectedMethods.add(new MethodCall("passivateObject", KEY, obj));
747 AbstractTestObjectPool.removeDestroyObjectCall(factory.getMethodCalls());
748
749 assertEquals(expectedMethods, factory.getMethodCalls());
750 assertEquals(1, pool.getNumIdle(KEY));
751 assertEquals(1, pool.getNumActive(KEY));
752
753 reset(pool, factory, expectedMethods);
754 obj = pool.borrowObject(KEY);
755 clear(factory, expectedMethods);
756 factory.setPassivateObjectFail(true);
757 factory.setDestroyObjectFail(true);
758 try {
759 pool.returnObject(KEY, obj);
760 if (!(pool instanceof GenericKeyedObjectPool)) {
761 fail("Expecting destroyObject exception to be propagated");
762 }
763 } catch (final PrivateException ex) {
764
765 }
766 pool.close();
767 }
768
769 @Test
770 public void testToString() {
771 final FailingKeyedPooledObjectFactory factory = new FailingKeyedPooledObjectFactory();
772 try (final KeyedObjectPool<Object, Object> pool = makeEmptyPool(factory)) {
773 pool.toString();
774 } catch (final UnsupportedOperationException uoe) {
775 return;
776 }
777 }
778 }