/apache-log4j-1.2.17/tests/src/java/org/apache/log4j/net/SyslogAppenderTest.java
Java | 594 lines | 389 code | 63 blank | 142 comment | 15 complexity | 922eb1b4dc5259b4c51207b3d54571b4 MD5 | raw file
Possible License(s): Apache-2.0
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
18package org.apache.log4j.net;
19
20import junit.framework.TestCase;
21
22import org.apache.log4j.AsyncAppender;
23import org.apache.log4j.Layout;
24import org.apache.log4j.Level;
25import org.apache.log4j.LogManager;
26import org.apache.log4j.Logger;
27import org.apache.log4j.PatternLayout;
28import org.apache.log4j.VectorErrorHandler;
29import org.apache.log4j.HTMLLayout;
30
31import java.util.StringTokenizer;
32import java.net.DatagramSocket;
33import java.net.DatagramPacket;
34import java.text.SimpleDateFormat;
35import java.util.Locale;
36import java.util.Date;
37import java.util.Calendar;
38
39
40/**
41 * Tests for SyslogAppender
42 *
43 *
44 * */
45public class SyslogAppenderTest extends TestCase {
46 /**
47 * Create new instance of SyslogAppenderTest.
48 * @param testName test name
49 */
50 public SyslogAppenderTest(final String testName) {
51 super(testName);
52 }
53
54 /**
55 * Resets configuration after every test.
56 */
57 public void tearDown() {
58 LogManager.resetConfiguration();
59 }
60
61 /**
62 * Test default constructor.
63 */
64 public void testDefaultConstructor() {
65 SyslogAppender appender = new SyslogAppender();
66 assertEquals("user", appender.getFacility());
67 assertEquals(false, appender.getFacilityPrinting());
68 assertNull(appender.getLayout());
69 assertNull(appender.getSyslogHost());
70 assertTrue(appender.requiresLayout());
71 }
72
73 /**
74 * Test two parameter constructor.
75 */
76 public void testTwoParamConstructor() {
77 Layout layout = new PatternLayout();
78 SyslogAppender appender = new SyslogAppender(layout, 24);
79 assertEquals("daemon", appender.getFacility());
80 assertEquals(false, appender.getFacilityPrinting());
81 assertEquals(layout, appender.getLayout());
82 assertNull(appender.getSyslogHost());
83 assertTrue(appender.requiresLayout());
84 }
85
86 /**
87 * Test two parameter constructor with unexpected facility.
88 */
89 public void testTwoParamConstructorBadFacility() {
90 Layout layout = new PatternLayout();
91 SyslogAppender appender = new SyslogAppender(layout, 25);
92 assertEquals("user", appender.getFacility());
93 assertEquals(false, appender.getFacilityPrinting());
94 assertEquals(layout, appender.getLayout());
95 assertNull(appender.getSyslogHost());
96 assertTrue(appender.requiresLayout());
97 }
98
99 /**
100 * Test three parameter constructor.
101 */
102 public void testThreeParamConstructor() {
103 Layout layout = new PatternLayout();
104 SyslogAppender appender =
105 new SyslogAppender(layout, "syslog.example.org", 24);
106 assertEquals("daemon", appender.getFacility());
107 assertEquals(false, appender.getFacilityPrinting());
108 assertEquals(layout, appender.getLayout());
109 assertEquals("syslog.example.org", appender.getSyslogHost());
110 assertTrue(appender.requiresLayout());
111 }
112
113 /**
114 * Test getFacilityString for expected facility codes.
115 */
116 public void testGetFacilityString() {
117 String expected =
118 "kern user mail daemon auth syslog lpr news "
119 + "uucp cron authpriv ftp local0 local1 local2 local3 "
120 + "local4 local5 local6 local7 ";
121 StringBuffer actual = new StringBuffer();
122
123 for (int i = 0; i <= 11; i++) {
124 actual.append(SyslogAppender.getFacilityString(i << 3));
125 actual.append(' ');
126 }
127
128 for (int i = 16; i <= 23; i++) {
129 actual.append(SyslogAppender.getFacilityString(i << 3));
130 actual.append(' ');
131 }
132
133 assertEquals(expected, actual.toString());
134 }
135
136 /**
137 * Test getFacilityString for some unexpected facility codes.
138 */
139 public void testGetFacilityStringUnexpected() {
140 assertNull(SyslogAppender.getFacilityString(1));
141 assertNull(SyslogAppender.getFacilityString(12 << 3));
142 }
143
144 /**
145 * Test getFacility with a bogus facility name.
146 */
147 public void testGetFacilityBogus() {
148 assertEquals(-1, SyslogAppender.getFacility("bogus"));
149 }
150
151 /**
152 * Test getFacility with a null facility name.
153 */
154 public void testGetFacilityNull() {
155 assertEquals(-1, SyslogAppender.getFacility(null));
156 }
157
158 /**
159 * Test getFacility for expected system facility names.
160 */
161 public void testGetFacilitySystemNames() {
162 String[] names =
163 new String[] {
164 "kErn", "usEr", "MaIL", "daemOn", "auTh", "syslOg", "lPr", "newS",
165 "Uucp", "croN", "authprIv", "ftP"
166 };
167
168 for (int i = 0; i <= 11; i++) {
169 assertEquals(i << 3, SyslogAppender.getFacility(names[i]));
170 }
171 }
172
173 /**
174 * Test getFacility for expected system facility names.
175 */
176 public void testGetFacilityLocalNames() {
177 String[] names =
178 new String[] {
179 "lOcal0", "LOCAL1", "loCal2", "locAl3", "locaL4", "local5", "LOCal6",
180 "loCAL7"
181 };
182
183 for (int i = 0; i <= 7; i++) {
184 assertEquals((16 + i) << 3, SyslogAppender.getFacility(names[i]));
185 }
186 }
187
188 /**
189 * Test setFacilityPrinting.
190 */
191 public void testSetFacilityPrinting() {
192 SyslogAppender appender = new SyslogAppender();
193 assertFalse(appender.getFacilityPrinting());
194 appender.setFacilityPrinting(true);
195 assertTrue(appender.getFacilityPrinting());
196 appender.setFacilityPrinting(false);
197 assertFalse(appender.getFacilityPrinting());
198 }
199
200 /**
201 * Test of SyslogAppender constants.
202 */
203 public void testConstants() {
204 assertEquals(0 << 3, SyslogAppender.LOG_KERN);
205 assertEquals(1 << 3, SyslogAppender.LOG_USER);
206 assertEquals(2 << 3, SyslogAppender.LOG_MAIL);
207 assertEquals(3 << 3, SyslogAppender.LOG_DAEMON);
208 assertEquals(4 << 3, SyslogAppender.LOG_AUTH);
209 assertEquals(5 << 3, SyslogAppender.LOG_SYSLOG);
210 assertEquals(6 << 3, SyslogAppender.LOG_LPR);
211 assertEquals(7 << 3, SyslogAppender.LOG_NEWS);
212 assertEquals(8 << 3, SyslogAppender.LOG_UUCP);
213 assertEquals(9 << 3, SyslogAppender.LOG_CRON);
214 assertEquals(10 << 3, SyslogAppender.LOG_AUTHPRIV);
215 assertEquals(11 << 3, SyslogAppender.LOG_FTP);
216 assertEquals(16 << 3, SyslogAppender.LOG_LOCAL0);
217 assertEquals(17 << 3, SyslogAppender.LOG_LOCAL1);
218 assertEquals(18 << 3, SyslogAppender.LOG_LOCAL2);
219 assertEquals(19 << 3, SyslogAppender.LOG_LOCAL3);
220 assertEquals(20 << 3, SyslogAppender.LOG_LOCAL4);
221 assertEquals(21 << 3, SyslogAppender.LOG_LOCAL5);
222 assertEquals(22 << 3, SyslogAppender.LOG_LOCAL6);
223 assertEquals(23 << 3, SyslogAppender.LOG_LOCAL7);
224 }
225
226 /**
227 * Test setFacility with null.
228 * Should have no effect.
229 */
230 public void testSetFacilityKern() {
231 SyslogAppender appender = new SyslogAppender();
232 appender.setFacility("kern");
233 appender.setFacility(null);
234 assertEquals("kern", appender.getFacility());
235 }
236
237 /**
238 * Test setFacility with null.
239 * Should have no effect.
240 */
241 public void testSetFacilityNull() {
242 SyslogAppender appender = new SyslogAppender();
243 appender.setFacility("kern");
244 appender.setFacility(null);
245 assertEquals("kern", appender.getFacility());
246 }
247
248 /**
249 * Test setFacility with bogus value.
250 * Should reset to user.
251 */
252 public void testSetFacilityBogus() {
253 SyslogAppender appender = new SyslogAppender();
254 appender.setFacility("kern");
255 appender.setFacility("bogus");
256 assertEquals("user", appender.getFacility());
257 }
258
259 /**
260 * Tests calling setFacility after appender has been activated.
261 */
262 public void testSetFacilityAfterActivation() {
263 SyslogAppender appender = new SyslogAppender();
264 appender.setName("foo");
265 appender.setThreshold(Level.INFO);
266 appender.setSyslogHost("localhost");
267 appender.setFacility("user");
268 appender.setLayout(new PatternLayout("%m%n"));
269
270 VectorErrorHandler errorHandler = new VectorErrorHandler();
271 appender.setErrorHandler(errorHandler);
272 appender.activateOptions();
273 appender.setFacility("kern");
274 assertEquals("kern", appender.getFacility());
275 }
276
277 /**
278 * Tests that append method drops messages below threshold.
279 * Can't reach isSevereAsThreshold call in SyslogAppender.append
280 * since it is checked in AppenderSkeleton.doAppend.
281 */
282 public void testAppendBelowThreshold() {
283 SyslogAppender appender = new SyslogAppender();
284 appender.setThreshold(Level.ERROR);
285 appender.activateOptions();
286
287 Logger logger = Logger.getRootLogger();
288 logger.addAppender(appender);
289 logger.info(
290 "Should not be logged by SyslogAppenderTest.testAppendBelowThreshold.");
291 }
292
293 /**
294 * Tests that append method drops messages below threshold.
295 */
296 public void testAppendNoHost() {
297 SyslogAppender appender = new SyslogAppender();
298 appender.setName("foo");
299 appender.setThreshold(Level.INFO);
300
301 VectorErrorHandler errorHandler = new VectorErrorHandler();
302 appender.setErrorHandler(errorHandler);
303 appender.setLayout(new PatternLayout("%m%n"));
304 appender.activateOptions();
305
306 Logger logger = Logger.getRootLogger();
307 logger.addAppender(appender);
308 logger.info(
309 "Should not be logged by SyslogAppenderTest.testAppendNoHost.");
310 assertEquals(1, errorHandler.size());
311
312 //
313 // Appender is misspelled in implementation
314 //
315 assertEquals(
316 "No syslog host is set for SyslogAppedender named \"foo\".",
317 errorHandler.getMessage(0));
318 }
319
320 /**
321 * Tests append method under normal conditions.
322 */
323 public void testAppend() {
324 SyslogAppender appender = new SyslogAppender();
325 appender.setName("foo");
326 appender.setThreshold(Level.INFO);
327 appender.setSyslogHost("localhost");
328 appender.setFacility("user");
329 appender.setLayout(new PatternLayout("%m%n"));
330
331 VectorErrorHandler errorHandler = new VectorErrorHandler();
332 appender.setErrorHandler(errorHandler);
333 appender.activateOptions();
334
335 //
336 // wrap SyslogAppender with an Async since appender may
337 // hang if syslogd is not accepting network messages
338 //
339 AsyncAppender asyncAppender = new AsyncAppender();
340 asyncAppender.addAppender(appender);
341 asyncAppender.activateOptions();
342
343 Logger logger = Logger.getRootLogger();
344 logger.addAppender(asyncAppender);
345
346 Exception e =
347 new Exception("Expected exception from SyslogAppenderTest.testAppend");
348 logger.info(
349 "Expected message from log4j unit test SyslogAppenderTest.testAppend.", e);
350 assertEquals(0, errorHandler.size());
351 }
352
353 /**
354 * Tests SyslogAppender with IPv6 address.
355 */
356 public void testIPv6() {
357 SyslogAppender appender = new SyslogAppender();
358 appender.setSyslogHost("::1");
359 }
360
361 /**
362 * Tests SyslogAppender with IPv6 address enclosed in square brackets.
363 */
364 public void testIPv6InBrackets() {
365 SyslogAppender appender = new SyslogAppender();
366 appender.setSyslogHost("[::1]");
367 }
368
369 /**
370 * Tests SyslogAppender with IPv6 address enclosed in square brackets
371 * followed by port specification.
372 */
373 public void testIPv6AndPort() {
374 SyslogAppender appender = new SyslogAppender();
375 appender.setSyslogHost("[::1]:1514");
376 }
377
378 /**
379 * Tests SyslogAppender with host name enclosed in square brackets
380 * followed by port specification.
381 */
382 public void testHostNameAndPort() {
383 SyslogAppender appender = new SyslogAppender();
384 appender.setSyslogHost("localhost:1514");
385 }
386
387
388 /**
389 * Tests SyslogAppender with IPv4 address followed by port specification.
390 */
391 public void testIPv4AndPort() {
392 SyslogAppender appender = new SyslogAppender();
393 appender.setSyslogHost("127.0.0.1:1514");
394 }
395
396 private static String[] log(final boolean header,
397 final String msg,
398 final Exception ex,
399 final int packets) throws Exception {
400 DatagramSocket ds = new DatagramSocket();
401 ds.setSoTimeout(2000);
402
403 SyslogAppender appender = new SyslogAppender();
404 appender.setSyslogHost("localhost:" + ds.getLocalPort());
405 appender.setName("name");
406 appender.setHeader(header);
407 PatternLayout pl = new PatternLayout("%m");
408 appender.setLayout(pl);
409 appender.activateOptions();
410
411 Logger l = Logger.getRootLogger();
412 l.addAppender(appender);
413 if (ex == null) {
414 l.info(msg);
415 } else {
416 l.error(msg, ex);
417 }
418 appender.close();
419 String[] retval = new String[packets];
420 byte[] buf = new byte[1000];
421 for(int i = 0; i < packets; i++) {
422 DatagramPacket p = new DatagramPacket(buf, 0, buf.length);
423 ds.receive(p);
424 retval[i] = new String(p.getData(), 0, p.getLength());
425 }
426 ds.close();
427 return retval;
428 }
429
430 public void testActualLogging() throws Exception {
431 String s = log(false, "greetings", null, 1)[0];
432 StringTokenizer st = new StringTokenizer(s, "<>() ");
433 assertEquals("14", st.nextToken());
434 assertEquals("greetings", st.nextToken());
435 }
436
437 /**
438 * Exception with printStackTrace that breaks earlier SyslogAppender.
439 */
440 private static class MishandledException extends Exception {
441 private static final long serialVersionUID = 1L;
442 /*
443 * Create new instance.
444 */
445 public MishandledException() {
446 }
447
448 /**
449 * Print stack trace.
450 * @param w print writer, may not be null.
451 */
452 public void printStackTrace(final java.io.PrintWriter w) {
453 w.println("Mishandled stack trace follows:");
454 w.println("");
455 w.println("No tab here");
456 w.println("\ttab here");
457 w.println("\t");
458 }
459 }
460
461 /**
462 * Tests fix for bug 40502.
463 * @throws Exception on IOException.
464 */
465 public void testBadTabbing() throws Exception {
466 String[] s = log(false, "greetings", new MishandledException(), 6);
467 StringTokenizer st = new StringTokenizer(s[0], "<>() ");
468 assertEquals("11", st.nextToken());
469 assertEquals("greetings", st.nextToken());
470 assertEquals("<11>Mishandled stack trace follows:", s[1]);
471 assertEquals("<11>", s[2]);
472 assertEquals("<11>No tab here", s[3]);
473 assertEquals("<11>" + SyslogAppender.TAB + "tab here", s[4]);
474 assertEquals("<11>" + SyslogAppender.TAB, s[5]);
475 }
476
477 /**
478 * Tests presence of timestamp if header = true.
479 *
480 * @throws Exception if IOException.
481 */
482 public void testHeaderLogging() throws Exception {
483 Date preDate = new Date();
484 String s = log(true, "greetings", null, 1)[0];
485 Date postDate = new Date();
486 assertEquals("<14>", s.substring(0, 4));
487
488 String syslogDateStr = s.substring(4, 20);
489 SimpleDateFormat fmt = new SimpleDateFormat("MMM dd HH:mm:ss ", Locale.ENGLISH);
490 Date syslogDate = fmt.parse(syslogDateStr);
491 Calendar cal = Calendar.getInstance(Locale.ENGLISH);
492 cal.setTime(syslogDate);
493 int syslogMonth = cal.get(Calendar.MONTH);
494 int syslogDay = cal.get(Calendar.DATE);
495 if (syslogDay < 10) {
496 assertEquals(' ', syslogDateStr.charAt(4));
497 }
498 cal.setTime(preDate);
499 int preMonth = cal.get(Calendar.MONTH);
500 cal.set(Calendar.MILLISECOND, 0);
501 preDate = cal.getTime();
502 int syslogYear;
503 if (preMonth == syslogMonth) {
504 syslogYear = cal.get(Calendar.YEAR);
505 } else {
506 cal.setTime(postDate);
507 syslogYear = cal.get(Calendar.YEAR);
508 }
509 cal.setTime(syslogDate);
510 cal.set(Calendar.YEAR, syslogYear);
511 syslogDate = cal.getTime();
512 assertTrue(syslogDate.compareTo(preDate) >= 0);
513 assertTrue(syslogDate.compareTo(postDate) <= 0);
514 }
515
516
517 /**
518 * Tests that any header or footer in layout is sent.
519 * @throws Exception if exception during test.
520 */
521 public void testLayoutHeader() throws Exception {
522 DatagramSocket ds = new DatagramSocket();
523 ds.setSoTimeout(2000);
524
525 SyslogAppender appender = new SyslogAppender();
526 appender.setSyslogHost("localhost:" + ds.getLocalPort());
527 appender.setName("name");
528 appender.setHeader(false);
529 HTMLLayout pl = new HTMLLayout();
530 appender.setLayout(pl);
531 appender.activateOptions();
532
533 Logger l = Logger.getRootLogger();
534 l.addAppender(appender);
535 l.info("Hello, World");
536 appender.close();
537 String[] s = new String[3];
538 byte[] buf = new byte[1000];
539 for(int i = 0; i < 3; i++) {
540 DatagramPacket p = new DatagramPacket(buf, 0, buf.length);
541 ds.receive(p);
542 s[i] = new String(p.getData(), 0, p.getLength());
543 }
544 ds.close();
545 assertEquals("<14><!DOCTYPE", s[0].substring(0,13));
546 assertEquals("<14></table>", s[2].substring(0,12));
547 }
548
549 /**
550 * Tests that syslog packets do not exceed 1024 bytes.
551 * See bug 42087.
552 * @throws Exception if exception during test.
553 */
554 public void testBigPackets() throws Exception {
555 DatagramSocket ds = new DatagramSocket();
556 ds.setSoTimeout(2000);
557
558 SyslogAppender appender = new SyslogAppender();
559 appender.setSyslogHost("localhost:" + ds.getLocalPort());
560 appender.setName("name");
561 appender.setHeader(false);
562 PatternLayout pl = new PatternLayout("%m");
563 appender.setLayout(pl);
564 appender.activateOptions();
565
566 Logger l = Logger.getRootLogger();
567 l.addAppender(appender);
568 StringBuffer msgbuf = new StringBuffer();
569 while(msgbuf.length() < 8000) {
570 msgbuf.append("0123456789");
571 }
572 String msg = msgbuf.toString();
573 l.info(msg);
574 appender.close();
575 String[] s = new String[8];
576 byte[] buf = new byte[1200];
577 for(int i = 0; i < 8; i++) {
578 DatagramPacket p = new DatagramPacket(buf, 0, buf.length);
579 ds.receive(p);
580 assertTrue(p.getLength() <= 1024);
581 s[i] = new String(p.getData(), 0, p.getLength());
582 }
583 ds.close();
584 StringBuffer rcvbuf = new StringBuffer(s[0]);
585 rcvbuf.delete(0, 4);
586 for(int i = 1; i < 8; i++) {
587 rcvbuf.setLength(rcvbuf.length() - 3);
588 rcvbuf.append(s[i].substring(s[i].indexOf("...") + 3));
589 }
590 assertEquals(msg.length(), rcvbuf.length());
591 assertEquals(msg, rcvbuf.toString());
592 }
593
594}