Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'testsrunner/org.eclipse.cdt.testsrunner.boost/src')
-rw-r--r--testsrunner/org.eclipse.cdt.testsrunner.boost/src/org/eclipse/cdt/testsrunner/internal/boost/BoostTestsRunnerMessages.java30
-rw-r--r--testsrunner/org.eclipse.cdt.testsrunner.boost/src/org/eclipse/cdt/testsrunner/internal/boost/BoostTestsRunnerMessages.properties16
-rw-r--r--testsrunner/org.eclipse.cdt.testsrunner.boost/src/org/eclipse/cdt/testsrunner/internal/boost/BoostTestsRunnerPlugin.java67
-rw-r--r--testsrunner/org.eclipse.cdt.testsrunner.boost/src/org/eclipse/cdt/testsrunner/internal/boost/BoostTestsRunnerProvider.java113
-rw-r--r--testsrunner/org.eclipse.cdt.testsrunner.boost/src/org/eclipse/cdt/testsrunner/internal/boost/BoostXmlLogHandler.java229
5 files changed, 455 insertions, 0 deletions
diff --git a/testsrunner/org.eclipse.cdt.testsrunner.boost/src/org/eclipse/cdt/testsrunner/internal/boost/BoostTestsRunnerMessages.java b/testsrunner/org.eclipse.cdt.testsrunner.boost/src/org/eclipse/cdt/testsrunner/internal/boost/BoostTestsRunnerMessages.java
new file mode 100644
index 0000000000..49d3329739
--- /dev/null
+++ b/testsrunner/org.eclipse.cdt.testsrunner.boost/src/org/eclipse/cdt/testsrunner/internal/boost/BoostTestsRunnerMessages.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Anton Gorenkov.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Anton Gorenkov - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.testsrunner.internal.boost;
+
+import org.eclipse.osgi.util.NLS;
+
+public class BoostTestsRunnerMessages extends NLS {
+ private static final String BUNDLE_NAME = "org.eclipse.cdt.testsrunner.internal.boost.BoostTestsRunnerMessages"; //$NON-NLS-1$
+ public static String BoostTestsRunner_error_format;
+ public static String BoostTestsRunner_io_error_prefix;
+ public static String BoostTestsRunner_wrong_tests_paths_count;
+ public static String BoostTestsRunner_xml_error_prefix;
+ public static String BoostXmlLogHandler_exception_suffix;
+ public static String BoostXmlLogHandler_wrong_tag_name;
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, BoostTestsRunnerMessages.class);
+ }
+
+ private BoostTestsRunnerMessages() {
+ }
+}
diff --git a/testsrunner/org.eclipse.cdt.testsrunner.boost/src/org/eclipse/cdt/testsrunner/internal/boost/BoostTestsRunnerMessages.properties b/testsrunner/org.eclipse.cdt.testsrunner.boost/src/org/eclipse/cdt/testsrunner/internal/boost/BoostTestsRunnerMessages.properties
new file mode 100644
index 0000000000..38b0bdb76d
--- /dev/null
+++ b/testsrunner/org.eclipse.cdt.testsrunner.boost/src/org/eclipse/cdt/testsrunner/internal/boost/BoostTestsRunnerMessages.properties
@@ -0,0 +1,16 @@
+###############################################################################
+# Copyright (c) 2011 Anton Gorenkov
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# Anton Gorenkov - Initial implementation
+###############################################################################
+BoostTestsRunner_error_format={0}: {1}
+BoostTestsRunner_io_error_prefix=I/O Error
+BoostTestsRunner_wrong_tests_paths_count=Only on test suite or test case should be specified to rerun
+BoostTestsRunner_xml_error_prefix=XML parse error
+BoostXmlLogHandler_exception_suffix=\nLast check point was here.
+BoostXmlLogHandler_wrong_tag_name=Invalid XML format: Element "{0}" is not accepted\!
diff --git a/testsrunner/org.eclipse.cdt.testsrunner.boost/src/org/eclipse/cdt/testsrunner/internal/boost/BoostTestsRunnerPlugin.java b/testsrunner/org.eclipse.cdt.testsrunner.boost/src/org/eclipse/cdt/testsrunner/internal/boost/BoostTestsRunnerPlugin.java
new file mode 100644
index 0000000000..0e0545eb7a
--- /dev/null
+++ b/testsrunner/org.eclipse.cdt.testsrunner.boost/src/org/eclipse/cdt/testsrunner/internal/boost/BoostTestsRunnerPlugin.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Anton Gorenkov
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Anton Gorenkov - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.testsrunner.internal.boost;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Plugin;
+import org.eclipse.core.runtime.Status;
+
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class BoostTestsRunnerPlugin extends Plugin {
+
+ /** The plug-in ID .*/
+ public static final String PLUGIN_ID = "org.eclipse.cdt.testsrunner.boost"; //$NON-NLS-1$
+
+ /** Plug-in instance. */
+ private static BoostTestsRunnerPlugin plugin;
+
+
+ public BoostTestsRunnerPlugin() {
+ super();
+ plugin = this;
+ }
+
+ /**
+ * Returns the Boost Tests Runner provider plug-in instance.
+ *
+ * @return the plug-in instance
+ */
+ public static BoostTestsRunnerPlugin getDefault() {
+ return plugin;
+ }
+
+ /** Convenience method which returns the unique identifier of this plugin. */
+ public static String getUniqueIdentifier() {
+ return PLUGIN_ID;
+ }
+
+ /**
+ * Logs the specified status with this plug-in's log.
+ *
+ * @param status status to log
+ */
+ public static void log(IStatus status) {
+ getDefault().getLog().log(status);
+ }
+
+ /**
+ * Logs an internal error with the specified throwable
+ *
+ * @param e the exception to be logged
+ */
+ public static void log(Throwable e) {
+ log(new Status(IStatus.ERROR, getUniqueIdentifier(), IStatus.ERROR, e.getMessage(), e));
+ }
+
+}
diff --git a/testsrunner/org.eclipse.cdt.testsrunner.boost/src/org/eclipse/cdt/testsrunner/internal/boost/BoostTestsRunnerProvider.java b/testsrunner/org.eclipse.cdt.testsrunner.boost/src/org/eclipse/cdt/testsrunner/internal/boost/BoostTestsRunnerProvider.java
new file mode 100644
index 0000000000..48d5fda932
--- /dev/null
+++ b/testsrunner/org.eclipse.cdt.testsrunner.boost/src/org/eclipse/cdt/testsrunner/internal/boost/BoostTestsRunnerProvider.java
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Anton Gorenkov
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Anton Gorenkov - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.testsrunner.internal.boost;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.text.MessageFormat;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.eclipse.cdt.testsrunner.launcher.ITestsRunnerProvider;
+import org.eclipse.cdt.testsrunner.model.ITestModelUpdater;
+import org.eclipse.cdt.testsrunner.model.TestingException;
+import org.xml.sax.SAXException;
+
+/**
+ * The Tests Runner provider plug-in to run tests with Boost.Test framework.
+ *
+ * Configures the test module to output in XML format, parses the output and
+ * provides the data for the Tests Runner Core.
+ *
+ * @note There is a note about Tests Runner provider plug-in accuracy. Communication
+ * between Boost test module and Boost Tests Runner provider plug-in is done through
+ * standard output (which is buffered by default). Boost.Test (at least current
+ * version - 1.48.0) does not provide a way to flush the data about tests
+ * execution when they are available, so there may be a delay between test event
+ * happening (e.g. test case is started) and its displaying in the results view.
+ * The possible solution is to turn off the standard output buffering like this:
+ * <pre>
+ * static struct DisableStdCoutBuffering
+ * {
+ * DisableStdCoutBuffering()
+ * {
+ * std::cout.setf(std::ios_base::unitbuf);
+ * }
+ * } s_disableStdCoutBuffering;
+ * </pre>
+ * It will make the results view showing progress more accurate.
+ */
+public class BoostTestsRunnerProvider implements ITestsRunnerProvider {
+
+ @Override
+ public String[] getAdditionalLaunchParameters(String[][] testPaths) throws TestingException {
+ final String[] boostParameters = {
+ "--output_format=xml", //$NON-NLS-1$
+ "--log_level=all", //$NON-NLS-1$
+ "--report_level=no" //$NON-NLS-1$
+ };
+ String[] result = boostParameters;
+
+ // Build tests filter
+ if (testPaths != null && testPaths.length >= 1) {
+ if (testPaths.length != 1) {
+ throw new TestingException(BoostTestsRunnerMessages.BoostTestsRunner_wrong_tests_paths_count);
+ }
+ StringBuilder sb = new StringBuilder("--run_test="); //$NON-NLS-1$
+ String[] testPath = testPaths[0];
+ for (int i = 1; i < testPath.length; i++) {
+ if (i != 1) {
+ sb.append("/"); //$NON-NLS-1$
+ }
+ sb.append(testPath[i]);
+ }
+ result = new String[boostParameters.length + 1];
+ System.arraycopy(boostParameters, 0, result, 0, boostParameters.length);
+ result[boostParameters.length] = sb.toString();
+ }
+ return result;
+ }
+
+ /**
+ * Construct the error message from prefix and detailed description.
+ *
+ * @param prefix prefix
+ * @param description detailed description
+ * @return the full message
+ */
+ private String getErrorText(String prefix, String description) {
+ return MessageFormat.format(BoostTestsRunnerMessages.BoostTestsRunner_error_format, prefix, description);
+ }
+
+ @Override
+ public void run(ITestModelUpdater modelUpdater, InputStream inputStream) throws TestingException {
+ try {
+ SAXParserFactory spf = SAXParserFactory.newInstance();
+ SAXParser sp = spf.newSAXParser();
+ sp.parse(inputStream, new BoostXmlLogHandler(modelUpdater));
+
+ } catch (IOException e) {
+ throw new TestingException(getErrorText(BoostTestsRunnerMessages.BoostTestsRunner_io_error_prefix, e.getLocalizedMessage()));
+
+ } catch (NumberFormatException e) {
+ throw new TestingException(getErrorText(BoostTestsRunnerMessages.BoostTestsRunner_xml_error_prefix, e.getLocalizedMessage()));
+
+ } catch (ParserConfigurationException e) {
+ throw new TestingException(getErrorText(BoostTestsRunnerMessages.BoostTestsRunner_xml_error_prefix, e.getLocalizedMessage()));
+
+ } catch (SAXException e) {
+ throw new TestingException(getErrorText(BoostTestsRunnerMessages.BoostTestsRunner_xml_error_prefix, e.getLocalizedMessage()));
+ }
+ }
+
+}
diff --git a/testsrunner/org.eclipse.cdt.testsrunner.boost/src/org/eclipse/cdt/testsrunner/internal/boost/BoostXmlLogHandler.java b/testsrunner/org.eclipse.cdt.testsrunner.boost/src/org/eclipse/cdt/testsrunner/internal/boost/BoostXmlLogHandler.java
new file mode 100644
index 0000000000..08b40e823f
--- /dev/null
+++ b/testsrunner/org.eclipse.cdt.testsrunner.boost/src/org/eclipse/cdt/testsrunner/internal/boost/BoostXmlLogHandler.java
@@ -0,0 +1,229 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Anton Gorenkov
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Anton Gorenkov - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.testsrunner.internal.boost;
+
+import java.text.MessageFormat;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Stack;
+
+import org.eclipse.cdt.testsrunner.model.ITestModelUpdater;
+import org.eclipse.cdt.testsrunner.model.ITestItem;
+import org.eclipse.cdt.testsrunner.model.ITestMessage;
+import org.eclipse.cdt.testsrunner.model.ITestItem.Status;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.helpers.DefaultHandler;
+
+
+/**
+ * Parses the Boost.Test XML log and notifies the Tests Runner Core about how
+ * the testing process is going.
+ */
+public class BoostXmlLogHandler extends DefaultHandler {
+
+ // Boost.Test XML log tags
+ private static final String XML_NODE_TEST_LOG = "TestLog"; //$NON-NLS-1$
+ private static final String XML_NODE_TEST_SUITE = "TestSuite"; //$NON-NLS-1$
+ private static final String XML_NODE_TEST_CASE = "TestCase"; //$NON-NLS-1$
+ private static final String XML_NODE_TESTING_TIME = "TestingTime"; //$NON-NLS-1$
+ private static final String XML_NODE_LAST_CHECKPOINT = "LastCheckpoint"; //$NON-NLS-1$
+
+ // Boost.Test XML log message levels representation
+ private static final String XML_NODE_INFO = "Info"; //$NON-NLS-1$
+ private static final String XML_NODE_MESSAGE = "Message"; //$NON-NLS-1$
+ private static final String XML_NODE_WARNING = "Warning"; //$NON-NLS-1$
+ private static final String XML_NODE_ERROR = "Error"; //$NON-NLS-1$
+ private static final String XML_NODE_FATAL_ERROR = "FatalError"; //$NON-NLS-1$
+ private static final String XML_NODE_EXCEPTION = "Exception"; //$NON-NLS-1$
+
+ // Boost.Test XML log attributes
+ private static final String XML_ATTR_TEST_SUITE_NAME = "name"; //$NON-NLS-1$
+ private static final String XML_ATTR_TEST_CASE_NAME = "name"; //$NON-NLS-1$
+ private static final String XML_ATTR_MESSAGE_FILE = "file"; //$NON-NLS-1$
+ private static final String XML_ATTR_MESSAGE_LINE = "line"; //$NON-NLS-1$
+
+ /** Maps the string message level representation to the Tests Runner internal enum code. */
+ private static final Map<String, ITestMessage.Level> STRING_TO_MESSAGE_LEVEL;
+ static {
+ Map<String, ITestMessage.Level> aMap = new HashMap<String, ITestMessage.Level>();
+ aMap.put(XML_NODE_INFO, ITestMessage.Level.Info);
+ aMap.put(XML_NODE_MESSAGE, ITestMessage.Level.Message);
+ aMap.put(XML_NODE_WARNING, ITestMessage.Level.Warning);
+ aMap.put(XML_NODE_ERROR, ITestMessage.Level.Error);
+ aMap.put(XML_NODE_FATAL_ERROR, ITestMessage.Level.FatalError);
+ // NOTE: Exception node is processed separately
+ STRING_TO_MESSAGE_LEVEL = Collections.unmodifiableMap(aMap);
+ }
+
+ /** The default file name for test message location. */
+ private static final String DEFAULT_LOCATION_FILE = null;
+
+ /** The default line number for test message location. */
+ private static final int DEFAULT_LOCATION_LINE = -1;
+
+ /** The interface to notify the Tests Runner Core */
+ private ITestModelUpdater modelUpdater;
+
+ /** Stores the text between XML tags. */
+ private Stack<StringBuilder> elementDataStack = new Stack<StringBuilder>();
+
+ /** File name for current test message location. */
+ private String fileName;
+
+ /** Line number for current test message location. */
+ private int lineNumber;
+
+ /** Current test case status. */
+ private ITestItem.Status testStatus;
+
+
+ BoostXmlLogHandler(ITestModelUpdater modelUpdater) {
+ this.modelUpdater = modelUpdater;
+ }
+
+ @Override
+ public void startElement(String namespaceURI, String localName, String qName, Attributes attrs) throws SAXException {
+
+ elementDataStack.push(new StringBuilder());
+ if (qName == XML_NODE_TEST_SUITE) {
+ String testSuiteName = attrs.getValue(XML_ATTR_TEST_SUITE_NAME);
+ modelUpdater.enterTestSuite(testSuiteName);
+
+ } else if (qName == XML_NODE_TEST_CASE) {
+ String testCaseName = attrs.getValue(XML_ATTR_TEST_CASE_NAME);
+ modelUpdater.enterTestCase(testCaseName);
+ testStatus = Status.Passed;
+
+ } else if (STRING_TO_MESSAGE_LEVEL.containsKey(qName)
+ || qName == XML_NODE_LAST_CHECKPOINT) {
+ fileName = attrs.getValue(XML_ATTR_MESSAGE_FILE);
+ String lineNumberStr = attrs.getValue(XML_ATTR_MESSAGE_LINE);
+ lineNumber = lineNumberStr != null ? Integer.parseInt(lineNumberStr.trim()) : DEFAULT_LOCATION_LINE;
+
+ } else if (qName == XML_NODE_EXCEPTION) {
+ fileName = DEFAULT_LOCATION_FILE;
+ lineNumber = DEFAULT_LOCATION_LINE;
+
+ } else if (qName == XML_NODE_TESTING_TIME ) {
+
+ } else if (qName == XML_NODE_TEST_LOG) {
+ /* just skip, do nothing */
+
+ } else {
+ logAndThrowErrorForElement(qName);
+ }
+ }
+
+ /**
+ * Common routing: notifies the Tests Runner core about new test message
+ * and resets the internal state.
+ *
+ * @param level test message level
+ */
+ private void addCurrentMessage(ITestMessage.Level level) {
+ modelUpdater.addTestMessage(fileName, lineNumber, level, elementDataStack.peek().toString());
+ fileName = DEFAULT_LOCATION_FILE;
+ lineNumber = DEFAULT_LOCATION_LINE;
+ if (level == ITestMessage.Level.Error || level == ITestMessage.Level.FatalError) {
+ if (testStatus != ITestItem.Status.Aborted) {
+ testStatus = ITestItem.Status.Failed;
+ }
+
+ } else if (level == ITestMessage.Level.Exception) {
+ testStatus = ITestItem.Status.Aborted;
+ }
+ }
+
+ @Override
+ public void endElement(String namespaceURI, String localName, String qName) throws SAXException {
+
+ if (qName == XML_NODE_TEST_SUITE) {
+ modelUpdater.exitTestSuite();
+
+ } else if (qName == XML_NODE_TEST_CASE) {
+ modelUpdater.setTestStatus(testStatus);
+ modelUpdater.exitTestCase();
+
+ } else if (qName == XML_NODE_TESTING_TIME) {
+ modelUpdater.setTestingTime(Integer.parseInt(elementDataStack.peek().toString().trim())/1000);
+
+ } else if (STRING_TO_MESSAGE_LEVEL.containsKey(qName)) {
+ addCurrentMessage(STRING_TO_MESSAGE_LEVEL.get(qName));
+
+ } else if (qName == XML_NODE_EXCEPTION) {
+ if (fileName != DEFAULT_LOCATION_FILE && !fileName.isEmpty() && lineNumber >= 0) {
+ elementDataStack.peek().append(BoostTestsRunnerMessages.BoostXmlLogHandler_exception_suffix);
+ }
+ addCurrentMessage(ITestMessage.Level.Exception);
+
+ } else if (qName == XML_NODE_TEST_LOG || qName == XML_NODE_LAST_CHECKPOINT) {
+ /* just skip, do nothing */
+
+ } else {
+ logAndThrowErrorForElement(qName);
+ }
+ elementDataStack.pop();
+ }
+
+ @Override
+ public void characters(char[] ch, int start, int length) {
+ StringBuilder builder = elementDataStack.peek();
+ for (int i = start; i < start + length; i++) {
+ builder.append(ch[i]);
+ }
+ }
+
+ /**
+ * Throws the testing exception for the specified XML tag.
+ *
+ * @param tagName XML tag name
+ * @throws SAXException the exception that will be thrown
+ */
+ private void logAndThrowErrorForElement(String tagName) throws SAXException {
+ logAndThrowError(
+ MessageFormat.format(BoostTestsRunnerMessages.BoostXmlLogHandler_wrong_tag_name, tagName)
+ );
+ }
+
+ /**
+ * Throws the testing exception with the specified message.
+ *
+ * @param message the reason
+ * @throws SAXException the exception that will be thrown
+ */
+ private void logAndThrowError(String message) throws SAXException {
+ SAXException e = new SAXException(message);
+ BoostTestsRunnerPlugin.log(e);
+ throw e;
+ }
+
+
+ @Override
+ public void warning(SAXParseException ex) throws SAXException {
+ BoostTestsRunnerPlugin.log(ex);
+ }
+
+ @Override
+ public void error(SAXParseException ex) throws SAXException {
+ BoostTestsRunnerPlugin.log(ex);
+ throw ex;
+ }
+
+ @Override
+ public void fatalError(SAXParseException ex) throws SAXException {
+ BoostTestsRunnerPlugin.log(ex);
+ throw ex;
+ }
+
+}

Back to the top