aboutsummaryrefslogtreecommitdiffstats
path: root/plugins
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 /plugins
parent0d5306a89afda6a6eed06df78c3f732d247a86d6 (diff)
downloadsonarqube-2f2eea3fa99f2148171885fb85561b83a7e4e052.tar.gz
sonarqube-2f2eea3fa99f2148171885fb85561b83a7e4e052.zip
SONAR-6278 Feed tests in compute report
Diffstat (limited to 'plugins')
-rw-r--r--plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java6
-rw-r--r--plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/test/CoveragePerTestSensor.java122
-rw-r--r--plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/test/TestExecutionSensor.java119
3 files changed, 247 insertions, 0 deletions
diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java
index 48756de3679..2d77a3d90c4 100644
--- a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java
+++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java
@@ -29,6 +29,8 @@ import org.sonar.xoo.lang.*;
import org.sonar.xoo.rule.*;
import org.sonar.xoo.scm.XooBlameCommand;
import org.sonar.xoo.scm.XooScmProvider;
+import org.sonar.xoo.test.CoveragePerTestSensor;
+import org.sonar.xoo.test.TestExecutionSensor;
import java.util.Arrays;
import java.util.List;
@@ -78,6 +80,10 @@ public class XooPlugin extends SonarPlugin {
ItCoverageSensor.class,
OverallCoverageSensor.class,
+ // Tests
+ TestExecutionSensor.class,
+ CoveragePerTestSensor.class,
+
// Other
XooProjectBuilder.class,
XooPostJob.class);
diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/test/CoveragePerTestSensor.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/test/CoveragePerTestSensor.java
new file mode 100644
index 00000000000..369b9d3fd6a
--- /dev/null
+++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/test/CoveragePerTestSensor.java
@@ -0,0 +1,122 @@
+/*
+ * 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.xoo.test;
+
+import com.google.common.base.Splitter;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang.StringUtils;
+import org.sonar.api.batch.DependsUpon;
+import org.sonar.api.batch.fs.FilePredicates;
+import org.sonar.api.batch.fs.FileSystem;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.InputFile.Type;
+import org.sonar.api.batch.sensor.Sensor;
+import org.sonar.api.batch.sensor.SensorContext;
+import org.sonar.api.batch.sensor.SensorDescriptor;
+import org.sonar.api.component.ResourcePerspectives;
+import org.sonar.api.test.MutableTestCase;
+import org.sonar.api.test.MutableTestPlan;
+import org.sonar.api.test.MutableTestable;
+import org.sonar.api.utils.log.Logger;
+import org.sonar.api.utils.log.Loggers;
+import org.sonar.xoo.Xoo;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Parse files *.xoo.testcoverage
+ */
+@DependsUpon("test-exec")
+public class CoveragePerTestSensor implements Sensor {
+ private static final Logger LOG = Loggers.get(CoveragePerTestSensor.class);
+
+ private static final String TEST_EXTENSION = ".testcoverage";
+
+ private final FileSystem fs;
+ private final ResourcePerspectives perspectives;
+
+ public CoveragePerTestSensor(FileSystem fileSystem, ResourcePerspectives perspectives) {
+ this.fs = fileSystem;
+ this.perspectives = perspectives;
+ }
+
+ private void processTestFile(InputFile inputFile, SensorContext context) {
+ File testExecutionFile = new File(inputFile.file().getParentFile(), inputFile.file().getName() + TEST_EXTENSION);
+ if (testExecutionFile.exists()) {
+ LOG.debug("Processing " + testExecutionFile.getAbsolutePath());
+ try {
+ List<String> lines = FileUtils.readLines(testExecutionFile, fs.encoding().name());
+ int lineNumber = 0;
+ MutableTestPlan testPlan = perspectives.as(MutableTestPlan.class, inputFile);
+ for (String line : lines) {
+ lineNumber++;
+ if (StringUtils.isBlank(line)) {
+ continue;
+ }
+ if (line.startsWith("#")) {
+ continue;
+ }
+ try {
+ Iterator<String> split = Splitter.on(";").split(line).iterator();
+ String name = split.next();
+ while (split.hasNext()) {
+ String coveredBlockStr = split.next();
+ Iterator<String> splitCoveredBlock = Splitter.on(",").split(coveredBlockStr).iterator();
+ String componentPath = splitCoveredBlock.next();
+ InputFile coveredFile = context.fileSystem().inputFile(context.fileSystem().predicates().hasPath(componentPath));
+ MutableTestable testable = perspectives.as(MutableTestable.class, coveredFile);
+ List<Integer> coveredLines = new ArrayList<>();
+ while (splitCoveredBlock.hasNext()) {
+ coveredLines.add(Integer.parseInt(splitCoveredBlock.next()));
+ }
+ for (MutableTestCase testCase : testPlan.testCasesByName(name)) {
+ testCase.setCoverageBlock(testable, coveredLines);
+ }
+ }
+ } catch (Exception e) {
+ throw new IllegalStateException("Error processing line " + lineNumber + " of file " + testExecutionFile.getAbsolutePath(), e);
+ }
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ @Override
+ public void describe(SensorDescriptor descriptor) {
+ descriptor
+ .name("Xoo Coverage Per Test Sensor")
+ .onlyOnLanguages(Xoo.KEY);
+ }
+
+ @Override
+ public void execute(SensorContext context) {
+ FilePredicates p = context.fileSystem().predicates();
+ for (InputFile file : context.fileSystem().inputFiles(p.and(p.hasLanguages(Xoo.KEY), p.hasType(Type.TEST)))) {
+ processTestFile(file, context);
+ }
+ }
+
+}
diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/test/TestExecutionSensor.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/test/TestExecutionSensor.java
new file mode 100644
index 00000000000..c3446daac3a
--- /dev/null
+++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/test/TestExecutionSensor.java
@@ -0,0 +1,119 @@
+/*
+ * 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.xoo.test;
+
+import com.google.common.base.Splitter;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang.StringUtils;
+import org.sonar.api.batch.DependedUpon;
+import org.sonar.api.batch.fs.FilePredicates;
+import org.sonar.api.batch.fs.FileSystem;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.InputFile.Type;
+import org.sonar.api.batch.sensor.Sensor;
+import org.sonar.api.batch.sensor.SensorContext;
+import org.sonar.api.batch.sensor.SensorDescriptor;
+import org.sonar.api.component.ResourcePerspectives;
+import org.sonar.api.test.MutableTestCase;
+import org.sonar.api.test.MutableTestPlan;
+import org.sonar.api.test.TestCase.Status;
+import org.sonar.api.utils.log.Logger;
+import org.sonar.api.utils.log.Loggers;
+import org.sonar.xoo.Xoo;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Parse files *.xoo.test
+ */
+@DependedUpon("test-exec")
+public class TestExecutionSensor implements Sensor {
+ private static final Logger LOG = Loggers.get(TestExecutionSensor.class);
+
+ private static final String TEST_EXTENSION = ".test";
+
+ private final FileSystem fs;
+ private final ResourcePerspectives perspectives;
+
+ public TestExecutionSensor(FileSystem fileSystem, ResourcePerspectives perspectives) {
+ this.fs = fileSystem;
+ this.perspectives = perspectives;
+ }
+
+ private void processTestFile(InputFile inputFile, SensorContext context) {
+ File testExecutionFile = new File(inputFile.file().getParentFile(), inputFile.file().getName() + TEST_EXTENSION);
+ if (testExecutionFile.exists()) {
+ LOG.debug("Processing " + testExecutionFile.getAbsolutePath());
+ try {
+ List<String> lines = FileUtils.readLines(testExecutionFile, fs.encoding().name());
+ int lineNumber = 0;
+ MutableTestPlan testPlan = perspectives.as(MutableTestPlan.class, inputFile);
+ for (String line : lines) {
+ lineNumber++;
+ if (StringUtils.isBlank(line)) {
+ continue;
+ }
+ if (line.startsWith("#")) {
+ continue;
+ }
+ try {
+ Iterator<String> split = Splitter.on(":").split(line).iterator();
+ String name = split.next();
+ String durationStr = split.next();
+ Long duration = StringUtils.isNotBlank(durationStr) ? Long.parseLong(durationStr) : null;
+ String msg = split.next();
+ String stack = split.next();
+ String status = split.next();
+ String type = split.next();
+ MutableTestCase testCase = testPlan.addTestCase(name);
+ testCase.setDurationInMs(duration);
+ testCase.setMessage(msg);
+ testCase.setStackTrace(stack);
+ testCase.setStatus(Status.valueOf(status));
+ testCase.setType(type);
+ } catch (Exception e) {
+ throw new IllegalStateException("Error processing line " + lineNumber + " of file " + testExecutionFile.getAbsolutePath(), e);
+ }
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ @Override
+ public void describe(SensorDescriptor descriptor) {
+ descriptor
+ .name("Xoo Test Execution Sensor")
+ .onlyOnLanguages(Xoo.KEY);
+ }
+
+ @Override
+ public void execute(SensorContext context) {
+ FilePredicates p = context.fileSystem().predicates();
+ for (InputFile file : context.fileSystem().inputFiles(p.and(p.hasLanguages(Xoo.KEY), p.hasType(Type.TEST)))) {
+ processTestFile(file, context);
+ }
+ }
+
+}