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