View Javadoc

1   /*
2    * $Id: AbstractMuleTestCase.java 7976 2007-08-21 14:26:13Z dirk.olmes $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule.tck;
12  
13  import org.mule.MuleManager;
14  import org.mule.config.MuleConfiguration;
15  import org.mule.impl.MuleDescriptor;
16  import org.mule.tck.testmodels.mule.TestConnector;
17  import org.mule.umo.UMOComponent;
18  import org.mule.umo.UMOEvent;
19  import org.mule.umo.UMOEventContext;
20  import org.mule.umo.UMOException;
21  import org.mule.umo.UMOSession;
22  import org.mule.umo.endpoint.UMOEndpoint;
23  import org.mule.umo.endpoint.UMOImmutableEndpoint;
24  import org.mule.umo.manager.UMOManager;
25  import org.mule.umo.model.UMOModel;
26  import org.mule.umo.transformer.UMOTransformer;
27  import org.mule.util.FileUtils;
28  import org.mule.util.MuleUrlStreamHandlerFactory;
29  import org.mule.util.StringMessageUtils;
30  import org.mule.util.StringUtils;
31  import org.mule.util.SystemUtils;
32  
33  import edu.emory.mathcs.backport.java.util.concurrent.TimeUnit;
34  
35  import java.util.HashMap;
36  import java.util.Map;
37  
38  import junit.framework.TestCase;
39  import junit.framework.TestResult;
40  
41  import org.apache.commons.logging.Log;
42  import org.apache.commons.logging.LogFactory;
43  
44  /**
45   * <code>AbstractMuleTestCase</code> is a base class for Mule testcases. This
46   * implementation provides services to test code for creating mock and test objects.
47   */
48  public abstract class AbstractMuleTestCase extends TestCase
49  {
50      /**
51       * This flag controls whether the text boxes will be logged when starting each test case.
52       */
53      private static final boolean verbose;
54      
55      protected final Log logger = LogFactory.getLog(this.getClass());
56  
57      // This should be set to a string message describing any prerequisites not met
58      private boolean offline = System.getProperty("org.mule.offline", "false").equalsIgnoreCase("true");
59  
60      private static Map testCounters;
61      
62      private TestCaseWatchdog watchdog;
63  
64      static
65      {
66          String muleOpts = SystemUtils.getenv("MULE_TEST_OPTS");
67          if (StringUtils.isNotBlank(muleOpts))
68          {
69              Map parsedOpts = SystemUtils.parsePropertyDefinitions(muleOpts);
70              String optVerbose = (String)parsedOpts.get("mule.verbose");
71              verbose = Boolean.valueOf(optVerbose).booleanValue();
72          }
73          else
74          {
75              // per default, revert to the old behaviour
76              verbose = true;
77          }
78  
79          // register the custom UrlStreamHandlerFactory.
80          MuleUrlStreamHandlerFactory.installUrlStreamHandlerFactory();
81      }
82      
83      public AbstractMuleTestCase()
84      {
85          super();
86          if (testCounters == null)
87          {
88              testCounters = new HashMap();
89          }
90          addTest();
91      }
92  
93      protected void addTest()
94      {
95          TestInfo info = (TestInfo) testCounters.get(getClass().getName());
96          if (info == null)
97          {
98              info = new TestInfo(getClass().getName());
99              testCounters.put(getClass().getName(), info);
100         }
101         info.incTestCount();
102     }
103 
104     protected void setDisposeManagerPerSuite(boolean val)
105     {
106         getTestInfo().setDisposeManagerPerSuite(val);
107     }
108 
109     protected TestInfo getTestInfo()
110     {
111         TestInfo info = (TestInfo) testCounters.get(getClass().getName());
112         if (info == null)
113         {
114             info = new TestInfo(getClass().getName());
115             testCounters.put(getClass().getName(), info);
116         }
117         return info;
118     }
119 
120     private void clearAllCounters()
121     {
122         if (testCounters != null)
123         {
124             testCounters.clear();
125         }
126     }
127 
128     private void clearCounter()
129     {
130         if (testCounters != null)
131         {
132             testCounters.remove(getClass().getName());
133         }
134     }
135 
136     public String getName()
137     {
138         return super.getName().substring(4).replaceAll("([A-Z])", " $1").toLowerCase() + " ";
139     }
140 
141     public void run(TestResult result) 
142     {
143         if (this.isDisabledInThisEnvironment())
144         {
145             logger.info(this.getClass().getName() + " disabled");
146             return;
147         }
148         
149         super.run(result);
150     }
151      
152     /**
153      * Subclasses can override this method to skip the execution of the entire test class.
154      * 
155      * @return <code>true</code> if the test class should not be run.
156      */
157     protected boolean isDisabledInThisEnvironment()
158     {
159         return false;
160     }
161     
162     /**
163      * Shamelessly copy from Spring's ConditionalTestCase so in MULE-2.0 we can extend
164      * this class from ConditionalTestCase.
165      * <p/>
166      * Subclasses can override <code>isDisabledInThisEnvironment</code> to skip a single test.
167      */
168     public void runBare() throws Throwable 
169     {
170         // getName will return the name of the method being run. Use the real JUnit implementation,
171         // this class has a different implementation
172         if (this.isDisabledInThisEnvironment(super.getName())) 
173         {
174             logger.warn(this.getClass().getName() + "." + super.getName() + " disabled in this environment");
175             return;
176         }
177         
178         // Let JUnit handle execution
179         super.runBare();
180     }
181 
182     /**
183      * Should this test run?
184      * @param testMethodName name of the test method
185      * @return whether the test should execute in the current envionment
186      */
187     protected boolean isDisabledInThisEnvironment(String testMethodName) 
188     {
189         return false;
190     }
191 
192     public boolean isOffline(String method)
193     {
194         if (offline)
195         {
196             logger.warn(StringMessageUtils.getBoilerPlate(
197                 "Working offline cannot run test: " + method, '=', 80));
198         }
199         return offline;
200     }
201 
202     protected final void setUp() throws Exception
203     {
204         // start a watchdog thread that kills the VM after 30 minutes timeout
205         watchdog = new TestCaseWatchdog(30, TimeUnit.MINUTES);
206         watchdog.start();
207         
208         if (verbose)
209         {
210             System.out.println(StringMessageUtils.getBoilerPlate("Testing: " + toString(), '=', 80));   
211         }
212         MuleManager.getConfiguration().getDefaultThreadingProfile().setDoThreading(false);
213         MuleManager.getConfiguration().setServerUrl(StringUtils.EMPTY);
214 
215         try
216         {
217             if (getTestInfo().getRunCount() == 0)
218             {
219                 if (getTestInfo().isDisposeManagerPerSuite())
220                 {
221                     // We dispose here jut in case
222                     disposeManager();
223                 }
224                 suitePreSetUp();
225             }
226             if (!getTestInfo().isDisposeManagerPerSuite())
227             {
228                 // We dispose here jut in case
229                 disposeManager();
230             }
231             doSetUp();
232             if (getTestInfo().getRunCount() == 0)
233             {
234                 suitePostSetUp();
235             }
236         }
237         catch (Exception e)
238         {
239             getTestInfo().incRunCount();
240             throw e;
241         }
242     }
243 
244     protected void suitePreSetUp() throws Exception
245     {
246         // nothing to do
247     }
248 
249     protected void suitePostSetUp() throws Exception
250     {
251         // nothing to do
252     }
253 
254     protected void suitePreTearDown() throws Exception
255     {
256         // nothing to do
257     }
258 
259     protected void suitePostTearDown() throws Exception
260     {
261         // nothing to do
262     }
263 
264     protected final void tearDown() throws Exception
265     {
266         try
267         {
268             if (getTestInfo().getRunCount() == getTestInfo().getTestCount())
269             {
270                 suitePreTearDown();
271             }
272             doTearDown();
273             if (!getTestInfo().isDisposeManagerPerSuite())
274             {
275                 disposeManager();
276             }
277         }
278         finally
279         {
280             try
281             {
282                 getTestInfo().incRunCount();
283                 if (getTestInfo().getRunCount() == getTestInfo().getTestCount())
284                 {
285                     try
286                     {
287                         suitePostTearDown();
288                     }
289                     finally
290                     {
291                         clearCounter();
292                         disposeManager();
293                     }
294                 }
295             }
296             finally 
297             {
298                 // remove the watchdog thread in any case
299                 watchdog.cancel();
300             }
301         }
302     }
303 
304     protected void disposeManager() throws UMOException
305     {
306         if (MuleManager.isInstanciated())
307         {
308             MuleManager.getInstance().dispose();
309         }
310         FileUtils.deleteTree(FileUtils.newFile(MuleManager.getConfiguration().getWorkingDirectory()));
311         FileUtils.deleteTree(FileUtils.newFile("./ActiveMQ"));
312         MuleManager.setConfiguration(new MuleConfiguration());
313     }
314 
315     protected void doSetUp() throws Exception
316     {
317         // template method
318     }
319 
320     protected void doTearDown() throws Exception
321     {
322         // template method
323     }
324 
325     public static UMOManager getManager(boolean disableAdminAgent) throws Exception
326     {
327         return MuleTestUtils.getManager(disableAdminAgent);
328     }
329 
330     public static UMOModel getDefaultModel() throws UMOException
331     {
332         return MuleTestUtils.getDefaultModel();
333     }
334 
335     public static UMOEndpoint getTestEndpoint(String name, String type) throws Exception
336     {
337         return MuleTestUtils.getTestEndpoint(name, type);
338     }
339 
340     public static UMOEvent getTestEvent(Object data) throws Exception
341     {
342         return MuleTestUtils.getTestEvent(data);
343     }
344 
345     public static UMOEventContext getTestEventContext(Object data) throws Exception
346     {
347         return MuleTestUtils.getTestEventContext(data);
348     }
349 
350     public static UMOTransformer getTestTransformer()
351     {
352         return MuleTestUtils.getTestTransformer();
353     }
354 
355     public static UMOEvent getTestEvent(Object data, MuleDescriptor descriptor) throws Exception
356     {
357         return MuleTestUtils.getTestEvent(data, descriptor);
358     }
359 
360     public static UMOEvent getTestEvent(Object data, UMOImmutableEndpoint endpoint) throws Exception
361     {
362         return MuleTestUtils.getTestEvent(data, endpoint);
363     }
364 
365     public static UMOEvent getTestEvent(Object data, MuleDescriptor descriptor, UMOImmutableEndpoint endpoint)
366         throws UMOException
367     {
368         return MuleTestUtils.getTestEvent(data, descriptor, endpoint);
369     }
370 
371     public static UMOSession getTestSession(UMOComponent component)
372     {
373         return MuleTestUtils.getTestSession(component);
374     }
375 
376     public static TestConnector getTestConnector()
377     {
378         return MuleTestUtils.getTestConnector();
379     }
380 
381     public static UMOComponent getTestComponent(MuleDescriptor descriptor)
382     {
383         return MuleTestUtils.getTestComponent(descriptor);
384     }
385 
386     public static MuleDescriptor getTestDescriptor(String name, String implementation) throws Exception
387     {
388         return MuleTestUtils.getTestDescriptor(name, implementation);
389     }
390 
391     public static UMOManager getTestManager() throws Exception
392     {
393         return MuleTestUtils.getManager(true);
394     }
395 
396     protected void finalize() throws Throwable
397     {
398         try
399         {
400             clearAllCounters();
401         }
402         finally
403         {
404             super.finalize();
405         }
406     }
407 
408     protected class TestInfo
409     {
410         /**
411          * Whether to dispose the manager after every method or once all tests for
412          * the class have run
413          */
414         private boolean disposeManagerPerSuite = false;
415         private int testCount = 0;
416         private int runCount = 0;
417         private String name;
418 
419         public TestInfo(String name)
420         {
421             this.name = name;
422         }
423 
424         public void clearCounts()
425         {
426             testCount = 0;
427             runCount = 0;
428         }
429 
430         public void incTestCount()
431         {
432             testCount++;
433         }
434 
435         public void incRunCount()
436         {
437             runCount++;
438         }
439 
440         public int getTestCount()
441         {
442             return testCount;
443         }
444 
445         public int getRunCount()
446         {
447             return runCount;
448         }
449 
450         public String getName()
451         {
452             return name;
453         }
454 
455         public boolean isDisposeManagerPerSuite()
456         {
457             return disposeManagerPerSuite;
458         }
459 
460         public void setDisposeManagerPerSuite(boolean disposeManagerPerSuite)
461         {
462             this.disposeManagerPerSuite = disposeManagerPerSuite;
463         }
464 
465         public String toString()
466         {
467             StringBuffer buf = new StringBuffer();
468             return buf.append(name).append(", (").append(runCount).append(" / ").append(testCount).append(
469                 ") tests run, disposePerSuite=").append(disposeManagerPerSuite).toString();
470         }
471     }
472 }