Author: skitching
Date: Wed Jun 29 20:21:03 2005
New Revision: 202471

URL: http://svn.apache.org/viewcvs?rev=202471&view=rev
Log:
Allow testcases to control the classloader hierarchy used during the test.

Added:
    
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/PathableClassLoader.java
   (with props)
    
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/PathableTestSuite.java
   (with props)
    
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/jdk14/CustomConfigAPITestCase.java
   (with props)
    
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/jdk14/CustomConfigFullTestCase.java
   (with props)
    
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/log4j/CustomConfigAPITestCase.java
   (with props)
    
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/log4j/CustomConfigFullTestCase.java
   (with props)
    
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/pathable/
    
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/pathable/PathableTestCase.java
   (with props)
Modified:
    
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/jdk14/CustomConfigTestCase.java
    
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/jdk14/DefaultConfigTestCase.java
    
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/log4j/CustomConfigTestCase.java
    
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/log4j/DefaultConfigTestCase.java

Added: 
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/PathableClassLoader.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/PathableClassLoader.java?rev=202471&view=auto
==============================================================================
--- 
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/PathableClassLoader.java
 (added)
+++ 
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/PathableClassLoader.java
 Wed Jun 29 20:21:03 2005
@@ -0,0 +1,251 @@
+/*
+ * Created on 24/06/2005
+ *
+ * TODO To change the template for this generated file go to
+ * Window - Preferences - Java - Code Style - Code Templates
+ */
+
+package org.apache.commons.logging;
+
+import java.net.URL;
+import java.net.URLClassLoader;
+
+// TODO: use Hashtable instead of HashMap
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Iterator;
+
+import java.util.Enumeration;
+import java.util.Vector;
+import java.io.File;
+import java.io.InputStream;
+import java.io.IOException;
+
+/**
+ * A ClassLoader which sees only the specified classes.
+ */
+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);
+    }
+
+    /**
+     * 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>
+     * 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 {
+            // ok, implement child-first
+            try {
+                Class 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);
+        }
+    }
+    
+    /**
+     * 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);
+        }
+    }
+    
+    /**
+     * Same as parent class method except that when parentFirst is false
+     * the resources available from this class are returned at the head of
+     * the list instead of the tail.
+     */
+    public Enumeration getResources(String name) throws IOException {
+        if (parentFirst) {
+            return super.getResources(name);
+        } else {
+            Enumeration local = super.findResources(name);
+            Enumeration parent = getParent().getResources(name);
+            
+            if (!local.hasMoreElements()) {
+                return parent;
+            }
+            
+            if (!parent.hasMoreElements()) {
+                return local;
+            }
+
+            Vector v = new Vector();
+            while (local.hasMoreElements()) {
+                v.add(local.nextElement());
+            }
+            while (parent.hasMoreElements()) {
+                v.add(parent.nextElement());
+            }
+            return v.elements();
+        }
+    }
+}

Propchange: 
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/PathableClassLoader.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: 
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/PathableTestSuite.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/PathableTestSuite.java?rev=202471&view=auto
==============================================================================
--- 
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/PathableTestSuite.java
 (added)
+++ 
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/PathableTestSuite.java
 Wed Jun 29 20:21:03 2005
@@ -0,0 +1,125 @@
+/*
+ * Created on 24/06/2005
+ *
+ * TODO To change the template for this generated file go to
+ * Window - Preferences - Java - Code Style - Code Templates
+ */
+
+package org.apache.commons.logging;
+
+import java.io.PrintStream;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import junit.framework.TestResult;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Modifier;
+import java.util.Vector;
+
+/**
+ * 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.
+ * <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>
+ * 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>
+ * <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 
+ */
+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).
+     */
+    public void runTest(Test test, TestResult result) {
+        ClassLoader origContext = 
Thread.currentThread().getContextClassLoader();
+        try {
+            Thread.currentThread().setContextClassLoader(contextLoader);
+            test.run(result);
+        } finally {
+            Thread.currentThread().setContextClassLoader(origContext);
+        }
+    }
+}

Propchange: 
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/PathableTestSuite.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: 
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/jdk14/CustomConfigAPITestCase.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/jdk14/CustomConfigAPITestCase.java?rev=202471&view=auto
==============================================================================
--- 
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/jdk14/CustomConfigAPITestCase.java
 (added)
