    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;
    19
    20
    21  import org.apache.log4j.Level;
    22  import org.apache.log4j.Logger;
    23  import java.util.Random;
    24
    25  /*
    26    Stress test the Logger class.
    27
    28  */
    29
    30  class StressCategory {
    31
    32    static Level[] level = new Level[] {Level.DEBUG,
    33  				      Level.INFO,
    34  				      Level.WARN,
    35  				      Level.ERROR,
    36  				      Level.FATAL};
    37
    38    static Level defaultLevel = Logger.getRootLogger().getLevel();
    39
    40    static int LENGTH;
    41    static String[] names;
    42    static Logger[] cat;
    43    static CT[] ct;
    44
    45    static Random random = new Random(10);
    46
    47    public static void main(String[] args) {
    48
    49      LENGTH = args.length;
    50
    51      if(LENGTH == 0) {
    52        System.err.println( "Usage: java " + StressCategory.class.getName() +
    53  			  " name1 ... nameN\n.");
    54        System.exit(1);
    55      }
    56      if(LENGTH >= 7) {
    57        System.err.println(
    58          "This stress test suffers from combinatorial explosion.\n"+
    59          "Invoking with seven arguments takes about 90 minutes even on fast machines");
    60      }
    61
    62      names = new String[LENGTH];
    63      for(int i=0; i < LENGTH; i++) {
    64        names[i] = args[i];
    65      }
    66      cat = new Logger[LENGTH];
    67      ct = new CT[LENGTH];
    68
    69
    70      permute(0);
    71
    72      // If did not exit, then passed all tests.
    73    }
    74
    75    // Loop through all permutations of names[].
    76    // On each possible permutation call createLoop
    77    static
    78    void permute(int n) {
    79      if(n == LENGTH)
    80        createLoop(0);
    81      else
    82        for(int i = n; i < LENGTH; i++) {
    83  	swap(names, n, i);
    84  	permute(n+1);
    85  	swap(names, n, i);
    86        }
    87    }
    88
    89    static
    90    void swap(String[] names, int i, int j) {
    91      String t = names[i];
    92      names[i] = names[j];
    93      names[j] = t;
    94    }
    95
    96    public
    97    static
    98    void permutationDump() {
    99      System.out.print("Current permutation is - ");
    100     for(int i = 0; i < LENGTH; i++) {
    101       System.out.print(names[i] + " ");
    102     }
    103     System.out.println();
    104   }
    105
    106
    107   // Loop through all possible 3^n combinations of not instantiating,
    108   // instantiating and setting/not setting a level.
    109
    110   static
    111   void createLoop(int n) {
    112     if(n == LENGTH) {
    113       //System.out.println("..............Creating cat[]...........");
    114       for(int i = 0; i < LENGTH; i++) {
    115 	if(ct[i] == null)
    116 	  cat[i] = null;
    117 	else {
    118 	  cat[i] = Logger.getLogger(ct[i].catstr);
    119 	  cat[i].setLevel(ct[i].level);
    120 	}
    121       }
    122       test();
    123       // Clear hash table for next round
    124       Hierarchy h = (Hierarchy) LogManager.getLoggerRepository();
    125       h.clear();
    126     }
    127     else {
    128       ct[n]  = null;
    129       createLoop(n+1);
    130
    131       ct[n]  = new CT(names[n], null);
    132       createLoop(n+1);
    133
    134       int r = random.nextInt(); if(r < 0) r = -r;
    135       ct[n]  = new CT(names[n], level[r%5]);
    136       createLoop(n+1);
    137     }
    138   }
    139
    140
    141   static
    142   void test() {
    143     //System.out.println("++++++++++++TEST called+++++++++++++");
    144     //permutationDump();
    145     //catDump();
    146
    147     for(int i = 0; i < LENGTH; i++) {
    148       if(!checkCorrectness(i)) {
    149 	System.out.println("Failed stress test.");
    150 	permutationDump();
    151
    152 	//Hierarchy._default.fullDump();
    153 	ctDump();
    154 	catDump();
    155 	System.exit(1);
    156       }
    157     }
    158   }
    159
    160   static
    161   void ctDump() {
    162     for(int j = 0; j < LENGTH; j++) {
    163        if(ct[j] != null)
    164 	    System.out.println("ct [" + j + "] = ("+ct[j].catstr+"," +
    165 			       ct[j].level + ")");
    166        else
    167 	 System.out.println("ct [" + j + "] = undefined");
    168     }
    169   }
    170
    171   static
    172   void catDump() {
    173     for(int j = 0; j < LENGTH; j++) {
    174       if(cat[j] != null)
    175 	System.out.println("cat[" + j + "] = (" + cat[j].name + "," +
    176 			   cat[j].getLevel() + ")");
    177       else
    178 	System.out.println("cat[" + j + "] = undefined");
    179     }
    180   }
    181
    182   //  static
    183   //void provisionNodesDump() {
    184   //for (Enumeration e = CategoryFactory.ht.keys(); e.hasMoreElements() ;) {
    185   //  CategoryKey key = (CategoryKey) e.nextElement();
    186   //  Object c = CategoryFactory.ht.get(key);
    187   //  if(c instanceof  ProvisionNode)
    188   //((ProvisionNode) c).dump(key.name);
    189   //}
    190   //}
    191
    192   static
    193   boolean checkCorrectness(int i) {
    194     CT localCT = ct[i];
    195
    196     // Can't perform test if logger is not instantiated
    197     if(localCT == null)
    198       return true;
    199
    200     // find expected level
    201     Level expected = getExpectedPrioriy(localCT);
    202
    203
    204     Level purported = cat[i].getEffectiveLevel();
    205
    206     if(expected != purported) {
    207       System.out.println("Expected level for " + localCT.catstr + " is " +
    208 		       expected);
    209       System.out.println("Purported level for "+ cat[i].name + " is "+purported);
    210       return false;
    211     }
    212     return true;
    213
    214   }
    215
    216   static
    217   Level getExpectedPrioriy(CT ctParam) {
    218     Level level = ctParam.level;
    219     if(level != null)
    220       return level;
    221
    222
    223     String catstr = ctParam.catstr;
    224
    225     for(int i = catstr.lastIndexOf('.', catstr.length()-1); i >= 0;
    226 	                              i = catstr.lastIndexOf('.', i-1))  {
    227       String substr = catstr.substring(0, i);
    228
    229       // find the level of ct corresponding to substr
    230       for(int j = 0; j < LENGTH; j++) {
    231 	if(ct[j] != null && substr.equals(ct[j].catstr)) {
    232 	  Level p = ct[j].level;
    233 	  if(p != null)
    234 	    return p;
    235 	}
    236       }
    237     }
    238     return defaultLevel;
    239   }
    240
    241
    242
    243   static class CT {
    244     public String   catstr;
    245     public Level level;
    246
    247     CT(String catstr,  Level level) {
    248       this.catstr = catstr;
    249       this.level = level;
    250     }
    251   }
    252 }