KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > avalon > excalibur > testcase > ExcaliburTestCase


1 /*
2  * Copyright (C) The Apache Software Foundation. All rights reserved.
3  *
4  * This software is published under the terms of the Apache Software License
5  * version 1.1, a copy of which has been included with this distribution in
6  * the LICENSE.txt file.
7  */

8 package org.apache.avalon.excalibur.testcase;
9
10 import java.io.InputStream JavaDoc;
11
12 import org.apache.avalon.framework.component.ComponentManager;
13 import org.apache.avalon.framework.configuration.Configuration;
14 import org.apache.avalon.framework.configuration.ConfigurationException;
15 import org.apache.avalon.framework.configuration.DefaultConfiguration;
16 import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
17 import org.apache.avalon.framework.context.Context;
18 import org.apache.avalon.framework.context.ContextException;
19 import org.apache.avalon.framework.context.DefaultContext;
20 import org.apache.avalon.framework.activity.Initializable;
21 import org.apache.avalon.framework.activity.Disposable;
22 import org.apache.avalon.framework.logger.LogKitLogger;
23 import org.apache.log.Logger;
24
25 import org.apache.avalon.excalibur.component.DefaultRoleManager;
26 import org.apache.avalon.excalibur.component.ExcaliburComponentManager;
27 import org.apache.avalon.excalibur.logger.DefaultLogKitManager;
28
29 import org.apache.log.Hierarchy;
30 import org.apache.log.LogTarget;
31 import org.apache.log.Priority;
32 import org.apache.log.format.PatternFormatter;
33 import org.apache.log.output.io.StreamTarget;
34
35 import junit.framework.TestCase;
36 import junit.framework.TestResult;
37 import junit.framework.AssertionFailedError;
38
39 import java.lang.reflect.Method JavaDoc;
40 import java.lang.reflect.Modifier JavaDoc;
41 import java.util.ArrayList JavaDoc;
42 import java.util.Iterator JavaDoc;
43 import java.util.HashMap JavaDoc;
44 import java.net.URL JavaDoc;
45
46 /**
47  * JUnit TestCase for Avalon Components
48  * <p>
49  * This class will extends the JUnit TestCase class to setup an environment
50  * to easily test Avalon Components. The following methods and instance variables
51  * are exposed for convenience testing:
52  * </p>
53  * <dl>
54  * <dt>m_logPriority</dt>
55  * <dd>
56  * This variable contains the log priority of the default logger setup
57  * at startup of the test. Overwrite the initialize() method to set a
58  * different Priority.
59  * </dd>
60  * <dt>manager</dt>
61  * <dd>
62  * This instance variable contains a initialized ComponentManager
63  * according to the test case configuration file (see below)
64  * </dd>
65  * <dt>getLogger()</dt>
66  * <dd>
67  * This method returns the default logger for this test case
68  * </dd>
69  * </dl>
70  * <p>
71  * The test case configuration file has the following structure:
72  * </p>
73  * <pre>
74  * &lt;testcase&gt;
75  * &lt;annotation&gt;
76  * &lt;![CDATA[
77  * &lt;title&gt;DataSourceComponent tests&lt;/title&gt;
78  * &lt;para&gt;
79  * This is some &lt;emphasis&gt;text&lt;/emphasis&gt; to
80  * describethe tests made herein. Unfortunately the
81  * ConfigurationBuilder used to read the test case configuration
82  * file doesn't allow to have mixed context. This should be fixed
83  * in a future version .
84  * &lt;/para&gt;
85  * ]]&gt;
86  * &lt;/annotation&gt;
87  *
88  * &lt;logkit&gt;
89  * &lt;factories&gt;
90  * &lt;factory type="file" class="org.apache.avalon.excalibur.logger.facatory.FileTargetFactory"/&gt;
91  * &lt;factory type="property-filter" class="org.apache.avalon.excalibur.logger.facatory.FilterTargetFactory"/&gt;
92  * &lt;factory type="servlet" class="org.apache.avalon.excalibur.logger.facatory.ServletTargetFactory"/&gt;
93  * ...
94  * &lt;/factories&gt;
95  *
96  * &lt;targets&gt;
97  * &lt;file id="root"&gt;
98  * &lt;filename&gt;dev/logs/main.log&lt;/filename&gt;
99  * &lt;/file&gt;
100  * &lt;file id="classloader"&gt;
101  * &lt;filename&gt;dev/logs/classloader.log&lt;/filename&gt;
102  * &lt;/file&gt;
103  * &lt;priority-filter id="servlet" log-level="ERROR"&gt;
104  * &lt;servlet/&gt;
105  * &lt;/priority-filter&gt;
106  * &lt;/targets&gt;
107  *
108  * &lt;categories&gt;
109  * &lt;category name="cocoon" log-level="INFO"&gt;
110  * &lt;log-target id-ref="root"/&gt;
111  * &lt;log-target id-ref="servlet"/&gt;
112  *
113  * &lt;category name="classloader" log-level="DEBUG"&gt;
114  * &lt;log-target id-ref="classloader"/&gt;
115  * &lt;/category&gt;
116  * &lt;/category&gt;
117  * &lt;/categories&gt;
118  * &lt;/logkit&gt;
119  *
120  * &lt;context&gt;
121  * &lt;entry name="foo" value="bar"/&gt;
122  * &lt;entry name="baz" class="my.context.Class"/&gt;
123  * &lt;/context&gt;
124  *
125  * &lt;roles&gt;
126  * &lt;role name="org.apache.avalon.excalibur.datasource.DataSourceComponentSelector"
127  * shorthand="datasources"
128  * default-class="org.apache.avalon.excalibur.component.ExcaliburComponentSelector"&gt;
129  * &lt;hint shorthand="jdbc" class="org.apache.avalon.excalibur.datasource.JdbcDataSource"/&gt;
130  * &lt;/role&gt;
131  * &lt;/roles&gt;
132  *
133  * &lt;components&gt;
134  * &lt;datasources&gt;
135  * &lt;jdbc name="personell"&gt;
136  * &lt;pool-controller min="5" max="10"/&gt;
137  * &lt;jdbc name="personnel"/&gt;
138  * &lt;dburl&gt;jdbc:odbc:test&lt;/dburl&gt;
139  * &lt;user&gt;test&lt;/user&gt;
140  * &lt;password&gt;test&lt;/password&gt;
141  * &lt;driver&gt;sun.jdbc.odbc.JdbcOdbcDriver&lt;/driver&gt;
142  * &lt;/jdbc&gt;
143  * &lt;/datasources&gt;
144  * &lt;/components&gt;
145  * &lt;/testcase&gt;
146  * </pre>
147  *
148  * @author <a HREF="mailto:giacomo@apache.org">Giacomo Pati</a>
149  * @version $Id: ExcaliburTestCase.java,v 1.15 2001/12/11 09:53:32 jefft Exp $
150  */

