/* * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.intellij.execution.testframework.sm.runner; import com.intellij.execution.executors.DefaultRunExecutor; import com.intellij.execution.runners.ExecutionEnvironment; import com.intellij.execution.testframework.Filter; import com.intellij.execution.testframework.TestConsoleProperties; import com.intellij.execution.testframework.actions.AbstractRerunFailedTestsAction; import com.intellij.execution.testframework.export.TestResultsXmlFormatter; import com.intellij.execution.testframework.sm.Marker; import com.intellij.execution.testframework.sm.runner.events.*; import com.intellij.execution.testframework.sm.runner.history.ImportedToGeneralTestEventsConverter; import com.intellij.execution.testframework.sm.runner.ui.MockPrinter; import com.intellij.execution.testframework.sm.runner.ui.SMTRunnerConsoleView; import com.intellij.execution.testframework.sm.runner.ui.SMTRunnerTestTreeView; 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 com.intellij.openapi.util.io.FileUtilRt; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.TreeModel; import javax.xml.transform.OutputKeys; import javax.xml.transform.TransformerFactory; import javax.xml.transform.sax.SAXTransformerFactory; import javax.xml.transform.sax.TransformerHandler; import javax.xml.transform.stream.StreamResult; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.StringReader; import java.util.List; /** * @author Roman Chernyatchik */ public class GeneralToSMTRunnerEventsConvertorTest extends BaseSMTRunnerTestCase { private SMTRunnerConsoleView myConsole; private GeneralToSMTRunnerEventsConvertor myEventsProcessor; private TreeModel myTreeModel; private SMTestRunnerResultsForm myResultsViewer; private MockPrinter myMockResettablePrinter; private File myTempFile; private class MyConsoleView extends SMTRunnerConsoleView { private final TestsOutputConsolePrinter myTestsOutputConsolePrinter; private MyConsoleView(final TestConsoleProperties consoleProperties, final ExecutionEnvironment environment) { super(consoleProperties); myTestsOutputConsolePrinter = new TestsOutputConsolePrinter(MyConsoleView.this, consoleProperties, null) { @Override public void print(final String text, final ConsoleViewContentType contentType) { myMockResettablePrinter.print(text, contentType); } }; } @Override public TestsOutputConsolePrinter getPrinter() { return myTestsOutputConsolePrinter; } } @Override protected void setUp() throws Exception { super.setUp(); TestConsoleProperties consoleProperties = createConsoleProperties(); TestConsoleProperties.HIDE_PASSED_TESTS.set(consoleProperties, false); TestConsoleProperties.OPEN_FAILURE_LINE.set(consoleProperties, false); TestConsoleProperties.SCROLL_TO_SOURCE.set(consoleProperties, false); TestConsoleProperties.SELECT_FIRST_DEFECT.set(consoleProperties, false); TestConsoleProperties.TRACK_RUNNING_TEST.set(consoleProperties, false); final ExecutionEnvironment environment = new ExecutionEnvironment(); myMockResettablePrinter = new MockPrinter(true); myConsole = new MyConsoleView(consoleProperties, environment); myConsole.initUI(); myResultsViewer = myConsole.getResultsViewer(); myEventsProcessor = new GeneralToSMTRunnerEventsConvertor(consoleProperties.getProject(), myResultsViewer.getTestsRootNode(), "SMTestFramework"); myEventsProcessor.addEventsListener(myResultsViewer); myTreeModel = myResultsViewer.getTreeView().getModel(); myEventsProcessor.onStartTesting(); } @Override protected void tearDown() throws Exception { Disposer.dispose(myEventsProcessor); Disposer.dispose(myConsole); super.tearDown(); if (myTempFile != null) { assertFalse(myTempFile.exists()); } } public void testOnStartedTesting() { final Object rootTreeNode = myTreeModel.getRoot(); assertEquals(0, myTreeModel.getChildCount(rootTreeNode)); final SMTRunnerNodeDescriptor nodeDescriptor = (SMTRunnerNodeDescriptor)((DefaultMutableTreeNode)rootTreeNode).getUserObject(); assertFalse(nodeDescriptor.expandOnDoubleClick()); final SMTestProxy rootProxy = SMTRunnerTestTreeView.getTestProxyFor(rootTreeNode); assertNotNull(rootProxy); assertTrue(rootProxy.wasLaunched()); assertTrue(rootProxy.isInProgress()); assertTrue(rootProxy.isLeaf()); assertEquals("[root]", rootTreeNode.toString()); } public void testOnTestStarted() throws InterruptedException { onTestStarted("some_test"); final String fullName = myEventsProcessor.getFullTestName("some_test"); final SMTestProxy proxy = myEventsProcessor.getProxyByFullTestName(fullName); assertNotNull(proxy); assertTrue(proxy.isInProgress()); final Object rootTreeNode = (myTreeModel.getRoot()); assertEquals(1, myTreeModel.getChildCount(rootTreeNode)); final SMTestProxy rootProxy = SMTRunnerTestTreeView.getTestProxyFor(rootTreeNode); assertNotNull(rootProxy); assertSameElements(rootProxy.getChildren(), proxy); onTestStarted("some_test2"); final String fullName2 = myEventsProcessor.getFullTestName("some_test2"); final SMTestProxy proxy2 = myEventsProcessor.getProxyByFullTestName(fullName2); assertSameElements(rootProxy.getChildren(), proxy, proxy2); } public void testOnTestStarted_Twice() { onTestStarted("some_test"); onTestStarted("some_test"); assertEquals(1, myEventsProcessor.getRunningTestsQuantity()); } public void testOnTestStarted_WithLocation() throws InterruptedException { onTestStarted("some_test", "file://some/file.rb:1"); final String fullName = myEventsProcessor.getFullTestName("some_test"); final SMTestProxy proxy = myEventsProcessor.getProxyByFullTestName(fullName); assertNotNull(proxy); assertEquals("file://some/file.rb:1", proxy.getLocationUrl()); } public void testOnTestFailure() { onTestStarted("some_test"); myEventsProcessor.onTestFailure(new TestFailedEvent("some_test", "", "", false, null, null)); final String fullName = myEventsProcessor.getFullTestName("some_test"); final SMTestProxy proxy = myEventsProcessor.getProxyByFullTestName(fullName); assertNotNull(proxy); assertTrue(proxy.isDefect()); assertFalse(proxy.isInProgress()); } public void testOnTestComparisonFailure() { onTestStarted("some_test"); myEventsProcessor.onTestFailure(new TestFailedEvent("some_test", "", "", false, "actual", "expected")); final String fullName = myEventsProcessor.getFullTestName("some_test"); final SMTestProxy proxy = myEventsProcessor.getProxyByFullTestName(fullName); assertNotNull(proxy); assertTrue(proxy.isDefect()); 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)); final String fullName = myEventsProcessor.getFullTestName("some_test"); final SMTestProxy proxy = myEventsProcessor.getProxyByFullTestName(fullName); assertNotNull(proxy); assertTrue(proxy.isDefect()); assertFalse(proxy.isInProgress()); } public void testOnTestFailure_Twice() { myMockResettablePrinter.resetIfNecessary(); onTestStarted("some_test"); myEventsProcessor.onTestFailure(new TestFailedEvent("some_test", "msg 1", "trace 1", false, null, null)); myEventsProcessor.onTestFailure(new TestFailedEvent("some_test", "msg 2", "trace 2", false, null, null)); assertEquals(1, myEventsProcessor.getRunningTestsQuantity()); assertEquals("\nmsg 1\ntrace 1\n\nmsg 2\ntrace 2\n", myMockResettablePrinter.getStdErr()); } public void testOnTestError() { onTestStarted("some_test"); myEventsProcessor.onTestFailure(new TestFailedEvent("some_test", "", "", true, null, null)); final String fullName = myEventsProcessor.getFullTestName("some_test"); final SMTestProxy proxy = myEventsProcessor.getProxyByFullTestName(fullName); assertNotNull(proxy); assertTrue(proxy.isDefect()); assertFalse(proxy.isInProgress()); } public void testOnTestIgnored() { onTestStarted("some_test"); myEventsProcessor.onTestIgnored(new TestIgnoredEvent("some_test", "", null)); final String fullName = myEventsProcessor.getFullTestName("some_test"); final SMTestProxy proxy = myEventsProcessor.getProxyByFullTestName(fullName); assertNotNull(proxy); assertTrue(proxy.isDefect()); assertFalse(proxy.isInProgress()); final Filter filter = AbstractRerunFailedTestsAction.getFailuresFilter(myConsole.getProperties()); assertFalse(filter.shouldAccept(proxy)); } public void testOnTestFinished() { onTestStarted("some_test"); final String fullName = myEventsProcessor.getFullTestName("some_test"); final SMTestProxy proxy = myEventsProcessor.getProxyByFullTestName(fullName); myEventsProcessor.onTestFinished(new TestFinishedEvent("some_test", 10l)); assertEquals(0, myEventsProcessor.getRunningTestsQuantity()); assertNotNull(proxy); assertFalse(proxy.isDefect()); assertFalse(proxy.isInProgress()); //Tree final Object rootTreeNode = myTreeModel.getRoot(); assertEquals(1, myTreeModel.getChildCount(rootTreeNode)); final SMTestProxy rootProxy = SMTRunnerTestTreeView.getTestProxyFor(rootTreeNode); assertNotNull(rootProxy); assertSameElements(rootProxy.getChildren(), proxy); } //TODO[romeo] catch assertion //public void testFinished_Twice() { // myEventsProcessor.onTestStarted("some_test"); // myEventsProcessor.onTestFinished("some_test"); // myEventsProcessor.onTestFinished("some_test"); // // assertEquals(1, myEventsProcessor.getTestsCurrentCount()); // assertEquals(0, myEventsProcessor.getRunningTestsFullNameToProxy().size()); // assertEquals(0, myEventsProcessor.getFailedTestsSet().size()); // //} public void testOnTestFinished_EmptySuite() { myEventsProcessor.onFinishTesting(); //Tree final Object rootTreeNode = myTreeModel.getRoot(); assertEquals(0, myTreeModel.getChildCount(rootTreeNode)); final SMTestProxy rootProxy = SMTRunnerTestTreeView.getTestProxyFor(rootTreeNode); assertNotNull(rootProxy); assertFalse(rootProxy.isInProgress()); assertFalse(rootProxy.isDefect()); } public void testOnFinishedTesting_WithFailure() { onTestStarted("test"); myEventsProcessor.onTestFailure(new TestFailedEvent("test", "", "", false, null, null)); myEventsProcessor.onTestFinished(new TestFinishedEvent("test", 10l)); myEventsProcessor.onFinishTesting(); //Tree final Object rootTreeNode = myTreeModel.getRoot(); assertEquals(1, myTreeModel.getChildCount(rootTreeNode)); final SMTestProxy rootProxy = SMTRunnerTestTreeView.getTestProxyFor(rootTreeNode); assertNotNull(rootProxy); assertFalse(rootProxy.isInProgress()); assertTrue(rootProxy.isDefect()); } public void testOnFinishedTesting_WithError() { onTestStarted("test"); myEventsProcessor.onTestFailure(new TestFailedEvent("test", "", "", true, null, null)); myEventsProcessor.onTestFinished(new TestFinishedEvent("test", 10l)); myEventsProcessor.onFinishTesting(); //Tree final Object rootTreeNode = myTreeModel.getRoot(); assertEquals(1, myTreeModel.getChildCount(rootTreeNode)); final SMTestProxy rootProxy = SMTRunnerTestTreeView.getTestProxyFor(rootTreeNode); assertNotNull(rootProxy); assertFalse(rootProxy.isInProgress()); assertTrue(rootProxy.isDefect()); } public void testOnFinishedTesting_WithIgnored() { onTestStarted("test"); myEventsProcessor.onTestIgnored(new TestIgnoredEvent("test", "", null)); myEventsProcessor.onTestFinished(new TestFinishedEvent("test", 10l)); myEventsProcessor.onFinishTesting(); //Tree final Object rootTreeNode = myTreeModel.getRoot(); assertEquals(1, myTreeModel.getChildCount(rootTreeNode)); final SMTestProxy rootProxy = SMTRunnerTestTreeView.getTestProxyFor(rootTreeNode); assertNotNull(rootProxy); assertFalse(rootProxy.isInProgress()); assertTrue(rootProxy.isDefect()); } public void testOnFinishedTesting_twice() { myEventsProcessor.onFinishTesting(); final Marker finishedMarker = new Marker(); myEventsProcessor.addEventsListener(new SMTRunnerEventsAdapter(){ @Override public void onTestingFinished(@NotNull SMTestProxy.SMRootTestProxy testsRoot) { finishedMarker.set(); } }); myEventsProcessor.onFinishTesting(); assertFalse(finishedMarker.isSet()); } public void testOnSuiteStarted() { onTestSuiteStarted("suite1"); //lets check that new tests have right parent onTestStarted("test1"); final SMTestProxy test1 = myEventsProcessor.getProxyByFullTestName(myEventsProcessor.getFullTestName("test1")); assertNotNull(test1); assertEquals("suite1", test1.getParent().getName()); //lets check that new suits have righ parent onTestSuiteStarted("suite2"); onTestSuiteStarted("suite3"); onTestStarted("test2"); final SMTestProxy test2 = myEventsProcessor.getProxyByFullTestName(myEventsProcessor.getFullTestName("test2")); assertNotNull(test2); assertEquals("suite3", test2.getParent().getName()); assertEquals("suite2", test2.getParent().getParent().getName()); myEventsProcessor.onTestFinished(new TestFinishedEvent("test2", 10l)); //check that after finishing suite (suite3), current will be parent of finished suite (i.e. suite2) myEventsProcessor.onSuiteFinished(new TestSuiteFinishedEvent("suite3")); onTestStarted("test3"); final SMTestProxy test3 = myEventsProcessor.getProxyByFullTestName(myEventsProcessor.getFullTestName("test3")); assertNotNull(test3); assertEquals("suite2", test3.getParent().getName()); //clean up myEventsProcessor.onSuiteFinished(new TestSuiteFinishedEvent("suite2")); myEventsProcessor.onSuiteFinished(new TestSuiteFinishedEvent("suite1")); } public void testOnSuiteStarted_WithLocation() { onTestSuiteStarted("suite1", "file://some/file.rb:1"); //lets check that new tests have right parent onTestStarted("test1", "file://some/file.rb:4"); final SMTestProxy test1 = myEventsProcessor.getProxyByFullTestName(myEventsProcessor.getFullTestName("test1")); assertNotNull(test1); assertEquals("file://some/file.rb:1", test1.getParent().getLocationUrl()); assertEquals("file://some/file.rb:4", test1.getLocationUrl()); } public void testGetCurrentTestSuite() { assertEquals(myResultsViewer.getTestsRootNode(), myEventsProcessor.getCurrentSuite()); onTestSuiteStarted("my_suite"); assertEquals("my_suite", myEventsProcessor.getCurrentSuite().getName()); } public void testConcurrentSuite_intersected() { myEventsProcessor.onSuiteStarted(new TestSuiteStartedEvent("suite1", null)); myEventsProcessor.onTestStarted(new TestStartedEvent("suite2.test1", null)); final SMTestProxy test1 = myEventsProcessor.getProxyByFullTestName(myEventsProcessor.getFullTestName("suite2.test1")); myEventsProcessor.onSuiteFinished(new TestSuiteFinishedEvent("suite1")); myEventsProcessor.onSuiteStarted(new TestSuiteStartedEvent("suite2", null)); myEventsProcessor.onTestFinished(new TestFinishedEvent("suite2.test1", 10l)); myEventsProcessor.onSuiteFinished(new TestSuiteFinishedEvent("suite2")); assertNotNull(test1); assertEquals("suite1", test1.getParent().getName()); final List<? extends SMTestProxy> children = myResultsViewer.getTestsRootNode().getChildren(); assertEquals(2, children.size()); assertEquals("suite1", children.get(0).getName()); assertEquals(1, children.get(0).getChildren().size()); assertEquals("suite2", children.get(1).getName()); assertEquals(0, children.get(1).getChildren().size()); } public void test3212() { // let's make myEventsProcessor.clearInternalSuitesStack(); assertEquals(myResultsViewer.getTestsRootNode(), myEventsProcessor.getCurrentSuite()); } private void onTestStarted(final String testName) { onTestStarted(testName, null); } private void onTestStarted(final String testName, @Nullable final String locationUrl) { myEventsProcessor.onTestStarted(new TestStartedEvent(testName, locationUrl)); myResultsViewer.performUpdate(); } private void onTestSuiteStarted(final String suiteName) { onTestSuiteStarted(suiteName, null); } private void onTestSuiteStarted(final String suiteName, @Nullable final String locationUrl) { myEventsProcessor.onSuiteStarted(new TestSuiteStartedEvent(suiteName, locationUrl)); myResultsViewer.performUpdate(); } public void testSampleImportTest() throws Exception { myEventsProcessor.onStartTesting(); ImportedToGeneralTestEventsConverter.parseTestResults(() -> new StringReader("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<testrun duration=\"592\" footerText=\"Generated by IntelliJ IDEA\" name=\"suite1\">\n" + " <suite name=\"suite1\" status=\"failed\">\n" + " <test name=\"ATest\" status=\"failed\"/>\n" + " </suite>\n" + "</testrun>\n"), myEventsProcessor); myEventsProcessor.onFinishTesting(); final List<? extends SMTestProxy> children = myResultsViewer.getTestsRootNode().getChildren(); assertEquals(1, children.size()); final SMTestProxy suite = children.get(0); assertEquals("suite1", suite.getName()); final List<? extends SMTestProxy> tests = suite.getChildren(); assertEquals(1, tests.size()); assertEquals("ATest", tests.get(0).getName()); } public void testEscapedImportTest() throws Exception { myEventsProcessor.onStartTesting(); ImportedToGeneralTestEventsConverter.parseTestResults(() -> new StringReader("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<testrun duration=\"592\" footerText=\"Generated by IntelliJ IDEA\" name=\"suite1\">\n" + " <suite name=\"sui&te1\" status=\"failed\">\n" + " <test name=\"ATe&st\" status=\"failed\"/>\n" + " </suite>\n" + "</testrun>\n"), myEventsProcessor); myEventsProcessor.onFinishTesting(); final List<? extends SMTestProxy> children = myResultsViewer.getTestsRootNode().getChildren(); assertEquals(1, children.size()); final SMTestProxy suite = children.get(0); assertEquals("sui&te1", suite.getName()); final List<? extends SMTestProxy> tests = suite.getChildren(); assertEquals(1, tests.size()); assertEquals("ATe&st", tests.get(0).getName()); } public void testPreserveFullOutputAfterImport() throws Exception { mySuite.addChild(mySimpleTest); for (int i = 0; i < 550; i++) { String message = "line" + i + "\n"; mySimpleTest.addLast(printer -> printer.print(message, ConsoleViewContentType.NORMAL_OUTPUT)); } mySimpleTest.setFinished(); mySuite.setFinished(); SAXTransformerFactory transformerFactory = (SAXTransformerFactory)TransformerFactory.newInstance(); TransformerHandler handler = transformerFactory.newTransformerHandler(); handler.getTransformer().setOutputProperty(OutputKeys.INDENT, "yes"); handler.getTransformer().setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); File output = FileUtil.createTempFile("output", ""); try { FileUtilRt.createParentDirs(output); handler.setResult(new StreamResult(new FileWriter(output))); MockRuntimeConfiguration configuration = new MockRuntimeConfiguration(getProject()); TestResultsXmlFormatter.execute(mySuite, configuration, new SMTRunnerConsoleProperties(configuration, "framework", new DefaultRunExecutor()), handler); String savedText = FileUtil.loadFile(output); assertTrue(savedText.split("\n").length > 550); myEventsProcessor.onStartTesting(); ImportedToGeneralTestEventsConverter.parseTestResults(() -> new StringReader(savedText), myEventsProcessor); myEventsProcessor.onFinishTesting(); List<? extends SMTestProxy> children = myResultsViewer.getTestsRootNode().getChildren(); assertSize(1, children); SMTestProxy testProxy = children.get(0); MockPrinter mockPrinter = new MockPrinter(); testProxy.printOn(mockPrinter); assertSize(550, mockPrinter.getAllOut().split("\n")); } finally { FileUtil.delete(output); } } }