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.harmony.logging.tests.java.util.logging; 19 20import java.io.ByteArrayOutputStream; 21import java.io.IOException; 22import java.io.OutputStream; 23import java.io.PrintStream; 24import java.security.Permission; 25import java.util.Properties; 26import java.util.logging.ConsoleHandler; 27import java.util.logging.Filter; 28import java.util.logging.Formatter; 29import java.util.logging.Handler; 30import java.util.logging.Level; 31import java.util.logging.LogManager; 32import java.util.logging.LogRecord; 33import java.util.logging.LoggingPermission; 34import java.util.logging.SimpleFormatter; 35 36import junit.framework.TestCase; 37 38import org.apache.harmony.logging.tests.java.util.logging.util.EnvironmentHelper; 39 40import tests.util.CallVerificationStack; 41 42/** 43 * Test class java.util.logging.ConsoleHandler 44 */ 45public class ConsoleHandlerTest extends TestCase { 46 47 private final static String INVALID_LEVEL = "impossible_level"; 48 49 private final PrintStream err = System.err; 50 51 private OutputStream errSubstituteStream = null; 52 53 private static String className = ConsoleHandlerTest.class.getName(); 54 55 /* 56 * @see TestCase#setUp() 57 */ 58 protected void setUp() throws Exception { 59 super.setUp(); 60 errSubstituteStream = new MockOutputStream(); 61 System.setErr(new PrintStream(errSubstituteStream)); 62 LogManager.getLogManager().reset(); 63 } 64 65 /* 66 * @see TestCase#tearDown() 67 */ 68 protected void tearDown() throws Exception { 69 super.tearDown(); 70 LogManager.getLogManager().reset(); 71 CallVerificationStack.getInstance().clear(); 72 System.setErr(err); 73 } 74 75 /* 76 * Test the constructor with no relevant log manager properties are set. 77 */ 78 public void testConstructor_NoProperties() { 79 assertNull(LogManager.getLogManager().getProperty( 80 "java.util.logging.ConsoleHandler.level")); 81 assertNull(LogManager.getLogManager().getProperty( 82 "java.util.logging.ConsoleHandler.filter")); 83 assertNull(LogManager.getLogManager().getProperty( 84 "java.util.logging.ConsoleHandler.formatter")); 85 assertNull(LogManager.getLogManager().getProperty( 86 "java.util.logging.ConsoleHandler.encoding")); 87 88 ConsoleHandler h = new ConsoleHandler(); 89 assertSame(h.getLevel(), Level.INFO); 90 assertTrue(h.getFormatter() instanceof SimpleFormatter); 91 assertNull(h.getFilter()); 92 assertSame(h.getEncoding(), null); 93 } 94 95 /* 96 * Test the constructor with valid relevant log manager properties are set. 97 */ 98 public void testConstructor_ValidProperties() throws Exception { 99 Properties p = new Properties(); 100 p.put("java.util.logging.ConsoleHandler.level", "FINE"); 101 p.put("java.util.logging.ConsoleHandler.filter", className 102 + "$MockFilter"); 103 p.put("java.util.logging.ConsoleHandler.formatter", className 104 + "$MockFormatter"); 105 p.put("java.util.logging.ConsoleHandler.encoding", "iso-8859-1"); 106 LogManager.getLogManager().readConfiguration( 107 EnvironmentHelper.PropertiesToInputStream(p)); 108 109 assertEquals(LogManager.getLogManager().getProperty( 110 "java.util.logging.ConsoleHandler.level"), "FINE"); 111 assertEquals(LogManager.getLogManager().getProperty( 112 "java.util.logging.ConsoleHandler.encoding"), "iso-8859-1"); 113 ConsoleHandler h = new ConsoleHandler(); 114 assertSame(h.getLevel(), Level.parse("FINE")); 115 assertTrue(h.getFormatter() instanceof MockFormatter); 116 assertTrue(h.getFilter() instanceof MockFilter); 117 assertEquals(h.getEncoding(), "iso-8859-1"); 118 } 119 120 /* 121 * Test the constructor with invalid relevant log manager properties are 122 * set. 123 */ 124 public void testConstructor_InvalidProperties() throws Exception { 125 Properties p = new Properties(); 126 p.put("java.util.logging.ConsoleHandler.level", INVALID_LEVEL); 127 p.put("java.util.logging.ConsoleHandler.filter", className); 128 p.put("java.util.logging.ConsoleHandler.formatter", className); 129 p.put("java.util.logging.ConsoleHandler.encoding", "XXXX"); 130 LogManager.getLogManager().readConfiguration( 131 EnvironmentHelper.PropertiesToInputStream(p)); 132 133 assertEquals(LogManager.getLogManager().getProperty( 134 "java.util.logging.ConsoleHandler.level"), INVALID_LEVEL); 135 assertEquals(LogManager.getLogManager().getProperty( 136 "java.util.logging.ConsoleHandler.encoding"), "XXXX"); 137 ConsoleHandler h = new ConsoleHandler(); 138 assertSame(h.getLevel(), Level.INFO); 139 assertTrue(h.getFormatter() instanceof SimpleFormatter); 140 assertNull(h.getFilter()); 141 assertNull(h.getEncoding()); 142 h.publish(new LogRecord(Level.SEVERE, "test")); 143 assertNull(h.getEncoding()); 144 } 145 146 /* 147 * Test close() when having sufficient privilege, and a record has been 148 * written to the output stream. 149 */ 150 public void testClose_SufficientPrivilege_NormalClose() throws Exception { 151 Properties p = new Properties(); 152 p.put("java.util.logging.ConsoleHandler.formatter", className 153 + "$MockFormatter"); 154 LogManager.getLogManager().readConfiguration( 155 EnvironmentHelper.PropertiesToInputStream(p)); 156 ConsoleHandler h = new ConsoleHandler(); 157 h.publish(new LogRecord(Level.SEVERE, 158 "testClose_SufficientPrivilege_NormalClose msg")); 159 h.close(); 160 assertEquals("flush", CallVerificationStack.getInstance() 161 .getCurrentSourceMethod()); 162 assertNull(CallVerificationStack.getInstance().pop()); 163 h.close(); 164 } 165 166 /* 167 * Test close() when having sufficient privilege, and an output stream that 168 * always throws exceptions. 169 */ 170 public void testClose_SufficientPrivilege_Exception() throws Exception { 171 Properties p = new Properties(); 172 p.put("java.util.logging.ConsoleHandler.formatter", className 173 + "$MockFormatter"); 174 LogManager.getLogManager().readConfiguration( 175 EnvironmentHelper.PropertiesToInputStream(p)); 176 ConsoleHandler h = new ConsoleHandler(); 177 178 h.publish(new LogRecord(Level.SEVERE, 179 "testClose_SufficientPrivilege_Exception msg")); 180 h.flush(); 181 h.close(); 182 } 183 184 /* 185 * Test close() when having sufficient privilege, and no record has been 186 * written to the output stream. 187 */ 188 public void testClose_SufficientPrivilege_DirectClose() throws Exception { 189 Properties p = new Properties(); 190 p.put("java.util.logging.ConsoleHandler.formatter", className 191 + "$MockFormatter"); 192 LogManager.getLogManager().readConfiguration( 193 EnvironmentHelper.PropertiesToInputStream(p)); 194 ConsoleHandler h = new ConsoleHandler(); 195 196 h.close(); 197 assertEquals("flush", CallVerificationStack.getInstance() 198 .getCurrentSourceMethod()); 199 assertNull(CallVerificationStack.getInstance().pop()); 200 assertTrue(CallVerificationStack.getInstance().empty()); 201 } 202 203 /* 204 * Test publish(), use no filter, having output stream, normal log record. 205 */ 206 public void testPublish_NoFilter() throws Exception { 207 Properties p = new Properties(); 208 p.put("java.util.logging.ConsoleHandler.formatter", className 209 + "$MockFormatter"); 210 LogManager.getLogManager().readConfiguration( 211 EnvironmentHelper.PropertiesToInputStream(p)); 212 ConsoleHandler h = new ConsoleHandler(); 213 214 LogRecord r = new LogRecord(Level.INFO, "testPublish_NoFilter"); 215 h.setLevel(Level.INFO); 216 h.publish(r); 217 h.flush(); 218 assertEquals("MockFormatter_Head" + "testPublish_NoFilter", 219 this.errSubstituteStream.toString()); 220 221 h.setLevel(Level.WARNING); 222 h.publish(r); 223 h.flush(); 224 assertEquals("MockFormatter_Head" + "testPublish_NoFilter", 225 this.errSubstituteStream.toString()); 226 227 h.setLevel(Level.CONFIG); 228 h.publish(r); 229 h.flush(); 230 assertEquals("MockFormatter_Head" + "testPublish_NoFilter" 231 + "testPublish_NoFilter", this.errSubstituteStream.toString()); 232 233 r.setLevel(Level.OFF); 234 h.setLevel(Level.OFF); 235 h.publish(r); 236 h.flush(); 237 assertEquals("MockFormatter_Head" + "testPublish_NoFilter" 238 + "testPublish_NoFilter", this.errSubstituteStream.toString()); 239 } 240 241 /* 242 * Test publish(), after system err is reset. 243 */ 244 public void testPublish_AfterResetSystemErr() throws Exception { 245 Properties p = new Properties(); 246 p.put("java.util.logging.ConsoleHandler.formatter", className 247 + "$MockFormatter"); 248 LogManager.getLogManager().readConfiguration( 249 EnvironmentHelper.PropertiesToInputStream(p)); 250 ConsoleHandler h = new ConsoleHandler(); 251 h.setFilter(new MockFilter()); 252 253 System.setErr(new PrintStream(new ByteArrayOutputStream())); 254 255 LogRecord r = new LogRecord(Level.INFO, "testPublish_WithFilter"); 256 h.setLevel(Level.INFO); 257 h.publish(r); 258 assertNull(CallVerificationStack.getInstance().pop()); 259 assertSame(r, CallVerificationStack.getInstance().pop()); 260 assertEquals("", this.errSubstituteStream.toString()); 261 } 262 263 /* 264 * Test publish(), use a filter, having output stream, normal log record. 265 */ 266 public void testPublish_WithFilter() throws Exception { 267 Properties p = new Properties(); 268 p.put("java.util.logging.ConsoleHandler.formatter", className 269 + "$MockFormatter"); 270 LogManager.getLogManager().readConfiguration( 271 EnvironmentHelper.PropertiesToInputStream(p)); 272 ConsoleHandler h = new ConsoleHandler(); 273 h.setFilter(new MockFilter()); 274 275 LogRecord r = new LogRecord(Level.INFO, "testPublish_WithFilter"); 276 h.setLevel(Level.INFO); 277 h.publish(r); 278 assertNull(CallVerificationStack.getInstance().pop()); 279 assertSame(r, CallVerificationStack.getInstance().pop()); 280 assertEquals("", this.errSubstituteStream.toString()); 281 282 h.setLevel(Level.WARNING); 283 h.publish(r); 284 assertNull(CallVerificationStack.getInstance().pop()); 285 assertTrue(CallVerificationStack.getInstance().empty()); 286 assertEquals("", this.errSubstituteStream.toString()); 287 288 h.setLevel(Level.CONFIG); 289 h.publish(r); 290 assertNull(CallVerificationStack.getInstance().pop()); 291 assertSame(r, CallVerificationStack.getInstance().pop()); 292 assertEquals("", this.errSubstituteStream.toString()); 293 294 r.setLevel(Level.OFF); 295 h.setLevel(Level.OFF); 296 h.publish(r); 297 assertNull(CallVerificationStack.getInstance().pop()); 298 assertEquals("", this.errSubstituteStream.toString()); 299 assertTrue(CallVerificationStack.getInstance().empty()); 300 } 301 302 /* 303 * Test publish(), null log record, having output stream, spec said 304 * rather than throw exception, handler should call errormanager to handle 305 * exception case, so NullPointerException shouldn't be thrown. 306 */ 307 public void testPublish_Null() throws Exception { 308 Properties p = new Properties(); 309 p.put("java.util.logging.ConsoleHandler.formatter", className 310 + "$MockFormatter"); 311 LogManager.getLogManager().readConfiguration( 312 EnvironmentHelper.PropertiesToInputStream(p)); 313 ConsoleHandler h = new ConsoleHandler(); 314 h.publish(null); 315 } 316 317 /* 318 * Test publish(), a log record with empty msg, having output stream 319 */ 320 public void testPublish_EmptyMsg() throws Exception { 321 Properties p = new Properties(); 322 p.put("java.util.logging.ConsoleHandler.formatter", className 323 + "$MockFormatter"); 324 LogManager.getLogManager().readConfiguration( 325 EnvironmentHelper.PropertiesToInputStream(p)); 326 ConsoleHandler h = new ConsoleHandler(); 327 LogRecord r = new LogRecord(Level.INFO, ""); 328 h.publish(r); 329 h.flush(); 330 assertEquals("MockFormatter_Head", this.errSubstituteStream.toString()); 331 } 332 333 /* 334 * Test publish(), a log record with null msg, having output stream 335 */ 336 public void testPublish_NullMsg() throws Exception { 337 Properties p = new Properties(); 338 p.put("java.util.logging.ConsoleHandler.formatter", className 339 + "$MockFormatter"); 340 LogManager.getLogManager().readConfiguration( 341 EnvironmentHelper.PropertiesToInputStream(p)); 342 ConsoleHandler h = new ConsoleHandler(); 343 LogRecord r = new LogRecord(Level.INFO, null); 344 h.publish(r); 345 h.flush(); 346 // assertEquals("MockFormatter_Head", 347 // this.errSubstituteStream.toString()); 348 } 349 350 public void testPublish_AfterClose() throws Exception { 351 PrintStream backup = System.err; 352 try { 353 ByteArrayOutputStream bos = new ByteArrayOutputStream(); 354 System.setErr(new PrintStream(bos)); 355 Properties p = new Properties(); 356 p.put("java.util.logging.ConsoleHandler.level", "FINE"); 357 p.put("java.util.logging.ConsoleHandler.formatter", className 358 + "$MockFormatter"); 359 LogManager.getLogManager().readConfiguration( 360 EnvironmentHelper.PropertiesToInputStream(p)); 361 ConsoleHandler h = new ConsoleHandler(); 362 assertSame(h.getLevel(), Level.FINE); 363 LogRecord r1 = new LogRecord(Level.INFO, "testPublish_Record1"); 364 LogRecord r2 = new LogRecord(Level.INFO, "testPublish_Record2"); 365 assertTrue(h.isLoggable(r1)); 366 h.publish(r1); 367 assertTrue(bos.toString().indexOf("testPublish_Record1") >= 0); 368 h.close(); 369 // assertFalse(h.isLoggable(r)); 370 assertTrue(h.isLoggable(r2)); 371 h.publish(r2); 372 assertTrue(bos.toString().indexOf("testPublish_Record2") >= 0); 373 h.flush(); 374 // assertEquals("MockFormatter_Head", 375 // this.errSubstituteStream.toString()); 376 } catch (IOException e) { 377 e.printStackTrace(); 378 } finally { 379 System.setErr(backup); 380 } 381 } 382 383 /* 384 * Test setOutputStream() under normal condition. 385 */ 386 public void testSetOutputStream_Normal() { 387 MockStreamHandler h = new MockStreamHandler(); 388 h.setFormatter(new MockFormatter()); 389 390 LogRecord r = new LogRecord(Level.INFO, "testSetOutputStream_Normal"); 391 h.publish(r); 392 assertNull(CallVerificationStack.getInstance().pop()); 393 assertSame(r, CallVerificationStack.getInstance().pop()); 394 assertTrue(CallVerificationStack.getInstance().empty()); 395 assertEquals("MockFormatter_Head" + "testSetOutputStream_Normal", 396 this.errSubstituteStream.toString()); 397 398 ByteArrayOutputStream aos2 = new ByteArrayOutputStream(); 399 h.setOutputStream(aos2); 400 401 // assertEquals("close", DelegationParameterStack.getInstance() 402 // .getCurrentSourceMethod()); 403 // assertNull(DelegationParameterStack.getInstance().pop()); 404 // assertEquals("flush", DelegationParameterStack.getInstance() 405 // .getCurrentSourceMethod()); 406 // assertNull(DelegationParameterStack.getInstance().pop()); 407 // assertEquals("MockFormatter_Head" + "testSetOutputStream_Normal" 408 // + "MockFormatter_Tail", this.errSubstituteStream.toString()); 409 // r = new LogRecord(Level.INFO, "testSetOutputStream_Normal2"); 410 // h.publish(r); 411 // assertSame(r, DelegationParameterStack.getInstance().pop()); 412 // assertTrue(DelegationParameterStack.getInstance().empty()); 413 // assertEquals("MockFormatter_Head" + "testSetOutputStream_Normal2", 414 // aos2 415 // .toString()); 416 // assertEquals("MockFormatter_Head" + "testSetOutputStream_Normal" 417 // + "MockFormatter_Tail", this.errSubstituteStream.toString()); 418 } 419 420 /* 421 * A mock filter, always return false. 422 */ 423 public static class MockFilter implements Filter { 424 425 public boolean isLoggable(LogRecord record) { 426 CallVerificationStack.getInstance().push(record); 427 // System.out.println("filter called..."); 428 return false; 429 } 430 } 431 432 /* 433 * A mock formatter. 434 */ 435 public static class MockFormatter extends Formatter { 436 public String format(LogRecord r) { 437 // System.out.println("formatter called..."); 438 return super.formatMessage(r); 439 } 440 441 /* 442 * (non-Javadoc) 443 * 444 * @see java.util.logging.Formatter#getHead(java.util.logging.Handler) 445 */ 446 public String getHead(Handler h) { 447 return "MockFormatter_Head"; 448 } 449 450 /* 451 * (non-Javadoc) 452 * 453 * @see java.util.logging.Formatter#getTail(java.util.logging.Handler) 454 */ 455 public String getTail(Handler h) { 456 return "MockFormatter_Tail"; 457 } 458 } 459 460 /* 461 * A mock output stream. 462 */ 463 public static class MockOutputStream extends ByteArrayOutputStream { 464 465 /* 466 * (non-Javadoc) 467 * 468 * @see java.io.OutputStream#close() 469 */ 470 public void close() throws IOException { 471 CallVerificationStack.getInstance().push(null); 472 super.close(); 473 } 474 475 /* 476 * (non-Javadoc) 477 * 478 * @see java.io.OutputStream#flush() 479 */ 480 public void flush() throws IOException { 481 CallVerificationStack.getInstance().push(null); 482 super.flush(); 483 } 484 485 /* 486 * (non-Javadoc) 487 * 488 * @see java.io.OutputStream#write(int) 489 */ 490 public void write(int oneByte) { 491 // TODO Auto-generated method stub 492 super.write(oneByte); 493 } 494 } 495 496 /* 497 * A mock stream handler, expose setOutputStream. 498 */ 499 public static class MockStreamHandler extends ConsoleHandler { 500 public MockStreamHandler() { 501 super(); 502 } 503 504 public void setOutputStream(OutputStream out) { 505 super.setOutputStream(out); 506 } 507 508 public boolean isLoggable(LogRecord r) { 509 CallVerificationStack.getInstance().push(r); 510 return super.isLoggable(r); 511 } 512 } 513 514} 515