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.log4j.xml;
19  
20  import junit.framework.Test;
21  import junit.framework.TestCase;
22  import junit.framework.TestSuite;
23  import org.apache.log4j.FileAppender;
24  import org.apache.log4j.Level;
25  import org.apache.log4j.Logger;
26  import org.apache.log4j.MDC;
27  import org.apache.log4j.util.Compare;
28  import org.apache.log4j.util.Filter;
29  import org.apache.log4j.util.JunitTestRunnerFilter;
30  import org.apache.log4j.util.LineNumberFilter;
31  import org.apache.log4j.util.SunReflectFilter;
32  import org.apache.log4j.util.Transformer;
33  import org.apache.log4j.util.XMLLineAttributeFilter;
34  import org.apache.log4j.util.XMLTimestampFilter;
35  
36  import java.util.Hashtable;
37  
38  public class XMLLayoutTestCase extends TestCase {
39  
40    static String TEMP = "output/temp";
41    static String FILTERED = "output/filtered";
42  
43    Logger root; 
44    Logger logger;
45  
46    public XMLLayoutTestCase(String name) {
47      super(name);
48    }
49  
50    public void setUp() {
51      root = Logger.getRootLogger();
52      root.setLevel(Level.TRACE);
53      logger = Logger.getLogger(XMLLayoutTestCase.class);
54      logger.setLevel(Level.TRACE);
55    }
56  
57    public void tearDown() {  
58      root.getLoggerRepository().resetConfiguration();
59    }
60  
61    public void basic() throws Exception {
62      XMLLayout xmlLayout = new XMLLayout();
63      root.addAppender(new FileAppender(xmlLayout, TEMP, false));
64      common();
65      Transformer.transform(
66        TEMP, FILTERED,
67        new Filter[] {
68          new LineNumberFilter(),
69          new XMLTimestampFilter(),
70          new JunitTestRunnerFilter(),
71          new SunReflectFilter()
72        });
73      assertTrue(Compare.compare(FILTERED, "witness/xmlLayout.1"));
74    }
75  
76    public void locationInfo() throws Exception {
77      XMLLayout xmlLayout = new XMLLayout();
78      xmlLayout.setLocationInfo(true);
79      root.addAppender(new FileAppender(xmlLayout, TEMP, false));
80      common();
81      Transformer.transform(
82        TEMP, FILTERED,
83        new Filter[] {
84          new LineNumberFilter(),
85          new XMLTimestampFilter(), 
86          new XMLLineAttributeFilter(),
87          new JunitTestRunnerFilter(),
88          new SunReflectFilter()
89        });
90      assertTrue(Compare.compare(FILTERED, "witness/xmlLayout.2"));
91    }
92  
93    public void testCDATA() throws Exception {
94      XMLLayout xmlLayout = new XMLLayout();
95      xmlLayout.setLocationInfo(true);
96      root.addAppender(new FileAppender(xmlLayout, TEMP, false));
97  
98      String oldThreadName = Thread.currentThread().getName();
99      Thread.currentThread().setName("main");
100     
101     logger.trace("Message with embedded <![CDATA[<hello>hi</hello>]]>.");
102     logger.debug("Message with embedded <![CDATA[<hello>hi</hello>]]>.");
103 
104     Thread.currentThread().setName(oldThreadName);
105 
106     Transformer.transform(
107       TEMP, FILTERED,
108       new Filter[] {
109         new LineNumberFilter(), 
110         new XMLTimestampFilter(),
111         new XMLLineAttributeFilter(), 
112         new SunReflectFilter(),
113         new JunitTestRunnerFilter()
114 
115       });
116     Transformer.transform(TEMP, FILTERED, new Filter[] {new LineNumberFilter(),
117     						  new XMLTimestampFilter(),
118     						  new XMLLineAttributeFilter()});
119     assertTrue(Compare.compare(FILTERED, "witness/xmlLayout.3"));
120   }
121 
122   public void testNull() throws Exception {
123     XMLLayout xmlLayout = new XMLLayout();
124     root.addAppender(new FileAppender(xmlLayout, TEMP, false));
125 
126     String oldThreadName = Thread.currentThread().getName();
127     Thread.currentThread().setName("main");
128 
129     logger.debug("hi");
130     logger.debug(null);
131     Exception e = new Exception((String) null);
132     logger.debug("hi", e);
133 
134     Thread.currentThread().setName(oldThreadName);
135 
136     Transformer.transform(
137       TEMP, FILTERED,
138       new Filter[] { new LineNumberFilter(),
139           new XMLTimestampFilter(),  
140           new JunitTestRunnerFilter(),
141           new SunReflectFilter()});
142     assertTrue(Compare.compare(FILTERED, "witness/xmlLayout.null"));
143   }
144 
145     /**
146      * Tests the format of the MDC portion of the layout to ensure
147      * the key-value pairs we put in turn up in the output file.
148      * @throws Exception
149      */
150     public void testMDC() throws Exception {
151       XMLLayout xmlLayout = new XMLLayout();
152       xmlLayout.setProperties(true);
153       root.addAppender(new FileAppender(xmlLayout, TEMP, false));
154 
155       Hashtable context = MDC.getContext();
156       if (context != null) {
157           context.clear();
158       }
159       MDC.put("key1", "val1");
160       MDC.put("key2", "val2");
161 
162       logger.debug("Hello");
163       Transformer.transform(
164         TEMP, FILTERED,
165         new Filter[] { new LineNumberFilter(),
166             new JunitTestRunnerFilter(),
167             new XMLTimestampFilter()});
168       assertTrue(Compare.compare(FILTERED, "witness/xmlLayout.mdc.1"));
169     }
170 
171     public void testMDCEscaped() throws Exception {
172       XMLLayout xmlLayout = new XMLLayout();
173       xmlLayout.setProperties(true);
174       root.addAppender(new FileAppender(xmlLayout, TEMP, false));
175 
176       Hashtable context = MDC.getContext();
177       if (context != null) {
178           context.clear();
179       }
180       MDC.put("blahAttribute", "<blah value='blah'>");
181       MDC.put("<blahKey value='blah'/>", "blahValue");
182 
183       logger.debug("Hello");
184       Transformer.transform(
185         TEMP, FILTERED,
186         new Filter[] { new LineNumberFilter(),
187             new JunitTestRunnerFilter(),
188             new XMLTimestampFilter() });
189       assertTrue(Compare.compare(FILTERED, "witness/xmlLayout.mdc.2"));
190     }
191 
192   
193   void common() {
194     String oldThreadName = Thread.currentThread().getName();
195     Thread.currentThread().setName("main");
196 
197     int i = -1;
198  
199     new X();
200 
201     logger.trace("Message " + ++i);
202     root.trace("Message " + i);    
203 
204     logger.debug("Message " + ++i);
205     root.debug("Message " + i);        
206 
207     logger.info("Message " + ++i);
208     root.info("Message " + i);        
209 
210     logger.warn ("Message " + ++i);
211     root.warn("Message " + i);        
212  
213     logger.error("Message " + ++i);
214     root.error("Message " + i);
215     
216     logger.log(Level.FATAL, "Message " + ++i);
217     root.log(Level.FATAL, "Message " + i);    
218     
219     Exception e = new Exception("Just testing");
220     logger.debug("Message " + ++i, e);
221     root.debug("Message " + i, e);
222     
223     logger.error("Message " + ++i, e);
224     root.error("Message " + i, e);    
225 
226 
227     Thread.currentThread().setName(oldThreadName);
228   }
229 
230   public static Test suite() {
231     TestSuite suite = new TestSuite();
232     suite.addTest(new XMLLayoutTestCase("basic"));
233     suite.addTest(new XMLLayoutTestCase("locationInfo"));
234     suite.addTest(new XMLLayoutTestCase("testCDATA"));
235     suite.addTest(new XMLLayoutTestCase("testNull"));
236     suite.addTest(new XMLLayoutTestCase("testMDC"));
237     suite.addTest(new XMLLayoutTestCase("testMDCEscaped"));
238     return suite;
239   }
240 
241 
242   class X {
243     Logger logger = Logger.getLogger(X.class);
244     public X() {
245       logger.info("in X() constructor");
246     }
247   }
248 }