bloritsch 2003/06/06 13:34:44
Modified: fortress/src/tools/org/apache/avalon/fortress/testcase
FortressTestCase.java
Log:
fixCRLF from browser translation...
Revision Changes Path
1.2 +591 -591
avalon-excalibur/fortress/src/tools/org/apache/avalon/fortress/testcase/FortressTestCase.java
Index: FortressTestCase.java
===================================================================
RCS file:
/home/cvs/avalon-excalibur/fortress/src/tools/org/apache/avalon/fortress/testcase/FortressTestCase.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- FortressTestCase.java 6 Jun 2003 20:33:14 -0000 1.1
+++ FortressTestCase.java 6 Jun 2003 20:34:44 -0000 1.2
@@ -1,591 +1,591 @@
-/*
-
- ============================================================================
- The Apache Software License, Version 1.1
- ============================================================================
-
- Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without modifica-
- tion, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-
- 3. The end-user documentation included with the redistribution, if any, must
- include the following acknowledgment: "This product includes software
- developed by the Apache Software Foundation (http://www.apache.org/)."
- Alternately, this acknowledgment may appear in the software itself, if
- and wherever such third-party acknowledgments normally appear.
-
- 4. The names "Jakarta", "Avalon", "Excalibur" and "Apache Software Foundation"
- must not be used to endorse or promote products derived from this software
- without prior written permission. For written permission, please contact
- [EMAIL PROTECTED]
-
- 5. Products derived from this software may not be called "Apache", nor may
- "Apache" appear in their name, without prior written permission of the
- Apache Software Foundation.
-
- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
- DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- This software consists of voluntary contributions made by many individuals
- on behalf of the Apache Software Foundation. For more information on the
- Apache Software Foundation, please see <http://www.apache.org/>.
-
-*/
-package org.apache.avalon.fortress.testcase;
-
-import java.io.InputStream;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-
-import org.apache.avalon.excalibur.logger.LoggerManager;
-import org.apache.avalon.fortress.impl.DefaultContainer;
-import org.apache.avalon.fortress.impl.DefaultContainerManager;
-import org.apache.avalon.fortress.util.FortressConfig;
-import org.apache.avalon.fortress.util.OverridableContext;
-import org.apache.avalon.framework.activity.Disposable;
-import org.apache.avalon.framework.activity.Initializable;
-import org.apache.avalon.framework.configuration.Configuration;
-import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
-import org.apache.avalon.framework.container.ContainerUtil;
-import org.apache.avalon.framework.context.Context;
-import org.apache.avalon.framework.context.DefaultContext;
-import org.apache.avalon.framework.logger.Logger;
-import org.apache.avalon.framework.logger.LogKitLogger;
-import org.apache.avalon.framework.service.ServiceException;
-import org.apache.avalon.framework.service.ServiceManager;
-
-import junit.framework.AssertionFailedError;
-import junit.framework.TestCase;
-import junit.framework.TestResult;
-
-import org.apache.log.Hierarchy;
-import org.apache.log.LogTarget;
-import org.apache.log.Priority;
-import org.apache.log.format.PatternFormatter;
-import org.apache.log.output.io.StreamTarget;
-
-/**
- * JUnit TestCase for Avalon Components in Fortress.
- * <p>
- * This class extends the JUnit TestCase class to setup an environment which
- * makes it possible to easily test Avalon Components. The following methods
- * and instance variables are exposed for convenience testing:
- * </p>
- * <dl>
- * <dt>m_serviceManager</dt>
- * <dd>
- * This instance variable contains an initialized ServiceLocator which
- * can be used to lookup Components configured in the test configuration
- * file. (see below)
- * </dd>
- * <dt>getLogger()</dt>
- * <dd>
- * This method returns the default logger for this test case
- * </dd>
- * </dl>
- * <p>
- * The following test case configuration can be used as a basis for new tests.
- * Detailed are explanations of the configuration elements can be found after
- * the example. The example will log all logger output to the console and to
- * a log file.
- * </p>
- * <pre>
- * <testcase>
- * <annotation>
- * <![CDATA[
- * <title>{Name of test}</title>
- * <para>
- * {Description of test}
- * The configuration is specified in the file located in
- * <parameter>avalon-excalibur/src/test/{path and name of conf
file}.xtext</parameter>.
- * </para>
- * ]]>
- * </annotation>
- *
- * <logger log-level="INFO">
- * <factories>
- * <factory type="stream"
class="org.apache.avalon.excalibur.logger.factory.StreamTargetFactory"/>
- * <factory type="file"
class="org.apache.avalon.excalibur.logger.factory.FileTargetFactory"/>
- * </factories>
- *
- * <targets>
- * <stream id="console">
- * <stream>System.out</stream>
- * <format type="avalon">
- * %7.7{priority} %23.23{time:yyyy-MM-dd' 'HH:mm:ss.SSS}
[%30.30{category}] (%{context}): %{message}\n%{throwable}
- * </format>
- * </stream>
- * <file id="log-file">
- * <filename>TEST-{full test class name}.log</filename>
- * <format type="avalon">
- * %7.7{priority} %23.23{time:yyyy-MM-dd' 'HH:mm:ss.SSS}
[%30.30{category}] (%{context}): %{message}\n%{throwable}
- * </format>
- * </file>
- * </targets>
- *
- * <categories>
- * <category name="test" log-level="INFO">
- * <log-target id-ref="console"/>
- * <log-target id-ref="log-file"/>
- * </category>
- * <category name="jdbc" log-level="INFO">
- * <log-target id-ref="console"/>
- * <log-target id-ref="log-file"/>
- * </category>
- * </categories>
- * </logger>
- *
- * <context>
- * <entry name="foo" value="bar"/>
- * <entry name="baz" class="my.context.Class"/>
- * </context>
- *
- * <roles>
- * <role name="org.apache.avalon.excalibur.datasource.DataSourceComponent"
- * <component shorthand="jdbc"
- * class="org.apache.avalon.excalibur.datasource.JdbcDataSource"
- *
handler="org.apache.avalon.fortress.impl.handler.ThreadSafeComponentHandler"/>
- * </role>
- * </roles>
- *
- * <components>
- * <jdbc name="personell" logger="jdbc">
- * <pool-controller min="5" max="10"/>
- * <jdbc name="personnel"/>
- * <dburl>jdbc:odbc:test</dburl>
- * <user>test</user>
- * <password>test</password>
- * <driver>sun.jdbc.odbc.JdbcOdbcDriver</driver>
- * </jdbc>
- * </components>
- * </testcase>
- * </pre>
- * <p>
- * Element Explanation:
- * <dl>
- * <dt>testcase</dt>
- * <dd>Defines a test case configuration. Must contain one each of the
- * following elements: <code>annotation</code>, <code>logger</code>,
- * <code>context</code>, <code>roles</code>, and <code>components</code>
- * </dd>.
- *
- * <dt>annotation</dt>
- * <dd>Defines a test annotation. This element should define a block of
- * XML enclosed within a CDATA element. The XML should be made up of a
- * <code>title</code> element, naming the test, and a <code>para</code>
- * element which is used to describe the test.</dd>
- *
- * <dt>logger</dt>
- * <dd>Configures the logger used by the test cases and the components used
- * by the tests. The <code>logger</code> element takes two optional
- * attributes:
- * <dl>
- * <dt>logger</dt><dd>Uses to name the logger which is used to bootstrap
- * the LogKit logger. (Defaults to <code>"lm"</code>)</dd>
- * <dt>log-level</dt><dd>Because the logger used by the LogKit must be
- * created before the Log Kit Manager is initialized, it must be fully
- * configured before the <code>logger</code> element is parsed. This
- * attribute allows the Log Kit's log priority to be set. This log
- * level will also become the default for the Role Manager, Service
- * Manager, and all components if they do not have <code>category</code>
- * elements declated in the <code>logger</code> element.
- * (Defaults to "INFO")</dd>
- * </dl>
- * The loggers used by test cases and components can be easily configured
- * from within this file. The default test configuration, shown above,
- * includes a "test" category. This category is used to configure the
- * default logger for all test cases. If it is set to "DEBUG", then all
- * test debug logging will be enabled. To enalble debug logging for a
- * single test case, a child category must be defined for the
- * "testCheckTotals" test case as follows:
- * <pre>
- * <categories>
- * <category name="test" log-level="INFO">
- * <log-target id-ref="console"/>
- * <log-target id-ref="log-file"/>
- *
- * <category name="testCheckTotals" log-level="DEBUG">
- * <log-target id-ref="console"/>
- * <log-target id-ref="log-file"/>
- * </category>
- * </category>
- * </categories>
- * </pre>
- * For general information on how to configure the Logger Manager, please
- * refer to the Log Kit documentation.
- * </dd>
- *
- * <dt>context</dt>
- * <dd>Allows context properties to be set in the context passed to any
- * Contextualizable components.</dd>
- *
- * <dt>roles</dt>
- * <dd>Roles configuration for the Components configured in the
- * <code>components</code> element. The logger used by the RoleManager
- * can be configured using a <code>logger</code> attribute, which defaults
- * to "rm". By default this logger will have the same log level and
- * formatting as the LogKit logger. It can be configured by adding a
- * <code>category</code> within the <code>logger</code> element.</dd>
- *
- * <dt>components</dt>
- * <dd>Used to configure any Components used by the test cases. The logger
- * used by the ServiceLocator can be configured using a <code>logger</code>
- * attribute, which defaults to "cm". By default this logger will have the
- * same log level and formatting as the LogKit logger. It can be configured
- * by adding a <code>category</code> within the <code>logger</code> element.
- * </dd>
- *
- * </dl>
- *
- * @author <a href="mailto:[EMAIL PROTECTED]">Giacomo Pati</a>
- * @author unico
- */
-public class FortressTestCase extends TestCase
-{
-
- ///Format of default formatter
- private static final String FORMAT =
- "%7.7{priority} %23.23{time:yyyy-MM-dd' 'HH:mm:ss.SSS}
[%30.30{category}] " +
- "(%{context}): %{message}\n%{throwable}";
-
-
- //The default logger
- private Logger m_logger;
-
- // The container manager
- private DefaultContainerManager m_containerManager;
-
- // The container itself
- private DefaultContainer m_container;
-
- private LoggerManager m_loggerManager;
- private ServiceManager m_serviceManager;
-
-
- private static HashMap m_tests = new HashMap();
-
-
- public FortressTestCase( final String name )
- {
- super( name );
-
- ArrayList methodList = (ArrayList)FortressTestCase.m_tests.get(
getClass() );
-
- Method[] methods = getClass().getMethods();
-
- if( null == methodList )
- {
- methodList = new ArrayList( methods.length );
-
- for( int i = 0; i < methods.length; i++ )
- {
- String methodName = methods[ i ].getName();
- if( methodName.startsWith( "test" ) &&
- ( Modifier.isPublic( methods[ i
].getModifiers() ) ) &&
- ( methods[ i ].getReturnType().equals(
Void.TYPE ) ) &&
- ( methods[ i ].getParameterTypes().length == 0
) )
- {
- methodList.add( methodName );
- }
- }
-
- FortressTestCase.m_tests.put( getClass(), methodList );
- }
- }
-
- protected final boolean hasService( final String key )
- {
- return m_serviceManager.hasService( key );
- }
-
- protected final Object lookup( final String key )
- throws ServiceException
- {
- return m_serviceManager.lookup( key );
- }
-
- protected final void release( final Object object )
- {
- m_serviceManager.release( object );
- }
-
- /** Return the logger */
- protected Logger getLogger()
- {
- return m_logger;
- }
-
-
- /**
- * Override <code>run</code> so that we can have code that is run once.
- */
- public final void run( TestResult result )
- {
- ArrayList methodList = (ArrayList)FortressTestCase.m_tests.get(
getClass() );
-
- if( null == methodList || methodList.isEmpty() )
- {
- return; // The test was already run! NOTE: this is a hack.
- }
-
- // Set the logger for the initialization phase.
- setCurrentLogger( getBaseClassName( getClass() ) );
-
- try
- {
-
- prepare();
-
- if( this instanceof Initializable )
- {
- ( (Initializable)this ).initialize();
- }
-
- Iterator tests = methodList.iterator();
-
- while( tests.hasNext() )
- {
- String methodName = (String)tests.next();
- setName( methodName );
- setCurrentLogger( methodName );
-
- if( getLogger().isDebugEnabled() )
- {
- getLogger().debug( "" );
- getLogger().debug(
"========================================" );
- getLogger().debug( " begin test: " +
methodName );
- getLogger().debug(
"========================================" );
- }
-
- super.run( result );
-
- if( getLogger().isDebugEnabled() )
- {
- getLogger().debug(
"========================================" );
- getLogger().debug( " end test: " + methodName
);
- getLogger().debug(
"========================================" );
- getLogger().debug( "" );
- }
- }
-
- }
- catch( Exception e )
- {
- System.out.println( e );
- e.printStackTrace();
- result.addError( this, e );
- }
- finally
- {
- done();
-
- if( this instanceof Disposable )
- {
- try
- {
- ( (Disposable)this ).dispose();
- }
- catch( Exception e )
- {
- result.addFailure( this, new
AssertionFailedError( "Disposal Error" ) );
- }
- }
- }
-
- methodList.clear();
- FortressTestCase.m_tests.put( getClass(), methodList );
- }
-
- /**
- * Initializes Fortress.
- *
- * The configuration file is determined by the class name plus .xtest appended,
- * all '.' replaced by '/' and loaded as a resource via classpath
- */
- protected void prepare() throws Exception
- {
- setCurrentLogger( "prepare" );
-
- final String resourceName = getClass().getName().replace( '.', '/' ) +
".xtest";
- URL resource = getClass().getClassLoader().getResource( resourceName );
-
- if( resource != null )
- {
- getLogger().debug( "Loading resource " + resourceName );
- prepare( resource.openStream() );
- }
- else
- {
- getLogger().warn( "Resource not found " + resourceName );
- }
- }
-
- /**
- * Initializes Fortress.
- *
- * @param testconf The configuration file is passed as an
<code>InputStream</code>
- *
- * A common way to supply a InputStream is to overide the prepare() method
- * in the sub class, do there whatever is needed to get the right InputStream
object
- * supplying a conformant xtest configuartion and pass it to this prepare
method.
- * the mentioned initialize method is also the place to set a different
logging priority
- * to the member variable m_logPriority.
- */
- protected final void prepare( final InputStream testconf )
- throws Exception
- {
- getLogger().debug( "FortressTestCase.initialize" );
-
- final DefaultConfigurationBuilder builder = new
DefaultConfigurationBuilder();
- final Configuration conf = builder.build( testconf );
-
- String annotation = conf.getChild( "annotation" ).getValue( null );
-
- if( ( null != annotation ) && !( "".equals( annotation ) ) )
- {
- m_logger.info( annotation );
- }
-
- final FortressConfig config = new FortressConfig();
- config.setContainerClass( DefaultContainer.class );
-
- config.setContextDirectory( "./" );
- config.setWorkDirectory( "./" );
- config.setLoggerCategory( "fortress" );
-
- config.setLoggerManagerConfiguration( conf.getChild( "logger" ) );
- config.setRoleManagerConfiguration( conf.getChild( "roles" ) );
- config.setContainerConfiguration( conf.getChild( "components" ) );
-
- m_containerManager = new DefaultContainerManager(
- setupContext( conf.getChild( "context", true ),
config.getContext() ) );
- ContainerUtil.initialize( m_containerManager );
-
- m_container = (DefaultContainer) m_containerManager.getContainer();
- m_serviceManager = m_container.getServiceManager();
- m_loggerManager = (LoggerManager) m_serviceManager.lookup(
LoggerManager.class.getName() );
- }
-
- /**
- * Sets the logger which will be returned by getLogger and getLogEnabledLogger
- */
- private void setCurrentLogger( String name )
- {
- if( m_loggerManager == null )
- {
- org.apache.log.Logger logger;
-
- // Logger for the portion of the configuration has been loaded.
- logger = Hierarchy.getDefaultHierarchy().getLoggerFor( name );
- logger.setPriority( Priority.INFO );
-
- PatternFormatter formatter = new PatternFormatter( FORMAT );
- StreamTarget target = new StreamTarget( System.out, formatter
);
- logger.setLogTargets( new LogTarget[]{target} );
- m_logger = new LogKitLogger( logger );
- }
- else
- {
- m_logger = m_loggerManager.getLoggerForCategory( "test." +
name );
- }
- }
-
- /**
- * Set up a context according to the xtest configuration specifications context
- * element.
- *
- * A method addContext(DefaultContext context) is called here to enable
subclasses
- * to put additional objects into the context programmatically.
- */
- private Context setupContext( final Configuration conf, final Context
parentContext )
- throws Exception
- {
- //FIXME(GP): This method should setup the Context object according to
the
- // configuration spec.
- final DefaultContext context = new OverridableContext( parentContext );
- final Configuration[] confs = conf.getChildren( "entry" );
- for( int i = 0; i < confs.length; i++ )
- {
- final String key = confs[ i ].getAttribute( "name" );
- final String value = confs[ i ].getAttribute( "value", null );
- if( value == null )
- {
- String clazz = confs[ i ].getAttribute( "class" );
- Object obj = getClass().getClassLoader().loadClass(
clazz ).newInstance();
- context.put( key, obj );
- if( getLogger().isInfoEnabled() )
- {
- getLogger().info( "FortressTestCase: added an
instance of class "
- + clazz + " to context entry " + key );
- }
-
- }
- else
- {
- context.put( key, value );
- if( getLogger().isInfoEnabled() )
- {
- getLogger().info( "FortressTestCase: added
value \"" + value
- + "\" to context entry " + key );
- }
-
- }
- }
- addContext( context );
- context.makeReadOnly();
- return context;
- }
-
- /**
- * This method may be overwritten by subclasses to put additional objects
- * into the context programmatically.
- */
- protected void addContext( DefaultContext context )
- {
- }
-
-
- /**
- * Exctract the base class name of a class.
- */
- private String getBaseClassName( Class clazz )
- {
- String name = clazz.getName();
- int pos = name.lastIndexOf( '.' );
- if( pos >= 0 )
- {
- name = name.substring( pos + 1 );
- }
- return name;
- }
-
-
- /**
- * Disposes Fortress
- */
- private void done()
- {
- ContainerUtil.dispose( m_containerManager );
- }
-
-}
+/*
+
+ ============================================================================
+ The Apache Software License, Version 1.1
+ ============================================================================
+
+ Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modifica-
+ tion, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. The end-user documentation included with the redistribution, if any, must
+ include the following acknowledgment: "This product includes software
+ developed by the Apache Software Foundation (http://www.apache.org/)."
+ Alternately, this acknowledgment may appear in the software itself, if
+ and wherever such third-party acknowledgments normally appear.
+
+ 4. The names "Jakarta", "Avalon", "Excalibur" and "Apache Software Foundation"
+ must not be used to endorse or promote products derived from this software
+ without prior written permission. For written permission, please contact
+ [EMAIL PROTECTED]
+
+ 5. Products derived from this software may not be called "Apache", nor may
+ "Apache" appear in their name, without prior written permission of the
+ Apache Software Foundation.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
+ DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many individuals
+ on behalf of the Apache Software Foundation. For more information on the
+ Apache Software Foundation, please see <http://www.apache.org/>.
+
+*/
+package org.apache.avalon.fortress.testcase;
+
+import java.io.InputStream;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+
+import org.apache.avalon.excalibur.logger.LoggerManager;
+import org.apache.avalon.fortress.impl.DefaultContainer;
+import org.apache.avalon.fortress.impl.DefaultContainerManager;
+import org.apache.avalon.fortress.util.FortressConfig;
+import org.apache.avalon.fortress.util.OverridableContext;
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.activity.Initializable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
+import org.apache.avalon.framework.container.ContainerUtil;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.DefaultContext;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.logger.LogKitLogger;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.TestCase;
+import junit.framework.TestResult;
+
+import org.apache.log.Hierarchy;
+import org.apache.log.LogTarget;
+import org.apache.log.Priority;
+import org.apache.log.format.PatternFormatter;
+import org.apache.log.output.io.StreamTarget;
+
+/**
+ * JUnit TestCase for Avalon Components in Fortress.
+ * <p>
+ * This class extends the JUnit TestCase class to setup an environment which
+ * makes it possible to easily test Avalon Components. The following methods
+ * and instance variables are exposed for convenience testing:
+ * </p>
+ * <dl>
+ * <dt>m_serviceManager</dt>
+ * <dd>
+ * This instance variable contains an initialized ServiceLocator which
+ * can be used to lookup Components configured in the test configuration
+ * file. (see below)
+ * </dd>
+ * <dt>getLogger()</dt>
+ * <dd>
+ * This method returns the default logger for this test case
+ * </dd>
+ * </dl>
+ * <p>
+ * The following test case configuration can be used as a basis for new tests.
+ * Detailed are explanations of the configuration elements can be found after
+ * the example. The example will log all logger output to the console and to
+ * a log file.
+ * </p>
+ * <pre>
+ * <testcase>
+ * <annotation>
+ * <![CDATA[
+ * <title>{Name of test}</title>
+ * <para>
+ * {Description of test}
+ * The configuration is specified in the file located in
+ * <parameter>avalon-excalibur/src/test/{path and name of conf
file}.xtext</parameter>.
+ * </para>
+ * ]]>
+ * </annotation>
+ *
+ * <logger log-level="INFO">
+ * <factories>
+ * <factory type="stream"
class="org.apache.avalon.excalibur.logger.factory.StreamTargetFactory"/>
+ * <factory type="file"
class="org.apache.avalon.excalibur.logger.factory.FileTargetFactory"/>
+ * </factories>
+ *
+ * <targets>
+ * <stream id="console">
+ * <stream>System.out</stream>
+ * <format type="avalon">
+ * %7.7{priority} %23.23{time:yyyy-MM-dd' 'HH:mm:ss.SSS}
[%30.30{category}] (%{context}): %{message}\n%{throwable}
+ * </format>
+ * </stream>
+ * <file id="log-file">
+ * <filename>TEST-{full test class name}.log</filename>
+ * <format type="avalon">
+ * %7.7{priority} %23.23{time:yyyy-MM-dd' 'HH:mm:ss.SSS}
[%30.30{category}] (%{context}): %{message}\n%{throwable}
+ * </format>
+ * </file>
+ * </targets>
+ *
+ * <categories>
+ * <category name="test" log-level="INFO">
+ * <log-target id-ref="console"/>
+ * <log-target id-ref="log-file"/>
+ * </category>
+ * <category name="jdbc" log-level="INFO">
+ * <log-target id-ref="console"/>
+ * <log-target id-ref="log-file"/>
+ * </category>
+ * </categories>
+ * </logger>
+ *
+ * <context>
+ * <entry name="foo" value="bar"/>
+ * <entry name="baz" class="my.context.Class"/>
+ * </context>
+ *
+ * <roles>
+ * <role name="org.apache.avalon.excalibur.datasource.DataSourceComponent"
+ * <component shorthand="jdbc"
+ * class="org.apache.avalon.excalibur.datasource.JdbcDataSource"
+ *
handler="org.apache.avalon.fortress.impl.handler.ThreadSafeComponentHandler"/>
+ * </role>
+ * </roles>
+ *
+ * <components>
+ * <jdbc name="personell" logger="jdbc">
+ * <pool-controller min="5" max="10"/>
+ * <jdbc name="personnel"/>
+ * <dburl>jdbc:odbc:test</dburl>
+ * <user>test</user>
+ * <password>test</password>
+ * <driver>sun.jdbc.odbc.JdbcOdbcDriver</driver>
+ * </jdbc>
+ * </components>
+ * </testcase>
+ * </pre>
+ * <p>
+ * Element Explanation:
+ * <dl>
+ * <dt>testcase</dt>
+ * <dd>Defines a test case configuration. Must contain one each of the
+ * following elements: <code>annotation</code>, <code>logger</code>,
+ * <code>context</code>, <code>roles</code>, and <code>components</code>
+ * </dd>.
+ *
+ * <dt>annotation</dt>
+ * <dd>Defines a test annotation. This element should define a block of
+ * XML enclosed within a CDATA element. The XML should be made up of a
+ * <code>title</code> element, naming the test, and a <code>para</code>
+ * element which is used to describe the test.</dd>
+ *
+ * <dt>logger</dt>
+ * <dd>Configures the logger used by the test cases and the components used
+ * by the tests. The <code>logger</code> element takes two optional
+ * attributes:
+ * <dl>
+ * <dt>logger</dt><dd>Uses to name the logger which is used to bootstrap
+ * the LogKit logger. (Defaults to <code>"lm"</code>)</dd>
+ * <dt>log-level</dt><dd>Because the logger used by the LogKit must be
+ * created before the Log Kit Manager is initialized, it must be fully
+ * configured before the <code>logger</code> element is parsed. This
+ * attribute allows the Log Kit's log priority to be set. This log
+ * level will also become the default for the Role Manager, Service
+ * Manager, and all components if they do not have <code>category</code>
+ * elements declated in the <code>logger</code> element.
+ * (Defaults to "INFO")</dd>
+ * </dl>
+ * The loggers used by test cases and components can be easily configured
+ * from within this file. The default test configuration, shown above,
+ * includes a "test" category. This category is used to configure the
+ * default logger for all test cases. If it is set to "DEBUG", then all
+ * test debug logging will be enabled. To enalble debug logging for a
+ * single test case, a child category must be defined for the
+ * "testCheckTotals" test case as follows:
+ * <pre>
+ * <categories>
+ * <category name="test" log-level="INFO">
+ * <log-target id-ref="console"/>
+ * <log-target id-ref="log-file"/>
+ *
+ * <category name="testCheckTotals" log-level="DEBUG">
+ * <log-target id-ref="console"/>
+ * <log-target id-ref="log-file"/>
+ * </category>
+ * </category>
+ * </categories>
+ * </pre>
+ * For general information on how to configure the Logger Manager, please
+ * refer to the Log Kit documentation.
+ * </dd>
+ *
+ * <dt>context</dt>
+ * <dd>Allows context properties to be set in the context passed to any
+ * Contextualizable components.</dd>
+ *
+ * <dt>roles</dt>
+ * <dd>Roles configuration for the Components configured in the
+ * <code>components</code> element. The logger used by the RoleManager
+ * can be configured using a <code>logger</code> attribute, which defaults
+ * to "rm". By default this logger will have the same log level and
+ * formatting as the LogKit logger. It can be configured by adding a
+ * <code>category</code> within the <code>logger</code> element.</dd>
+ *
+ * <dt>components</dt>
+ * <dd>Used to configure any Components used by the test cases. The logger
+ * used by the ServiceLocator can be configured using a <code>logger</code>
+ * attribute, which defaults to "cm". By default this logger will have the
+ * same log level and formatting as the LogKit logger. It can be configured
+ * by adding a <code>category</code> within the <code>logger</code> element.
+ * </dd>
+ *
+ * </dl>
+ *
+ * @author <a href="mailto:[EMAIL PROTECTED]">Giacomo Pati</a>
+ * @author unico
+ */
+public class FortressTestCase extends TestCase
+{
+
+ ///Format of default formatter
+ private static final String FORMAT =
+ "%7.7{priority} %23.23{time:yyyy-MM-dd' 'HH:mm:ss.SSS} [%30.30{category}] "
+
+ "(%{context}): %{message}\n%{throwable}";
+
+
+ //The default logger
+ private Logger m_logger;
+
+ // The container manager
+ private DefaultContainerManager m_containerManager;
+
+ // The container itself
+ private DefaultContainer m_container;
+
+ private LoggerManager m_loggerManager;
+ private ServiceManager m_serviceManager;
+
+
+ private static HashMap m_tests = new HashMap();
+
+
+ public FortressTestCase( final String name )
+ {
+ super( name );
+
+ ArrayList methodList = (ArrayList)FortressTestCase.m_tests.get( getClass()
);
+
+ Method[] methods = getClass().getMethods();
+
+ if( null == methodList )
+ {
+ methodList = new ArrayList( methods.length );
+
+ for( int i = 0; i < methods.length; i++ )
+ {
+ String methodName = methods[ i ].getName();
+ if( methodName.startsWith( "test" ) &&
+ ( Modifier.isPublic( methods[ i ].getModifiers() ) ) &&
+ ( methods[ i ].getReturnType().equals( Void.TYPE ) ) &&
+ ( methods[ i ].getParameterTypes().length == 0 ) )
+ {
+ methodList.add( methodName );
+ }
+ }
+
+ FortressTestCase.m_tests.put( getClass(), methodList );
+ }
+ }
+
+ protected final boolean hasService( final String key )
+ {
+ return m_serviceManager.hasService( key );
+ }
+
+ protected final Object lookup( final String key )
+ throws ServiceException
+ {
+ return m_serviceManager.lookup( key );
+ }
+
+ protected final void release( final Object object )
+ {
+ m_serviceManager.release( object );
+ }
+
+ /** Return the logger */
+ protected Logger getLogger()
+ {
+ return m_logger;
+ }
+
+
+ /**
+ * Override <code>run</code> so that we can have code that is run once.
+ */
+ public final void run( TestResult result )
+ {
+ ArrayList methodList = (ArrayList)FortressTestCase.m_tests.get( getClass()
);
+
+ if( null == methodList || methodList.isEmpty() )
+ {
+ return; // The test was already run! NOTE: this is a hack.
+ }
+
+ // Set the logger for the initialization phase.
+ setCurrentLogger( getBaseClassName( getClass() ) );
+
+ try
+ {
+
+ prepare();
+
+ if( this instanceof Initializable )
+ {
+ ( (Initializable)this ).initialize();
+ }
+
+ Iterator tests = methodList.iterator();
+
+ while( tests.hasNext() )
+ {
+ String methodName = (String)tests.next();
+ setName( methodName );
+ setCurrentLogger( methodName );
+
+ if( getLogger().isDebugEnabled() )
+ {
+ getLogger().debug( "" );
+ getLogger().debug( "========================================" );
+ getLogger().debug( " begin test: " + methodName );
+ getLogger().debug( "========================================" );
+ }
+
+ super.run( result );
+
+ if( getLogger().isDebugEnabled() )
+ {
+ getLogger().debug( "========================================" );
+ getLogger().debug( " end test: " + methodName );
+ getLogger().debug( "========================================" );
+ getLogger().debug( "" );
+ }
+ }
+
+ }
+ catch( Exception e )
+ {
+ System.out.println( e );
+ e.printStackTrace();
+ result.addError( this, e );
+ }
+ finally
+ {
+ done();
+
+ if( this instanceof Disposable )
+ {
+ try
+ {
+ ( (Disposable)this ).dispose();
+ }
+ catch( Exception e )
+ {
+ result.addFailure( this, new AssertionFailedError( "Disposal
Error" ) );
+ }
+ }
+ }
+
+ methodList.clear();
+ FortressTestCase.m_tests.put( getClass(), methodList );
+ }
+
+ /**
+ * Initializes Fortress.
+ *
+ * The configuration file is determined by the class name plus .xtest appended,
+ * all '.' replaced by '/' and loaded as a resource via classpath
+ */
+ protected void prepare() throws Exception
+ {
+ setCurrentLogger( "prepare" );
+
+ final String resourceName = getClass().getName().replace( '.', '/' ) +
".xtest";
+ URL resource = getClass().getClassLoader().getResource( resourceName );
+
+ if( resource != null )
+ {
+ getLogger().debug( "Loading resource " + resourceName );
+ prepare( resource.openStream() );
+ }
+ else
+ {
+ getLogger().warn( "Resource not found " + resourceName );
+ }
+ }
+
+ /**
+ * Initializes Fortress.
+ *
+ * @param testconf The configuration file is passed as an
<code>InputStream</code>
+ *
+ * A common way to supply a InputStream is to overide the prepare() method
+ * in the sub class, do there whatever is needed to get the right InputStream
object
+ * supplying a conformant xtest configuartion and pass it to this prepare
method.
+ * the mentioned initialize method is also the place to set a different logging
priority
+ * to the member variable m_logPriority.
+ */
+ protected final void prepare( final InputStream testconf )
+ throws Exception
+ {
+ getLogger().debug( "FortressTestCase.initialize" );
+
+ final DefaultConfigurationBuilder builder = new
DefaultConfigurationBuilder();
+ final Configuration conf = builder.build( testconf );
+
+ String annotation = conf.getChild( "annotation" ).getValue( null );
+
+ if( ( null != annotation ) && !( "".equals( annotation ) ) )
+ {
+ m_logger.info( annotation );
+ }
+
+ final FortressConfig config = new FortressConfig();
+ config.setContainerClass( DefaultContainer.class );
+
+ config.setContextDirectory( "./" );
+ config.setWorkDirectory( "./" );
+ config.setLoggerCategory( "fortress" );
+
+ config.setLoggerManagerConfiguration( conf.getChild( "logger" ) );
+ config.setRoleManagerConfiguration( conf.getChild( "roles" ) );
+ config.setContainerConfiguration( conf.getChild( "components" ) );
+
+ m_containerManager = new DefaultContainerManager(
+ setupContext( conf.getChild( "context", true ), config.getContext() ) );
+ ContainerUtil.initialize( m_containerManager );
+
+ m_container = (DefaultContainer) m_containerManager.getContainer();
+ m_serviceManager = m_container.getServiceManager();
+ m_loggerManager = (LoggerManager) m_serviceManager.lookup(
LoggerManager.class.getName() );
+ }
+
+ /**
+ * Sets the logger which will be returned by getLogger and getLogEnabledLogger
+ */
+ private void setCurrentLogger( String name )
+ {
+ if( m_loggerManager == null )
+ {
+ org.apache.log.Logger logger;
+
+ // Logger for the portion of the configuration has been loaded.
+ logger = Hierarchy.getDefaultHierarchy().getLoggerFor( name );
+ logger.setPriority( Priority.INFO );
+
+ PatternFormatter formatter = new PatternFormatter( FORMAT );
+ StreamTarget target = new StreamTarget( System.out, formatter );
+ logger.setLogTargets( new LogTarget[]{target} );
+ m_logger = new LogKitLogger( logger );
+ }
+ else
+ {
+ m_logger = m_loggerManager.getLoggerForCategory( "test." + name );
+ }
+ }
+
+ /**
+ * Set up a context according to the xtest configuration specifications context
+ * element.
+ *
+ * A method addContext(DefaultContext context) is called here to enable
subclasses
+ * to put additional objects into the context programmatically.
+ */
+ private Context setupContext( final Configuration conf, final Context
parentContext )
+ throws Exception
+ {
+ //FIXME(GP): This method should setup the Context object according to the
+ // configuration spec.
+ final DefaultContext context = new OverridableContext( parentContext );
+ final Configuration[] confs = conf.getChildren( "entry" );
+ for( int i = 0; i < confs.length; i++ )
+ {
+ final String key = confs[ i ].getAttribute( "name" );
+ final String value = confs[ i ].getAttribute( "value", null );
+ if( value == null )
+ {
+ String clazz = confs[ i ].getAttribute( "class" );
+ Object obj = getClass().getClassLoader().loadClass( clazz
).newInstance();
+ context.put( key, obj );
+ if( getLogger().isInfoEnabled() )
+ {
+ getLogger().info( "FortressTestCase: added an instance of class
"
+ + clazz + " to context entry " + key );
+ }
+
+ }
+ else
+ {
+ context.put( key, value );
+ if( getLogger().isInfoEnabled() )
+ {
+ getLogger().info( "FortressTestCase: added value \"" + value
+ + "\" to context entry " + key );
+ }
+
+ }
+ }
+ addContext( context );
+ context.makeReadOnly();
+ return context;
+ }
+
+ /**
+ * This method may be overwritten by subclasses to put additional objects
+ * into the context programmatically.
+ */
+ protected void addContext( DefaultContext context )
+ {
+ }
+
+
+ /**
+ * Exctract the base class name of a class.
+ */
+ private String getBaseClassName( Class clazz )
+ {
+ String name = clazz.getName();
+ int pos = name.lastIndexOf( '.' );
+ if( pos >= 0 )
+ {
+ name = name.substring( pos + 1 );
+ }
+ return name;
+ }
+
+
+ /**
+ * Disposes Fortress
+ */
+ private void done()
+ {
+ ContainerUtil.dispose( m_containerManager );
+ }
+
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]