/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

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