    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    *
    9    *      http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   */
    17
    18  package org.apache.commons.logging.tccl.logfactory;
    19
    20
    21  import java.net.URL;
    22
    23  import junit.framework.Test;
    24  import junit.framework.TestCase;
    25
    26  import org.apache.commons.logging.LogFactory;
    27  import org.apache.commons.logging.PathableClassLoader;
    28  import org.apache.commons.logging.PathableTestSuite;
    29
    30
    31  /**
    32   * Verify that by default a custom LogFactoryImpl is loaded from the
    33   * tccl classloader.
    34   */
    35
    36  public class TcclEnabledTestCase extends TestCase {
    37
    38      // ------------------------------------------- JUnit Infrastructure Methods
    39
    40
    41      /**
    42       * Return the tests included in this test suite.
    43       */
    44      public static Test suite() throws Exception {
    45          Class thisClass = TcclEnabledTestCase.class;
    46
    47          // Determine the URL to this .class file, so that we can then
    48          // append the priority dirs to it. For tidiness, load this
    49          // class through a dummy loader though this is not absolutely
    50          // necessary...
    51          PathableClassLoader dummy = new PathableClassLoader(null);
    52          dummy.useExplicitLoader("junit.", Test.class.getClassLoader());
    53          dummy.addLogicalLib("testclasses");
    54          dummy.addLogicalLib("commons-logging");
    55
    56          String thisClassPath = thisClass.getName().replace('.', '/') + ".class";
    57          URL baseUrl = dummy.findResource(thisClassPath);
    58
    59          // Now set up the desired classloader hierarchy. Everything goes into
    60          // the parent classpath, but we exclude the custom LogFactoryImpl
    61          // class.
    62          //
    63          // We then create a tccl classloader that can see the custom
    64          // LogFactory class. Therefore if that class can be found, then the
    65          // TCCL must have been used to load it.
    66          PathableClassLoader emptyLoader = new PathableClassLoader(null);
    67
    68          PathableClassLoader parentLoader = new PathableClassLoader(null);
    69          parentLoader.useExplicitLoader("junit.", Test.class.getClassLoader());
    70          parentLoader.addLogicalLib("commons-logging");
    71          parentLoader.addLogicalLib("testclasses");
    72          // hack to ensure that the testcase classloader can't see
    73          // the cust MyLogFactoryImpl
    74          parentLoader.useExplicitLoader(
    75              "org.apache.commons.logging.tccl.custom.", emptyLoader);
    76
    77          URL propsEnableUrl = new URL(baseUrl, "props_enable_tccl/");
    78          parentLoader.addURL(propsEnableUrl);
    79
    80          PathableClassLoader tcclLoader = new PathableClassLoader(parentLoader);
    81          tcclLoader.addLogicalLib("testclasses");
    82
    83          Class testClass = parentLoader.loadClass(thisClass.getName());
    84          return new PathableTestSuite(testClass, tcclLoader);
    85      }
    86
    87      /**
    88       * Set up instance variables required by this test case.
    89       */
    90      public void setUp() throws Exception {
    91          LogFactory.releaseAll();
    92      }
    93
    94      /**
    95       * Tear down instance variables required by this test case.
    96       */
    97      public void tearDown() {
    98          LogFactory.releaseAll();
    99      }
    100
    101     // ----------------------------------------------------------- Test Methods
    102
    103     /**
    104      * Verify that MyLogFactoryImpl is only loadable via the tccl.
    105      */
    106     public void testLoader() throws Exception {
    107
    108         ClassLoader thisClassLoader = this.getClass().getClassLoader();
    109         ClassLoader tcclLoader = Thread.currentThread().getContextClassLoader();
    110
    111         // the tccl loader should NOT be the same as the loader that loaded this test class.
    112         assertNotSame("tccl not same as test classloader", thisClassLoader, tcclLoader);
    113
    114         // MyLogFactoryImpl should not be loadable via parent loader
    115         try {
    116             Class clazz = thisClassLoader.loadClass(
    117                 "org.apache.commons.logging.tccl.custom.MyLogFactoryImpl");
    118             fail("Unexpectedly able to load MyLogFactoryImpl via test class classloader");
    119             assertNotNull(clazz); // silence warning about unused var
    120         } catch(ClassNotFoundException ex) {
    121             // ok, expected
    122         }
    123
    124         // MyLogFactoryImpl should be loadable via tccl loader
    125         try {
    126             Class clazz = tcclLoader.loadClass(
    127                 "org.apache.commons.logging.tccl.custom.MyLogFactoryImpl");
    128             assertNotNull(clazz);
    129         } catch(ClassNotFoundException ex) {
    130             fail("Unexpectedly unable to load MyLogFactoryImpl via tccl classloader");
    131         }
    132     }
    133
    134     /**
    135      * Verify that the custom LogFactory implementation which is only accessable
    136      * via the TCCL has successfully been loaded as specified in the config file.
    137      * This proves that the TCCL was used to load that class.
    138      */
    139     public void testTcclLoading() throws Exception {
    140         LogFactory instance = LogFactory.getFactory();
    141
    142         assertEquals(
    143             "Correct LogFactory loaded",
    144             "org.apache.commons.logging.tccl.custom.MyLogFactoryImpl",
    145             instance.getClass().getName());
    146     }
    147 }