[jboss-cvs] apache/commons-logging/src/test/org/apache/commons/logging ...
Scott Stark
scott.stark at jboss.com
Fri Feb 9 01:57:17 EST 2007
User: starksm
Date: 07/02/09 01:57:17
Modified: commons-logging/src/test/org/apache/commons/logging
UserClass.java AbstractLogTest.java
Added: commons-logging/src/test/org/apache/commons/logging
LoadTestCase.java NullClassLoaderTestCase.java
AltHashtable.java PathableTestSuite.java
AltHashtableTestCase.java SimpleLogTestCase.java
LogTestCase.java BadHashtablePropertyTestCase.java
BasicOperationsTestCase.java
PathableClassLoader.java
Log:
Update to the http://apache.ziply.com/jakarta/commons/logging/source/commons-logging-1.1-src.zip release
Revision Changes Path
1.2 +42 -27 apache/commons-logging/src/test/org/apache/commons/logging/UserClass.java
(In the diff below, changes in quantity of whitespace are not shown.)
Index: UserClass.java
===================================================================
RCS file: /cvsroot/jboss/apache/commons-logging/src/test/org/apache/commons/logging/UserClass.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- UserClass.java 17 Apr 2006 21:00:05 -0000 1.1
+++ UserClass.java 9 Feb 2007 06:57:16 -0000 1.2
@@ -16,12 +16,27 @@
package org.apache.commons.logging;
+import org.apache.commons.logging.LogFactory;
+import org.apache.commons.logging.impl.LogFactoryImpl;
+
public class UserClass {
+ /**
+ * Set the ALLOW_FLAWED_CONTEXT feature on the LogFactoryImpl object
+ * associated with this class' classloader.
+ * <p>
+ * Don't forget to set the context classloader to whatever it will be
+ * when an instance of this class is actually created <i>before</i> calling
+ * this method!
+ */
+ public static void setAllowFlawedContext(String state) {
+ LogFactory f = LogFactory.getFactory();
+ f.setAttribute(LogFactoryImpl.ALLOW_FLAWED_CONTEXT_PROPERTY, state);
+ }
public UserClass() {
- Log log = LogFactory.getLog(LoadTest.class);
+ Log log = LogFactory.getLog(LoadTestCase.class);
}
}
1.2 +95 -98 apache/commons-logging/src/test/org/apache/commons/logging/AbstractLogTest.java
(In the diff below, changes in quantity of whitespace are not shown.)
Index: AbstractLogTest.java
===================================================================
RCS file: /cvsroot/jboss/apache/commons-logging/src/test/org/apache/commons/logging/AbstractLogTest.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- AbstractLogTest.java 17 Apr 2006 21:00:05 -0000 1.1
+++ AbstractLogTest.java 9 Feb 2007 06:57:17 -0000 1.2
@@ -17,22 +17,19 @@
package org.apache.commons.logging;
-import junit.framework.*;
+import junit.framework.TestCase;
/**
+ * Generic tests that can be applied to any log adapter by
+ * subclassing this class and defining method getLogObject
+ * appropriately.
*
* @author Sean C. Sullivan
- * @version $Revision: 1.1 $
- *
+ * @version $Revision: 1.2 $
*/
public abstract class AbstractLogTest extends TestCase {
- public AbstractLogTest(String testName) {
- super(testName);
- }
-
-
public abstract Log getLogObject();
public void testLoggingWithNullParameters()
1.1 date: 2007/02/09 06:57:16; author: starksm; state: Exp;apache/commons-logging/src/test/org/apache/commons/logging/LoadTestCase.java
Index: LoadTestCase.java
===================================================================
/*
* Copyright 2001-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.logging;
import junit.framework.TestCase;
/**
* testcase to emulate container and application isolated from container
* @author baliuka
* @version $Id: LoadTestCase.java,v 1.1 2007/02/09 06:57:16 starksm Exp $
*/
public class LoadTestCase extends TestCase{
//TODO: need some way to add service provider packages
static private String LOG_PCKG[] = {"org.apache.commons.logging",
"org.apache.commons.logging.impl"};
/**
* A custom classloader which "duplicates" logging classes available
* in the parent classloader into itself.
* <p>
* When asked to load a class that is in one of the LOG_PCKG packages,
* it loads the class itself (child-first). This class doesn't need
* to be set up with a classpath, as it simply uses the same classpath
* as the classloader that loaded it.
*/
static class AppClassLoader extends ClassLoader{
java.util.Map classes = new java.util.HashMap();
AppClassLoader(ClassLoader parent){
super(parent);
}
private Class def(String name)throws ClassNotFoundException{
Class result = (Class)classes.get(name);
if(result != null){
return result;
}
try{
ClassLoader cl = this.getClass().getClassLoader();
String classFileName = name.replace('.','/') + ".class";
java.io.InputStream is = cl.getResourceAsStream(classFileName);
java.io.ByteArrayOutputStream out = new java.io.ByteArrayOutputStream();
while(is.available() > 0){
out.write(is.read());
}
byte data [] = out.toByteArray();
result = super.defineClass(name, data, 0, data.length );
classes.put(name,result);
return result;
}catch(java.io.IOException ioe){
throw new ClassNotFoundException( name + " caused by "
+ ioe.getMessage() );
}
}
// not very trivial to emulate we must implement "findClass",
// but it will delegete to junit class loder first
public Class loadClass(String name)throws ClassNotFoundException{
//isolates all logging classes, application in the same classloader too.
//filters exeptions to simlify handling in test
for(int i = 0; i < LOG_PCKG.length; i++ ){
if( name.startsWith( LOG_PCKG[i] ) &&
name.indexOf("Exception") == -1 ){
return def(name);
}
}
return super.loadClass(name);
}
}
/**
* Call the static setAllowFlawedContext method on the specified class
* (expected to be a UserClass loaded via a custom classloader), passing
* it the specified state parameter.
*/
private void setAllowFlawedContext(Class c, String state) throws Exception {
Class[] params = {String.class};
java.lang.reflect.Method m = c.getDeclaredMethod("setAllowFlawedContext", params);
m.invoke(null, new Object[] {state});
}
/**
* Test what happens when we play various classloader tricks like those
* that happen in web and j2ee containers.
* <p>
* Note that this test assumes that commons-logging.jar and log4j.jar
* are available via the system classpath.
*/
public void testInContainer()throws Exception{
//problem can be in this step (broken app container or missconfiguration)
//1. Thread.currentThread().setContextClassLoader(ClassLoader.getSystemClassLoader());
//2. Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
// we expect this :
// 1. Thread.currentThread().setContextClassLoader(appLoader);
// 2. Thread.currentThread().setContextClassLoader(null);
// Context classloader is same as class calling into log
Class cls = reload();
Thread.currentThread().setContextClassLoader(cls.getClassLoader());
execute(cls);
// Context classloader is the "bootclassloader". This is technically
// bad, but LogFactoryImpl.ALLOW_FLAWED_CONTEXT defaults to true so
// this test should pass.
cls = reload();
Thread.currentThread().setContextClassLoader(null);
execute(cls);
// Context classloader is the "bootclassloader". This is same as above
// except that ALLOW_FLAWED_CONTEXT is set to false; an error should
// now be reported.
cls = reload();
Thread.currentThread().setContextClassLoader(null);
try {
setAllowFlawedContext(cls, "false");
execute(cls);
fail("Logging config succeeded when context classloader was null!");
} catch(LogConfigurationException ex) {
// expected; the boot classloader doesn't *have* JCL available
}
// Context classloader is the system classloader.
//
// This is expected to cause problems, as LogFactoryImpl will attempt
// to use the system classloader to load the Log4JLogger class, which
// will then be unable to cast that object to the Log interface loaded
// via the child classloader. However as ALLOW_FLAWED_CONTEXT defaults
// to true this test should pass.
cls = reload();
Thread.currentThread().setContextClassLoader(ClassLoader.getSystemClassLoader());
execute(cls);
// Context classloader is the system classloader. This is the same
// as above except that ALLOW_FLAWED_CONTEXT is set to false; an error
// should now be reported.
cls = reload();
Thread.currentThread().setContextClassLoader(ClassLoader.getSystemClassLoader());
try {
setAllowFlawedContext(cls, "false");
execute(cls);
fail("Error: somehow downcast a Logger loaded via system classloader"
+ " to the Log interface loaded via a custom classloader");
} catch(LogConfigurationException ex) {
// expected
}
}
/**
* Load class UserClass via a temporary classloader which is a child of
* the classloader used to load this test class.
*/
private Class reload()throws Exception{
Class testObjCls = null;
AppClassLoader appLoader = new AppClassLoader(
this.getClass().getClassLoader());
try{
testObjCls = appLoader.loadClass(UserClass.class.getName());
}catch(ClassNotFoundException cnfe){
throw cnfe;
}catch(Throwable t){
t.printStackTrace();
fail("AppClassLoader failed ");
}
assertTrue( "app isolated" ,testObjCls.getClassLoader() == appLoader );
return testObjCls;
}
private void execute(Class cls)throws Exception{
cls.newInstance();
}
public static void main(String[] args){
String[] testCaseName = { LoadTestCase.class.getName() };
junit.textui.TestRunner.main(testCaseName);
}
public void setUp() {
// save state before test starts so we can restore it when test ends
origContextClassLoader = Thread.currentThread().getContextClassLoader();
}
public void tearDown() {
// restore original state so a test can't stuff up later tests.
Thread.currentThread().setContextClassLoader(origContextClassLoader);
}
private ClassLoader origContextClassLoader;
}
1.1 date: 2007/02/09 06:57:16; author: starksm; state: Exp;apache/commons-logging/src/test/org/apache/commons/logging/NullClassLoaderTestCase.java
Index: NullClassLoaderTestCase.java
===================================================================
/*
* Copyright 2001-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.logging;
import junit.framework.TestCase;
/**
* Test cases for situations where getClassLoader or getContextClassLoader
* return null. This can happen when using JDK 1.1. It can also happen when
* JCL is deployed via the bootclassloader - something that could be done when
* using java in embedded systems.
*/
public class NullClassLoaderTestCase extends TestCase {
//---------------------- Main ---------------------------------
/**
* Main method so this test case can be run direct from the command line.
*/
public static void main(String[] args){
String[] testCaseName = { NullClassLoaderTestCase.class.getName() };
junit.textui.TestRunner.main(testCaseName);
}
//---------------------- unit tests ---------------------------------
/**
* This tests that when getContextClassLoader returns null, the
* LogFactory.getLog(name) method still correctly returns the same
* log object when called multiple times with the same name.
*/
public void testSameLogObject() throws Exception {
// unfortunately, there just isn't any way to emulate JCL being
// accessable via the null classloader in "standard" systems, so
// we can't include this test in our standard unit tests.
}
}
1.1 date: 2007/02/09 06:57:16; author: starksm; state: Exp;apache/commons-logging/src/test/org/apache/commons/logging/AltHashtable.java
Index: AltHashtable.java
===================================================================
/*
* Copyright 2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.logging;
import java.util.Hashtable;
public class AltHashtable extends Hashtable {
public static Object lastKey;
public static Object lastValue;
public Object put(Object key, Object value) {
lastKey = key;
lastValue = value;
return super.put(key, value);
}
}
1.1 date: 2007/02/09 06:57:16; author: starksm; state: Exp;apache/commons-logging/src/test/org/apache/commons/logging/PathableTestSuite.java
Index: PathableTestSuite.java
===================================================================
/*
* Copyright 2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.logging;
import java.util.Properties;
import junit.framework.Test;
import junit.framework.TestResult;
import junit.framework.TestSuite;
/**
* Custom TestSuite class that can be used to control the context classloader
* in operation when a test runs.
* <p>
* For tests that need to control exactly what the classloader hierarchy is
* like when the test is run, something like the following is recommended:
* <pre>
* class SomeTestCase extends TestCase {
* public static Test suite() throws Exception {
* PathableClassLoader parent = new PathableClassLoader(null);
* parent.useSystemLoader("junit.");
*
* PathableClassLoader child = new PathableClassLoader(parent);
* child.addLogicalLib("testclasses");
* child.addLogicalLib("log4j12");
* child.addLogicalLib("commons-logging");
*
* Class testClass = child.loadClass(SomeTestCase.class.getName());
* ClassLoader contextClassLoader = child;
*
* PathableTestSuite suite = new PathableTestSuite(testClass, child);
* return suite;
* }
*
* // test methods go here
* }
* </pre>
* Note that if the suite method throws an exception then this will be handled
* reasonable gracefully by junit; it will report that the suite method for
* a test case failed with exception yyy.
* <p>
* The use of PathableClassLoader is not required to use this class, but it
* is expected that using the two classes together is common practice.
* <p>
* This class will run each test methods within the specified TestCase using
* the specified context classloader and system classloader. If different
* tests within the same class require different context classloaders,
* then the context classloader passed to the constructor should be the
* "lowest" one available, and tests that need the context set to some parent
* of this "lowest" classloader can call
* <pre>
* // NB: pseudo-code only
* setContextClassLoader(getContextClassLoader().getParent());
* </pre>
* This class ensures that any context classloader changes applied by a test
* is undone after the test is run, so tests don't need to worry about
* restoring the context classloader on exit. This class also ensures that
* the system properties are restored to their original settings after each
* test, so tests that manipulate those don't need to worry about resetting them.
* <p>
* This class does not provide facilities for manipulating system properties;
* tests that need specific system properties can simply set them in the
* fixture or at the start of a test method.
* <p>
* <b>Important!</b> When the test case is run, "this.getClass()" refers of
* course to the Class object passed to the constructor of this class - which
* is different from the class whose suite() method was executed to determine
* the classpath. This means that the suite method cannot communicate with
* the test cases simply by setting static variables (for example to make the
* custom classloaders available to the test methods or setUp/tearDown fixtures).
* If this is really necessary then it is possible to use reflection to invoke
* static methods on the class object passed to the constructor of this class.
* <p>
* <h2>Limitations</h2>
* <p>
* This class cannot control the system classloader (ie what method
* ClassLoader.getSystemClassLoader returns) because Java provides no
* mechanism for setting the system classloader. In this case, the only
* option is to invoke the unit test in a separate JVM with the appropriate
* settings.
* <p>
* The effect of using this approach in a system that uses junit's
* "reloading classloader" behaviour is unknown. This junit feature is
* intended for junit GUI apps where a test may be run multiple times
* within the same JVM - and in particular, when the .class file may
* be modified between runs of the test. How junit achieves this is
* actually rather weird (the whole junit code is rather weird in fact)
* and it is not clear whether this approach will work as expected in
* such situations.
*/
public class PathableTestSuite extends TestSuite {
/**
* The classloader that should be set as the context classloader
* before each test in the suite is run.
*/
private ClassLoader contextLoader;
/**
* Constructor.
*
* @param testClass is the TestCase that is to be run, as loaded by
* the appropriate ClassLoader.
*
* @param contextClassLoader is the loader that should be returned by
* calls to Thread.currentThread.getContextClassLoader from test methods
* (or any method called by test methods).
*/
public PathableTestSuite(Class testClass, ClassLoader contextClassLoader) {
super(testClass);
contextLoader = contextClassLoader;
}
/**
* This method is invoked once for each Test in the current TestSuite.
* Note that a Test may itself be a TestSuite object (ie a collection
* of tests).
* <p>
* The context classloader and system properties are saved before each
* test, and restored after the test completes to better isolate tests.
*/
public void runTest(Test test, TestResult result) {
ClassLoader origContext = Thread.currentThread().getContextClassLoader();
Properties oldSysProps = (Properties) System.getProperties().clone();
try {
Thread.currentThread().setContextClassLoader(contextLoader);
test.run(result);
} finally {
System.setProperties(oldSysProps);
Thread.currentThread().setContextClassLoader(origContext);
}
}
}
1.1 date: 2007/02/09 06:57:17; author: starksm; state: Exp;apache/commons-logging/src/test/org/apache/commons/logging/AltHashtableTestCase.java
Index: AltHashtableTestCase.java
===================================================================
/*
* Copyright 2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.logging;
import junit.framework.*;
/**
* Test the ability to force the LogFactory class to use some
* arbitrary Hashtable implementation to store its mapping from
* context-classloader -> LogFactory object.
* <p>
* This is done by
*/
public class AltHashtableTestCase extends TestCase {
public static Test suite() throws Exception {
Class thisClass = AltHashtableTestCase.class;
ClassLoader thisClassLoader = thisClass.getClassLoader();
PathableClassLoader loader = new PathableClassLoader(null);
loader.useExplicitLoader("junit.", thisClassLoader);
loader.addLogicalLib("testclasses");
loader.addLogicalLib("commons-logging");
Class testClass = loader.loadClass(thisClass.getName());
return new PathableTestSuite(testClass, loader);
}
/**
* Set up before each test.
* <p>
* This method ensures that the appropriate system property is defined
* to force the LogFactory class to use the AltHashtable class as its
* Hashtable implementation for storing factories in.
* <p>
* This does make the assumption that whatever JVM we are running in
* doesn't initialise classes until they are actually referenced (ie the
* LogFactory class hasn't been initialised before this method is called).
* This is true of all JVMs I know of; and if it isn't then this test will
* fail and someone will tell us.
*/
public void setUp() {
System.setProperty(
"org.apache.commons.logging.LogFactory.HashtableImpl",
AltHashtable.class.getName());
}
/**
* Verify that initialising the LogFactory class will cause it
* to instantiate an object of type specified in system property
* "org.apache.commons.logging.LogFactory.HashtableImpl".
*/
public void testType() {
// Here, the reference to the LogFactory class should cause the
// class to be loaded and initialised. It will see the property
// set and use the AltHashtable class. If other tests in this
// class have already been run within the same classloader then
// LogFactory will already have been initialised, but that
// doesn't change the effectiveness of this test.
assertTrue(LogFactory.factories instanceof AltHashtable);
}
/**
* Verify that when LogFactory sees a context-classloader for the
* first time that it creates a new entry in the LogFactory.factories
* hashmap. In particular, this checks that this process works ok when
* a system property has been used to specify an alternative Hashtable
* implementation for LogFactory to use.
*/
public void testPutCalled() throws Exception {
AltHashtable.lastKey = null;
AltHashtable.lastValue = null;
LogFactory.getLog(AltHashtableTestCase.class);
ClassLoader contextLoader = Thread.currentThread().getContextClassLoader();
assertEquals(contextLoader, AltHashtable.lastKey);
assertNotNull(AltHashtable.lastValue);
}
}
1.1 date: 2007/02/09 06:57:17; author: starksm; state: Exp;apache/commons-logging/src/test/org/apache/commons/logging/SimpleLogTestCase.java
Index: SimpleLogTestCase.java
===================================================================
/*
* Copyright 2001-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.logging;
import org.apache.commons.logging.impl.SimpleLog;
/**
*
*
*
*
*
*
*/
public class SimpleLogTestCase extends AbstractLogTest
{
/**
*
*
*
*/
public Log getLogObject()
{
return (Log) new SimpleLog(this.getClass().getName());
}
public static void main(String[] args) {
String[] testCaseName = { SimpleLogTestCase.class.getName() };
junit.textui.TestRunner.main(testCaseName);
}
}
1.1 date: 2007/02/09 06:57:17; author: starksm; state: Exp;apache/commons-logging/src/test/org/apache/commons/logging/LogTestCase.java
Index: LogTestCase.java
===================================================================
/*
* Copyright 2001-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.logging;
/**
*
*
*
*
*
*
*/
public class LogTestCase extends AbstractLogTest
{
/**
*
*
*
*/
public Log getLogObject()
{
/**
* Pickup whatever is found/configured!
*/
return LogFactory.getLog(this.getClass().getName());
}
public static void main(String[] args)
{
String[] testCaseName = { LogTestCase.class.getName() };
junit.textui.TestRunner.main(testCaseName);
}
}
1.1 date: 2007/02/09 06:57:17; author: starksm; state: Exp;apache/commons-logging/src/test/org/apache/commons/logging/BadHashtablePropertyTestCase.java
Index: BadHashtablePropertyTestCase.java
===================================================================
/*
* Copyright 2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.logging;
import junit.framework.*;
import java.util.Hashtable;
/**
* Tests behaviour when the property is misconfigured.
*/
public class BadHashtablePropertyTestCase extends TestCase {
public void testType() {
assertTrue(LogFactory.factories instanceof Hashtable);
}
public void testPutCalled() throws Exception {
Log log = LogFactory.getLog(BadHashtablePropertyTestCase.class);
}
}
1.1 date: 2007/02/09 06:57:17; author: starksm; state: Exp;apache/commons-logging/src/test/org/apache/commons/logging/BasicOperationsTestCase.java
Index: BasicOperationsTestCase.java
===================================================================
/*
* Copyright 2004,2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.logging;
import junit.framework.TestCase;
/**
* Tests the basic logging operations to ensure that they all function
* without exception failure. In other words, that they do no fail by
* throwing exceptions.
* This is the minimum requirement for any well behaved logger
* and so this test should be run for each kind.
*/
public class BasicOperationsTestCase extends TestCase
{
public void testIsEnabledClassLog()
{
Log log = LogFactory.getLog(BasicOperationsTestCase.class);
executeIsEnabledTest(log);
}
public void testIsEnabledNamedLog()
{
Log log = LogFactory.getLog(BasicOperationsTestCase.class.getName());
executeIsEnabledTest(log);
}
public void executeIsEnabledTest(Log log)
{
try
{
log.isTraceEnabled();
log.isDebugEnabled();
log.isInfoEnabled();
log.isWarnEnabled();
log.isErrorEnabled();
log.isFatalEnabled();
}
catch (Throwable t)
{
t.printStackTrace();
fail("Exception thrown: " + t);
}
}
public void testMessageWithoutExceptionClassLog()
{
Log log = LogFactory.getLog(BasicOperationsTestCase.class);
executeMessageWithoutExceptionTest(log);
}
public void testMessageWithoutExceptionNamedLog()
{
Log log = LogFactory.getLog(BasicOperationsTestCase.class.getName());
executeMessageWithoutExceptionTest(log);
}
public void executeMessageWithoutExceptionTest(Log log)
{
try
{
log.trace("Hello, Mum");
log.debug("Hello, Mum");
log.info("Hello, Mum");
log.warn("Hello, Mum");
log.error("Hello, Mum");
log.fatal("Hello, Mum");
}
catch (Throwable t)
{
t.printStackTrace();
fail("Exception thrown: " + t);
}
}
public void testMessageWithExceptionClassLog()
{
Log log = LogFactory.getLog(BasicOperationsTestCase.class);
executeMessageWithExceptionTest(log);
}
public void testMessageWithExceptionNamedLog()
{
Log log = LogFactory.getLog(BasicOperationsTestCase.class.getName());
executeMessageWithExceptionTest(log);
}
public void executeMessageWithExceptionTest(Log log)
{
try
{
log.trace("Hello, Mum", new ArithmeticException());
log.debug("Hello, Mum", new ArithmeticException());
log.info("Hello, Mum", new ArithmeticException());
log.warn("Hello, Mum", new ArithmeticException());
log.error("Hello, Mum", new ArithmeticException());
log.fatal("Hello, Mum", new ArithmeticException());
}
catch (Throwable t)
{
t.printStackTrace();
fail("Exception thrown: " + t);
}
}
}
1.1 date: 2007/02/09 06:57:17; author: starksm; state: Exp;apache/commons-logging/src/test/org/apache/commons/logging/PathableClassLoader.java
Index: PathableClassLoader.java
===================================================================
/*
* Copyright 2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.logging;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
* A ClassLoader which sees only specified classes, and which can be
* set to do parent-first or child-first path lookup.
* <p>
* Note that this classloader is not "industrial strength"; users
* looking for such a class may wish to look at the Tomcat sourcecode
* instead. In particular, this class may not be threadsafe.
* <p>
* Note that the ClassLoader.getResources method isn't overloaded here.
* It would be nice to ensure that when child-first lookup is set the
* resources from the child are returned earlier in the list than the
* resources from the parent. However overriding this method isn't possible
* as the java 1.4 version of ClassLoader declares this method final
* (though the java 1.5 version has removed the final qualifier). As the
* ClassLoader javadoc doesn't specify the order in which resources
* are returned, it's valid to return the resources in any order (just
* untidy) so the inherited implementation is technically ok.
*/
public class PathableClassLoader extends URLClassLoader {
private static final URL[] NO_URLS = new URL[0];
/**
* A map of package-prefix to ClassLoader. Any class which is in
* this map is looked up via the specified classloader instead of
* the classpath associated with this classloader or its parents.
* <p>
* This is necessary in order for the rest of the world to communicate
* with classes loaded via a custom classloader. As an example, junit
* testcases which are loaded via a custom classloader needs to see
* the same junit classes as the code invoking the testcase, otherwise
* they can't pass result objects back.
* <p>
* Normally, only a classloader created with a null parent needs to
* have any lookasides defined.
*/
private HashMap lookasides = null;
/**
* See setParentFirst.
*/
private boolean parentFirst = true;
/**
* Constructor.
*/
public PathableClassLoader(ClassLoader parent) {
super(NO_URLS, parent);
}
/**
* Allow caller to explicitly add paths. Generally this not a good idea;
* use addLogicalLib instead, then define the location for that logical
* library in the build.xml file.
*/
public void addURL(URL url) {
super.addURL(url);
}
/**
* Specify whether this classloader should ask the parent classloader
* to resolve a class first, before trying to resolve it via its own
* classpath.
* <p>
* Checking with the parent first is the normal approach for java, but
* components within containers such as servlet engines can use
* child-first lookup instead, to allow the components to override libs
* which are visible in shared classloaders provided by the container.
* <p>
* Note that the method getResources always behaves as if parentFirst=true,
* because of limitations in java 1.4; see the javadoc for method
* getResourcesInOrder for details.
* <p>
* This value defaults to true.
*/
public void setParentFirst(boolean state) {
parentFirst = state;
}
/**
* For classes with the specified prefix, get them from the system
* classpath <i>which is active at the point this method is called</i>.
* <p>
* This method is just a shortcut for
* <pre>
* useExplicitLoader(prefix, ClassLoader.getSystemClassLoader());
* </pre>
*/
public void useSystemLoader(String prefix) {
useExplicitLoader(prefix, ClassLoader.getSystemClassLoader());
}
/**
* Specify a classloader to use for specific java packages.
*/
public void useExplicitLoader(String prefix, ClassLoader loader) {
if (lookasides == null) {
lookasides = new HashMap();
}
lookasides.put(prefix, loader);
}
/**
* Specify a collection of logical libraries. See addLogicalLib.
*/
public void addLogicalLib(String[] logicalLibs) {
for(int i=0; i<logicalLibs.length; ++i) {
addLogicalLib(logicalLibs[i]);
}
}
/**
* Specify a logical library to be included in the classpath used to
* locate classes.
* <p>
* The specified lib name is used as a key into the system properties;
* there is expected to be a system property defined with that name
* whose value is a url that indicates where that logical library can
* be found. Typically this is the name of a jar file, or a directory
* containing class files.
* <p>
* Using logical library names allows the calling code to specify its
* desired classpath without knowing the exact location of the necessary
* classes.
*/
public void addLogicalLib(String logicalLib) {
String filename = System.getProperty(logicalLib);
if (filename == null) {
throw new UnknownError(
"Logical lib [" + logicalLib + "] is not defined"
+ " as a System property.");
}
try {
URL url = new File(filename).toURL();
addURL(url);
} catch(java.net.MalformedURLException e) {
throw new UnknownError(
"Invalid file [" + filename + "] for logical lib [" + logicalLib + "]");
}
}
/**
* Override ClassLoader method.
* <p>
* For each explicitly mapped package prefix, if the name matches the
* prefix associated with that entry then attempt to load the class via
* that entries' classloader.
*/
protected Class loadClass(String name, boolean resolve)
throws ClassNotFoundException {
// just for performance, check java and javax
if (name.startsWith("java.") || name.startsWith("javax.")) {
return super.loadClass(name, resolve);
}
if (lookasides != null) {
for(Iterator i = lookasides.entrySet().iterator(); i.hasNext(); ) {
Map.Entry entry = (Map.Entry) i.next();
String prefix = (String) entry.getKey();
if (name.startsWith(prefix) == true) {
ClassLoader loader = (ClassLoader) entry.getValue();
Class clazz = Class.forName(name, resolve, loader);
return clazz;
}
}
}
if (parentFirst) {
return super.loadClass(name, resolve);
} else {
// Implement child-first.
//
// It appears that the findClass method doesn't check whether the
// class has already been loaded. This seems odd to me, but without
// first checking via findLoadedClass we can get java.lang.LinkageError
// with message "duplicate class definition" which isn't good.
try {
Class clazz = findLoadedClass(name);
if (clazz == null) {
clazz = super.findClass(name);
}
if (resolve) {
resolveClass(clazz);
}
return clazz;
} catch(ClassNotFoundException e) {
return super.loadClass(name, resolve);
}
}
}
/**
* Same as parent class method except that when parentFirst is false
* the resource is looked for in the local classpath before the parent
* loader is consulted.
*/
public URL getResource(String name) {
if (parentFirst) {
return super.getResource(name);
} else {
URL local = super.findResource(name);
if (local != null) {
return local;
}
return super.getResource(name);
}
}
/**
* Emulate a proper implementation of getResources which respects the
* setting for parentFirst.
* <p>
* Note that it's not possible to override the inherited getResources, as
* it's declared final in java1.4 (thought that's been removed for 1.5).
* The inherited implementation always behaves as if parentFirst=true.
*/
public Enumeration getResourcesInOrder(String name) throws IOException {
if (parentFirst) {
return super.getResources(name);
} else {
Enumeration localUrls = super.findResources(name);
ClassLoader parent = getParent();
if (parent == null) {
// Alas, there is no method to get matching resources
// from a null (BOOT) parent classloader. Calling
// ClassLoader.getSystemClassLoader isn't right. Maybe
// calling Class.class.getResources(name) would do?
//
// However for the purposes of unit tests, we can
// simply assume that no relevant resources are
// loadable from the parent; unit tests will never be
// putting any of their resources in a "boot" classloader
// path!
return localUrls;
}
Enumeration parentUrls = parent.getResources(name);
ArrayList localItems = toList(localUrls);
ArrayList parentItems = toList(parentUrls);
localItems.addAll(parentItems);
return Collections.enumeration(localItems);
}
}
/**
*
* Clean implementation of list function of
* {@link java.utils.Collection} added in JDK 1.4
* @param en <code>Enumeration</code>, possibly null
* @return <code>ArrayList</code> containing the enumerated
* elements in the enumerated order, not null
*/
private ArrayList toList(Enumeration en) {
ArrayList results = new ArrayList();
if (en != null) {
while (en.hasMoreElements()){
Object element = en.nextElement();
results.add(element);
}
}
return results;
}
/**
* Same as parent class method except that when parentFirst is false
* the resource is looked for in the local classpath before the parent
* loader is consulted.
*/
public InputStream getResourceAsStream(String name) {
if (parentFirst) {
return super.getResourceAsStream(name);
} else {
URL local = super.findResource(name);
if (local != null) {
try {
return local.openStream();
} catch(IOException e) {
// TODO: check if this is right or whether we should
// fall back to trying parent. The javadoc doesn't say...
return null;
}
}
return super.getResourceAsStream(name);
}
}
}
More information about the jboss-cvs-commits
mailing list