avalon-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From blorit...@apache.org
Subject cvs commit: avalon-excalibur/fortress/src/tools/org/apache/avalon/fortress/testcase FortressTestCase.java
Date Fri, 06 Jun 2003 20:34:44 GMT
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 
  -	apache@apache.org.
  - 
  - 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>
  - *   &lt;testcase&gt;
  - *     &lt;annotation&gt;
  - *       &lt;![CDATA[
  - *         &lt;title&gt;{Name of test}&lt;/title&gt;
  - *         &lt;para&gt;
  - *           {Description of test}
  - *           The configuration is specified in the file located in
  - *           &lt;parameter&gt;avalon-excalibur/src/test/{path and name of conf file}.xtext&lt;/parameter&gt;.
  - *         &lt;/para&gt;
  - *       ]]&gt;
  - *     &lt;/annotation&gt;
  - *
  - *     &lt;logger log-level="INFO"&gt;
  - *       &lt;factories&gt;
  - *         &lt;factory type="stream" class="org.apache.avalon.excalibur.logger.factory.StreamTargetFactory"/&gt;
  - *         &lt;factory type="file" class="org.apache.avalon.excalibur.logger.factory.FileTargetFactory"/&gt;
  - *       &lt;/factories&gt;
  - *
  - *       &lt;targets&gt;
  - *         &lt;stream id="console"&gt;
  - *           &lt;stream&gt;System.out&lt;/stream&gt;
  - *           &lt;format type="avalon"&gt;
  - *             %7.7{priority} %23.23{time:yyyy-MM-dd' 'HH:mm:ss.SSS} [%30.30{category}] (%{context}): %{message}\n%{throwable}
  - *           &lt;/format&gt;
  - *         &lt;/stream&gt;
  - *         &lt;file id="log-file"&gt;
  - *           &lt;filename&gt;TEST-{full test class name}.log&lt;/filename&gt;
  - *           &lt;format type="avalon"&gt;
  - *             %7.7{priority} %23.23{time:yyyy-MM-dd' 'HH:mm:ss.SSS} [%30.30{category}] (%{context}): %{message}\n%{throwable}
  - *           &lt;/format&gt;
  - *         &lt;/file&gt;
  - *       &lt;/targets&gt;
  - *
  - *       &lt;categories&gt;
  - *         &lt;category name="test" log-level="INFO"&gt;
  - *           &lt;log-target id-ref="console"/&gt;
  - *           &lt;log-target id-ref="log-file"/&gt;
  - *         &lt;/category&gt;
  - *         &lt;category name="jdbc" log-level="INFO"&gt;
  - *           &lt;log-target id-ref="console"/&gt;
  - *           &lt;log-target id-ref="log-file"/&gt;
  - *         &lt;/category&gt;
  - *       &lt;/categories&gt;
  - *     &lt;/logger&gt;
  - *
  - *     &lt;context&gt;
  - *       &lt;entry name="foo" value="bar"/&gt;
  - *       &lt;entry name="baz" class="my.context.Class"/&gt;
  - *     &lt;/context&gt;
  - *
  - *     &lt;roles&gt;
  - *       &lt;role name="org.apache.avalon.excalibur.datasource.DataSourceComponent"
  - *             &lt;component shorthand="jdbc"
  - *             class="org.apache.avalon.excalibur.datasource.JdbcDataSource"
  - *             handler="org.apache.avalon.fortress.impl.handler.ThreadSafeComponentHandler"/&gt;
  - *       &lt;/role&gt;
  - *     &lt;/roles&gt;
  - *
  - *     &lt;components&gt;
  - *         &lt;jdbc name="personell" logger="jdbc"&gt;
  - *           &lt;pool-controller min="5" max="10"/&gt;
  - *           &lt;jdbc name="personnel"/&gt;
  - *           &lt;dburl&gt;jdbc:odbc:test&lt;/dburl&gt;
  - *           &lt;user&gt;test&lt;/user&gt;
  - *           &lt;password&gt;test&lt;/password&gt;
  - *           &lt;driver&gt;sun.jdbc.odbc.JdbcOdbcDriver&lt;/driver&gt;
  - *         &lt;/jdbc&gt;
  - *     &lt;/components&gt;
  - *   &lt;/testcase&gt;
  - * </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>
  - *       &lt;categories&gt;
  - *         &lt;category name="test" log-level="INFO"&gt;
  - *           &lt;log-target id-ref="console"/&gt;
  - *           &lt;log-target id-ref="log-file"/&gt;
  - *
  - *           &lt;category name="testCheckTotals" log-level="DEBUG"&gt;
  - *             &lt;log-target id-ref="console"/&gt;
  - *             &lt;log-target id-ref="log-file"/&gt;
  - *           &lt;/category&gt;
  - *         &lt;/category&gt;
  - *       &lt;/categories&gt;
  - *  </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:giacomo@apache.org">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 
  +    apache@apache.org.
  + 
  + 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>
  + *   &lt;testcase&gt;
  + *     &lt;annotation&gt;
  + *       &lt;![CDATA[
  + *         &lt;title&gt;{Name of test}&lt;/title&gt;
  + *         &lt;para&gt;
  + *           {Description of test}
  + *           The configuration is specified in the file located in
  + *           &lt;parameter&gt;avalon-excalibur/src/test/{path and name of conf file}.xtext&lt;/parameter&gt;.
  + *         &lt;/para&gt;
  + *       ]]&gt;
  + *     &lt;/annotation&gt;
  + *
  + *     &lt;logger log-level="INFO"&gt;
  + *       &lt;factories&gt;
  + *         &lt;factory type="stream" class="org.apache.avalon.excalibur.logger.factory.StreamTargetFactory"/&gt;
  + *         &lt;factory type="file" class="org.apache.avalon.excalibur.logger.factory.FileTargetFactory"/&gt;
  + *       &lt;/factories&gt;
  + *
  + *       &lt;targets&gt;
  + *         &lt;stream id="console"&gt;
  + *           &lt;stream&gt;System.out&lt;/stream&gt;
  + *           &lt;format type="avalon"&gt;
  + *             %7.7{priority} %23.23{time:yyyy-MM-dd' 'HH:mm:ss.SSS} [%30.30{category}] (%{context}): %{message}\n%{throwable}
  + *           &lt;/format&gt;
  + *         &lt;/stream&gt;
  + *         &lt;file id="log-file"&gt;
  + *           &lt;filename&gt;TEST-{full test class name}.log&lt;/filename&gt;
  + *           &lt;format type="avalon"&gt;
  + *             %7.7{priority} %23.23{time:yyyy-MM-dd' 'HH:mm:ss.SSS} [%30.30{category}] (%{context}): %{message}\n%{throwable}
  + *           &lt;/format&gt;
  + *         &lt;/file&gt;
  + *       &lt;/targets&gt;
  + *
  + *       &lt;categories&gt;
  + *         &lt;category name="test" log-level="INFO"&gt;
  + *           &lt;log-target id-ref="console"/&gt;
  + *           &lt;log-target id-ref="log-file"/&gt;
  + *         &lt;/category&gt;
  + *         &lt;category name="jdbc" log-level="INFO"&gt;
  + *           &lt;log-target id-ref="console"/&gt;
  + *           &lt;log-target id-ref="log-file"/&gt;
  + *         &lt;/category&gt;
  + *       &lt;/categories&gt;
  + *     &lt;/logger&gt;
  + *
  + *     &lt;context&gt;
  + *       &lt;entry name="foo" value="bar"/&gt;
  + *       &lt;entry name="baz" class="my.context.Class"/&gt;
  + *     &lt;/context&gt;
  + *
  + *     &lt;roles&gt;
  + *       &lt;role name="org.apache.avalon.excalibur.datasource.DataSourceComponent"
  + *             &lt;component shorthand="jdbc"
  + *             class="org.apache.avalon.excalibur.datasource.JdbcDataSource"
  + *             handler="org.apache.avalon.fortress.impl.handler.ThreadSafeComponentHandler"/&gt;
  + *       &lt;/role&gt;
  + *     &lt;/roles&gt;
  + *
  + *     &lt;components&gt;
  + *         &lt;jdbc name="personell" logger="jdbc"&gt;
  + *           &lt;pool-controller min="5" max="10"/&gt;
  + *           &lt;jdbc name="personnel"/&gt;
  + *           &lt;dburl&gt;jdbc:odbc:test&lt;/dburl&gt;
  + *           &lt;user&gt;test&lt;/user&gt;
  + *           &lt;password&gt;test&lt;/password&gt;
  + *           &lt;driver&gt;sun.jdbc.odbc.JdbcOdbcDriver&lt;/driver&gt;
  + *         &lt;/jdbc&gt;
  + *     &lt;/components&gt;
  + *   &lt;/testcase&gt;
  + * </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>
  + *       &lt;categories&gt;
  + *         &lt;category name="test" log-level="INFO"&gt;
  + *           &lt;log-target id-ref="console"/&gt;
  + *           &lt;log-target id-ref="log-file"/&gt;
  + *
  + *           &lt;category name="testCheckTotals" log-level="DEBUG"&gt;
  + *             &lt;log-target id-ref="console"/&gt;
  + *             &lt;log-target id-ref="log-file"/&gt;
  + *           &lt;/category&gt;
  + *         &lt;/category&gt;
  + *       &lt;/categories&gt;
  + *  </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:giacomo@apache.org">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: cvs-unsubscribe@avalon.apache.org
For additional commands, e-mail: cvs-help@avalon.apache.org


Mime
View raw message