FileHandlerTest.java revision 5d709784bbf5001012d7f25172927d46f6c1abe1
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 dalvik.annotation.AndroidOnly;
21import dalvik.annotation.TestTargetClass;
22import dalvik.annotation.TestTargets;
23import dalvik.annotation.TestLevel;
24import dalvik.annotation.TestTargetNew;
25
26import java.io.BufferedReader;
27import java.io.ByteArrayOutputStream;
28import java.io.File;
29import java.io.FileOutputStream;
30import java.io.FilePermission;
31import java.io.FileReader;
32import java.io.IOException;
33import java.io.OutputStream;
34import java.io.PrintStream;
35import java.io.Reader;
36import java.io.StringWriter;
37import java.security.Permission;
38import java.util.Properties;
39import java.util.logging.FileHandler;
40import java.util.logging.Filter;
41import java.util.logging.Formatter;
42import java.util.logging.Handler;
43import java.util.logging.Level;
44import java.util.logging.LogManager;
45import java.util.logging.LogRecord;
46import java.util.logging.LoggingPermission;
47import java.util.logging.XMLFormatter;
48
49import junit.framework.TestCase;
50
51import org.apache.harmony.logging.tests.java.util.logging.HandlerTest.NullOutputStream;
52import org.apache.harmony.logging.tests.java.util.logging.util.EnvironmentHelper;
53
54/**
55 */
56@TestTargetClass(FileHandler.class)
57public class FileHandlerTest extends TestCase {
58
59    static LogManager manager = LogManager.getLogManager();
60
61    final static Properties props = new Properties();
62
63    final static String className = FileHandlerTest.class.getName();
64
65    final static StringWriter writer = new StringWriter();
66
67    final static SecurityManager securityManager = new MockLogSecurityManager();
68
69    final static String SEP = File.separator;
70
71    private String oldHomePath = System.getProperty("user.home");
72
73    // The HOMEPATH can't be used in android.
74    final static String HOMEPATH = System.getProperty("java.io.tmpdir") + SEP + "home";
75
76    final static String TEMPPATH = System.getProperty("java.io.tmpdir");
77
78    private final PrintStream err = System.err;
79
80    private OutputStream errSubstituteStream = null;
81
82    FileHandler handler;
83
84    LogRecord r;
85
86    /*
87     * @see TestCase#setUp()
88     */
89    protected void setUp() throws Exception {
90        super.setUp();
91        manager.reset();
92
93        //initProp
94        props.clear();
95        props.put("java.util.logging.FileHandler.level", "FINE");
96        props.put("java.util.logging.FileHandler.filter", className
97                + "$MockFilter");
98        props.put("java.util.logging.FileHandler.formatter", className
99                + "$MockFormatter");
100        props.put("java.util.logging.FileHandler.encoding", "iso-8859-1");
101        // limit to only two message
102        props.put("java.util.logging.FileHandler.limit", "1000");
103        // rotation count is 2
104        props.put("java.util.logging.FileHandler.count", "2");
105        // using append mode
106        props.put("java.util.logging.FileHandler.append", "true");
107        props.put("java.util.logging.FileHandler.pattern",
108                        "%t/log/java%u.test");
109
110        File home = new File(HOMEPATH);
111        if (!home.exists()) {
112            home.mkdirs();
113        } else if (!home.isDirectory()) {
114            home.delete();
115            home.mkdirs();
116        }
117        if(!home.isDirectory()) {
118            fail("unable to create temp path");
119        }
120        System.setProperty("user.home", HOMEPATH);
121
122        File file = new File(TEMPPATH + SEP + "log");
123        file.mkdir();
124        manager.readConfiguration(EnvironmentHelper
125                .PropertiesToInputStream(props));
126        handler = new FileHandler();
127        r = new LogRecord(Level.CONFIG, "msg");
128        errSubstituteStream = new NullOutputStream();
129        System.setErr(new PrintStream(errSubstituteStream));
130    }
131
132
133    /*
134     * @see TestCase#tearDown()
135     */
136
137    protected void tearDown() throws Exception {
138        if (null != handler) {
139            handler.close();
140        }
141        reset(TEMPPATH + SEP + "log", "");
142        System.setErr(err);
143        System.setProperty("user.home", oldHomePath);
144        new File(HOMEPATH).delete();
145        super.tearDown();
146    }
147
148    /*
149     * test for constructor void FileHandler()
150     */
151    @TestTargetNew(
152        level = TestLevel.PARTIAL_COMPLETE,
153        notes = "Doesn't verify exceptions.",
154        method = "FileHandler",
155        args = {}
156    )
157    public void testFileHandler() throws Exception {
158        assertEquals("character encoding is non equal to actual value",
159                "iso-8859-1", handler.getEncoding());
160        assertNotNull("Filter is null", handler.getFilter());
161        assertNotNull("Formatter is null", handler.getFormatter());
162        assertEquals("is non equal to actual value", Level.FINE, handler
163                .getLevel());
164        assertNotNull("ErrorManager is null", handler.getErrorManager());
165        handler.publish(r);
166        handler.close();
167        // output 3 times, and all records left
168        // append mode is true
169        for (int i = 0; i < 3; i++) {
170            handler = new FileHandler();
171            handler.publish(r);
172            handler.close();
173        }
174        assertFileContent(TEMPPATH + SEP + "log", "java0.test.0",
175                new LogRecord[] { r, null, r, null, r, null, r },
176                new MockFormatter());
177    }
178
179    /*
180     * test for constructor void FileHandler(String)
181     */
182    @TestTargetNew(
183        level = TestLevel.PARTIAL_COMPLETE,
184        notes = "Doesn't verify security exception.",
185        method = "FileHandler",
186        args = {java.lang.String.class}
187    )
188    public void testFileHandler_1params() throws Exception {
189
190        handler = new FileHandler("%t/log/string");
191        assertEquals("character encoding is non equal to actual value",
192                "iso-8859-1", handler.getEncoding());
193        assertNotNull("Filter is null", handler.getFilter());
194        assertNotNull("Formatter is null", handler.getFormatter());
195        assertEquals("is non equal to actual value", Level.FINE, handler
196                .getLevel());
197        assertNotNull("ErrorManager is null", handler.getErrorManager());
198        handler.publish(r);
199        handler.close();
200
201        // output 3 times, and all records left
202        // append mode is true
203        for (int i = 0; i < 3; i++) {
204            handler = new FileHandler("%t/log/string");
205            handler.publish(r);
206            handler.close();
207        }
208        assertFileContent(TEMPPATH + SEP + "log", "/string", new LogRecord[] {
209                r, null, r, null, r, null, r }, new MockFormatter());
210
211        // test if unique ids not specified, it will append at the end
212        // no generation number is used
213        FileHandler h = new FileHandler("%t/log/string");
214        FileHandler h2 = new FileHandler("%t/log/string");
215        FileHandler h3 = new FileHandler("%t/log/string");
216        FileHandler h4 = new FileHandler("%t/log/string");
217        h.publish(r);
218        h2.publish(r);
219        h3.publish(r);
220        h4.publish(r);
221        h.close();
222        h2.close();
223        h3.close();
224        h4.close();
225        assertFileContent(TEMPPATH + SEP + "log", "string", h.getFormatter());
226        assertFileContent(TEMPPATH + SEP + "log", "string.1", h.getFormatter());
227        assertFileContent(TEMPPATH + SEP + "log", "string.2", h.getFormatter());
228        assertFileContent(TEMPPATH + SEP + "log", "string.3", h.getFormatter());
229
230        // default is append mode
231        FileHandler h6 = new FileHandler("%t/log/string%u.log");
232        h6.publish(r);
233        h6.close();
234        FileHandler h7 = new FileHandler("%t/log/string%u.log");
235        h7.publish(r);
236        h7.close();
237        try {
238            assertFileContent(TEMPPATH + SEP + "log", "string0.log", h
239                    .getFormatter());
240            fail("should assertion failed");
241        } catch (Error e) {
242        }
243        File file = new File(TEMPPATH + SEP + "log");
244        assertTrue("length list of file is incorrect", file.list().length <= 2);
245
246        // test unique ids
247        FileHandler h8 = new FileHandler("%t/log/%ustring%u.log");
248        h8.publish(r);
249        FileHandler h9 = new FileHandler("%t/log/%ustring%u.log");
250        h9.publish(r);
251        h9.close();
252        h8.close();
253        assertFileContent(TEMPPATH + SEP + "log", "0string0.log", h
254                .getFormatter());
255        assertFileContent(TEMPPATH + SEP + "log", "1string1.log", h
256                .getFormatter());
257        file = new File(TEMPPATH + SEP + "log");
258        assertTrue("length list of file is incorrect", file.list().length <= 2);
259
260        try {
261            new FileHandler("");
262            fail("IllegalArgumentException expected");
263        } catch (IllegalArgumentException e) {
264            //expected
265        }
266    }
267
268    /*
269     * test for constructor void FileHandler(String pattern, boolean append)
270     */
271    @TestTargetNew(
272        level = TestLevel.PARTIAL_COMPLETE,
273        notes = "Doesn't verify security exception.",
274        method = "FileHandler",
275        args = {java.lang.String.class, boolean.class}
276    )
277    public void testFileHandler_2params() throws Exception {
278        boolean append = false;
279        do {
280            append = !append;
281            handler = new FileHandler("%t/log/string", append);
282            assertEquals("character encoding is non equal to actual value",
283                    "iso-8859-1", handler.getEncoding());
284            assertNotNull("Filter is null", handler.getFilter());
285            assertNotNull("Formatter is null", handler.getFormatter());
286            assertEquals("is non equal to actual value", Level.FINE, handler
287                    .getLevel());
288            assertNotNull("ErrorManager is null", handler.getErrorManager());
289            handler.publish(r);
290            handler.close();
291            // output 3 times, and all records left
292            // append mode is true
293            for (int i = 0; i < 3; i++) {
294                handler = new FileHandler("%t/log/string", append);
295                handler.publish(r);
296                handler.close();
297            }
298            if (append) {
299                assertFileContent(TEMPPATH + SEP + "log", "/string",
300                        new LogRecord[] { r, null, r, null, r, null, r },
301                        new MockFormatter());
302            } else {
303                assertFileContent(TEMPPATH + SEP + "log", "/string",
304                        new LogRecord[] { r }, new MockFormatter());
305            }
306        } while (append);
307
308        try {
309            new FileHandler("", true);
310            fail("IllegalArgumentException expected");
311        } catch (IllegalArgumentException e) {
312            //expected
313        }
314    }
315
316    /*
317     * test for constructor void FileHandler(String pattern, int limit, int
318     * count)
319     */
320    @TestTargetNew(
321        level = TestLevel.PARTIAL_COMPLETE,
322        notes = "Doesn't verifysecurity exception.",
323        method = "FileHandler",
324        args = {java.lang.String.class, int.class, int.class}
325    )
326    public void testFileHandler_3params() throws Exception {
327        int limit = 120;
328        int count = 1;
329        handler = new FileHandler("%t/log/string", limit, count);
330        assertEquals("character encoding is non equal to actual value",
331                "iso-8859-1", handler.getEncoding());
332        assertNotNull("Filter is null", handler.getFilter());
333        assertNotNull("Formatter is null", handler.getFormatter());
334        assertEquals("is non equal to actual value", Level.FINE, handler
335                .getLevel());
336        assertNotNull("ErrorManager is null", handler.getErrorManager());
337        handler.publish(r);
338        handler.close();
339        // output 3 times, and all records left
340        // append mode is true
341        for (int i = 0; i < 3; i++) {
342            handler = new FileHandler("%t/log/string", limit, count);
343            handler.publish(r);
344            handler.close();
345        }
346        assertFileContent(TEMPPATH + SEP + "log", "/string", new LogRecord[] {
347                r, null, r, null, r, null, r }, new MockFormatter());
348
349        try {
350            new FileHandler("", limit, count);
351            fail("IllegalArgumentException expected");
352        } catch (IllegalArgumentException e) {
353            //expected
354        }
355
356        try {
357            new FileHandler("%t/log/string", -1, count);
358            fail("IllegalArgumentException expected");
359        } catch (IllegalArgumentException e) {
360            //expected
361        }
362
363        try {
364            new FileHandler("%t/log/string", limit, 0);
365            fail("IllegalArgumentException expected");
366        } catch (IllegalArgumentException e) {
367            //expected
368        }
369    }
370
371    /*
372     * test for constructor public FileHandler(String pattern, int limit, int
373     * count, boolean append)
374     */
375    @TestTargetNew(
376        level = TestLevel.PARTIAL_COMPLETE,
377        notes = "Doesn't verify security exception.",
378        method = "FileHandler",
379        args = {java.lang.String.class, int.class, int.class, boolean.class}
380    )
381    public void testFileHandler_4params() throws Exception {
382        int limit = 120;
383        int count = 1;
384        boolean append = false;
385        do {
386            append = !append;
387            handler = new FileHandler("%t/log/string", limit, count, append);
388            assertEquals("character encoding is non equal to actual value",
389                    "iso-8859-1", handler.getEncoding());
390            assertNotNull("Filter is null", handler.getFilter());
391            assertNotNull("Formatter is null", handler.getFormatter());
392            assertEquals("is non equal to actual value", Level.FINE, handler
393                    .getLevel());
394            assertNotNull("ErrorManager is null", handler.getErrorManager());
395            handler.publish(r);
396            handler.close();
397            // output 3 times, and all records left
398            // append mode is true
399            for (int i = 0; i < 3; i++) {
400                handler = new FileHandler("%t/log/string", limit, count, append);
401                handler.publish(r);
402                handler.close();
403            }
404            if (append) {
405                assertFileContent(TEMPPATH + SEP + "log", "/string",
406                        new LogRecord[] { r, null, r, null, r, null, r },
407                        new MockFormatter());
408            } else {
409                assertFileContent(TEMPPATH + SEP + "log", "/string",
410                        new LogRecord[] { r }, new MockFormatter());
411            }
412        } while (append);
413
414        try {
415            new FileHandler("", limit, count, true);
416            fail("IllegalArgumentException expected");
417        } catch (IllegalArgumentException e) {
418            //expected
419        }
420
421        try {
422            new FileHandler("%t/log/string", -1, count, false);
423            fail("IllegalArgumentException expected");
424        } catch (IllegalArgumentException e) {
425            //expected
426        }
427
428        try {
429            new FileHandler("%t/log/string", limit, 0, true);
430            fail("IllegalArgumentException expected");
431        } catch (IllegalArgumentException e) {
432            //expected
433        }
434    }
435    @TestTargets({
436        @TestTargetNew(
437            level = TestLevel.PARTIAL_COMPLETE,
438            notes = "",
439            method = "getEncoding",
440            args = {}
441        ),
442        @TestTargetNew(
443            level = TestLevel.PARTIAL_COMPLETE,
444            notes = "",
445            method = "getFilter",
446            args = {}
447        ),
448        @TestTargetNew(
449            level = TestLevel.PARTIAL_COMPLETE,
450            notes = "",
451            method = "getFormatter",
452            args = {}
453        ),
454        @TestTargetNew(
455            level = TestLevel.PARTIAL_COMPLETE,
456            notes = "",
457            method = "getLevel",
458            args = {}
459        ),
460        @TestTargetNew(
461            level = TestLevel.PARTIAL_COMPLETE,
462            notes = "",
463            method = "getErrorManager",
464            args = {}
465        )
466    })
467    public void testDefaultValue() throws Exception {
468        handler.publish(r);
469        handler.close();
470        props.clear();
471        manager.readConfiguration(EnvironmentHelper
472                .PropertiesToInputStream(props));
473        handler = new FileHandler();
474        assertNull(handler.getEncoding());
475        assertNull(handler.getFilter());
476        assertTrue(handler.getFormatter() instanceof XMLFormatter);
477        assertEquals(handler.getLevel(), Level.ALL);
478        assertNotNull(handler.getErrorManager());
479        handler.publish(r);
480        handler.close();
481        // output 3 times, and only one record left
482        // default append mode is false
483        for (int i = 0; i < 3; i++) {
484            handler = new FileHandler();
485            handler.publish(r);
486            handler.close();
487        }
488        assertFileContent(HOMEPATH, "java0.log", new XMLFormatter());
489    }
490
491    private void assertFileContent(String homepath, String filename,
492            Formatter formatter) throws Exception {
493        assertFileContent(homepath, filename, new LogRecord[] { r }, formatter);
494    }
495
496    private void assertFileContent(String homepath, String filename,
497            LogRecord[] lr, Formatter formatter) throws Exception {
498        handler.close();
499        String msg = "";
500        // if formatter is null, the file content should be empty
501        // else the message should be formatted given records
502        if (null != formatter) {
503            StringBuffer sb = new StringBuffer();
504            sb.append(formatter.getHead(handler));
505            for (int i = 0; i < lr.length; i++) {
506                if (null == lr[i] && i < lr.length - 1) {
507                    // if one record is null and is not the last record, means
508                    // here is
509                    // output completion point, should output tail, then output
510                    // head
511                    // (ready for next output)
512                    sb.append(formatter.getTail(handler));
513                    sb.append(formatter.getHead(handler));
514                } else {
515                    sb.append(formatter.format(lr[i]));
516                }
517            }
518            sb.append(formatter.getTail(handler));
519            msg = sb.toString();
520        }
521        char[] chars = new char[msg.length()];
522        Reader reader = null;
523        try {
524            reader = new BufferedReader(new FileReader(homepath + SEP
525                    + filename));
526            reader.read(chars);
527            assertEquals(msg, new String(chars));
528            // assert has reached the end of the file
529            assertEquals(-1, reader.read());
530        } finally {
531            try {
532                if (reader != null) {
533                    reader.close();
534                }
535            } catch (Exception e) {
536                // don't care
537            }
538            reset(homepath, filename);
539        }
540    }
541
542    /**
543     * Does a cleanup of given file
544     *
545     * @param homepath
546     * @param filename
547     */
548    private void reset(String homepath, String filename) {
549        File file = null;
550        try {
551            file = new File(homepath + SEP + filename);
552            if (file.isFile()) {
553                file.delete();
554            } else if (file.isDirectory()) {
555                File[] files = file.listFiles();
556                for (int i = 0; i < files.length; i++) {
557                    files[i].delete();
558                }
559                file.delete();
560            }
561        } catch (Exception e) {
562            e.printStackTrace();
563        }
564        try {
565            file = new File(homepath + SEP + filename + ".lck");
566            file.delete();
567        } catch (Exception e) {
568            e.printStackTrace();
569        }
570    }
571    @TestTargetNew(
572        level = TestLevel.PARTIAL_COMPLETE,
573        notes = "",
574        method = "FileHandler",
575        args = {java.lang.String.class, int.class, int.class, boolean.class}
576    )
577    public void testLimitAndCount() throws Exception {
578        handler.close();
579        // very small limit value, count=2
580        // output, rename current output file to the second generation file
581        // close it and open a new file as rotation output
582        handler = new FileHandler("%t/testLimitCount%g", 1, 2, false);
583        handler.publish(r);
584        handler.close();
585        assertFileContent(TEMPPATH, "testLimitCount1", handler.getFormatter());
586
587        // very small limit value, count=1
588        // output once, rotate(equals to nothing output)
589        handler = new FileHandler("%t/testLimitCount%g", 1, 1, false);
590        handler.publish(r);
591        handler.close();
592        assertFileContent(TEMPPATH, "testLimitCount0", new LogRecord[0],
593                handler.getFormatter());
594
595        // normal case, limit is 60(>2*msg length <3*msg length), append is
596        // false
597        handler = new FileHandler("%t/testLimitCount%u", 60, 3, false);
598        LogRecord[] rs = new LogRecord[10];
599        // batch output twice to test the append mode
600        for (int i = 0; i < 5; i++) {
601            rs[i] = new LogRecord(Level.SEVERE, "msg" + i);
602            handler.publish(rs[i]);
603        }
604        handler.close();
605        handler = new FileHandler("%t/testLimitCount%u", 60, 3, false);
606        for (int i = 5; i < 10; i++) {
607            rs[i] = new LogRecord(Level.SEVERE, "msg" + i);
608            handler.publish(rs[i]);
609        }
610
611        assertFileContent(TEMPPATH, "testLimitCount0.1", new LogRecord[] {
612                rs[5], rs[6], rs[7] }, handler.getFormatter());
613        assertFileContent(TEMPPATH, "testLimitCount0.0", new LogRecord[] {
614                rs[8], rs[9] }, handler.getFormatter());
615
616        // normal case, limit is 60(>2*msg length <3*msg length), append is true
617        handler = new FileHandler("%t/testLimitCount%u", 60, 3, false);
618        // batch output twice to test the append mode
619        for (int i = 0; i < 5; i++) {
620            rs[i] = new LogRecord(Level.SEVERE, "msg" + i);
621            handler.publish(rs[i]);
622        }
623        handler.close();
624        handler = new FileHandler("%t/testLimitCount%u", 60, 3, true);
625        for (int i = 5; i < 10; i++) {
626            rs[i] = new LogRecord(Level.SEVERE, "msg" + i);
627            handler.publish(rs[i]);
628        }
629        handler.close();
630        assertFileContent(TEMPPATH, "testLimitCount0.2", new LogRecord[] {
631                rs[3], rs[4], null, rs[5] }, handler.getFormatter());
632        assertFileContent(TEMPPATH, "testLimitCount0.1", new LogRecord[] {
633                rs[6], rs[7], rs[8] }, handler.getFormatter());
634        assertFileContent(TEMPPATH, "testLimitCount0.0",
635                new LogRecord[] { rs[9] }, handler.getFormatter());
636
637        String oldUserDir = System.getProperty("user.dir");
638        System.setProperty("user.dir", System.getProperty("java.io.tmpdir"));
639        FileHandler h1 = null;
640        FileHandler h2 = null;
641        try {
642            File logDir = new File("log");
643            reset("log", "");
644            logDir.mkdir();
645            h1 = new FileHandler("log/a", 0, 1);
646            assertNotNull(h1);
647            h2 = new FileHandler("log/a", 0, 1, false);
648            assertNotNull(h2);
649        } finally {
650            try {
651                h1.close();
652            } catch (Exception e) {
653            }
654            try {
655                h2.close();
656            } catch (Exception e) {
657            }
658            reset("log", "");
659            System.setProperty("user.dir", oldUserDir);
660        }
661    }
662    @TestTargets({
663        @TestTargetNew(
664            level = TestLevel.PARTIAL_COMPLETE,
665            notes = "",
666            method = "close",
667            args = {}
668        ),
669        @TestTargetNew(
670            level = TestLevel.PARTIAL_COMPLETE,
671            notes = "",
672            method = "FileHandler",
673            args = {}
674        ),
675        @TestTargetNew(
676            level = TestLevel.PARTIAL_COMPLETE,
677            notes = "",
678            method = "FileHandler",
679            args = {java.lang.String.class}
680        ),
681        @TestTargetNew(
682            level = TestLevel.PARTIAL_COMPLETE,
683            notes = "",
684            method = "FileHandler",
685            args = {java.lang.String.class, boolean.class}
686        ),
687        @TestTargetNew(
688            level = TestLevel.PARTIAL_COMPLETE,
689            notes = "",
690            method = "FileHandler",
691            args = {java.lang.String.class, int.class, int.class}
692        ),
693        @TestTargetNew(
694            level = TestLevel.PARTIAL_COMPLETE,
695            notes = "",
696            method = "FileHandler",
697            args = {java.lang.String.class, int.class, int.class, boolean.class}
698        )
699    })
700    public void testSecurity() throws IOException {
701        SecurityManager currentManager = System.getSecurityManager();
702
703        try {
704            System.setSecurityManager(new MockLogSecurityManager());
705            try {
706                handler.close();
707                fail("should throw security exception");
708            } catch (SecurityException e) {
709            }
710            handler.publish(new LogRecord(Level.SEVERE, "msg"));
711
712            try {
713                handler = new FileHandler();
714                fail("should throw security exception");
715            } catch (SecurityException e) {
716            }
717
718            try {
719                handler = new FileHandler("pattern1");
720                fail("should throw security exception");
721            } catch (SecurityException e) {
722            }
723            try {
724                handler = new FileHandler("pattern2", true);
725                fail("should throw security exception");
726            } catch (SecurityException e) {
727            }
728            try {
729                handler = new FileHandler("pattern3", 1000, 1);
730                fail("should throw security exception");
731            } catch (SecurityException e) {
732            }
733            try {
734                handler = new FileHandler("pattern4", 1000, 1, true);
735                fail("should throw security exception");
736            } catch (SecurityException e) {
737            }
738        } finally {
739            System.setSecurityManager(currentManager);
740        }
741
742    }
743    @TestTargets({
744        @TestTargetNew(
745            level = TestLevel.PARTIAL_COMPLETE,
746            notes = "Verifies SecurityException.",
747            method = "close",
748            args = {}
749        ),
750        @TestTargetNew(
751            level = TestLevel.PARTIAL_COMPLETE,
752            notes = "Verifies SecurityException.",
753            method = "FileHandler",
754            args = {}
755        ),
756        @TestTargetNew(
757            level = TestLevel.PARTIAL_COMPLETE,
758            notes = "Verifies SecurityException.",
759            method = "FileHandler",
760            args = {java.lang.String.class}
761        ),
762        @TestTargetNew(
763            level = TestLevel.PARTIAL_COMPLETE,
764            notes = "Verifies SecurityException.",
765            method = "FileHandler",
766            args = {java.lang.String.class, boolean.class}
767        ),
768        @TestTargetNew(
769            level = TestLevel.PARTIAL_COMPLETE,
770            notes = "Verifies SecurityException.",
771            method = "FileHandler",
772            args = {java.lang.String.class, int.class, int.class}
773        ),
774        @TestTargetNew(
775            level = TestLevel.PARTIAL_COMPLETE,
776            notes = "Verifies SecurityException.",
777            method = "FileHandler",
778            args = {java.lang.String.class, int.class, int.class, boolean.class}
779        )
780    })
781    public void testFileSecurity() throws IOException {
782        SecurityManager currentManager = System.getSecurityManager();
783
784        try {
785            System.setSecurityManager(new MockFileSecurityManager());
786            handler.publish(new LogRecord(Level.SEVERE, "msg"));
787            try {
788                handler.close();
789                fail("should throw security exception");
790            } catch (SecurityException e) {
791            }
792
793            try {
794                handler = new FileHandler();
795                fail("should throw security exception");
796            } catch (SecurityException e) {
797            }
798
799            try {
800                handler = new FileHandler("pattern1");
801                fail("should throw security exception");
802            } catch (SecurityException e) {
803            }
804            try {
805                handler = new FileHandler("pattern2", true);
806                fail("should throw security exception");
807            } catch (SecurityException e) {
808            }
809            try {
810                handler = new FileHandler("pattern3", 1000, 1);
811                fail("should throw security exception");
812            } catch (SecurityException e) {
813            }
814            try {
815                handler = new FileHandler("pattern4", 1000, 1, true);
816                fail("should throw security exception");
817            } catch (SecurityException e) {
818            }
819        } finally {
820            System.setSecurityManager(currentManager);
821        }
822    }
823    @TestTargetNew(
824        level = TestLevel.PARTIAL_COMPLETE,
825        notes = "Verifies FileHandler when configuration file is invalid.",
826        method = "FileHandler",
827        args = {}
828    )
829    public void testInvalidProperty() throws Exception {
830        props.put("java.util.logging.FileHandler.level", "null");
831        props.put("java.util.logging.FileHandler.filter", className
832                + "$MockFilte");
833        props.put("java.util.logging.FileHandler.formatter", className
834                + "$MockFormatte");
835        props.put("java.util.logging.FileHandler.encoding", "ut");
836        // limit to only two message
837        props.put("java.util.logging.FileHandler.limit", "-1");
838        // rotation count is 2
839        props.put("java.util.logging.FileHandler.count", "-1");
840        // using append mode
841        props.put("java.util.logging.FileHandler.append", "bad");
842
843        handler.close();
844
845        manager.readConfiguration(EnvironmentHelper
846                .PropertiesToInputStream(props));
847        handler = new FileHandler();
848        assertEquals(Level.ALL, handler.getLevel());
849        assertNull(handler.getFilter());
850        assertTrue(handler.getFormatter() instanceof XMLFormatter);
851        assertNull(handler.getEncoding());
852        handler.close();
853
854        props.put("java.util.logging.FileHandler.pattern", "");
855        manager.readConfiguration(EnvironmentHelper
856                .PropertiesToInputStream(props));
857        try {
858            handler = new FileHandler();
859            fail("shouldn't open file with empty name");
860        } catch (NullPointerException e) {
861        }
862    }
863    @TestTargets({
864        @TestTargetNew(
865            level = TestLevel.PARTIAL_COMPLETE,
866            notes = "Verifies illegal parameters and exceptions: IOException, NullPointerException, IllegalArgumentException.",
867            method = "FileHandler",
868            args = {java.lang.String.class}
869        ),
870        @TestTargetNew(
871            level = TestLevel.PARTIAL_COMPLETE,
872            notes = "Verifies illegal parameters and exceptions: IOException, NullPointerException, IllegalArgumentException.",
873            method = "FileHandler",
874            args = {java.lang.String.class, boolean.class}
875        ),
876        @TestTargetNew(
877            level = TestLevel.PARTIAL_COMPLETE,
878            notes = "Verifies illegal parameters and exceptions: IOException, NullPointerException, IllegalArgumentException.",
879            method = "FileHandler",
880            args = {java.lang.String.class, int.class, int.class}
881        ),
882        @TestTargetNew(
883            level = TestLevel.PARTIAL_COMPLETE,
884            notes = "Verifies illegal parameters and exceptions: IOException, NullPointerException, IllegalArgumentException.",
885            method = "publish",
886            args = {java.util.logging.LogRecord.class}
887        )
888    })
889    @AndroidOnly("This test fails on RI. Doesn't parse special pattern \"%t/%h.")
890    public void testInvalidParams() throws IOException {
891
892        // %t and %p parsing can add file separator automatically
893        FileHandler h1 = new FileHandler("%taaa");
894        h1.close();
895        File file = new File(TEMPPATH + SEP + "aaa");
896        assertTrue(file.exists());
897        reset(TEMPPATH, "aaa");
898
899        h1 = new FileHandler("%t%g");
900        h1.close();
901        file = new File(TEMPPATH + SEP + "0");
902        assertTrue(file.exists());
903        reset(TEMPPATH, "0");
904        h1 = new FileHandler("%t%u%g");
905        h1.close();
906        file = new File(TEMPPATH + SEP + "00");
907        assertTrue(file.exists());
908        reset(TEMPPATH, "00");
909
910        // this is normal case
911        h1 = new FileHandler("%t/%u%g%%g");
912        h1.close();
913        file = new File(TEMPPATH + SEP + "00%g");
914        assertTrue(file.exists());
915        reset(TEMPPATH, "00%g");
916
917        // multi separator has no effect
918        h1 = new FileHandler("//%t//multi%g");
919        h1.close();
920        file = new File(TEMPPATH + SEP + "multi0");
921        assertTrue(file.exists());
922        reset(TEMPPATH, "multi0");
923
924        // bad directory, IOException
925        try {
926            h1 = new FileHandler("%t/baddir/multi%g");
927            fail("should throw IO exception");
928        } catch (IOException e) {
929        }
930        file = new File(TEMPPATH + SEP + "baddir" + SEP + "multi0");
931        assertFalse(file.exists());
932
933        // bad directory, IOException, append
934        try {
935            h1 = new FileHandler("%t/baddir/multi%g", true);
936            fail("should throw IO exception");
937        } catch (IOException e) {
938        }
939        file = new File(TEMPPATH + SEP + "baddir" + SEP + "multi0");
940        assertFalse(file.exists());
941        try {
942            h1 = new FileHandler("%t/baddir/multi%g", false);
943            fail("should throw IO exception");
944        } catch (IOException e) {
945        }
946        file = new File(TEMPPATH + SEP + "baddir" + SEP + "multi0");
947        assertFalse(file.exists());
948
949        try {
950            h1 = new FileHandler("%t/baddir/multi%g", 12, 4);
951            fail("should throw IO exception");
952        } catch (IOException e) {
953        }
954        file = new File(TEMPPATH + SEP + "baddir" + SEP + "multi0");
955        assertFalse(file.exists());
956
957        try {
958            h1 = new FileHandler("%t/baddir/multi%g", 12, 4, true);
959            fail("should throw IO exception");
960        } catch (IOException e) {
961        }
962        file = new File(TEMPPATH + SEP + "baddir" + SEP + "multi0");
963        assertFalse(file.exists());
964
965
966        try {
967            new FileHandler(null);
968            fail("should throw null exception");
969        } catch (NullPointerException e) {
970        }
971        try {
972            handler.publish(null);
973        } catch (NullPointerException e) {
974            fail("should not throw NPE");
975        }
976        try {
977            new FileHandler(null, false);
978            fail("should throw null exception");
979        } catch (NullPointerException e) {
980        }
981        try {
982            new FileHandler("");
983            fail("should throw IllegalArgumentException");
984        } catch (IllegalArgumentException e) {
985            // expected
986        }
987        try {
988            new FileHandler("%t/java%u", 0, 0);
989            fail("should throw IllegalArgumentException");
990        } catch (IllegalArgumentException e) {
991        }
992        try {
993            new FileHandler("%t/java%u", -1, 1);
994            fail("should throw IllegalArgumentException");
995        } catch (IllegalArgumentException e) {
996        }
997
998        try {
999            new FileHandler("%t/java%u", -1, -1);
1000            fail("should throw IllegalArgumentException");
1001        } catch (IllegalArgumentException e) {
1002        }
1003
1004        // always parse special pattern
1005        System.setProperty("user.home", "home");
1006        try {
1007            h1 = new FileHandler("%t/%h.txt");
1008        } catch (Exception e) {
1009            fail("Unexpected exception " + e.toString());
1010        }
1011    }
1012
1013    /*
1014     * test for method public void publish(LogRecord record)
1015     */
1016    @TestTargetNew(
1017        level = TestLevel.PARTIAL_COMPLETE,
1018        notes = "",
1019        method = "publish",
1020        args = {java.util.logging.LogRecord.class}
1021    )
1022    public void testPublish() throws Exception {
1023        LogRecord[] r = new LogRecord[] { new LogRecord(Level.CONFIG, "msg__"),
1024                new LogRecord(Level.WARNING, "message"),
1025                new LogRecord(Level.INFO, "message for"),
1026                new LogRecord(Level.FINE, "message for test") };
1027        for (int i = 0; i < r.length; i++) {
1028            handler = new FileHandler("%t/log/stringPublish");
1029            handler.publish(r[i]);
1030            handler.close();
1031            assertFileContent(TEMPPATH + SEP + "log", "stringPublish",
1032                    new LogRecord[] { r[i] }, handler.getFormatter());
1033        }
1034    }
1035
1036    /*
1037     * test for method public void close()
1038     */
1039    @TestTargetNew(
1040        level = TestLevel.COMPLETE,
1041        notes = "",
1042        method = "close",
1043        args = {}
1044    )
1045    public void testClose() throws Exception {
1046        FileHandler h = new FileHandler("%t/log/stringPublish");
1047        h.publish(r);
1048        h.close();
1049        assertFileContent(TEMPPATH + SEP + "log", "stringPublish", h
1050                .getFormatter());
1051    }
1052    @TestTargetNew(
1053        level = TestLevel.PARTIAL,
1054        notes = "Doesn't verify SecurityException.",
1055        method = "setOutputStream",
1056        args = {java.io.OutputStream.class}
1057    )
1058    // set output stream still works, just like super StreamHandler
1059    public void testSetOutputStream() throws Exception {
1060        MockFileHandler handler = new MockFileHandler("%h/setoutput.log");
1061        handler.setFormatter(new MockFormatter());
1062        handler.publish(r);
1063
1064        ByteArrayOutputStream out = new ByteArrayOutputStream();
1065        handler.publicSetOutputStream(out);
1066        handler.publish(r);
1067        handler.close();
1068        String msg = new String(out.toByteArray());
1069        Formatter f = handler.getFormatter();
1070        assertEquals(msg, f.getHead(handler) + f.format(r) + f.getTail(handler));
1071        assertFileContent(HOMEPATH, "setoutput.log", handler.getFormatter());
1072    }
1073
1074    @TestTargetNew(
1075        level = TestLevel.PARTIAL_COMPLETE,
1076        notes = "Verifies IllegalArgumentException.",
1077        method = "FileHandler",
1078        args = {java.lang.String.class, int.class, int.class}
1079    )
1080    public void testEmptyPattern_3params() throws SecurityException,
1081            IOException {
1082        try {
1083            new FileHandler(new String(), 1, 1);
1084            fail("Expected an IllegalArgumentException");
1085        } catch (IllegalArgumentException e) {
1086            // Expected
1087        }
1088    }
1089    @TestTargetNew(
1090        level = TestLevel.PARTIAL_COMPLETE,
1091        notes = "Verifies IllegalArgumentException.",
1092        method = "FileHandler",
1093        args = {java.lang.String.class, boolean.class}
1094    )
1095    public void testEmptyPattern_2params() throws SecurityException,
1096            IOException {
1097        try {
1098            new FileHandler(new String(), true);
1099            fail("Expected an IllegalArgumentException");
1100        } catch (IllegalArgumentException e) {
1101            // Expected
1102        }
1103    }
1104    @TestTargetNew(
1105        level = TestLevel.PARTIAL_COMPLETE,
1106        notes = "Verifies IllegalArgumentException.",
1107        method = "FileHandler",
1108        args = {java.lang.String.class, int.class, int.class, boolean.class}
1109    )
1110    public void testEmptyPattern_4params() throws SecurityException,
1111            IOException {
1112        try {
1113            new FileHandler(new String(), 1, 1, true);
1114            fail("Expected an IllegalArgumentException");
1115        } catch (IllegalArgumentException e) {
1116            // Expected
1117        }
1118    }
1119
1120    /*
1121     * mock classes
1122     */
1123    public static class MockFilter implements Filter {
1124        public boolean isLoggable(LogRecord record) {
1125            return !record.getMessage().equals("false");
1126        }
1127    }
1128
1129    public static class MockFormatter extends Formatter {
1130        public String format(LogRecord r) {
1131            if (null == r) {
1132                return "";
1133            }
1134            return r.getMessage() + " by MockFormatter\n";
1135        }
1136
1137        public String getTail(Handler h) {
1138            return "tail\n";
1139        }
1140
1141        public String getHead(Handler h) {
1142            return "head\n";
1143        }
1144    }
1145
1146    public static class MockLogSecurityManager extends SecurityManager {
1147        public void checkPermission(Permission perm) {
1148            if (perm instanceof LoggingPermission) {
1149                throw new SecurityException();
1150            }
1151            return;
1152        }
1153    }
1154
1155    public static class MockFileSecurityManager extends SecurityManager {
1156        public void checkPermission(Permission perm) {
1157            if (perm instanceof FilePermission) {
1158                throw new SecurityException();
1159            }
1160        }
1161    }
1162
1163    public static class MockFileHandler extends FileHandler {
1164        public MockFileHandler() throws IOException {
1165            super();
1166        }
1167
1168        public MockFileHandler(String pattern) throws IOException {
1169            super(pattern);
1170        }
1171
1172        public void publicSetOutputStream(OutputStream stream) {
1173            super.setOutputStream(stream);
1174        }
1175    }
1176}
1177