+++ 
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/jdk14/CustomConfigAPITestCase.java
 Wed Jun 29 20:21:03 2005
@@ -0,0 +1,59 @@
+/*
+ * 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.jdk14;
+
+import junit.framework.Test;
+
+import org.apache.commons.logging.PathableTestSuite;
+import org.apache.commons.logging.PathableClassLoader;
+
+
+/**
+ * TestCase for Jdk14 logging when the commons-logging-api jar file is in
+ * the parent classpath and commons-logging.jar is in the child.
+ */
+
+public class CustomConfigAPITestCase extends CustomConfigTestCase {
+
+
+    public CustomConfigAPITestCase(String name) {
+        super(name);
+    }
+
+
+    /**
+     * Return the tests included in this test suite.
+     */
+    public static Test suite() throws Exception {
+        PathableClassLoader parent = new PathableClassLoader(null);
+        parent.useSystemLoader("junit.");
+        // the TestHandler class must be accessable from the System classloader
+        // in order for java.util.logging.LogManager.readConfiguration to
+        // be able to instantiate it. And this test case must see the same
+        // class in order to be able to access its data. Yes this is ugly
+        // but the whole jdk14 API is a ******* mess anyway.
+        parent.useSystemLoader("org.apache.commons.logging.jdk14.TestHandler");
+        parent.addLogicalLib("commons-logging-api");
+
+        PathableClassLoader child = new PathableClassLoader(parent);
+        child.addLogicalLib("testclasses");
+        child.addLogicalLib("commons-logging");
+        
+        Class testClass = 
child.loadClass(CustomConfigAPITestCase.class.getName());
+        return new PathableTestSuite(testClass, child);
+    }
+}

Propchange: 
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/jdk14/CustomConfigAPITestCase.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: 
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/jdk14/CustomConfigFullTestCase.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/jdk14/CustomConfigFullTestCase.java?rev=202471&view=auto
==============================================================================
--- 
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/jdk14/CustomConfigFullTestCase.java
 (added)
+++ 
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/jdk14/CustomConfigFullTestCase.java
 Wed Jun 29 20:21:03 2005
@@ -0,0 +1,59 @@
+/*
+ * 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.jdk14;
+
+
+import junit.framework.Test;
+
+import org.apache.commons.logging.PathableTestSuite;
+import org.apache.commons.logging.PathableClassLoader;
+
+
+/**
+ * TestCase for Jdk14 logging when the commons-logging jar file is in
+ * the parent classpath.
+ */
+
+public class CustomConfigFullTestCase extends CustomConfigTestCase {
+
+
+    public CustomConfigFullTestCase(String name) {
+        super(name);
+    }
+
+
+    /**
+     * Return the tests included in this test suite.
+     */
+    public static Test suite() throws Exception {
+        PathableClassLoader parent = new PathableClassLoader(null);
+        parent.useSystemLoader("junit.");
+        // the TestHandler class must be accessable from the System classloader
+        // in order for java.util.logging.LogManager.readConfiguration to
+        // be able to instantiate it. And this test case must see the same
+        // class in order to be able to access its data. Yes this is ugly
+        // but the whole jdk14 API is a ******* mess anyway.
+        parent.useSystemLoader("org.apache.commons.logging.jdk14.TestHandler");
+        parent.addLogicalLib("commons-logging");
+
+        PathableClassLoader child = new PathableClassLoader(parent);
+        child.addLogicalLib("testclasses");
+        
+        Class testClass = 
child.loadClass(CustomConfigFullTestCase.class.getName());
+        return new PathableTestSuite(testClass, child);
+    }
+}

Propchange: 
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/jdk14/CustomConfigFullTestCase.java
------------------------------------------------------------------------------
    svn:keywords = Id

Modified: 
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/jdk14/CustomConfigTestCase.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/jdk14/CustomConfigTestCase.java?rev=202471&r1=202470&r2=202471&view=diff
==============================================================================
--- 
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/jdk14/CustomConfigTestCase.java
 (original)
+++ 
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/jdk14/CustomConfigTestCase.java
 Wed Jun 29 20:21:03 2005
