1
2
3
4
5
6
7 package org.mule.transport;
8
9 import org.mule.api.MuleContext;
10 import org.mule.api.MuleException;
11 import org.mule.api.context.WorkManager;
12 import org.mule.api.endpoint.ImmutableEndpoint;
13 import org.mule.api.retry.RetryCallback;
14 import org.mule.api.retry.RetryPolicyTemplate;
15 import org.mule.endpoint.MuleEndpointURI;
16 import org.mule.transport.MuleAbstractTransportMessageHandlerTestCase.MethodInvocation.MethodPart;
17
18 import java.util.List;
19 import java.util.Vector;
20 import java.util.concurrent.atomic.AtomicBoolean;
21
22 import edu.umd.cs.mtc.MultithreadedTestCase;
23 import edu.umd.cs.mtc.TestFramework;
24
25 import org.apache.commons.lang.builder.EqualsBuilder;
26 import org.apache.commons.lang.builder.HashCodeBuilder;
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29 import org.junit.After;
30 import org.junit.Before;
31 import org.junit.Ignore;
32 import org.junit.Test;
33 import org.mockito.invocation.InvocationOnMock;
34 import org.mockito.stubbing.Answer;
35
36 import static org.junit.Assert.fail;
37 import static org.mockito.Matchers.any;
38 import static org.mockito.Mockito.mock;
39 import static org.mockito.Mockito.when;
40
41
42
43
44
45
46 public class MuleAbstractTransportMessageHandlerTestCase
47 {
48
49
50
51 static Log log = LogFactory.getLog(MuleAbstractTransportMessageHandlerTestCase.class);
52
53 @Test
54 public void testStartRethrowsMuleExceptionCorrectly() throws Exception
55 {
56 final MuleException someMuleException = mock(MuleException.class);
57 AbstractTransportMessageHandler connectable = new AbstractTransportMessageHandler(createDummyEndpoint())
58 {
59 @Override
60 protected void doStart() throws MuleException
61 {
62 throw someMuleException;
63 }
64
65 @Override
66 protected WorkManager getWorkManager()
67 {
68 return null;
69 }
70
71 @Override
72 protected ConnectableLifecycleManager createLifecycleManager()
73 {
74 return new ConnectableLifecycleManager("test", this);
75 }
76 };
77 connectable.initialise();
78 connectable.connect();
79 try
80 {
81 connectable.start();
82 fail("Should have thrown a " + MuleException.class.getSimpleName());
83 }
84 catch (MuleException caughtException)
85 {
86 assertExceptionIsInCaughtException(someMuleException, caughtException);
87 }
88 }
89
90
91
92
93
94
95
96
97
98
99
100
101
102 @Ignore
103 @Test
104 public void testStartIsThreadSafe() throws Throwable
105 {
106 TestFramework.runOnce(new AbstractConnectableMultithreaded());
107 }
108
109
110
111
112
113
114 @Ignore
115 class AbstractConnectableMultithreaded extends MultithreadedTestCase
116 {
117 private volatile AbstractConnectableForTest connectable;
118
119
120
121
122
123 @Override
124 public void initialize()
125 {
126 try
127 {
128 ImmutableEndpoint endpoint = createDummyEndpoint();
129
130 connectable = new AbstractConnectableForTest(endpoint);
131 connectable.initialise();
132 }
133 catch (Exception e)
134 {
135 throw new RuntimeException(e);
136 }
137 }
138
139
140
141
142
143
144
145
146 public void thread1() throws Exception
147 {
148 connectable.start();
149 }
150
151
152
153
154
155 public void thread2() throws Exception
156 {
157
158
159 waitForTick(1);
160 connectable.start();
161 }
162
163
164
165
166
167 @Override
168 public void finish()
169 {
170 for (MethodInvocation methodInvocation : connectable.methodInvocations)
171 {
172 log.debug(methodInvocation);
173 }
174
175 int i = 0;
176 assertEquals("doConnect", connectable.methodInvocations.get(i++).getMethodName());
177 assertEquals("doConnect", connectable.methodInvocations.get(i++).getMethodName());
178 assertEquals("doStart", connectable.methodInvocations.get(i++).getMethodName());
179 assertEquals("doStart", connectable.methodInvocations.get(i++).getMethodName());
180 }
181
182
183
184
185
186
187
188
189
190
191
192
193 @Ignore
194 class AbstractConnectableForTest extends AbstractTransportMessageHandler
195 {
196 private final AtomicBoolean doConnectCalled = new AtomicBoolean();
197 private final AtomicBoolean doStartCalled = new AtomicBoolean();
198
199
200
201
202
203
204 List<MethodInvocation> methodInvocations = new Vector<MethodInvocation>();
205
206 public AbstractConnectableForTest(ImmutableEndpoint endpoint)
207 {
208 super(endpoint);
209 }
210
211 @Override
212 protected WorkManager getWorkManager()
213 {
214 return null;
215 }
216
217 @Override
218 protected ConnectableLifecycleManager createLifecycleManager()
219 {
220 return new ConnectableLifecycleManager("test", this);
221 }
222
223 @Override
224 protected void doConnect() throws Exception
225 {
226 methodInvocations.add(new MethodInvocation(Thread.currentThread(), "doConnect",
227 MethodPart.BEGINNING));
228 assertTrue(doConnectCalled.compareAndSet(false, true));
229 assertFalse(doStartCalled.get());
230
231
232
233
234
235
236
237 waitForTick(2);
238
239 assertFalse(doStartCalled.get());
240
241 methodInvocations.add(new MethodInvocation(Thread.currentThread(), "doConnect",
242 MethodPart.END));
243 }
244
245 @Override
246 protected void doStart() throws MuleException
247 {
248 methodInvocations.add(new MethodInvocation(Thread.currentThread(), "doStart",
249 MethodPart.BEGINNING));
250 assertTrue(doStartCalled.compareAndSet(false, true));
251 assertTrue(doConnectCalled.get());
252 methodInvocations.add(new MethodInvocation(Thread.currentThread(), "doStart", MethodPart.END));
253 }
254
255 }
256 }
257
258
259
260
261
262 @org.junit.Ignore
263 static class MethodInvocation
264 {
265 @Ignore
266 static enum MethodPart
267 {
268 BEGINNING, END
269 }
270
271 private final Thread thread;
272 private final String methodName;
273 private final MethodPart methodPart;
274
275 public MethodInvocation(Thread thread, String methodName, MethodPart methodPart)
276 {
277 this.thread = thread;
278 this.methodName = methodName;
279 this.methodPart = methodPart;
280 }
281
282 public Thread getThread()
283 {
284 return thread;
285 }
286
287 public String getMethodName()
288 {
289 return methodName;
290 }
291
292 public MethodPart getMethodPart()
293 {
294 return methodPart;
295 }
296
297 @Override
298 public boolean equals(Object obj)
299 {
300 if (this == obj)
301 {
302 return true;
303 }
304 else if (obj == null || obj.getClass() != this.getClass())
305 {
306 return false;
307 }
308 else
309 {
310 MethodInvocation other = (MethodInvocation) obj;
311 return new EqualsBuilder().append(this.thread, other.thread).append(this.methodName,
312 other.methodName).append(this.methodPart, other.methodPart).isEquals();
313 }
314 }
315
316 @Override
317 public int hashCode()
318 {
319 return new HashCodeBuilder().append(this.thread)
320 .append(this.methodName)
321 .append(this.methodPart)
322 .toHashCode();
323 }
324
325 @Override
326 public String toString()
327 {
328 return "Thread " + this.thread + " passing through " + this.methodName + "() at the "
329 + this.methodPart;
330 }
331 }
332
333 private void assertExceptionIsInCaughtException(MuleException someMuleException, MuleException caughtException)
334 {
335 boolean found = false;
336 Throwable candidate = caughtException;
337 while (candidate != null)
338 {
339 if (someMuleException.equals(candidate))
340 {
341 found = true;
342 break;
343 }
344
345 candidate = candidate.getCause();
346 }
347
348 if (found == false)
349 {
350 fail();
351 }
352 }
353
354
355
356
357
358
359 ImmutableEndpoint createDummyEndpoint() throws Exception
360 {
361 ImmutableEndpoint endpoint = mock(ImmutableEndpoint.class);
362 MuleContext muleContext = mock(MuleContext.class);
363 when(endpoint.getEndpointURI()).thenReturn(new MuleEndpointURI("http://dummy.endpoint/", muleContext));
364 AbstractConnector connector = mock(AbstractConnector.class);
365 when(endpoint.getConnector()).thenReturn(connector);
366
367 RetryPolicyTemplate retryPolicyTemplate = mock(RetryPolicyTemplate.class);
368 when(endpoint.getRetryPolicyTemplate()).thenReturn(retryPolicyTemplate);
369 when(retryPolicyTemplate.execute(any(RetryCallback.class), any(WorkManager.class))).thenAnswer(
370 new Answer<Object>()
371 {
372 public Object answer(InvocationOnMock invocation) throws Throwable
373 {
374 RetryCallback retryCallback = (RetryCallback) invocation.getArguments()[0];
375 retryCallback.doWork(null);
376 return null;
377 }
378 });
379
380 return endpoint;
381 }
382 }