From bc76eb25ca34d5011da38437e04304e41488299e Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Wed, 27 Jul 2016 15:19:05 +0300 Subject: [PATCH] In case of test failure log all LOG.debugs and LOG.infos since the beginning of the test --- .../testFramework/PlatformTestCase.java | 4 -- .../intellij/testFramework/TestLogger.java | 38 +++++++++++++++++-- .../testFramework/TestLoggerFactory.java | 38 ++++++++++++++++--- .../testFramework/UsefulTestCase.java | 15 +++++++- 4 files changed, 80 insertions(+), 15 deletions(-) diff --git a/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java b/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java index 364d75814091..328653faaf83 100644 --- a/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java @@ -116,10 +116,6 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro private static boolean ourPlatformPrefixInitialized; private static Set ourEternallyLivingFilesCache; - static { - Logger.setFactory(TestLoggerFactory.class); - } - /** * If a temp directory is reused from some previous test run, there might be cached children in its VFS. * Ensure they're removed diff --git a/platform/testFramework/src/com/intellij/testFramework/TestLogger.java b/platform/testFramework/src/com/intellij/testFramework/TestLogger.java index 683491292f37..c330e014a603 100644 --- a/platform/testFramework/src/com/intellij/testFramework/TestLogger.java +++ b/platform/testFramework/src/com/intellij/testFramework/TestLogger.java @@ -18,11 +18,12 @@ package com.intellij.testFramework; import com.intellij.openapi.diagnostic.Log4jBasedLogger; import org.apache.log4j.Level; import org.apache.log4j.Logger; +import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class TestLogger extends Log4jBasedLogger { - public TestLogger(Logger logger) { + TestLogger(@NotNull Logger logger) { super(logger); } @@ -38,7 +39,38 @@ public class TestLogger extends Log4jBasedLogger { LoggedErrorProcessor.getInstance().processError(message, t, details, myLogger); } - public Level getLevel() { - return myLogger.getLevel(); + @Override + public void debug(@NonNls String message) { + super.debug(message); + TestLoggerFactory.log(myLogger, Level.DEBUG, message, null); + } + + @Override + public void debug(@Nullable Throwable t) { + super.debug(t); + TestLoggerFactory.log(myLogger, Level.DEBUG, null, t); + } + + @Override + public void debug(@NonNls String message, @Nullable Throwable t) { + super.debug(message, t); + TestLoggerFactory.log(myLogger, Level.DEBUG, message, t); + } + + @Override + public void info(@NonNls String message) { + super.info(message); + TestLoggerFactory.log(myLogger, Level.INFO, message, null); + } + + @Override + public void info(@NonNls String message, @Nullable Throwable t) { + super.info(message, t); + TestLoggerFactory.log(myLogger, Level.INFO, message, t); + } + + @Override + public boolean isDebugEnabled() { + return true; } } diff --git a/platform/testFramework/src/com/intellij/testFramework/TestLoggerFactory.java b/platform/testFramework/src/com/intellij/testFramework/TestLoggerFactory.java index be3cd20f1f17..7f9752c9d06a 100644 --- a/platform/testFramework/src/com/intellij/testFramework/TestLoggerFactory.java +++ b/platform/testFramework/src/com/intellij/testFramework/TestLoggerFactory.java @@ -21,15 +21,13 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; -import org.apache.log4j.Level; -import org.apache.log4j.LogManager; +import org.apache.log4j.*; +import org.apache.log4j.spi.LoggingEvent; import org.apache.log4j.xml.DOMConfigurator; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; -import java.io.File; -import java.io.IOException; -import java.io.RandomAccessFile; -import java.io.StringReader; +import java.io.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -144,4 +142,32 @@ public class TestLoggerFactory implements Logger.Factory { Disposer.register(parentDisposable, () -> logger.setLevel(Level.INFO)); } } + + private static final StringWriter STRING_WRITER = new StringWriter(); + private static final StringBuffer BUFFER = STRING_WRITER.getBuffer(); + private static final WriterAppender APPENDER = new WriterAppender(new PatternLayout("%d{HH:mm:ss,SSS} %p %.30c - %m%n"), STRING_WRITER); + private static final int MAX_BUFFER_LENGTH = 100000; + private static final String CFQN = Category.class.getName(); + static void log(@NotNull org.apache.log4j.Logger logger, @NotNull Level level, @Nullable String message, @Nullable Throwable t) { + if (!UsefulTestCase.IS_UNDER_TEAMCITY) { + //return; + } + LoggingEvent event = new LoggingEvent(CFQN, logger, level, message, t); + APPENDER.append(event); + + if (BUFFER.length() > MAX_BUFFER_LENGTH) { + synchronized (BUFFER) { + if (BUFFER.length() > MAX_BUFFER_LENGTH) { + BUFFER.delete(0, BUFFER.length() - MAX_BUFFER_LENGTH + MAX_BUFFER_LENGTH / 4); + } + } + } + } + + public static void onTestFinished(boolean success) { + if (!success) { + System.err.println(BUFFER); + } + BUFFER.setLength(0); + } } \ No newline at end of file diff --git a/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java b/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java index 76036affeb62..c592bd9956b5 100644 --- a/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java @@ -24,6 +24,7 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.PathManager; import com.intellij.openapi.application.impl.ApplicationInfoImpl; import com.intellij.openapi.command.impl.StartMarkAction; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.*; @@ -91,6 +92,10 @@ public abstract class UsefulTestCase extends TestCase { private static final Map TOTAL_SETUP_COST_MILLIS = new HashMap<>(); private static final Map TOTAL_TEARDOWN_COST_MILLIS = new HashMap<>(); + static { + Logger.setFactory(TestLoggerFactory.class); + } + @NotNull private final Disposable myTestRootDisposable = new Disposable() { @Override @@ -321,22 +326,28 @@ public abstract class UsefulTestCase extends TestCase { protected void runTest() throws Throwable { final Throwable[] throwables = new Throwable[1]; - invokeTestRunnable(() -> { + Runnable runnable = () -> { try { super.runTest(); + TestLoggerFactory.onTestFinished(true); } catch (InvocationTargetException e) { + TestLoggerFactory.onTestFinished(false); e.fillInStackTrace(); throwables[0] = e.getTargetException(); } catch (IllegalAccessException e) { + TestLoggerFactory.onTestFinished(false); e.fillInStackTrace(); throwables[0] = e; } catch (Throwable e) { + TestLoggerFactory.onTestFinished(false); throwables[0] = e; } - }); + }; + + invokeTestRunnable(runnable); if (throwables[0] != null) { throw throwables[0];