@@ -28,6 +28,9 @@
 import junit.framework.Test;
 import junit.framework.TestSuite;
 
+import org.apache.commons.logging.PathableTestSuite;
+import org.apache.commons.logging.PathableClassLoader;
+
 
 /**
  * <p>TestCase for JDK 1.4 logging when running on a JDK 1.4 system with
@@ -114,8 +117,19 @@
     /**
      * Return the tests included in this test suite.
      */
-    public static Test suite() {
-        return (new TestSuite(CustomConfigTestCase.class));
+    public static Test suite() throws Exception {
+        /*
+        PathableClassLoader loader = new PathableClassLoader(null);
+        loader.useSystemLoader("junit.");
+
+        PathableClassLoader child = new PathableClassLoader(parent);
+        child.addLogicalLib("testclasses");
+        child.addLogicalLib("commons-logging");
+        
+        Class testClass = 
child.loadClass(CustomConfigTestCase.class.getName());
+        return new PathableTestSuite(testClass, child);
+        */
+        return new TestSuite(CustomConfigTestCase.class);
     }
 
     /**
@@ -220,9 +234,9 @@
                          testLevels[i], record.getLevel());
             assertEquals("LogRecord message",
                          testMessages[i], record.getMessage());
-            assertEquals("LogRecord class",
-                         this.getClass().getName(),
-                         record.getSourceClassName());
+            assertTrue("LogRecord class",
+                         record.getSourceClassName().startsWith(
+                                 
"org.apache.commons.logging.jdk14.CustomConfig"));
             if (thrown) {
                 assertEquals("LogRecord method",
                              "logExceptionMessages",

Modified: 
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/jdk14/DefaultConfigTestCase.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/jdk14/DefaultConfigTestCase.java?rev=202471&r1=202470&r2=202471&view=diff
==============================================================================
--- 
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/jdk14/DefaultConfigTestCase.java
 (original)
+++ 
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/jdk14/DefaultConfigTestCase.java
 Wed Jun 29 20:21:03 2005
@@ -85,7 +85,7 @@
     /**
      * Return the tests included in this test suite.
      */
-    public static Test suite() {
+    public static Test suite() throws Exception {
         return (new TestSuite(DefaultConfigTestCase.class));
     }
 

Added: 
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/log4j/CustomConfigAPITestCase.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/log4j/CustomConfigAPITestCase.java?rev=202471&view=auto
==============================================================================
--- 
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/log4j/CustomConfigAPITestCase.java
 (added)
+++ 
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/log4j/CustomConfigAPITestCase.java
 Wed Jun 29 20:21:03 2005
@@ -0,0 +1,54 @@
+/*
+ * 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.log4j;
+
+import junit.framework.Test;
+
+import org.apache.commons.logging.PathableTestSuite;
+import org.apache.commons.logging.PathableClassLoader;
+
+
+/**
+ * TestCase for Log4J logging when the commons-logging-api jar file is in
+ * the parent classpath and commons-logging.jar is in the child.
+ */
+
+public class CustomConfigAPITestCase extends CustomConfigTestCase {
+
+
+    public CustomConfigAPITestCase(String name) {
+        super(name);
+    }
+
+
+    /**
+     * Return the tests included in this test suite.
+     */
+    public static Test suite() throws Exception {
+        PathableClassLoader parent = new PathableClassLoader(null);
+        parent.useSystemLoader("junit.");
+        parent.addLogicalLib("commons-logging-api");
+
+        PathableClassLoader child = new PathableClassLoader(parent);
+        child.addLogicalLib("testclasses");
+        child.addLogicalLib("log4j12");
+        child.addLogicalLib("commons-logging");
+        
+        Class testClass = 
child.loadClass(CustomConfigAPITestCase.class.getName());
+        return new PathableTestSuite(testClass, child);
+    }
+}

Propchange: 
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/log4j/CustomConfigAPITestCase.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: 
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/log4j/CustomConfigFullTestCase.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/log4j/CustomConfigFullTestCase.java?rev=202471&view=auto
==============================================================================
--- 
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/log4j/CustomConfigFullTestCase.java
 (added)
+++ 
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/log4j/CustomConfigFullTestCase.java
 Wed Jun 29 20:21:03 2005
@@ -0,0 +1,53 @@
+/*
+ * 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.log4j;
+
+import junit.framework.Test;
+
+import org.apache.commons.logging.PathableTestSuite;
+import org.apache.commons.logging.PathableClassLoader;
+
+
+/**
+ * TestCase for Log4J logging when the commons-logging jar file is in
+ * the parent classpath.
+ */
+
+public class CustomConfigFullTestCase extends CustomConfigTestCase {
+
+
+    public CustomConfigFullTestCase(String name) {
+        super(name);
+    }
+
+
+    /**
+     * Return the tests included in this test suite.
+     */
+    public static Test suite() throws Exception {
+        PathableClassLoader parent = new PathableClassLoader(null);
+        parent.useSystemLoader("junit.");
+        parent.addLogicalLib("commons-logging");
+        parent.addLogicalLib("log4j12");
+
+        PathableClassLoader child = new PathableClassLoader(parent);
+        child.addLogicalLib("testclasses");
+        
+        Class testClass = 
child.loadClass(CustomConfigFullTestCase.class.getName());
+        return new PathableTestSuite(testClass, child);
+    }
+}

Propchange: 
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/log4j/CustomConfigFullTestCase.java
------------------------------------------------------------------------------
    svn:keywords = Id

Modified: 
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/log4j/CustomConfigTestCase.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/log4j/CustomConfigTestCase.java?rev=202471&r1=202470&r2=202471&view=diff
==============================================================================
--- 
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/log4j/CustomConfigTestCase.java
 (original)
+++ 
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/log4j/CustomConfigTestCase.java
 Wed Jun 29 20:21:03 2005
@@ -23,13 +23,15 @@
 import java.util.Properties;
 
 import junit.framework.Test;
-import junit.framework.TestSuite;
 
 import org.apache.log4j.Level;
 import org.apache.log4j.Logger;
 import org.apache.log4j.PropertyConfigurator;
 import org.apache.log4j.spi.LoggingEvent;
 
+import org.apache.commons.logging.PathableTestSuite;
+import org.apache.commons.logging.PathableClassLoader;
+
 
 /**
  * <p>TestCase for Log4J logging when running on a system with Log4J present,
@@ -103,8 +105,17 @@
     /**
      * Return the tests included in this test suite.
      */
-    public static Test suite() {
-        return (new TestSuite(CustomConfigTestCase.class));
+    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(CustomConfigTestCase.class.getName());
+        return new PathableTestSuite(testClass, child);
     }
 
     /**
@@ -123,7 +134,6 @@
 
     // Test logging message strings with exceptions
     public void testExceptionMessages() throws Exception {
-
         logExceptionMessages();
         checkLoggingEvents(true);
 

Modified: 
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/log4j/DefaultConfigTestCase.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/log4j/DefaultConfigTestCase.java?rev=202471&r1=202470&r2=202471&view=diff
==============================================================================
--- 
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/log4j/DefaultConfigTestCase.java
 (original)
+++ 
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/log4j/DefaultConfigTestCase.java
 Wed Jun 29 20:21:03 2005
@@ -28,6 +28,8 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.commons.logging.PathableTestSuite;
+import org.apache.commons.logging.PathableClassLoader;
 
 
 /**
@@ -85,8 +87,17 @@
     /**
      * Return the tests included in this test suite.
      */
-    public static Test suite() {
-        return (new TestSuite(DefaultConfigTestCase.class));
+    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(DefaultConfigTestCase.class.getName());
+        return new PathableTestSuite(testClass, child);
     }
 
     /**

Added: 
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/pathable/PathableTestCase.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/pathable/PathableTestCase.java?rev=202471&view=auto
==============================================================================
--- 
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/pathable/PathableTestCase.java
 (added)
+++ 
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/pathable/PathableTestCase.java
 Wed Jun 29 20:21:03 2005
@@ -0,0 +1,129 @@
+/*
+ * 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.pathable;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import org.apache.commons.logging.PathableTestSuite;
+import org.apache.commons.logging.PathableClassLoader;
+
+/**
+ * Tests for the PathableTestSuite and PathableClassLoader functionality.
+ * <p>
+ * These tests assume:
+ * <ul>
+ * <li>junit is in system classpath
+ * <li>nothing else is in system classpath
+ * </ul>
+ */
+
+public class PathableTestCase extends TestCase {
+    public static Test suite() throws Exception {
+        // make the parent a direct child of the bootloader to hide all
+        // other classes in the system classpath
+        PathableClassLoader parent = new PathableClassLoader(null);
+        
+        // make the junit classes from the system classpath visible, though,
+        // as junit won't be able to call this class at all without this..
+        parent.useSystemLoader("junit.");
+        
+        // make the commons-logging-api.jar classes visible via the parent
+        parent.addLogicalLib("commons-logging-api");
+        
+        // create a child classloader to load the test case through
+        PathableClassLoader child = new PathableClassLoader(parent);
+        
+        // obviously, the child classloader needs to have the test classes
+        // in its path!
+        child.addLogicalLib("testclasses");
+        
+        // create a third classloader to be the context classloader.
+        PathableClassLoader context = new PathableClassLoader(child);
+
+        // reload this class via the child classloader
+        Class testClass = child.loadClass(PathableTestCase.class.getName());
+        
+        // and return our custom TestSuite class
+        return new PathableTestSuite(testClass, context);
+    }
+    
+    public void testPaths() throws Exception {
+        // the context classloader is not expected to be null
+        ClassLoader contextLoader = 
Thread.currentThread().getContextClassLoader();
+        assertNotNull("Context classloader is null", contextLoader);
+        assertEquals("Context classloader has unexpected type",
+                PathableClassLoader.class.getName(),
+                contextLoader.getClass().getName());
+        
+        // the classloader that loaded this class is obviously not null
+        ClassLoader thisLoader = this.getClass().getClassLoader();
+        assertNotNull("thisLoader is null", thisLoader);
+        assertEquals("thisLoader has unexpected type",
+                PathableClassLoader.class.getName(),
+                thisLoader.getClass().getName());
+        
+        // the suite method specified that the context classloader's parent
+        // is the loader that loaded this test case.
+        assertSame("Context classloader is not child of thisLoader",
+                thisLoader, contextLoader.getParent());
+
+        // thisLoader's parent should be available
+        ClassLoader parentLoader = thisLoader.getParent();
+        assertNotNull("Parent classloader is null", parentLoader);
+        assertEquals("Parent classloader has unexpected type",
+                PathableClassLoader.class.getName(),
+                parentLoader.getClass().getName());
+        
+        // parent should have a parent of null
+        assertNull("Parent classloader has non-null parent", 
parentLoader.getParent());
+
+        // getSystemClassloader is not a PathableClassLoader; it's of a
+        // built-in type. This also verifies that system classloader is none of
+        // (context, child, parent).
+        ClassLoader systemLoader = ClassLoader.getSystemClassLoader();
+        assertNotNull("System classloader is null", systemLoader);
+        assertFalse("System classloader has unexpected type",
+                PathableClassLoader.class.getName().equals(
+                        systemLoader.getClass().getName()));
+
+        // junit classes should be visible; their classloader is system.
+        // this will of course throw an exception if not found.
+        Class junitTest = contextLoader.loadClass("junit.framework.Test");
+        assertSame("Junit not loaded via systemloader",
+                systemLoader, junitTest.getClassLoader());
+
+        // jcl api classes should be visible via the parent
+        Class logClass = 
contextLoader.loadClass("org.apache.commons.logging.Log");
+        assertSame("Log class not loaded via parent",
+                logClass.getClassLoader(), parentLoader);
+
+        // jcl non-api classes should not be visible
+        try {
+            Class log4jClass = contextLoader.loadClass(
+                "org.apache.commons.logging.impl.Log4J12Logger");
+            fail("Class Log4J12Logger is unexpectedly available");
+        } catch(ClassNotFoundException ex) {
+            // ok
+        }
+
+        // String class classloader is null
+        Class stringClass = contextLoader.loadClass("java.lang.String");
+        assertNull("String class classloader is not null!",
+                stringClass.getClassLoader());
+    }
+}

Propchange: 
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/pathable/PathableTestCase.java
------------------------------------------------------------------------------
    svn:keywords = Id



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to