]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-19728 Update ws indexation_status to return project count instead of branch...
authorEric Giffon <eric.giffon@sonarsource.com>
Wed, 12 Jul 2023 09:13:14 +0000 (11:13 +0200)
committersonartech <sonartech@sonarsource.com>
Wed, 19 Jul 2023 20:03:05 +0000 (20:03 +0000)
15 files changed:
server/sonar-db-dao/src/it/java/org/sonar/db/component/BranchDaoIT.java
server/sonar-db-dao/src/it/java/org/sonar/db/project/ProjectDaoIT.java
server/sonar-db-dao/src/main/java/org/sonar/db/component/BranchDao.java
server/sonar-db-dao/src/main/java/org/sonar/db/component/BranchMapper.java
server/sonar-db-dao/src/main/java/org/sonar/db/project/ProjectDao.java
server/sonar-db-dao/src/main/java/org/sonar/db/project/ProjectMapper.java
server/sonar-db-dao/src/main/resources/org/sonar/db/component/BranchMapper.xml
server/sonar-db-dao/src/main/resources/org/sonar/db/project/ProjectMapper.xml
server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueIndexSyncProgressChecker.java
server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueSyncProgress.java
server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexSyncProgressCheckerTest.java
server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/IndexationStatusActionIT.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/IndexationStatusAction.java
server/sonar-webserver-webapi/src/main/resources/org/sonar/server/ce/ws/indexation_status-example.json
sonar-ws/src/main/protobuf/ws-ce.proto

index e2103039d44a2787d47bd8faf8dba22f3f4e3f4b..8caffc16280ae361d339ce07dfd67885f88b3af4 100644 (file)
@@ -690,42 +690,6 @@ public class BranchDaoIT {
     assertThat(underTest.countByTypeAndCreationDate(dbSession, BranchType.PULL_REQUEST, NOW + 100)).isZero();
   }
 