151 public class ExcaliburTestCase
152     extends TestCase
153 {
154     ///Format of default formatter
155
private static final String JavaDoc FORMAT =
156         "%7.7{priority} %5.5{time} [%8.8{category}] (%{context}): %{message}\\n%{throwable}";
157
158     //The default logger
159
private Logger m_logger;
160     private LogKitLogger m_logEnabledLogger;
161     private ExcaliburComponentManager m_manager;
162     private static HashMap JavaDoc m_tests = new HashMap JavaDoc();
163
164     protected Priority m_logPriority = Priority.DEBUG;
165     protected ComponentManager manager;
166
167     public ExcaliburTestCase( final String JavaDoc name )
168     {
169         super( name );
170
171         ArrayList JavaDoc methodList = (ArrayList JavaDoc) ExcaliburTestCase.m_tests.get(this.getClass());
172
173         Method JavaDoc[] methods = this.getClass().getDeclaredMethods();
174
175         if ( null == methodList )
176         {
177             methodList = new ArrayList JavaDoc( methods.length );
178
179             for ( int i = 0; i < methods.length; i++ )
180             {
181                 String JavaDoc methodName = methods[i].getName();
182                 if (methodName.startsWith( "test" ) &&
183                     ( Modifier.isPublic( methods[i].getModifiers() ) ) &&
184                     ( methods[i].getReturnType().equals( Void.TYPE ) ) &&
185                     ( methods[i].getParameterTypes().length == 0 ) )
186                 {
187                     methodList.add(methodName);
188                 }
189             }
190
191             ExcaliburTestCase.m_tests.put( this.getClass(), methodList );
192         }
193     }
194
195     /** Return the logger */
196     protected Logger getLogger()
197     {
198         if ( null == m_logger )
199         {
200             m_logger = this.setupLogger();
201         }
202
203         return m_logger;
204     }
205
206     /** Return the logger */
207     protected LogKitLogger getLogEnabledLogger()
208     {
209         if ( null == m_logEnabledLogger )
210         {
211             m_logEnabledLogger = new LogKitLogger( this.getLogger() );
212         }
213
214         return m_logEnabledLogger;
215     }
216
217     /**
218      * Initializes the ComponentManager
219      *
220      * The configuration file is determined by the class name plus .xtest appended,
221      * all '.' replaced by '/' and loaded as a resource via classpath
222      */

223     protected void prepare()
224         throws Exception JavaDoc
225     {
226         final String JavaDoc resourceName = this.getClass().getName().replace( '.', '/' ) + ".xtest";
227         URL JavaDoc resource = this.getClass().getClassLoader().getResource( resourceName );
228         if ( resource != null ) {
229             getLogger().debug("Loading resource " + resourceName);
230             prepare( resource.openStream() );
231         }
232         else
233             getLogger().debug("Resource not found " + resourceName);
234     }
235
236     /**
237      * Initializes the ComponentManager
238      *
239      * @param testconf The configuration file is passed as a <code>InputStream</code>
240      *
241      * A common way to supply a InputStream is to overwrite the initialize() method
242      * in the sub class, do there whatever is needed to get the right InputStream object
243      * supplying a conformant xtest configuartion and pass it to this initialize method.
244      * the mentioned initialize method is also the place to set a different logging priority
245      * to the member variable m_logPriority.
246      */

247     protected final void prepare( final InputStream JavaDoc testconf )
248         throws Exception JavaDoc
249     {
250         getLogger().debug( "ExcaliburTestCase.initialize" );
251
252         final DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
253         final Configuration conf = builder.build( testconf );
254
255         String JavaDoc annotation = conf.getChild( "annotation" ).getValue( null );
256
257         if ( ( null != annotation ) || !( "".equals( annotation ) ) )
258         {
259             m_logger.info( annotation );
260         }
261
262         Context context = setupContext( conf.getChild( "context" ) );
263
264         m_manager = setupComponentManager( conf.getChild( "components" ),
265                                            conf.getChild( "roles" ),
266                                            conf.getChild( "logkit" ),
267                                            context );
268         manager = m_manager;
269     }
270
271     /**
272      * Disposes the <code>ComponentManager</code>
273      */

274     final private void done()
275     {
276         if ( null != m_manager )
277         {
278             m_manager.dispose();
279         }
280
281         m_manager = null;
282     }
283
284     /**
285      * Override <code>run</code> so that we can have code that is run once.
286      */

287     final public void run(TestResult result)
288     {
289         ArrayList JavaDoc methodList = (ArrayList JavaDoc) ExcaliburTestCase.m_tests.get( this.getClass() );
290
291         if ( null == methodList || methodList.isEmpty() )
292         {
293             return; // The test was already run! NOTE: this is a hack.
294
}
295
296         try
297         {
298             if (this instanceof Initializable)
299             {
300                 ((Initializable)this).initialize();
301             }
302
303             this.prepare();
304
305             Iterator JavaDoc tests = methodList.iterator();
306
307             while ( tests.hasNext() )
308             {
309                 String JavaDoc methodName = (String JavaDoc) tests.next();
310                 this.setName( methodName );
311                 m_logger = null;
312
313                 if ( this.getLogger().isDebugEnabled() )
314                 {
315                     this.getLogger().debug("Now running the following test: " + methodName);
316                 }
317
318                 super.run(result);
319             }
320
321         }
322         catch ( Exception JavaDoc e )
323         {
324             result.addFailure(this, new AssertionFailedError());
325         }
326         finally
327         {
328             this.done();
329
330             if (this instanceof Disposable)
331             {
332                 try
333                 {
334                     ((Disposable)this).dispose();
335                 }
336                 catch( Exception JavaDoc e )
337                 {
338                     result.addFailure(this, new AssertionFailedError("Disposal Error"));
339                 }
340             }
341         }
342
343         methodList.clear();
344         ExcaliburTestCase.m_tests.put( this.getClass(), methodList );
345     }
346
347     /**
348      * Set up logger configuration
349      */

350     final private Logger setupLogger()
351     {
352         //FIXME(GP): This method should setup a LogConfigurator and LogManager
353
// according to the configuration spec. not yet completed/implemented
354
// It will return a default logger for now.
355
final org.apache.log.Logger logger = Hierarchy.getDefaultHierarchy().getLoggerFor( getName() );
356         logger.setPriority( m_logPriority );
357
358         final PatternFormatter formatter = new PatternFormatter( FORMAT );
359         final StreamTarget target = new StreamTarget( System.out, formatter );
360         logger.setLogTargets( new LogTarget[] { target } );
361
362         return logger;
363     }
364
365     /**
366      * set up a context according to the xtest configuration specifications context
367      * element.
368      *
369      * A method addContext(DefaultContext context) is called here to enable subclasses
370      * to put additional objects into the context programmatically.
371      */

372     final private Context setupContext( final Configuration conf )
373         throws Exception JavaDoc
374     {
375         //FIXME(GP): This method should setup the Context object according to the
376
// configuration spec. not yet completed
377
final DefaultContext context = new DefaultContext();
378         final Configuration [] confs = conf.getChildren( "entry" );
379         for (int i = 0; i < confs.length; i++)
380         {
381             final String JavaDoc key = confs[i].getAttribute( "name" );
382             final String JavaDoc value = confs[i].getAttribute( "value", null );
383             if (value == null) {
384                 String JavaDoc clazz = confs[i].getAttribute( "class" );
385                 Object JavaDoc obj = this.getClass().getClassLoader().loadClass( clazz ).newInstance();
386                 context.put( key, obj );
387                 if (getLogger().isInfoEnabled())
388                     getLogger().info( "ExcaliburTestCase: added an instance of class " + clazz + " to context entry " + key);
389             } else {
390                 context.put( key, value );
391                 if (getLogger().isInfoEnabled())
392                     getLogger().info( "ExcaliburTestCase: added value \"" + value + "\" to context entry " + key);
393             }
394         }
395         addContext( context );
396         return( context );
397     }
398
399     /**
400      * This method may be overwritten by subclasses to put additional objects
401      * into the context programmatically.
402      */

403     protected void addContext( DefaultContext context )
404     {
405     }
406
407     final private ExcaliburComponentManager setupComponentManager ( final Configuration confCM,
408                                                                     final Configuration confRM,
409                                                                     final Configuration confLM,
410                                                                     final Context context )
411         throws Exception JavaDoc
412     {
413         final DefaultRoleManager roleManager = new DefaultRoleManager();
414         roleManager.setLogger( getLogger() );
415         roleManager.configure( confRM );
416
417         final DefaultLogKitManager logKitManager = new DefaultLogKitManager();
418         logKitManager.enableLogging( getLogEnabledLogger() );
419         logKitManager.contextualize( context );
420         logKitManager.configure( confLM );
421
422         final ExcaliburComponentManager manager = new ExcaliburComponentManager();
423         manager.setLogger( getLogger() );
424         manager.setRoleManager( roleManager );
425         manager.contextualize( context );
426         manager.setLogKitManager( logKitManager );
427         manager.configure( confCM );
428         manager.initialize();
429         return manager;
430     }
431 }
432
Popular Tags