]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-13915 - Handle No Project Branches for NCLOC Language Distribution
authorBelen Pruvost <belen.pruvost@sonarsource.com>
Thu, 14 Jul 2022 09:10:43 +0000 (11:10 +0200)
committersonartech <sonartech@sonarsource.com>
Thu, 14 Jul 2022 20:03:47 +0000 (20:03 +0000)
server/sonar-db-dao/src/main/java/org/sonar/db/measure/ProjectMeasuresIndexerIterator.java
server/sonar-db-dao/src/test/java/org/sonar/db/measure/ProjectMeasuresIndexerIteratorTest.java
server/sonar-db-dao/src/testFixtures/java/org/sonar/db/component/ComponentDbTester.java

index 37126bf775b8b0d835b317253496c37b90062a39..12bf30347409e581b1009c8111d6b2f08effbef0 100644 (file)
@@ -202,13 +202,16 @@ public class ProjectMeasuresIndexerIterator extends CloseableIterator<ProjectMea
       }
 
       List<String> projectBranches = selectProjectBranches(dbSession, projectUuid);
-      long biggestNcloc = selectProjectBiggestNcloc(dbSession, projectBranches);
-      String biggestBranch = selectProjectBiggestBranch(dbSession, projectBranches, biggestNcloc);
-      PreparedStatement prepareNclocByLanguageStatement = prepareNclocByLanguageStatement(dbSession, biggestBranch);
-      rs = prepareNclocByLanguageStatement.executeQuery();
 
-      if (rs.next()) {
-        readMeasure(rs, measures);
+      if (!projectBranches.isEmpty()) {
+        long biggestNcloc = selectProjectBiggestNcloc(dbSession, projectBranches);
+        String biggestBranch = selectProjectBiggestBranch(dbSession, projectBranches, biggestNcloc);
+        PreparedStatement prepareNclocByLanguageStatement = prepareNclocByLanguageStatement(dbSession, biggestBranch);
+        rs = prepareNclocByLanguageStatement.executeQuery();
+
+        if (rs.next()) {
+          readMeasure(rs, measures);
+        }
       }
 
       return measures;
@@ -242,10 +245,10 @@ public class ProjectMeasuresIndexerIterator extends CloseableIterator<ProjectMea
     }
   }
 
-  private static List<String> selectProjectBranches(DbSession session, @Nullable String projectUuid) {
+  private static List<String> selectProjectBranches(DbSession session, String projectUuid) {
     ResultSet rs = null;
     List<String> projectBranches = new ArrayList<>();
-    try (PreparedStatement stmt = session.getConnection().prepareStatement(SQL_PROJECT_BRANCHES)){
+    try (PreparedStatement stmt = session.getConnection().prepareStatement(SQL_PROJECT_BRANCHES)) {
       AtomicInteger index = new AtomicInteger(1);
       stmt.setString(index.getAndIncrement(), projectUuid);
 
@@ -327,7 +330,6 @@ public class ProjectMeasuresIndexerIterator extends CloseableIterator<ProjectMea
     }
     if (NCLOC_LANGUAGE_DISTRIBUTION_KEY.equals(metricKey)) {
       readTextValue(rs, measures::setNclocByLanguages);
-      return;
     }
   }
 
index 15d9976d6c23b6846235d1549447b62a471b3f54..84d9e502cd68f4957ed6bfde83ecb69321fe1251 100644 (file)
@@ -21,6 +21,7 @@ package org.sonar.db.measure;
 
 import com.google.common.collect.Maps;
 import java.util.Map;
+import java.util.function.Consumer;
 import javax.annotation.Nullable;
 import org.junit.Rule;
 import org.junit.Test;
@@ -29,10 +30,13 @@ import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.db.DbTester;
 import org.sonar.db.component.ComponentDto;
+import org.sonar.db.component.ComponentTesting;
 import org.sonar.db.component.SnapshotDto;
 import org.sonar.db.measure.ProjectMeasuresIndexerIterator.ProjectMeasures;
 import org.sonar.db.metric.MetricDto;
+import org.sonar.db.project.ProjectDto;
 
+import static com.google.common.base.Preconditions.checkState;
 import static com.google.common.collect.Lists.newArrayList;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.entry;
@@ -43,6 +47,8 @@ import static org.sonar.api.measures.Metric.ValueType.DISTRIB;
 import static org.sonar.api.measures.Metric.ValueType.INT;
 import static org.sonar.api.measures.Metric.ValueType.LEVEL;
 import static org.sonar.api.measures.Metric.ValueType.STRING;
+import static org.sonar.db.component.ComponentDbTester.defaults;
+import static org.sonar.db.component.ComponentDbTester.toProjectDto;
 import static org.sonar.db.component.SnapshotTesting.newAnalysis;
 
 public class ProjectMeasuresIndexerIteratorTest {
@@ -159,6 +165,17 @@ public class ProjectMeasuresIndexerIteratorTest {
       .containsOnly(entry("<null>", 4), entry("java", 12), entry("xoo", 36));
   }
 
+  @Test
+  public void return_language_distribution_measure_from_project_with_no_branches() {
+    ComponentDto project = insertComponentAndProject(ComponentTesting.newPublicProjectDto(), false,
+      defaults(), defaults());
+
+    Map<String, ProjectMeasures> docsById = createResultSetAndReturnDocsById();
+
+    assertThat(docsById.get(project.uuid()).getMeasures().getNclocByLanguages())
+      .isEmpty();
+  }
+
   @Test
   public void does_not_return_none_numeric_metrics() {
     ComponentDto project = dbTester.components().insertPrivateProject();
@@ -292,4 +309,18 @@ public class ProjectMeasuresIndexerIteratorTest {
     it.close();
     return docsById;
   }
+
+  private ComponentDto insertComponentAndProject(ComponentDto component, @Nullable Boolean isPrivate,
+    Consumer<ComponentDto> componentDtoPopulator, Consumer<ProjectDto> projectDtoPopulator) {
+    componentDtoPopulator.accept(component);
+    checkState(isPrivate == null || component.isPrivate() == isPrivate, "Illegal modification of private flag");
+    dbClient.componentDao().insert(dbSession, component);
+
+    ProjectDto projectDto = toProjectDto(component, System2.INSTANCE.now());
+    projectDtoPopulator.accept(projectDto);
+    dbClient.projectDao().insert(dbSession, projectDto);
+
+    dbTester.commit();
+    return component;
+  }
 }
index b82859f34199ffab29b632f16448dd0c21545813..db56cf6c597a09891746bba7e8f176ef02cdb651 100644 (file)
@@ -370,7 +370,7 @@ public class ComponentDbTester {
   }
 
   private ComponentDto insertComponentAndBranchAndProject(ComponentDto component, @Nullable Boolean isPrivate, Consumer<BranchDto> branchPopulator,
-                                                          Consumer<ComponentDto> componentDtoPopulator, Consumer<ProjectDto> projectDtoPopulator) {
+    Consumer<ComponentDto> componentDtoPopulator, Consumer<ProjectDto> projectDtoPopulator) {
     insertComponentImpl(component, isPrivate, componentDtoPopulator);
 
     ProjectDto projectDto = toProjectDto(component, System2.INSTANCE.now());