-  @Test
-  public void countByNeedIssueSync() {
-    assertThat(underTest.countByNeedIssueSync(dbSession, true)).isZero();
-    assertThat(underTest.countByNeedIssueSync(dbSession, false)).isZero();
-
-    // master branch with flag set to false
-    ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent();
-    // branches & PRs
-    db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.BRANCH).setNeedIssueSync(true));
-    db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.BRANCH).setNeedIssueSync(true));
-    db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.BRANCH).setNeedIssueSync(false));
-    db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.BRANCH).setNeedIssueSync(false));
-    db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.PULL_REQUEST).setNeedIssueSync(true));
-    db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.PULL_REQUEST).setNeedIssueSync(false));
-    db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.PULL_REQUEST).setNeedIssueSync(true));
-
-    assertThat(underTest.countByNeedIssueSync(dbSession, true)).isEqualTo(4);
-    assertThat(underTest.countByNeedIssueSync(dbSession, false)).isEqualTo(4);
-  }
-
-  @Test
-  public void countAll() {
-    assertThat(underTest.countAll(dbSession)).isZero();
-
-    ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent();
-    db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.BRANCH).setNeedIssueSync(true));
-    db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.BRANCH).setNeedIssueSync(true));
-    db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.BRANCH).setNeedIssueSync(false));
-    db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.BRANCH).setNeedIssueSync(false));
-    db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.PULL_REQUEST).setNeedIssueSync(true));
-    db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.PULL_REQUEST).setNeedIssueSync(false));
-    db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.PULL_REQUEST).setNeedIssueSync(true));
-
-    assertThat(underTest.countAll(dbSession)).isEqualTo(8);
-  }
-
   @Test
   public void selectBranchNeedingIssueSync() {
     ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent();
index 77c2c9180260448b83172cb4974524c44f8a7884..1b3a13df9e784a9cca53746d4a22e31fdeba2266 100644 (file)
@@ -43,6 +43,7 @@ import org.sonar.db.Pagination;
 import org.sonar.db.audit.AuditPersister;
 import org.sonar.db.audit.NoOpAuditPersister;
 import org.sonar.db.component.BranchDto;
+import org.sonar.db.component.BranchType;
 import org.sonar.db.component.ComponentDto;
 import org.sonar.db.component.ProjectData;
 import org.sonar.db.measure.LiveMeasureDto;
@@ -369,6 +370,33 @@ public class ProjectDaoIT {
     assertThat(projectDtos).extracting(ProjectDto::getName).containsOnly("Project_2", "Project_3");
   }
 
+  @Test
+  public void countIndexedProjects() {
+    assertThat(projectDao.countIndexedProjects(db.getSession())).isZero();
+
+    // master branch with flag set to false
+    ComponentDto project1 = db.components().insertPrivateProject().getMainBranchComponent();
+    ComponentDto project2 = db.components().insertPrivateProject().getMainBranchComponent();
+    // branches & PRs
+    db.components().insertProjectBranch(project1, b -> b.setBranchType(BranchType.BRANCH).setNeedIssueSync(true));
+    db.components().insertProjectBranch(project1, b -> b.setBranchType(BranchType.BRANCH).setNeedIssueSync(false));
+    db.components().insertProjectBranch(project2, b -> b.setBranchType(BranchType.BRANCH).setNeedIssueSync(false));
+    db.components().insertProjectBranch(project1, b -> b.setBranchType(BranchType.PULL_REQUEST).setNeedIssueSync(true));
+    db.components().insertProjectBranch(project1, b -> b.setBranchType(BranchType.PULL_REQUEST).setNeedIssueSync(false));
+    db.components().insertProjectBranch(project2, b -> b.setBranchType(BranchType.PULL_REQUEST).setNeedIssueSync(false));
+
+    assertThat(projectDao.countIndexedProjects(db.getSession())).isEqualTo(1);
+  }
+
+  @Test
+  public void countProjects() {
+    assertThat(projectDao.countProjects(db.getSession())).isZero();
+
+    IntStream.range(0, 10).forEach(x -> db.components().insertPrivateProject());
+
+    assertThat(projectDao.countProjects(db.getSession())).isEqualTo(10);
+  }
+
   private void insertDefaultQualityProfile(String language) {
     QProfileDto profile = db.qualityProfiles().insert(qp -> qp.setIsBuiltIn(true).setLanguage(language));
     db.qualityProfiles().setAsDefault(profile);
index 6430ec203c135bcbac281f6f0586f136e5a55642..c65d73d43f5db217073c09c5b6d74c583615e5d3 100644 (file)
@@ -160,14 +160,6 @@ public class BranchDao implements Dao {
     return mapper(dbSession).countByTypeAndCreationDate(branchType.name(), sinceDate);
   }
 
-  public int countByNeedIssueSync(DbSession session, boolean needIssueSync) {
-    return mapper(session).countByNeedIssueSync(needIssueSync);
-  }
-
-  public int countAll(DbSession session) {
-    return mapper(session).countAll();
-  }
-
   private static BranchMapper mapper(DbSession dbSession) {
     return dbSession.getMapper(BranchMapper.class);
   }
index 4e252fe19d4886f4db2df8fc2de1a46b65b89890..435bcfebb44ba55cdcddd079933048c2874161bc 100644 (file)
@@ -58,10 +58,6 @@ public interface BranchMapper {
 
   short hasAnyBranchWhereNeedIssueSync(@Param("needIssueSync") boolean needIssueSync);
 
-  int countByNeedIssueSync(@Param("needIssueSync") boolean needIssueSync);
-
-  int countAll();
-
   List<BranchDto> selectBranchNeedingIssueSync();
 
   List<BranchDto> selectBranchNeedingIssueSyncForProject(@Param("projectUuid") String projectUuid);
index 73f030a9d6bfd56eac10481bd00ba3497f00dc3d..e10f753f9c25d0f102eceac81920c7542147d19d 100644 (file)
@@ -152,4 +152,12 @@ public class ProjectDao implements Dao {
   public long getNclocSum(DbSession dbSession, @Nullable String projectUuidToExclude) {
     return Optional.ofNullable(mapper(dbSession).getNclocSum(projectUuidToExclude)).orElse(0L);
   }
+
+  public int countIndexedProjects(DbSession session) {
+    return mapper(session).countIndexedProjects();
+  }
+
+  public int countProjects(DbSession session) {
+    return mapper(session).countProjects();
+  }
 }
index e189566d7bde9f4e10808eaa59d8ea96970c0a9d..cc4c34a050e4307dd8a465e406a520bbf29a5e80 100644 (file)
@@ -74,4 +74,8 @@ public interface ProjectMapper {
 
   @CheckForNull
   Long getNclocSum(@Nullable @Param("projectUuidToExclude") String projectUuidToExclude);
+
+  int countIndexedProjects();
+
+  int countProjects();
 }
index 6e056b19b641ee0ecedf8590bf4cb18f47305741..8f05c259c8d8045709613f8986cc44833910ef1a 100644 (file)
     from dual
   </select>
 
-  <select id="countByNeedIssueSync" parameterType="map" resultType="int">
-    select
-    count(pb.uuid)
-    from project_branches pb
-    where
-    pb.need_issue_sync = #{needIssueSync, jdbcType=BOOLEAN}
-  </select>
-
-  <select id="countAll" parameterType="map" resultType="int">
-    select
-    count(pb.uuid)
-    from project_branches pb
-  </select>
-
   <select id="selectBranchNeedingIssueSync" resultType="org.sonar.db.component.BranchDto">
     select
     <include refid="columns"/>
index 362f33aa3c62d7ff9db8f5cff5ef41a2e02be88b..dd94c2f4f374b2bf4bc2320e6a207d29155940c1 100644 (file)
       and uuid &lt;&gt; #{projectUuidToExclude,jdbcType=VARCHAR}
     </if>
   </select>
+
+  <select id="countIndexedProjects" resultType="int">
+    select count(p.uuid)
+    from projects p
+    where p.qualifier = 'TRK'
+    and not exists (select 1 from project_branches pb where pb.project_uuid = p.uuid and pb.need_issue_sync = ${_true})
+  </select>
+
+  <select id="countProjects" resultType="int">
+    select count(p.uuid)
+    from projects p
+    where p.qualifier = 'TRK'
+  </select>
+
 </mapper>
index 931d5dbc74c5fd06a633247407560659d9428b11..f1340e65d9d6c70171f73839b8b3a830824f77a2 100644 (file)
@@ -41,11 +41,11 @@ public class IssueIndexSyncProgressChecker {
   }
 
   public IssueSyncProgress getIssueSyncProgress(DbSession dbSession) {
-    int completed = dbClient.branchDao().countByNeedIssueSync(dbSession, false);
+    int completedCount = dbClient.projectDao().countIndexedProjects(dbSession);
+    int total = dbClient.projectDao().countProjects(dbSession);
     boolean hasFailures = dbClient.ceActivityDao().hasAnyFailedOrCancelledIssueSyncTask(dbSession);
     boolean isCompleted = !dbClient.ceQueueDao().hasAnyIssueSyncTaskPendingOrInProgress(dbSession);
-    int total = dbClient.branchDao().countAll(dbSession);
-    return new IssueSyncProgress(isCompleted, completed, total, hasFailures);
+    return new IssueSyncProgress(isCompleted, completedCount, total, hasFailures);
   }
 
   public void checkIfAnyComponentsNeedIssueSync(DbSession dbSession, List<String> componentKeys) {
index 8b53c27bfc58cc08608344c4dee3d2434eed6fb9..28a5de6e272a1f2a99e9e6d9fbacafa8690eac2a 100644 (file)
 package org.sonar.server.issue.index;
 
 public class IssueSyncProgress {
-  private static final int PERCENT_100 = 100;
 
-  private final int completed;
+  private final int completedCount;
   private final int total;
-
   private final boolean hasFailures;
   private final boolean isCompleted;
 
-  public IssueSyncProgress(boolean isCompleted, int completed, int total, boolean hasFailures) {
-    this.completed = completed;
+  public IssueSyncProgress(boolean isCompleted, int completedCount, int total, boolean hasFailures) {
+    this.completedCount = completedCount;
     this.hasFailures = hasFailures;
     this.isCompleted = isCompleted;
     this.total = total;
   }
 
-  public int getCompleted() {
-    return completed;
+  public int getCompletedCount() {
+    return completedCount;
   }
 
   public boolean hasFailures() {
@@ -47,14 +45,7 @@ public class IssueSyncProgress {
     return total;
   }
 
-  public int toPercentCompleted() {
-    if (total != 0) {
-      return (int) Math.floor(PERCENT_100 * (double) completed / total);
-    }
-    return PERCENT_100;
-  }
-
   public boolean isCompleted() {
-    return completed == total || isCompleted;
+    return completedCount == total || isCompleted;
   }
 }
index c9cab2dc339006b2ebe1cb46d0aa3313800ef322..b69948dfd8cbecd024196fc8d9c24ca03cc5aa93 100644 (file)
@@ -19,9 +19,7 @@
  */
 package org.sonar.server.issue.index;
 
-import com.tngtech.java.junit.dataprovider.DataProvider;
 import com.tngtech.java.junit.dataprovider.DataProviderRunner;
-import com.tngtech.java.junit.dataprovider.UseDataProvider;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
@@ -56,30 +54,27 @@ public class IssueIndexSyncProgressCheckerTest {
   private final IssueIndexSyncProgressChecker underTest = new IssueIndexSyncProgressChecker(db.getDbClient());
 
   @Test
-  public void return_100_if_there_is_no_tasks_left() {
+  public void getIssueSyncProgress_whenNoTasksLeft_shouldReturnCompleted() {
     IssueSyncProgress issueSyncProgress = underTest.getIssueSyncProgress(db.getSession());
-    assertThat(issueSyncProgress.getCompleted()).isZero();
+    assertThat(issueSyncProgress.getCompletedCount()).isZero();
     assertThat(issueSyncProgress.getTotal()).isZero();
-    assertThat(issueSyncProgress.toPercentCompleted()).isEqualTo(100);
     assertThat(issueSyncProgress.isCompleted()).isTrue();
     assertThat(issueSyncProgress.hasFailures()).isFalse();
   }
 
   @Test
-  public void return_100_if_all_branches_have_need_issue_sync_set_FALSE() {
-    IntStream.range(0, 13).forEach(value -> insertProjectWithBranches(false, 2));
-    IntStream.range(0, 14).forEach(value -> insertProjectWithBranches(false, 4));
-    IntStream.range(0, 4).forEach(value -> insertProjectWithBranches(false, 10));
+  public void getIssueSyncProgress_whenNoBranchesNeedsIssueSync_shouldReturnCompleted() {
+    IntStream.range(0, 10).forEach(value -> insertProjectWithBranches(false, 1));
+    IntStream.range(0, 20).forEach(value -> insertProjectWithBranches(false, 2));
 
     IssueSyncProgress result = underTest.getIssueSyncProgress(db.getSession());
-    assertThat(result.getCompleted()).isEqualTo(153);
-    assertThat(result.getTotal()).isEqualTo(153);
-    assertThat(result.toPercentCompleted()).isEqualTo(100);
+    assertThat(result.getCompletedCount()).isEqualTo(30);
+    assertThat(result.getTotal()).isEqualTo(30);
     assertThat(result.isCompleted()).isTrue();
   }
 
   @Test
-  public void return_has_failure_true_if_exists_task() {
+  public void getIssueSyncProgress_whenTasksExist_shouldReturnFailures() {
     assertThat(underTest.getIssueSyncProgress(db.getSession()).hasFailures()).isFalse();
 
     ProjectData projectData1 = insertProjectWithBranches(false, 0);
@@ -97,36 +92,8 @@ public class IssueIndexSyncProgressCheckerTest {
   }
 
   @Test
-  @UseDataProvider("various_task_numbers")
-  public void return_correct_percent_value_for_branches_to_sync(int toSync, int synced, int expectedPercent) {
-    IntStream.range(0, toSync).forEach(value -> insertProjectWithBranches(true, 0));
-    IntStream.range(0, synced).forEach(value -> insertProjectWithBranches(false, 0));
-
-    IssueSyncProgress result = underTest.getIssueSyncProgress(db.getSession());
-    assertThat(result.getCompleted()).isEqualTo(synced);
-    assertThat(result.getTotal()).isEqualTo(toSync + synced);
-    assertThat(result.toPercentCompleted()).isEqualTo(expectedPercent);
-  }
-
-  @DataProvider
-  public static Object[][] various_task_numbers() {
-    return new Object[][] {
-      // toSync, synced, expected result
-      {0, 0, 100},
-      {0, 9, 100},
-      {10, 0, 0},
-      {99, 1, 1},
-      {2, 1, 33},
-      {6, 4, 40},
-      {7, 7, 50},
-      {1, 2, 66},
-      {4, 10, 71},
-      {1, 99, 99},
-    };
-  }
-
-  @Test
-  public void return_0_if_all_branches_have_need_issue_sync_set_true() {
+  public void getIssueSyncProgress_whenBranchesNeedIssueSync_shouldReturnNotCompleted() {
+    insertCeQueue("TASK_1", Status.PENDING);
     // only project
     IntStream.range(0, 10).forEach(value -> insertProjectWithBranches(true, 0));
 
@@ -134,9 +101,9 @@ public class IssueIndexSyncProgressCheckerTest {
     IntStream.range(0, 10).forEach(value -> insertProjectWithBranches(true, 1));
 
     IssueSyncProgress result = underTest.getIssueSyncProgress(db.getSession());
-    assertThat(result.getCompleted()).isZero();
-    assertThat(result.getTotal()).isEqualTo(30);
-    assertThat(result.toPercentCompleted()).isZero();
+    assertThat(result.getCompletedCount()).isZero();
+    assertThat(result.getTotal()).isEqualTo(20);
+    assertThat(result.isCompleted()).isFalse();
   }
 
   @Test
index 71a39a57f74223f7db25274af935935ab609f805..ea037058b745da1e499571e7a22bcb6e3c48a08f 100644 (file)
@@ -48,7 +48,7 @@ public class IndexationStatusActionIT {
   @Rule
   public DbTester db = DbTester.create(System2.INSTANCE);
 
-  private WsActionTester ws = new WsActionTester(new IndexationStatusAction(db.getDbClient(), issueIndexSyncProgressCheckerMock));
+  private final WsActionTester ws = new WsActionTester(new IndexationStatusAction(db.getDbClient(), issueIndexSyncProgressCheckerMock));
 
   @Test
   public void definition() {
@@ -61,27 +61,29 @@ public class IndexationStatusActionIT {
 
   @Test
   public void verify_example_of_response() {
-    when(issueIndexSyncProgressCheckerMock.getIssueSyncProgress(any())).thenReturn(new IssueSyncProgress(true,0, 0, false));
+    when(issueIndexSyncProgressCheckerMock.getIssueSyncProgress(any())).thenReturn(new IssueSyncProgress(false, 22, 38, false));
     ws.newRequest().execute().assertJson(ws.getDef().responseExampleAsString());
   }
 
   @Test
-  public void return_100_if_there_is_no_tasks_left() {
+  public void call_whenNoTasksLeft_shouldReturnCompleted() {
     when(issueIndexSyncProgressCheckerMock.getIssueSyncProgress(any())).thenReturn(new IssueSyncProgress(true, 10, 10, false));
     IndexationStatusWsResponse response = ws.newRequest()
       .executeProtobuf(IndexationStatusWsResponse.class);
-    assertThat(response.getPercentCompleted()).isEqualTo(100);
+    assertThat(response.getCompletedCount()).isEqualTo(10);
+    assertThat(response.getTotal()).isEqualTo(10);
     assertThat(response.getIsCompleted()).isTrue();
     assertThat(response.getHasFailures()).isFalse();
   }
 
   @Test
-  public void return_0_if_all_branches_have_need_issue_sync_set_TRUE() {
-    when(issueIndexSyncProgressCheckerMock.getIssueSyncProgress(any())).thenReturn(new IssueSyncProgress(false,0, 10, false));
+  public void call_whenBranchesNeedIssueSync_shouldReturnNotCompleted() {
+    when(issueIndexSyncProgressCheckerMock.getIssueSyncProgress(any())).thenReturn(new IssueSyncProgress(false, 0, 10, false));
 
     IndexationStatusWsResponse response = ws.newRequest()
       .executeProtobuf(IndexationStatusWsResponse.class);
-    assertThat(response.getPercentCompleted()).isZero();
+    assertThat(response.getCompletedCount()).isZero();
+    assertThat(response.getTotal()).isEqualTo(10);
     assertThat(response.getIsCompleted()).isFalse();
     assertThat(response.getHasFailures()).isFalse();
   }
index 23fcaf09dcbebe4531106aaef8157dd92c663b8f..cfaef26995a71fcc5132ddaeeed2bec585a00c55 100644 (file)
@@ -19,6 +19,7 @@
  */
 package org.sonar.server.ce.ws;
 
+import org.sonar.api.server.ws.Change;
 import org.sonar.api.server.ws.Request;
 import org.sonar.api.server.ws.Response;
 import org.sonar.api.server.ws.WebService;
@@ -42,8 +43,9 @@ public class IndexationStatusAction implements CeWsAction {
   @Override
   public void define(WebService.NewController controller) {
     controller.createAction("indexation_status")
-      .setDescription("Returns percentage of completed issue synchronization.")
+      .setDescription("Returns the count of projects with completed issue indexation.")
       .setResponseExample(getClass().getResource("indexation_status-example.json"))
+      .setChangelog(new Change("10.2", "Project count is returned instead of branch percentage."))
       .setHandler(this)
       .setInternal(true)
       .setSince("8.4");
@@ -63,8 +65,9 @@ public class IndexationStatusAction implements CeWsAction {
 
     return IndexationStatusWsResponse.newBuilder()
       .setIsCompleted(issueSyncProgress.isCompleted())
-      .setPercentCompleted(issueSyncProgress.toPercentCompleted())
       .setHasFailures(issueSyncProgress.hasFailures())
+      .setCompletedCount(issueSyncProgress.getCompletedCount())
+      .setTotal(issueSyncProgress.getTotal())
       .build();
   }
 
index a2a31b63a196dd952746e903db69cb53e3b54779..9b053dd2611b4ffde665f424c062934eb4b95e02 100644 (file)
@@ -1,5 +1,6 @@
 {
-  "isCompleted": true,
-  "percentCompleted": 100,
-  "hasFailures": false
+  "isCompleted": false,
+  "hasFailures": false,
+  "completedCount": 22,
+  "total": 38
 }
index c094aca171c8cd8b5b5e388454558c40f496c2a4..3c19f02a691ca3488490f1115b5c3c02780238de 100644 (file)
@@ -55,8 +55,9 @@ message ActivityStatusWsResponse {
 // GET api/ce/indexation_status
 message IndexationStatusWsResponse {
   optional bool isCompleted = 1;
-  optional int32 percentCompleted = 2;
-  optional bool hasFailures = 3;
+  optional bool hasFailures = 2;
+  optional int32 completedCount = 3;
+  optional int32 total = 4;
 }
 
 // GET api/ce/analysis_status