From 34343c165dc6d68978e6248d7fa7aa81099808dd Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Tue, 12 Jul 2016 11:05:07 +0200 Subject: [PATCH] optimize protocol with long lines printed into system out; cut out too long output before parsing control messages to avoid OOME and produce testSuccessful instead of testFailure (IDEA-158222) --- .../testframework/sm/runner/OutputLineSplitter.java | 11 ++++++++++- .../runner/OutputToGeneralTestEventsConverter.java | 12 +++++++++++- .../testframework/sm/OutputLineSplitterTest.java | 8 ++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/OutputLineSplitter.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/OutputLineSplitter.java index 1ee0b76183ee..87c5fb7fa0a2 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/OutputLineSplitter.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/OutputLineSplitter.java @@ -159,6 +159,7 @@ public abstract class OutputLineSplitter { private static class OutputChunk { private final Key myKey; private String myText; + private StringBuilder myBuilder; private OutputChunk(Key key, String text) { myKey = key; @@ -170,11 +171,19 @@ public abstract class OutputLineSplitter { } public String getText() { + if (myBuilder != null) { + myText = myBuilder.toString(); + myBuilder = null; + } return myText; } public void append(String text) { - myText += text; + if (myBuilder == null) { + myBuilder = new StringBuilder(myText); + myText = null; + } + myBuilder.append(text); } } } diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/OutputToGeneralTestEventsConverter.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/OutputToGeneralTestEventsConverter.java index 0d4ecbbf61ab..43b405aa039c 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/OutputToGeneralTestEventsConverter.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/OutputToGeneralTestEventsConverter.java @@ -15,6 +15,7 @@ */ package com.intellij.execution.testframework.sm.runner; +import com.intellij.execution.impl.ConsoleBuffer; import com.intellij.execution.process.ProcessOutputTypes; import com.intellij.execution.testframework.TestConsoleProperties; import com.intellij.execution.testframework.sm.runner.events.*; @@ -41,6 +42,7 @@ import static com.intellij.execution.testframework.sm.runner.GeneralToSMTRunnerE */ public class OutputToGeneralTestEventsConverter implements ProcessOutputConsumer { private static final Logger LOG = Logger.getInstance(OutputToGeneralTestEventsConverter.class.getName()); + private final int CYCLE_BUFFER_SIZE = ConsoleBuffer.getCycleBufferSize(); private final MyServiceMessageVisitor myServiceMessageVisitor; private final String myTestFrameworkName; @@ -90,7 +92,15 @@ public class OutputToGeneralTestEventsConverter implements ProcessOutputConsumer fireOnUncapturedOutput("\n", ProcessOutputTypes.STDOUT); } - private void processConsistentText(final String text, final Key outputType, boolean tcLikeFakeOutput) { + private void processConsistentText(String text, final Key outputType, boolean tcLikeFakeOutput) { + if (text.length() > CYCLE_BUFFER_SIZE) { + final StringBuilder builder = new StringBuilder(CYCLE_BUFFER_SIZE); + builder.append(text, 0, CYCLE_BUFFER_SIZE - 105); + builder.append("<...>"); + builder.append(text, text.length() - 100, text.length()); + text = builder.toString(); + } + try { if (!processServiceMessages(text, outputType, myServiceMessageVisitor)) { if (myPendingLineBreakFlag) { diff --git a/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/OutputLineSplitterTest.java b/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/OutputLineSplitterTest.java index 90a7dbafcd99..454006000c01 100644 --- a/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/OutputLineSplitterTest.java +++ b/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/OutputLineSplitterTest.java @@ -21,6 +21,7 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.text.StringUtil; import com.intellij.testFramework.PlatformTestCase; +import com.intellij.testFramework.PlatformTestUtil; import gnu.trove.THashMap; import org.jetbrains.annotations.NotNull; @@ -178,6 +179,13 @@ public class OutputLineSplitterTest extends PlatformTestCase { } } + public void testPerformanceWithLotsOfFragments() throws Exception { + for (int i = 0; i < 10_000; i++) { + mySplitter.process("some string without slash n appending in raw, attempt: " + i + "; ", ProcessOutputTypes.STDOUT); + } + PlatformTestUtil.startPerformanceTest("Flashing lot's of fragments", 10, mySplitter::flush).attempts(1).useLegacyScaling().assertTiming(); + } + private Future execute(final Runnable runnable) { return ApplicationManager.getApplication().executeOnPooledThread(runnable); }