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