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    
018    package org.apache.commons.logging.log4j;
019    
020    
021    import java.io.ByteArrayInputStream;
022    import java.io.ByteArrayOutputStream;
023    import java.io.ObjectInputStream;
024    import java.io.ObjectOutputStream;
025    import java.util.ArrayList;
026    import java.util.List;
027    
028    import junit.framework.TestCase;
029    
030    import org.apache.commons.logging.DummyException;
031    import org.apache.commons.logging.Log;
032    import org.apache.commons.logging.LogFactory;
033    
034    
035    /**
036     * Abstract set of tests that can be executed with various classpaths set.
037     * <p>
038     * The tests verify that when running on a system with Log4J present,
039     * Log4J is selected and that the logger basically works.
040     */
041    
042    public abstract class StandardTests extends TestCase {
043    
044        /**
045         * Simple structure to store information about messages that actually get
046         * logged by the underlying logging library.
047         */
048        public static class LogEvent {
049            public String msg;
050            public String level;
051            public Throwable throwable;
052        }
053    
054        // ------------------------------------------------------------------- 
055        // JUnit Infrastructure Methods
056        // ------------------------------------------------------------------- 
057    
058        /**
059         * Set up instance variables required by this test case.
060         */
061        public void setUp() throws Exception {
062            LogFactory.releaseAll();
063        }
064    
065        /**
066         * Tear down instance variables required by this test case.
067         */
068        public void tearDown() {
069            LogFactory.releaseAll();
070        }
071    
072        // ----------------------------------------------------------- 
073        // abstract methods
074        // ----------------------------------------------------------- 
075    
076        /**
077         * Modify log4j's setup so that all messages actually logged get redirected
078         * into the specified list.
079         * <p>
080         * This method also sets the logging level to INFO so that we
081         * can test whether messages are getting properly filtered.
082         */
083        public abstract void setUpTestAppender(List logEvents) throws Exception;
084        
085        // ----------------------------------------------------------- Test Methods
086    
087        /**
088         * Test that a LogFactory gets created as expected.
089         */
090        public void testCreateFactory() {
091            LogFactory factory = LogFactory.getFactory();
092            assertNotNull("LogFactory exists", factory);
093            assertEquals("LogFactory class",
094                         "org.apache.commons.logging.impl.LogFactoryImpl",
095                         factory.getClass().getName());
096    
097            String names[] = factory.getAttributeNames();
098            assertNotNull("Names exists", names);
099            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    }