001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     * 
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     * 
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */ 
017    package org.apache.commons.logging.pathable;
018    
019    import java.net.URL;
020    import java.net.URLClassLoader;
021    
022    import junit.framework.Test;
023    import junit.framework.TestCase;
024    
025    import org.apache.commons.logging.PathableClassLoader;
026    import org.apache.commons.logging.PathableTestSuite;
027    
028    /**
029     * Tests for the PathableTestSuite class.
030     */
031    
032    public class GeneralTestCase extends TestCase {
033        
034        /**
035         * Set up a custom classloader hierarchy for this test case.
036         */
037        public static Test suite() throws Exception {
038            Class thisClass = GeneralTestCase.class;
039            ClassLoader thisClassLoader = thisClass.getClassLoader();
040            
041            PathableClassLoader loader = new PathableClassLoader(null);
042            loader.useExplicitLoader("junit.", thisClassLoader);
043            loader.addLogicalLib("testclasses");
044    
045            // reload this class via the child classloader
046            Class testClass = loader.loadClass(thisClass.getName());
047            
048            // and return our custom TestSuite class
049            return new PathableTestSuite(testClass, loader);
050        }
051        
052        /**
053         * Verify that a certain system property is not set, then set it.
054         */
055        private static void checkAndSetProperties() {
056            String prop = System.getProperty("no.such.property");
057            assertNull("no.such.property is unexpectedly defined", prop);
058            System.setProperty("no.such.property", "dummy value");
059            prop = System.getProperty("no.such.property");
060            assertNotNull("no.such.property is unexpectedly undefined", prop);
061        }
062        
063        /**
064         * Verify that when a test method modifies the system properties they are
065         * reset before the next test is run.
066         * <p>
067         * This method works in conjunction with testResetProps2. There is no
068         * way of knowing which test method junit will run first, but it doesn't
069         * matter; whichever one of them runs first will modify the system properties.
070         * If the PathableTestSuite isn't resetting the system properties then whichever
071         * of them runs second will fail. Of course if other methods are run in-between
072         * then those methods might also fail...
073         */
074        public void testResetProps1() {
075            checkAndSetProperties();
076        }
077    
078        /**
079         * See testResetProps1.
080         */
081        public void testResetProps2() {
082            checkAndSetProperties();
083        }
084        
085        /**
086         * Verify that the context classloader is a custom one, then reset it to
087         * a non-custom one.
088         */
089        private static void checkAndSetContext() {
090            ClassLoader contextLoader = Thread.currentThread().getContextClassLoader();
091            assertEquals("ContextLoader is of unexpected type", 
092                    contextLoader.getClass().getName(), 
093                    PathableClassLoader.class.getName());
094            
095            URL[] noUrls = new URL[0];
096            Thread.currentThread().setContextClassLoader(new URLClassLoader(noUrls));
097        }
098        
099        /**
100         * Verify that when a test method modifies the context classloader it is
101         * reset before the next test is run.
102         * <p>
103         * This method works in conjunction with testResetContext2. There is no
104         * way of knowing which test method junit will run first, but it doesn't
105         * matter; whichever one of them runs first will modify the contextClassloader.
106         * If the PathableTestSuite isn't resetting the contextClassLoader then whichever
107         * of them runs second will fail. Of course if other methods are run in-between
108         * then those methods might also fail...
109         */
110        public void testResetContext1() {
111            checkAndSetContext();
112        }
113    
114        /**
115         * See testResetContext1.
116         */
117        public void testResetContext2() {
118            checkAndSetContext();
119        }
120    }