1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.pool2.proxy;
18
19 import static org.junit.jupiter.api.Assertions.assertEquals;
20 import static org.junit.jupiter.api.Assertions.assertNotNull;
21 import static org.junit.jupiter.api.Assertions.assertThrows;
22 import static org.junit.jupiter.api.Assertions.assertTrue;
23
24 import java.io.PrintWriter;
25 import java.io.StringWriter;
26 import java.time.Duration;
27
28 import org.apache.commons.pool2.BasePooledObjectFactory;
29 import org.apache.commons.pool2.ObjectPool;
30 import org.apache.commons.pool2.PooledObject;
31 import org.apache.commons.pool2.PooledObjectFactory;
32 import org.apache.commons.pool2.impl.AbandonedConfig;
33 import org.apache.commons.pool2.impl.DefaultPooledObject;
34 import org.apache.commons.pool2.impl.GenericObjectPool;
35 import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
36 import org.junit.jupiter.api.BeforeEach;
37 import org.junit.jupiter.api.Test;
38
39 public abstract class AbstractTestProxiedObjectPool {
40
41 protected interface TestObject {
42 String getData();
43 void setData(String data);
44 }
45 private static final class TestObjectFactory extends
46 BasePooledObjectFactory<TestObject> {
47
48 @Override
49 public TestObject create() {
50 return new TestObjectImpl();
51 }
52 @Override
53 public PooledObject<TestObject> wrap(final TestObject value) {
54 return new DefaultPooledObject<>(value);
55 }
56 }
57
58 private static final class TestObjectImpl implements TestObject {
59
60 private String data;
61
62 @Override
63 public String getData() {
64 return data;
65 }
66
67 @Override
68 public void setData(final String data) {
69 this.data = data;
70 }
71 }
72 private static final String DATA1 = "data1";
73
74 private static final Duration ABANDONED_TIMEOUT_SECS = Duration.ofSeconds(3);
75
76 private ObjectPool<TestObject> pool;
77
78 private StringWriter log;
79
80 protected abstract ProxySource<TestObject> getproxySource();
81
82 @BeforeEach
83 public void setUp() {
84 log = new StringWriter();
85
86 final PrintWriter pw = new PrintWriter(log);
87 final AbandonedConfig abandonedConfig = new AbandonedConfig();
88 abandonedConfig.setLogAbandoned(true);
89 abandonedConfig.setRemoveAbandonedOnBorrow(true);
90 abandonedConfig.setUseUsageTracking(true);
91 abandonedConfig.setRemoveAbandonedTimeout(ABANDONED_TIMEOUT_SECS);
92 abandonedConfig.setLogWriter(pw);
93
94 final GenericObjectPoolConfig<TestObject> config = new GenericObjectPoolConfig<>();
95 config.setMaxTotal(3);
96
97 final PooledObjectFactory<TestObject> factory = new TestObjectFactory();
98
99 @SuppressWarnings("resource")
100 final ObjectPool<TestObject> innerPool = new GenericObjectPool<>(factory, config, abandonedConfig);
101
102 pool = new ProxiedObjectPool<>(innerPool, getproxySource());
103 }
104
105 @Test
106 void testAccessAfterInvalidate() throws Exception {
107 final TestObject obj = pool.borrowObject();
108 assertNotNull(obj);
109
110
111 obj.setData(DATA1);
112 assertEquals(DATA1, obj.getData());
113
114 pool.invalidateObject(obj);
115
116 assertNotNull(obj);
117
118 assertThrows(IllegalStateException.class,
119 obj::getData);
120
121 }
122
123 @Test
124 void testAccessAfterReturn() throws Exception {
125 final TestObject obj = pool.borrowObject();
126 assertNotNull(obj);
127
128
129 obj.setData(DATA1);
130 assertEquals(DATA1, obj.getData());
131
132 pool.returnObject(obj);
133
134 assertNotNull(obj);
135
136 assertThrows(IllegalStateException.class,
137 obj::getData);
138 }
139
140 @Test
141 void testBorrowObject() throws Exception {
142 final TestObject obj = pool.borrowObject();
143 assertNotNull(obj);
144
145
146 obj.setData(DATA1);
147 assertEquals(DATA1, obj.getData());
148
149 pool.returnObject(obj);
150 }
151
152 @Test
153 void testPassThroughMethods01() throws Exception {
154 assertEquals(0, pool.getNumActive());
155 assertEquals(0, pool.getNumIdle());
156
157 pool.addObject();
158
159 assertEquals(0, pool.getNumActive());
160 assertEquals(1, pool.getNumIdle());
161
162 pool.clear();
163
164 assertEquals(0, pool.getNumActive());
165 assertEquals(0, pool.getNumIdle());
166 }
167
168 @Test
169 void testPassThroughMethods02() {
170 pool.close();
171
172 assertThrows(IllegalStateException.class,
173 () -> pool.addObject());
174 }
175
176 @Test
177 void testUsageTracking() throws Exception {
178 final TestObject obj = pool.borrowObject();
179 assertNotNull(obj);
180
181
182 obj.setData(DATA1);
183
184
185 Thread.sleep(ABANDONED_TIMEOUT_SECS.plusSeconds(2).toMillis());
186
187
188 pool.borrowObject();
189
190 final String logOutput = log.getBuffer().toString();
191
192 assertTrue(logOutput.contains("Pooled object created"));
193 assertTrue(logOutput.contains("The last code to use this object was"));
194 }
195
196 }