1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package net.grinder.communication;
23
24 import static org.junit.Assert.assertEquals;
25 import static org.junit.Assert.assertNull;
26 import static org.junit.Assert.assertSame;
27 import static org.junit.Assert.assertTrue;
28 import static org.mockito.Mockito.mock;
29 import static org.mockito.Mockito.verify;
30 import static org.mockito.Mockito.verifyNoMoreInteractions;
31
32 import java.util.List;
33 import java.util.concurrent.CyclicBarrier;
34
35 import net.grinder.common.UncheckedInterruptedException;
36 import net.grinder.communication.ResourcePool.Listener;
37
38 import org.junit.Test;
39
40
41
42
43
44
45
46 public class TestResourcePool {
47
48 @Test public void testConstructorAndSentinel() throws Exception {
49
50 final ResourcePool resourcePool = new ResourcePoolImplementation();
51
52 final ResourcePool.Reservation reservation = resourcePool.reserveNext();
53 assertTrue(reservation.isSentinel());
54
55
56
57 final ResourcePool.Reservation reservation2 = resourcePool.reserveNext();
58 assertTrue(reservation2.isSentinel());
59
60
61 reservation2.free();
62 reservation2.close();
63
64 assertTrue(!reservation2.isClosed());
65
66 final ResourcePool.Reservation reservation3 = resourcePool.reserveNext();
67 assertTrue(reservation3.isSentinel());
68
69
70 assertNull(reservation3.getResource());
71 }
72
73 @Test public void testAddAndReserveNext() throws Exception {
74
75 final ResourcePool resourcePool = new ResourcePoolImplementation();
76
77 final Listener listener1 = mock(ResourcePool.Listener.class);
78 final Listener listener2 = mock(ResourcePool.Listener.class);
79
80 resourcePool.addListener(listener1);
81 resourcePool.addListener(listener2);
82
83 final MyResource resource1 = new MyResource();
84 final MyResource resource2 = new MyResource();
85
86 resourcePool.add(resource1);
87 resourcePool.add(resource2);
88
89 verify(listener1).resourceAdded(resource1);
90 verify(listener1).resourceAdded(resource2);
91
92 verify(listener2).resourceAdded(resource1);
93 verify(listener2).resourceAdded(resource2);
94
95 final ResourcePool.Reservation reservation1 = resourcePool.reserveNext();
96 final ResourcePool.Reservation reservation2 = resourcePool.reserveNext();
97 final ResourcePool.Reservation sentinel = resourcePool.reserveNext();
98
99 assertTrue(!reservation1.isSentinel());
100 assertTrue(!reservation2.isSentinel());
101 assertTrue(sentinel.isSentinel());
102 assertTrue(resourcePool.reserveNext().isSentinel());
103
104 if (resource1.equals(reservation1.getResource())) {
105 assertEquals(resource1, reservation1.getResource());
106 assertEquals(resource2, reservation2.getResource());
107 }
108 else {
109 assertEquals(resource1, reservation2.getResource());
110 assertEquals(resource2, reservation1.getResource());
111 }
112
113 reservation2.free();
114 assertSame(reservation2, resourcePool.reserveNext());
115
116 assertSame(sentinel, resourcePool.reserveNext());
117
118 reservation1.free();
119 assertSame(reservation1, resourcePool.reserveNext());
120
121 reservation1.free();
122 reservation2.free();
123
124
125
126 for (int i = 0; i < 1100; ++i) {
127 resourcePool.reserveNext().free();
128 }
129
130 assertEquals(2, resourcePool.countActive());
131
132 reservation2.close();
133 assertTrue(reservation2.isClosed());
134 assertSame(sentinel, resourcePool.reserveNext());
135
136 verify(listener1).resourceClosed(resource2);
137 verify(listener2).resourceClosed(resource2);
138
139 assertTrue(!resource1.isClosed());
140 assertTrue(resource2.isClosed());
141
142 for (int i = 0; i < 1100; ++i) {
143 resourcePool.reserveNext().free();
144 }
145
146 assertEquals(1, resourcePool.countActive());
147
148 verifyNoMoreInteractions(listener1, listener2);
149 }
150
151 @Test public void testReserveAll() throws Exception {
152
153 final ResourcePool resourcePool = new ResourcePoolImplementation();
154 assertEquals(0, resourcePool.reserveAll().size());
155 assertEquals(0, resourcePool.reserveAll().size());
156
157 final MyResource resource1 = new MyResource();
158 final MyResource resource2 = new MyResource();
159
160 resourcePool.add(resource1);
161 resourcePool.add(resource2);
162
163 final List<?> reservations = resourcePool.reserveAll();
164 assertEquals(2, reservations.size());
165
166 final ResourcePool.Reservation reservation1 =
167 (ResourcePool.Reservation)reservations.get(0);
168
169 final ResourcePool.Reservation reservation2 =
170 (ResourcePool.Reservation)reservations.get(1);
171
172 if (resource1.equals(reservation1.getResource())) {
173 assertEquals(resource1, reservation1.getResource());
174 assertEquals(resource2, reservation2.getResource());
175 }
176 else {
177 assertEquals(resource1, reservation2.getResource());
178 assertEquals(resource2, reservation1.getResource());
179 }
180
181 assertTrue(!reservation1.isSentinel());
182 reservation1.free();
183
184 assertTrue(!reservation2.isSentinel());
185 reservation2.free();
186
187 final List<?> reservations2 = resourcePool.reserveAll();
188 assertEquals(2, reservations2.size());
189
190 ((ResourcePool.Reservation)reservations2.get(0)).free();
191
192 assertEquals(
193 UncheckedInterruptedException.class,
194 new BlockingActionThread() {
195 protected void blockingAction() throws InterruptedException {
196 resourcePool.reserveAll();
197 }
198 }.getException().getClass());
199 }
200
201 @Test public void testReserveAllMultiThreaded() throws Exception {
202 final ResourcePool resourcePool = new ResourcePoolImplementation();
203
204 resourcePool.add(new MyResource());
205 resourcePool.add(new MyResource());
206 resourcePool.add(new MyResource());
207 resourcePool.add(new MyResource());
208 resourcePool.add(new MyResource());
209
210 final CyclicBarrier barrier = new CyclicBarrier(20);
211
212 class ReserveAll implements Runnable {
213 public void run() {
214 try {
215 barrier.await();
216 }
217 catch (Exception e) {
218 }
219
220 for (int i = 0; i < 50; ++i) {
221 final List<? extends ResourcePool.Reservation> list =
222 resourcePool.reserveAll();
223
224 assert list.size() == 5;
225
226 for (ResourcePool.Reservation reservation : list) {
227 reservation.free();
228 }
229 }
230 }
231 }
232
233 final Thread[] threads = new Thread[barrier.getParties()];
234
235 for (int i = 0; i<threads.length; ++i) {
236 threads[i] = new Thread(new ReserveAll());
237 }
238
239 for (int i = 0; i<threads.length; ++i) {
240 threads[i].start();
241 }
242
243 for (int i=0; i<threads.length; ++i) {
244 threads[i].join();
245 }
246 }
247
248 @Test public void testClose() throws Exception {
249
250 final ResourcePool resourcePool = new ResourcePoolImplementation();
251 assertEquals(0, resourcePool.reserveAll().size());
252 assertEquals(0, resourcePool.reserveAll().size());
253
254 final Listener listener = mock(ResourcePool.Listener.class);
255
256 final MyResource resource1 = new MyResource();
257 final MyResource resource2 = new MyResource();
258
259 resourcePool.addListener(listener);
260
261 resourcePool.add(resource1);
262 resourcePool.add(resource2);
263
264 verify(listener).resourceAdded(resource1);
265 verify(listener).resourceAdded(resource2);
266
267 final List<?> reservations = resourcePool.reserveAll();
268 assertEquals(2, reservations.size());
269
270 ((ResourcePool.Reservation)reservations.get(1)).free();
271
272 resourcePool.closeCurrentResources();
273
274 verify(listener).resourceClosed(resource1);
275 verify(listener).resourceClosed(resource2);
276
277 final List<?> reservations2 = resourcePool.reserveAll();
278 assertEquals(0, reservations2.size());
279
280 assertTrue(resource1.isClosed());
281 assertTrue(resource2.isClosed());
282
283 verifyNoMoreInteractions(listener);
284 }
285
286 @Test public void testCountActive() throws Exception {
287
288 final ResourcePool resourcePool = new ResourcePoolImplementation();
289 assertEquals(0, resourcePool.countActive());
290
291 final MyResource resource1 = new MyResource();
292 final MyResource resource2 = new MyResource();
293
294 resourcePool.add(resource1);
295 assertEquals(1, resourcePool.countActive());
296
297 resourcePool.add(resource2);
298 assertEquals(2, resourcePool.countActive());
299
300 final List<?> reservations = resourcePool.reserveAll();
301 assertEquals(2, resourcePool.countActive());
302
303 ((ResourcePool.Reservation)reservations.get(1)).close();
304 assertEquals(1, resourcePool.countActive());
305
306 ((ResourcePool.Reservation)reservations.get(0)).close();
307 assertEquals(0, resourcePool.countActive());
308 }
309
310 private static class MyResource implements ResourcePool.Resource {
311
312 private boolean m_closed = false;
313
314 public void close() {
315 m_closed = true;
316 }
317
318 public boolean isClosed() {
319 return m_closed;
320 }
321 }
322 }