MemoryHandlerTest.java revision f6c387128427e121477c1b32ad35cdcaa5101ba3
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.TestTargets;
21import dalvik.annotation.TestLevel;
22import dalvik.annotation.TestTargetNew;
23import dalvik.annotation.TestTargetClass;
24
25import java.io.IOException;
26import java.io.OutputStream;
27import java.io.PrintStream;
28import java.io.StringWriter;
29import java.security.Permission;
30import java.util.Properties;
31import java.util.ResourceBundle;
32import java.util.logging.Filter;
33import java.util.logging.Formatter;
34import java.util.logging.Handler;
35import java.util.logging.Level;
36import java.util.logging.LogManager;
37import java.util.logging.LogRecord;
38import java.util.logging.LoggingPermission;
39import java.util.logging.MemoryHandler;
40import java.util.logging.SimpleFormatter;
41
42import junit.framework.TestCase;
43
44import org.apache.harmony.logging.tests.java.util.logging.HandlerTest.NullOutputStream;
45import org.apache.harmony.logging.tests.java.util.logging.util.EnvironmentHelper;
46
47/**
48 *
49 */
50@TestTargetClass(MemoryHandler.class)
51public class MemoryHandlerTest extends TestCase {
52
53    final static LogManager manager = LogManager.getLogManager();
54
55    final static Properties props = new Properties();
56
57    final static String baseClassName = MemoryHandlerTest.class.getName();
58
59    final static StringWriter writer = new StringWriter();
60
61    final static SecurityManager securityManager = new MockSecurityManager();
62
63    private final PrintStream err = System.err;
64
65    private OutputStream errSubstituteStream = null;
66
67    MemoryHandler handler;
68
69    Handler target = new MockHandler();
70
71    /*
72     * @see TestCase#setUp()
73     */
74    protected void setUp() throws Exception {
75        super.setUp();
76        manager.reset();
77        initProps();
78        manager.readConfiguration(EnvironmentHelper
79                .PropertiesToInputStream(props));
80        handler = new MemoryHandler();
81        errSubstituteStream = new NullOutputStream();
82        System.setErr(new PrintStream(errSubstituteStream));
83    }
84
85    /**
86     *
87     */
88    private void initProps() {
89        props.put("java.util.logging.MemoryHandler.level", "FINE");
90        props.put("java.util.logging.MemoryHandler.filter", baseClassName
91                + "$MockFilter");
92        props.put("java.util.logging.MemoryHandler.size", "2");
93        props.put("java.util.logging.MemoryHandler.push", "WARNING");
94        props.put("java.util.logging.MemoryHandler.target", baseClassName
95                + "$MockHandler");
96        props.put("java.util.logging.MemoryHandler.formatter", baseClassName
97                + "$MockFormatter");
98    }
99
100    /*
101     * @see TestCase#tearDown()
102     */
103    protected void tearDown() throws Exception {
104        super.tearDown();
105        manager.readConfiguration();
106        props.clear();
107        System.setErr(err);
108    }
109
110    @TestTargets({
111        @TestTargetNew(
112            level = TestLevel.COMPLETE,
113            notes = "SecurityException",
114            method = "close",
115            args = {}
116        ),
117        @TestTargetNew(
118            level = TestLevel.COMPLETE,
119            notes = "SecurityException",
120            method = "setPushLevel",
121            args = {java.util.logging.Level.class}
122        ),
123        @TestTargetNew(
124            level = TestLevel.COMPLETE,
125            notes = "SecurityException",
126            method = "flush",
127            args = {}
128        ),
129        @TestTargetNew(
130            level = TestLevel.COMPLETE,
131            notes = "SecurityException",
132            method = "push",
133            args = {}
134        ),
135        @TestTargetNew(
136            level = TestLevel.COMPLETE,
137            notes = "SecurityException",
138            method = "getPushLevel",
139            args = {}
140        ),
141        @TestTargetNew(
142            level = TestLevel.COMPLETE,
143            notes = "SecurityException",
144            method = "isLoggable",
145            args = {java.util.logging.LogRecord.class}
146        ),
147        @TestTargetNew(
148            level = TestLevel.COMPLETE,
149            notes = "SecurityException",
150            method = "publish",
151            args = {java.util.logging.LogRecord.class}
152        )
153    })
154    public void testGlobalSecurity() {
155        SecurityManager currentManager = System.getSecurityManager();
156        System.setSecurityManager(securityManager);
157        try {
158            try {
159                handler.close();
160                fail("should throw security exception");
161            } catch (SecurityException e) {
162            }
163            try {
164                handler.setPushLevel(Level.CONFIG);
165                fail("should throw security exception");
166            } catch (SecurityException e) {
167            }
168            handler.flush();
169            handler.push();
170            handler.getPushLevel();
171            handler.isLoggable(new LogRecord(Level.ALL, "message"));
172            handler.publish(new LogRecord(Level.ALL, "message"));
173        } finally {
174            System.setSecurityManager(currentManager);
175        }
176
177    }
178
179    @TestTargetNew(
180        level = TestLevel.PARTIAL_COMPLETE,
181        notes = "",
182        method = "close",
183        args = {}
184    )
185    public void testClose() {
186        Filter filter = handler.getFilter();
187        Formatter formatter = handler.getFormatter();
188        writer.getBuffer().setLength(0);
189        handler.close();
190        assertEquals(writer.toString(), "close");
191        assertEquals(handler.getFilter(), filter);
192        assertEquals(handler.getFormatter(), formatter);
193        assertNull(handler.getEncoding());
194        assertNotNull(handler.getErrorManager());
195        assertEquals(handler.getLevel(), Level.OFF);
196        assertEquals(handler.getPushLevel(), Level.WARNING);
197        assertFalse(handler.isLoggable(new LogRecord(Level.SEVERE, "test")));
198    }
199
200    @TestTargetNew(
201        level = TestLevel.PARTIAL_COMPLETE,
202        notes = "",
203        method = "flush",
204        args = {}
205    )
206    public void testFlush() {
207        Filter filter = handler.getFilter();
208        Formatter formatter = handler.getFormatter();
209        writer.getBuffer().setLength(0);
210        handler.flush();
211        assertEquals(writer.toString(), "flush");
212        assertEquals(handler.getFilter(), filter);
213        assertEquals(handler.getFormatter(), formatter);
214        assertNull(handler.getEncoding());
215        assertNotNull(handler.getErrorManager());
216        assertEquals(handler.getLevel(), Level.FINE);
217        assertEquals(handler.getPushLevel(), Level.WARNING);
218        assertTrue(handler.isLoggable(new LogRecord(Level.SEVERE, "test")));
219    }
220
221    @TestTargetNew(
222        level = TestLevel.COMPLETE,
223        notes = "",
224        method = "isLoggable",
225        args = {java.util.logging.LogRecord.class}
226    )
227    public void testIsLoggable() {
228        try {
229            handler.isLoggable(null);
230            fail("should throw NullPointerException");
231        } catch (NullPointerException e) {
232            // expected
233        }
234        LogRecord record = new LogRecord(Level.FINER, "MSG1");
235        assertFalse(handler.isLoggable(record));
236
237
238        record = new LogRecord(Level.FINE, "MSG2");
239        assertTrue(handler.isLoggable(record));
240        assertTrue(handler.isLoggable(new LogRecord(Level.INFO, "1")));
241        assertTrue(handler.isLoggable(new LogRecord(Level.WARNING, "2")));
242        assertTrue(handler.isLoggable(new LogRecord(Level.SEVERE, "3")));
243
244        record = new LogRecord(Level.CONFIG, "MSG3");
245        assertTrue(handler.isLoggable(record));
246
247        record = new LogRecord(Level.CONFIG, "false");
248        assertFalse(handler.isLoggable(record));
249
250        handler.setFilter(null);
251        record = new LogRecord(Level.CONFIG, "false");
252        assertTrue(handler.isLoggable(record));
253    }
254
255    /*
256     * Class under test for void MemoryHandler()
257     */
258    @TestTargetNew(
259        level = TestLevel.PARTIAL,
260        notes = "check errors",
261        method = "MemoryHandler",
262        args = {}
263    )
264    public void testMemoryHandler() throws IOException {
265        assertNotNull("Filter should not be null", handler.getFilter());
266        assertNotNull("Formatter should not be null", handler.getFormatter());
267        assertNull("character encoding should be null", handler.getEncoding());
268        assertNotNull("ErrorManager should not be null", handler
269                .getErrorManager());
270        assertEquals("Level should be FINE", Level.FINE, handler.getLevel());
271        assertEquals("Level should be WARNING", Level.WARNING, handler
272                .getPushLevel());
273
274        props.clear();
275        props.put("java.util.logging.MemoryHandler.target", baseClassName
276                + "$MockHandler");
277
278        manager.readConfiguration(EnvironmentHelper
279                .PropertiesToInputStream(props));
280        handler = new MemoryHandler();
281        assertNull(handler.getFilter());
282        assertTrue(handler.getFormatter() instanceof SimpleFormatter);
283        assertNull(handler.getEncoding());
284        assertNotNull(handler.getErrorManager());
285        assertEquals(handler.getLevel(), Level.ALL);
286        assertEquals(handler.getPushLevel(), Level.SEVERE);
287
288    }
289
290    @TestTargetNew(
291        level = TestLevel.COMPLETE,
292        notes = "",
293        method = "MemoryHandler",
294        args = {}
295    )
296    public void testMemoryHandlerInvalidProps() throws IOException {
297        // null target
298        try {
299            props.remove("java.util.logging.MemoryHandler.target");
300            manager.readConfiguration(EnvironmentHelper
301                    .PropertiesToInputStream(props));
302            handler = new MemoryHandler();
303            fail("should throw RuntimeException: target must be set");
304        } catch (RuntimeException e) {
305        }
306
307        // invalid target
308        try {
309            props.put("java.util.logging.MemoryHandler.target", "badname");
310            manager.readConfiguration(EnvironmentHelper
311                    .PropertiesToInputStream(props));
312            handler = new MemoryHandler();
313            fail("should throw RuntimeException: target must be valid");
314        } catch (RuntimeException e) {
315        }
316
317        // invalid formatter
318        initProps();
319        props.put("java.util.logging.MemoryHandler.formatter", "badname");
320        manager.readConfiguration(EnvironmentHelper
321                .PropertiesToInputStream(props));
322        handler = new MemoryHandler();
323        assertTrue(handler.getFormatter() instanceof SimpleFormatter);
324
325        // invalid level
326        initProps();
327        props.put("java.util.logging.MemoryHandler.level", "badname");
328        manager.readConfiguration(EnvironmentHelper
329                .PropertiesToInputStream(props));
330        handler = new MemoryHandler();
331        assertEquals(handler.getLevel(), Level.ALL);
332
333        // invalid pushlevel
334        initProps();
335        props.put("java.util.logging.MemoryHandler.push", "badname");
336        manager.readConfiguration(EnvironmentHelper
337                .PropertiesToInputStream(props));
338        handler = new MemoryHandler();
339        assertEquals(handler.getPushLevel(), Level.SEVERE);
340
341        // invalid filter
342        initProps();
343        props.put("java.util.logging.MemoryHandler.filter", "badname");
344        manager.readConfiguration(EnvironmentHelper
345                .PropertiesToInputStream(props));
346        handler = new MemoryHandler();
347        assertNull(handler.getFilter());
348
349        // invalid size
350        initProps();
351        props.put("java.util.logging.MemoryHandler.size", "-1");
352        manager.readConfiguration(EnvironmentHelper
353                .PropertiesToInputStream(props));
354        handler = new MemoryHandler();
355        initProps();
356        props.put("java.util.logging.MemoryHandler.size", "badsize");
357        manager.readConfiguration(EnvironmentHelper
358                .PropertiesToInputStream(props));
359        handler = new MemoryHandler();
360
361    }
362
363    @TestTargetNew(
364        level = TestLevel.COMPLETE,
365        notes = "",
366        method = "MemoryHandler",
367        args = {}
368    )
369    public void testMemoryHandlerDefaultValue() throws SecurityException,
370            IOException {
371        props.clear();
372        props.put("java.util.logging.MemoryHandler.target", baseClassName
373                + "$MockHandler");
374
375        manager.readConfiguration(EnvironmentHelper
376                .PropertiesToInputStream(props));
377        handler = new MemoryHandler();
378        assertNull(handler.getFilter());
379        assertTrue(handler.getFormatter() instanceof SimpleFormatter);
380        assertNull(handler.getEncoding());
381        assertNotNull(handler.getErrorManager());
382        assertEquals(handler.getLevel(), Level.ALL);
383        assertEquals(handler.getPushLevel(), Level.SEVERE);
384    }
385
386    /*
387     * Class under test for void MemoryHandler(Handler, int, Level)
388     */
389    @TestTargetNew(
390        level = TestLevel.COMPLETE,
391        notes = "",
392        method = "MemoryHandler",
393        args = {java.util.logging.Handler.class, int.class, java.util.logging.Level.class}
394    )
395    public void testMemoryHandlerHandlerintLevel() {
396        handler = new MemoryHandler(target, 2, Level.FINEST);
397        assertNotNull("Filter should not be null", handler.getFilter());
398        assertNotNull("Formatter should not be null", handler.getFormatter());
399        assertNull("character encoding should be null", handler.getEncoding());
400        assertNotNull("ErrorManager should not be null", handler
401                .getErrorManager());
402        assertEquals("Level should be FINE", Level.FINE, handler.getLevel());
403        assertEquals("Level should be FINEST", Level.FINEST, handler
404                .getPushLevel());
405
406        try {
407            new MemoryHandler(null, 2, Level.FINEST);
408            fail("should throw NullPointerException");
409        } catch (NullPointerException e) {
410        }
411        try {
412            new MemoryHandler(target, 2, null);
413            fail("should throw NullPointerException");
414        } catch (NullPointerException e) {
415        }
416        try {
417            new MemoryHandler(target, 0, Level.FINEST);
418            fail("should throw IllegalArgumentException");
419        } catch (IllegalArgumentException e) {
420        }
421        try {
422            new MemoryHandler(target, -1, Level.FINEST);
423            fail("should throw IllegalArgumentException");
424        } catch (IllegalArgumentException e) {
425        }
426
427    }
428
429    @TestTargetNew(
430        level = TestLevel.COMPLETE,
431        notes = "",
432        method = "getPushLevel",
433        args = {}
434    )
435    public void testGetPushLevel() {
436        try {
437            handler.setPushLevel(null);
438            fail("should throw NullPointerException");
439        } catch (NullPointerException e) {
440        }
441        handler.setPushLevel(Level.parse("123"));
442        assertEquals(handler.getPushLevel(), Level.parse("123"));
443    }
444
445    @TestTargetNew(
446        level = TestLevel.COMPLETE,
447        notes = "",
448        method = "setPushLevel",
449        args = {java.util.logging.Level.class}
450    )
451    public void testSetPushLevel() {
452        // change push level don't trigger push action
453        writer.getBuffer().setLength(0);
454        LogRecord lr = new LogRecord(Level.CONFIG, "lr");
455        assertTrue(handler.isLoggable(lr));
456        handler.publish(lr);
457        assertEquals(writer.toString(), "");
458        writer.getBuffer().setLength(0);
459        handler.setPushLevel(Level.FINE);
460        assertEquals(writer.toString(), "");
461        handler.publish(lr);
462        assertEquals(writer.toString(), lr.getMessage() + lr.getMessage());
463    }
464
465    @TestTargetNew(
466        level = TestLevel.COMPLETE,
467        notes = "",
468        method = "push",
469        args = {}
470    )
471    public void testPushPublic() {
472        writer.getBuffer().setLength(0);
473        // loggable but don't trig push
474        handler.publish(new LogRecord(Level.CONFIG, "MSG1"));
475        assertEquals("", writer.toString());
476        // trig push
477        handler.publish(new LogRecord(Level.SEVERE, "MSG2"));
478        assertEquals(writer.toString(), "MSG1MSG2");
479        writer.getBuffer().setLength(0);
480
481        // regression test for Harmony-1292
482        handler.publish(new LogRecord(Level.WARNING, "MSG"));
483        assertEquals("MSG",writer.toString());
484
485        writer.getBuffer().setLength(0);
486        // push nothing
487        handler.push();
488        assertEquals("", writer.toString());
489        // loggable but not push
490        handler.publish(new LogRecord(Level.CONFIG, "MSG3"));
491        assertEquals("", writer.toString());
492        // not loggable
493        handler.publish(new LogRecord(Level.FINEST, "MSG4"));
494        assertEquals("", writer.toString());
495        // loggable but not push
496        handler.publish(new LogRecord(Level.CONFIG, "MSG5"));
497        assertEquals("", writer.toString());
498        // not loggable
499        handler.publish(new LogRecord(Level.FINER, "MSG6"));
500        assertEquals("", writer.toString());
501        // not loggable
502        handler.publish(new LogRecord(Level.FINER, "false"));
503        assertEquals("", writer.toString());
504        // loggable but not push
505        handler.publish(new LogRecord(Level.CONFIG, "MSG8"));
506        assertEquals("", writer.toString());
507        // push all
508        handler.push();
509        assertEquals(writer.toString(), "MSG5MSG8");
510        writer.getBuffer().setLength(0);
511        handler.push();
512        assertEquals("", writer.toString());
513    }
514
515    /*
516     * mock classes
517     */
518    public static class MockFilter implements Filter {
519        public boolean isLoggable(LogRecord record) {
520            return !record.getMessage().equals("false");
521        }
522    }
523
524    public static class MockHandler extends Handler {
525        public void close() {
526            writer.write("close");
527        }
528
529        public void flush() {
530            writer.write("flush");
531        }
532
533        public void publish(LogRecord record) {
534            writer.write(record.getMessage());
535        }
536
537    }
538
539    public static class MockFormatter extends Formatter {
540        public String format(LogRecord r) {
541            return r.getMessage();
542        }
543    }
544
545    public static class MockSecurityManager extends SecurityManager {
546        public void checkPermission(Permission perm) {
547            if (perm instanceof LoggingPermission) {
548                throw new SecurityException();
549            }
550            return;
551        }
552    }
553
554}
555