Skip to content

Commit

Permalink
Merge ee3836e into abc1818
Browse files Browse the repository at this point in the history
  • Loading branch information
kimmoal committed Nov 23, 2017
2 parents abc1818 + ee3836e commit 33c5bf7
Show file tree
Hide file tree
Showing 136 changed files with 3,066 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,6 @@ __pycache__/
/tmc-langs-java/src/main/resources/tmc-junit-runner.jar
/tmc-langs-java/src/test/resources/exit_zero/build/

# Qt Creator user files
*.pro.user*

3 changes: 3 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,15 @@ before_install:
- curl -L https://static.rust-lang.org/rustup.sh | sh -s -- --channel=stable --yes --prefix=$PWD --disable-sudo
- sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys E084DAB9
- echo "deb https://cloud.r-project.org/bin/linux/ubuntu trusty/" | sudo tee -a /etc/apt/sources.list
- sudo add-apt-repository --yes ppa:beineri/opt-qt591-trusty
- sudo apt-get update -qq
- sudo apt-get install r-base -y
- sudo apt-get install qt59base
- sudo chmod 277 /usr/local/lib/R/site-library
- Rscript -e 'install.packages(c("devtools","testthat"),repos="http://cran.us.r-project.org")'
- Rscript -e 'devtools::install_github("RTMC/tmc-r-tester/tmcRtestrunner")'
- export PATH=$PATH:$PWD/bin
- source /opt/qt59/bin/qt59-env.sh
- export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/lib
- mkdir -p $HOME/bin && ln -s $(which python3.4) $HOME/bin/python3 && export PATH="$HOME/bin:$PATH"
- mvn install -Dmaven.test.skip=true
Expand Down
1 change: 1 addition & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@
<module>tmc-langs-python3</module>
<module>tmc-langs-notests</module>
<!--module>tmc-langs-rust</module-->
<module>tmc-langs-qmake</module>
<!-- TODO: add plugins and support libraries here -->

<module>tmc-langs-util</module>
Expand Down
71 changes: 71 additions & 0 deletions tmc-langs-qmake/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>fi.helsinki.cs.tmc</groupId>
<artifactId>tmc-langs</artifactId>
<version>0.7.7-SNAPSHOT</version>
</parent>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
<tmc.basedir>../target</tmc.basedir>
</properties>

<artifactId>tmc-langs-qmake</artifactId>
<packaging>jar</packaging>

<!-- Deploy to maven.testmycode.net/nexus -->
<distributionManagement>
<repository>
<id>tmc</id>
<name>TMC releases</name>
<url>http://maven.testmycode.net/nexus/content/repositories/releases</url>
</repository>
<snapshotRepository>
<id>tmc-snapshots</id>
<name>TMC snapshots</name>
<url>http://maven.testmycode.net/nexus/content/repositories/snapshots</url>
</snapshotRepository>
</distributionManagement>

<dependencies>
<dependency>
<groupId>fi.helsinki.cs.tmc</groupId>
<artifactId>tmc-langs-framework</artifactId>
<version>${project.version}</version>
<type>jar</type>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
<configuration>
<excludes>
<exclude>**/make-project/**/*</exclude>
<exclude>**/eRror/**/*</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.6</version>
<configuration>
<outputDirectory>${tmc.basedir}</outputDirectory>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package fi.helsinki.cs.tmc.langs.qmake;

import fi.helsinki.cs.tmc.langs.domain.TestResult;

import com.google.common.collect.ImmutableList;

import java.util.List;

