1
2
3
4
5
6
7
8
9
10
11 package org.mule.tck;
12
13 import org.mule.MuleServer;
14 import org.mule.RegistryContext;
15 import org.mule.api.MuleContext;
16 import org.mule.api.MuleEvent;
17 import org.mule.api.MuleEventContext;
18 import org.mule.api.MuleSession;
19 import org.mule.api.config.ConfigurationBuilder;
20 import org.mule.api.context.MuleContextBuilder;
21 import org.mule.api.context.MuleContextFactory;
22 import org.mule.api.endpoint.ImmutableEndpoint;
23 import org.mule.api.endpoint.InboundEndpoint;
24 import org.mule.api.endpoint.OutboundEndpoint;
25 import org.mule.api.routing.filter.Filter;
26 import org.mule.api.service.Service;
27 import org.mule.api.transformer.Transformer;
28 import org.mule.config.builders.DefaultsConfigurationBuilder;
29 import org.mule.config.builders.SimpleConfigurationBuilder;
30 import org.mule.context.DefaultMuleContextBuilder;
31 import org.mule.context.DefaultMuleContextFactory;
32 import org.mule.tck.testmodels.mule.TestConnector;
33 import org.mule.util.FileUtils;
34 import org.mule.util.MuleUrlStreamHandlerFactory;
35 import org.mule.util.StringMessageUtils;
36 import org.mule.util.StringUtils;
37 import org.mule.util.SystemUtils;
38 import org.mule.util.concurrent.Latch;
39
40 import java.io.IOException;
41 import java.net.URI;
42 import java.net.URISyntaxException;
43 import java.net.URL;
44 import java.net.URLClassLoader;
45 import java.security.CodeSource;
46 import java.util.ArrayList;
47 import java.util.Collections;
48 import java.util.HashMap;
49 import java.util.HashSet;
50 import java.util.Iterator;
51 import java.util.List;
52 import java.util.Map;
53 import java.util.Properties;
54 import java.util.Set;
55
56 import junit.framework.TestCase;
57 import junit.framework.TestResult;
58
59 import edu.emory.mathcs.backport.java.util.concurrent.TimeUnit;
60
61 import org.apache.commons.collections.IteratorUtils;
62 import org.apache.commons.collections.Predicate;
63 import org.apache.commons.logging.Log;
64 import org.apache.commons.logging.LogFactory;
65
66
67
68
69
70 public abstract class AbstractMuleTestCase extends TestCase implements TestCaseWatchdogTimeoutHandler
71 {
72
73
74
75
76
77
78 public static final String[] IGNORED_DOT_MULE_DIRS = new String[]{"transaction-log"};
79
80 protected static MuleContext muleContext;
81
82
83
84
85 private static final boolean verbose;
86
87
88
89 private static final Map testInfos = Collections.synchronizedMap(new HashMap());
90
91
92 protected final transient Log logger = LogFactory.getLog(this.getClass());
93
94
95
96
97 private boolean startContext = false;
98
99
100 private boolean offline = "true".equalsIgnoreCase(System.getProperty("org.mule.offline"));
101
102
103 private TestCaseWatchdog watchdog;
104
105 static
106 {
107 String muleOpts = SystemUtils.getenv("MULE_TEST_OPTS");
108 if (StringUtils.isNotBlank(muleOpts))
109 {
110 Map parsedOpts = SystemUtils.parsePropertyDefinitions(muleOpts);
111 String optVerbose = (String) parsedOpts.get("mule.verbose");
112 verbose = Boolean.valueOf(optVerbose).booleanValue();
113 }
114 else
115 {
116
117 verbose = true;
118 }
119
120
121 MuleUrlStreamHandlerFactory.installUrlStreamHandlerFactory();
122 }
123
124
125
126
127 public static final String TEST_MESSAGE = "Test Message";
128
129
130
131
132
133
134
135 public static final long LOCK_TIMEOUT = 30000;
136
137
138
139
140 public static final int RECEIVE_TIMEOUT = 5000;
141
142
143
144
145 protected Latch callbackCalled;
146
147 public AbstractMuleTestCase()
148 {
149 super();
150
151 TestInfo info = (TestInfo) testInfos.get(getClass().getName());
152 if (info == null)
153 {
154 info = this.createTestInfo();
155 testInfos.put(getClass().getName(), info);
156 }
157 this.registerTestMethod();
158 }
159
160 protected void registerTestMethod()
161 {
162 if (this.getName() != null)
163 {
164 this.getTestInfo().incTestCount(getName());
165 }
166 }
167
168 public void setName(String name)
169 {
170 super.setName(name);
171 registerTestMethod();
172 }
173
174 protected TestInfo createTestInfo()
175 {
176 return new TestInfo(this);
177 }
178
179 protected TestInfo getTestInfo()
180 {
181 return (TestInfo) testInfos.get(this.getClass().getName());
182 }
183
184 private void clearInfo()
185 {
186 testInfos.remove(this.getClass().getName());
187 }
188
189 public String getName()
190 {
191 if (verbose && super.getName() != null)
192 {
193 return super.getName().substring(4).replaceAll("([A-Z])", " $1").toLowerCase() + " ";
194 }
195 return super.getName();
196 }
197
198 public void run(TestResult result)
199 {
200 if (this.isExcluded())
201 {
202 if (verbose)
203 {
204 logger.info(this.getClass().getName() + " excluded");
205 }
206 return;
207 }
208
209 if (this.isDisabledInThisEnvironment())
210 {
211 if (verbose)
212 {
213 logger.info(this.getClass().getName() + " disabled");
214 }
215 return;
216 }
217
218 super.run(result);
219 }
220
221
222
223
224
225
226
227 public void runBare() throws Throwable
228 {
229
230
231 if (this.isDisabledInThisEnvironment(super.getName()))
232 {
233 logger.warn(this.getClass().getName() + "." + super.getName() + " disabled in this environment");
234 return;
235 }
236
237
238 super.runBare();
239 }
240
241
242
243
244
245
246 protected boolean isDisabledInThisEnvironment()
247 {
248 return false;
249 }
250
251
252
253
254
255
256
257 protected boolean isExcluded()
258 {
259 return getTestInfo().isExcluded();
260 }
261
262
263
264
265
266
267
268 protected boolean isDisabledInThisEnvironment(String testMethodName)
269 {
270 return false;
271 }
272
273 public boolean isOffline(String method)
274 {
275 if (offline)
276 {
277 logger.warn(StringMessageUtils.getBoilerPlate(
278 "Working offline cannot run test: " + method, '=', 80));
279 }
280 return offline;
281 }
282
283 protected boolean isDisposeManagerPerSuite()
284 {
285 return getTestInfo().isDisposeManagerPerSuite();
286 }
287
288 protected void setDisposeManagerPerSuite(boolean val)
289 {
290 getTestInfo().setDisposeManagerPerSuite(val);
291 }
292
293 protected TestCaseWatchdog createWatchdog()
294 {
295 return new TestCaseWatchdog(10, TimeUnit.MINUTES, this);
296 }
297
298 public void handleTimeout(long timeout, TimeUnit unit)
299 {
300 logger.fatal("Timeout of " + unit.toMillis(timeout) + "ms exceeded - exiting VM!");
301 Runtime.getRuntime().halt(1);
302 }
303
304 protected final void setUp() throws Exception
305 {
306
307 watchdog = createWatchdog();
308 watchdog.start();
309
310 if (verbose)
311 {
312 System.out.println(StringMessageUtils.getBoilerPlate("Testing: " + toString(), '=', 80));
313 }
314
315 try
316 {
317 if (getTestInfo().getRunCount() == 0)
318 {
319 if (getTestInfo().isDisposeManagerPerSuite())
320 {
321
322 disposeManager();
323 }
324 suitePreSetUp();
325 }
326 if (!getTestInfo().isDisposeManagerPerSuite())
327 {
328
329 disposeManager();
330 }
331
332 muleContext = createMuleContext();
333 if (isStartContext() && null != muleContext && muleContext.isStarted() == false)
334 {
335 muleContext.start();
336 }
337
338 doSetUp();
339 }
340 catch (Exception e)
341 {
342 getTestInfo().incRunCount();
343 throw e;
344 }
345 }
346
347 protected MuleContext createMuleContext() throws Exception
348 {
349
350 MuleContext context;
351 if (getTestInfo().isDisposeManagerPerSuite() && muleContext != null)
352 {
353 context = muleContext;
354 }
355 else
356 {
357 MuleContextFactory muleContextFactory = new DefaultMuleContextFactory();
358 List builders = new ArrayList();
359 builders.add(new SimpleConfigurationBuilder(getStartUpProperties()));
360 builders.add(getBuilder());
361 MuleContextBuilder contextBuilder = new DefaultMuleContextBuilder();
362 configureMuleContext(contextBuilder);
363 context = muleContextFactory.createMuleContext(builders, contextBuilder);
364 }
365 return context;
366 }
367
368
369
370
371
372 protected void configureMuleContext(MuleContextBuilder contextBuilder)
373 {
374 contextBuilder.setWorkListener(new TestingWorkListener());
375 }
376
377 protected ConfigurationBuilder getBuilder() throws Exception
378 {
379 return new DefaultsConfigurationBuilder();
380 }
381
382 protected String getConfigurationResources()
383 {
384 return StringUtils.EMPTY;
385 }
386
387 protected Properties getStartUpProperties()
388 {
389 return null;
390 }
391
392
393
394
395 protected void suitePreSetUp() throws Exception
396 {
397
398 }
399
400
401
402
403 protected void suitePostTearDown() throws Exception
404 {
405
406 }
407
408 protected final void tearDown() throws Exception
409 {
410 try
411 {
412 doTearDown();
413
414 if (!getTestInfo().isDisposeManagerPerSuite())
415 {
416 disposeManager();
417 }
418 }
419 finally
420 {
421 try
422 {
423 getTestInfo().incRunCount();
424 if (getTestInfo().getRunCount() == getTestInfo().getTestCount())
425 {
426 try
427 {
428 suitePostTearDown();
429 }
430 finally
431 {
432 clearInfo();
433 disposeManager();
434 }
435 }
436 }
437 finally
438 {
439
440 watchdog.cancel();
441 }
442 }
443 }
444
445 protected void disposeManager()
446 {
447 try
448 {
449 if (muleContext != null && !(muleContext.isDisposed() || muleContext.isDisposing()))
450 {
451 muleContext.dispose();
452
453 final String workingDir = muleContext.getConfiguration().getWorkingDirectory();
454
455
456 FileUtils.deleteTree(FileUtils.newFile(workingDir), IGNORED_DOT_MULE_DIRS);
457 }
458 FileUtils.deleteTree(FileUtils.newFile("./ActiveMQ"));
459 }
460 finally
461 {
462 muleContext = null;
463 RegistryContext.setRegistry(null);
464 MuleServer.setMuleContext(null);
465 }
466 }
467
468 protected void doSetUp() throws Exception
469 {
470
471 }
472
473 protected void doTearDown() throws Exception
474 {
475
476 }
477
478 public static InboundEndpoint getTestInboundEndpoint(String name) throws Exception
479 {
480 return MuleTestUtils.getTestInboundEndpoint(name, muleContext);
481 }
482
483 public static OutboundEndpoint getTestOutboundEndpoint(String name) throws Exception
484 {
485 return MuleTestUtils.getTestOutboundEndpoint(name, muleContext);
486 }
487
488 public static InboundEndpoint getTestInboundEndpoint(String name, String uri) throws Exception
489 {
490 return MuleTestUtils.getTestInboundEndpoint(name, muleContext, uri, null, null, null);
491 }
492
493 public static OutboundEndpoint getTestOutboundEndpoint(String name, String uri) throws Exception
494 {
495 return MuleTestUtils.getTestOutboundEndpoint(name, muleContext, uri, null, null, null);
496 }
497
498 public static InboundEndpoint getTestInboundEndpoint(String name, List transformers) throws Exception
499 {
500 return MuleTestUtils.getTestInboundEndpoint(name, muleContext, null, transformers, null, null);
501 }
502
503 public static OutboundEndpoint getTestOutboundEndpoint(String name, List transformers) throws Exception
504 {
505 return MuleTestUtils.getTestOutboundEndpoint(name, muleContext, null, transformers, null, null);
506 }
507
508 public static InboundEndpoint getTestInboundEndpoint(String name, String uri, List transformers, Filter filter, Map properties) throws Exception
509 {
510 return MuleTestUtils.getTestInboundEndpoint(name, muleContext, uri, transformers, filter, properties);
511 }
512
513 public static OutboundEndpoint getTestOutboundEndpoint(String name, String uri, List transformers, Filter filter, Map properties) throws Exception
514 {
515 return MuleTestUtils.getTestOutboundEndpoint(name, muleContext, uri, transformers, filter, properties);
516 }
517
518 public static MuleEvent getTestEvent(Object data, Service service) throws Exception
519 {
520 return MuleTestUtils.getTestEvent(data, service, muleContext);
521 }
522
523 public static MuleEvent getTestEvent(Object data) throws Exception
524 {
525 return MuleTestUtils.getTestEvent(data, muleContext);
526 }
527
528 public static MuleEvent getTestInboundEvent(Object data) throws Exception
529 {
530 return MuleTestUtils.getTestInboundEvent(data, muleContext);
531 }
532
533 public static MuleEventContext getTestEventContext(Object data) throws Exception
534 {
535 return MuleTestUtils.getTestEventContext(data, muleContext);
536 }
537
538 public static Transformer getTestTransformer() throws Exception
539 {
540 return MuleTestUtils.getTestTransformer();
541 }
542
543 public static MuleEvent getTestEvent(Object data, ImmutableEndpoint endpoint) throws Exception
544 {
545 return MuleTestUtils.getTestEvent(data, endpoint, muleContext);
546 }
547
548 public static MuleEvent getTestEvent(Object data, Service service, ImmutableEndpoint endpoint)
549 throws Exception
550 {
551 return MuleTestUtils.getTestEvent(data, service, endpoint, muleContext);
552 }
553
554 public static MuleSession getTestSession(Service service, MuleContext context)
555 {
556 return MuleTestUtils.getTestSession(service, context);
557 }
558
559 public static TestConnector getTestConnector() throws Exception
560 {
561 return MuleTestUtils.getTestConnector(muleContext);
562 }
563
564 public static Service getTestService() throws Exception
565 {
566 return MuleTestUtils.getTestService(muleContext);
567 }
568
569 public static Service getTestService(String name, Class clazz) throws Exception
570 {
571 return MuleTestUtils.getTestService(name, clazz, muleContext);
572 }
573
574 public static Service getTestService(String name, Class clazz, Map props) throws Exception
575 {
576 return MuleTestUtils.getTestService(name, clazz, props, muleContext);
577 }
578
579 public static class TestInfo
580 {
581
582
583
584
585 private final String name;
586 private boolean disposeManagerPerSuite = false;
587 private boolean excluded = false;
588 private volatile int testCount = 0;
589 private volatile int runCount = 0;
590
591 private Set registeredTestMethod = new HashSet();
592
593
594
595
596 public static URL getClassPathRoot(Class clazz)
597 {
598 CodeSource cs = clazz.getProtectionDomain().getCodeSource();
599 return (cs != null ? cs.getLocation() : null);
600 }
601
602 public TestInfo(TestCase test)
603 {
604 this.name = test.getClass().getName();
605
606
607 try
608 {
609
610
611
612 URL[] urls = new URL[]{getClassPathRoot(test.getClass())};
613 URL fileUrl = new URLClassLoader(urls).getResource("mule-test-exclusions.txt");
614
615 if (fileUrl != null)
616 {
617
618 URI fileUri = new URI(StringUtils.removeStart(fileUrl.toString(), "jar:"));
619
620
621 Iterator lines = FileUtils.lineIterator(FileUtils.newFile(fileUri));
622
623
624 excluded = IteratorUtils.filteredIterator(lines, new Predicate()
625 {
626 public boolean evaluate(Object object)
627 {
628 return StringUtils.equals(name, StringUtils.trimToEmpty((String) object));
629 }
630 }).hasNext();
631 }
632 }
633 catch (IOException ioex)
634 {
635
636 }
637 catch (URISyntaxException e)
638 {
639
640 }
641 }
642
643 public int getTestCount()
644 {
645 return testCount;
646 }
647
648 public synchronized void incTestCount(String name)
649 {
650 if (!registeredTestMethod.contains(name))
651 {
652 testCount++;
653 registeredTestMethod.add(name);
654 }
655 }
656
657 public int getRunCount()
658 {
659 return runCount;
660 }
661
662 public void incRunCount()
663 {
664 runCount++;
665 }
666
667 public String getName()
668 {
669 return name;
670 }
671
672 public boolean isDisposeManagerPerSuite()
673 {
674 return disposeManagerPerSuite;
675 }
676
677 public void setDisposeManagerPerSuite(boolean disposeManagerPerSuite)
678 {
679 this.disposeManagerPerSuite = disposeManagerPerSuite;
680 }
681
682 public boolean isExcluded()
683 {
684 return excluded;
685 }
686
687 public synchronized String toString()
688 {
689 StringBuffer buf = new StringBuffer();
690 return buf.append(name).append(", (").append(runCount).append(" / ").append(testCount).append(
691 ") tests run, disposePerSuite=").append(disposeManagerPerSuite).toString();
692 }
693 }
694
695 protected boolean isStartContext()
696 {
697 return startContext;
698 }
699
700 protected void setStartContext(boolean startContext)
701 {
702 this.startContext = startContext;
703 }
704 }