package de.vksi.c4j.systemtest;
import java.util.HashMap;
import java.util.Map;
import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.Level;
import org.apache.log4j.spi.LoggingEvent;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
import de.vksi.c4j.internal.Agent;
public class TransformerAwareRule implements TestRule {
private String expectedLogMessage;
private Level expectedLogLevel;
private Level bannedLogLevel;
private String bannedLogMessage;
private Map<String, Level> usedLogMap;
private static Map<String, Level> globalLogMap = new HashMap<String, Level>();
private static Map<String, Level> localLogMap = new HashMap<String, Level>();
private static int numTestsRun = 0;
private static boolean hasFatalLogMessage = false;
public void expectGlobalLog(Level level, String message) {
usedLogMap = globalLogMap;
expectedLogLevel = level;
expectedLogMessage = message;
}
public void banGlobalLog(Level level, String message) {
usedLogMap = globalLogMap;
bannedLogLevel = level;
bannedLogMessage = message;
}
public void expectLocalLog(Level level, String message) {
usedLogMap = localLogMap;
expectedLogLevel = level;
expectedLogMessage = message;
}
public void banLocalLog(Level level, String message) {
usedLogMap = localLogMap;
bannedLogLevel = level;
bannedLogMessage = message;
}
@Override
public Statement apply(final Statement base, final Description description) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
localLogMap.clear();
usedLogMap = null;
expectedLogLevel = null;
expectedLogMessage = null;
bannedLogLevel = null;
bannedLogMessage = null;
base.evaluate();
numTestsRun++;
verify();
}
};
}
public static boolean haveTestsRun() {
return numTestsRun > 0;
}
protected void verify() throws Throwable {
verifyException();
verifyLog(usedLogMap);
}
private void verifyLog(Map<String, Level> logMap) throws Exception {
if (expectedLogMessage != null
&& (!logMap.containsKey(expectedLogMessage) || !logMap.get(expectedLogMessage).equals(expectedLogLevel))) {
throw new Exception("expected " + expectedLogLevel + " with message '" + expectedLogMessage + "'");
}
if (bannedLogMessage != null && logMap.containsKey(bannedLogMessage)
&& logMap.get(bannedLogMessage).equals(bannedLogLevel)) {
throw new Exception("noticed banned " + bannedLogLevel + " with message '" + bannedLogMessage + "'");
}
if (hasFatalLogMessage) {
hasFatalLogMessage = false;
throw new Exception("encountered FATAL log message");
}
}
private void verifyException() throws Exception, Throwable {
if (Agent.getLastException() != null) {
Throwable lastException = Agent.getLastException();
Agent.resetLastException();
throw lastException;
}
}
public static class RuleAppender extends AppenderSkeleton {
@Override
public void close() {
}
@Override
public boolean requiresLayout() {
return false;
}
@Override
protected void append(LoggingEvent event) {
globalLogMap.put(event.getMessage().toString(), event.getLevel());
localLogMap.put(event.getMessage().toString(), event.getLevel());
if (event.getLevel().equals(Level.FATAL)) {
hasFatalLogMessage = true;
}
}
}
}