mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
comparison diff: create temp files when content would be truncated by OOM threshold on IDE side (IDEA-163388)
This commit is contained in:
@@ -19,6 +19,7 @@ import com.intellij.ExtensionPoints;
|
||||
import com.intellij.debugger.impl.GenericDebuggerRunnerSettings;
|
||||
import com.intellij.diagnostic.logging.OutputFileUtil;
|
||||
import com.intellij.execution.configurations.*;
|
||||
import com.intellij.execution.impl.ConsoleBuffer;
|
||||
import com.intellij.execution.process.OSProcessHandler;
|
||||
import com.intellij.execution.process.ProcessAdapter;
|
||||
import com.intellij.execution.process.ProcessEvent;
|
||||
@@ -125,14 +126,6 @@ public abstract class JavaTestFrameworkRunnableState<T extends
|
||||
@NotNull
|
||||
@Override
|
||||
public ExecutionResult execute(@NotNull Executor executor, @NotNull ProgramRunner runner) throws ExecutionException {
|
||||
return startSMRunner(executor);
|
||||
}
|
||||
|
||||
/**
|
||||
* to be removed in 2017.1, compatibility with jtreg plugin
|
||||
*/
|
||||
@Deprecated
|
||||
protected ExecutionResult startSMRunner(Executor executor) throws ExecutionException {
|
||||
final RunnerSettings runnerSettings = getRunnerSettings();
|
||||
|
||||
final SMTRunnerConsoleProperties testConsoleProperties = getConfiguration().createTestConsoleProperties(executor);
|
||||
@@ -228,6 +221,10 @@ public abstract class JavaTestFrameworkRunnableState<T extends
|
||||
javaParameters.getProgramParametersList().addAll(getNamedParams(parameters));
|
||||
}
|
||||
|
||||
if (ConsoleBuffer.useCycleBuffer()) {
|
||||
javaParameters.getVMParametersList().addProperty("idea.test.cyclic.buffer.size", String.valueOf(ConsoleBuffer.getCycleBufferSize()));
|
||||
}
|
||||
|
||||
return javaParameters;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,9 @@ package com.intellij.rt.execution.junit;
|
||||
|
||||
import junit.framework.ComparisonFailure;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@@ -84,7 +87,8 @@ public class ComparisonFailureData {
|
||||
|
||||
final int failureIdx = failureMessage != null ? trace.indexOf(failureMessage) : -1;
|
||||
final int failureMessageLength = failureMessage != null ? failureMessage.length() : 0;
|
||||
attrs.put("details", failureIdx > -1 ? trace.substring(failureIdx + failureMessageLength) : trace);
|
||||
String details = failureIdx > -1 ? trace.substring(failureIdx + failureMessageLength) : trace;
|
||||
attrs.put("details", details);
|
||||
|
||||
if (notification != null) {
|
||||
final int expectedIdx = trace.indexOf(expectedPrefix);
|
||||
@@ -101,18 +105,26 @@ public class ComparisonFailureData {
|
||||
attrs.put("message", comparisonFailureMessage);
|
||||
|
||||
final String filePath = notification.getFilePath();
|
||||
final String actualFilePath = notification.getActualFilePath();
|
||||
final String expected = notification.getExpected();
|
||||
final String actual = notification.getActual();
|
||||
|
||||
int fullLength = (filePath == null && expected != null ? expected.length() : 0) +
|
||||
(actualFilePath == null && actual != null ? actual.length() : 0) +
|
||||
details.length() +
|
||||
comparisonFailureMessage.length() + 100;
|
||||
if (filePath != null) {
|
||||
attrs.put("expectedFile", filePath);
|
||||
}
|
||||
else {
|
||||
attrs.put("expected", notification.getExpected());
|
||||
writeDiffSide(attrs, "expected", expected, fullLength);
|
||||
}
|
||||
final String actualFilePath = notification.getActualFilePath();
|
||||
|
||||
if (actualFilePath != null) {
|
||||
attrs.put("actualFile", actualFilePath);
|
||||
}
|
||||
else {
|
||||
attrs.put("actual", notification.getActual());
|
||||
writeDiffSide(attrs, "actual", actual, fullLength);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -130,6 +142,37 @@ public class ComparisonFailureData {
|
||||
}
|
||||
}
|
||||
|
||||
private static void writeDiffSide(Map attrs, final String expectedOrActualPrefix, final String text, int fullLength) {
|
||||
String property = System.getProperty("idea.test.cyclic.buffer.size");
|
||||
|
||||
int threshold;
|
||||
try {
|
||||
threshold = Integer.parseInt(property);
|
||||
}
|
||||
catch (NumberFormatException ignored) {
|
||||
threshold = -1;
|
||||
}
|
||||
|
||||
if (threshold > 0 && fullLength > threshold) {
|
||||
try {
|
||||
//noinspection SSBasedInspection
|
||||
File tempFile = File.createTempFile(expectedOrActualPrefix, "");
|
||||
OutputStream stream = new FileOutputStream(tempFile, false);
|
||||
try {
|
||||
stream.write(text.getBytes("UTF-8"), 0, text.length());
|
||||
}
|
||||
finally {
|
||||
stream.close();
|
||||
}
|
||||
attrs.put(expectedOrActualPrefix + "File", tempFile.getAbsolutePath());
|
||||
attrs.put(expectedOrActualPrefix + "IsTempFile", "true");
|
||||
return;
|
||||
}
|
||||
catch (Throwable ignored) {}
|
||||
}
|
||||
attrs.put(expectedOrActualPrefix, text);
|
||||
}
|
||||
|
||||
public static boolean isAssertionError(Class throwableClass) {
|
||||
if (throwableClass == null) return false;
|
||||
final String throwableClassName = throwableClass.getName();
|
||||
|
||||
+1
-4
@@ -254,10 +254,7 @@ public class GeneralIdBasedToSMTRunnerEventsConvertor extends GeneralTestEventsP
|
||||
String failureMessage = testFailedEvent.getLocalizedFailureMessage();
|
||||
String stackTrace = testFailedEvent.getStacktrace();
|
||||
if (comparisonFailureActualText != null && comparisonFailureExpectedText != null) {
|
||||
testProxy.setTestComparisonFailed(failureMessage, stackTrace,
|
||||
comparisonFailureActualText, comparisonFailureExpectedText,
|
||||
testFailedEvent.getExpectedFilePath(),
|
||||
testFailedEvent.getActualFilePath());
|
||||
testProxy.setTestComparisonFailed(failureMessage, stackTrace, comparisonFailureActualText, comparisonFailureExpectedText, testFailedEvent);
|
||||
} else if (comparisonFailureActualText == null && comparisonFailureExpectedText == null) {
|
||||
testProxy.setTestFailed(failureMessage, stackTrace, testFailedEvent.isTestError());
|
||||
} else {
|
||||
|
||||
+1
-3
@@ -386,9 +386,7 @@ public class GeneralToSMTRunnerEventsConvertor extends GeneralTestEventsProcesso
|
||||
}
|
||||
|
||||
if (comparisionFailureActualText != null && comparisionFailureExpectedText != null) {
|
||||
testProxy.setTestComparisonFailed(localizedMessage, stackTrace,
|
||||
comparisionFailureActualText, comparisionFailureExpectedText,
|
||||
testFailedEvent.getExpectedFilePath(), testFailedEvent.getActualFilePath());
|
||||
testProxy.setTestComparisonFailed(localizedMessage, stackTrace, comparisionFailureActualText, comparisionFailureExpectedText, testFailedEvent);
|
||||
}
|
||||
else if (comparisionFailureActualText == null && comparisionFailureExpectedText == null) {
|
||||
testProxy.setTestFailed(localizedMessage, stackTrace, isTestError);
|
||||
|
||||
+24
-9
@@ -20,6 +20,7 @@ import com.intellij.execution.process.ProcessHandler;
|
||||
import com.intellij.execution.testframework.*;
|
||||
import com.intellij.execution.testframework.sm.SMStacktraceParser;
|
||||
import com.intellij.execution.testframework.sm.SMStacktraceParserEx;
|
||||
import com.intellij.execution.testframework.sm.runner.events.TestFailedEvent;
|
||||
import com.intellij.execution.testframework.sm.runner.states.*;
|
||||
import com.intellij.execution.testframework.sm.runner.ui.TestsPresentationUtil;
|
||||
import com.intellij.execution.testframework.stacktrace.DiffHyperlink;
|
||||
@@ -29,6 +30,7 @@ import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
@@ -446,23 +448,26 @@ public class SMTestProxy extends AbstractTestProxy {
|
||||
@Nullable final String stackTrace,
|
||||
@NotNull final String actualText,
|
||||
@NotNull final String expectedText) {
|
||||
setTestComparisonFailed(localizedMessage, stackTrace, actualText, expectedText, null);
|
||||
setTestComparisonFailed(localizedMessage, stackTrace, actualText, expectedText, null, null);
|
||||
}
|
||||
|
||||
public void setTestComparisonFailed(@NotNull final String localizedMessage,
|
||||
@Nullable final String stackTrace,
|
||||
@NotNull final String actualText,
|
||||
@NotNull final String expectedText,
|
||||
@Nullable final String filePath) {
|
||||
setTestComparisonFailed(localizedMessage, stackTrace, actualText, expectedText, filePath, null);
|
||||
@NotNull final TestFailedEvent event) {
|
||||
TestComparisionFailedState comparisionFailedState =
|
||||
setTestComparisonFailed(localizedMessage, stackTrace, actualText, expectedText, event.getExpectedFilePath(), event.getActualFilePath());
|
||||
comparisionFailedState.setToDeleteExpectedFile(event.isExpectedFIleTemp());
|
||||
comparisionFailedState.setToDeleteActualFile(event.isActualFileTemp());
|
||||
}
|
||||
|
||||
public void setTestComparisonFailed(@NotNull final String localizedMessage,
|
||||
@Nullable final String stackTrace,
|
||||
@NotNull final String actualText,
|
||||
@NotNull final String expectedText,
|
||||
@Nullable final String expectedFilePath,
|
||||
@Nullable final String actualFilePath) {
|
||||
public TestComparisionFailedState setTestComparisonFailed(@NotNull final String localizedMessage,
|
||||
@Nullable final String stackTrace,
|
||||
@NotNull final String actualText,
|
||||
@NotNull final String expectedText,
|
||||
@Nullable final String expectedFilePath,
|
||||
@Nullable final String actualFilePath) {
|
||||
setStacktraceIfNotSet(stackTrace);
|
||||
final TestComparisionFailedState comparisionFailedState = new TestComparisionFailedState(localizedMessage, stackTrace, actualText, expectedText, expectedFilePath, actualFilePath);
|
||||
if (myState instanceof CompoundTestFailedState) {
|
||||
@@ -478,6 +483,16 @@ public class SMTestProxy extends AbstractTestProxy {
|
||||
myState = comparisionFailedState;
|
||||
}
|
||||
fireOnNewPrintable(comparisionFailedState);
|
||||
return comparisionFailedState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
if (myState instanceof TestFailedState) {
|
||||
Disposer.dispose((TestFailedState)myState);
|
||||
}
|
||||
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
public void setTestIgnored(@Nullable String ignoreComment, @Nullable String stackTrace) {
|
||||
|
||||
+24
-2
@@ -23,6 +23,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
public class TestFailedEvent extends TreeNodeEvent {
|
||||
|
||||
@@ -34,6 +35,8 @@ public class TestFailedEvent extends TreeNodeEvent {
|
||||
private final String myExpectedFilePath;
|
||||
private final String myActualFilePath;
|
||||
private final long myDurationMillis;
|
||||
private boolean myExpectedFileTemp;
|
||||
private boolean myActualFileTemp;
|
||||
|
||||
public TestFailedEvent(@NotNull TestFailed testFailed, boolean testError) {
|
||||
this(testFailed, testError, null);
|
||||
@@ -71,7 +74,18 @@ public class TestFailedEvent extends TreeNodeEvent {
|
||||
}
|
||||
myComparisonFailureActualText = actual;
|
||||
|
||||
myDurationMillis = parseDuration(testFailed.getAttributes().get("duration"));
|
||||
Map<String, String> attributes = testFailed.getAttributes();
|
||||
myDurationMillis = parseDuration(attributes.get("duration"));
|
||||
myActualFileTemp = Boolean.parseBoolean(attributes.get("actualIsTempFile"));
|
||||
myExpectedFileTemp = Boolean.parseBoolean(attributes.get("expectedIsTempFile"));
|
||||
}
|
||||
|
||||
public boolean isExpectedFIleTemp() {
|
||||
return myExpectedFileTemp;
|
||||
}
|
||||
|
||||
public boolean isActualFileTemp() {
|
||||
return myActualFileTemp;
|
||||
}
|
||||
|
||||
private static long parseDuration(@Nullable String durationStr) {
|
||||
@@ -99,6 +113,9 @@ public class TestFailedEvent extends TreeNodeEvent {
|
||||
comparisonFailureActualText,
|
||||
comparisonFailureExpectedText,
|
||||
null,
|
||||
null,
|
||||
false,
|
||||
false,
|
||||
-1);
|
||||
}
|
||||
|
||||
@@ -110,6 +127,9 @@ public class TestFailedEvent extends TreeNodeEvent {
|
||||
@Nullable String comparisonFailureActualText,
|
||||
@Nullable String comparisonFailureExpectedText,
|
||||
@Nullable String expectedFilePath,
|
||||
@Nullable String actualFilePath,
|
||||
boolean expectedFileTemp,
|
||||
boolean actualFileTemp,
|
||||
long durationMillis) {
|
||||
super(testName, id);
|
||||
myLocalizedFailureMessage = localizedFailureMessage;
|
||||
@@ -124,9 +144,11 @@ public class TestFailedEvent extends TreeNodeEvent {
|
||||
}
|
||||
myComparisonFailureActualText = comparisonFailureActualText;
|
||||
|
||||
myActualFilePath = null;
|
||||
myActualFilePath = actualFilePath;
|
||||
myComparisonFailureExpectedText = comparisonFailureExpectedText;
|
||||
myDurationMillis = durationMillis;
|
||||
myExpectedFileTemp = expectedFileTemp;
|
||||
myActualFileTemp = actualFileTemp;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+2
-1
@@ -18,7 +18,7 @@ package com.intellij.execution.testframework.sm.runner.states;
|
||||
|
||||
import com.intellij.execution.testframework.Printer;
|
||||
import com.intellij.execution.testframework.stacktrace.DiffHyperlink;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -36,6 +36,7 @@ public class CompoundTestFailedState extends TestFailedState {
|
||||
|
||||
public void addFailure(TestFailedState state) {
|
||||
myStates.add(state);
|
||||
Disposer.register(this, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+22
@@ -20,10 +20,13 @@ import com.intellij.execution.testframework.CompositePrintable;
|
||||
import com.intellij.execution.testframework.Printer;
|
||||
import com.intellij.execution.testframework.stacktrace.DiffHyperlink;
|
||||
import com.intellij.execution.ui.ConsoleViewContentType;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* @author Roman.Chernyatchik
|
||||
*/
|
||||
@@ -31,6 +34,8 @@ public class TestComparisionFailedState extends TestFailedState {
|
||||
private final String myErrorMsgPresentation;
|
||||
private final String myStacktracePresentation;
|
||||
private DiffHyperlink myHyperlink;
|
||||
private boolean myToDeleteExpectedFile;
|
||||
private boolean myToDeleteActualFile;
|
||||
|
||||
|
||||
public TestComparisionFailedState(@Nullable final String localizedMessage,
|
||||
@@ -82,4 +87,21 @@ public class TestComparisionFailedState extends TestFailedState {
|
||||
public DiffHyperlink getHyperlink() {
|
||||
return myHyperlink;
|
||||
}
|
||||
|
||||
public void setToDeleteExpectedFile(boolean expectedTemp) {
|
||||
myToDeleteExpectedFile = expectedTemp;
|
||||
}
|
||||
|
||||
public void setToDeleteActualFile(boolean actualTemp) {
|
||||
myToDeleteActualFile = actualTemp;
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
if (myToDeleteActualFile) {
|
||||
FileUtil.delete(new File(myHyperlink.getActualFilePath()));
|
||||
}
|
||||
if (myToDeleteExpectedFile) {
|
||||
FileUtil.delete(new File(myHyperlink.getFilePath()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+5
-1
@@ -19,6 +19,7 @@ import com.intellij.execution.process.ProcessOutputTypes;
|
||||
import com.intellij.execution.testframework.CompositePrintable;
|
||||
import com.intellij.execution.testframework.Printer;
|
||||
import com.intellij.execution.ui.ConsoleViewContentType;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -31,7 +32,7 @@ import java.util.List;
|
||||
/**
|
||||
* @author Roman Chernyatchik
|
||||
*/
|
||||
public class TestFailedState extends AbstractState {
|
||||
public class TestFailedState extends AbstractState implements Disposable{
|
||||
private final List<String> myPresentationText;
|
||||
|
||||
public TestFailedState(@Nullable final String localizedMessage,
|
||||
@@ -51,6 +52,9 @@ public class TestFailedState extends AbstractState {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {}
|
||||
|
||||
@Nullable
|
||||
public static String buildErrorPresentationText(@Nullable final String localizedMessage,
|
||||
@Nullable final String stackTrace)
|
||||
|
||||
+1
-1
@@ -124,7 +124,7 @@ public class GeneralIdBasedToSMTRunnerEventsConvertorTest extends BaseSMTRunnerT
|
||||
|
||||
private void onTestFailed(@NotNull String id, @NotNull String errorMessage, int durationMillis) {
|
||||
myEventsProcessor.onTestFailure(new TestFailedEvent(null, id, errorMessage, null, false, null,
|
||||
null, null, durationMillis));
|
||||
null, null, null, false, false, durationMillis));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+23
@@ -29,11 +29,14 @@ import com.intellij.execution.testframework.sm.runner.ui.SMTestRunnerResultsForm
|
||||
import com.intellij.execution.testframework.ui.TestsOutputConsolePrinter;
|
||||
import com.intellij.execution.ui.ConsoleViewContentType;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.tree.DefaultMutableTreeNode;
|
||||
import javax.swing.tree.TreeModel;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.List;
|
||||
|
||||
@@ -46,6 +49,7 @@ public class GeneralToSMTRunnerEventsConvertorTest extends BaseSMTRunnerTestCase
|
||||
private TreeModel myTreeModel;
|
||||
private SMTestRunnerResultsForm myResultsViewer;
|
||||
private MockPrinter myMockResettablePrinter;
|
||||
private File myTempFile;
|
||||
|
||||
private class MyConsoleView extends SMTRunnerConsoleView {
|
||||
private final TestsOutputConsolePrinter myTestsOutputConsolePrinter;
|
||||
@@ -96,6 +100,10 @@ public class GeneralToSMTRunnerEventsConvertorTest extends BaseSMTRunnerTestCase
|
||||
Disposer.dispose(myConsole);
|
||||
|
||||
super.tearDown();
|
||||
|
||||
if (myTempFile != null) {
|
||||
assertFalse(myTempFile.exists());
|
||||
}
|
||||
}
|
||||
|
||||
public void testOnStartedTesting() {
|
||||
@@ -177,6 +185,21 @@ public class GeneralToSMTRunnerEventsConvertorTest extends BaseSMTRunnerTestCase
|
||||
assertFalse(proxy.isInProgress());
|
||||
}
|
||||
|
||||
public void testOnTestComparisonFailureLongExpectedText() throws IOException {
|
||||
onTestStarted("some_test");
|
||||
myTempFile = FileUtil.createTempFile("expected", "");
|
||||
FileUtil.writeToFile(myTempFile, "expected text");
|
||||
myEventsProcessor.onTestFailure(new TestFailedEvent("some_test", "", "", null, false, "actual",
|
||||
"expected", myTempFile.getCanonicalPath(), null, true, false, -1));
|
||||
|
||||
final String fullName = myEventsProcessor.getFullTestName("some_test");
|
||||
final SMTestProxy proxy = myEventsProcessor.getProxyByFullTestName(fullName);
|
||||
|
||||
assertNotNull(proxy);
|
||||
assertTrue(proxy.isDefect());
|
||||
assertFalse(proxy.isInProgress());
|
||||
}
|
||||
|
||||
public void testOnTestTruncatedComparisonFailure() {
|
||||
onTestStarted("some_test");
|
||||
myEventsProcessor.onTestFailure(new TestFailedEvent("some_test", "", "", false, "actual", null));
|
||||
|
||||
Reference in New Issue
Block a user