1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-05 08:46:02 +02:00

Bug 472767 - Add support for Test Anything Protocol test runner

Change-Id: I3da84f0bdf46ca5082638ec7a6540df82f2cda63
Signed-off-by: Colin Leitner <colin.leitner@gmail.com>
This commit is contained in:
Colin Leitner 2015-07-15 22:50:16 +02:00 committed by Gerrit Code Review @ Eclipse.org
parent 2b3d664972
commit 23833f697e
18 changed files with 813 additions and 1 deletions

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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

View file

@ -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"

View file

@ -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>

View file

@ -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

View file

@ -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

View file

@ -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>

View file

@ -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>

View file

@ -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() {
}
}

View file

@ -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

View file

@ -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));
}
}

View file

@ -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>
* &lt;filename&gt;: (error|warning|info): ...
* &lt;filename&gt;:&lt;line&gt;: (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()));
}
}
}

View file

@ -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

View file

@ -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();
}
}