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 final 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 protected abstract Object getNthObject(Object key, int n);
200
201 protected abstract boolean isFifo();
202
203 protected abstract boolean isLifo();
204
205
206
207
208
209
210
211
212
213
214
215 protected abstract <E extends Exception> KeyedObjectPool<Object, Object> makeEmptyPool(int minCapacity);
216
217
218
219
220
221
222
223
224
225
226
227 protected abstract <E extends Exception> KeyedObjectPool<Object, Object> makeEmptyPool(
228 KeyedPooledObjectFactory<Object, Object> factory);
229
230 protected abstract Object makeKey(int n);
231
232 private <E extends Exception> void reset(final KeyedObjectPool<Object, Object> pool,
233 final FailingKeyedPooledObjectFactory factory,
234 final List<MethodCall> expectedMethods) throws Exception {
235 pool.clear();
236 clear(factory, expectedMethods);
237 factory.reset();
238 }
239
240 @AfterEach
241 public void tearDown() {
242 pool = null;
243 }
244
245 @Test
246 public void testBaseAddObject() throws Exception {
247 try {
248 pool = makeEmptyPool(3);
249 } catch (final UnsupportedOperationException uoe) {
250 return;
251 }
252 final Object key = makeKey(0);
253 try {
254 assertEquals(0, pool.getNumIdle());
255 assertEquals(0, pool.getNumActive());
256 assertEquals(0, pool.getNumIdle(key));
257 assertEquals(0, pool.getNumActive(key));
258 pool.addObject(key);
259 assertEquals(1, pool.getNumIdle());
260 assertEquals(0, pool.getNumActive());
261 assertEquals(1, pool.getNumIdle(key));
262 assertEquals(0, pool.getNumActive(key));
263 final Object obj = pool.borrowObject(key);
264 assertEquals(getNthObject(key, 0), obj);
265 assertEquals(0, pool.getNumIdle());
266 assertEquals(1, pool.getNumActive());
267 assertEquals(0, pool.getNumIdle(key));
268 assertEquals(1, pool.getNumActive(key));
269 pool.returnObject(key, obj);
270 assertEquals(1, pool.getNumIdle());
271 assertEquals(0, pool.getNumActive());
272 assertEquals(1, pool.getNumIdle(key));
273 assertEquals(0, pool.getNumActive(key));
274 } catch (final UnsupportedOperationException e) {
275 return;
276 } finally {
277 pool.close();
278 }
279 }
280
281 @Test
282 public void testBaseBorrow() throws Exception {
283 try {
284 pool = makeEmptyPool(3);
285 } catch (final UnsupportedOperationException uoe) {
286 return;
287 }
288 final Object keya = makeKey(0);
289 final Object keyb = makeKey(1);
290 assertEquals(getNthObject(keya, 0), pool.borrowObject(keya), "1");
291 assertEquals(getNthObject(keyb, 0), pool.borrowObject(keyb), "2");
292 assertEquals(getNthObject(keyb, 1), pool.borrowObject(keyb), "3");
293 assertEquals(getNthObject(keya, 1), pool.borrowObject(keya), "4");
294 assertEquals(getNthObject(keyb, 2), pool.borrowObject(keyb), "5");
295 assertEquals(getNthObject(keya, 2), pool.borrowObject(keya), "6");
296 pool.close();
297 }
298
299 @Test
300 public void testBaseBorrowReturn() throws Exception {
301 try {
302 pool = makeEmptyPool(3);
303 } catch (final UnsupportedOperationException uoe) {
304 return;
305 }
306 final Object keya = makeKey(0);
307 Object obj0 = pool.borrowObject(keya);
308 assertEquals(getNthObject(keya, 0), obj0);
309 Object obj1 = pool.borrowObject(keya);
310 assertEquals(getNthObject(keya, 1), obj1);
311 Object obj2 = pool.borrowObject(keya);
312 assertEquals(getNthObject(keya, 2), obj2);
313 pool.returnObject(keya, obj2);
314 obj2 = pool.borrowObject(keya);
315 assertEquals(getNthObject(keya, 2), obj2);
316 pool.returnObject(keya, obj1);
317 obj1 = pool.borrowObject(keya);
318 assertEquals(getNthObject(keya, 1), obj1);
319 pool.returnObject(keya, obj0);
320 pool.returnObject(keya, obj2);
321 obj2 = pool.borrowObject(keya);
322 if (isLifo()) {
323 assertEquals(getNthObject(keya, 2), obj2);
324 }
325 if (isFifo()) {
326 assertEquals(getNthObject(keya, 0), obj2);
327 }
328 obj0 = pool.borrowObject(keya);
329 if (isLifo()) {
330 assertEquals(getNthObject(keya, 0), obj0);
331 }
332 if (isFifo()) {
333 assertEquals(getNthObject(keya, 2), obj0);
334 }
335 pool.close();
336 }
337
338 @Test
339 public void testBaseClear() throws Exception {
340 try {
341 pool = makeEmptyPool(3);
342 } catch (final UnsupportedOperationException uoe) {
343 return;
344 }
345 final Object keya = makeKey(0);
346 assertEquals(0, pool.getNumActive(keya));
347 assertEquals(0, pool.getNumIdle(keya));
348 final Object obj0 = pool.borrowObject(keya);
349 final Object obj1 = pool.borrowObject(keya);
350 assertEquals(2, pool.getNumActive(keya));
351 assertEquals(0, pool.getNumIdle(keya));
352 pool.returnObject(keya, obj1);
353 pool.returnObject(keya, obj0);
354 assertEquals(0, pool.getNumActive(keya));
355 assertEquals(2, pool.getNumIdle(keya));
356 pool.clear(keya);
357 assertEquals(0, pool.getNumActive(keya));
358 assertEquals(0, pool.getNumIdle(keya));
359 final Object obj2 = pool.borrowObject(keya);
360 assertEquals(getNthObject(keya, 2), obj2);
361 pool.close();
362 }
363
364 @Test
365 public void testBaseInvalidateObject() throws Exception {
366 try {
367 pool = makeEmptyPool(3);
368 } catch (final UnsupportedOperationException uoe) {
369 return;
370 }
371 final Object keya = makeKey(0);
372 assertEquals(0, pool.getNumActive(keya));
373 assertEquals(0, pool.getNumIdle(keya));
374 final Object obj0 = pool.borrowObject(keya);
375 final Object obj1 = pool.borrowObject(keya);
376 assertEquals(2, pool.getNumActive(keya));
377 assertEquals(0, pool.getNumIdle(keya));
378 pool.invalidateObject(keya, obj0);
379 assertEquals(1, pool.getNumActive(keya));
380 assertEquals(0, pool.getNumIdle(keya));
381 pool.invalidateObject(keya, obj1);
382 assertEquals(0, pool.getNumActive(keya));
383 assertEquals(0, pool.getNumIdle(keya));
384 pool.close();
385 }
386
387 @Test
388 public void testBaseNumActiveNumIdle() throws Exception {
389 try {
390 pool = makeEmptyPool(3);
391 } catch (final UnsupportedOperationException uoe) {
392 return;
393 }
394 final Object keya = makeKey(0);
395 assertEquals(0, pool.getNumActive(keya));
396 assertEquals(0, pool.getNumIdle(keya));
397 final Object obj0 = pool.borrowObject(keya);
398 assertEquals(1, pool.getNumActive(keya));
399 assertEquals(0, pool.getNumIdle(keya));
400 final Object obj1 = pool.borrowObject(keya);
401 assertEquals(2, pool.getNumActive(keya));
402 assertEquals(0, pool.getNumIdle(keya));
403 pool.returnObject(keya, obj1);
404 assertEquals(1, pool.getNumActive(keya));
405 assertEquals(1, pool.getNumIdle(keya));
406 pool.returnObject(keya, obj0);
407 assertEquals(0, pool.getNumActive(keya));
408 assertEquals(2, pool.getNumIdle(keya));
409
410 assertEquals(0, pool.getNumActive("xyzzy12345"));
411 assertEquals(0, pool.getNumIdle("xyzzy12345"));
412
413 pool.close();
414 }
415
416 @Test
417 public void testBaseNumActiveNumIdle2() throws Exception {
418 try {
419 pool = makeEmptyPool(6);
420 } catch (final UnsupportedOperationException uoe) {
421 return;
422 }
423 final Object keya = makeKey(0);
424 final Object keyb = makeKey(1);
425 assertEquals(0, pool.getNumActive());
426 assertEquals(0, pool.getNumIdle());
427 assertEquals(0, pool.getNumActive(keya));
428 assertEquals(0, pool.getNumIdle(keya));
429 assertEquals(0, pool.getNumActive(keyb));
430 assertEquals(0, pool.getNumIdle(keyb));
431
432 final Object objA0 = pool.borrowObject(keya);
433 final Object objB0 = pool.borrowObject(keyb);
434
435 assertEquals(2, pool.getNumActive());
436 assertEquals(0, pool.getNumIdle());
437 assertEquals(1, pool.getNumActive(keya));
438 assertEquals(0, pool.getNumIdle(keya));
439 assertEquals(1, pool.getNumActive(keyb));
440 assertEquals(0, pool.getNumIdle(keyb));
441
442 final Object objA1 = pool.borrowObject(keya);
443 final Object objB1 = pool.borrowObject(keyb);
444
445 assertEquals(4, pool.getNumActive());
446 assertEquals(0, pool.getNumIdle());
447 assertEquals(2, pool.getNumActive(keya));
448 assertEquals(0, pool.getNumIdle(keya));
449 assertEquals(2, pool.getNumActive(keyb));
450 assertEquals(0, pool.getNumIdle(keyb));
451
452 pool.returnObject(keya, objA0);
453 pool.returnObject(keyb, objB0);
454
455 assertEquals(2, pool.getNumActive());
456 assertEquals(2, pool.getNumIdle());
457 assertEquals(1, pool.getNumActive(keya));
458 assertEquals(1, pool.getNumIdle(keya));
459 assertEquals(1, pool.getNumActive(keyb));
460 assertEquals(1, pool.getNumIdle(keyb));
461
462 pool.returnObject(keya, objA1);
463 pool.returnObject(keyb, objB1);
464
465 assertEquals(0, pool.getNumActive());
466 assertEquals(4, pool.getNumIdle());
467 assertEquals(0, pool.getNumActive(keya));
468 assertEquals(2, pool.getNumIdle(keya));
469 assertEquals(0, pool.getNumActive(keyb));
470 assertEquals(2, pool.getNumIdle(keyb));
471
472 pool.close();
473 }
474
475 @Test
476 public void testClosedPoolBehavior() throws Exception {
477 final KeyedObjectPool<Object, Object> pool;
478 try {
479 pool = makeEmptyPool(new TestFactory());
480 } catch (final UnsupportedOperationException uoe) {
481 return;
482 }
483
484 final Object o1 = pool.borrowObject(KEY);
485 final Object o2 = pool.borrowObject(KEY);
486
487 pool.close();
488
489 assertThrows(IllegalStateException.class, () -> pool.addObject(KEY),
490 "A closed pool must throw an IllegalStateException when addObject is called.");
491
492 assertThrows(IllegalStateException.class, () -> pool.borrowObject(KEY),
493 "A closed pool must throw an IllegalStateException when borrowObject is called.");
494
495
496 assertEquals(0, pool.getNumIdle(KEY), "A closed pool shouldn't have any idle objects.");
497 assertEquals(0, pool.getNumIdle(), "A closed pool shouldn't have any idle objects.");
498 pool.getNumActive();
499 pool.getNumActive(KEY);
500 pool.returnObject(KEY, o1);
501 assertEquals(0, pool.getNumIdle(KEY),
502 "returnObject should not add items back into the idle object pool for a closed pool.");
503 assertEquals(0, pool.getNumIdle(),
504 "returnObject should not add items back into the idle object pool for a closed pool.");
505 pool.invalidateObject(KEY, o2);
506 pool.clear(KEY);
507 pool.clear();
508 pool.close();
509 }
510
511 @Test
512 public void testKPOFAddObjectUsage() throws Exception {
513 final FailingKeyedPooledObjectFactory factory = new FailingKeyedPooledObjectFactory();
514 final KeyedObjectPool<Object, Object> pool;
515 try {
516 pool = makeEmptyPool(factory);
517 } catch (final UnsupportedOperationException uoe) {
518 return;
519 }
520 final List<MethodCall> expectedMethods = new ArrayList<>();
521
522
523 pool.addObject(KEY);
524 expectedMethods.add(new MethodCall("makeObject", KEY).returned(ZERO));
525 expectedMethods.add(new MethodCall("passivateObject", KEY, ZERO));
526 assertEquals(expectedMethods, factory.getMethodCalls());
527
528
529 reset(pool, factory, expectedMethods);
530
531
532 factory.setMakeObjectFail(true);
533 assertThrows(PrivateException.class, () -> pool.addObject(KEY),
534 "Expected addObject to propagate makeObject exception.");
535 expectedMethods.add(new MethodCall("makeObject", KEY));
536 assertEquals(expectedMethods, factory.getMethodCalls());
537
538 clear(factory, expectedMethods);
539
540
541 factory.setMakeObjectFail(false);
542 factory.setPassivateObjectFail(true);
543 assertThrows(PrivateException.class, () -> pool.addObject(KEY),
544 "Expected addObject to propagate passivateObject exception.");
545 expectedMethods.add(new MethodCall("makeObject", KEY).returned(ONE));
546 expectedMethods.add(new MethodCall("passivateObject", KEY, ONE));
547 assertEquals(expectedMethods, factory.getMethodCalls());
548 pool.close();
549 }
550
551 @Test
552 public void testKPOFBorrowObjectUsages() throws Exception {
553 final FailingKeyedPooledObjectFactory factory = new FailingKeyedPooledObjectFactory();
554 final KeyedObjectPool<Object, Object> pool;
555 try {
556 pool = makeEmptyPool(factory);
557 } catch (final UnsupportedOperationException uoe) {
558 return;
559 }
560 final List<MethodCall> expectedMethods = new ArrayList<>();
561 Object obj;
562
563 if (pool instanceof GenericKeyedObjectPool) {
564 ((GenericKeyedObjectPool<Object, Object>) pool).setTestOnBorrow(true);
565 }
566
567
568
569
570 pool.addObject(KEY);
571 clear(factory, expectedMethods);
572 obj = pool.borrowObject(KEY);
573 expectedMethods.add(new MethodCall("activateObject", KEY, ZERO));
574 expectedMethods.add(new MethodCall("validateObject", KEY, ZERO).returned(Boolean.TRUE));
575 assertEquals(expectedMethods, factory.getMethodCalls());
576 pool.returnObject(KEY, obj);
577
578
579 reset(pool, factory, expectedMethods);
580
581
582 factory.setMakeObjectFail(true);
583 assertThrows(PrivateException.class, () -> pool.borrowObject(KEY),
584 "Expected borrowObject to propagate makeObject exception.");
585 expectedMethods.add(new MethodCall("makeObject", KEY));
586 assertEquals(expectedMethods, factory.getMethodCalls());
587
588
589
590 reset(pool, factory, expectedMethods);
591 pool.addObject(KEY);
592 clear(factory, expectedMethods);
593
594 factory.setActivateObjectFail(true);
595 expectedMethods.add(new MethodCall("activateObject", KEY, obj));
596 assertThrows(NoSuchElementException.class, () -> pool.borrowObject(KEY));
597
598
599 expectedMethods.add(new MethodCall("makeObject", KEY).returned(ONE));
600 expectedMethods.add(new MethodCall("activateObject", KEY, ONE));
601 AbstractTestObjectPool.removeDestroyObjectCall(factory.getMethodCalls());
602
603 assertEquals(expectedMethods, factory.getMethodCalls());
604
605
606
607 reset(pool, factory, expectedMethods);
608 pool.addObject(KEY);
609 clear(factory, expectedMethods);
610
611 factory.setValidateObjectFail(true);
612
613
614 assertThrows(NoSuchElementException.class, () -> pool.borrowObject(KEY));
615
616 expectedMethods.add(new MethodCall("activateObject", KEY, ZERO));
617 expectedMethods.add(new MethodCall("validateObject", KEY, ZERO));
618
619 expectedMethods.add(new MethodCall("makeObject", KEY).returned(ONE));
620 expectedMethods.add(new MethodCall("activateObject", KEY, ONE));
621 expectedMethods.add(new MethodCall("validateObject", KEY, ONE));
622 AbstractTestObjectPool.removeDestroyObjectCall(factory.getMethodCalls());
623 assertEquals(expectedMethods, factory.getMethodCalls());
624 pool.close();
625 }
626
627 @Test
628 public void testKPOFClearUsages() throws Exception {
629 final FailingKeyedPooledObjectFactory factory = new FailingKeyedPooledObjectFactory();
630 final KeyedObjectPool<Object, Object> pool;
631 try {
632 pool = makeEmptyPool(factory);
633 } catch (final UnsupportedOperationException uoe) {
634 return;
635 }
636 final List<MethodCall> expectedMethods = new ArrayList<>();
637
638
639 pool.addObjects(KEY, 5);
640 pool.clear();
641
642
643 reset(pool, factory, expectedMethods);
644 factory.setDestroyObjectFail(true);
645 pool.addObjects(KEY, 5);
646 pool.clear();
647 pool.close();
648 }
649
650 @Test
651 public void testKPOFCloseUsages() throws Exception {
652 final FailingKeyedPooledObjectFactory factory = new FailingKeyedPooledObjectFactory();
653 KeyedObjectPool<Object, Object> pool;
654 try {
655 pool = makeEmptyPool(factory);
656 } catch (final UnsupportedOperationException uoe) {
657 return;
658 }
659 final List<MethodCall> expectedMethods = new ArrayList<>();
660
661
662 pool.addObjects(KEY, 5);
663 pool.close();
664
665
666 try (final KeyedObjectPool<Object, Object> pool2 = makeEmptyPool(factory)) {
667 reset(pool2, factory, expectedMethods);
668 factory.setDestroyObjectFail(true);
669 pool2.addObjects(KEY, 5);
670 }
671 }
672
673 @Test
674 public void testKPOFInvalidateObjectUsages() throws Exception {
675 final FailingKeyedPooledObjectFactory factory = new FailingKeyedPooledObjectFactory();
676 final KeyedObjectPool<Object, Object> pool;
677 try {
678 pool = makeEmptyPool(factory);
679 } catch (final UnsupportedOperationException uoe) {
680 return;
681 }
682 final List<MethodCall> expectedMethods = new ArrayList<>();
683 Object obj;
684
685
686
687 obj = pool.borrowObject(KEY);
688 clear(factory, expectedMethods);
689
690
691 pool.invalidateObject(KEY, obj);
692 expectedMethods.add(new MethodCall("destroyObject", KEY, obj));
693 assertEquals(expectedMethods, factory.getMethodCalls());
694
695
696 reset(pool, factory, expectedMethods);
697 final Object obj2 = pool.borrowObject(KEY);
698 clear(factory, expectedMethods);
699 factory.setDestroyObjectFail(true);
700 assertThrows(PrivateException.class, () -> pool.invalidateObject(KEY, obj2),
701 "Expecting destroy exception to propagate");
702 Thread.sleep(250);
703 AbstractTestObjectPool.removeDestroyObjectCall(factory.getMethodCalls());
704 assertEquals(expectedMethods, factory.getMethodCalls());
705 pool.close();
706 }
707
708 @Test
709 public void testKPOFReturnObjectUsages() throws Exception {
710 final FailingKeyedPooledObjectFactory factory = new FailingKeyedPooledObjectFactory();
711 final KeyedObjectPool<Object, Object> pool;
712 try {
713 pool = makeEmptyPool(factory);
714 } catch (final UnsupportedOperationException uoe) {
715 return;
716 }
717 final List<MethodCall> expectedMethods = new ArrayList<>();
718 Object obj;
719
720
721 obj = pool.borrowObject(KEY);
722 clear(factory, expectedMethods);
723
724
725 pool.returnObject(KEY, obj);
726 expectedMethods.add(new MethodCall("passivateObject", KEY, obj));
727 assertEquals(expectedMethods, factory.getMethodCalls());
728
729
730 reset(pool, factory, expectedMethods);
731
732
733 pool.addObject(KEY);
734 pool.addObject(KEY);
735 pool.addObject(KEY);
736 assertEquals(3, pool.getNumIdle(KEY));
737 obj = pool.borrowObject(KEY);
738 obj = pool.borrowObject(KEY);
739 assertEquals(1, pool.getNumIdle(KEY));
740 assertEquals(2, pool.getNumActive(KEY));
741 clear(factory, expectedMethods);
742 factory.setPassivateObjectFail(true);
743 pool.returnObject(KEY, obj);
744 expectedMethods.add(new MethodCall("passivateObject", KEY, obj));
745 AbstractTestObjectPool.removeDestroyObjectCall(factory.getMethodCalls());
746
747 assertEquals(expectedMethods, factory.getMethodCalls());
748 assertEquals(1, pool.getNumIdle(KEY));
749 assertEquals(1, pool.getNumActive(KEY));
750
751 reset(pool, factory, expectedMethods);
752 obj = pool.borrowObject(KEY);
753 clear(factory, expectedMethods);
754 factory.setPassivateObjectFail(true);
755 factory.setDestroyObjectFail(true);
756 try {
757 pool.returnObject(KEY, obj);
758 if (!(pool instanceof GenericKeyedObjectPool)) {
759 fail("Expecting destroyObject exception to be propagated");
760 }
761 } catch (final PrivateException ex) {
762
763 }
764 pool.close();
765 }
766
767 @Test
768 public void testToString() {
769 final FailingKeyedPooledObjectFactory factory = new FailingKeyedPooledObjectFactory();
770 try (final KeyedObjectPool<Object, Object> pool = makeEmptyPool(factory)) {
771 pool.toString();
772 } catch (final UnsupportedOperationException uoe) {
773 return;
774 }
775 }
776 }