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.synchronisation;
23
24 import static org.junit.Assert.assertEquals;
25 import static org.junit.Assert.assertNotSame;
26 import static org.junit.Assert.assertNull;
27 import static org.junit.Assert.assertSame;
28 import static org.junit.Assert.fail;
29 import static org.mockito.Matchers.argThat;
30 import static org.mockito.Matchers.eq;
31 import static org.mockito.Matchers.isA;
32 import static org.mockito.Mockito.mock;
33 import static org.mockito.Mockito.times;
34 import static org.mockito.Mockito.verify;
35 import static org.mockito.Mockito.verifyNoMoreInteractions;
36 import static org.mockito.Mockito.when;
37
38 import java.util.Set;
39
40 import net.grinder.communication.MessageDispatchRegistry;
41 import net.grinder.communication.Sender;
42 import net.grinder.communication.MessageDispatchRegistry.AbstractHandler;
43 import net.grinder.synchronisation.BarrierGroup.Listener;
44 import net.grinder.synchronisation.messages.AddBarrierMessage;
45 import net.grinder.synchronisation.messages.AddWaiterMessage;
46 import net.grinder.synchronisation.messages.BarrierIdentity;
47 import net.grinder.synchronisation.messages.CancelWaiterMessage;
48 import net.grinder.synchronisation.messages.OpenBarrierMessage;
49 import net.grinder.synchronisation.messages.RemoveBarriersMessage;
50 import net.grinder.testutility.MockingUtilities.TypedArgumentMatcher;
51
52 import org.junit.Before;
53 import org.junit.Test;
54 import org.mockito.ArgumentCaptor;
55 import org.mockito.Captor;
56 import org.mockito.Mock;
57 import org.mockito.MockitoAnnotations;
58
59
60
61
62
63
64
65
66 public class TestClientBarrierGroups {
67
68 private static final BarrierIdentity ID1 = new BarrierIdentity() {};
69 private static final BarrierIdentity ID2 = new BarrierIdentity() {};
70
71 @Mock private Sender m_sender;
72 @Mock private MessageDispatchRegistry m_messageDispatch;
73 @Captor
74 private ArgumentCaptor<AbstractHandler<OpenBarrierMessage>> m_handlerCaptor;
75
76 private int m_awakenCount = 0;
77
78 private ClientBarrierGroups m_groups;
79
80 @Before public void setUp() {
81 MockitoAnnotations.initMocks(this);
82
83 m_groups = new ClientBarrierGroups(m_sender, m_messageDispatch);
84 }
85
86 @Test public void testCreateAndRetrieve() throws Exception {
87 assertNull(m_groups.getExistingGroup("A"));
88
89 final BarrierGroup a = m_groups.getGroup("A");
90 assertEquals("A", a.getName());
91 assertSame(a, m_groups.getGroup("A"));
92 assertNotSame(a, m_groups.getGroup("B"));
93
94 assertSame(a, m_groups.getExistingGroup("A"));
95
96 a.addBarrier();
97
98 a.removeBarriers(1);
99
100 verify(m_sender).send(isA(AddBarrierMessage.class));
101 verify(m_sender).send(isA(RemoveBarriersMessage.class));
102
103 assertNotSame(a, m_groups.getGroup("A"));
104
105 verifyNoMoreInteractions(m_sender);
106 }
107
108 @Test public void testMessageHandler() throws Exception {
109
110 verify(m_messageDispatch).set(eq(OpenBarrierMessage.class),
111 m_handlerCaptor.capture());
112
113 final AbstractHandler<OpenBarrierMessage> handler =
114 m_handlerCaptor.getValue();
115
116 final OpenBarrierMessage message = mock(OpenBarrierMessage.class);
117 when(message.getName()).thenReturn("A");
118
119 handler.handle(message);
120 assertNull(m_groups.getExistingGroup("A"));
121 assertEquals(0, m_awakenCount);
122
123 createBarrierGroup("A");
124 assertEquals(0, m_awakenCount);
125 handler.handle(message);
126 assertEquals(1, m_awakenCount);
127
128 verifyNoMoreInteractions(m_messageDispatch);
129 }
130
131 private BarrierGroup createBarrierGroup(String groupName) {
132 final BarrierGroup bg = m_groups.getGroup(groupName);
133
134 bg.addListener(new Listener() {
135 public void awaken(Set<BarrierIdentity> waiters) {
136 ++m_awakenCount;
137 }
138 });
139
140 return bg;
141 }
142
143 @Test public void testBarrierGroup() {
144 final BarrierGroup bg = createBarrierGroup("Foo");
145
146 assertEquals("Foo", bg.getName());
147 assertEquals(0, m_awakenCount);
148 }
149
150 @Test public void testBarrierGroupAddWaiter() throws Exception {
151 final BarrierGroup bg = createBarrierGroup("Foo");
152
153 bg.addBarrier();
154 bg.addBarrier();
155
156 verify(m_sender, times(2)).send(isA(AddBarrierMessage.class));
157
158 bg.addWaiter(ID1);
159
160 bg.addWaiter(ID2);
161
162 verify(m_sender).send(argThat(new AddWaiterMessageMatcher(ID1)));
163 verify(m_sender).send(argThat(new AddWaiterMessageMatcher(ID2)));
164
165 assertEquals(0, m_awakenCount);
166
167 verifyNoMoreInteractions(m_sender);
168 }
169
170 @Test public void testBarrierGroupAddTooManyWaiters() throws Exception {
171 final BarrierGroup bg = createBarrierGroup("Foo");
172
173 bg.addBarrier();
174 bg.addWaiter(ID1);
175
176 try {
177 bg.addWaiter(ID2);
178 fail("Expected AssertionError");
179 }
180 catch (AssertionError e) {
181 }
182 }
183
184 @Test public void testRemoveBarriers() throws Exception {
185 final BarrierGroup bg = createBarrierGroup("Foo");
186
187 bg.addBarrier();
188 bg.addBarrier();
189 bg.addBarrier();
190
191 verify(m_sender, times(3)).send(isA(AddBarrierMessage.class));
192
193 bg.addWaiter(ID1);
194 bg.addWaiter(ID2);
195
196 verify(m_sender).send(argThat(new AddWaiterMessageMatcher(ID1)));
197 verify(m_sender).send(argThat(new AddWaiterMessageMatcher(ID2)));
198
199 bg.removeBarriers(1);
200
201 verify(m_sender).send(argThat(new RemoveBarriersMessageMatcher(1)));
202
203 assertEquals(0, m_awakenCount);
204
205 verifyNoMoreInteractions(m_sender);
206 }
207
208 @Test public void testRemoveTooManyBarriers() throws Exception {
209 final BarrierGroup bg = createBarrierGroup("Foo");
210
211 bg.addBarrier();
212 bg.addBarrier();
213 bg.addBarrier();
214
215 bg.removeBarriers(1);
216 bg.removeBarriers(1);
217
218 try {
219 bg.removeBarriers(2);
220 fail("Expected IllegalStateException");
221 }
222 catch (IllegalStateException e) {
223 }
224
225 assertEquals(0, m_awakenCount);
226 }
227
228 @Test public void testInvalidGroup() throws Exception {
229 final BarrierGroup bg = createBarrierGroup("Foo");
230
231 bg.addBarrier();
232 bg.removeBarriers(1);
233
234 try {
235 bg.addWaiter(null);
236 fail("Expected IllegalStateException");
237 }
238 catch (IllegalStateException e) {
239 }
240
241 try {
242 bg.addBarrier();
243 fail("Expected IllegalStateException");
244 }
245 catch (IllegalStateException e) {
246 }
247
248 try {
249 bg.removeBarriers(1);
250 fail("Expected IllegalStateException");
251 }
252 catch (IllegalStateException e) {
253 }
254
255 assertEquals(0, m_awakenCount);
256 }
257
258 @Test public void addMoreWaitersThanBarriers() throws Exception {
259 final BarrierGroup bg = createBarrierGroup("Foo");
260
261 try {
262 bg.addWaiter(ID2);
263 fail("Expected IllegalStateException");
264 }
265 catch (IllegalStateException e) {
266 }
267 }
268
269 @Test public void testCancelWaiter() throws Exception {
270 final BarrierGroup bg = createBarrierGroup("Foo");
271
272 bg.addBarrier();
273 bg.addBarrier();
274
275 verify(m_sender, times(2)).send(isA(AddBarrierMessage.class));
276
277 bg.addWaiter(ID1);
278 verify(m_sender).send(argThat(new AddWaiterMessageMatcher(ID1)));
279
280 bg.cancelWaiter(ID2);
281 verify(m_sender).send(argThat(new CancelWaiterMessageMatcher(ID2)));
282
283 bg.cancelWaiter(ID1);
284 verify(m_sender).send(argThat(new CancelWaiterMessageMatcher(ID1)));
285
286 bg.addWaiter(ID2);
287 verify(m_sender).send(argThat(new AddWaiterMessageMatcher(ID2)));
288
289 bg.addWaiter(ID1);
290 verify(m_sender, times(2)).send(argThat(new AddWaiterMessageMatcher(ID1)));
291
292 assertEquals(0, m_awakenCount);
293
294 verifyNoMoreInteractions(m_sender);
295 }
296
297 private static class RemoveBarriersMessageMatcher
298 extends TypedArgumentMatcher<RemoveBarriersMessage> {
299
300 private final int m_numberOfBarriers;
301
302 RemoveBarriersMessageMatcher(int numberOfBarriers) {
303 m_numberOfBarriers = numberOfBarriers;
304 }
305
306 @Override protected boolean argumentMatches(RemoveBarriersMessage t) {
307 return t.getNumberOfBarriers() == m_numberOfBarriers;
308 }
309 }
310
311 private static class AddWaiterMessageMatcher
312 extends TypedArgumentMatcher<AddWaiterMessage> {
313
314 private final BarrierIdentity m_barrierIdentity;
315
316 AddWaiterMessageMatcher(BarrierIdentity barrierIdentity) {
317 m_barrierIdentity = barrierIdentity;
318 }
319
320 @Override protected boolean argumentMatches(AddWaiterMessage t) {
321 return t.getBarrierIdentity().equals(m_barrierIdentity);
322 }
323 }
324
325 private static class CancelWaiterMessageMatcher
326 extends TypedArgumentMatcher<CancelWaiterMessage> {
327
328 private final BarrierIdentity m_barrierIdentity;
329
330 CancelWaiterMessageMatcher(BarrierIdentity barrierIdentity) {
331 m_barrierIdentity = barrierIdentity;
332 }
333
334 @Override protected boolean argumentMatches(CancelWaiterMessage t) {
335 return t.getBarrierIdentity().equals(m_barrierIdentity);
336 }
337 }
338 }