1 package ch.qos.logback.classic.html;
2
3 import static org.junit.Assert.assertEquals;
4 import static org.junit.Assert.assertFalse;
5 import static org.junit.Assert.assertNotNull;
6 import static org.junit.Assert.assertTrue;
7
8 import java.io.ByteArrayInputStream;
9 import java.util.List;
10
11 import org.dom4j.Document;
12 import org.dom4j.Element;
13 import org.dom4j.io.SAXReader;
14 import org.junit.After;
15 import org.junit.Before;
16 import org.junit.Ignore;
17 import org.junit.Test;
18 import org.xml.sax.EntityResolver;
19
20 import ch.qos.logback.classic.Level;
21 import ch.qos.logback.classic.Logger;
22 import ch.qos.logback.classic.LoggerContext;
23 import ch.qos.logback.classic.TestConstants;
24 import ch.qos.logback.classic.joran.JoranConfigurator;
25 import ch.qos.logback.classic.spi.LoggingEvent;
26 import ch.qos.logback.classic.spi.ThrowableDataPoint;
27 import ch.qos.logback.classic.spi.ThrowableProxy;
28 import ch.qos.logback.classic.util.TeztConstants;
29 import ch.qos.logback.core.CoreConstants;
30 import ch.qos.logback.core.joran.spi.JoranException;
31 import ch.qos.logback.core.read.ListAppender;
32 import ch.qos.logback.core.testUtil.StringListAppender;
33 import ch.qos.logback.core.util.StatusPrinter;
34
35 public class HTMLLayoutTest {
36
37 LoggerContext lc;
38 Logger root;
39 HTMLLayout layout;
40
41 @Before
42 public void setUp() throws Exception {
43 lc = new LoggerContext();
44 lc.setName("default");
45
46 ListAppender<LoggingEvent> appender = new ListAppender<LoggingEvent>();
47 appender.setContext(lc);
48 layout = new HTMLLayout();
49 layout.setThrowableRenderer(new DefaultThrowableRenderer());
50 layout.setContext(lc);
51 layout.setPattern("%level%thread%msg");
52 layout.start();
53 appender.setLayout(layout);
54 root = lc.getLogger(LoggerContext.ROOT_NAME);
55 root.addAppender(appender);
56 appender.start();
57 }
58
59 @After
60 public void tearDown() throws Exception {
61 lc = null;
62 layout = null;
63 }
64
65 @SuppressWarnings("unchecked")
66 @Test
67 public void testHeader() throws Exception {
68 String header = layout.getFileHeader();
69
70
71 Document doc = parseOutput(header + "</body></html>");
72 Element rootElement = doc.getRootElement();
73 assertNotNull(rootElement.element("body"));
74 }
75
76 @SuppressWarnings("unchecked")
77 @Test
78 public void testPresentationHeader() throws Exception {
79 String header = layout.getFileHeader();
80 String presentationHeader = layout.getPresentationHeader();
81 header = header + presentationHeader;
82
83
84 Document doc = parseOutput(header + "</table></body></html>");
85 Element rootElement = doc.getRootElement();
86 Element bodyElement = rootElement.element("body");
87 Element tableElement = bodyElement.element("table");
88 Element trElement = tableElement.element("tr");
89 List<Element> elementList = trElement.elements();
90 assertEquals("Level", elementList.get(0).getText());
91 assertEquals("Thread", elementList.get(1).getText());
92 assertEquals("Message", elementList.get(2).getText());
93 }
94
95 @Test
96 public void testAppendThrowable() throws Exception {
97 StringBuilder buf = new StringBuilder();
98 ThrowableDataPoint[] strArray = { new ThrowableDataPoint("test1"),
99 new ThrowableDataPoint("test2") };
100 DefaultThrowableRenderer renderer = (DefaultThrowableRenderer) layout
101 .getThrowableRenderer();
102 renderer.render(buf, strArray);
103
104 String[] result = buf.toString().split(CoreConstants.LINE_SEPARATOR);
105 assertEquals("<tr><td class=\"Exception\" colspan=\"6\">test1", result[0]);
106 assertEquals(DefaultThrowableRenderer.TRACE_PREFIX + "test2", result[1]);
107 }
108
109 @Test
110 public void testDoLayout() throws Exception {
111 LoggingEvent le = createLoggingEvent();
112
113 String result = layout.getFileHeader();
114 result += layout.getPresentationHeader();
115 result += layout.doLayout(le);
116 result += layout.getPresentationFooter();
117 result += layout.getFileFooter();
118
119 Document doc = parseOutput(result);
120 Element rootElement = doc.getRootElement();
121 rootElement.toString();
122
123
124
125
126
127
128
129
130 assertEquals(2, rootElement.elements().size());
131 Element bodyElement = (Element) rootElement.elements().get(1);
132 Element tableElement = (Element) bodyElement.elements().get(3);
133 assertEquals("table", tableElement.getName());
134 Element trElement = (Element) tableElement.elements().get(1);
135 {
136 Element tdElement = (Element) trElement.elements().get(0);
137 assertEquals("DEBUG", tdElement.getText());
138 }
139 {
140 Element tdElement = (Element) trElement.elements().get(1);
141 String regex = TestConstants.NAKED_MAIN_REGEX;
142 assertTrue(tdElement.getText().toString().matches(regex));
143 }
144 {
145 Element tdElement = (Element) trElement.elements().get(2);
146 assertEquals("test message", tdElement.getText());
147 }
148 }
149
150 @SuppressWarnings("unchecked")
151 @Test
152 public void layoutWithException() throws Exception {
153 layout.setPattern("%level %thread %msg %ex");
154 LoggingEvent le = createLoggingEvent();
155 le.setThrowableProxy(new ThrowableProxy(new Exception("test Exception")));
156 String result = layout.doLayout(le);
157
158 String stringToParse = layout.getFileHeader();
159 stringToParse = stringToParse + layout.getPresentationHeader();
160 stringToParse += result;
161 stringToParse += "</table></body></html>";
162
163
164
165 Document doc = parseOutput(stringToParse);
166 Element rootElement = doc.getRootElement();
167 Element bodyElement = rootElement.element("body");
168 Element tableElement = bodyElement.element("table");
169 List<Element> trElementList = tableElement.elements();
170 Element exceptionRowElement = trElementList.get(2);
171 Element exceptionElement = exceptionRowElement.element("td");
172
173 assertEquals(3, tableElement.elements().size());
174 assertTrue(exceptionElement.getText().contains(
175 "java.lang.Exception: test Exception"));
176 }
177
178 @Test
179 @Ignore
180 public void rawLimit() throws Exception {
181 StringBuilder sb = new StringBuilder();
182 String header = layout.getFileHeader();
183 assertTrue(header
184 .startsWith("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">"));
185 sb.append(header);
186 sb.append(layout.getPresentationHeader());
187 for (int i = 0; i < CoreConstants.TABLE_ROW_LIMIT * 3; i++) {
188 sb.append(layout.doLayout(new LoggingEvent(this.getClass().getName(),
189 root, Level.DEBUG, "test message" + i, null, null)));
190 }
191 sb.append(layout.getPresentationFooter());
192 sb.append(layout.getFileFooter());
193
194 parseOutput(sb.toString());
195 }
196
197 private LoggingEvent createLoggingEvent() {
198 LoggingEvent le = new LoggingEvent(this.getClass().getName(), root,
199 Level.DEBUG, "test message", null, null);
200 return le;
201 }
202
203 Document parseOutput(String output) throws Exception {
204 EntityResolver resolver = new XHTMLEntityResolver();
205 SAXReader reader = new SAXReader();
206 reader.setValidation(true);
207 reader.setEntityResolver(resolver);
208 return reader.read(new ByteArrayInputStream(output.getBytes()));
209 }
210
211 void configure(String file) throws JoranException {
212 JoranConfigurator jc = new JoranConfigurator();
213 jc.setContext(lc);
214 jc.doConfigure(file);
215 }
216
217 @Test
218 public void testConversionRuleSupportInHtmlLayout() throws JoranException {
219 configure(TeztConstants.TEST_DIR_PREFIX
220 + "input/joran/conversionRule/htmlLayout0.xml");
221
222 root.getAppender("LIST");
223 String msg = "Simon says";
224 root.debug(msg);
225 StringListAppender<LoggingEvent> sla = (StringListAppender<LoggingEvent>) root
226 .getAppender("LIST");
227 assertNotNull(sla);
228 StatusPrinter.print(lc);
229 assertEquals(1, sla.strList.size());
230 assertFalse(sla.strList.get(0).contains("PARSER_ERROR"));
231 }
232 }