package jetbrains.mps.testbench.junit;
/*Generated by MPS */
import org.apache.log4j.Level;
import java.util.regex.Pattern;
import jetbrains.mps.testbench.util.CachingAppender;
import java.util.Map;
import org.junit.runner.Description;
import java.util.HashMap;
import jetbrains.mps.testbench.util.ThreadWatcher;
import org.junit.runner.notification.RunNotifier;
import java.util.List;
import java.util.ArrayList;
import org.junit.runner.notification.StoppedByUserException;
import org.junit.runner.notification.Failure;
import org.apache.log4j.Logger;
/**
* fyodor, Aug 18, 2010
*/
public class WatchingRunNotifier extends DelegatingRunNotifier {
private static final Level DEFAULT_WATCH_LOGGER_LEVEL = Level.ERROR;
private static final Pattern EXECUTION_LIMIT_FAILED_PATTERN = Pattern.compile("(\\d)* ms execution limit failed for:[^,]*,(\\d*)(\\s)*");
private static final Pattern WARN_PATTERN_MULTILINE = Pattern.compile("\\[([\\d\\s])*\\](\\s)*WARN.*:\\n[^\\[^\\s].*");
private static final Pattern WARN_PATTERN = Pattern.compile("\\[([\\d\\s])*\\](\\s)*WARN.*");
private final Level myWatchLevel;
private final IgnoringPatternErrorStream myErrorCachingStream;
private CachingAppender myCachingAppender;
private Map<Description, Object> myTestsToIgnore = new HashMap<Description, Object>();
private ThreadWatcher myThreadWatcher;
public WatchingRunNotifier(RunNotifier delegate) {
this(delegate, DEFAULT_WATCH_LOGGER_LEVEL, true);
}
public WatchingRunNotifier(RunNotifier delegate, Level watchLevel, boolean ignoreWarnings) {
super(delegate);
myWatchLevel = watchLevel;
myErrorCachingStream = new IgnoringPatternErrorStream(getPatternsToIgnore(ignoreWarnings));
}
private List<Pattern> getPatternsToIgnore(boolean ignoreWarnings) {
List<Pattern> result = new ArrayList<Pattern>();
result.add(EXECUTION_LIMIT_FAILED_PATTERN);
if (ignoreWarnings) {
result.add(WARN_PATTERN_MULTILINE);
result.add(WARN_PATTERN);
}
return result;
}
public void dispose() {
}
@Override
public void fireTestStarted(Description description) throws StoppedByUserException {
super.fireTestStarted(description);
try {
beforeTest(description);
} catch (Throwable e) {
super.fireTestFailure(new Failure(description, e));
}
}
@Override
public void fireTestFinished(Description description) {
try {
afterTest(description);
} catch (Throwable e) {
super.fireTestFailure(new Failure(description, e));
}
super.fireTestFinished(description);
}
@Override
public void fireTestFailure(Failure failure) {
myTestsToIgnore.put(failure.getDescription(), Boolean.TRUE);
super.fireTestFailure(failure);
}
@Override
public void fireTestAssumptionFailed(Failure failure) {
myTestsToIgnore.put(failure.getDescription(), Boolean.TRUE);
super.fireTestAssumptionFailed(failure);
}
@Override
public void fireTestIgnored(Description description) {
myTestsToIgnore.put(description, Boolean.TRUE);
super.fireTestIgnored(description);
}
private void beforeTest(Description desc) {
myErrorCachingStream.reRoute();
myCachingAppender = new CachingAppender(myWatchLevel);
Logger.getRootLogger().addAppender(myCachingAppender);
ExpectLogEvent expectEvent = desc.getAnnotation(ExpectLogEvent.class);
if (expectEvent != null) {
for (String text : expectEvent.text()) {
myCachingAppender.expectEvent(expectEvent.level(), text);
}
}
IgnoreLogEvents ignoreEvents = desc.getAnnotation(IgnoreLogEvents.class);
if (ignoreEvents != null) {
myTestsToIgnore.put(desc, Boolean.TRUE);
}
myThreadWatcher = new ThreadWatcher(true);
}
private void afterTest(Description desc) {
myThreadWatcher.waitUntilSettled(15000);
myErrorCachingStream.reset();
myCachingAppender.sealEvents();
Logger.getRootLogger().removeAppender(myCachingAppender);
Failure fail = null;
if (!(myTestsToIgnore.containsKey(desc))) {
if (myErrorCachingStream.isNotEmpty() || myCachingAppender.isNotEmpty() || myThreadWatcher.isNotEmpty()) {
fail = new Failure(desc, new UncleanTestExecutionException(myErrorCachingStream, myCachingAppender, myThreadWatcher));
}
}
myErrorCachingStream.clear();
if (fail != null) {
super.fireTestFailure(fail);
}
}
}