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 }