    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    *
    9    *      http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   */
    17
    18  package org.apache.log4j.pattern;
    19
    20  import java.lang.reflect.Method;
    21  import java.text.SimpleDateFormat;
    22  import java.util.ArrayList;
    23  import java.util.Date;
    24  import java.util.HashMap;
    25  import java.util.Iterator;
    26  import java.util.List;
    27  import java.util.Map;
    28  import java.util.TimeZone;
    29
    30  import junit.framework.TestCase;
    31
    32  import org.apache.log4j.Layout;
    33  import org.apache.log4j.Level;
    34  import org.apache.log4j.Logger;
    35  import org.apache.log4j.spi.LoggingEvent;
    36
    37
    38  /**
    39     Test case for PatternParser.java. Tests the various
    40     conversion patterns supported by PatternParser. This test
    41     class tests PatternParser via the EnhancedPatternLayout class which
    42     uses it.
    43   */
    44  public class PatternParserTest extends TestCase {
    45    private final Logger logger = Logger.getLogger("org.foobar");
    46    private final LoggingEvent event;
    47
    48    public PatternParserTest(String name) {
    49      super(name);
    50      event = new LoggingEvent("org.apache.log4j.Logger",
    51              logger, Level.INFO, "msg 1", null);
    52    }
    53
    54    private static String convert(
    55                   String pattern,
    56                   Map registry,
    57                   LoggingEvent event) {
    58      List converters = new ArrayList();
    59      List fields = new ArrayList();
    60      PatternParser.parse(pattern, converters, fields,
    61              registry,
    62              PatternParser.getPatternLayoutRules());
    63      assertEquals(converters.size(), fields.size());
    64
    65      StringBuffer buf = new StringBuffer();
    66      Iterator converterIter = converters.iterator();
    67      Iterator fieldIter = fields.iterator();
    68      while(converterIter.hasNext()) {
    69          int fieldStart = buf.length();
    70          ((PatternConverter) converterIter.next()).format(event, buf);
    71          ((FormattingInfo) fieldIter.next()).format(fieldStart, buf);
    72      }
    73      return buf.toString();
    74    }
    75
    76    public void testNewWord() throws Exception {
    77      HashMap ruleRegistry = new HashMap(5);
    78      ruleRegistry.put("z343", Num343PatternConverter.class.getName());
    79      String result = convert("%z343", ruleRegistry, event);
    80      assertEquals("343", result);
    81    }
    82
    83    /* Test whether words starting with the letter 'n' are treated differently,
    84     * which was previously the case by mistake.
    85     */
    86    public void testNewWord2() throws Exception {
    87      HashMap ruleRegistry = new HashMap(5);
    88      ruleRegistry.put("n343", Num343PatternConverter.class.getName());
    89      String result = convert("%n343", ruleRegistry, event);
    90      assertEquals("343", result);
    91    }
    92
    93    public void testBogusWord1() throws Exception {
    94      String result = convert("%, foobar", null, event);
    95      assertEquals("%, foobar", result);
    96    }
    97
    98    public void testBogusWord2() throws Exception {
    99      String result = convert("xyz %, foobar", null, event);
    100     assertEquals("xyz %, foobar", result);
    101   }
    102
    103   public void testBasic1() throws Exception {
    104     String result = convert("hello %-5level - %m%n", null, event);
    105     assertEquals("hello INFO  - msg 1" + Layout.LINE_SEP, result);
    106   }
    107
    108   public void testBasic2() throws Exception {
    109     String result = convert("%relative %-5level [%thread] %logger - %m%n", null, event);
    110
    111     long expectedRelativeTime = event.timeStamp - LoggingEvent.getStartTime();
    112     assertEquals(expectedRelativeTime + " INFO  [main] "+logger.getName()+" - msg 1" + Layout.LINE_SEP, result);
    113   }
    114
    115   public void testMultiOption() throws Exception {
    116     String result = convert("%d{HH:mm:ss}{GMT} %d{HH:mm:ss} %c  - %m", null, event);
    117
    118     SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
    119     String localTime = dateFormat.format(new Date(event.timeStamp));
    120     dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
    121     String utcTime = dateFormat.format(new Date(event.timeStamp));
    122     StringBuffer buf = new StringBuffer(utcTime);
    123     buf.append(' ');
    124     buf.append(localTime);
    125     buf.append(" org.foobar  - msg 1");
    126     assertEquals(buf.toString(), result);
    127   }
    128
    129   public void testBogus() throws Exception {
    130       String result = convert("%bogus", null, event);
    131       assertEquals("%bogus", result);
    132     }
    133
    134   public void testMore() throws Exception {
    135         String result = convert("%more", null, event);
    136         assertEquals("msg 1ore", result);
    137   }
    138
    139     /**
    140      * Options with missing close braces will be treated as a literal.
    141      * Endless looped with earlier code.
    142      *
    143      */
    144     public void testMalformedOption() {
    145         String result = convert("foo%m{yyyy.MM.dd", null, event);
    146         assertEquals("foomsg 1{yyyy.MM.dd", result);
    147     }
    148
    149
    150   private void assertFactories(Map rules) throws Exception {
    151       assertTrue(rules.size() > 0);
    152       Iterator iter = rules.values().iterator();
    153       Class[] factorySig = new Class[] { Class.forName("[Ljava.lang.String;") };
    154       Object[] factoryArg = new Object[] { null };
    155       while(iter.hasNext()) {
    156           Class ruleClass = (Class) iter.next();
    157           Method factory =  ruleClass.getMethod("newInstance", factorySig);
    158           Object converter = factory.invoke(null, factoryArg);
    159           assertTrue(converter != null);
    160       }
    161   }
    162
    163   public void testPatternLayoutFactories() throws Exception {
    164       assertFactories(PatternParser.getPatternLayoutRules());
    165   }
    166
    167   public void testFileNamePatternFactories() throws Exception {
    168         assertFactories(PatternParser.getFileNamePatternRules());
    169   }
    170
    171 }