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.simple;
19  
20  import java.util.ArrayList;
21  import java.util.Iterator;
22  import java.util.List;
23  
24  import org.apache.commons.logging.DummyException;
25  import org.apache.commons.logging.LogFactory;
26  import org.apache.commons.logging.PathableClassLoader;
27  import org.apache.commons.logging.PathableTestSuite;
28  import org.apache.commons.logging.impl.SimpleLog;
29  
30  import junit.framework.Test;
31  
32  /**
33   * <p>TestCase for simple logging when running with custom configuration
34   * properties.</p>
35   */
36  public class CustomConfigTestCase extends DefaultConfigTestCase {
37  
38      /**
39       * Return the tests included in this test suite.
40       * <p>
41       * We need to use a PathableClassLoader here because the SimpleLog class
42       * is a pile of junk and chock-full of static variables. Any other test
43       * (like simple.CustomConfigTestCase) that has used the SimpleLog class
44       * will already have caused it to do once-only initialization that we
45       * can't reset, even by calling LogFactory.releaseAll, because of those
46       * ugly statics. The only clean solution is to load a clean copy of
47       * commons-logging including SimpleLog via a nice clean class loader.
48       * Or we could fix SimpleLog to be sane...
49       */
50      public static Test suite() throws Exception {
51          final Class thisClass = CustomConfigTestCase.class;
52  
53          final PathableClassLoader loader = new PathableClassLoader(null);
54          loader.useExplicitLoader("junit.", Test.class.getClassLoader());
55          loader.addLogicalLib("testclasses");
56          loader.addLogicalLib("commons-logging");
57  
58          final Class testClass = loader.loadClass(thisClass.getName());
59          return new PathableTestSuite(testClass, loader);
60      }
61  
62      /**
63       * <p>The message levels that should have been logged.</p>
64       */
65      /*
66      protected Level[] testLevels =
67      { Level.FINE, Level.INFO, Level.WARNING, Level.SEVERE, Level.SEVERE };
68      */
69  
70      /**
71       * <p>The expected log records.</p>
72       */
73      protected List expected;
74  
75      /**
76       * <p>The message strings that should have been logged.</p>
77       */
78      protected String[] testMessages =
79      { "debug", "info", "warn", "error", "fatal" };
80  
81      // Check the decorated log instance
82      @Override
83      protected void checkDecorated() {
84  
85          assertNotNull("Log exists", log);
86          assertEquals("Log class",
87                       "org.apache.commons.logging.simple.DecoratedSimpleLog",
88                       log.getClass().getName());
89  
90          // Can we call level checkers with no exceptions?
91          assertTrue(log.isDebugEnabled());
92          assertTrue(log.isErrorEnabled());
93          assertTrue(log.isFatalEnabled());
94          assertTrue(log.isInfoEnabled());
95          assertFalse(log.isTraceEnabled());
96          assertTrue(log.isWarnEnabled());
97  
98          // Can we retrieve the current log level?
99          assertEquals(SimpleLog.LOG_LEVEL_DEBUG, ((SimpleLog) log).getLevel());
100 
101         // Can we validate the extra exposed properties?
102         checkDecoratedDateTime();
103         assertEquals("DecoratedLogger",
104                      ((DecoratedSimpleLog) log).getLogName());
105         checkShowDateTime();
106         assertTrue(((DecoratedSimpleLog) log).getShowShortName());
107 
108     }
109 
110     /** Hook for subclasses */
111     protected void checkDecoratedDateTime() {
112             assertEquals("yyyy/MM/dd HH:mm:ss:SSS zzz",
113                      ((DecoratedSimpleLog) log).getDateTimeFormat());
114     }
115 
116     // Check the actual log records against the expected ones
117     protected void checkExpected() {
118         final List acts = ((DecoratedSimpleLog) log).getCache();
119         final Iterator exps = expected.iterator();
120         int n = 0;
121         while (exps.hasNext()) {
122             final LogRecord exp = (LogRecord) exps.next();
123             final LogRecord act = (LogRecord) acts.get(n++);
124             assertEquals("Row " + n + " type", exp.type, act.type);
125             assertEquals("Row " + n + " message", exp.message, act.message);
126             assertEquals("Row " + n + " throwable", exp.t, act.t);
127         }
128     }
129 
130     /** Hook for subclassses */
131     protected void checkShowDateTime() {
132         assertFalse(((DecoratedSimpleLog) log).getShowDateTime());
133     }
134 
135     // Check the standard log instance
136     @Override
137     protected void checkStandard() {
138         checkDecorated();
139     }
140 
141     // Log the messages with exceptions
142     protected void logExceptionMessages() {
143         // Generate log records
144         final Throwable t = new DummyException();
145         log.trace("trace", t); // Should not actually get logged
146         log.debug("debug", t);
147         log.info("info", t);
148         log.warn("warn", t);
149         log.error("error", t);
150         log.fatal("fatal", t);
151 
152         // Record the log records we expect
153         expected.add(new LogRecord(SimpleLog.LOG_LEVEL_DEBUG, "debug", t));
154         expected.add(new LogRecord(SimpleLog.LOG_LEVEL_INFO, "info", t));
155         expected.add(new LogRecord(SimpleLog.LOG_LEVEL_WARN, "warn", t));
156         expected.add(new LogRecord(SimpleLog.LOG_LEVEL_ERROR, "error", t));
157         expected.add(new LogRecord(SimpleLog.LOG_LEVEL_FATAL, "fatal", t));
158     }
159 
160     // Log the plain messages
161     protected void logPlainMessages() {
162         // Generate log records
163         log.trace("trace"); // Should not actually get logged
164         log.debug("debug");
165         log.info("info");
166         log.warn("warn");
167         log.error("error");
168         log.fatal("fatal");
169 
170         // Record the log records we expect
171         expected.add(new LogRecord(SimpleLog.LOG_LEVEL_DEBUG, "debug", null));
172         expected.add(new LogRecord(SimpleLog.LOG_LEVEL_INFO, "info", null));
173         expected.add(new LogRecord(SimpleLog.LOG_LEVEL_WARN, "warn", null));
174         expected.add(new LogRecord(SimpleLog.LOG_LEVEL_ERROR, "error", null));
175         expected.add(new LogRecord(SimpleLog.LOG_LEVEL_FATAL, "fatal", null));
176     }
177 
178     /**
179      * Sets system properties that will control the LogFactory/Log objects
180      * when they are created. Subclasses can override this method to
181      * define properties that suit them.
182      */
183     @Override
184     public void setProperties() {
185         System.setProperty(
186             "org.apache.commons.logging.Log",
187             "org.apache.commons.logging.simple.DecoratedSimpleLog");
188         System.setProperty(
189             "org.apache.commons.logging.simplelog.defaultlog",
190             "debug");
191     }
192 
193     /**
194      * Sets up instance variables required by this test case.
195      */
196     @Override
197     public void setUp() throws Exception {
198         LogFactory.releaseAll();
199         setProperties();
200         expected = new ArrayList();
201         setUpFactory();
202         setUpLog("DecoratedLogger");
203     }
204 
205     /**
206      * Tear down instance variables required by this test case.
207      */
208     @Override
209     public void tearDown() {
210         super.tearDown();
211         expected = null;
212     }
213 
214     // Test logging message strings with exceptions
215     public void testExceptionMessages() throws Exception {
216         ((DecoratedSimpleLog) log).clearCache();
217         logExceptionMessages();
218         checkExpected();
219     }
220 
221     // Test logging plain message strings
222     public void testPlainMessages() throws Exception {
223         ((DecoratedSimpleLog) log).clearCache();
224         logPlainMessages();
225         checkExpected();
226     }
227 
228     // Test Serializability of standard instance
229     @Override
230     public void testSerializable() throws Exception {
231         ((DecoratedSimpleLog) log).clearCache();
232         logPlainMessages();
233         super.testSerializable();
234         logExceptionMessages();
235         checkExpected();
236     }
237 }