]> source.dussan.org Git - sonarqube.git/commitdiff
Ignore source file information that is set on an unknown line
authorSimon Brandhof <simon.brandhof@sonarsource.com>
Thu, 12 Feb 2015 14:36:13 +0000 (15:36 +0100)
committerSimon Brandhof <simon.brandhof@sonarsource.com>
Thu, 12 Feb 2015 14:36:13 +0000 (15:36 +0100)
sonar-batch/src/main/java/org/sonar/batch/index/SourceDataFactory.java
sonar-batch/src/test/java/org/sonar/batch/index/SourceDataFactoryTest.java

index 3475e9f60468f21af79f41db5158edf1755dac88..aa61c83c77ea9828d1f293366fd02f61742330bc 100644 (file)
@@ -50,7 +50,7 @@ import java.util.List;
 import java.util.Map;
 
 /**
- * Consolidate different caches for the export of report to server.
+ * Consolidate different caches for the export of file sources to server.
  * @see org.sonar.server.source.db.FileSourceDb
  */
 public class SourceDataFactory implements BatchComponent {
@@ -175,10 +175,13 @@ public class SourceDataFactory implements BatchComponent {
       for (Measure measure : measures) {
         Map<Integer, String> lineMeasures = KeyValueFormat.parseIntString((String) measure.value());
         for (Map.Entry<Integer, String> lineMeasure : lineMeasures.entrySet()) {
-          String value = lineMeasure.getValue();
-          if (StringUtils.isNotEmpty(value)) {
-            FileSourceDb.Line.Builder lineBuilder = to.getLinesBuilder(lineMeasure.getKey() - 1);
-            op.apply(value, lineBuilder);
+          int lineIdx = lineMeasure.getKey();
+          if (lineIdx <= to.getLinesCount()) {
+            String value = lineMeasure.getValue();
+            if (StringUtils.isNotEmpty(value)) {
+              FileSourceDb.Line.Builder lineBuilder = to.getLinesBuilder(lineIdx - 1);
+              op.apply(value, lineBuilder);
+            }
           }
         }
       }
@@ -290,8 +293,8 @@ public class SourceDataFactory implements BatchComponent {
   }
 
   private <G> void writeItem(G item, StringBuilder[] dataPerLine, int currentLineIdx, long startLineOffset, long endLineOffset, RangeItemWriter<G> writer) {
-    if (startLineOffset == endLineOffset) {
-      // Do not store empty items
+    if (startLineOffset == endLineOffset || currentLineIdx > dataPerLine.length) {
+      // empty items or bad line index
       return;
     }
     if (dataPerLine[currentLineIdx - 1] == null) {
@@ -363,8 +366,10 @@ public class SourceDataFactory implements BatchComponent {
   private void addBlock(int blockId, DuplicationGroup.Block block, FileSourceDb.Data.Builder to) {
     int currentLine = block.startLine();
     for (int i = 0; i < block.length(); i++) {
-      to.getLinesBuilder(currentLine-1).addDuplications(blockId);
-      currentLine++;
+      if (currentLine <= to.getLinesCount()) {
+        to.getLinesBuilder(currentLine - 1).addDuplications(blockId);
+        currentLine++;
+      }
     }
   }
 }
index 2c510d62aac243aa0b131ea2f478d5be570d0cb1..3ced19c739b23b4a14d48f515b10fdb560c87fd5 100644 (file)
@@ -113,6 +113,24 @@ public class SourceDataFactoryTest {
     assertThat(data.getLines(2).getUtLineHits()).isEqualTo(4);
   }
 
+  @Test
+  public void applyLineMeasure_ignore_bad_line_numbers() throws Exception {
+    Metric metric = CoreMetrics.COVERAGE_LINE_HITS_DATA;
+    when(measureCache.byMetric("component_key", metric.key())).thenReturn(
+      // line 30 does not exist
+      Arrays.asList(new Measure().setData("30=42").setMetric(metric)));
+
+    sut.applyLineMeasure("component_key", metric.key(), output, new SourceDataFactory.MeasureOperation() {
+      @Override
+      public void apply(String value, FileSourceDb.Line.Builder lineBuilder) {
+        lineBuilder.setUtLineHits(Integer.parseInt(value));
+      }
+    });
+
+    FileSourceDb.Data data = output.build();
+    assertThat(data.getLinesCount()).isEqualTo(3);
+  }
+
   @Test
   public void applyLineMeasures() throws Exception {
     setupLineMeasure(CoreMetrics.SCM_AUTHORS_BY_LINE, "1=him;2=her");
@@ -169,6 +187,22 @@ public class SourceDataFactoryTest {
     assertThat(data.getLines(2).getDuplicationsList()).containsExactly(2);
   }
 
+  @Test
+  public void applyDuplications_ignore_bad_lines() throws Exception {
+    // duplication on 10 lines
+    DuplicationGroup group1 = new DuplicationGroup(new DuplicationGroup.Block(inputFile.key(), 1, 10))
+      .addDuplicate(new DuplicationGroup.Block("anotherFile1", 12, 1))
+      .addDuplicate(new DuplicationGroup.Block("anotherFile2", 13, 1));
+    when(duplicationCache.byComponent(inputFile.key())).thenReturn(Lists.newArrayList(group1));
+
+    sut.applyDuplications(inputFile.key(), output);
+
+    FileSourceDb.Data data = output.build();
+    assertThat(data.getLines(0).getDuplicationsList()).containsExactly(1);
+    assertThat(data.getLines(1).getDuplicationsList()).containsExactly(1);
+    assertThat(data.getLines(2).getDuplicationsList()).containsExactly(1);
+  }
+
   @Test
   public void applyHighlighting_missing() throws Exception {
     when(componentDataCache.getData(inputFile.key(), SnapshotDataTypes.SYNTAX_HIGHLIGHTING)).thenReturn(null);
@@ -199,6 +233,22 @@ public class SourceDataFactoryTest {
     assertThat(data.getLines(2).getHighlighting()).isEqualTo("0,9,c");
   }
 
+  @Test
+  public void applyHighlighting_ignore_bad_line() throws Exception {
+    SyntaxHighlightingData highlighting = new SyntaxHighlightingDataBuilder()
+      .registerHighlightingRule(0, 4, TypeOfText.ANNOTATION)
+      .registerHighlightingRule(4, 5, TypeOfText.COMMENT)
+      .registerHighlightingRule(7, 25, TypeOfText.CONSTANT)
+      .build();
+    when(componentDataCache.getData(inputFile.key(), SnapshotDataTypes.SYNTAX_HIGHLIGHTING)).thenReturn(highlighting);
+    metadata.setOriginalLineOffsets(new int[] {0, 4, 7, 15});
+
+    sut.applyHighlighting(inputFile, metadata, output);
+
+    FileSourceDb.Data data = output.build();
+    assertThat(data.getLinesCount()).isEqualTo(3);
+  }
+
   @Test
   public void applyHighlighting_multiple_lines() throws Exception {
     SyntaxHighlightingData highlighting = new SyntaxHighlightingDataBuilder()