StressCategory.java
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import java.util.Random;
/*
Stress test the Logger class.
*/
class StressCategory {
static Level[] level = new Level[] { Level.DEBUG, Level.INFO, Level.WARN, Level.ERROR, Level.FATAL };
static Level defaultLevel = Logger.getRootLogger().getLevel();
static int LENGTH;
static String[] names;
static Logger[] cat;
static CT[] ct;
static Random random = new Random(10);
public static void main(String[] args) {
LENGTH = args.length;
if (LENGTH == 0) {
System.err.println("Usage: java " + StressCategory.class.getName() + " name1 ... nameN\n.");
System.exit(1);
}
if (LENGTH >= 7) {
System.err.println("This stress test suffers from combinatorial explosion.\n"
+ "Invoking with seven arguments takes about 90 minutes even on fast machines");
}
names = new String[LENGTH];
for (int i = 0; i < LENGTH; i++) {
names[i] = args[i];
}
cat = new Logger[LENGTH];
ct = new CT[LENGTH];
permute(0);
// If did not exit, then passed all tests.
}
// Loop through all permutations of names[].
// On each possible permutation call createLoop
static void permute(int n) {
if (n == LENGTH)
createLoop(0);
else
for (int i = n; i < LENGTH; i++) {
swap(names, n, i);
permute(n + 1);
swap(names, n, i);
}
}
static void swap(String[] names, int i, int j) {
String t = names[i];
names[i] = names[j];
names[j] = t;
}
public static void permutationDump() {
System.out.print("Current permutation is - ");
for (int i = 0; i < LENGTH; i++) {
System.out.print(names[i] + " ");
}
System.out.println();
}
// Loop through all possible 3^n combinations of not instantiating,
// instantiating and setting/not setting a level.
static void createLoop(int n) {
if (n == LENGTH) {
// System.out.println("..............Creating cat[]...........");
for (int i = 0; i < LENGTH; i++) {
if (ct[i] == null)
cat[i] = null;
else {
cat[i] = Logger.getLogger(ct[i].catstr);
cat[i].setLevel(ct[i].level);
}
}
test();
// Clear hash table for next round
Hierarchy h = (Hierarchy) LogManager.getLoggerRepository();
h.clear();
} else {
ct[n] = null;
createLoop(n + 1);
ct[n] = new CT(names[n], null);
createLoop(n + 1);
int r = random.nextInt();
if (r < 0)
r = -r;
ct[n] = new CT(names[n], level[r % 5]);
createLoop(n + 1);
}
}
static void test() {
// System.out.println("++++++++++++TEST called+++++++++++++");
// permutationDump();
// catDump();
for (int i = 0; i < LENGTH; i++) {
if (!checkCorrectness(i)) {
System.out.println("Failed stress test.");
permutationDump();
// Hierarchy._default.fullDump();
ctDump();
catDump();
System.exit(1);
}
}
}
static void ctDump() {
for (int j = 0; j < LENGTH; j++) {
if (ct[j] != null)
System.out.println("ct [" + j + "] = (" + ct[j].catstr + "," + ct[j].level + ")");
else
System.out.println("ct [" + j + "] = undefined");
}
}
static void catDump() {
for (int j = 0; j < LENGTH; j++) {
if (cat[j] != null)
System.out.println("cat[" + j + "] = (" + cat[j].name + "," + cat[j].getLevel() + ")");
else
System.out.println("cat[" + j + "] = undefined");
}
}
// static
// void provisionNodesDump() {
// for (Enumeration e = CategoryFactory.ht.keys(); e.hasMoreElements() ;) {
// CategoryKey key = (CategoryKey) e.nextElement();
// Object c = CategoryFactory.ht.get(key);
// if(c instanceof ProvisionNode)
// ((ProvisionNode) c).dump(key.name);
// }
// }
static boolean checkCorrectness(int i) {
CT localCT = ct[i];
// Can't perform test if logger is not instantiated
if (localCT == null)
return true;
// find expected level
Level expected = getExpectedPrioriy(localCT);
Level purported = cat[i].getEffectiveLevel();
if (expected != purported) {
System.out.println("Expected level for " + localCT.catstr + " is " + expected);
System.out.println("Purported level for " + cat[i].name + " is " + purported);
return false;
}
return true;
}
static Level getExpectedPrioriy(CT ctParam) {
Level level = ctParam.level;
if (level != null)
return level;
String catstr = ctParam.catstr;
for (int i = catstr.lastIndexOf('.', catstr.length() - 1); i >= 0; i = catstr.lastIndexOf('.', i - 1)) {
String substr = catstr.substring(0, i);
// find the level of ct corresponding to substr
for (int j = 0; j < LENGTH; j++) {
if (ct[j] != null && substr.equals(ct[j].catstr)) {
Level p = ct[j].level;
if (p != null)
return p;
}
}
}
return defaultLevel;
}
static class CT {
public String catstr;
public Level level;
CT(String catstr, Level level) {
this.catstr = catstr;
this.level = level;
}
}
}