Browse Source

SONAR-19728 Update ws indexation_status to return project count instead of branch percentage

tags/10.2.0.77647
Eric Giffon 10 months ago
parent
commit
21fb2157a4

+ 0
- 36
server/sonar-db-dao/src/it/java/org/sonar/db/component/BranchDaoIT.java View 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();

+ 28
- 0
server/sonar-db-dao/src/it/java/org/sonar/db/project/ProjectDaoIT.java View 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);

+ 0
- 8
server/sonar-db-dao/src/main/java/org/sonar/db/component/BranchDao.java View 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);
}

+ 0
- 4
server/sonar-db-dao/src/main/java/org/sonar/db/component/BranchMapper.java View 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);

+ 8
- 0
server/sonar-db-dao/src/main/java/org/sonar/db/project/ProjectDao.java View 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();
}
}

+ 4
- 0
server/sonar-db-dao/src/main/java/org/sonar/db/project/ProjectMapper.java View File

@@ -74,4 +74,8 @@ public interface ProjectMapper {

@CheckForNull
Long getNclocSum(@Nullable @Param("projectUuidToExclude") String projectUuidToExclude);

int countIndexedProjects();

int countProjects();
}

+ 0
- 14
server/sonar-db-dao/src/main/resources/org/sonar/db/component/BranchMapper.xml View File

@@ -228,20 +228,6 @@
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"/>

+ 14
- 0
server/sonar-db-dao/src/main/resources/org/sonar/db/project/ProjectMapper.xml View File

@@ -217,4 +217,18 @@
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>

+ 3
- 3
server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueIndexSyncProgressChecker.java View 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) {

+ 6
- 15
server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueSyncProgress.java View File

@@ -20,23 +20,21 @@
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;
}
}

+ 13
- 46
server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexSyncProgressCheckerTest.java View 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

+ 9
- 7
server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/IndexationStatusActionIT.java View 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();
}

+ 5
- 2
server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/IndexationStatusAction.java View 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();
}


+ 4
- 3
server/sonar-webserver-webapi/src/main/resources/org/sonar/server/ce/ws/indexation_status-example.json View File

@@ -1,5 +1,6 @@
{
"isCompleted": true,
"percentCompleted": 100,
"hasFailures": false
"isCompleted": false,
"hasFailures": false,
"completedCount": 22,
"total": 38
}

+ 3
- 2
sonar-ws/src/main/protobuf/ws-ce.proto View 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

Loading…
Cancel
Save