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