diff options
author | Aurelien Poscia <aurelien.poscia@sonarsource.com> | 2023-05-23 09:56:47 +0200 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2023-05-26 20:03:08 +0000 |
commit | d6364ee9a0dcd7ada6ee8b192f1738d260baadee (patch) | |
tree | dc8ad22535ccf9296deb7d4a208fd7652580cb40 | |
parent | 36d7ca7391eed1ca47784cf4715e875c90145b50 (diff) | |
download | sonarqube-d6364ee9a0dcd7ada6ee8b192f1738d260baadee.tar.gz sonarqube-d6364ee9a0dcd7ada6ee8b192f1738d260baadee.zip |
SONAR-19346 Publish GitHub sync provisioning summary
13 files changed, 285 insertions, 238 deletions
diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/ce/CeActivityDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/ce/CeActivityDaoIT.java index eb05863189f..5a45c0e42e1 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/ce/CeActivityDaoIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/ce/CeActivityDaoIT.java @@ -50,6 +50,7 @@ import org.sonar.db.Pagination; import org.sonar.db.component.BranchDto; import org.sonar.db.project.ProjectDto; +import static java.util.Collections.emptyList; import static java.util.Collections.singleton; import static java.util.Collections.singletonList; import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic; @@ -115,35 +116,46 @@ public class CeActivityDaoIT { assertThat(dto.getErrorStacktrace()).isNull(); assertThat(dto.getErrorType()).isNull(); assertThat(dto.isHasScannerContext()).isFalse(); - assertThat(dto.getWarningCount()).isZero(); + assertThat(dto.getCeTaskMessageDtos()).isEmpty(); } @Test - public void selectByUuid_populates_warning_count() { + public void selectByUuid_populates_messages() { CeActivityDto[] tasks = { insert("TASK_1", REPORT, "PROJECT_1", SUCCESS), insert("TASK_2", REPORT, "PROJECT_1", SUCCESS), insert("TASK_3", REPORT, "PROJECT_1", SUCCESS) }; - int moreThan1 = 2 + new Random().nextInt(5); - insertWarnings(tasks[0], moreThan1); - insertWarnings(tasks[1], 0); - insertWarnings(tasks[2], 1); - - assertThat(underTest.selectByUuid(dbSession, tasks[0].getUuid()).get().getWarningCount()).isEqualTo(moreThan1); - assertThat(underTest.selectByUuid(dbSession, tasks[1].getUuid()).get().getWarningCount()).isZero(); - assertThat(underTest.selectByUuid(dbSession, tasks[2].getUuid()).get().getWarningCount()).isOne(); - } - - private void insertWarnings(CeActivityDto task, int warningCount) { - IntStream.range(0, warningCount).forEach(i -> db.getDbClient().ceTaskMessageDao().insert(dbSession, - new CeTaskMessageDto() - .setUuid(UuidFactoryFast.getInstance().create()) - .setTaskUuid(task.getUuid()) - .setMessage("message_" + task.getUuid() + "_" + i) - .setType(CeTaskMessageType.GENERIC) - .setCreatedAt(task.getUuid().hashCode() + i))); + List<CeTaskMessageDto> task1messages = insertCeTaskMessage(tasks[0], 4); + List<CeTaskMessageDto> task2messages = insertCeTaskMessage(tasks[1], 0); + List<CeTaskMessageDto> task3messages = insertCeTaskMessage(tasks[2], 1); + + getCeActivityAndAssertMessages(tasks[0].getUuid(), task1messages); + getCeActivityAndAssertMessages(tasks[1].getUuid(), task2messages); + getCeActivityAndAssertMessages(tasks[2].getUuid(), task3messages); + } + + private void getCeActivityAndAssertMessages(String taskUuid, List<CeTaskMessageDto> taskMessages) { + CeActivityDto ceActivityDto = underTest.selectByUuid(dbSession, taskUuid).orElseThrow(); + assertThat(ceActivityDto.getCeTaskMessageDtos()).usingRecursiveFieldByFieldElementComparator().hasSameElementsAs(taskMessages); + } + + private List<CeTaskMessageDto> insertCeTaskMessage(CeActivityDto task, int messagesCount) { + List<CeTaskMessageDto> ceTaskMessageDtos = IntStream.range(0, messagesCount) + .mapToObj(i -> createMessage(task, i)) + .toList(); + ceTaskMessageDtos.forEach(ceTaskMessageDto -> db.getDbClient().ceTaskMessageDao().insert(dbSession, ceTaskMessageDto)); db.commit(); + return ceTaskMessageDtos; + } + + private static CeTaskMessageDto createMessage(CeActivityDto task, int i) { + return new CeTaskMessageDto() + .setUuid(UuidFactoryFast.getInstance().create()) + .setTaskUuid(task.getUuid()) + .setMessage("message_" + task.getUuid() + "_" + i) + .setType(CeTaskMessageType.GENERIC) + .setCreatedAt(task.getUuid().hashCode() + i); } @Test @@ -518,7 +530,7 @@ public class CeActivityDaoIT { } @Test - public void selectByQuery_populates_warningCount() { + public void selectByQuery_populates_messages() { CeActivityDto[] tasks = { insert("TASK_1", REPORT, "PROJECT_1", SUCCESS), insert("TASK_2", REPORT, "PROJECT_1", FAILED), @@ -526,45 +538,57 @@ public class CeActivityDaoIT { insert("TASK_4", "views", null, SUCCESS) }; int moreThan1 = 2 + new Random().nextInt(5); - insertWarnings(tasks[0], moreThan1); - insertWarnings(tasks[1], 3); - insertWarnings(tasks[2], 1); - insertWarnings(tasks[3], 6); + insertCeTaskMessage(tasks[0], moreThan1); + insertCeTaskMessage(tasks[1], 30); + insertCeTaskMessage(tasks[2], 10); + insertCeTaskMessage(tasks[3], 60); // no filters - CeTaskQuery query = new CeTaskQuery().setStatuses(Collections.emptyList()); + CeTaskQuery query = new CeTaskQuery(); assertThat(underTest.selectByQuery(db.getSession(), query, forPage(1).andSize(10))) - .extracting(CeActivityDto::getUuid, CeActivityDto::getWarningCount) - .containsExactly(tuple("TASK_4", 6), tuple("TASK_3", 1), tuple("TASK_2", 3), tuple("TASK_1", moreThan1)); + .extracting(CeActivityDto::getUuid, ceActivityDto -> ceActivityDto.getCeTaskMessageDtos().size()) + .containsExactly(tuple("TASK_4", 60), tuple("TASK_3", 10), tuple("TASK_2", 30), tuple("TASK_1", moreThan1)); // select by component uuid query = new CeTaskQuery().setMainComponentUuid("PROJECT_1"); assertThat(underTest.selectByQuery(db.getSession(), query, forPage(1).andSize(100))) - .extracting(CeActivityDto::getUuid, CeActivityDto::getWarningCount) - .containsExactly(tuple("TASK_2", 3), tuple("TASK_1", moreThan1)); + .extracting(CeActivityDto::getUuid, ceActivityDto -> ceActivityDto.getCeTaskMessageDtos().size()) + .containsExactly(tuple("TASK_2", 30), tuple("TASK_1", moreThan1)); // select by status query = new CeTaskQuery().setStatuses(singletonList(SUCCESS.name())); assertThat(underTest.selectByQuery(db.getSession(), query, forPage(1).andSize(100))) - .extracting(CeActivityDto::getUuid, CeActivityDto::getWarningCount) - .containsExactly(tuple("TASK_4", 6), tuple("TASK_3", 1), tuple("TASK_1", moreThan1)); + .extracting(CeActivityDto::getUuid, ceActivityDto -> ceActivityDto.getCeTaskMessageDtos().size()) + .containsExactly(tuple("TASK_4", 60), tuple("TASK_3", 10), tuple("TASK_1", moreThan1)); // select by type query = new CeTaskQuery().setType(REPORT); assertThat(underTest.selectByQuery(db.getSession(), query, forPage(1).andSize(100))) - .extracting(CeActivityDto::getUuid, CeActivityDto::getWarningCount) - .containsExactly(tuple("TASK_3", 1), tuple("TASK_2", 3), tuple("TASK_1", moreThan1)); + .extracting(CeActivityDto::getUuid, ceActivityDto -> ceActivityDto.getCeTaskMessageDtos().size()) + .containsExactly(tuple("TASK_3", 10), tuple("TASK_2", 30), tuple("TASK_1", moreThan1)); query = new CeTaskQuery().setType("views"); assertThat(underTest.selectByQuery(db.getSession(), query, forPage(1).andSize(100))) - .extracting(CeActivityDto::getUuid, CeActivityDto::getWarningCount) - .containsExactly(tuple("TASK_4", 6)); + .extracting(CeActivityDto::getUuid, ceActivityDto -> ceActivityDto.getCeTaskMessageDtos().size()) + .containsExactly(tuple("TASK_4", 60)); // select by multiple conditions query = new CeTaskQuery().setType(REPORT).setOnlyCurrents(true).setMainComponentUuid("PROJECT_1"); assertThat(underTest.selectByQuery(db.getSession(), query, forPage(1).andSize(100))) - .extracting(CeActivityDto::getUuid, CeActivityDto::getWarningCount) - .containsExactly(tuple("TASK_2", 3)); + .extracting(CeActivityDto::getUuid, ceActivityDto -> ceActivityDto.getCeTaskMessageDtos().size()) + .containsExactly(tuple("TASK_2", 30)); + + } + @Test + public void selectByQuery_whenNoMessage_returnsEmptyList() { + insert("TASK_1", REPORT, "PROJECT_1", SUCCESS); + + List<CeActivityDto> results = underTest.selectByQuery(db.getSession(), new CeTaskQuery(), Pagination.all()); + + assertThat(results) + .hasSize(1) + .extracting(CeActivityDto::getCeTaskMessageDtos) + .containsExactly(emptyList()); } @Test @@ -682,18 +706,18 @@ public class CeActivityDaoIT { } @Test - public void selectOlderThan_does_not_populate_warningCount() { + public void selectOlderThan_populatesCorrectly() { CeActivityDto activity1 = insert("TASK_1", REPORT, "PROJECT_1", FAILED); - insertWarnings(activity1, 10); + insertCeTaskMessage(activity1, 10); CeActivityDto activity2 = insert("TASK_2", REPORT, "PROJECT_1", SUCCESS); - insertWarnings(activity2, 1); + insertCeTaskMessage(activity2, 1); List<CeActivityDto> dtos = underTest.selectOlderThan(db.getSession(), system2.now() + 1_000_000L); assertThat(dtos) .hasSize(2) - .extracting(CeActivityDto::getWarningCount) - .containsOnly(0); + .extracting(ceActivityDto -> ceActivityDto.getCeTaskMessageDtos().size()) + .containsOnly(10, 1); } @Test @@ -804,7 +828,7 @@ public class CeActivityDaoIT { insert("TASK_6", CeTaskTypes.BRANCH_ISSUE_SYNC, projectBranch1.getUuid(), projectDto3.getUuid(), FAILED); BranchDto projectBranch2 = db.components() - .insertProjectBranch(projectDto3, branchDto -> branchDto.setNeedIssueSync(true)); + .insertProjectBranch(projectDto3, branchDto -> branchDto.setNeedIssueSync(true)); insert("TASK_7", CeTaskTypes.BRANCH_ISSUE_SYNC, projectBranch2.getUuid(), projectDto3.getUuid(), CANCELED); diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeActivityDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeActivityDto.java index 407a093b368..1ae1fde50ed 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeActivityDto.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeActivityDto.java @@ -19,11 +19,12 @@ */ package org.sonar.db.ce; +import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Strings; +import java.util.List; import javax.annotation.CheckForNull; import javax.annotation.Nullable; import org.sonar.db.DbSession; -import org.sonar.db.component.ComponentDto; import static com.google.common.base.Preconditions.checkArgument; import static java.lang.String.format; @@ -99,13 +100,13 @@ public class CeActivityDto { * This property can not be populated when inserting but <strong>is populated when reading</strong>. */ private boolean hasScannerContext; + /** - * Count of warnings attached to the current activity. + * Messages attached to the current activity. * <p> - * This property can not be populated when inserting but <strong>is populated when retrieving the activity by UUID</strong>. + * This property can not be populated when inserting but <strong>is populated when retrieving the activity</strong>. */ - private int warningCount = 0; - + private List<CeTaskMessageDto> ceTaskMessageDtos; private String nodeName; CeActivityDto() { @@ -324,13 +325,13 @@ public class CeActivityDto { return this; } - public int getWarningCount() { - return warningCount; + public List<CeTaskMessageDto> getCeTaskMessageDtos() { + return ceTaskMessageDtos; } - protected CeActivityDto setWarningCount(int warningCount) { - checkArgument(warningCount >= 0); - this.warningCount = warningCount; + @VisibleForTesting + protected CeActivityDto setCeTaskMessageDtos(List<CeTaskMessageDto> ceTaskMessageDtos) { + this.ceTaskMessageDtos = ceTaskMessageDtos; return this; } @@ -369,7 +370,6 @@ public class CeActivityDto { ", errorMessage='" + errorMessage + '\'' + ", errorStacktrace='" + errorStacktrace + '\'' + ", hasScannerContext=" + hasScannerContext + - ", warningCount=" + warningCount + '}'; } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeTaskMessageType.java b/server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeTaskMessageType.java index a7a7b343fbe..da7a1ddb2b2 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeTaskMessageType.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeTaskMessageType.java @@ -20,17 +20,23 @@ package org.sonar.db.ce; public enum CeTaskMessageType { - GENERIC(false), - SUGGEST_DEVELOPER_EDITION_UPGRADE(true), - INFO(false); + INFO(false, false), + GENERIC(false, true), + SUGGEST_DEVELOPER_EDITION_UPGRADE(true, true); private final boolean dismissible; + private final boolean isWarning; - CeTaskMessageType(boolean dismissible) { + CeTaskMessageType(boolean dismissible, boolean isWarning) { this.dismissible = dismissible; + this.isWarning = isWarning; } public boolean isDismissible() { return dismissible; } + + public boolean isWarning() { + return isWarning; + } } diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/ce/CeActivityMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/ce/CeActivityMapper.xml index 0ad2f5d286b..07a3d8e4411 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/ce/CeActivityMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/ce/CeActivityMapper.xml @@ -15,10 +15,6 @@ csc.task_uuid is not null as hasScannerContext </sql> - <sql id="countWarnings"> - (select count(1) from ce_task_message ctm where ctm.task_uuid = ca.uuid) as warningCount - </sql> - <sql id="ceActivityColumns"> ca.uuid, ca.node_name as nodeName, @@ -40,7 +36,12 @@ ca.main_is_last_key as mainIsLastKey, ca.execution_time_ms as executionTimeMs, ca.error_message as errorMessage, - ca.error_type as errorType + ca.error_type as errorType, + ctm.uuid as ctm_uuid, + ctm.task_uuid as ctm_taskUuid, + ctm.message as ctm_message, + ctm.message_type as ctm_type, + ctm.created_at as ctm_createdAt </sql> <sql id="columns"> @@ -48,57 +49,55 @@ <include refid="hasScannerContextColumn"/> </sql> - <select id="selectByUuid" parameterType="String" resultType="org.sonar.db.ce.CeActivityDto"> + <sql id="fromClauseWithJoins"> + from ce_activity ca + left outer join ce_task_message ctm on ca.uuid = ctm.task_uuid + left outer join ce_scanner_context csc on csc.task_uuid = ca.uuid + </sql> + + <resultMap id="ceActivityResultMap" type="org.sonar.db.ce.CeActivityDto" autoMapping="true"> + <id property="uuid" column="uuid"/> + <collection property="ceTaskMessageDtos" ofType="org.sonar.db.ce.CeTaskMessageDto" autoMapping="true" columnPrefix="ctm_"> + <id property="uuid" column="uuid"/> + <result property="key" column="kee"/> + </collection> + </resultMap> + + <select id="selectByUuid" parameterType="String" resultMap="ceActivityResultMap"> select <include refid="columns"/>, - ca.error_stacktrace as errorStacktrace, - <include refid="countWarnings"/> - from ce_activity ca - left outer join ce_scanner_context csc on - ca.uuid = csc.task_uuid + ca.error_stacktrace as errorStacktrace + <include refid="fromClauseWithJoins"/> where ca.uuid=#{uuid,jdbcType=VARCHAR} </select> - <select id="selectByQuery" parameterType="map" resultType="org.sonar.db.ce.CeActivityDto"> + <select id="selectByQuery" parameterType="map" resultMap="ceActivityResultMap"> select - <include refid="columns"/>, - <include refid="countWarnings"/> - <include refid="sqlSelectByQuery" /> - order by - ca.created_at desc, uuid desc - limit #{pagination.pageSize,jdbcType=INTEGER} offset #{pagination.offset,jdbcType=INTEGER} - </select> - - <select id="selectByQuery" parameterType="map" resultType="org.sonar.db.ce.CeActivityDto" databaseId="mssql"> - select * from ( - select row_number() over(order by ca.created_at desc, uuid desc) as number, - <include refid="columns"/>, - <include refid="countWarnings"/> + <include refid="columns"/> + <include refid="fromClauseWithJoins"/> + where ca.uuid in ( <include refid="sqlSelectByQuery" /> - ) as query - where - query.number between #{pagination.startRowNumber,jdbcType=INTEGER} and #{pagination.endRowNumber,jdbcType=INTEGER} - order by createdAt desc, uuid desc + ) + order by ca.created_at desc, ca.uuid desc </select> - <select id="selectByQuery" parameterType="map" resultType="org.sonar.db.ce.CeActivityDto" databaseId="oracle"> - select * from ( - select rownum as rn, t.* from ( - select - <include refid="columns"/>, - <include refid="countWarnings"/> - <include refid="sqlSelectByQuery" /> - order by ca.created_at desc, ca.uuid desc - ) t - ) t - where - t.rn between #{pagination.startRowNumber,jdbcType=INTEGER} and #{pagination.endRowNumber,jdbcType=INTEGER} + <sql id="sqlSelectByQuery"> + <include refid="sqlSelectByQueryWithoutPagination"/> + order by ca.created_at desc, uuid desc + offset (#{pagination.startRowNumber,jdbcType=INTEGER}-1) rows fetch next #{pagination.pageSize,jdbcType=INTEGER} rows only + </sql> + + <select id="countByQuery" parameterType="map" resultType="int"> + select + count(1) from ( + <include refid="sqlSelectByQueryWithoutPagination" /> + ) allTaskUuids </select> - <sql id="sqlSelectByQuery"> + <sql id="sqlSelectByQueryWithoutPagination"> + select ca.uuid from ce_activity ca - left outer join ce_scanner_context csc on csc.task_uuid = ca.uuid <where> <if test="query.onlyCurrents"> and ca.main_is_last=${_true} @@ -136,30 +135,22 @@ </where> </sql> - <select id="selectOlderThan" parameterType="long" resultType="org.sonar.db.ce.CeActivityDto"> + <select id="selectOlderThan" parameterType="long" resultMap="ceActivityResultMap"> select <include refid="columns"/> - from ce_activity ca - left outer join ce_scanner_context csc on csc.task_uuid = ca.uuid + <include refid="fromClauseWithJoins"/> where ca.created_at < #{beforeDate,jdbcType=BIGINT} </select> - <select id="selectNewerThan" parameterType="long" resultType="org.sonar.db.ce.CeActivityDto"> + <select id="selectNewerThan" parameterType="long" resultMap="ceActivityResultMap"> select <include refid="columns"/> - from ce_activity ca - left outer join ce_scanner_context csc on csc.task_uuid = ca.uuid + <include refid="fromClauseWithJoins"/> where ca.created_at > #{afterDate,jdbcType=BIGINT} </select> - <select id="countByQuery" parameterType="map" resultType="int"> - select - count(1) - <include refid="sqlSelectByQuery" /> - </select> - <select id="countLastByStatusAndMainComponentUuid" resultType="int"> select count(1) @@ -254,12 +245,10 @@ </foreach> </delete> - <select id="selectLastByComponentUuidAndTaskType" parameterType="map" resultType="org.sonar.db.ce.CeActivityDto"> + <select id="selectLastByComponentUuidAndTaskType" parameterType="map" resultMap="ceActivityResultMap"> select <include refid="columns"/> - from ce_activity ca - left outer join ce_scanner_context csc on - ca.uuid = csc.task_uuid + <include refid="fromClauseWithJoins"/> where ca.component_uuid = #{componentUuid,jdbcType=VARCHAR} and ca.task_type = #{taskType,jdbcType=VARCHAR} @@ -289,10 +278,10 @@ from dual </select> - <select id="selectByTaskType" parameterType="map" resultType="org.sonar.db.ce.CeActivityDto"> + <select id="selectByTaskType" parameterType="map" resultMap="ceActivityResultMap"> select <include refid="ceActivityColumns"/> - from ce_activity ca + <include refid="fromClauseWithJoins"/> where ca.task_type = #{taskType,jdbcType=VARCHAR} </select> diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/ce/CeActivityDtoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/ce/CeActivityDtoTest.java index 77d67fa80b8..702551ef98e 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/ce/CeActivityDtoTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/ce/CeActivityDtoTest.java @@ -142,15 +142,6 @@ public class CeActivityDtoTest { assertThat(underTest.getErrorMessage()).isEqualTo(before + after); } - @Test - public void setWarningCount_throws_IAE_if_less_than_0() { - underTest.setWarningCount(0); - underTest.setWarningCount(1 + new Random().nextInt(10)); - - assertThatThrownBy(() -> underTest.setWarningCount(-1 - new Random().nextInt(10))) - .isInstanceOf(IllegalArgumentException.class); - } - @DataProvider public static Object[][] stringsWithChar0() { return new Object[][] { diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/ActivityActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/ActivityActionIT.java index 893f5ede974..1a993ffed32 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/ActivityActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/ActivityActionIT.java @@ -241,15 +241,15 @@ public class ActivityActionIT { } @Test - public void return_warnings_count_on_queue_and_activity_but_no_warnings_list() { + public void return_warnings_count_on_queue_and_activity_and_warnings_list() { logInAsSystemAdministrator(); ComponentDto project1 = db.components().insertPrivateProject().getMainBranchComponent(); ComponentDto project2 = db.components().insertPrivateProject().getMainBranchComponent(); insertActivity("T1", project1, SUCCESS); insertActivity("T2", project2, FAILED); insertQueue("T3", project1, IN_PROGRESS); - insertMessages("T1", 2); - insertMessages("T2", 0); + List<String> messagesT1 = insertMessages("T1", 2); + List<String> messagesT2 = insertMessages("T2", 1); insertMessages("T3", 5); ActivityResponse activityResponse = call(ws.newRequest() @@ -257,18 +257,22 @@ public class ActivityActionIT { .setParam(PARAM_STATUS, "SUCCESS,FAILED,CANCELED,IN_PROGRESS,PENDING")); assertThat(activityResponse.getTasksList()) .extracting(Task::getId, Task::getWarningCount, Task::getWarningsList) - .containsOnly(tuple("T1", 2, emptyList()), tuple("T2", 0, emptyList()), tuple("T3", 0, emptyList())); + .containsOnly(tuple("T1", messagesT1.size(), messagesT1), tuple("T2", messagesT2.size(), messagesT2), tuple("T3", 0, emptyList())); } - private void insertMessages(String taskUuid, int messageCount) { - IntStream.range(0, messageCount) - .forEach(i -> db.getDbClient().ceTaskMessageDao().insert(db.getSession(), new CeTaskMessageDto() + private List<String> insertMessages(String taskUuid, int messageCount) { + List<CeTaskMessageDto> ceTaskMessageDtos = IntStream.range(0, messageCount) + .mapToObj(i -> new CeTaskMessageDto() .setUuid("uuid_" + taskUuid + "_" + i) .setTaskUuid(taskUuid) .setMessage("m_" + taskUuid + "_" + i) .setType(CeTaskMessageType.GENERIC) - .setCreatedAt(taskUuid.hashCode() + i))); + .setCreatedAt(taskUuid.hashCode() + i)) + .toList(); + + ceTaskMessageDtos.forEach(ceTaskMessageDto -> db.getDbClient().ceTaskMessageDao().insert(db.getSession(), ceTaskMessageDto)); db.commit(); + return ceTaskMessageDtos.stream().map(CeTaskMessageDto::getMessage).toList(); } @Test diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/ComponentActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/ComponentActionIT.java index 4c9111b7182..8884dfa1965 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/ComponentActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/ComponentActionIT.java @@ -20,7 +20,7 @@ package org.sonar.server.ce.ws; import java.util.Collections; -import java.util.Random; +import java.util.List; import java.util.stream.IntStream; import javax.annotation.Nullable; import org.junit.Rule; @@ -243,18 +243,22 @@ public class ComponentActionIT { } @Test - public void populates_warning_count_of_activities_but_not_warnings() { + public void populates_warning_count_and_warnings_of_activities() { ComponentDto privateProject = db.components().insertPrivateProject().getMainBranchComponent(); userSession.addProjectPermission(UserRole.USER, privateProject); SnapshotDto analysis = db.components().insertSnapshot(privateProject); CeActivityDto activity = insertActivity("Branch", privateProject, SUCCESS, analysis); - int messageCount = 1 + new Random().nextInt(10); - IntStream.range(0, messageCount).forEach(i -> db.getDbClient().ceTaskMessageDao().insert(db.getSession(), new CeTaskMessageDto() - .setUuid("uuid_" + i) - .setTaskUuid(activity.getUuid()) - .setMessage("m_" + i) - .setType(CeTaskMessageType.GENERIC) - .setCreatedAt(i))); + int messageCount = 5; + List<CeTaskMessageDto> ceTaskMessageDtos = IntStream.range(0, messageCount) + .mapToObj(i -> new CeTaskMessageDto() + .setUuid("uuid_" + i) + .setTaskUuid(activity.getUuid()) + .setMessage("m_" + i) + .setType(CeTaskMessageType.GENERIC) + .setCreatedAt(i)) + .toList(); + + ceTaskMessageDtos.forEach(ceTaskMessageDto -> db.getDbClient().ceTaskMessageDao().insert(db.getSession(), ceTaskMessageDto)); db.commit(); Ce.ComponentResponse response = ws.newRequest() @@ -263,7 +267,7 @@ public class ComponentActionIT { assertThat(response.hasCurrent()).isTrue(); assertThat(response.getCurrent()) .extracting(Ce.Task::getWarningCount, Ce.Task::getWarningsList) - .containsOnly(messageCount, emptyList()); + .containsOnly(messageCount, ceTaskMessageDtos.stream().map(CeTaskMessageDto::getMessage).toList()); } @Test diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/TaskActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/TaskActionIT.java index bad7f04b69e..42a6b28c5f4 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/TaskActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/TaskActionIT.java @@ -20,7 +20,7 @@ package org.sonar.server.ce.ws; import java.util.Collections; -import java.util.Random; +import java.util.List; import java.util.stream.IntStream; import javax.annotation.Nullable; import org.junit.Before; @@ -115,7 +115,7 @@ public class TaskActionIT { UserDto user = db.users().insertUser(); userSession.logIn(user).setSystemAdministrator(); CeQueueDto queueDto = createAndPersistQueueTask(null, user); - IntStream.range(0, 1 + new Random().nextInt(5)) + IntStream.range(0, 6) .forEach(i -> db.getDbClient().ceTaskMessageDao().insert(db.getSession(), new CeTaskMessageDto() .setUuid("u_" + i) @@ -181,7 +181,7 @@ public class TaskActionIT { public void branch_in_queue_analysis() { UserDto user = db.users().insertUser(); userSession.logIn(user).setSystemAdministrator(); - ; + String branch = "my_branch"; CeQueueDto queueDto = createAndPersistQueueTask(null, user); insertCharacteristic(queueDto, BRANCH_KEY, branch); @@ -433,7 +433,7 @@ public class TaskActionIT { public void get_warnings_on_global_archived_task_requires_to_be_system_administrator() { logInAsSystemAdministrator(); - getWarningsImpl(createAndPersistArchivedTask(null)); + insertWarningsCallEndpointAndAssertWarnings(createAndPersistArchivedTask(null)); } @Test @@ -441,7 +441,7 @@ public class TaskActionIT { userSession.logIn().registerComponents(publicProject); CeActivityDto persistArchivedTask = createAndPersistArchivedTask(publicProject); - assertThatThrownBy(() -> getWarningsImpl(persistArchivedTask)) + assertThatThrownBy(() -> insertWarningsCallEndpointAndAssertWarnings(persistArchivedTask)) .isInstanceOf(ForbiddenException.class); } @@ -450,7 +450,7 @@ public class TaskActionIT { userSession.logIn().addProjectPermission(UserRole.USER, privateProject); CeActivityDto persistArchivedTask = createAndPersistArchivedTask(privateProject); - assertThatThrownBy(() -> getWarningsImpl(persistArchivedTask)) + assertThatThrownBy(() -> insertWarningsCallEndpointAndAssertWarnings(persistArchivedTask)) .isInstanceOf(ForbiddenException.class); } @@ -458,33 +458,50 @@ public class TaskActionIT { public void get_warnings_on_private_project_archived_task_if_scan() { userSession.logIn().addProjectPermission(GlobalPermission.SCAN.getKey(), privateProject); - getWarningsImpl(createAndPersistArchivedTask(privateProject)); + insertWarningsCallEndpointAndAssertWarnings(createAndPersistArchivedTask(privateProject)); } @Test public void get_warnings_on_private_project_archived_task_if_global_scan_permission() { userSession.logIn().addPermission(GlobalPermission.SCAN); - getWarningsImpl(createAndPersistArchivedTask(privateProject)); + insertWarningsCallEndpointAndAssertWarnings(createAndPersistArchivedTask(privateProject)); + } + + @Test + public void get_warnings_on_global_archived_task_requires_to_be_system_administrator2() { + logInAsSystemAdministrator(); + + CeActivityDto activityDto = persist(createActivityDto("uuid1")); + insertMessage(activityDto, 1, CeTaskMessageType.INFO); + CeTaskMessageDto warning = insertMessage(activityDto, 2, CeTaskMessageType.GENERIC); + + callEndpointAndAssertWarnings(activityDto, List.of(warning)); } - private void getWarningsImpl(CeActivityDto task) { - String[] warnings = IntStream.range(0, 1 + new Random().nextInt(10)) + private void insertWarningsCallEndpointAndAssertWarnings(CeActivityDto task) { + List<CeTaskMessageDto> warnings = IntStream.range(0, 6) .mapToObj(i -> insertWarning(task, i)) - .map(CeTaskMessageDto::getMessage) - .toArray(String[]::new); + .toList(); + callEndpointAndAssertWarnings(task, warnings); + } + private void callEndpointAndAssertWarnings(CeActivityDto task, List<CeTaskMessageDto> warnings) { Ce.Task taskWithWarnings = callWithWarnings(task.getUuid()); - assertThat(taskWithWarnings.getWarningCount()).isEqualTo(warnings.length); - assertThat(taskWithWarnings.getWarningsList()).containsExactly(warnings); + assertThat(taskWithWarnings.getWarningCount()).isEqualTo(warnings.size()); + assertThat(taskWithWarnings.getWarningsList()).isEqualTo(warnings.stream().map(CeTaskMessageDto::getMessage).toList()); } private CeTaskMessageDto insertWarning(CeActivityDto task, int i) { + return insertMessage(task, i, CeTaskMessageType.GENERIC); + } + + private CeTaskMessageDto insertMessage(CeActivityDto task, int i, CeTaskMessageType ceTaskMessageType) { CeTaskMessageDto res = new CeTaskMessageDto() .setUuid(UuidFactoryFast.getInstance().create()) .setTaskUuid(task.getUuid()) .setMessage("msg_" + task.getUuid() + "_" + i) - .setType(CeTaskMessageType.GENERIC) + .setType(ceTaskMessageType) .setCreatedAt(task.getUuid().hashCode() + i); db.getDbClient().ceTaskMessageDao().insert(db.getSession(), res); db.getSession().commit(); diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/ActivityAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/ActivityAction.java index 5eb7b96b74c..f30975adf1d 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/ActivityAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/ActivityAction.java @@ -58,7 +58,6 @@ import static java.lang.Integer.max; import static java.lang.Integer.parseInt; import static java.lang.String.format; import static java.util.Arrays.asList; -import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; import static java.util.stream.Collectors.toSet; import static org.sonar.api.server.ws.WebService.Param.TEXT_QUERY; @@ -78,7 +77,7 @@ import static org.sonar.server.ws.WsUtils.writeProtobuf; public class ActivityAction implements CeWsAction { private static final int MAX_PAGE_SIZE = 1000; - private static final String[] POSSIBLE_QUALIFIERS = new String[]{Qualifiers.PROJECT, Qualifiers.APP, Qualifiers.VIEW}; + private static final String[] POSSIBLE_QUALIFIERS = new String[] {Qualifiers.PROJECT, Qualifiers.APP, Qualifiers.VIEW}; private static final String INVALID_QUERY_PARAM_ERROR_MESSAGE = "%s and %s must not be set at the same time"; private final UserSession userSession; @@ -113,7 +112,9 @@ public class ActivityAction implements CeWsAction { new Change("7.6", format("The use of module keys in parameters '%s' is deprecated", TEXT_QUERY)), new Change("8.8", "field \"logs\" is dropped"), new Change("10.0", "Remove deprecated field 'componentId'"), - new Change("10.1", String.format("The use of module keys in parameter '%s' is removed", PARAM_COMPONENT))) + new Change("10.1", String.format("The use of module keys in parameter '%s' is removed", PARAM_COMPONENT)), + new Change("10.1", "Warnings field will be now be filled (it was always empty in the past).") + ) .setSince("5.2"); action.createParam(PARAM_COMPONENT) @@ -264,7 +265,7 @@ public class ActivityAction implements CeWsAction { } Optional<CeActivityDto> activity = dbClient.ceActivityDao().selectByUuid(dbSession, textQuery); - return activity.map(ceActivityDto -> formatter.formatActivity(dbSession, ceActivityDto, null, emptyList())); + return activity.map(ceActivityDto -> formatter.formatActivity(dbSession, ceActivityDto, null)); } private CeTaskQuery buildQuery(DbSession dbSession, Request request, @Nullable ComponentDto component) { diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/ComponentAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/ComponentAction.java index 6273a27cbe7..b9178c473ba 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/ComponentAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/ComponentAction.java @@ -38,7 +38,6 @@ import org.sonarqube.ws.Ce; import org.sonarqube.ws.Ce.ComponentResponse; import static java.lang.String.format; -import static java.util.Collections.emptyList; import static org.sonar.db.Pagination.forPage; import static org.sonar.server.ce.ws.CeWsParameters.PARAM_COMPONENT; import static org.sonar.server.ws.WsUtils.writeProtobuf; @@ -92,7 +91,7 @@ public class ComponentAction implements CeWsAction { Ce.ComponentResponse.Builder wsResponseBuilder = ComponentResponse.newBuilder(); wsResponseBuilder.addAllQueue(formatter.formatQueue(dbSession, queueDtos)); if (activityDtos.size() == 1) { - wsResponseBuilder.setCurrent(formatter.formatActivity(dbSession, activityDtos.get(0), null, emptyList())); + wsResponseBuilder.setCurrent(formatter.formatActivity(dbSession, activityDtos.get(0), null)); } writeProtobuf(wsResponseBuilder.build(), wsRequest, wsResponse); } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/TaskAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/TaskAction.java index cc52bb9251b..2f15f9272a1 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/TaskAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/TaskAction.java @@ -39,7 +39,6 @@ import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.ce.CeActivityDto; import org.sonar.db.ce.CeQueueDto; -import org.sonar.db.ce.CeTaskMessageDto; import org.sonar.db.component.ComponentDto; import org.sonar.db.permission.GlobalPermission; import org.sonar.server.user.UserSession; @@ -75,7 +74,10 @@ public class TaskAction implements CeWsAction { .setResponseExample(getClass().getResource("task-example.json")) .setSince("5.2") .setChangelog( - new Change("6.6", "fields \"branch\" and \"branchType\" added")) + new Change("6.6", "fields \"branch\" and \"branchType\" added"), + new Change("10.1", "Warnings field will be now always be filled (it is not necessary to mention it explicitly in 'additionalFields'). " + + "'additionalFields' value `warning' is deprecated.") + ) .setHandler(this); action @@ -109,8 +111,7 @@ public class TaskAction implements CeWsAction { maskErrorStacktrace(ceActivityDto, additionalFields); wsTaskResponse.setTask( wsTaskFormatter.formatActivity(dbSession, ceActivityDto, - extractScannerContext(dbSession, ceActivityDto, additionalFields), - extractWarnings(dbSession, ceActivityDto, additionalFields))); + extractScannerContext(dbSession, ceActivityDto, additionalFields))); } writeProtobuf(wsTaskResponse.build(), wsRequest, wsResponse); } @@ -151,19 +152,10 @@ public class TaskAction implements CeWsAction { return null; } - private List<String> extractWarnings(DbSession dbSession, CeActivityDto activityDto, Set<AdditionalField> additionalFields) { - if (additionalFields.contains(AdditionalField.WARNINGS)) { - List<CeTaskMessageDto> dtos = dbClient.ceTaskMessageDao().selectByTask(dbSession, activityDto.getUuid()); - return dtos.stream() - .map(CeTaskMessageDto::getMessage) - .collect(MoreCollectors.toList(dtos.size())); - } - return Collections.emptyList(); - } - private enum AdditionalField { STACKTRACE("stacktrace"), SCANNER_CONTEXT("scannerContext"), + @Deprecated(forRemoval = true, since = "10.1") WARNINGS("warnings"); private final String label; diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/TaskFormatter.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/TaskFormatter.java index 54f941beb71..d8240d3bbc0 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/TaskFormatter.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/TaskFormatter.java @@ -37,13 +37,13 @@ import org.sonar.db.DbSession; import org.sonar.db.ce.CeActivityDto; import org.sonar.db.ce.CeQueueDto; import org.sonar.db.ce.CeTaskCharacteristicDto; +import org.sonar.db.ce.CeTaskMessageDto; import org.sonar.db.component.ComponentDto; import org.sonar.db.user.UserDto; import org.sonarqube.ws.Ce; import org.sonarqube.ws.Common; import static java.lang.String.format; -import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; import static java.util.Optional.ofNullable; import static org.sonar.api.utils.DateUtils.formatDateTime; @@ -90,39 +90,40 @@ public class TaskFormatter { return builder.build(); } - public Ce.Task formatActivity(DbSession dbSession, CeActivityDto dto, @Nullable String scannerContext, List<String> warnings) { - return formatActivity(dto, DtoCache.forActivityDtos(dbClient, dbSession, singletonList(dto)), scannerContext, warnings); + public Ce.Task formatActivity(DbSession dbSession, CeActivityDto dto, @Nullable String scannerContext) { + return formatActivity(dto, DtoCache.forActivityDtos(dbClient, dbSession, singletonList(dto)), scannerContext); } public List<Ce.Task> formatActivity(DbSession dbSession, List<CeActivityDto> dtos) { DtoCache cache = DtoCache.forActivityDtos(dbClient, dbSession, dtos); return dtos.stream() - .map(input -> formatActivity(input, cache, null, emptyList())) + .map(input -> formatActivity(input, cache, null)) .collect(MoreCollectors.toList(dtos.size())); } - private static Ce.Task formatActivity(CeActivityDto dto, DtoCache cache, @Nullable String scannerContext, List<String> warnings) { + private static Ce.Task formatActivity(CeActivityDto activityDto, DtoCache cache, @Nullable String scannerContext) { Ce.Task.Builder builder = Ce.Task.newBuilder(); - builder.setId(dto.getUuid()); - builder.setStatus(Ce.TaskStatus.valueOf(dto.getStatus().name())); - builder.setType(dto.getTaskType()); - ofNullable(dto.getNodeName()).ifPresent(builder::setNodeName); - ofNullable(dto.getComponentUuid()).ifPresent(uuid -> setComponent(builder, uuid, cache).setComponentId(uuid)); - String analysisUuid = dto.getAnalysisUuid(); + builder.setId(activityDto.getUuid()); + builder.setStatus(Ce.TaskStatus.valueOf(activityDto.getStatus().name())); + builder.setType(activityDto.getTaskType()); + ofNullable(activityDto.getNodeName()).ifPresent(builder::setNodeName); + ofNullable(activityDto.getComponentUuid()).ifPresent(uuid -> setComponent(builder, uuid, cache).setComponentId(uuid)); + String analysisUuid = activityDto.getAnalysisUuid(); ofNullable(analysisUuid).ifPresent(builder::setAnalysisId); - setBranchOrPullRequest(builder, dto.getUuid(), cache); + setBranchOrPullRequest(builder, activityDto.getUuid(), cache); ofNullable(analysisUuid).ifPresent(builder::setAnalysisId); - cache.getUser(dto.getSubmitterUuid()).ifPresent(user -> builder.setSubmitterLogin(user.getLogin())); - builder.setSubmittedAt(formatDateTime(new Date(dto.getSubmittedAt()))); - ofNullable(dto.getStartedAt()).map(DateUtils::formatDateTime).ifPresent(builder::setStartedAt); - ofNullable(dto.getExecutedAt()).map(DateUtils::formatDateTime).ifPresent(builder::setExecutedAt); - ofNullable(dto.getExecutionTimeMs()).ifPresent(builder::setExecutionTimeMs); - ofNullable(dto.getErrorMessage()).ifPresent(builder::setErrorMessage); - ofNullable(dto.getErrorStacktrace()).ifPresent(builder::setErrorStacktrace); - ofNullable(dto.getErrorType()).ifPresent(builder::setErrorType); + cache.getUser(activityDto.getSubmitterUuid()).ifPresent(user -> builder.setSubmitterLogin(user.getLogin())); + builder.setSubmittedAt(formatDateTime(new Date(activityDto.getSubmittedAt()))); + ofNullable(activityDto.getStartedAt()).map(DateUtils::formatDateTime).ifPresent(builder::setStartedAt); + ofNullable(activityDto.getExecutedAt()).map(DateUtils::formatDateTime).ifPresent(builder::setExecutedAt); + ofNullable(activityDto.getExecutionTimeMs()).ifPresent(builder::setExecutionTimeMs); + ofNullable(activityDto.getErrorMessage()).ifPresent(builder::setErrorMessage); + ofNullable(activityDto.getErrorStacktrace()).ifPresent(builder::setErrorStacktrace); + ofNullable(activityDto.getErrorType()).ifPresent(builder::setErrorType); ofNullable(scannerContext).ifPresent(builder::setScannerContext); - builder.setHasScannerContext(dto.isHasScannerContext()); - builder.setWarningCount(dto.getWarningCount()); + builder.setHasScannerContext(activityDto.isHasScannerContext()); + List<String> warnings = extractWarningMessages(activityDto); + builder.setWarningCount(warnings.size()); warnings.forEach(builder::addWarnings); return builder.build(); @@ -157,6 +158,13 @@ public class TaskFormatter { return builder; } + private static List<String> extractWarningMessages(CeActivityDto dto) { + return dto.getCeTaskMessageDtos().stream() + .filter(ceTaskMessageDto -> ceTaskMessageDto.getType().isWarning()) + .map(CeTaskMessageDto::getMessage) + .toList(); + } + private static class DtoCache { private final Map<String, ComponentDto> componentsByUuid; private final Multimap<String, CeTaskCharacteristicDto> characteristicsByTaskUuid; @@ -190,8 +198,8 @@ public class TaskFormatter { static DtoCache forActivityDtos(DbClient dbClient, DbSession dbSession, Collection<CeActivityDto> ceActivityDtos) { Map<String, ComponentDto> componentsByUuid = dbClient.componentDao().selectByUuids( - dbSession, - getComponentUuidsOfCeActivities(ceActivityDtos)) + dbSession, + getComponentUuidsOfCeActivities(ceActivityDtos)) .stream() .collect(uniqueIndex(ComponentDto::uuid)); Multimap<String, CeTaskCharacteristicDto> characteristicsByTaskUuid = dbClient.ceTaskCharacteristicsDao() diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/ce/ws/TaskFormatterTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/ce/ws/TaskFormatterTest.java index 73d898d8272..ed2da8ed38b 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/ce/ws/TaskFormatterTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/ce/ws/TaskFormatterTest.java @@ -19,42 +19,41 @@ */ package org.sonar.server.ce.ws; -import java.util.Arrays; +import java.util.ArrayList; import java.util.Collections; import java.util.Date; -import java.util.Random; +import java.util.List; import java.util.stream.IntStream; import javax.annotation.Nullable; import org.junit.Rule; import org.junit.Test; import org.sonar.api.utils.DateUtils; import org.sonar.api.utils.System2; -import org.sonar.db.DbSession; import org.sonar.db.DbTester; import org.sonar.db.ce.CeActivityDto; import org.sonar.db.ce.CeQueueDto; +import org.sonar.db.ce.CeTaskMessageDto; +import org.sonar.db.ce.CeTaskMessageType; import org.sonar.db.ce.CeTaskTypes; import org.sonar.db.user.UserDto; import org.sonarqube.ws.Ce; import static java.util.Arrays.asList; -import static java.util.Collections.emptyList; -import static java.util.stream.Collectors.toList; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.Assertions.tuple; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static org.sonar.db.ce.CeQueueTesting.makeInProgress; +import static org.sonar.db.ce.CeTaskMessageType.INFO; public class TaskFormatterTest { private static final String NODE_NAME = "nodeName1"; + private static final int WARNING_COUNT = 5; + @Rule public DbTester db = DbTester.create(System2.INSTANCE); - private final int warningCount = new Random().nextInt(10); - private final System2 system2 = mock(System2.class); private final TaskFormatter underTest = new TaskFormatter(db.getDbClient(), system2); @@ -170,21 +169,11 @@ public class TaskFormatterTest { } @Test - public void formatActivity_throws_NPE_if_warnings_parameter_is_null() { - UserDto user = db.users().insertUser(); - CeActivityDto dto = newActivity("UUID", "COMPONENT_UUID", CeActivityDto.Status.FAILED, user); - - DbSession dbSession = db.getSession(); - assertThatThrownBy(() -> underTest.formatActivity(dbSession, dto, "foo", null)) - .isInstanceOf(NullPointerException.class); - } - - @Test public void formatActivity() { UserDto user = db.users().insertUser(); CeActivityDto dto = newActivity("UUID", "COMPONENT_UUID", CeActivityDto.Status.FAILED, user); - Ce.Task wsTask = underTest.formatActivity(db.getSession(), dto, null, emptyList()); + Ce.Task wsTask = underTest.formatActivity(db.getSession(), dto, null); assertThat(wsTask.getType()).isEqualTo(CeTaskTypes.REPORT); assertThat(wsTask.getId()).isEqualTo("UUID"); @@ -195,7 +184,7 @@ public class TaskFormatterTest { assertThat(wsTask.getExecutionTimeMs()).isEqualTo(500L); assertThat(wsTask.getAnalysisId()).isEqualTo("U1"); assertThat(wsTask.hasScannerContext()).isFalse(); - assertThat(wsTask.getWarningCount()).isEqualTo(warningCount); + assertThat(wsTask.getWarningCount()).isZero(); assertThat(wsTask.getWarningsList()).isEmpty(); } @@ -204,21 +193,31 @@ public class TaskFormatterTest { CeActivityDto dto = newActivity("UUID", "COMPONENT_UUID", CeActivityDto.Status.FAILED, null); String expected = "scanner context baby!"; - Ce.Task wsTask = underTest.formatActivity(db.getSession(), dto, expected, emptyList()); + Ce.Task wsTask = underTest.formatActivity(db.getSession(), dto, expected); assertThat(wsTask.hasScannerContext()).isTrue(); assertThat(wsTask.getScannerContext()).isEqualTo(expected); } @Test - public void formatActivity_set_warnings_list_if_argument_is_non_empty_not_checking_consistency_with_warning_count() { - CeActivityDto dto = newActivity("UUID", "COMPONENT_UUID", CeActivityDto.Status.FAILED, null); - String[] warnings = IntStream.range(0, warningCount + 1 + new Random().nextInt(5)).mapToObj(i -> "warning_" + i).toArray(String[]::new); + public void formatActivity_filterNonWarnings_andSetMessagesAndCount() { + TestActivityDto dto = newActivity("UUID", "COMPONENT_UUID", CeActivityDto.Status.FAILED, null); + CeTaskMessageDto warning1 = createCeTaskMessageDto(1998, CeTaskMessageType.GENERIC); + CeTaskMessageDto warning2 = createCeTaskMessageDto(1999, CeTaskMessageType.GENERIC); + + List<CeTaskMessageDto> ceTaskMessageDtos = new ArrayList<>(dto.getCeTaskMessageDtos()); + ceTaskMessageDtos.add(warning1); + ceTaskMessageDtos.add(warning2); + dto.setCeTaskMessageDtos(ceTaskMessageDtos); - Ce.Task wsTask = underTest.formatActivity(db.getSession(), dto, null, Arrays.stream(warnings).collect(toList())); + Ce.Task wsTask = underTest.formatActivity(db.getSession(), dto, null); + + assertThat(wsTask.getWarningCount()).isEqualTo(2); + assertThat(wsTask.getWarningsList()).hasSameElementsAs(getMessagesText(List.of(warning1, warning2))); + } - assertThat(wsTask.getWarningCount()).isEqualTo(warningCount); - assertThat(wsTask.getWarningsList()).containsExactly(warnings); + private static List<String> getMessagesText(List<CeTaskMessageDto> ceTaskMessageDtos) { + return ceTaskMessageDtos.stream().map(CeTaskMessageDto::getMessage).toList(); } @Test @@ -273,7 +272,7 @@ public class TaskFormatterTest { assertThat(task.hasErrorStacktrace()).isFalse(); } - private CeActivityDto newActivity(String taskUuid, String componentUuid, CeActivityDto.Status status, @Nullable UserDto user) { + private TestActivityDto newActivity(String taskUuid, String componentUuid, CeActivityDto.Status status, @Nullable UserDto user) { CeQueueDto queueDto = new CeQueueDto() .setCreatedAt(1_450_000_000_000L) .setTaskType(CeTaskTypes.REPORT) @@ -281,14 +280,27 @@ public class TaskFormatterTest { .setSubmitterUuid(user == null ? null : user.getUuid()) .setUuid(taskUuid); TestActivityDto testActivityDto = new TestActivityDto(queueDto); - testActivityDto.setWarningCount(warningCount); - return testActivityDto + + List<CeTaskMessageDto> ceTaskMessageDtos = IntStream.range(0, WARNING_COUNT) + .mapToObj(i -> createCeTaskMessageDto(i, INFO)) + .toList(); + testActivityDto.setCeTaskMessageDtos(ceTaskMessageDtos); + return (TestActivityDto) testActivityDto .setStatus(status) .setNodeName(NODE_NAME) .setExecutionTimeMs(500L) .setAnalysisUuid("U1"); } + private CeTaskMessageDto createCeTaskMessageDto(int i, CeTaskMessageType ceTaskMessageType) { + CeTaskMessageDto ceTaskMessageDto = new CeTaskMessageDto(); + ceTaskMessageDto.setMessage("message_" + i); + ceTaskMessageDto.setCreatedAt(system2.now()); + ceTaskMessageDto.setTaskUuid("uuid_" + i); + ceTaskMessageDto.setType(ceTaskMessageType); + return ceTaskMessageDto; + } + private static class TestActivityDto extends CeActivityDto { public TestActivityDto(CeQueueDto queueDto) { @@ -301,8 +313,8 @@ public class TaskFormatterTest { } @Override - public CeActivityDto setWarningCount(int warningCount) { - return super.setWarningCount(warningCount); + public CeActivityDto setCeTaskMessageDtos(List<CeTaskMessageDto> ceTaskMessageDtos) { + return super.setCeTaskMessageDtos(ceTaskMessageDtos); } } } |