From 0dd8ba5e1436ee730ec0cd4acdcc6c78e9575f73 Mon Sep 17 00:00:00 2001 From: Roman Chernyatchik Date: Wed, 19 May 2010 20:10:31 +0400 Subject: [PATCH] Errors logging/reporting was improved. Now each error/warning contains test framework id. Also log errors will be thrown usually in "debug mode" and warnings in default normal mode --- .../sm/SMTestRunnerConnectionUtil.java | 41 +++-- .../sm/runner/GeneralTestEventsProcessor.java | 38 +++-- .../GeneralToSMTRunnerEventsConvertor.java | 146 +++++++++++++----- .../OutputToGeneralTestEventsConverter.java | 47 +++++- .../sm/runner/SMTRunnerConsoleProperties.java | 11 +- .../testframework/sm/runner/SMTestProxy.java | 3 +- .../sm/runner/states/TestErrorState.java | 5 +- .../sm/runner/ui/SMTRunnerConsoleView.java | 7 + .../sm/runner/BaseSMTRunnerTestCase.java | 2 +- ...GeneralToSMTRunnerEventsConvertorTest.java | 2 +- .../sm/runner/SMTRunnerConsoleTest.java | 2 +- .../ui/SMTestRunnerResultsFormTest.java | 2 +- .../runner/ui/TestsPresentationUtilTest.java | 2 +- 13 files changed, 228 insertions(+), 80 deletions(-) diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/SMTestRunnerConnectionUtil.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/SMTestRunnerConnectionUtil.java index ea57bfa42ab8..dc71ad9d28cc 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/SMTestRunnerConnectionUtil.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/SMTestRunnerConnectionUtil.java @@ -37,7 +37,6 @@ import com.intellij.execution.ui.ConsoleView; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Key; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; /** * @author Roman Chernyatchik @@ -57,25 +56,34 @@ public class SMTestRunnerConnectionUtil { * just override "execute" method of your custom command line state and return * test runner's console. * + * NB: For debug purposes please enable "debug mode". In this mode test runner will also validate + * consistency of test events communication protocol and throw assertion errors. To enable debug mode + * please set system property idea.smrunner.debug=true + * * @param processHandler Process handler * @param consoleProperties Console properties for test console actions + * @param testFrameworkName Is used to store(project level) latest value of testTree/consoleTab splitter and other settings + * and also will be mentioned in debug diagnostics * @return Console view * @throws ExecutionException If IDEA cannot execute process this Exception will - * be catched and shown in error message box + * be caught and shown in error message box */ public static BaseTestsOutputConsoleView attachRunner(@NotNull final ProcessHandler processHandler, @NotNull final TestConsoleProperties consoleProperties, final RunnerSettings runnerSettings, final ConfigurationPerRunnerSettings configurationSettings, - final String splitterPropertyName) throws ExecutionException { + @NotNull final String testFrameworkName) throws ExecutionException { // Console + final String splitterPropertyName = testFrameworkName + ".Splitter.Proportion"; final SMTRunnerConsoleView testRunnerConsole = new SMTRunnerConsoleView(consoleProperties, runnerSettings, configurationSettings, splitterPropertyName); testRunnerConsole.initUI(); final SMTestRunnerResultsForm resultsViewer = testRunnerConsole.getResultsViewer(); // attach listeners - attachEventsProcessors(consoleProperties, resultsViewer, resultsViewer.getStatisticsPane(), processHandler); + attachEventsProcessors(consoleProperties, resultsViewer, + resultsViewer.getStatisticsPane(), + processHandler, testFrameworkName); testRunnerConsole.attachToProcess(processHandler); return testRunnerConsole; @@ -113,22 +121,29 @@ public class SMTestRunnerConnectionUtil { * } * * + * + * NB: For debug purposes please enable "debug mode". In this mode test runner will also validate + * consistency of test events communication protocol and throw assertion errors. To enable debug mode + * please set system property idea.smrunner.debug=true + * * @param processHandler Process handler * @param commandLineState Command line state * @param config User run configuration settings - * @param splitterPropertyName This property will be used for storing splitter position. + * @param testFrameworkName Is used to store(project level) latest value of testTree/consoleTab splitter and other settings * @return Console view * @throws ExecutionException If IDEA cannot execute process this Exception will - * be catched and shown in error message box + * be caught and shown in error message box */ public static ConsoleView attachRunner(@NotNull final ProcessHandler processHandler, @NotNull final CommandLineState commandLineState, @NotNull final RuntimeConfiguration config, - @Nullable final String splitterPropertyName) throws ExecutionException { - final TestConsoleProperties consoleProperties = new SMTRunnerConsoleProperties(config); + @NotNull final String testFrameworkName) throws ExecutionException { + // final String testFrameworkName + final TestConsoleProperties consoleProperties = new SMTRunnerConsoleProperties(config, testFrameworkName); return attachRunner(processHandler, consoleProperties, - commandLineState.getRunnerSettings(), commandLineState.getConfigurationSettings(), splitterPropertyName); + commandLineState.getRunnerSettings(), + commandLineState.getConfigurationSettings(), testFrameworkName); } /** @@ -144,14 +159,16 @@ public class SMTestRunnerConnectionUtil { private static ProcessHandler attachEventsProcessors(@NotNull final TestConsoleProperties consoleProperties, final SMTestRunnerResultsForm resultsViewer, final StatisticsPanel statisticsPane, - final ProcessHandler processHandler) + final ProcessHandler processHandler, + @NotNull final String testFrameworkName) throws ExecutionException { //build messages consumer - final OutputToGeneralTestEventsConverter outputConsumer = new OutputToGeneralTestEventsConverter(); + final OutputToGeneralTestEventsConverter outputConsumer = new OutputToGeneralTestEventsConverter(testFrameworkName); //events processor - final GeneralToSMTRunnerEventsConvertor eventsProcessor = new GeneralToSMTRunnerEventsConvertor(resultsViewer.getTestsRootNode()); + final GeneralToSMTRunnerEventsConvertor eventsProcessor = new GeneralToSMTRunnerEventsConvertor(resultsViewer.getTestsRootNode(), + testFrameworkName); // ui actions final SMTRunnerUIActionsHandler uiActionsHandler = new SMTRunnerUIActionsHandler(consoleProperties); diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/GeneralTestEventsProcessor.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/GeneralTestEventsProcessor.java index 7fa143269bd9..9cc012aef90d 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/GeneralTestEventsProcessor.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/GeneralTestEventsProcessor.java @@ -31,18 +31,35 @@ import org.jetbrains.annotations.Nullable; public interface GeneralTestEventsProcessor extends Disposable { void onTestsCountInSuite(final int count); - void onTestStarted(final String testName, @Nullable final String locationUrl); - void onTestFinished(final String testName, final int duration); - void onTestFailure(final String testName, final String localizedMessage, final String stackTrace, + void onTestStarted(@NotNull final String testName, + @Nullable final String locationUrl); + + void onTestFinished(@NotNull final String testName, + final int duration); + + void onTestFailure(@NotNull final String testName, + @NotNull final String localizedMessage, + @Nullable final String stackTrace, final boolean testError); - void onTestIgnored(final String testName, final String ignoreComment, @Nullable final String stackTrace); - void onTestOutput(final String testName, final String text, final boolean stdOut); - void onSuiteStarted(final String suiteName, @Nullable final String locationUrl); - void onSuiteFinished(final String suiteName); + void onTestIgnored(@NotNull final String testName, + @NotNull final String ignoreComment, + @Nullable final String stackTrace); - void onUncapturedOutput(final String text, final Key outputType); - void onError(@NotNull final String localizedMessage, @Nullable final String stackTrace); + void onTestOutput(@NotNull final String testName, + @NotNull final String text, + final boolean stdOut); + + void onSuiteStarted(@NotNull final String suiteName, + @Nullable final String locationUrl); + + void onSuiteFinished(@NotNull final String suiteName); + + void onUncapturedOutput(@NotNull final String text, + final Key outputType); + + void onError(@NotNull final String localizedMessage, + @Nullable final String stackTrace); // Custom progress statistics @@ -51,7 +68,8 @@ public interface GeneralTestEventsProcessor extends Disposable { * If name is null statistics will be switched to normal mode * @param testCount - 0 will be considered as unknown tests number */ - void onCustomProgressTestsCategory(@Nullable final String categoryName, final int testCount); + void onCustomProgressTestsCategory(@Nullable final String categoryName, + final int testCount); void onCustomProgressTestStarted(); void onCustomProgressTestFailed(); } \ No newline at end of file diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/GeneralToSMTRunnerEventsConvertor.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/GeneralToSMTRunnerEventsConvertor.java index 90dcd4520199..b96b6002905f 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/GeneralToSMTRunnerEventsConvertor.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/GeneralToSMTRunnerEventsConvertor.java @@ -18,6 +18,7 @@ package com.intellij.execution.testframework.sm.runner; import com.intellij.execution.process.ProcessOutputTypes; import com.intellij.execution.testframework.AbstractTestProxy; import com.intellij.execution.testframework.sm.SMRunnerUtil; +import com.intellij.execution.testframework.sm.SMTestRunnerConnectionUtil; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; @@ -43,10 +44,13 @@ public class GeneralToSMTRunnerEventsConvertor implements GeneralTestEventsProce private final TestSuiteStack mySuitesStack = new TestSuiteStack(); private final List myEventsListeners = new ArrayList(); private final SMTestProxy myTestsRootNode; + private final String myTestFrameworkName; private boolean myIsTestingFinished; - public GeneralToSMTRunnerEventsConvertor(@NotNull final SMTestProxy testsRootNode) { + public GeneralToSMTRunnerEventsConvertor(@NotNull final SMTestProxy testsRootNode, + @NotNull final String testFrameworkName) { myTestsRootNode = testsRootNode; + myTestFrameworkName = testFrameworkName; } public void addEventsListener(final SMTRunnerEventsListener listener) { @@ -92,15 +96,21 @@ public class GeneralToSMTRunnerEventsConvertor implements GeneralTestEventsProce }); } - public void onTestStarted(final String testName, final String locationUrl) { + public void onTestStarted(@NotNull final String testName, + @Nullable final String locationUrl) { SMRunnerUtil.addToInvokeLater(new Runnable() { public void run() { final String fullName = getFullTestName(testName); if (myRunningTestsFullNameToProxy.containsKey(fullName)) { - //Dublicated event - LOG.warn("Test [" + fullName + "] has been already started"); - return; + //Duplicated event + final boolean inDebugMode = SMTestRunnerConnectionUtil.isInDebugMode(); + logProblem("Test [" + fullName + "] has been already started", + inDebugMode); + + if (inDebugMode) { + return; + } } final SMTestProxy parentSuite = getCurrentSuite(); @@ -120,7 +130,7 @@ public class GeneralToSMTRunnerEventsConvertor implements GeneralTestEventsProce }); } - public void onSuiteStarted(final String suiteName, @Nullable final String locationUrl) { + public void onSuiteStarted(@NotNull final String suiteName, @Nullable final String locationUrl) { SMRunnerUtil.addToInvokeLater(new Runnable() { public void run() { final SMTestProxy parentSuite = getCurrentSuite(); @@ -139,14 +149,16 @@ public class GeneralToSMTRunnerEventsConvertor implements GeneralTestEventsProce }); } - public void onTestFinished(final String testName, final int duration) { + public void onTestFinished(@NotNull final String testName, + @Nullable final int duration) { SMRunnerUtil.addToInvokeLater(new Runnable() { public void run() { final String fullTestName = getFullTestName(testName); final SMTestProxy testProxy = getProxyByFullTestName(fullTestName); + if (testProxy == null) { - LOG.warn("Test wasn't started! TestFinished event: name = {" + testName + "}. " + - cannotFindFullTestNameMsg(fullTestName)); + logProblem("Test wasn't started! TestFinished event: name = {" + testName + "}. " + + cannotFindFullTestNameMsg(fullTestName)); return; } @@ -160,7 +172,7 @@ public class GeneralToSMTRunnerEventsConvertor implements GeneralTestEventsProce }); } - public void onSuiteFinished(final String suiteName) { + public void onSuiteFinished(@NotNull final String suiteName) { SMRunnerUtil.addToInvokeLater(new Runnable() { public void run() { final SMTestProxy mySuite = mySuitesStack.popSuite(suiteName); @@ -174,7 +186,7 @@ public class GeneralToSMTRunnerEventsConvertor implements GeneralTestEventsProce }); } - public void onUncapturedOutput(final String text, final Key outputType) { + public void onUncapturedOutput(@NotNull final String text, final Key outputType) { SMRunnerUtil.addToInvokeLater(new Runnable() { public void run() { final SMTestProxy currentProxy = findCurrentTestOrSuite(); @@ -225,27 +237,50 @@ public class GeneralToSMTRunnerEventsConvertor implements GeneralTestEventsProce }); } - public void onTestFailure(final String testName, - final String localizedMessage, final String stackTrace, + public void onTestFailure(@NotNull final String testName, + @NotNull final String localizedMessage, + @Nullable final String stackTrace, final boolean isTestError) { SMRunnerUtil.addToInvokeLater(new Runnable() { public void run() { + final boolean inDebugMode = SMTestRunnerConnectionUtil.isInDebugMode(); + final String fullTestName = getFullTestName(testName); - final SMTestProxy testProxy = getProxyByFullTestName(fullTestName); + SMTestProxy testProxy = getProxyByFullTestName(fullTestName); if (testProxy == null) { - LOG.warn("Test wasn't started! TestFailure event: name = {" + testName + "}" + - ", message = {" + localizedMessage + "}" + - ", stackTrace = {" + stackTrace + "}. " + - cannotFindFullTestNameMsg(fullTestName)); - return; - } - // if wasn't processed - if (myFailedTestsSet.contains(testProxy)) { - // dublicate message - LOG.warn("Duplicate failure for test [" + fullTestName + "]: msg = " + localizedMessage + ", stacktrace = " + stackTrace); - return; + logProblem("Test wasn't started! TestFailure event: name = {" + testName + "}" + + ", message = {" + localizedMessage + "}" + + ", stackTrace = {" + stackTrace + "}. " + + cannotFindFullTestNameMsg(fullTestName), + inDebugMode); + if (inDebugMode) { + return; + } else { + // try to fix the problem: + if (!myFailedTestsSet.contains(testProxy)) { + // if hasn't been already reported + // 1. report + onTestStarted(testName, null); + // 2. add failure + testProxy = getProxyByFullTestName(fullTestName); + } + } } + // check if has been already processed + if (myFailedTestsSet.contains(testProxy)) { + // duplicate message + logProblem("Duplicate failure for test [" + fullTestName + "]: msg = " + localizedMessage + ", stacktrace = " + stackTrace, + inDebugMode); + + if (inDebugMode) { + return; + } + } + + if (testProxy == null) { + return; + } testProxy.setTestFailed(localizedMessage, stackTrace, isTestError); @@ -257,21 +292,35 @@ public class GeneralToSMTRunnerEventsConvertor implements GeneralTestEventsProce }); } - public void onTestIgnored(@NotNull final String testName, + public void onTestIgnored(@NotNull final String testName, @NotNull final String ignoreComment, @Nullable final String stackTrace) { SMRunnerUtil.addToInvokeLater(new Runnable() { public void run() { final String fullTestName = getFullTestName(testName); - final SMTestProxy testProxy = getProxyByFullTestName(fullTestName); + SMTestProxy testProxy = getProxyByFullTestName(fullTestName); + if (testProxy == null) { + final boolean debugMode = SMTestRunnerConnectionUtil.isInDebugMode(); + logProblem("Test wasn't started! " + + "TestIgnored event: name = {" + testName + "}, " + + "message = {" + ignoreComment + "}. " + + cannotFindFullTestNameMsg(fullTestName), + debugMode); + if (debugMode) { + return; + } else { + // try to fix + // 1. report test opened + onTestStarted(testName, null); + + // 2. report failure + testProxy = getProxyByFullTestName(fullTestName); + } + + } if (testProxy == null) { - LOG.warn("Test wasn't started! " + - "TestIgnored event: name = {" + testName + "}, " + - "message = {" + ignoreComment + "}. " + - cannotFindFullTestNameMsg(fullTestName)); return; } - testProxy.setTestIgnored(ignoreComment, stackTrace); // fire event @@ -280,17 +329,17 @@ public class GeneralToSMTRunnerEventsConvertor implements GeneralTestEventsProce }); } - public void onTestOutput(final String testName, - final String text, final boolean stdOut) { + public void onTestOutput(@NotNull final String testName, + @NotNull final String text, final boolean stdOut) { SMRunnerUtil.addToInvokeLater(new Runnable() { public void run() { final String fullTestName = getFullTestName(testName); final SMTestProxy testProxy = getProxyByFullTestName(fullTestName); if (testProxy == null) { - LOG.warn("Test wasn't started! TestOutput event: name = {" + testName + "}, " + - "isStdOut = " + stdOut + ", " + - "text = {" + text + "}. " + - cannotFindFullTestNameMsg(fullTestName)); + logProblem("Test wasn't started! TestOutput event: name = {" + testName + "}, " + + "isStdOut = " + stdOut + ", " + + "text = {" + text + "}. " + + cannotFindFullTestNameMsg(fullTestName)); return; } @@ -321,7 +370,7 @@ public class GeneralToSMTRunnerEventsConvertor implements GeneralTestEventsProce // current suite shouldn't be null otherwise test runner isn't correct // or may be we are in debug mode - LOG.warn("Current suite is undefined. Root suite will be used."); + logProblem("Current suite is undefined. Root suite will be used."); return myTestsRootNode; } @@ -450,7 +499,7 @@ public class GeneralToSMTRunnerEventsConvertor implements GeneralTestEventsProce if (!myRunningTestsFullNameToProxy.isEmpty()) { final Application application = ApplicationManager.getApplication(); if (!application.isHeadlessEnvironment() && !application.isUnitTestMode()) { - LOG.warn("Not all events were processed! " + dumpRunningTestsNames()); + logProblem("Not all events were processed! " + dumpRunningTestsNames()); } } myRunningTestsFullNameToProxy.clear(); @@ -474,4 +523,21 @@ public class GeneralToSMTRunnerEventsConvertor implements GeneralTestEventsProce } return currentProxy; } + + public static String getTFrameworkPrefix(final String testFrameworkName) { + return "[" + testFrameworkName + "]: "; + } + + private void logProblem(final String msg) { + logProblem(msg, SMTestRunnerConnectionUtil.isInDebugMode()); + } + private void logProblem(final String msg, boolean throwError) { + final String text = getTFrameworkPrefix(myTestFrameworkName) + msg; + if (throwError) { + LOG.error(text); + } + else { + LOG.warn(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 1704f6e35bf1..fea168f9ef6f 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 @@ -29,6 +29,8 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import static com.intellij.execution.testframework.sm.runner.GeneralToSMTRunnerEventsConvertor.getTFrameworkPrefix; + /** * @author Roman Chernyatchik * @@ -42,6 +44,7 @@ public class OutputToGeneralTestEventsConverter implements ProcessOutputConsumer private GeneralTestEventsProcessor myProcessor; private final MyServiceMessageVisitor myServiceMessageVisitor; + private final String myTestFrameworkName; private static class OutputChunk { private final Key myKey; @@ -67,7 +70,8 @@ public class OutputToGeneralTestEventsConverter implements ProcessOutputConsumer private final List myOutputChunks; - public OutputToGeneralTestEventsConverter() { + public OutputToGeneralTestEventsConverter(@NotNull final String testFrameworkName) { + myTestFrameworkName = testFrameworkName; myServiceMessageVisitor = new MyServiceMessageVisitor(); myOutputChunks = new ArrayList(); } @@ -165,11 +169,14 @@ public class OutputToGeneralTestEventsConverter implements ProcessOutputConsumer } } catch (ParseException e) { - LOG.error(e); + + LOG.error(getTFrameworkPrefix(myTestFrameworkName) + "Parsing error.", e); } } private void fireOnTestStarted(final String testName, @Nullable final String locationUrl) { + assertNotNull(testName); + // local variable is used to prevent concurrent modification final GeneralTestEventsProcessor processor = myProcessor; if (processor != null) { @@ -179,6 +186,8 @@ public class OutputToGeneralTestEventsConverter implements ProcessOutputConsumer private void fireOnTestFailure(final String testName, final String localizedMessage, final String stackTrace, final boolean isTestError) { + assertNotNull(testName); + assertNotNull(localizedMessage); // local variable is used to prevent concurrent modification final GeneralTestEventsProcessor processor = myProcessor; @@ -189,6 +198,8 @@ public class OutputToGeneralTestEventsConverter implements ProcessOutputConsumer private void fireOnTestIgnored(final String testName, final String ignoreComment, @Nullable final String details) { + assertNotNull(testName); + assertNotNull(ignoreComment); // local variable is used to prevent concurrent modification final GeneralTestEventsProcessor processor = myProcessor; @@ -198,6 +209,8 @@ public class OutputToGeneralTestEventsConverter implements ProcessOutputConsumer } private void fireOnTestFinished(final String testName, final int duration) { + assertNotNull(testName); + // local variable is used to prevent concurrent modification final GeneralTestEventsProcessor processor = myProcessor; if (processor != null) { @@ -205,7 +218,10 @@ public class OutputToGeneralTestEventsConverter implements ProcessOutputConsumer } } - private void fireOnCustomProgressTestsCategory(@NotNull final String categoryName, int testsCount) { + private void fireOnCustomProgressTestsCategory(final String categoryName, + int testsCount) { + assertNotNull(categoryName); + final GeneralTestEventsProcessor processor = myProcessor; if (processor != null) { final boolean disableCustomMode = StringUtil.isEmpty(categoryName); @@ -229,6 +245,9 @@ public class OutputToGeneralTestEventsConverter implements ProcessOutputConsumer } private void fireOnTestOutput(final String testName, final String text, final boolean stdOut) { + assertNotNull(testName); + assertNotNull(text); + // local variable is used to prevent concurrent modification final GeneralTestEventsProcessor processor = myProcessor; if (processor != null) { @@ -237,6 +256,8 @@ public class OutputToGeneralTestEventsConverter implements ProcessOutputConsumer } private void fireOnUncapturedOutput(final String text, final Key outputType) { + assertNotNull(text); + // local variable is used to prevent concurrent modification final GeneralTestEventsProcessor processor = myProcessor; if (processor != null) { @@ -253,6 +274,8 @@ public class OutputToGeneralTestEventsConverter implements ProcessOutputConsumer } private void fireOnSuiteStarted(final String suiteName, @Nullable final String locationUrl) { + assertNotNull(suiteName); + // local variable is used to prevent concurrent modification final GeneralTestEventsProcessor processor = myProcessor; if (processor != null) { @@ -261,6 +284,8 @@ public class OutputToGeneralTestEventsConverter implements ProcessOutputConsumer } private void fireOnSuiteFinished(final String suiteName) { + assertNotNull(suiteName); + // local variable is used to prevent concurrent modification final GeneralTestEventsProcessor processor = myProcessor; if (processor != null) { @@ -268,8 +293,9 @@ public class OutputToGeneralTestEventsConverter implements ProcessOutputConsumer } } - private void fireOnErrorMsg(@NotNull final String localizedMessage, + private void fireOnErrorMsg(final String localizedMessage, @Nullable final String stackTrace) { + assertNotNull(localizedMessage); // local variable is used to prevent concurrent modification final GeneralTestEventsProcessor processor = myProcessor; @@ -278,6 +304,12 @@ public class OutputToGeneralTestEventsConverter implements ProcessOutputConsumer } } + private void assertNotNull(final String s) { + if (s == null) { + LOG.error(getTFrameworkPrefix(myTestFrameworkName) + " @NotNull value is expected."); + } + } + private class MyServiceMessageVisitor extends DefaultServiceMessageVisitor { @NonNls public static final String KEY_TESTS_COUNT = "testCount"; @NonNls private static final String ATTR_KEY_TEST_ERROR = "error"; @@ -306,14 +338,15 @@ public class OutputToGeneralTestEventsConverter implements ProcessOutputConsumer } @Nullable - private String fetchTestLocation(TestSuiteStarted suiteStarted) { + private String fetchTestLocation(final TestSuiteStarted suiteStarted) { final Map attrs = suiteStarted.getAttributes(); final String location = attrs.get(ATTR_KEY_LOCATION_URL); if (location == null) { // try old API final String oldLocation = attrs.get(ATTR_KEY_LOCATION_URL_OLD); if (oldLocation != null) { - LOG.error("Test Runner API was changed for TeamCity 5.0 compatibility. Please use 'locationHint' attribute instead of 'location'."); + LOG.error(getTFrameworkPrefix(myTestFrameworkName) + + "Test Runner API was changed for TeamCity 5.0 compatibility. Please use 'locationHint' attribute instead of 'location'."); return oldLocation; } return null; @@ -441,7 +474,7 @@ public class OutputToGeneralTestEventsConverter implements ProcessOutputConsumer try { count = Integer.parseInt(countStr); } catch (NumberFormatException ex) { - LOG.error(ex); + LOG.error(getTFrameworkPrefix(myTestFrameworkName) + "Parse integer error.", ex); } return count; } diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTRunnerConsoleProperties.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTRunnerConsoleProperties.java index f685d5d4ee86..34f39808194b 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTRunnerConsoleProperties.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTRunnerConsoleProperties.java @@ -21,19 +21,22 @@ import com.intellij.ide.util.PropertiesComponent; import com.intellij.util.config.Storage; import com.intellij.xdebugger.XDebugSession; import com.intellij.xdebugger.XDebuggerManager; -import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.Nullable; /** * @author: Roman Chernyatchik */ public class SMTRunnerConsoleProperties extends TestConsoleProperties { - @NonNls private static final String PREFIX = "RubyTestUnitSupport."; private final RuntimeConfiguration myConfiguration; - public SMTRunnerConsoleProperties(final RuntimeConfiguration config) + /** + * @param config + * @param testFrameworkName Prefix for storage which keeps runner settings. E.g. "RubyTestUnit" + */ + public SMTRunnerConsoleProperties(final RuntimeConfiguration config, + final String testFrameworkName) { - super(new Storage.PropertiesComponentStorage(PREFIX, PropertiesComponent.getInstance()), config.getProject()); + super(new Storage.PropertiesComponentStorage(testFrameworkName + "Support.", PropertiesComponent.getInstance()), config.getProject()); myConfiguration = config; } diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTestProxy.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTestProxy.java index 76341de59ea9..f7eb3bb6f0ff 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTestProxy.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTestProxy.java @@ -282,7 +282,8 @@ public class SMTestProxy extends CompositePrintable implements PrintableTestProx } public void setTestFailed(@NotNull final String localizedMessage, - @NotNull final String stackTrace, final boolean testError) { + @Nullable final String stackTrace, + final boolean testError) { myState = testError ? new TestErrorState(localizedMessage, stackTrace) : new TestFailedState(localizedMessage, stackTrace); diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/states/TestErrorState.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/states/TestErrorState.java index 0d817970490a..a89c2bda9678 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/states/TestErrorState.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/states/TestErrorState.java @@ -15,11 +15,14 @@ */ package com.intellij.execution.testframework.sm.runner.states; +import org.jetbrains.annotations.Nullable; + /** * @author Roman Chernyatchik */ public class TestErrorState extends TestFailedState { - public TestErrorState(final String localizedMessage, final String stackTrace) { + public TestErrorState(@Nullable final String localizedMessage, + @Nullable final String stackTrace) { super(localizedMessage, stackTrace); } diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTRunnerConsoleView.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTRunnerConsoleView.java index 521c390ffdd8..21f0ddf8eca9 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTRunnerConsoleView.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTRunnerConsoleView.java @@ -43,6 +43,13 @@ public class SMTRunnerConsoleView extends BaseTestsOutputConsoleView { this(consoleProperties, runnerSettings, configurationPerRunnerSettings, null); } + /** + * + * @param consoleProperties + * @param runnerSettings + * @param configurationPerRunnerSettings + * @param splitterProperty Key to store(project level) latest value of testTree/consoleTab splitter. E.g. "RSpec.Splitter.Proportion" + */ public SMTRunnerConsoleView(final TestConsoleProperties consoleProperties, final RunnerSettings runnerSettings, final ConfigurationPerRunnerSettings configurationPerRunnerSettings, @Nullable final String splitterProperty) { diff --git a/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/BaseSMTRunnerTestCase.java b/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/BaseSMTRunnerTestCase.java index d5ae3b05c100..e6552e9b9f61 100644 --- a/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/BaseSMTRunnerTestCase.java +++ b/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/BaseSMTRunnerTestCase.java @@ -81,7 +81,7 @@ public abstract class BaseSMTRunnerTestCase extends LightPlatformTestCase { protected TestConsoleProperties createConsoleProperties() { final RuntimeConfiguration runConfiguration = createRunConfiguration(); - final TestConsoleProperties consoleProperties = new SMTRunnerConsoleProperties(runConfiguration); + final TestConsoleProperties consoleProperties = new SMTRunnerConsoleProperties(runConfiguration, "SMRunnerTests"); TestConsoleProperties.HIDE_PASSED_TESTS.set(consoleProperties, false); return consoleProperties; diff --git a/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/GeneralToSMTRunnerEventsConvertorTest.java b/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/GeneralToSMTRunnerEventsConvertorTest.java index 0a17d9b71c46..7e44c03084ee 100644 --- a/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/GeneralToSMTRunnerEventsConvertorTest.java +++ b/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/GeneralToSMTRunnerEventsConvertorTest.java @@ -53,7 +53,7 @@ public class GeneralToSMTRunnerEventsConvertorTest extends BaseSMTRunnerTestCase myConsole = new SMTRunnerConsoleView(consoleProperties, environment.getRunnerSettings(), environment.getConfigurationSettings()); myConsole.initUI(); myResultsViewer = myConsole.getResultsViewer(); - myEventsProcessor = new GeneralToSMTRunnerEventsConvertor(myResultsViewer.getTestsRootNode()); + myEventsProcessor = new GeneralToSMTRunnerEventsConvertor(myResultsViewer.getTestsRootNode(), "SMTestFramework"); myEventsProcessor.addEventsListener(myResultsViewer); myTreeModel = myResultsViewer.getTreeView().getModel(); diff --git a/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/SMTRunnerConsoleTest.java b/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/SMTRunnerConsoleTest.java index ea0cec21d675..4a5a46eceb63 100644 --- a/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/SMTRunnerConsoleTest.java +++ b/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/SMTRunnerConsoleTest.java @@ -72,7 +72,7 @@ public class SMTRunnerConsoleTest extends BaseSMTRunnerTestCase { myConsole.initUI(); myResultsViewer = myConsole.getResultsViewer(); myRootSuite = myResultsViewer.getTestsRootNode(); - myEventsProcessor = new GeneralToSMTRunnerEventsConvertor(myResultsViewer.getTestsRootNode()); + myEventsProcessor = new GeneralToSMTRunnerEventsConvertor(myResultsViewer.getTestsRootNode(), "SMTestFramework"); myEventsProcessor.onStartTesting(); } diff --git a/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/ui/SMTestRunnerResultsFormTest.java b/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/ui/SMTestRunnerResultsFormTest.java index aa25e75e99c8..a4f7bfc180ca 100644 --- a/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/ui/SMTestRunnerResultsFormTest.java +++ b/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/ui/SMTestRunnerResultsFormTest.java @@ -59,7 +59,7 @@ public class SMTestRunnerResultsFormTest extends BaseSMTRunnerTestCase { myConsole.initUI(); myResultsViewer = myConsole.getResultsViewer(); myTestsRootNode = myResultsViewer.getTestsRootNode(); - myEventsProcessor = new GeneralToSMTRunnerEventsConvertor(myResultsViewer.getTestsRootNode()); + myEventsProcessor = new GeneralToSMTRunnerEventsConvertor(myResultsViewer.getTestsRootNode(), "SMTestFramework"); myEventsProcessor.addEventsListener(myResultsViewer); myTreeModel = myResultsViewer.getTreeView().getModel(); } diff --git a/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/ui/TestsPresentationUtilTest.java b/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/ui/TestsPresentationUtilTest.java index 4b252144638e..efb7f16e7b76 100644 --- a/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/ui/TestsPresentationUtilTest.java +++ b/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/ui/TestsPresentationUtilTest.java @@ -638,7 +638,7 @@ public class TestsPresentationUtilTest extends BaseSMTRunnerTestCase { public MyRenderer(final boolean isPaused, final UITestUtil.FragmentsContainer fragmentsContainer) { - super(new SMTRunnerConsoleProperties(createRunConfiguration()) { + super(new SMTRunnerConsoleProperties(createRunConfiguration(), "SMRunnerTests") { @Override public boolean isPaused() { return isPaused;