    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.log4j;
    19
    20
    21  import java.io.ByteArrayInputStream;
    22  import java.io.ByteArrayOutputStream;
    23  import java.io.ObjectInputStream;
    24  import java.io.ObjectOutputStream;
    25  import java.util.ArrayList;
    26  import java.util.List;
    27
    28  import junit.framework.TestCase;
    29
    30  import org.apache.commons.logging.DummyException;
    31  import org.apache.commons.logging.Log;
    32  import org.apache.commons.logging.LogFactory;
    33
    34
    35  /**
    36   * Abstract set of tests that can be executed with various classpaths set.
    37   * <p>
    38   * The tests verify that when running on a system with Log4J present,
    39   * Log4J is selected and that the logger basically works.
    40   */
    41
    42  public abstract class StandardTests extends TestCase {
    43
    44      /**
    45       * Simple structure to store information about messages that actually get
    46       * logged by the underlying logging library.
    47       */
    48      public static class LogEvent {
    49          public String msg;
    50          public String level;
    51          public Throwable throwable;
    52      }
    53
    54      // -------------------------------------------------------------------
    55      // JUnit Infrastructure Methods
    56      // -------------------------------------------------------------------
    57
    58      /**
    59       * Set up instance variables required by this test case.
    60       */
    61      public void setUp() throws Exception {
    62          LogFactory.releaseAll();
    63      }
    64
    65      /**
    66       * Tear down instance variables required by this test case.
    67       */
    68      public void tearDown() {
    69          LogFactory.releaseAll();
    70      }
    71
    72      // -----------------------------------------------------------
    73      // abstract methods
    74      // -----------------------------------------------------------
    75
    76      /**
    77       * Modify log4j's setup so that all messages actually logged get redirected
    78       * into the specified list.
    79       * <p>
    80       * This method also sets the logging level to INFO so that we
    81       * can test whether messages are getting properly filtered.
    82       */
    83      public abstract void setUpTestAppender(List logEvents) throws Exception;
    84
    85      // ----------------------------------------------------------- Test Methods
    86
    87      /**
    88       * Test that a LogFactory gets created as expected.
    89       */
    90      public void testCreateFactory() {
    91          LogFactory factory = LogFactory.getFactory();
    92          assertNotNull("LogFactory exists", factory);
    93          assertEquals("LogFactory class",
    94                       "org.apache.commons.logging.impl.LogFactoryImpl",
    95                       factory.getClass().getName());
    96
    97          String names[] = factory.getAttributeNames();
    98          assertNotNull("Names exists", names);
    99          assertEquals("Names empty", 0, names.length);
    100     }
    101
    102     /**
    103      * Verify that we can log messages without exceptions.
    104      */
    105     public void testPlainMessages() throws Exception {
    106         List logEvents = new ArrayList();
    107         setUpTestAppender(logEvents);
    108         Log log = LogFactory.getLog("test-category");
    109         logPlainMessages(log);
    110         checkLoggingEvents(logEvents, false);
    111     }
    112
    113     /**
    114      * Verify that we can log exception messages.
    115      */
    116     public void testExceptionMessages() throws Exception {
    117         List logEvents = new ArrayList();
    118         setUpTestAppender(logEvents);
    119         Log log = LogFactory.getLog("test-category");
    120         logExceptionMessages(log);
    121         checkLoggingEvents(logEvents, true);
    122     }
    123
    124     /**
    125      * Test Serializability of Log instance
    126      */
    127     public void testSerializable() throws Exception {
    128         List logEvents = new ArrayList();
    129         setUpTestAppender(logEvents);
    130         Log log = LogFactory.getLog("test-category");
    131
    132         ByteArrayOutputStream baos = new ByteArrayOutputStream();
    133         ObjectOutputStream oos = new ObjectOutputStream(baos);
    134         oos.writeObject(log);
    135         oos.close();
    136         ByteArrayInputStream bais =
    137             new ByteArrayInputStream(baos.toByteArray());
    138         ObjectInputStream ois = new ObjectInputStream(bais);
    139         Log newLog = (Log) ois.readObject();
    140         ois.close();
    141
    142         // Check the characteristics of the resulting object
    143         logExceptionMessages(newLog);
    144         checkLoggingEvents(logEvents, true);
    145     }
    146
    147     // -------------------------------------------------------- Support Methods
    148
    149     /**
    150      * Verify that the TestAppender has received the expected
    151      * number of messages. This assumes that:
    152      * <ul>
    153      * <li>setUpTestAppender has been called
    154      * <li>logPlainMessages or logExceptionMessages has been
    155      * called to log a known number of messages at known levels.
    156      * </ul>
    157      *
    158      * @param logEvents is the list of log events received.
    159      *
    160      * @param thrown False if logPlainMessages was called
    161      * (ie the TestAppender is expected to have received
    162      * logevents with no associated exception info). True if
    163      * logExceptionMessages was called.
    164      */
    165     private void checkLoggingEvents(List logEvents, boolean thrown) {
    166         LogEvent ev;
    167
    168         assertEquals("Unexpected number of log events", 4, logEvents.size());
    169
    170         ev = (LogEvent) logEvents.get(0);
    171         assertEquals("Info message expected", "info", ev.msg);
    172         assertEquals("Info level expected", "INFO", ev.level);
    173         assertEquals("Exception data incorrect", (ev.throwable!=null), thrown);
    174
    175         ev = (LogEvent) logEvents.get(1);
    176         assertEquals("Warn message expected", "warn", ev.msg);
    177         assertEquals("Warn level expected", "WARN", ev.level);
    178         assertEquals("Exception data incorrect", (ev.throwable!=null), thrown);
    179
    180         ev = (LogEvent) logEvents.get(2);
    181         assertEquals("Error message expected", "error", ev.msg);
    182         assertEquals("Error level expected", "ERROR", ev.level);
    183         assertEquals("Exception data incorrect", (ev.throwable!=null), thrown);
    184
    185         ev = (LogEvent) logEvents.get(3);
    186         assertEquals("Fatal message expected", "fatal", ev.msg);
    187         assertEquals("Fatal level expected", "FATAL", ev.level);
    188         assertEquals("Exception data incorrect", (ev.throwable!=null), thrown);
    189     }
    190
    191
    192     /**
    193      * Log plain messages.
    194      */
    195     private void logPlainMessages(Log log) {
    196         log.trace("trace"); // Should not actually get logged
    197         log.debug("debug"); // Should not actually get logged
    198         log.info("info");
    199         log.warn("warn");
    200         log.error("error");
    201         log.fatal("fatal");
    202     }
    203
    204     /**
    205      * Log messages with exceptions
    206      */
    207     private void logExceptionMessages(Log log) {
    208         Throwable t = new DummyException();
    209         log.trace("trace", t); // Should not actually get logged
    210         log.debug("debug", t); // Should not actually get logged
    211         log.info("info", t);
    212         log.warn("warn", t);
    213         log.error("error", t);
    214         log.fatal("fatal", t);
    215     }
    216 }