    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  package org.apache.log4j;
    18
    19  import junit.framework.TestCase;
    20
    21  import java.io.File;
    22  import java.io.FileOutputStream;
    23  import java.io.FileWriter;
    24  import java.io.IOException;
    25  import java.net.URL;
    26  import java.util.Properties;
    27  import java.util.zip.ZipEntry;
    28  import java.util.zip.ZipOutputStream;
    29
    30  import org.apache.log4j.spi.OptionHandler;
    31  import org.apache.log4j.spi.Filter;
    32  import org.apache.log4j.spi.LoggingEvent;
    33  import org.apache.log4j.spi.ThrowableRenderer;
    34  import org.apache.log4j.spi.ThrowableRendererSupport;
    35  import org.apache.log4j.varia.LevelRangeFilter;
    36
    37  /**
    38   * Test property configurator.
    39   *
    40   */
    41  public class PropertyConfiguratorTest extends TestCase {
    42      public PropertyConfiguratorTest(final String testName) {
    43          super(testName);
    44      }
    45
    46      /**
    47       * Test for bug 40944.
    48       * Did not catch IllegalArgumentException on Properties.load
    49       * and close input stream.
    50       * @throws IOException if IOException creating properties file.
    51       */
    52      public void testBadUnicodeEscape() throws IOException {
    53          String fileName = "output/badescape.properties";
    54          FileWriter writer = new FileWriter(fileName);
    55          writer.write("log4j.rootLogger=\\uXX41");
    56          writer.close();
    57          PropertyConfigurator.configure(fileName);
    58          File file = new File(fileName);
    59          assertTrue(file.delete()) ;
    60          assertFalse(file.exists());
    61      }
    62
    63      /**
    64       * Test for bug 40944.
    65       * configure(URL) never closed opened stream.
    66       * @throws IOException if IOException creating properties file.
    67       */
    68          public void testURL() throws IOException {
    69          File file = new File("output/unclosed.properties");
    70          FileWriter writer = new FileWriter(file);
    71          writer.write("log4j.rootLogger=debug");
    72          writer.close();
    73          URL url = file.toURL();
    74          PropertyConfigurator.configure(url);
    75          assertTrue(file.delete());
    76          assertFalse(file.exists());
    77      }
    78
    79      /**
    80       * Test for bug 40944.
    81       * configure(URL) did not catch IllegalArgumentException and
    82       * did not close stream.
    83       * @throws IOException if IOException creating properties file.
    84       */
    85          public void testURLBadEscape() throws IOException {
    86          File file = new File("output/urlbadescape.properties");
    87          FileWriter writer = new FileWriter(file);
    88          writer.write("log4j.rootLogger=\\uXX41");
    89          writer.close();
    90          URL url = file.toURL();
    91          PropertyConfigurator.configure(url);
    92          assertTrue(file.delete());
    93          assertFalse(file.exists());
    94      }
    95
    96      /**
    97       * Test for bug 47465.
    98       * configure(URL) did not close opened JarURLConnection.
    99       * @throws IOException if IOException creating properties jar.
    100      */
    101     public void testJarURL() throws IOException {
    102         File dir = new File("output");
    103         dir.mkdirs();
    104         File file = new File("output/properties.jar");
    105         ZipOutputStream zos =
    106             new ZipOutputStream(new FileOutputStream(file));
    107         zos.putNextEntry(new ZipEntry(LogManager.DEFAULT_CONFIGURATION_FILE));
    108         zos.write("log4j.rootLogger=debug".getBytes());
    109         zos.closeEntry();
    110         zos.close();
    111         URL url = new URL("jar:" + file.toURL() + "!/" +
    112                 LogManager.DEFAULT_CONFIGURATION_FILE);
    113         PropertyConfigurator.configure(url);
    114         assertTrue(file.delete());
    115         assertFalse(file.exists());
    116     }
    117
    118     /**
    119      * Test processing of log4j.reset property, see bug 17531.
    120      *
    121      */
    122     public void testReset() {
    123         VectorAppender appender = new VectorAppender();
    124         appender.setName("A1");
    125         Logger.getRootLogger().addAppender(appender);
    126         Properties props = new Properties();
    127         props.put("log4j.reset", "true");
    128         PropertyConfigurator.configure(props);
    129         assertNull(Logger.getRootLogger().getAppender("A1"));
    130         LogManager.resetConfiguration();
    131     }
    132
    133
    134     /**
    135      * Mock definition of org.apache.log4j.rolling.RollingPolicy
    136      * from extras companion.
    137      */
    138     public static class RollingPolicy implements OptionHandler {
    139         private boolean activated = false;
    140
    141         public RollingPolicy() {
    142
    143         }
    144         public void activateOptions() {
    145             activated = true;
    146         }
    147
    148         public final boolean isActivated() {
    149             return activated;
    150         }
    151
    152     }
    153
    154     /**
    155      * Mock definition of FixedWindowRollingPolicy from extras companion.
    156      */
    157     public static final class FixedWindowRollingPolicy extends RollingPolicy {
    158         private String activeFileName;
    159         private String fileNamePattern;
    160         private int minIndex;
    161
    162         public FixedWindowRollingPolicy() {
    163             minIndex = -1;
    164         }
    165
    166         public String getActiveFileName() {
    167             return activeFileName;
    168         }
    169         public void setActiveFileName(final String val) {
    170             activeFileName = val;
    171         }
    172
    173         public String getFileNamePattern() {
    174             return fileNamePattern;
    175         }
    176         public void setFileNamePattern(final String val) {
    177             fileNamePattern = val;
    178         }
    179
    180         public int getMinIndex() {
    181             return minIndex;
    182         }
    183
    184         public void setMinIndex(final int val) {
    185             minIndex = val;
    186         }
    187     }
    188
    189     /**
    190      * Mock definition of TriggeringPolicy from extras companion.
    191      */
    192     public static class TriggeringPolicy implements OptionHandler {
    193         private boolean activated = false;
    194
    195         public TriggeringPolicy() {
    196
    197         }
    198         public void activateOptions() {
    199             activated = true;
    200         }
    201
    202         public final boolean isActivated() {
    203             return activated;
    204         }
    205
    206     }
    207
    208     /**
    209      * Mock definition of FilterBasedTriggeringPolicy from extras companion.
    210      */
    211     public static final class FilterBasedTriggeringPolicy extends TriggeringPolicy {
    212         private Filter filter;
    213         public FilterBasedTriggeringPolicy() {
    214         }
    215
    216         public void setFilter(final Filter val) {
    217              filter = val;
    218         }
    219
    220         public Filter getFilter() {
    221             return filter;
    222
    223         }
    224     }
    225
    226     /**
    227      * Mock definition of org.apache.log4j.rolling.RollingFileAppender
    228      * from extras companion.
    229      */
    230     public static final class RollingFileAppender extends AppenderSkeleton {
    231         private RollingPolicy rollingPolicy;
    232         private TriggeringPolicy triggeringPolicy;
    233         private boolean append;
    234
    235         public RollingFileAppender() {
    236
    237         }
    238
    239         public RollingPolicy getRollingPolicy() {
    240             return rollingPolicy;
    241         }
    242
    243         public void setRollingPolicy(final RollingPolicy policy) {
    244             rollingPolicy = policy;
    245         }
    246
    247         public TriggeringPolicy getTriggeringPolicy() {
    248             return triggeringPolicy;
    249         }
    250
    251         public void setTriggeringPolicy(final TriggeringPolicy policy) {
    252             triggeringPolicy = policy;
    253         }
    254
    255         public boolean getAppend() {
    256             return append;
    257         }
    258
    259         public void setAppend(boolean val) {
    260             append = val;
    261         }
    262
    263         public void close() {
    264
    265         }
    266
    267         public boolean requiresLayout() {
    268             return true;
    269         }
    270
    271         public void append(final LoggingEvent event) {
    272
    273         }
    274     }
    275
    276     /**
    277      * Test processing of nested objects, see bug 36384.
    278      *
    279      */
    280     public void testNested() {
    281         PropertyConfigurator.configure("input/filter1.properties");
    282         RollingFileAppender rfa = (RollingFileAppender)
    283                 Logger.getLogger("org.apache.log4j.PropertyConfiguratorTest")
    284                    .getAppender("ROLLING");
    285         FixedWindowRollingPolicy rollingPolicy = (FixedWindowRollingPolicy) rfa.getRollingPolicy();
    286         assertEquals("filterBase-test1.log", rollingPolicy.getActiveFileName());
    287         assertEquals("filterBased-test1.%i", rollingPolicy.getFileNamePattern());
    288         assertEquals(0, rollingPolicy.getMinIndex());
    289         assertTrue(rollingPolicy.isActivated());
    290         FilterBasedTriggeringPolicy triggeringPolicy =
    291                 (FilterBasedTriggeringPolicy) rfa.getTriggeringPolicy();
    292         LevelRangeFilter filter = (LevelRangeFilter) triggeringPolicy.getFilter();
    293         assertTrue(Level.INFO.equals(filter.getLevelMin()));
    294         LogManager.resetConfiguration();
    295     }
    296
    297
    298     /**
    299      * Mock ThrowableRenderer for testThrowableRenderer.  See bug 45721.
    300      */
    301     public static class MockThrowableRenderer implements ThrowableRenderer, OptionHandler {
    302         private boolean activated = false;
    303         private boolean showVersion = true;
    304
    305         public MockThrowableRenderer() {
    306         }
    307
    308         public void activateOptions() {
    309             activated = true;
    310         }
    311
    312         public boolean isActivated() {
    313             return activated;
    314         }
    315
    316         public String[] doRender(final Throwable t) {
    317             return new String[0];
    318         }
    319
    320         public void setShowVersion(boolean v) {
    321             showVersion = v;
    322         }
    323
    324         public boolean getShowVersion() {
    325             return showVersion;
    326         }
    327     }
    328
    329     /**
    330      * Test of log4j.throwableRenderer support.  See bug 45721.
    331      */
    332     public void testThrowableRenderer() {
    333         Properties props = new Properties();
    334         props.put("log4j.throwableRenderer", "org.apache.log4j.PropertyConfiguratorTest$MockThrowableRenderer");
    335         props.put("log4j.throwableRenderer.showVersion", "false");
    336         PropertyConfigurator.configure(props);
    337         ThrowableRendererSupport repo = (ThrowableRendererSupport) LogManager.getLoggerRepository();
    338         MockThrowableRenderer renderer = (MockThrowableRenderer) repo.getThrowableRenderer();
    339         LogManager.resetConfiguration();
    340         assertNotNull(renderer);
    341         assertEquals(true, renderer.isActivated());
    342         assertEquals(false, renderer.getShowVersion());
    343     }
    344 }