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