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 libcore.java.util.logging; 19 20import java.io.BufferedReader; 21import java.io.ByteArrayInputStream; 22import java.io.ByteArrayOutputStream; 23import java.io.File; 24import java.io.FileReader; 25import java.io.IOException; 26import java.io.InputStream; 27import java.io.Reader; 28import java.util.Properties; 29import java.util.logging.FileHandler; 30import java.util.logging.Filter; 31import java.util.logging.Formatter; 32import java.util.logging.Handler; 33import java.util.logging.Level; 34import java.util.logging.LogManager; 35import java.util.logging.LogRecord; 36import junit.framework.AssertionFailedError; 37import junit.framework.TestCase; 38 39public class OldFileHandlerTest extends TestCase { 40 41 static LogManager manager = LogManager.getLogManager(); 42 final static Properties props = new Properties(); 43 final static String className = OldFileHandlerTest.class.getName(); 44 final static String SEP = File.separator; 45 String HOMEPATH; 46 String TEMPPATH; 47 FileHandler handler; 48 LogRecord r; 49 50 protected void setUp() throws Exception { 51 super.setUp(); 52 manager.reset(); 53 54 //initProp 55 props.clear(); 56 props.put("java.util.logging.FileHandler.level", "FINE"); 57 props.put("java.util.logging.FileHandler.filter", className 58 + "$MockFilter"); 59 props.put("java.util.logging.FileHandler.formatter", className 60 + "$MockFormatter"); 61 props.put("java.util.logging.FileHandler.encoding", "iso-8859-1"); 62 // limit to only two message 63 props.put("java.util.logging.FileHandler.limit", "1000"); 64 // rotation count is 2 65 props.put("java.util.logging.FileHandler.count", "2"); 66 // using append mode 67 props.put("java.util.logging.FileHandler.append", "true"); 68 props.put("java.util.logging.FileHandler.pattern", 69 "%t/log/java%u.test"); 70 71 HOMEPATH = System.getProperty("user.home"); 72 TEMPPATH = System.getProperty("java.io.tmpdir"); 73 74 File file = new File(TEMPPATH + SEP + "log"); 75 file.mkdir(); 76 manager.readConfiguration(propertiesToInputStream(props)); 77 handler = new FileHandler(); 78 r = new LogRecord(Level.CONFIG, "msg"); 79 } 80 81 protected void tearDown() throws Exception { 82 if (null != handler) { 83 handler.close(); 84 } 85 reset(TEMPPATH + SEP + "log", ""); 86 super.tearDown(); 87 } 88 89 public static InputStream propertiesToInputStream(Properties p) throws IOException { 90 ByteArrayOutputStream bos = new ByteArrayOutputStream(); 91 p.store(bos, ""); 92 return new ByteArrayInputStream(bos.toByteArray()); 93 } 94 95 public void testFileHandler() throws Exception { 96 assertEquals("character encoding is non equal to actual value", 97 "iso-8859-1", handler.getEncoding()); 98 assertNotNull("Filter is null", handler.getFilter()); 99 assertNotNull("Formatter is null", handler.getFormatter()); 100 assertEquals("is non equal to actual value", Level.FINE, handler 101 .getLevel()); 102 assertNotNull("ErrorManager is null", handler.getErrorManager()); 103 handler.publish(r); 104 handler.close(); 105 // output 3 times, and all records left 106 // append mode is true 107 for (int i = 0; i < 3; i++) { 108 handler = new FileHandler(); 109 handler.publish(r); 110 handler.close(); 111 } 112 assertFileContent(TEMPPATH + SEP + "log", "java0.test.0", 113 new LogRecord[] { r, null, r, null, r, null, r }, 114 new MockFormatter()); 115 } 116 117 public void testFileHandler_1params() throws Exception { 118 119 handler = new FileHandler("%t/log/string"); 120 assertEquals("character encoding is non equal to actual value", 121 "iso-8859-1", handler.getEncoding()); 122 assertNotNull("Filter is null", handler.getFilter()); 123 assertNotNull("Formatter is null", handler.getFormatter()); 124 assertEquals("is non equal to actual value", Level.FINE, handler 125 .getLevel()); 126 assertNotNull("ErrorManager is null", handler.getErrorManager()); 127 handler.publish(r); 128 handler.close(); 129 130 // output 3 times, and all records left 131 // append mode is true 132 for (int i = 0; i < 3; i++) { 133 handler = new FileHandler("%t/log/string"); 134 handler.publish(r); 135 handler.close(); 136 } 137 assertFileContent(TEMPPATH + SEP + "log", "/string", new LogRecord[] { 138 r, null, r, null, r, null, r }, new MockFormatter()); 139 140 // test if unique ids not specified, it will append at the end 141 // no generation number is used 142 FileHandler h = new FileHandler("%t/log/string"); 143 FileHandler h2 = new FileHandler("%t/log/string"); 144 FileHandler h3 = new FileHandler("%t/log/string"); 145 FileHandler h4 = new FileHandler("%t/log/string"); 146 h.publish(r); 147 h2.publish(r); 148 h3.publish(r); 149 h4.publish(r); 150 h.close(); 151 h2.close(); 152 h3.close(); 153 h4.close(); 154 assertFileContent(TEMPPATH + SEP + "log", "string", h.getFormatter()); 155 assertFileContent(TEMPPATH + SEP + "log", "string.1", h.getFormatter()); 156 assertFileContent(TEMPPATH + SEP + "log", "string.2", h.getFormatter()); 157 assertFileContent(TEMPPATH + SEP + "log", "string.3", h.getFormatter()); 158 159 // default is append mode 160 FileHandler h6 = new FileHandler("%t/log/string%u.log"); 161 h6.publish(r); 162 h6.close(); 163 FileHandler h7 = new FileHandler("%t/log/string%u.log"); 164 h7.publish(r); 165 h7.close(); 166 boolean assertionPassed = false; 167 try { 168 assertFileContent(TEMPPATH + SEP + "log", "string0.log", h.getFormatter()); 169 assertionPassed = true; 170 } catch (AssertionFailedError e) { 171 // Assertion failed as expected. 172 } 173 if (assertionPassed) { 174 fail("assertion should have failed"); 175 } 176 File file = new File(TEMPPATH + SEP + "log"); 177 assertTrue("length list of file is incorrect", file.list().length <= 2); 178 179 // test unique ids 180 FileHandler h8 = new FileHandler("%t/log/%ustring%u.log"); 181 h8.publish(r); 182 FileHandler h9 = new FileHandler("%t/log/%ustring%u.log"); 183 h9.publish(r); 184 h9.close(); 185 h8.close(); 186 assertFileContent(TEMPPATH + SEP + "log", "0string0.log", h 187 .getFormatter()); 188 assertFileContent(TEMPPATH + SEP + "log", "1string1.log", h 189 .getFormatter()); 190 file = new File(TEMPPATH + SEP + "log"); 191 assertTrue("length list of file is incorrect", file.list().length <= 2); 192 193 try { 194 new FileHandler(""); 195 fail("IllegalArgumentException expected"); 196 } catch (IllegalArgumentException e) { 197 //expected 198 } 199 } 200 201 public void testFileHandler_2params() throws Exception { 202 boolean append = false; 203 do { 204 append = !append; 205 handler = new FileHandler("%t/log/string", append); 206 assertEquals("character encoding is non equal to actual value", 207 "iso-8859-1", handler.getEncoding()); 208 assertNotNull("Filter is null", handler.getFilter()); 209 assertNotNull("Formatter is null", handler.getFormatter()); 210 assertEquals("is non equal to actual value", Level.FINE, handler 211 .getLevel()); 212 assertNotNull("ErrorManager is null", handler.getErrorManager()); 213 handler.publish(r); 214 handler.close(); 215 // output 3 times, and all records left 216 // append mode is true 217 for (int i = 0; i < 3; i++) { 218 handler = new FileHandler("%t/log/string", append); 219 handler.publish(r); 220 handler.close(); 221 } 222 if (append) { 223 assertFileContent(TEMPPATH + SEP + "log", "/string", 224 new LogRecord[] { r, null, r, null, r, null, r }, 225 new MockFormatter()); 226 } else { 227 assertFileContent(TEMPPATH + SEP + "log", "/string", 228 new LogRecord[] { r }, new MockFormatter()); 229 } 230 } while (append); 231 232 try { 233 new FileHandler("", true); 234 fail("IllegalArgumentException expected"); 235 } catch (IllegalArgumentException e) { 236 //expected 237 } 238 } 239 240 public void testFileHandler_3params() throws Exception { 241 int limit = 120; 242 int count = 1; 243 handler = new FileHandler("%t/log/string", limit, count); 244 assertEquals("character encoding is non equal to actual value", 245 "iso-8859-1", handler.getEncoding()); 246 assertNotNull("Filter is null", handler.getFilter()); 247 assertNotNull("Formatter is null", handler.getFormatter()); 248 assertEquals("is non equal to actual value", Level.FINE, handler 249 .getLevel()); 250 assertNotNull("ErrorManager is null", handler.getErrorManager()); 251 handler.publish(r); 252 handler.close(); 253 // output 3 times, and all records left 254 // append mode is true 255 for (int i = 0; i < 3; i++) { 256 handler = new FileHandler("%t/log/string", limit, count); 257 handler.publish(r); 258 handler.close(); 259 } 260 assertFileContent(TEMPPATH + SEP + "log", "/string", new LogRecord[] { 261 r, null, r, null, r, null, r }, new MockFormatter()); 262 263 try { 264 new FileHandler("", limit, count); 265 fail("IllegalArgumentException expected"); 266 } catch (IllegalArgumentException e) { 267 //expected 268 } 269 270 try { 271 new FileHandler("%t/log/string", -1, count); 272 fail("IllegalArgumentException expected"); 273 } catch (IllegalArgumentException e) { 274 //expected 275 } 276 277 try { 278 new FileHandler("%t/log/string", limit, 0); 279 fail("IllegalArgumentException expected"); 280 } catch (IllegalArgumentException e) { 281 //expected 282 } 283 } 284 285 public void testFileHandler_4params() throws Exception { 286 int limit = 120; 287 int count = 1; 288 boolean append = false; 289 do { 290 append = !append; 291 handler = new FileHandler("%t/log/string", limit, count, append); 292 assertEquals("character encoding is non equal to actual value", 293 "iso-8859-1", handler.getEncoding()); 294 assertNotNull("Filter is null", handler.getFilter()); 295 assertNotNull("Formatter is null", handler.getFormatter()); 296 assertEquals("is non equal to actual value", Level.FINE, handler 297 .getLevel()); 298 assertNotNull("ErrorManager is null", handler.getErrorManager()); 299 handler.publish(r); 300 handler.close(); 301 // output 3 times, and all records left 302 // append mode is true 303 for (int i = 0; i < 3; i++) { 304 handler = new FileHandler("%t/log/string", limit, count, append); 305 handler.publish(r); 306 handler.close(); 307 } 308 if (append) { 309 assertFileContent(TEMPPATH + SEP + "log", "/string", 310 new LogRecord[] { r, null, r, null, r, null, r }, 311 new MockFormatter()); 312 } else { 313 assertFileContent(TEMPPATH + SEP + "log", "/string", 314 new LogRecord[] { r }, new MockFormatter()); 315 } 316 } while (append); 317 318 try { 319 new FileHandler("", limit, count, true); 320 fail("IllegalArgumentException expected"); 321 } catch (IllegalArgumentException e) { 322 //expected 323 } 324 325 try { 326 new FileHandler("%t/log/string", -1, count, false); 327 fail("IllegalArgumentException expected"); 328 } catch (IllegalArgumentException e) { 329 //expected 330 } 331 332 try { 333 new FileHandler("%t/log/string", limit, 0, true); 334 fail("IllegalArgumentException expected"); 335 } catch (IllegalArgumentException e) { 336 //expected 337 } 338 } 339 340 private void assertFileContent(String homepath, String filename, 341 Formatter formatter) throws Exception { 342 assertFileContent(homepath, filename, new LogRecord[] { r }, formatter); 343 } 344 345 private void assertFileContent(String homepath, String filename, 346 LogRecord[] lr, Formatter formatter) throws Exception { 347 handler.close(); 348 String msg = ""; 349 // if formatter is null, the file content should be empty 350 // else the message should be formatted given records 351 if (null != formatter) { 352 StringBuffer sb = new StringBuffer(); 353 sb.append(formatter.getHead(handler)); 354 for (int i = 0; i < lr.length; i++) { 355 if (null == lr[i] && i < lr.length - 1) { 356 // if one record is null and is not the last record, means 357 // here is 358 // output completion point, should output tail, then output 359 // head 360 // (ready for next output) 361 sb.append(formatter.getTail(handler)); 362 sb.append(formatter.getHead(handler)); 363 } else { 364 sb.append(formatter.format(lr[i])); 365 } 366 } 367 sb.append(formatter.getTail(handler)); 368 msg = sb.toString(); 369 } 370 char[] chars = new char[msg.length()]; 371 Reader reader = null; 372 try { 373 reader = new BufferedReader(new FileReader(homepath + SEP 374 + filename)); 375 reader.read(chars); 376 assertEquals(msg, new String(chars)); 377 // assert has reached the end of the file 378 assertEquals(-1, reader.read()); 379 } finally { 380 try { 381 if (reader != null) { 382 reader.close(); 383 } 384 } catch (Exception e) { 385 // don't care 386 } 387 reset(homepath, filename); 388 } 389 } 390 391 /** 392 * Does a cleanup of given file 393 */ 394 private void reset(String homepath, String filename) { 395 File file; 396 try { 397 file = new File(homepath + SEP + filename); 398 if (file.isFile()) { 399 file.delete(); 400 } else if (file.isDirectory()) { 401 File[] files = file.listFiles(); 402 for (int i = 0; i < files.length; i++) { 403 files[i].delete(); 404 } 405 file.delete(); 406 } 407 } catch (Exception e) { 408 e.printStackTrace(); 409 } 410 try { 411 file = new File(homepath + SEP + filename + ".lck"); 412 file.delete(); 413 } catch (Exception e) { 414 e.printStackTrace(); 415 } 416 } 417 418 // This test fails on RI. Doesn't parse special pattern \"%t/%h." 419 public void testInvalidParams() throws IOException { 420 421 // %t and %p parsing can add file separator automatically 422 423 // bad directory, IOException, append 424 try { 425 new FileHandler("%t/baddir/multi%g", true); 426 fail("should throw IO exception"); 427 } catch (IOException e) { 428 } 429 File file = new File(TEMPPATH + SEP + "baddir" + SEP + "multi0"); 430 assertFalse(file.exists()); 431 try { 432 new FileHandler("%t/baddir/multi%g", false); 433 fail("should throw IO exception"); 434 } catch (IOException e) { 435 } 436 file = new File(TEMPPATH + SEP + "baddir" + SEP + "multi0"); 437 assertFalse(file.exists()); 438 439 try { 440 new FileHandler("%t/baddir/multi%g", 12, 4); 441 fail("should throw IO exception"); 442 } catch (IOException e) { 443 } 444 file = new File(TEMPPATH + SEP + "baddir" + SEP + "multi0"); 445 assertFalse(file.exists()); 446 447 try { 448 new FileHandler("%t/java%u", -1, -1); 449 fail("should throw IllegalArgumentException"); 450 } catch (IllegalArgumentException e) { 451 } 452 } 453 454 public void testPublish() throws Exception { 455 LogRecord[] r = new LogRecord[] { new LogRecord(Level.CONFIG, "msg__"), 456 new LogRecord(Level.WARNING, "message"), 457 new LogRecord(Level.INFO, "message for"), 458 new LogRecord(Level.FINE, "message for test") }; 459 for (int i = 0; i < r.length; i++) { 460 handler = new FileHandler("%t/log/stringPublish"); 461 handler.publish(r[i]); 462 handler.close(); 463 assertFileContent(TEMPPATH + SEP + "log", "stringPublish", 464 new LogRecord[] { r[i] }, handler.getFormatter()); 465 } 466 } 467 468 public void testClose() throws Exception { 469 FileHandler h = new FileHandler("%t/log/stringPublish"); 470 h.publish(r); 471 h.close(); 472 assertFileContent(TEMPPATH + SEP + "log", "stringPublish", h 473 .getFormatter()); 474 } 475 476 /* 477 * mock classes 478 */ 479 public static class MockFilter implements Filter { 480 public boolean isLoggable(LogRecord record) { 481 return !record.getMessage().equals("false"); 482 } 483 } 484 485 public static class MockFormatter extends Formatter { 486 public String format(LogRecord r) { 487 if (null == r) { 488 return ""; 489 } 490 return r.getMessage() + " by MockFormatter\n"; 491 } 492 493 public String getTail(Handler h) { 494 return "tail\n"; 495 } 496 497 public String getHead(Handler h) { 498 return "head\n"; 499 } 500 } 501} 502