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 18 package org.apache.harmony.logging.tests.java.util.logging; 19 20 import java.io.Serializable; 21 import java.util.Locale; 22 import java.util.ResourceBundle; 23 import java.util.logging.Handler; 24 import java.util.logging.Level; 25 import java.util.logging.LogRecord; 26 import java.util.logging.Logger; 27 28 import junit.framework.TestCase; 29 30 import org.apache.harmony.testframework.serialization.SerializationTest; 31 import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert; 32 33 public class LogRecordTest extends TestCase { 34 35 static final String MSG = "test msg, pls. ignore itb"; 36 37 private LogRecord lr; 38 39 private static String className = LogRecordTest.class.getName(); 40 setUp()41 protected void setUp() throws Exception { 42 super.setUp(); 43 lr = new LogRecord(Level.CONFIG, MSG); 44 45 } 46 testLogRecordWithNullPointers()47 public void testLogRecordWithNullPointers() { 48 try { 49 new LogRecord(null, null); 50 fail("should throw NullPointerException"); 51 } catch (NullPointerException e) { 52 } 53 try { 54 new LogRecord(null, MSG); 55 fail("should throw NullPointerException"); 56 } catch (NullPointerException e) { 57 } 58 LogRecord r = new LogRecord(Level.WARNING, null); 59 assertSame(r.getLevel(), Level.WARNING); 60 assertNull(r.getMessage()); 61 } 62 testGetSetLoggerName()63 public void testGetSetLoggerName() { 64 assertNull(lr.getLoggerName()); 65 lr.setLoggerName(null); 66 assertNull(lr.getLoggerName()); 67 lr.setLoggerName("test logger name"); 68 assertEquals("test logger name", lr.getLoggerName()); 69 } 70 testGetSetResourceBundle()71 public void testGetSetResourceBundle() { 72 assertNull(lr.getResourceBundleName()); 73 assertNull(lr.getResourceBundle()); 74 75 lr.setResourceBundle(null); 76 assertNull(lr.getResourceBundle()); 77 78 lr.setResourceBundleName("bundles/com/android/java/util/logging/res"); 79 assertNull(lr.getResourceBundle()); 80 81 lr.setResourceBundleName(null); 82 ResourceBundle rb = ResourceBundle 83 .getBundle("bundles/com/android/java/util/logging/res"); 84 lr.setResourceBundle(rb); 85 assertEquals(rb, lr.getResourceBundle()); 86 assertNull(lr.getResourceBundleName()); 87 } 88 testGetSetResourceBundleName()89 public void testGetSetResourceBundleName() { 90 assertNull(lr.getResourceBundleName()); 91 lr.setResourceBundleName(null); 92 assertNull(lr.getResourceBundleName()); 93 lr.setResourceBundleName("test"); 94 assertEquals("test", lr.getResourceBundleName()); 95 } 96 testGetSetLevel()97 public void testGetSetLevel() { 98 try { 99 lr.setLevel(null); 100 fail("should throw NullPointerException"); 101 } catch (NullPointerException e) { 102 } 103 assertSame(lr.getLevel(), Level.CONFIG); 104 } 105 testGetSetSequenceNumber()106 public void testGetSetSequenceNumber() { 107 long l = lr.getSequenceNumber(); 108 lr.setSequenceNumber(-111); 109 assertEquals(lr.getSequenceNumber(), -111L); 110 lr.setSequenceNumber(0); 111 assertEquals(lr.getSequenceNumber(), 0L); 112 lr = new LogRecord(Level.ALL, null); 113 assertEquals(lr.getSequenceNumber(), l + 1); 114 } 115 testGetSetSourceClassName()116 public void testGetSetSourceClassName() { 117 lr.setSourceClassName(null); 118 assertNull(lr.getSourceClassName()); 119 lr.setSourceClassName("bad class name"); 120 assertEquals("bad class name", lr.getSourceClassName()); 121 lr.setSourceClassName(this.getClass().getName()); 122 assertEquals(this.getClass().getName(), lr.getSourceClassName()); 123 } 124 testGetSetSourceMethodName()125 public void testGetSetSourceMethodName() { 126 lr.setSourceMethodName(null); 127 assertNull(lr.getSourceMethodName()); 128 lr.setSourceMethodName("bad class name"); 129 assertEquals("bad class name", lr.getSourceMethodName()); 130 lr.setSourceMethodName(this.getClass().getName()); 131 assertEquals(this.getClass().getName(), lr.getSourceMethodName()); 132 } 133 testGetSourceDefaultValue()134 public void testGetSourceDefaultValue() { 135 assertNull(lr.getSourceMethodName()); 136 assertNull(lr.getSourceClassName()); 137 138 // find class and method who called logger 139 Logger logger = Logger.global; 140 MockHandler handler = new MockHandler(); 141 logger.addHandler(handler); 142 logger.log(Level.SEVERE, MSG); 143 assertEquals(this.getClass().getName(), handler.getSourceClassName()); 144 assertEquals("testGetSourceDefaultValue", handler.getSourceMethodName()); 145 146 // only set source method to null 147 lr = new LogRecord(Level.SEVERE, MSG); 148 lr.setSourceMethodName(null); 149 logger.log(lr); 150 assertNull(handler.getSourceClassName()); 151 assertNull(handler.getSourceMethodName()); 152 153 // only set source class to null 154 lr = new LogRecord(Level.SEVERE, MSG); 155 lr.setSourceClassName(null); 156 logger.log(lr); 157 assertNull(handler.getSourceClassName()); 158 assertNull(handler.getSourceMethodName()); 159 160 // set both 161 lr = new LogRecord(Level.SEVERE, MSG); 162 lr.setSourceClassName("className"); 163 lr.setSourceMethodName(null); 164 logger.log(lr); 165 assertEquals("className", handler.getSourceClassName()); 166 assertNull(handler.getSourceMethodName()); 167 168 // test if LogRecord is constructed in another class, and is published 169 // by Logger 170 logger.log(RecordFactory.getDefaultRecord()); 171 assertEquals(this.getClass().getName(), handler.getSourceClassName()); 172 assertEquals("testGetSourceDefaultValue", handler.getSourceMethodName()); 173 174 lr = RecordFactory.getDefaultRecord(); 175 // assertNull(lr.getSourceClassName()); 176 // assertNull(lr.getSourceMethodName()); 177 RecordFactory.log(logger, lr); 178 assertEquals(RecordFactory.class.getName(), handler 179 .getSourceClassName()); 180 assertEquals("log", handler.getSourceMethodName()); 181 182 // only try once to get the default value 183 lr = RecordFactory.getDefaultRecord(); 184 assertNull(lr.getSourceClassName()); 185 assertNull(lr.getSourceMethodName()); 186 RecordFactory.log(logger, lr); 187 assertNull(handler.getSourceClassName()); 188 assertNull(handler.getSourceMethodName()); 189 190 // it cannot find correct default value when logger is subclass 191 MockLogger ml = new MockLogger("foo", null); 192 ml.addHandler(handler); 193 ml.info(MSG); 194 assertEquals(className + "$MockLogger", handler.getSourceClassName()); 195 assertEquals("info", handler.getSourceMethodName()); 196 197 // it can find nothing when only call Subclass 198 ml = new MockLogger("foo", null); 199 ml.addHandler(handler); 200 ml.log(Level.SEVERE, MSG); 201 assertNull(handler.getSourceClassName()); 202 assertNull(handler.getSourceMethodName()); 203 204 // test if don't call logger, what is the default value 205 lr = new LogRecord(Level.SEVERE, MSG); 206 handler.publish(lr); 207 assertNull(handler.getSourceClassName()); 208 assertNull(handler.getSourceMethodName()); 209 logger.removeHandler(handler); 210 } 211 testGetSetMessage()212 public void testGetSetMessage() { 213 assertEquals(MSG, lr.getMessage()); 214 lr.setMessage(null); 215 assertNull(lr.getMessage()); 216 lr.setMessage(""); 217 assertEquals("", lr.getMessage()); 218 } 219 testGetSetParameters()220 public void testGetSetParameters() { 221 assertNull(lr.getParameters()); 222 lr.setParameters(null); 223 assertNull(lr.getParameters()); 224 Object[] oa = new Object[0]; 225 lr.setParameters(oa); 226 assertEquals(oa, lr.getParameters()); 227 oa = new Object[] { new Object(), new Object() }; 228 lr.setParameters(oa); 229 assertSame(oa, lr.getParameters()); 230 } 231 testGetSetMillis()232 public void testGetSetMillis() { 233 long milli = lr.getMillis(); 234 assertTrue(milli > 0); 235 lr.setMillis(-1); 236 assertEquals(-1, lr.getMillis()); 237 lr.setMillis(0); 238 assertEquals(0, lr.getMillis()); 239 } 240 testGetSetThreadID()241 public void testGetSetThreadID() { 242 // TODO how to test the different thread 243 int id = lr.getThreadID(); 244 lr = new LogRecord(Level.ALL, "a1"); 245 assertEquals(id, lr.getThreadID()); 246 lr.setThreadID(id + 10); 247 assertEquals(id + 10, lr.getThreadID()); 248 lr = new LogRecord(Level.ALL, "a1"); 249 assertEquals(id, lr.getThreadID()); 250 } 251 testGetSetThrown()252 public void testGetSetThrown() { 253 assertNull(lr.getThrown()); 254 lr.setThrown(null); 255 assertNull(lr.getThrown()); 256 Throwable e = new Exception(); 257 lr.setThrown(e); 258 assertEquals(e, lr.getThrown()); 259 } 260 261 // comparator for LogRecord objects 262 private static final SerializableAssert LOGRECORD_COMPARATOR = new SerializableAssert() { 263 public void assertDeserialized(Serializable initial, 264 Serializable deserialized) { 265 266 LogRecord init = (LogRecord) initial; 267 LogRecord dser = (LogRecord) deserialized; 268 269 assertEquals("Class", init.getClass(), dser.getClass()); 270 assertEquals("Level", init.getLevel(), dser.getLevel()); 271 assertEquals("LoggerName", init.getLoggerName(), dser 272 .getLoggerName()); 273 assertEquals("Message", init.getMessage(), dser.getMessage()); 274 assertEquals("Millis", init.getMillis(), dser.getMillis()); 275 276 // compare parameters 277 Object[] paramInit = init.getParameters(); 278 Object[] paramDser = dser.getParameters(); 279 assertEquals("Parameters length", paramInit.length, 280 paramDser.length); 281 for (int i = 0; i < paramInit.length; i++) { 282 assertEquals("Param: " + i, paramInit[i].toString(), 283 paramDser[i]); 284 } 285 286 // don't check ResourceBundle object 287 // verify only bundle's name 288 assertEquals("ResourceBundleName", init.getResourceBundleName(), 289 dser.getResourceBundleName()); 290 assertEquals("SequenceNumber", init.getSequenceNumber(), dser 291 .getSequenceNumber()); 292 assertEquals("SourceClassName", init.getSourceClassName(), dser 293 .getSourceClassName()); 294 assertEquals("SourceMethodName", init.getSourceMethodName(), dser 295 .getSourceMethodName()); 296 assertEquals("ThreadID", init.getThreadID(), dser.getThreadID()); 297 298 SerializationTest.THROWABLE_COMPARATOR.assertDeserialized(init 299 .getThrown(), dser.getThrown()); 300 } 301 }; 302 303 /** 304 * @tests serialization/deserialization compatibility. 305 */ testSerializationSelf()306 public void testSerializationSelf() throws Exception { 307 LogRecord r = new LogRecord(Level.ALL, "msg"); 308 r.setLoggerName("LoggerName"); 309 r.setMillis(123456789); 310 r.setResourceBundleName("ResourceBundleName"); 311 r.setSequenceNumber(987654321); 312 r.setSourceClassName("SourceClassName"); 313 r.setSourceMethodName("SourceMethodName"); 314 r 315 .setParameters(new Object[] { "test string", 316 new Exception("ex-msg") }); 317 r.setThreadID(3232); 318 r.setThrown(new Exception("ExceptionMessage")); 319 320 SerializationTest.verifySelf(r, LOGRECORD_COMPARATOR); 321 } 322 323 /** 324 * @tests resolution of resource bundle for serialization/deserialization. 325 */ testSerializationResourceBundle()326 public void testSerializationResourceBundle() throws Exception { 327 328 // test case: valid resource bundle name 329 lr.setResourceBundleName("bundles/com/android/java/util/logging/res2"); 330 lr.setResourceBundle(ResourceBundle.getBundle( 331 "bundles/com/android/java/util/logging/res", Locale.US)); 332 333 LogRecord result = (LogRecord) SerializationTest.copySerializable(lr); 334 assertNotNull(result.getResourceBundle()); 335 336 // test case: invalid resource bundle name, it is not resolved during 337 // deserialization LogRecord object so check for returned null value 338 lr.setResourceBundleName("bad bundle name"); 339 lr.setResourceBundle(ResourceBundle.getBundle( 340 "bundles/com/android/java/util/logging/res", Locale.US)); 341 342 result = (LogRecord) SerializationTest.copySerializable(lr); 343 assertNull(result.getResourceBundle()); 344 } 345 346 /** 347 * @tests serialization/deserialization compatibility with RI. 348 */ testSerializationCompatibility()349 public void testSerializationCompatibility() throws Exception { 350 LogRecord r = new LogRecord(Level.ALL, "msg"); 351 r.setLoggerName("LoggerName"); 352 r.setMillis(123456789); 353 r.setResourceBundleName("ResourceBundleName"); 354 r.setSequenceNumber(987654321); 355 r.setSourceClassName("SourceClassName"); 356 r.setSourceMethodName("SourceMethodName"); 357 r 358 .setParameters(new Object[] { "test string", 359 new Exception("ex-msg") }); 360 r.setThreadID(3232); 361 r.setThrown(new Exception("ExceptionMessage")); 362 363 SerializationTest.verifyGolden(this, r, LOGRECORD_COMPARATOR); 364 } 365 366 public static class MockHandler extends Handler { 367 private String className; 368 369 private String methodName; 370 close()371 public void close() { 372 } 373 flush()374 public void flush() { 375 } 376 publish(LogRecord record)377 public void publish(LogRecord record) { 378 className = record.getSourceClassName(); 379 methodName = record.getSourceMethodName(); 380 } 381 getSourceMethodName()382 public String getSourceMethodName() { 383 return methodName; 384 } 385 getSourceClassName()386 public String getSourceClassName() { 387 return className; 388 } 389 } 390 391 // mock class, try to test when the sourceclass and sourcemethod of 392 // LogRecord is initiated 393 public static class RecordFactory { 394 getDefaultRecord()395 public static LogRecord getDefaultRecord() { 396 return new LogRecord(Level.SEVERE, MSG); 397 } 398 log(Logger logger, LogRecord lr)399 public static void log(Logger logger, LogRecord lr) { 400 logger.log(lr); 401 } 402 } 403 404 public static class MockLogger extends Logger { 405 406 /** 407 * @param name 408 * @param resourceBundleName 409 */ MockLogger(String name, String resourceBundleName)410 public MockLogger(String name, String resourceBundleName) { 411 super(name, resourceBundleName); 412 } 413 log(Level l, String s)414 public void log(Level l, String s) { 415 this.log(new LogRecord(l, s)); 416 } 417 info(String s)418 public void info(String s) { 419 super.info(s); 420 } 421 log(LogRecord record)422 public void log(LogRecord record) { 423 if (isLoggable(record.getLevel())) { 424 // call the handlers of this logger 425 // TODO: What if an exception occurred in handler? 426 Handler[] ha = this.getHandlers(); 427 for (int i = 0; i < ha.length; i++) { 428 ha[i].publish(record); 429 } 430 // call the parent's handlers if set useParentHandlers 431 if (getUseParentHandlers()) { 432 Logger anyParent = this.getParent(); 433 while (null != anyParent) { 434 ha = anyParent.getHandlers(); 435 for (int i = 0; i < ha.length; i++) { 436 ha[i].publish(record); 437 } 438 if (anyParent.getUseParentHandlers()) { 439 anyParent = anyParent.getParent(); 440 } else { 441 break; 442 } 443 } 444 } 445 } 446 } 447 } 448 } 449