1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.log4j;
19
20 import org.apache.log4j.spi.LoggingEvent;
21 import org.w3c.dom.Document;
22 import org.xml.sax.InputSource;
23
24 import javax.xml.parsers.DocumentBuilder;
25 import javax.xml.parsers.DocumentBuilderFactory;
26 import java.io.Reader;
27 import java.io.StringReader;
28 import java.util.Hashtable;
29
30
31 /***
32 * Test for HTMLLayout.
33 *
34 * @author Curt Arnold
35 */
36 public class HTMLLayoutTest extends LayoutTest {
37 /***
38 * Construct new instance of XMLLayoutTest.
39 *
40 * @param testName test name.
41 */
42 public HTMLLayoutTest(final String testName) {
43 super(testName, "text/html", false, null, null);
44 }
45
46 /***
47 * @{inheritDoc}
48 */
49 protected Layout createLayout() {
50 return new HTMLLayout();
51 }
52
53 /***
54 * Parses the string as the body of an XML document and returns the document element.
55 * @param source source string.
56 * @return document element.
57 * @throws Exception if parser can not be constructed or source is not a valid XML document.
58 */
59 private Document parse(final String source) throws Exception {
60 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
61 factory.setNamespaceAware(false);
62 factory.setCoalescing(true);
63
64 DocumentBuilder builder = factory.newDocumentBuilder();
65 Reader reader = new StringReader(source);
66
67 return builder.parse(new InputSource(reader));
68 }
69
70 /***
71 * Tests formatted results.
72 * @throws Exception if unable to create parser or output is not valid XML.
73 */
74 public void testFormat() throws Exception {
75 Logger logger = Logger.getLogger("org.apache.log4j.xml.HTMLLayoutTest");
76 NDC.push("NDC goes here");
77
78 LoggingEvent event =
79 new LoggingEvent(
80 "org.apache.log4j.Logger", logger, Level.INFO, "Hello, World", null);
81 HTMLLayout layout = (HTMLLayout) createLayout();
82 layout.setLocationInfo(true);
83
84 String result = layout.format(event);
85 NDC.pop();
86
87 String src =
88 "<!DOCTYPE body [ <!ENTITY nbsp ' '>]><body>" + result + "</body>";
89 Document doc = parse(src);
90 }
91
92 /***
93 * Tests getHeader.
94 */
95 public void testGetHeader() {
96 assertEquals("<!DOCTYPE", createLayout().getHeader().substring(0, 9));
97 }
98
99 /***
100 * Tests getHeader with locationInfo = true.
101 */
102 public void testGetHeaderWithLocation() {
103 HTMLLayout layout = (HTMLLayout) createLayout();
104 layout.setLocationInfo(true);
105 assertEquals("<!DOCTYPE", layout.getHeader().substring(0, 9));
106 }
107
108 /***
109 * Tests getFooter.
110 */
111 public void testGetFooter() {
112 assertEquals("</table>", createLayout().getFooter().substring(0, 8));
113 }
114
115 /***
116 * Tests getLocationInfo and setLocationInfo.
117 */
118 public void testGetSetLocationInfo() {
119 HTMLLayout layout = new HTMLLayout();
120 assertEquals(false, layout.getLocationInfo());
121 layout.setLocationInfo(true);
122 assertEquals(true, layout.getLocationInfo());
123 layout.setLocationInfo(false);
124 assertEquals(false, layout.getLocationInfo());
125 }
126
127 /***
128 * Tests activateOptions().
129 */
130 public void testActivateOptions() {
131 HTMLLayout layout = new HTMLLayout();
132 layout.activateOptions();
133 }
134
135 /***
136 * Tests getTitle and setTitle.
137 */
138 public void testGetSetTitle() {
139 HTMLLayout layout = new HTMLLayout();
140 assertEquals("Log4J Log Messages", layout.getTitle());
141 layout.setTitle(null);
142 assertNull(layout.getTitle());
143
144 String newTitle = "A treatise on messages of log persuasion";
145 layout.setTitle(newTitle);
146 assertEquals(newTitle, layout.getTitle());
147 }
148
149 /***
150 * Tests buffer downsizing and DEBUG and WARN colorization code paths.
151 */
152 public void testFormatResize() {
153 Logger logger = Logger.getLogger("org.apache.log4j.xml.HTMLLayoutTest");
154 NDC.clear();
155
156 char[] msg = new char[2000];
157
158 for (int i = 0; i < msg.length; i++) {
159 msg[i] = 'A';
160 }
161
162 LoggingEvent event1 =
163 new LoggingEvent(
164 "org.apache.log4j.Logger", logger, Level.DEBUG, new String(msg), null);
165 HTMLLayout layout = (HTMLLayout) createLayout();
166 layout.setLocationInfo(true);
167
168 String result = layout.format(event1);
169 Exception ex = new IllegalArgumentException("'foo' is not a valid value.");
170 LoggingEvent event2 =
171 new LoggingEvent(
172 "org.apache.log4j.Logger", logger, Level.WARN, "Hello, World", ex);
173 result = layout.format(event2);
174 assertEquals(
175 Layout.LINE_SEP + "<tr>",
176 result.substring(0, Layout.LINE_SEP.length() + 4));
177 }
178
179
180 /***
181 * Level with arbitrary toString value.
182 */
183 private static final class ProblemLevel extends Level {
184 /***
185 * Construct new instance.
186 * @param levelName level name, may not be null.
187 */
188 public ProblemLevel(final String levelName) {
189 super(6000, levelName, 6);
190 }
191 }
192
193 /***
194 * Tests problematic characters in multiple fields.
195 * @throws Exception if parser can not be constructed
196 * or source is not a valid XML document.
197 */
198 public void testProblemCharacters() throws Exception {
199 String problemName = "com.example.bar<>&\"'";
200 Logger logger = Logger.getLogger(problemName);
201 Level level = new ProblemLevel(problemName);
202 Exception ex = new IllegalArgumentException(problemName);
203 String threadName = Thread.currentThread().getName();
204 Thread.currentThread().setName(problemName);
205 NDC.push(problemName);
206 Hashtable mdcMap = MDC.getContext();
207 if (mdcMap != null) {
208 mdcMap.clear();
209 }
210 MDC.put(problemName, problemName);
211 LoggingEvent event =
212 new LoggingEvent(
213 problemName, logger, level, problemName, ex);
214 HTMLLayout layout = (HTMLLayout) createLayout();
215 String result = layout.format(event);
216 mdcMap = MDC.getContext();
217 if (mdcMap != null) {
218 mdcMap.clear();
219 }
220
221 Thread.currentThread().setName(threadName);
222
223
224
225
226 StringBuffer buf = new StringBuffer(
227 "<!DOCTYPE table [<!ENTITY nbsp ' '>]><table>");
228 buf.append(result);
229 buf.append("</table>");
230 String doc = buf.toString();
231 for(int i = doc.lastIndexOf("<br>");
232 i != -1;
233 i = doc.lastIndexOf("<br>", i - 1)) {
234 buf.replace(i, i + 4, "<br/>");
235 }
236
237 parse(buf.toString());
238 }
239
240 }