]> source.dussan.org Git - sonarqube.git/commitdiff
Fix some quality flaws
authorJulien HENRY <julien.henry@sonarsource.com>
Thu, 11 Sep 2014 11:30:27 +0000 (13:30 +0200)
committerJulien HENRY <julien.henry@sonarsource.com>
Thu, 11 Sep 2014 11:30:55 +0000 (13:30 +0200)
plugins/sonar-design-plugin/src/main/java/org/sonar/plugins/design/batch/MavenDependenciesSensor.java
plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/CoveragePerTestSensor.java
plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/TestCaseSensor.java
plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/CoveragePerTestSensorTest.java [new file with mode: 0644]
plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/TestCaseSensorTest.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/mediumtest/BatchMediumTester.java
sonar-batch/src/main/java/org/sonar/batch/test/package-info.java
sonar-maven-plugin/src/main/java/org/sonar/maven/SonarMojo.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/test/internal/DefaultTestCase.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/test/internal/package-info.java

index 9afa425a0e44a4eb808835e2b11f55d894dc95d9..49324d7340c13b6a739a7bdfac73b589b8fa0057 100644 (file)
@@ -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);
     }
   }
 
index aee8297811ee881b3f61110b0c752eb68aabb275..cf0ff9389bf08badaafa17c81d614a91e40fa12f 100644 (file)
@@ -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);
     }
   }
 
index c4238b51e187c1d870fd0b205b2e67d6160011e2..96c7de1b045c8a2acd0826322dd366a39452e714 100644 (file)
@@ -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 (file)
index 0000000..583911e
--- /dev/null
@@ -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 (file)
index 0000000..35967a5
--- /dev/null
@@ -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());
+  }
+
+}
index 403ec002b23539863359b81c28318b5ae6df5a69..16f058187a076f2584780652bd81e21b6c714afa 100644 (file)
@@ -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());
       }
     }
 
index 227ae02188b040bc489f676b5c4397e5687b193c..d85ce0026bfc1de8dd2181df0be6f9812dc4838e 100644 (file)
  * 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;
+
index f17d1bf1b2818ceb55feb5b7575293e6958a0741..301ce90d35d2a07b9555bea1b88f14f64566722b 100644 (file)
@@ -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);
index a6616abcb8fbbdbda0934005268959ff99ab5cad..5248a9d05a133072a112c23ba37e9605b504957a 100644 (file)
@@ -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;
index 02a8929120059b1027a410732622e97bf32958d1..6074f3891d6cb89d16b526407806ec6e5fac5cf8 100644 (file)
@@ -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;
+