Skip to content

Commit

Permalink
Added JUnit parser
Browse files Browse the repository at this point in the history
  • Loading branch information
chemfy committed Jun 4, 2019
1 parent 23b8371 commit 1310007
Show file tree
Hide file tree
Showing 6 changed files with 246 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ A number of **parsers** have been implemented. Some **parsers** can parse output
| [_Infer_](http://fbinfer.com/) | `PMD` | Facebook Infer. With `--pmd-xml`.
| [_JCReport_](https://github.com/jCoderZ/fawkez/wiki/JcReport) | `JCREPORT` |
| [_JSHint_](http://jshint.com/) | `JSHINT` |
| [_JUnit_](https://junit.org/junit4/) | `JUNIT` |
| [_KTLint_](https://github.com/shyiko/ktlint) | `CHECKSTYLE` |
| [_Klocwork_](http://www.klocwork.com/products-services/klocwork/static-code-analysis) | `KLOCWORK` |
| [_KotlinGradle_](https://github.com/JetBrains/kotlin) | `KOTLINGRADLE` | Output from Kotlin Gradle Plugin.
Expand Down
76 changes: 76 additions & 0 deletions src/main/java/se/bjurr/violations/lib/parsers/JUnitParser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package se.bjurr.violations.lib.parsers;

import static se.bjurr.violations.lib.util.ViolationParserUtils.getAttribute;
import static se.bjurr.violations.lib.util.ViolationParserUtils.getChunks;

import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import se.bjurr.violations.lib.model.SEVERITY;
import se.bjurr.violations.lib.model.Violation;
import se.bjurr.violations.lib.reports.Parser;

public class JUnitParser implements ViolationsParser {
private static Logger LOG = Logger.getLogger(JUnitParser.class.getSimpleName());

@Override
public List<Violation> parseReportOutput(String reportContent) throws Exception {
final List<Violation> violations = new ArrayList<>();

final List<String> errors = getChunks(reportContent, "<testcase", "(/>|</testcase>)");

for (final String errorChunk : errors) {
final List<String> failures = getChunks(errorChunk, "<failure", "</failure>");
for (final String failure : failures) {
final String message = getAttribute(failure, "message");
final String className = getAttribute(errorChunk, "classname");
final String name = getAttribute(errorChunk, "name");
final String type = getAttribute(errorChunk, "type");

final List<String> failLine = getChunks(failure, className + "." + name, "\\)");

if (failLine.isEmpty()) {
LOG.log(Level.WARNING, "Found failure, but failed to find fail line from stacktrace");
continue;
}
final List<String> fileNameAndLine = getChunks(failLine.get(0), "\\(", "\\)");

if (fileNameAndLine.isEmpty()) {
LOG.log(
Level.WARNING,
"Found failure line from stacktrace. But failed to get File name and line number from it.");
continue;
}

final String[] split = fileNameAndLine.get(0).split("[.\\:\\)]");

if (split.length < 3) {
LOG.log(Level.WARNING, "Failed to split Filename to its ending and line number");
continue;
}

int lineOfFailure;

try {
lineOfFailure = Integer.parseInt(split[2]);
} catch (NumberFormatException e) {
LOG.log(Level.WARNING, "Failed to parse line number from: " + split[2]);
continue;
}

violations.add(
Violation.violationBuilder()
.setParser(Parser.JUNIT)
.setMessage(name + " : " + message)
.setStartLine(lineOfFailure)
.setFile(className.replaceAll("\\.", "/") + "." + split[1])
.setSource(className)
.setRule(type)
.setSeverity(SEVERITY.ERROR)
.build());
}
}
return violations;
}
}
2 changes: 2 additions & 0 deletions src/main/java/se/bjurr/violations/lib/reports/Parser.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import se.bjurr.violations.lib.parsers.IARParser;
import se.bjurr.violations.lib.parsers.JCReportParser;
import se.bjurr.violations.lib.parsers.JSHintParser;
import se.bjurr.violations.lib.parsers.JUnitParser;
import se.bjurr.violations.lib.parsers.KlocworkParser;
import se.bjurr.violations.lib.parsers.KotlinGradleParser;
import se.bjurr.violations.lib.parsers.KotlinMavenParser;
Expand Down Expand Up @@ -65,6 +66,7 @@ public enum Parser {
IAR(new IARParser()), //
JCREPORT(new JCReportParser()), //
JSHINT(new JSHintParser()), //
JUNIT(new JUnitParser()), //
LINT(new LintParser()), //
KLOCWORK(new KlocworkParser()), //
KOTLINMAVEN(new KotlinMavenParser()), //
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public enum Reporter {
"With `--no_wrap_diagnostics`"),
JCREPORT("JCReport", Parser.JCREPORT, "https://github.com/jCoderZ/fawkez/wiki/JcReport", ""),
JSHINT("JSHint", Parser.JSHINT, "http://jshint.com/", ""),
JUNIT("JUnit", Parser.JUNIT, "https://junit.org/junit4/", ""),
KTLINT("KTLint", Parser.CHECKSTYLE, "https://github.com/shyiko/ktlint", ""),
KLOCWORK(
"Klocwork",
Expand Down
48 changes: 48 additions & 0 deletions src/test/java/se/bjurr/violations/lib/JUnitTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package se.bjurr.violations.lib;

import static org.assertj.core.api.Assertions.assertThat;
import static se.bjurr.violations.lib.TestUtils.getRootFolder;
import static se.bjurr.violations.lib.ViolationsApi.violationsApi;
import static se.bjurr.violations.lib.model.SEVERITY.ERROR;
import static se.bjurr.violations.lib.reports.Parser.JUNIT;

import java.util.List;
import org.junit.Test;
import se.bjurr.violations.lib.model.Violation;

public class JUnitTest {
@Test
public void testThatViolationsCanBeParsed() {
String rootFolder = getRootFolder();

List<Violation> actual =
violationsApi() //
.withPattern(".*/junit/.*\\.xml$") //
.inFolder(rootFolder) //
.findAll(JUNIT) //
.violations();

assertThat(actual) //
.hasSize(2);

assertThat(actual.get(0).getSource()) //
.isEqualTo("com.example.jenkinstest.ExampleUnitTest");
assertThat(actual.get(0).getFile()) //
.isEqualTo("com/example/jenkinstest/ExampleUnitTest.kt");
assertThat(actual.get(0).getMessage()) //
.startsWith("failTest4") //
.contains("java.lang.AssertionError");
assertThat(actual.get(0).getSeverity()) //
.isEqualTo(ERROR);

assertThat(actual.get(1).getSource()) //
.isEqualTo("com.example.jenkinstest.ExampleUnitTest");
assertThat(actual.get(1).getFile()) //
.isEqualTo("com/example/jenkinstest/ExampleUnitTest.kt");
assertThat(actual.get(1).getMessage()) //
.startsWith("failTest5") //
.contains("java.lang.AssertionError");
assertThat(actual.get(1).getSeverity()) //
.isEqualTo(ERROR);
}
}
118 changes: 118 additions & 0 deletions src/test/resources/junit/junit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuite name="com.example.jenkinstest.ExampleUnitTest" tests="6" skipped="0" failures="2" errors="0" timestamp="2019-05-31T03:44:09" hostname="localhost" time="0.002">
<properties/>
<testcase name="failTest2" classname="com.example.jenkinstest.ExampleUnitTest" time="0.0"/>
<testcase name="failTest3" classname="com.example.jenkinstest.ExampleUnitTest" time="0.0"/>
<testcase name="failTest4" classname="com.example.jenkinstest.ExampleUnitTest" time="0.0">
<failure message="java.lang.AssertionError" type="java.lang.AssertionError">java.lang.AssertionError
at org.junit.Assert.fail(Assert.java:86)
at org.junit.Assert.fail(Assert.java:95)
at com.example.jenkinstest.ExampleUnitTest.failTest4(ExampleUnitTest.kt:44)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass(JUnitTestClassExecutor.java:110)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:58)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:38)
at org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass(AbstractJUnitTestClassProcessor.java:62)
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
at com.sun.proxy.$Proxy2.processTestClass(Unknown Source)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:118)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:175)
at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:157)
at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:404)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
at java.lang.Thread.run(Thread.java:745)
</failure>
</testcase>
<testcase name="failTest5" classname="com.example.jenkinstest.ExampleUnitTest" time="0.0">
<failure message="java.lang.AssertionError" type="java.lang.AssertionError">java.lang.AssertionError
at org.junit.Assert.fail(Assert.java:86)
at org.junit.Assert.fail(Assert.java:95)
at com.example.jenkinstest.ExampleUnitTest.failTest5(ExampleUnitTest.kt:39)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass(JUnitTestClassExecutor.java:110)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:58)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:38)
at org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass(AbstractJUnitTestClassProcessor.java:62)
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
at com.sun.proxy.$Proxy2.processTestClass(Unknown Source)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:118)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:175)
at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:157)
at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:404)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
at java.lang.Thread.run(Thread.java:745)
</failure>
</testcase>
<testcase name="failTest" classname="com.example.jenkinstest.ExampleUnitTest" time="0.0"/>
<testcase name="addition_isCorrect" classname="com.example.jenkinstest.ExampleUnitTest" time="0.0"/>
<system-out><![CDATA[]]></system-out>
<system-err><![CDATA[]]></system-err>
</testsuite>

0 comments on commit 1310007

Please sign in to comment.