diff options
10 files changed, 245 insertions, 81 deletions
diff --git a/plugins/sonar-design-plugin/src/main/java/org/sonar/plugins/design/batch/MavenDependenciesSensor.java b/plugins/sonar-design-plugin/src/main/java/org/sonar/plugins/design/batch/MavenDependenciesSensor.java index 9afa425a0e4..49324d7340c 100644 --- a/plugins/sonar-design-plugin/src/main/java/org/sonar/plugins/design/batch/MavenDependenciesSensor.java +++ b/plugins/sonar-design-plugin/src/main/java/org/sonar/plugins/design/batch/MavenDependenciesSensor.java @@ -26,7 +26,6 @@ import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializer; import com.google.gson.JsonElement; import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; import com.google.gson.reflect.TypeToken; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.factory.ArtifactFactory; @@ -139,7 +138,7 @@ public class MavenDependenciesSensor implements Sensor { private static class DependencyDeserializer implements JsonDeserializer<InputDependency> { @Override - public InputDependency deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { + public InputDependency deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) { JsonObject dep = json.getAsJsonObject(); String key = dep.get("k").getAsString(); @@ -175,40 +174,43 @@ public class MavenDependenciesSensor implements Sensor { } catch (Exception e) { throw new IllegalStateException("Unable to deserialize dependency information: " + depsAsJson, e); } + } else if (treeBuilder != null) { + computeDependencyTree(project, context); } - else if (treeBuilder != null) { - LOG.warn("Computation of Maven dependencies by SonarQube is deprecated. Please update the version of SonarQube Maven plugin to 2.5+"); - try { - DependencyNode root = treeBuilder.buildDependencyTree(project.getPom(), localRepository, artifactFactory, artifactMetadataSource, null, artifactCollector); + } - DependencyNodeVisitor visitor = new BuildingDependencyNodeVisitor(new DependencyNodeVisitor() { - public boolean visit(DependencyNode node) { - return true; - } + private void computeDependencyTree(final Project project, final SensorContext context) { + LOG.warn("Computation of Maven dependencies by SonarQube is deprecated. Please update the version of SonarQube Maven plugin to 2.5+"); + try { + DependencyNode root = treeBuilder.buildDependencyTree(project.getPom(), localRepository, artifactFactory, artifactMetadataSource, null, artifactCollector); - public boolean endVisit(DependencyNode node) { - if (node.getParent() != null && node.getParent() != node) { - saveDependency(node, context); - } - return true; + DependencyNodeVisitor visitor = new BuildingDependencyNodeVisitor(new DependencyNodeVisitor() { + public boolean visit(DependencyNode node) { + return true; + } + + public boolean endVisit(DependencyNode node) { + if (node.getParent() != null && node.getParent() != node) { + saveDependency(node, context); } - }); + return true; + } + }); - // mode verbose OFF : do not show the same lib many times - DependencyNodeFilter filter = StateDependencyNodeFilter.INCLUDED; + // mode verbose OFF : do not show the same lib many times + DependencyNodeFilter filter = StateDependencyNodeFilter.INCLUDED; - CollectingDependencyNodeVisitor collectingVisitor = new CollectingDependencyNodeVisitor(); - DependencyNodeVisitor firstPassVisitor = new FilteringDependencyNodeVisitor(collectingVisitor, filter); - root.accept(firstPassVisitor); + CollectingDependencyNodeVisitor collectingVisitor = new CollectingDependencyNodeVisitor(); + DependencyNodeVisitor firstPassVisitor = new FilteringDependencyNodeVisitor(collectingVisitor, filter); + root.accept(firstPassVisitor); - DependencyNodeFilter secondPassFilter = new AncestorOrSelfDependencyNodeFilter(collectingVisitor.getNodes()); - visitor = new FilteringDependencyNodeVisitor(visitor, secondPassFilter); + DependencyNodeFilter secondPassFilter = new AncestorOrSelfDependencyNodeFilter(collectingVisitor.getNodes()); + visitor = new FilteringDependencyNodeVisitor(visitor, secondPassFilter); - root.accept(visitor); + root.accept(visitor); - } catch (DependencyTreeBuilderException e) { - throw new SonarException("Can not load the graph of dependencies of the project " + project.getKey(), e); - } + } catch (DependencyTreeBuilderException e) { + throw new SonarException("Can not load the graph of dependencies of the project " + project.getKey(), e); } } diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/CoveragePerTestSensor.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/CoveragePerTestSensor.java index aee8297811e..cf0ff9389bf 100644 --- a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/CoveragePerTestSensor.java +++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/CoveragePerTestSensor.java @@ -50,18 +50,18 @@ public class CoveragePerTestSensor implements Sensor { private void processCoveragePerTest(InputFile inputFile, SensorContext context) { File ioFile = inputFile.file(); - File testPlanFile = new File(ioFile.getParentFile(), ioFile.getName() + COVER_PER_TEST_EXTENSION); - if (testPlanFile.exists()) { - LOG.debug("Processing " + testPlanFile.getAbsolutePath()); + File coverPerTestFile = new File(ioFile.getParentFile(), ioFile.getName() + COVER_PER_TEST_EXTENSION); + if (coverPerTestFile.exists()) { + LOG.debug("Processing " + coverPerTestFile.getAbsolutePath()); try { - List<String> lines = FileUtils.readLines(testPlanFile, context.fileSystem().encoding().name()); + List<String> lines = FileUtils.readLines(coverPerTestFile, context.fileSystem().encoding().name()); int lineNumber = 0; for (String line : lines) { lineNumber++; if (StringUtils.isBlank(line) || line.startsWith("#")) { continue; } - processLine(testPlanFile, lineNumber, context, line, inputFile); + processLine(coverPerTestFile, lineNumber, context, line, inputFile); } } catch (IOException e) { throw new IllegalStateException(e); @@ -69,7 +69,7 @@ public class CoveragePerTestSensor implements Sensor { } } - private void processLine(File testplanFile, int lineNumber, SensorContext context, String line, InputFile testFile) { + private void processLine(File coverPerTest, int lineNumber, SensorContext context, String line, InputFile testFile) { try { Iterator<String> split = Splitter.on(":").split(line).iterator(); String testCaseName = split.next(); @@ -87,7 +87,7 @@ public class CoveragePerTestSensor implements Sensor { } context.saveCoveragePerTest(testCase, mainFile, coveredLines); } catch (Exception e) { - throw new IllegalStateException("Error processing line " + lineNumber + " of file " + testplanFile.getAbsolutePath(), e); + throw new IllegalStateException("Error processing line " + lineNumber + " of file " + coverPerTest.getAbsolutePath(), e); } } diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/TestCaseSensor.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/TestCaseSensor.java index c4238b51e18..96c7de1b045 100644 --- a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/TestCaseSensor.java +++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/TestCaseSensor.java @@ -80,8 +80,8 @@ public class TestCaseSensor implements Sensor { context.addTestCase(context.testCaseBuilder(testFile, name) .type(TestCase.Type.valueOf(type)) .status(TestCase.Status.valueOf(status)) - .message(message) - .stackTrace(stack) + .message(StringUtils.trimToNull(message)) + .stackTrace(StringUtils.trimToNull(stack)) .durationInMs(duration) .build()); } catch (Exception e) { diff --git a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/CoveragePerTestSensorTest.java b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/CoveragePerTestSensorTest.java new file mode 100644 index 00000000000..583911e4d76 --- /dev/null +++ b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/CoveragePerTestSensorTest.java @@ -0,0 +1,75 @@ +package org.sonar.xoo.lang; + +import org.apache.commons.io.FileUtils; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.sonar.api.batch.fs.InputFile.Type; +import org.sonar.api.batch.fs.internal.DefaultFileSystem; +import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.sensor.SensorContext; +import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor; +import org.sonar.api.batch.sensor.test.TestCase; +import org.sonar.api.batch.sensor.test.internal.DefaultTestCaseBuilder; + +import java.io.File; +import java.io.IOException; +import java.util.Arrays; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class CoveragePerTestSensorTest { + + private CoveragePerTestSensor sensor; + private SensorContext context = mock(SensorContext.class); + private DefaultFileSystem fileSystem; + + @Rule + public TemporaryFolder temp = new TemporaryFolder(); + private File baseDir; + + @Before + public void prepare() throws IOException { + baseDir = temp.newFolder(); + sensor = new CoveragePerTestSensor(); + fileSystem = new DefaultFileSystem(); + when(context.fileSystem()).thenReturn(fileSystem); + } + + @Test + public void testDescriptor() { + sensor.describe(new DefaultSensorDescriptor()); + } + + @Test + public void testNoExecutionIfCoveragePerTestFile() { + DefaultInputFile testFile = new DefaultInputFile("foo", "test/fooTest.xoo").setAbsolutePath(new File(baseDir, "test/fooTest.xoo").getAbsolutePath()).setLanguage("xoo") + .setType(Type.TEST); + fileSystem.add(testFile); + sensor.execute(context); + } + + @Test + public void testExecution() throws IOException { + File coverPerTest = new File(baseDir, "test/fooTest.xoo.coveragePerTest"); + FileUtils.write(coverPerTest, "test1:src/foo.xoo:1,2,3,4\ntest2:src/foo.xoo:5,6,7\n\n#comment"); + DefaultInputFile inputFile = new DefaultInputFile("foo", "src/foo.xoo").setAbsolutePath(new File(baseDir, "src/foo.xoo").getAbsolutePath()).setLanguage("xoo"); + DefaultInputFile testFile = new DefaultInputFile("foo", "test/fooTest.xoo").setAbsolutePath(new File(baseDir, "test/fooTest.xoo").getAbsolutePath()).setLanguage("xoo") + .setType(Type.TEST); + fileSystem.add(inputFile); + fileSystem.add(testFile); + + TestCase test1 = new DefaultTestCaseBuilder(testFile, "test1").durationInMs(10).build(); + TestCase test2 = new DefaultTestCaseBuilder(testFile, "test2").durationInMs(10).build(); + when(context.getTestCase(testFile, "test1")).thenReturn(test1); + when(context.getTestCase(testFile, "test2")).thenReturn(test2); + + sensor.execute(context); + + verify(context).saveCoveragePerTest(test1, inputFile, Arrays.asList(1, 2, 3, 4)); + verify(context).saveCoveragePerTest(test2, inputFile, Arrays.asList(5, 6, 7)); + } +} diff --git a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/TestCaseSensorTest.java b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/TestCaseSensorTest.java new file mode 100644 index 00000000000..35967a58349 --- /dev/null +++ b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/TestCaseSensorTest.java @@ -0,0 +1,72 @@ +package org.sonar.xoo.lang; + +import org.apache.commons.io.FileUtils; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.sonar.api.batch.fs.InputFile.Type; +import org.sonar.api.batch.fs.internal.DefaultFileSystem; +import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.sensor.SensorContext; +import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor; +import org.sonar.api.batch.sensor.test.TestCase; +import org.sonar.api.batch.sensor.test.internal.DefaultTestCaseBuilder; + +import java.io.File; +import java.io.IOException; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class TestCaseSensorTest { + + private TestCaseSensor sensor; + private SensorContext context = mock(SensorContext.class); + private DefaultFileSystem fileSystem; + + @Rule + public TemporaryFolder temp = new TemporaryFolder(); + private File baseDir; + + @Before + public void prepare() throws IOException { + baseDir = temp.newFolder(); + sensor = new TestCaseSensor(); + fileSystem = new DefaultFileSystem(); + when(context.fileSystem()).thenReturn(fileSystem); + } + + @Test + public void testDescriptor() { + sensor.describe(new DefaultSensorDescriptor()); + } + + @Test + public void testNoExecutionIfNoTestFile() { + DefaultInputFile testFile = new DefaultInputFile("foo", "test/fooTest.xoo").setAbsolutePath(new File(baseDir, "test/fooTest.xoo").getAbsolutePath()).setLanguage("xoo") + .setType(Type.TEST); + fileSystem.add(testFile); + sensor.execute(context); + } + + @Test + public void testExecution() throws IOException { + File testPlan = new File(baseDir, "test/fooTest.xoo.testplan"); + FileUtils.write(testPlan, "test1:UNIT:OK:::10\ntest2:INTEGRATION:ERROR:message:stack:15\n\n#comment"); + DefaultInputFile testFile = new DefaultInputFile("foo", "test/fooTest.xoo").setAbsolutePath(new File(baseDir, "test/fooTest.xoo").getAbsolutePath()).setLanguage("xoo") + .setType(Type.TEST); + fileSystem.add(testFile); + + when(context.testCaseBuilder(testFile, "test1")).thenReturn(new DefaultTestCaseBuilder(testFile, "test1")); + when(context.testCaseBuilder(testFile, "test2")).thenReturn(new DefaultTestCaseBuilder(testFile, "test2")); + + sensor.execute(context); + + verify(context).addTestCase(new DefaultTestCaseBuilder(testFile, "test1").durationInMs(10).build()); + verify(context).addTestCase( + new DefaultTestCaseBuilder(testFile, "test2").type(TestCase.Type.INTEGRATION).status(TestCase.Status.ERROR).message("message").stackTrace("stack").durationInMs(15).build()); + } + +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/mediumtest/BatchMediumTester.java b/sonar-batch/src/main/java/org/sonar/batch/mediumtest/BatchMediumTester.java index 403ec002b23..16f058187a0 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/mediumtest/BatchMediumTester.java +++ b/sonar-batch/src/main/java/org/sonar/batch/mediumtest/BatchMediumTester.java @@ -244,33 +244,29 @@ public class BatchMediumTester { measures.add(measure); } - InputPathCache inputFileCache = container.getComponentByType(InputPathCache.class); - for (InputPath inputPath : inputFileCache.all()) { - if (inputPath instanceof InputFile) { - inputFiles.add((InputFile) inputPath); - } else { - inputDirs.add((InputDir) inputPath); - } - } + storeFs(container); + storeComponentData(container); + storeDuplication(container); + storeTestCases(container); + storeCoveragePerTest(container); + } - ComponentDataCache componentDataCache = container.getComponentByType(ComponentDataCache.class); - for (InputFile file : inputFiles) { - SyntaxHighlightingData highlighting = componentDataCache.getData(((DefaultInputFile) file).key(), SnapshotDataTypes.SYNTAX_HIGHLIGHTING); - if (highlighting != null) { - highlightingPerFile.put(file, highlighting); + private void storeCoveragePerTest(ProjectScanContainer container) { + CoveragePerTestCache coveragePerTestCache = container.getComponentByType(CoveragePerTestCache.class); + for (Entry<List<Integer>> entry : coveragePerTestCache.entries()) { + String testFileKey = entry.key()[0].toString(); + if (!coveragePerTest.containsKey(testFileKey)) { + coveragePerTest.put(testFileKey, new HashMap<String, Map<String, List<Integer>>>()); } - SymbolData symbolTable = componentDataCache.getData(((DefaultInputFile) file).key(), SnapshotDataTypes.SYMBOL_HIGHLIGHTING); - if (symbolTable != null) { - symbolTablePerFile.put(file, symbolTable); + String testName = entry.key()[1].toString(); + if (!coveragePerTest.get(testFileKey).containsKey(testName)) { + coveragePerTest.get(testFileKey).put(testName, new HashMap<String, List<Integer>>()); } + coveragePerTest.get(testFileKey).get(testName).put(entry.key()[2].toString(), entry.value()); } + } - DuplicationCache duplicationCache = container.getComponentByType(DuplicationCache.class); - for (Entry<List<DuplicationGroup>> entry : duplicationCache.entries()) { - String effectiveKey = entry.key()[0].toString(); - duplications.put(effectiveKey, entry.value()); - } - + private void storeTestCases(ProjectScanContainer container) { TestCaseCache testCaseCache = container.getComponentByType(TestCaseCache.class); for (Entry<TestCase> entry : testCaseCache.entries()) { String effectiveKey = entry.key()[0].toString(); @@ -279,18 +275,38 @@ public class BatchMediumTester { } testCasesPerFile.get(effectiveKey).put(entry.value().name(), entry.value()); } + } + + private void storeDuplication(ProjectScanContainer container) { + DuplicationCache duplicationCache = container.getComponentByType(DuplicationCache.class); + for (Entry<List<DuplicationGroup>> entry : duplicationCache.entries()) { + String effectiveKey = entry.key()[0].toString(); + duplications.put(effectiveKey, entry.value()); + } + } - CoveragePerTestCache coveragePerTestCache = container.getComponentByType(CoveragePerTestCache.class); - for (Entry<List<Integer>> entry : coveragePerTestCache.entries()) { - String testFileKey = entry.key()[0].toString(); - if (!coveragePerTest.containsKey(testFileKey)) { - coveragePerTest.put(testFileKey, new HashMap<String, Map<String, List<Integer>>>()); + private void storeComponentData(ProjectScanContainer container) { + ComponentDataCache componentDataCache = container.getComponentByType(ComponentDataCache.class); + for (InputFile file : inputFiles) { + SyntaxHighlightingData highlighting = componentDataCache.getData(((DefaultInputFile) file).key(), SnapshotDataTypes.SYNTAX_HIGHLIGHTING); + if (highlighting != null) { + highlightingPerFile.put(file, highlighting); } - String testName = entry.key()[1].toString(); - if (!coveragePerTest.get(testFileKey).containsKey(testName)) { - coveragePerTest.get(testFileKey).put(testName, new HashMap<String, List<Integer>>()); + SymbolData symbolTable = componentDataCache.getData(((DefaultInputFile) file).key(), SnapshotDataTypes.SYMBOL_HIGHLIGHTING); + if (symbolTable != null) { + symbolTablePerFile.put(file, symbolTable); + } + } + } + + private void storeFs(ProjectScanContainer container) { + InputPathCache inputFileCache = container.getComponentByType(InputPathCache.class); + for (InputPath inputPath : inputFileCache.all()) { + if (inputPath instanceof InputFile) { + inputFiles.add((InputFile) inputPath); + } else { + inputDirs.add((InputDir) inputPath); } - coveragePerTest.get(testFileKey).get(testName).put(entry.key()[2].toString(), entry.value()); } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/test/package-info.java b/sonar-batch/src/main/java/org/sonar/batch/test/package-info.java index 227ae02188b..d85ce0026bf 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/test/package-info.java +++ b/sonar-batch/src/main/java/org/sonar/batch/test/package-info.java @@ -17,11 +17,8 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -/** - * - */ -/** - * @author julien - * - */ -package org.sonar.batch.test;
\ No newline at end of file +@ParametersAreNonnullByDefault +package org.sonar.batch.test; + +import javax.annotation.ParametersAreNonnullByDefault; + diff --git a/sonar-maven-plugin/src/main/java/org/sonar/maven/SonarMojo.java b/sonar-maven-plugin/src/main/java/org/sonar/maven/SonarMojo.java index f17d1bf1b28..301ce90d35d 100644 --- a/sonar-maven-plugin/src/main/java/org/sonar/maven/SonarMojo.java +++ b/sonar-maven-plugin/src/main/java/org/sonar/maven/SonarMojo.java @@ -47,10 +47,11 @@ import org.sonar.runner.api.ScanProperties; import java.io.File; import java.io.IOException; +import java.util.ArrayDeque; import java.util.ArrayList; +import java.util.Deque; import java.util.Iterator; import java.util.List; -import java.util.Stack; /** * @goal sonar @@ -232,15 +233,14 @@ public final class SonarMojo extends AbstractMojo { DependencyNodeVisitor visitor = new BuildingDependencyNodeVisitor(new DependencyNodeVisitor() { - private Stack<Dependency> stack = new Stack<SonarMojo.Dependency>(); + private Deque<Dependency> stack = new ArrayDeque<SonarMojo.Dependency>(); public boolean visit(DependencyNode node) { if (node.getParent() != null && node.getParent() != node) { Dependency dependency = toDependency(node); if (stack.isEmpty()) { result.add(dependency); - } - else { + } else { stack.peek().dependencies().add(dependency); } stack.push(dependency); diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/test/internal/DefaultTestCase.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/test/internal/DefaultTestCase.java index a6616abcb8f..5248a9d05a1 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/test/internal/DefaultTestCase.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/test/internal/DefaultTestCase.java @@ -27,6 +27,7 @@ import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.sensor.test.TestCase; import javax.annotation.CheckForNull; +import javax.annotation.Nullable; public class DefaultTestCase implements TestCase { @@ -38,7 +39,7 @@ public class DefaultTestCase implements TestCase { private final Type type; private final String stackTrace; - public DefaultTestCase(InputFile testFile, String name, Long duration, Status status, String message, Type type, String stackTrace) { + public DefaultTestCase(InputFile testFile, String name, @Nullable Long duration, Status status, @Nullable String message, Type type, @Nullable String stackTrace) { this.testFile = testFile; this.name = name; this.duration = duration; diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/test/internal/package-info.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/test/internal/package-info.java index 02a89291200..6074f3891d6 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/test/internal/package-info.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/test/internal/package-info.java @@ -18,4 +18,5 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ @javax.annotation.ParametersAreNonnullByDefault -package org.sonar.api.batch.sensor.test.internal;
\ No newline at end of file +package org.sonar.api.batch.sensor.test.internal; + |