diff options
18 files changed, 813 insertions, 1 deletions
@@ -203,6 +203,7 @@ <module>testsrunner/org.eclipse.cdt.testsrunner.boost</module> <module>testsrunner/org.eclipse.cdt.testsrunner.gtest</module> <module>testsrunner/org.eclipse.cdt.testsrunner.qttest</module> + <module>testsrunner/org.eclipse.cdt.testsrunner.tap</module> <module>testsrunner/org.eclipse.cdt.testsrunner.test</module> <module>testsrunner/org.eclipse.cdt.testsrunner.feature</module> <module>testsrunner/org.eclipse.cdt.testsrunner.source.feature</module> diff --git a/testsrunner/org.eclipse.cdt.testsrunner.feature/feature.xml b/testsrunner/org.eclipse.cdt.testsrunner.feature/feature.xml index efc04616bc5..edad02de756 100644 --- a/testsrunner/org.eclipse.cdt.testsrunner.feature/feature.xml +++ b/testsrunner/org.eclipse.cdt.testsrunner.feature/feature.xml @@ -47,4 +47,11 @@ version="0.0.0" unpack="false"/> + <plugin + id="org.eclipse.cdt.testsrunner.tap" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + </feature> diff --git a/testsrunner/org.eclipse.cdt.testsrunner.source.feature/feature.xml b/testsrunner/org.eclipse.cdt.testsrunner.source.feature/feature.xml index c08519d8a8d..ab29de63e62 100644 --- a/testsrunner/org.eclipse.cdt.testsrunner.source.feature/feature.xml +++ b/testsrunner/org.eclipse.cdt.testsrunner.source.feature/feature.xml @@ -47,4 +47,11 @@ version="0.0.0" unpack="false"/> + <plugin + id="org.eclipse.cdt.testsrunner.tap.source" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + </feature> diff --git a/testsrunner/org.eclipse.cdt.testsrunner.tap/.classpath b/testsrunner/org.eclipse.cdt.testsrunner.tap/.classpath new file mode 100644 index 00000000000..b277a8ac870 --- /dev/null +++ b/testsrunner/org.eclipse.cdt.testsrunner.tap/.classpath @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="src"/> + <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/testsrunner/org.eclipse.cdt.testsrunner.tap/.project b/testsrunner/org.eclipse.cdt.testsrunner.tap/.project new file mode 100644 index 00000000000..92a252fde38 --- /dev/null +++ b/testsrunner/org.eclipse.cdt.testsrunner.tap/.project @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.cdt.testsrunner.tap</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature>
+ </natures>
+</projectDescription>
diff --git a/testsrunner/org.eclipse.cdt.testsrunner.tap/.settings/org.eclipse.jdt.core.prefs b/testsrunner/org.eclipse.cdt.testsrunner.tap/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000000..f00153f89a6 --- /dev/null +++ b/testsrunner/org.eclipse.cdt.testsrunner.tap/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,82 @@ +#Mon Apr 16 13:01:24 EEST 2012 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.autoboxing=ignore +org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning +org.eclipse.jdt.core.compiler.problem.deadCode=warning +org.eclipse.jdt.core.compiler.problem.deprecation=warning +org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled +org.eclipse.jdt.core.compiler.problem.discouragedReference=warning +org.eclipse.jdt.core.compiler.problem.emptyStatement=warning +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning +org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled +org.eclipse.jdt.core.compiler.problem.fieldHiding=warning +org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning +org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning +org.eclipse.jdt.core.compiler.problem.forbiddenReference=error +org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning +org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled +org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning +org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning +org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore +org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore +org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=error +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning +org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=ignore +org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning +org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning +org.eclipse.jdt.core.compiler.problem.nullReference=error +org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=error +org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore +org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning +org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning +org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning +org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning +org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore +org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=warning +org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore +org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning +org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled +org.eclipse.jdt.core.compiler.problem.unusedImport=warning +org.eclipse.jdt.core.compiler.problem.unusedLabel=warning +org.eclipse.jdt.core.compiler.problem.unusedLocal=warning +org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning +org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning +org.eclipse.jdt.core.compiler.source=1.7 diff --git a/testsrunner/org.eclipse.cdt.testsrunner.tap/META-INF/MANIFEST.MF b/testsrunner/org.eclipse.cdt.testsrunner.tap/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..cef3d2e0797 --- /dev/null +++ b/testsrunner/org.eclipse.cdt.testsrunner.tap/META-INF/MANIFEST.MF @@ -0,0 +1,13 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %pluginName +Bundle-SymbolicName: org.eclipse.cdt.testsrunner.tap;singleton:=true +Bundle-Version: 1.0.0.qualifier +Bundle-Activator: org.eclipse.cdt.testsrunner.internal.tap.TAPTestsRunnerPlugin +Bundle-Vendor: %providerName +Bundle-Localization: plugin +Bundle-ActivationPolicy: lazy +Bundle-RequiredExecutionEnvironment: JavaSE-1.7 +Require-Bundle: org.eclipse.core.runtime;bundle-version="3.5.0", + org.eclipse.cdt.testsrunner;bundle-version="3.5.0" +Export-Package: org.eclipse.cdt.testsrunner.internal.tap;x-friends:="org.eclipse.cdt.testsrunner.test" diff --git a/testsrunner/org.eclipse.cdt.testsrunner.tap/about.html b/testsrunner/org.eclipse.cdt.testsrunner.tap/about.html new file mode 100644 index 00000000000..d7c511887d6 --- /dev/null +++ b/testsrunner/org.eclipse.cdt.testsrunner.tap/about.html @@ -0,0 +1,24 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"><head> +<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>About</title></head> + +<body lang="EN-US"> +<h2>About This Content</h2> + +<p>June 22, 2007</p> +<h3>License</h3> + +<p>The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise +indicated below, the Content is provided to you under the terms and conditions of the +Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available +at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>. +For purposes of the EPL, "Program" will mean the Content.</p> + +<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is +being redistributed by another party ("Redistributor") and different terms and conditions may +apply to your use of any object code in the Content. Check the Redistributor's license that was +provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise +indicated below, the terms and conditions of the EPL still apply to any source code in the Content +and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p> + +</body></html>
\ No newline at end of file diff --git a/testsrunner/org.eclipse.cdt.testsrunner.tap/build.properties b/testsrunner/org.eclipse.cdt.testsrunner.tap/build.properties new file mode 100644 index 00000000000..55d9be83320 --- /dev/null +++ b/testsrunner/org.eclipse.cdt.testsrunner.tap/build.properties @@ -0,0 +1,21 @@ +############################################################################### +# 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 +############################################################################### + +bin.includes = plugin.xml,\ + plugin.properties,\ + about.html,\ + .,\ + META-INF/ +javadoc.packages = org.eclipse.cdt.launch.ui.*,\ + org.eclipse.cdt.launch.sourcelookup*,\ + org.eclipse.cdt.launch.* +source.. = src/ +src.includes = about.html diff --git a/testsrunner/org.eclipse.cdt.testsrunner.tap/plugin.properties b/testsrunner/org.eclipse.cdt.testsrunner.tap/plugin.properties new file mode 100644 index 00000000000..d4b77c6a80d --- /dev/null +++ b/testsrunner/org.eclipse.cdt.testsrunner.tap/plugin.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 +# Colin Leitner - Changed to TAP +############################################################################### +pluginName=C/C++ Development Tools Test Anything Protocol (TAP) Tests Runner Support +providerName=Eclipse CDT + +TAPTestsRunner.name=TAP Tests Runner +TAPTestsRunner.description=Tests runner for a test module based on the Test Anything Protocol diff --git a/testsrunner/org.eclipse.cdt.testsrunner.tap/plugin.xml b/testsrunner/org.eclipse.cdt.testsrunner.tap/plugin.xml new file mode 100644 index 00000000000..384e9708aa7 --- /dev/null +++ b/testsrunner/org.eclipse.cdt.testsrunner.tap/plugin.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> +<?eclipse version="3.0"?> +<plugin> + <extension + point="org.eclipse.cdt.testsrunner.TestsRunner"> + <runner + class="org.eclipse.cdt.testsrunner.internal.tap.TAPTestsRunnerProvider" + description="%TAPTestsRunner.description" + id="org.eclipse.cdt.testsrunner.tap" + name="%TAPTestsRunner.name"> + </runner> + </extension> +</plugin> diff --git a/testsrunner/org.eclipse.cdt.testsrunner.tap/pom.xml b/testsrunner/org.eclipse.cdt.testsrunner.tap/pom.xml new file mode 100644 index 00000000000..5d27798ab26 --- /dev/null +++ b/testsrunner/org.eclipse.cdt.testsrunner.tap/pom.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" + xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.eclipse.cdt</groupId> + <artifactId>cdt-parent</artifactId> + <version>8.8.0-SNAPSHOT</version> + <relativePath>../../pom.xml</relativePath> + </parent> + + <version>1.0.0-SNAPSHOT</version> + <artifactId>org.eclipse.cdt.testsrunner.tap</artifactId> + <packaging>eclipse-plugin</packaging> +</project> diff --git a/testsrunner/org.eclipse.cdt.testsrunner.tap/src/org/eclipse/cdt/testsrunner/internal/tap/TAPTestsRunnerMessages.java b/testsrunner/org.eclipse.cdt.testsrunner.tap/src/org/eclipse/cdt/testsrunner/internal/tap/TAPTestsRunnerMessages.java new file mode 100644 index 00000000000..5aba876b65e --- /dev/null +++ b/testsrunner/org.eclipse.cdt.testsrunner.tap/src/org/eclipse/cdt/testsrunner/internal/tap/TAPTestsRunnerMessages.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * 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.tap; + +import org.eclipse.osgi.util.NLS; + +public class TAPTestsRunnerMessages extends NLS { + private static final String BUNDLE_NAME = "org.eclipse.cdt.testsrunner.internal.tap.TAPTestsRunnerMessages"; //$NON-NLS-1$ + public static String TAPTestsRunner_error_format; + public static String TAPTestsRunner_io_error_prefix; + public static String TAPTestsRunner_tap_error_prefix; + public static String TAPTestsRunner_invalid_version_line; + public static String TAPTestsRunner_multiple_plans; + public static String TAPTestsRunner_invalid_test_number; + + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, TAPTestsRunnerMessages.class); + } + + private TAPTestsRunnerMessages() { + } +} diff --git a/testsrunner/org.eclipse.cdt.testsrunner.tap/src/org/eclipse/cdt/testsrunner/internal/tap/TAPTestsRunnerMessages.properties b/testsrunner/org.eclipse.cdt.testsrunner.tap/src/org/eclipse/cdt/testsrunner/internal/tap/TAPTestsRunnerMessages.properties new file mode 100644 index 00000000000..cd9e28e420f --- /dev/null +++ b/testsrunner/org.eclipse.cdt.testsrunner.tap/src/org/eclipse/cdt/testsrunner/internal/tap/TAPTestsRunnerMessages.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 +############################################################################### +TAPTestsRunner_error_format={0}: {1} +TAPTestsRunner_io_error_prefix=I/O Error +TAPTestsRunner_tap_error_prefix=TAP Error +TAPTestsRunner_invalid_version_line=Version information not on first line +TAPTestsRunner_multiple_plans=More than one test plan +TAPTestsRunner_invalid_test_number=Invalid test number diff --git a/testsrunner/org.eclipse.cdt.testsrunner.tap/src/org/eclipse/cdt/testsrunner/internal/tap/TAPTestsRunnerPlugin.java b/testsrunner/org.eclipse.cdt.testsrunner.tap/src/org/eclipse/cdt/testsrunner/internal/tap/TAPTestsRunnerPlugin.java new file mode 100644 index 00000000000..ce02e1ef8bf --- /dev/null +++ b/testsrunner/org.eclipse.cdt.testsrunner.tap/src/org/eclipse/cdt/testsrunner/internal/tap/TAPTestsRunnerPlugin.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.tap; + +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 TAPTestsRunnerPlugin extends Plugin { + + /** The plug-in ID .*/ + public static final String PLUGIN_ID = "org.eclipse.cdt.testsrunner.tap"; //$NON-NLS-1$ + + /** Plug-in instance. */ + private static TAPTestsRunnerPlugin plugin; + + + public TAPTestsRunnerPlugin() { + super(); + plugin = this; + } + + /** + * Returns the TAP Tests Runner provider plug-in instance. + * + * @return the plug-in instance + */ + public static TAPTestsRunnerPlugin 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.tap/src/org/eclipse/cdt/testsrunner/internal/tap/TAPTestsRunnerProvider.java b/testsrunner/org.eclipse.cdt.testsrunner.tap/src/org/eclipse/cdt/testsrunner/internal/tap/TAPTestsRunnerProvider.java new file mode 100644 index 00000000000..a81db57842c --- /dev/null +++ b/testsrunner/org.eclipse.cdt.testsrunner.tap/src/org/eclipse/cdt/testsrunner/internal/tap/TAPTestsRunnerProvider.java @@ -0,0 +1,256 @@ +/******************************************************************************* + * 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 + * Colin Leitner - adapted to TAP support + *******************************************************************************/ +package org.eclipse.cdt.testsrunner.internal.tap; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.text.MessageFormat; +import java.util.LinkedList; +import java.util.Queue; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.cdt.testsrunner.launcher.ITestsRunnerProvider; +import org.eclipse.cdt.testsrunner.model.ITestItem.Status; +import org.eclipse.cdt.testsrunner.model.ITestMessage.Level; +import org.eclipse.cdt.testsrunner.model.ITestModelUpdater; +import org.eclipse.cdt.testsrunner.model.TestingException; + +/** + * The Tests Runner provider plug-in to run tests with the Test Anything + * Protocol. + * + * <p> + * Parses the standard output of an application for TAP conforming output. + * + * <p> + * The YAML output isn't parsed, but logged like any unknown output. As an + * unofficial extension, any lines with gcc compatible diagnostic output of the + * kind + * + * <pre> + * <filename>: (error|warning|info): ... + * <filename>:<line>: (error|warning|info): ...</pre> + * + * <p> + * will be reported with the correct level and location. + * + * <p> + * As with the Boost test runner, the <tt>stdout</tt> buffering might delay + * test output if not disabled by + * + * <pre> + * setvbuf(stdout, NULL, _IONBF, 0);</pre> + */ +public class TAPTestsRunnerProvider implements ITestsRunnerProvider { + + private final Pattern VERSION_PATTERN = Pattern.compile("^TAP version \\d+$", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$ + private final Pattern PLAN_PATTERN = Pattern.compile("^1..(?<count>\\d+)(\\s*#\\s*(?<message>(?<skip>skip).*|.*))?$", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$ + private final Pattern BAIL_OUT_PATTERN = Pattern.compile("^Bail out!(\\s*(?<message>.+))?$", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$ + private final Pattern TEST_RESULT_PATTERN = Pattern.compile("^(?<not>not )?ok( (?<number>\\d+))?(\\s*(?<name>[^#]+))?(\\s*#\\s*(?<message>((?<skip>SKIP)|(?<todo>TODO)).*|.*))?", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$ + private final Pattern GCC_DIAGNOSTIC_PATTERN = Pattern.compile("^(?<filename>[^:]+):((?<line>\\d+):)? (?<level>(error|warning|info)):\\s*(?<message>.*)"); //$NON-NLS-1$ + + @Override + public String[] getAdditionalLaunchParameters(String[][] testPaths) throws TestingException { + // No arguments specified by TAP + return new String[0]; + } + + /** + * 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(TAPTestsRunnerMessages.TAPTestsRunner_error_format, prefix, description); + } + + @Override + public void run(ITestModelUpdater modelUpdater, InputStream inputStream) throws TestingException { + // The TAP is really has lots of optional data and supports the most + // bare minimum possible for test output + + try { + // The TAP version may only be specified on the first line + boolean firstLine = true; + // The test plan is optional, but may be specified at most once + boolean hasPlan = false; + int plannedCount = -1; + int currentTestNumber = 1; + + Queue<String> output = new LinkedList<>(); + + BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); + String line; + while ((line = reader.readLine()) != null) { + Matcher m; + if ((m = VERSION_PATTERN.matcher(line)).matches()) { + // Version must be on the first line, or missing + if (!firstLine) { + throw new TestingException(getErrorText(TAPTestsRunnerMessages.TAPTestsRunner_tap_error_prefix, TAPTestsRunnerMessages.TAPTestsRunner_invalid_version_line)); + } + + // We actually don't care about the version itself + + } else if ((m = PLAN_PATTERN.matcher(line)).matches()) { + // Only one plan is allowed (after the optional version or at the end of the test run) + if (hasPlan) { + throw new TestingException(getErrorText(TAPTestsRunnerMessages.TAPTestsRunner_tap_error_prefix, TAPTestsRunnerMessages.TAPTestsRunner_multiple_plans)); + } + hasPlan = true; + + plannedCount = Integer.parseInt(m.group("count")); //$NON-NLS-1$ + + // The plan might decide to skip all tests. We fill up + // remaining tests if the count doesn't add up. + // + // This loop is almost identical to the final filler loop, + // but we may have a message as to why we had to skip these + // tests, which we don't have if the test has completed + // without a matching number of test results to the + // planned number of tests + if (m.group("skip") != null) { //$NON-NLS-1$ + String message = m.group("message"); //$NON-NLS-1$ + for (; currentTestNumber <= plannedCount; currentTestNumber += 1) { + modelUpdater.enterTestCase(Integer.toString(currentTestNumber)); + if (message != null) { + modelUpdater.addTestMessage(null, 0, Level.Message, message); + } + modelUpdater.setTestStatus(Status.Skipped); + modelUpdater.exitTestCase(); + } + + // Exit early + break; + } + + } else if ((m = BAIL_OUT_PATTERN.matcher(line)).matches()) { + // The test has been aborted by the module. Mark any + // planned tests accordingly + + String message = m.group("message"); //$NON-NLS-1$ + for (; currentTestNumber <= plannedCount; currentTestNumber += 1) { + modelUpdater.enterTestCase(Integer.toString(currentTestNumber)); + if (message != null) { + modelUpdater.addTestMessage(null, 0, Level.Message, message); + } + modelUpdater.setTestStatus(Status.Aborted); + modelUpdater.exitTestCase(); + } + + } else if ((m = TEST_RESULT_PATTERN.matcher(line)).matches()) { + // The index number optional. It may indicate skipped tests + // if it jumps ahead + String number = m.group("number"); //$NON-NLS-1$ + if (number != null) { + int newNumber = Integer.parseInt(number); + + // Negative jumps however, are not allowed + if (newNumber < currentTestNumber) { + throw new TestingException(getErrorText(TAPTestsRunnerMessages.TAPTestsRunner_tap_error_prefix, TAPTestsRunnerMessages.TAPTestsRunner_invalid_test_number)); + } + + // Skip tests for all numbers that have been skipped by + // the new test number + for (; currentTestNumber < newNumber; currentTestNumber += 1) { + modelUpdater.enterTestCase(Integer.toString(currentTestNumber)); + modelUpdater.setTestStatus(Status.Skipped); + modelUpdater.exitTestCase(); + } + + assert currentTestNumber == newNumber; + } + + // The test name is of course also optional + String name = m.group("name"); //$NON-NLS-1$ + if (name == null || name.trim().isEmpty()) { + name = Integer.toString(currentTestNumber); + } else { + name = name.trim(); + } + + modelUpdater.enterTestCase(name); + + // Add the optional test result message of skip and todo + // results + String message = m.group("message"); //$NON-NLS-1$ + if (message != null) { + modelUpdater.addTestMessage(null, 0, Level.Message, message); + } + + for (String o : output) { + Matcher diagnosticMatch = GCC_DIAGNOSTIC_PATTERN.matcher(o); + if (diagnosticMatch.matches()) { + int lineNumber = 0; + Level level = Level.Message; + + String diagLine = diagnosticMatch.group("line"); //$NON-NLS-1$ + if (diagLine != null) { + lineNumber = Integer.parseInt(diagLine); + } + + String diagLevel = diagnosticMatch.group("level"); //$NON-NLS-1$ + if (diagLevel.equals("error")) { //$NON-NLS-1$ + level = Level.Error; + } else if (diagLevel.equals("warning")) { //$NON-NLS-1$ + level = Level.Warning; + } else if (diagLevel.equals("info")) { //$NON-NLS-1$ + level = Level.Info; + } + + modelUpdater.addTestMessage(diagnosticMatch.group("filename"), lineNumber, level, diagnosticMatch.group("message")); //$NON-NLS-1$ //$NON-NLS-2$ + } else { + modelUpdater.addTestMessage(null, 0, Level.Message, o); + } + } + output.clear(); + + if (m.group("skip") != null) { //$NON-NLS-1$ + modelUpdater.setTestStatus(Status.Skipped); + } else if (m.group("todo") != null) { //$NON-NLS-1$ + modelUpdater.setTestStatus(Status.NotRun); + } else if (m.group("not") != null) { //$NON-NLS-1$ + modelUpdater.setTestStatus(Status.Failed); + } else { + modelUpdater.setTestStatus(Status.Passed); + } + + modelUpdater.exitTestCase(); + + currentTestNumber += 1; + + } else { + // Add unknown output to the test case. We associate that + // data as soon as we see the "ok/not ok" line + output.add(line); + } + + firstLine = false; + } + + // The test plan may contain more tests than we have test results + // for. Skip the remaining tests. + for (; currentTestNumber <= plannedCount; currentTestNumber += 1) { + modelUpdater.enterTestCase(Integer.toString(currentTestNumber)); + modelUpdater.setTestStatus(Status.Skipped); + modelUpdater.exitTestCase(); + } + + } catch (IOException e) { + throw new TestingException(getErrorText(TAPTestsRunnerMessages.TAPTestsRunner_io_error_prefix, e.getLocalizedMessage())); + } + } +} diff --git a/testsrunner/org.eclipse.cdt.testsrunner.test/META-INF/MANIFEST.MF b/testsrunner/org.eclipse.cdt.testsrunner.test/META-INF/MANIFEST.MF index 95611d2fedf..cbb8832849e 100644 --- a/testsrunner/org.eclipse.cdt.testsrunner.test/META-INF/MANIFEST.MF +++ b/testsrunner/org.eclipse.cdt.testsrunner.test/META-INF/MANIFEST.MF @@ -10,7 +10,8 @@ Require-Bundle: org.junit, org.eclipse.cdt.testsrunner;bundle-version="7.0.0", org.eclipse.cdt.testsrunner.boost;bundle-version="7.0.0", org.eclipse.cdt.testsrunner.qttest;bundle-version="7.0.0", - org.eclipse.cdt.testsrunner.gtest;bundle-version="7.0.0" + org.eclipse.cdt.testsrunner.gtest;bundle-version="7.0.0", + org.eclipse.cdt.testsrunner.tap;bundle-version="1.0.0" Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-1.7 Bundle-Vendor: %Bundle-Vendor diff --git a/testsrunner/org.eclipse.cdt.testsrunner.test/src/org/eclipse/cdt/testsrunner/testsrunners/TAPTestCase.java b/testsrunner/org.eclipse.cdt.testsrunner.test/src/org/eclipse/cdt/testsrunner/testsrunners/TAPTestCase.java new file mode 100644 index 00000000000..d977b378000 --- /dev/null +++ b/testsrunner/org.eclipse.cdt.testsrunner.test/src/org/eclipse/cdt/testsrunner/testsrunners/TAPTestCase.java @@ -0,0 +1,199 @@ +/*******************************************************************************
+ * Copyright (c) 2015 Colin Leitner
+ * 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:
+ * Colin Leitner - initial implementation
+ *******************************************************************************/
+package org.eclipse.cdt.testsrunner.testsrunners;
+
+import org.eclipse.cdt.testsrunner.internal.tap.TAPTestsRunnerProvider;
+import org.eclipse.cdt.testsrunner.launcher.ITestsRunnerProvider;
+import org.eclipse.cdt.testsrunner.model.ITestItem.Status;
+import org.eclipse.cdt.testsrunner.model.ITestMessage.Level;
+
+@SuppressWarnings("nls")
+public class TAPTestCase extends BaseTestCase {
+
+ @Override
+ protected ITestsRunnerProvider createTestsRunner() {
+ return new TAPTestsRunnerProvider();
+ }
+
+ //
+ public void testNoTestCases() {
+ }
+
+ //TAP version 1
+ public void testIgnoreVersion() {
+ }
+
+ //
+ //TAP version 1
+ public void testVersionMustBeOnFirstLine() {
+ expectTestingException();
+ }
+
+ //ok
+ //not ok
+ //ok # skip
+ //not ok # SKiPped
+ //ok # todo
+ //not ok # toDO
+ public void testBasicTestCases() {
+ mockModelUpdater.enterTestCase("1");
+ mockModelUpdater.setTestStatus(Status.Passed);
+ mockModelUpdater.exitTestCase();
+ mockModelUpdater.enterTestCase("2");
+ mockModelUpdater.setTestStatus(Status.Failed);
+ mockModelUpdater.exitTestCase();
+ mockModelUpdater.enterTestCase("3");
+ mockModelUpdater.addTestMessage(null, 0, Level.Message, "skip");
+ mockModelUpdater.setTestStatus(Status.Skipped);
+ mockModelUpdater.exitTestCase();
+ mockModelUpdater.enterTestCase("4");
+ mockModelUpdater.addTestMessage(null, 0, Level.Message, "SKiPped");
+ mockModelUpdater.setTestStatus(Status.Skipped);
+ mockModelUpdater.exitTestCase();
+ mockModelUpdater.enterTestCase("5");
+ mockModelUpdater.addTestMessage(null, 0, Level.Message, "todo");
+ mockModelUpdater.setTestStatus(Status.NotRun);
+ mockModelUpdater.exitTestCase();
+ mockModelUpdater.enterTestCase("6");
+ mockModelUpdater.addTestMessage(null, 0, Level.Message, "toDO");
+ mockModelUpdater.setTestStatus(Status.NotRun);
+ mockModelUpdater.exitTestCase();
+ }
+
+ //1..3
+ //ok
+ //not ok
+ public void testMorePlannedThanExecutedTestCases() {
+ mockModelUpdater.enterTestCase("1");
+ mockModelUpdater.setTestStatus(Status.Passed);
+ mockModelUpdater.exitTestCase();
+ mockModelUpdater.enterTestCase("2");
+ mockModelUpdater.setTestStatus(Status.Failed);
+ mockModelUpdater.exitTestCase();
+ mockModelUpdater.enterTestCase("3");
+ mockModelUpdater.setTestStatus(Status.Skipped);
+ mockModelUpdater.exitTestCase();
+ }
+
+ //ok
+ //ok 4
+ public void testForwardJump() {
+ mockModelUpdater.enterTestCase("1");
+ mockModelUpdater.setTestStatus(Status.Passed);
+ mockModelUpdater.exitTestCase();
+ mockModelUpdater.enterTestCase("2");
+ mockModelUpdater.setTestStatus(Status.Skipped);
+ mockModelUpdater.exitTestCase();
+ mockModelUpdater.enterTestCase("3");
+ mockModelUpdater.setTestStatus(Status.Skipped);
+ mockModelUpdater.exitTestCase();
+ mockModelUpdater.enterTestCase("4");
+ mockModelUpdater.setTestStatus(Status.Passed);
+ mockModelUpdater.exitTestCase();
+ }
+
+ //ok
+ //ok 1
+ public void testNoBackwardJump() {
+ mockModelUpdater.enterTestCase("1");
+ mockModelUpdater.setTestStatus(Status.Passed);
+ mockModelUpdater.exitTestCase();
+ expectTestingException();
+ }
+
+ //ok some test name
+ //not ok 3 other test name
+ public void testTestCaseName() {
+ mockModelUpdater.enterTestCase("some test name");
+ mockModelUpdater.setTestStatus(Status.Passed);
+ mockModelUpdater.exitTestCase();
+ mockModelUpdater.enterTestCase("2");
+ mockModelUpdater.setTestStatus(Status.Skipped);
+ mockModelUpdater.exitTestCase();
+ mockModelUpdater.enterTestCase("other test name");
+ mockModelUpdater.setTestStatus(Status.Failed);
+ mockModelUpdater.exitTestCase();
+ }
+
+ //1..3
+ //ok 1
+ //Bail out! because I'm done with this testing
+ //Ignored trailing data
+ public void testBailOut() {
+ mockModelUpdater.enterTestCase("1");
+ mockModelUpdater.setTestStatus(Status.Passed);
+ mockModelUpdater.exitTestCase();
+ mockModelUpdater.enterTestCase("2");
+ mockModelUpdater.addTestMessage(null, 0, Level.Message, "because I'm done with this testing");
+ mockModelUpdater.setTestStatus(Status.Aborted);
+ mockModelUpdater.exitTestCase();
+ mockModelUpdater.enterTestCase("3");
+ mockModelUpdater.addTestMessage(null, 0, Level.Message, "because I'm done with this testing");
+ mockModelUpdater.setTestStatus(Status.Aborted);
+ mockModelUpdater.exitTestCase();
+ }
+
+ //1..3
+ //ok
+ //1..2
+ public void testAtMostOnePlan() {
+ mockModelUpdater.enterTestCase("1");
+ mockModelUpdater.setTestStatus(Status.Passed);
+ mockModelUpdater.exitTestCase();
+ expectTestingException();
+ }
+
+ //1..2 # skipped for some reason
+ public void testSkippedAllTestsWithReason() {
+ mockModelUpdater.enterTestCase("1");
+ mockModelUpdater.addTestMessage(null, 0, Level.Message, "skipped for some reason");
+ mockModelUpdater.setTestStatus(Status.Skipped);
+ mockModelUpdater.exitTestCase();
+ mockModelUpdater.enterTestCase("2");
+ mockModelUpdater.addTestMessage(null, 0, Level.Message, "skipped for some reason");
+ mockModelUpdater.setTestStatus(Status.Skipped);
+ mockModelUpdater.exitTestCase();
+ }
+
+ //output for 1 (1)
+ //output for 1 (2)
+ //ok
+ //output for 2 (1)
+ //output for 2 (2)
+ //not ok second test # skipped for some reason
+ //ignored output
+ public void testOutput() {
+ mockModelUpdater.enterTestCase("1");
+ mockModelUpdater.addTestMessage(null, 0, Level.Message, "output for 1 (1)");
+ mockModelUpdater.addTestMessage(null, 0, Level.Message, "output for 1 (2)");
+ mockModelUpdater.setTestStatus(Status.Passed);
+ mockModelUpdater.exitTestCase();
+ mockModelUpdater.enterTestCase("second test");
+ mockModelUpdater.addTestMessage(null, 0, Level.Message, "skipped for some reason");
+ mockModelUpdater.addTestMessage(null, 0, Level.Message, "output for 2 (1)");
+ mockModelUpdater.addTestMessage(null, 0, Level.Message, "output for 2 (2)");
+ mockModelUpdater.setTestStatus(Status.Skipped);
+ mockModelUpdater.exitTestCase();
+ }
+
+ //filenameA: info: info text
+ //filenameB: warning: warning text
+ //filenameC:17: error: error text
+ //ok
+ public void testGCCDiagnosticOutput() {
+ mockModelUpdater.enterTestCase("1");
+ mockModelUpdater.addTestMessage("filenameA", 0, Level.Info, "info text");
+ mockModelUpdater.addTestMessage("filenameB", 0, Level.Warning, "warning text");
+ mockModelUpdater.addTestMessage("filenameC", 17, Level.Error, "error text");
+ mockModelUpdater.setTestStatus(Status.Passed);
+ mockModelUpdater.exitTestCase();
+ }
+}
|