summaryrefslogtreecommitdiffstats
path: root/sonar-batch
diff options
context:
space:
mode:
authorJulien HENRY <julien.henry@sonarsource.com>2015-04-22 23:32:39 +0200
committerJulien HENRY <julien.henry@sonarsource.com>2015-04-27 15:46:23 +0200
commit2f2eea3fa99f2148171885fb85561b83a7e4e052 (patch)
treecd8ef2f2ebb6a9a75b874d5d79245396fc3aeefa /sonar-batch
parent0d5306a89afda6a6eed06df78c3f732d247a86d6 (diff)
downloadsonarqube-2f2eea3fa99f2148171885fb85561b83a7e4e052.tar.gz
sonarqube-2f2eea3fa99f2148171885fb85561b83a7e4e052.zip
SONAR-6278 Feed tests in compute report
Diffstat (limited to 'sonar-batch')
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/deprecated/perspectives/BatchPerspectives.java7
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/index/ResourceCache.java16
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/index/ResourcePersister.java8
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/mediumtest/TaskResult.java32
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/report/TestExecutionAndCoveragePublisher.java133
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java1
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/mediumtest/coverage/CoverageMediumTest.java (renamed from sonar-batch/src/test/java/org/sonar/batch/mediumtest/coverage/CoverageTest.java)2
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/mediumtest/tests/CoveragePerTestMediumTest.java115
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/mediumtest/tests/TestExecutionMediumTest.java105
9 files changed, 410 insertions, 9 deletions
diff --git a/sonar-batch/src/main/java/org/sonar/batch/deprecated/perspectives/BatchPerspectives.java b/sonar-batch/src/main/java/org/sonar/batch/deprecated/perspectives/BatchPerspectives.java
index d743cca7301..445508ab0f5 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/deprecated/perspectives/BatchPerspectives.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/deprecated/perspectives/BatchPerspectives.java
@@ -19,10 +19,6 @@
*/
package org.sonar.batch.deprecated.perspectives;
-import org.sonar.core.component.PerspectiveBuilder;
-import org.sonar.core.component.PerspectiveNotFoundException;
-import org.sonar.core.component.ResourceComponent;
-
import com.google.common.collect.Maps;
import org.sonar.api.batch.SonarIndex;
import org.sonar.api.batch.fs.InputDir;
@@ -34,6 +30,9 @@ import org.sonar.api.component.ResourcePerspectives;
import org.sonar.api.resources.Directory;
import org.sonar.api.resources.File;
import org.sonar.api.resources.Resource;
+import org.sonar.core.component.PerspectiveBuilder;
+import org.sonar.core.component.PerspectiveNotFoundException;
+import org.sonar.core.component.ResourceComponent;
import javax.annotation.CheckForNull;
diff --git a/sonar-batch/src/main/java/org/sonar/batch/index/ResourceCache.java b/sonar-batch/src/main/java/org/sonar/batch/index/ResourceCache.java
index db5c29edeb4..12ca8d6be65 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/index/ResourceCache.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/index/ResourceCache.java
@@ -19,6 +19,7 @@
*/
package org.sonar.batch.index;
+import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.collect.Maps;
@@ -27,6 +28,8 @@ import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.resources.Library;
import org.sonar.api.resources.Resource;
+import org.sonar.api.resources.ResourceUtils;
+import org.sonar.core.component.ScanGraph;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
@@ -41,6 +44,16 @@ public class ResourceCache implements BatchComponent {
private final Map<Library, BatchResource> libraries = Maps.newLinkedHashMap();
private BatchResource root;
+ private final ScanGraph scanGraph;
+
+ public ResourceCache(ScanGraph scanGraph) {
+ this.scanGraph = scanGraph;
+ }
+
+ @VisibleForTesting
+ public ResourceCache() {
+ this.scanGraph = null;
+ }
@CheckForNull
public BatchResource get(String componentKey) {
@@ -73,6 +86,9 @@ public class ResourceCache implements BatchComponent {
} else {
libraries.put((Library) resource, batchResource);
}
+ if (scanGraph != null && ResourceUtils.isPersistable(batchResource.resource())) {
+ scanGraph.addComponent(batchResource.resource());
+ }
return batchResource;
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/index/ResourcePersister.java b/sonar-batch/src/main/java/org/sonar/batch/index/ResourcePersister.java
index 3566bb0edcd..1520a672cc5 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/index/ResourcePersister.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/index/ResourcePersister.java
@@ -54,15 +54,15 @@ public class ResourcePersister implements ScanPersister {
private final DatabaseSession session;
private final ResourcePermissions permissions;
private final ResourceCache resourceCache;
- private final ScanGraph graph;
private final ProjectTree projectTree;
+ private final ScanGraph scanGraph;
- public ResourcePersister(ProjectTree projectTree, DatabaseSession session, ResourcePermissions permissions, ResourceCache resourceCache, ScanGraph graph) {
+ public ResourcePersister(ProjectTree projectTree, DatabaseSession session, ResourcePermissions permissions, ResourceCache resourceCache, ScanGraph scanGraph) {
this.projectTree = projectTree;
this.session = session;
this.permissions = permissions;
this.resourceCache = resourceCache;
- this.graph = graph;
+ this.scanGraph = scanGraph;
}
@Override
@@ -101,7 +101,7 @@ public class ResourcePersister implements ScanPersister {
}
batchResource.setSnapshot(s);
if (ResourceUtils.isPersistable(batchResource.resource())) {
- graph.addComponent(batchResource.resource(), batchResource.snapshotId());
+ scanGraph.completeComponent(batchResource.key(), batchResource.resource().getId(), s.getId());
}
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/mediumtest/TaskResult.java b/sonar-batch/src/main/java/org/sonar/batch/mediumtest/TaskResult.java
index f2f7b379759..43cb60c251a 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/mediumtest/TaskResult.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/mediumtest/TaskResult.java
@@ -264,6 +264,38 @@ public class TaskResult implements org.sonar.batch.mediumtest.ScanTaskObserver {
return null;
}
+ public BatchReport.Test testExecutionFor(InputFile testFile, String testName) {
+ int ref = reportComponents.get(((DefaultInputFile) testFile).key()).getRef();
+ try (InputStream inputStream = FileUtils.openInputStream(getReportReader().readTests(ref))) {
+ BatchReport.Test test = BatchReport.Test.PARSER.parseDelimitedFrom(inputStream);
+ while (test != null) {
+ if (test.getName().equals(testName)) {
+ return test;
+ }
+ test = BatchReport.Test.PARSER.parseDelimitedFrom(inputStream);
+ }
+ } catch (Exception e) {
+ throw new IllegalStateException(e);
+ }
+ return null;
+ }
+
+ public BatchReport.CoverageDetail coveragePerTestFor(InputFile testFile, String testName) {
+ int ref = reportComponents.get(((DefaultInputFile) testFile).key()).getRef();
+ try (InputStream inputStream = FileUtils.openInputStream(getReportReader().readCoverageDetails(ref))) {
+ BatchReport.CoverageDetail details = BatchReport.CoverageDetail.PARSER.parseDelimitedFrom(inputStream);
+ while (details != null) {
+ if (details.getTestName().equals(testName)) {
+ return details;
+ }
+ details = BatchReport.CoverageDetail.PARSER.parseDelimitedFrom(inputStream);
+ }
+ } catch (Exception e) {
+ throw new IllegalStateException(e);
+ }
+ return null;
+ }
+
/**
* @return null if no dependency else return dependency weight.
*/
diff --git a/sonar-batch/src/main/java/org/sonar/batch/report/TestExecutionAndCoveragePublisher.java b/sonar-batch/src/main/java/org/sonar/batch/report/TestExecutionAndCoveragePublisher.java
new file mode 100644
index 00000000000..53c86c345a4
--- /dev/null
+++ b/sonar-batch/src/main/java/org/sonar/batch/report/TestExecutionAndCoveragePublisher.java
@@ -0,0 +1,133 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.batch.report;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Iterables;
+import org.sonar.api.batch.fs.InputFile.Type;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.test.CoverageBlock;
+import org.sonar.api.test.MutableTestCase;
+import org.sonar.api.test.MutableTestPlan;
+import org.sonar.api.test.TestCase;
+import org.sonar.batch.index.BatchResource;
+import org.sonar.batch.index.ResourceCache;
+import org.sonar.batch.protocol.Constants.TestStatus;
+import org.sonar.batch.protocol.output.BatchReport;
+import org.sonar.batch.protocol.output.BatchReport.CoverageDetail;
+import org.sonar.batch.protocol.output.BatchReport.Test;
+import org.sonar.batch.protocol.output.BatchReportWriter;
+import org.sonar.core.test.TestPlanBuilder;
+
+import java.util.HashSet;
+import java.util.Set;
+
+public class TestExecutionAndCoveragePublisher implements ReportPublisherStep {
+
+ private final class FunctionImplementation implements Function<String, CoverageDetail> {
+ private final MutableTestPlan testPlan;
+ private BatchReport.CoverageDetail.Builder builder = BatchReport.CoverageDetail.newBuilder();
+ private BatchReport.CoverageDetail.CoveredFile.Builder coveredBuilder = BatchReport.CoverageDetail.CoveredFile.newBuilder();
+
+ private FunctionImplementation(MutableTestPlan testPlan) {
+ this.testPlan = testPlan;
+ }
+
+ @Override
+ public CoverageDetail apply(String testName) {
+ // Take first test with provided name
+ MutableTestCase testCase = testPlan.testCasesByName(testName).iterator().next();
+ builder.clear();
+ builder.setTestName(testName);
+ for (CoverageBlock block : testCase.coverageBlocks()) {
+ coveredBuilder.clear();
+ coveredBuilder.setFileRef(resourceCache.get(block.testable().component().key()).batchId());
+ for (int line : block.lines()) {
+ coveredBuilder.addCoveredLine(line);
+ }
+ builder.addCoveredFile(coveredBuilder.build());
+ }
+ return builder.build();
+ }
+ }
+
+ private final ResourceCache resourceCache;
+ private final TestPlanBuilder testPlanBuilder;
+
+ public TestExecutionAndCoveragePublisher(ResourceCache resourceCache, TestPlanBuilder testPlanBuilder) {
+ this.resourceCache = resourceCache;
+ this.testPlanBuilder = testPlanBuilder;
+ }
+
+ @Override
+ public void publish(BatchReportWriter writer) {
+ for (final BatchResource resource : resourceCache.all()) {
+ if (!resource.isFile()) {
+ continue;
+ }
+
+ DefaultInputFile inputFile = (DefaultInputFile) resource.inputPath();
+ if (inputFile.type() != Type.TEST) {
+ continue;
+ }
+
+ final MutableTestPlan testPlan = testPlanBuilder.get(MutableTestPlan.class, inputFile.key());
+ if (testPlan == null || Iterables.isEmpty(testPlan.testCases())) {
+ continue;
+ }
+
+ final Set<String> testNamesWithCoverage = new HashSet<>();
+
+ writer.writeTests(resource.batchId(), Iterables.transform(testPlan.testCases(), new Function<MutableTestCase, BatchReport.Test>() {
+
+ private BatchReport.Test.Builder builder = BatchReport.Test.newBuilder();
+
+ @Override
+ public Test apply(MutableTestCase testCase) {
+ builder.clear();
+ builder.setName(testCase.name());
+ if (testCase.doesCover()) {
+ testNamesWithCoverage.add(testCase.name());
+ }
+ Long durationInMs = testCase.durationInMs();
+ if (durationInMs != null) {
+ builder.setDurationInMs(durationInMs);
+ }
+ String msg = testCase.message();
+ if (msg != null) {
+ builder.setMsg(msg);
+ }
+ String stack = testCase.stackTrace();
+ if (stack != null) {
+ builder.setStacktrace(stack);
+ }
+ TestCase.Status status = testCase.status();
+ if (status != null) {
+ builder.setStatus(TestStatus.valueOf(status.name()));
+ }
+ return builder.build();
+ }
+
+ }));
+
+ writer.writeCoverageDetails(resource.batchId(), Iterables.transform(testNamesWithCoverage, new FunctionImplementation(testPlan)));
+ }
+ }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java
index e510aae33a6..8e074792365 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java
@@ -188,6 +188,7 @@ public class ProjectScanContainer extends ComponentContainer {
DuplicationsPublisher.class,
CoveragePublisher.class,
SourcePublisher.class,
+ TestExecutionAndCoveragePublisher.class,
ScanTaskObservers.class);
}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/coverage/CoverageTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/coverage/CoverageMediumTest.java
index 6a10da86b37..b3e786841a0 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/coverage/CoverageTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/coverage/CoverageMediumTest.java
@@ -38,7 +38,7 @@ import java.io.IOException;
import static org.assertj.core.api.Assertions.assertThat;
-public class CoverageTest {
+public class CoverageMediumTest {
@org.junit.Rule
public TemporaryFolder temp = new TemporaryFolder();
diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/tests/CoveragePerTestMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/tests/CoveragePerTestMediumTest.java
new file mode 100644
index 00000000000..be0ba5e9207
--- /dev/null
+++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/tests/CoveragePerTestMediumTest.java
@@ -0,0 +1,115 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.batch.mediumtest.tests;
+
+import com.google.common.collect.ImmutableMap;
+import org.apache.commons.io.FileUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.batch.mediumtest.BatchMediumTester;
+import org.sonar.batch.mediumtest.TaskResult;
+import org.sonar.xoo.XooPlugin;
+
+import java.io.File;
+import java.io.IOException;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class CoveragePerTestMediumTest {
+
+ @org.junit.Rule
+ public TemporaryFolder temp = new TemporaryFolder();
+
+ public BatchMediumTester tester = BatchMediumTester.builder()
+ .registerPlugin("xoo", new XooPlugin())
+ .addDefaultQProfile("xoo", "Sonar Way")
+ .build();
+
+ @Before
+ public void prepare() {
+ tester.start();
+ }
+
+ @After
+ public void stop() {
+ tester.stop();
+ }
+
+ @Test
+ public void coveragePerTestInReport() throws IOException {
+
+ File baseDir = temp.newFolder();
+ File srcDir = new File(baseDir, "src");
+ srcDir.mkdir();
+ File testDir = new File(baseDir, "test");
+ testDir.mkdir();
+
+ File xooFile = new File(srcDir, "sample.xoo");
+ FileUtils.write(xooFile, "foo");
+
+ File xooFile2 = new File(srcDir, "sample2.xoo");
+ FileUtils.write(xooFile2, "foo");
+
+ File xooTestFile = new File(testDir, "sampleTest.xoo");
+ FileUtils.write(xooTestFile, "failure\nerror\nok\nskipped");
+
+ File xooTestFile2 = new File(testDir, "sample2Test.xoo");
+ FileUtils.write(xooTestFile2, "test file tests");
+
+ File xooTestExecutionFile = new File(testDir, "sampleTest.xoo.test");
+ FileUtils.write(xooTestExecutionFile, "some test:4:::OK:UNIT\n" +
+ "another test:10:::OK:UNIT\n" +
+ "test without coverage:10:::OK:UNIT\n");
+
+ File xooCoveragePerTestFile = new File(testDir, "sampleTest.xoo.testcoverage");
+ FileUtils.write(xooCoveragePerTestFile, "some test;src/sample.xoo,10,11;src/sample2.xoo,1,2\n" +
+ "another test;src/sample.xoo,10,20\n");
+
+ TaskResult result = tester.newTask()
+ .properties(ImmutableMap.<String, String>builder()
+ .put("sonar.task", "scan")
+ .put("sonar.projectBaseDir", baseDir.getAbsolutePath())
+ .put("sonar.projectKey", "com.foo.project")
+ .put("sonar.projectName", "Foo Project")
+ .put("sonar.projectVersion", "1.0-SNAPSHOT")
+ .put("sonar.projectDescription", "Description of Foo Project")
+ .put("sonar.sources", "src")
+ .put("sonar.tests", "test")
+ .build())
+ .start();
+
+ InputFile file = result.inputFile("test/sampleTest.xoo");
+ org.sonar.batch.protocol.output.BatchReport.CoverageDetail someTest = result.coveragePerTestFor(file, "some test");
+ assertThat(someTest.getCoveredFileList()).hasSize(2);
+ assertThat(someTest.getCoveredFile(0).getFileRef()).isGreaterThan(0);
+ assertThat(someTest.getCoveredFile(0).getCoveredLineList()).containsExactly(10, 11);
+ assertThat(someTest.getCoveredFile(1).getFileRef()).isGreaterThan(0);
+ assertThat(someTest.getCoveredFile(1).getCoveredLineList()).containsExactly(1, 2);
+
+ org.sonar.batch.protocol.output.BatchReport.CoverageDetail anotherTest = result.coveragePerTestFor(file, "another test");
+ assertThat(anotherTest.getCoveredFileList()).hasSize(1);
+ assertThat(anotherTest.getCoveredFile(0).getFileRef()).isGreaterThan(0);
+ assertThat(anotherTest.getCoveredFile(0).getCoveredLineList()).containsExactly(10, 20);
+ }
+
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/tests/TestExecutionMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/tests/TestExecutionMediumTest.java
new file mode 100644
index 00000000000..2e96cd42156
--- /dev/null
+++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/tests/TestExecutionMediumTest.java
@@ -0,0 +1,105 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.batch.mediumtest.tests;
+
+import com.google.common.collect.ImmutableMap;
+import org.apache.commons.io.FileUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.batch.mediumtest.BatchMediumTester;
+import org.sonar.batch.mediumtest.TaskResult;
+import org.sonar.batch.protocol.Constants.TestStatus;
+import org.sonar.xoo.XooPlugin;
+
+import java.io.File;
+import java.io.IOException;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class TestExecutionMediumTest {
+
+ @org.junit.Rule
+ public TemporaryFolder temp = new TemporaryFolder();
+
+ public BatchMediumTester tester = BatchMediumTester.builder()
+ .registerPlugin("xoo", new XooPlugin())
+ .addDefaultQProfile("xoo", "Sonar Way")
+ .build();
+
+ @Before
+ public void prepare() {
+ tester.start();
+ }
+
+ @After
+ public void stop() {
+ tester.stop();
+ }
+
+ @Test
+ public void unitTests() throws IOException {
+
+ File baseDir = temp.newFolder();
+ File srcDir = new File(baseDir, "src");
+ srcDir.mkdir();
+ File testDir = new File(baseDir, "test");
+ testDir.mkdir();
+
+ File xooFile = new File(srcDir, "sample.xoo");
+ FileUtils.write(xooFile, "foo");
+
+ File xooTestFile = new File(testDir, "sampleTest.xoo");
+ FileUtils.write(xooTestFile, "failure\nerror\nok\nskipped");
+
+ File xooTestExecutionFile = new File(testDir, "sampleTest.xoo.test");
+ FileUtils.write(xooTestExecutionFile, "skipped::::SKIPPED:UNIT\n" +
+ "failure:2:Failure::FAILURE:UNIT\n" +
+ "error:2:Error:The stack:ERROR:UNIT\n" +
+ "success:4:::OK:INTEGRATION");
+
+ TaskResult result = tester.newTask()
+ .properties(ImmutableMap.<String, String>builder()
+ .put("sonar.task", "scan")
+ .put("sonar.projectBaseDir", baseDir.getAbsolutePath())
+ .put("sonar.projectKey", "com.foo.project")
+ .put("sonar.projectName", "Foo Project")
+ .put("sonar.projectVersion", "1.0-SNAPSHOT")
+ .put("sonar.projectDescription", "Description of Foo Project")
+ .put("sonar.sources", "src")
+ .put("sonar.tests", "test")
+ .build())
+ .start();
+
+ InputFile file = result.inputFile("test/sampleTest.xoo");
+ org.sonar.batch.protocol.output.BatchReport.Test success = result.testExecutionFor(file, "success");
+ assertThat(success.getDurationInMs()).isEqualTo(4);
+ assertThat(success.getStatus()).isEqualTo(TestStatus.OK);
+
+ org.sonar.batch.protocol.output.BatchReport.Test error = result.testExecutionFor(file, "error");
+ assertThat(error.getDurationInMs()).isEqualTo(2);
+ assertThat(error.getStatus()).isEqualTo(TestStatus.ERROR);
+ assertThat(error.getMsg()).isEqualTo("Error");
+ assertThat(error.getStacktrace()).isEqualTo("The stack");
+ }
+
+}