public final class QTestCase {

private String name;
private boolean passed;
private String message;
private List<String> points;

/**
* Create a test case for QT tests.
*
* @param name Name of the test
* @param passed Passed status
* @param message for failed assertion
* @param points for test case
*/
public QTestCase(String name, boolean passed, String message, List<String> points) {
this.name = name;
this.passed = passed;
this.message = message;
this.points = points;
}

/**
* Get the test result of this test case.
*/
public TestResult getTestResult() {
String msg = message;

ImmutableList<String> trace = ImmutableList.of();
ImmutableList<String> points = ImmutableList.of();
if (this.points != null) {
points = ImmutableList.copyOf(this.points);
}

return new TestResult(name, passed, points, msg, trace);
}

public String getName() {
return name;
}

public boolean getResult() {
return passed;
}

public String getMessage() {
return message;
}

public List<String> getPoints() {
return points;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
package fi.helsinki.cs.tmc.langs.qmake;

import fi.helsinki.cs.tmc.langs.domain.RunResult;
import fi.helsinki.cs.tmc.langs.domain.RunResult.Status;
import fi.helsinki.cs.tmc.langs.domain.TestResult;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

public final class QTestResultParser {

private static final String DOC_NULL_ERROR_MESSAGE = "Failed to parse test results";
private static final String SAX_PARSER_ERROR = "SAX parser error occured";
private static final String PARSING_DONE_MESSAGE = "Qt test cases parsed.";

private static final Logger log = LoggerFactory.getLogger(QTestResultParser.class);

private List<TestResult> tests;

public QTestResultParser() {
}

public void loadTests(Path testResult) {
this.tests = parseTestCases(testResult);
}

private List<TestResult> parseTestCases(Path testOutput) {
Document doc;
try {
doc = prepareDocument(testOutput);
} catch (ParserConfigurationException | IOException e) {
log.error("Unexpected exception, could not parse Qt testcases.", e);
return new ArrayList<>();
}

NodeList nodeList = doc.getElementsByTagName("TestFunction");
List<TestResult> cases = createQtTestResults(nodeList);

log.info(PARSING_DONE_MESSAGE);

return cases;
}

private Document prepareDocument(Path testOutput)
throws ParserConfigurationException, IOException {
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = dbFactory.newDocumentBuilder();
documentBuilder.setErrorHandler(null); // Silence logging
dbFactory.setValidating(false);

InputStream inputStream = new FileInputStream(testOutput.toFile());
Reader reader = new InputStreamReader(inputStream, "UTF-8");
InputSource is = new InputSource(reader);
is.setEncoding("UTF-8");

Document doc = null;
try {
doc = documentBuilder.parse(is);
} catch (SAXException ex) {
log.info(SAX_PARSER_ERROR);
log.info(ex.toString());
}

if (doc == null) {
log.info(DOC_NULL_ERROR_MESSAGE);
throw new IllegalStateException(DOC_NULL_ERROR_MESSAGE);
}

doc.getDocumentElement().normalize();

return doc;
}

/**
* Parses Qt testlib XML output, as generated with -o filename.xml,xml.
* <p>
* Points are mapped to test cases with Message node type 'qinfo'. These
* messages contain: prefix "TMC:" test case name: "test_function_name"
* points separated by period: ".1"
*
* With failing testcase assertions, there will be an Incident node with
* type "fail" and Description node with the failed assertion message.
*
* When the testcase assertion(s) has passed, there will be an Incident node
* with type "pass" and no Description node.
* </p>
* <TestFunction name="test_function_name">
* <Message type="qinfo" file="" line="0">
* <Description><![CDATA[TMC:test_function_name.1]]></Description>
* </Message>
* <Incident type="fail" file="test_source.cpp" line="420">
* <Description>
* <![CDATA['!strcmp(hello_msg(), "Helo, world!" )' returned FALSE. ()]]>
* </Description>
* </Incident>
* <Duration msecs="0.135260"/>
* </TestFunction>
*
*/
private List<TestResult> createQtTestResults(NodeList nodeList) {
List<TestResult> cases = new ArrayList<>();

for (int i = 0; i < nodeList.getLength(); i++) {
Element testcase = (Element) nodeList.item(i);
List<String> points = parsePoints(testcase);

if (points.isEmpty()) {
// No points == not a TMC testcase
continue;
}

Element incident = (Element) testcase.getElementsByTagName("Incident").item(0);

String id = testcase.getAttribute("name");
boolean passed = incident.getAttribute("type").equals("pass");
String msg = "";

// Get the assertion error if testcase failed
if (!passed) {
Element desc = (Element) incident.getElementsByTagName("Description").item(0);
msg = desc.getTextContent();
}

ImmutableList<String> trace = ImmutableList.of();
cases.add(new TestResult(id, passed, ImmutableList.copyOf(points), msg, trace));
}

return cases;
}

/**
* <p>
* Parse potential points from testcase.
* </p>
*/
private List<String> parsePoints(Element testcase) {
List<String> points = new ArrayList<>();
NodeList messages = testcase.getElementsByTagName("Message");
for (int i = 0; i < messages.getLength(); i++) {
// Convert node to element, messages.item(i) returns a node
Element message = (Element) messages.item(i);
Element desc = (Element) message.getElementsByTagName("Description").item(0);
String text = desc.getTextContent();
if (text.matches("^(TMC:.*)")) {
String[] split = text.split("\\.");
String result = split[1];
for (int j = 2; j < split.length; j++) {
result += "." + split[j];
}
points.add(result);
}
}

return points;
}

public List<TestResult> getTestResults() {
return this.tests;
}

private Status getResultStatus() {
for (TestResult result : getTestResults()) {
if (!result.isSuccessful()) {
return Status.TESTS_FAILED;
}
}

return Status.PASSED;
}

/**
* Returns the run result of this file.
*
* @return Runresults
*/
public RunResult result() {
return new RunResult(
getResultStatus(),
ImmutableList.copyOf(getTestResults()),
new ImmutableMap.Builder<String, byte[]>().build());
}
}
Loading

0 comments on commit 33c5bf7

Please sign in to comment.