diff options
3 files changed, 80 insertions, 17 deletions
diff --git a/sonar-db/src/main/java/org/sonar/db/ce/CeActivityDto.java b/sonar-db/src/main/java/org/sonar/db/ce/CeActivityDto.java index a8646769cf8..ceaf4f1aa36 100644 --- a/sonar-db/src/main/java/org/sonar/db/ce/CeActivityDto.java +++ b/sonar-db/src/main/java/org/sonar/db/ce/CeActivityDto.java @@ -68,6 +68,13 @@ public class CeActivityDto { * @see CeActivityDao#selectByUuid(DbSession, String) */ private String errorStacktrace; + /** + * Flag indicating whether the analysis of the current activity has a scanner context or not. + * <p> + * This property can not be populated when inserting but <strong>is populated when reading</strong>. + * </p> + */ + private boolean hasScannerContext; CeActivityDto() { // required for MyBatis @@ -240,6 +247,14 @@ public class CeActivityDto { return this; } + public boolean isHasScannerContext() { + return hasScannerContext; + } + + protected void setHasScannerContext(boolean hasScannerContext) { + this.hasScannerContext = hasScannerContext; + } + @Override public String toString() { return MoreObjects.toStringHelper(this) @@ -259,6 +274,7 @@ public class CeActivityDto { .add("executionTimeMs", executionTimeMs) .add("errorMessage", errorMessage) .add("errorStacktrace", errorStacktrace) + .add("hasScannerContext", hasScannerContext) .toString(); } } diff --git a/sonar-db/src/main/resources/org/sonar/db/ce/CeActivityMapper.xml b/sonar-db/src/main/resources/org/sonar/db/ce/CeActivityMapper.xml index d07903498ba..b40d037158d 100644 --- a/sonar-db/src/main/resources/org/sonar/db/ce/CeActivityMapper.xml +++ b/sonar-db/src/main/resources/org/sonar/db/ce/CeActivityMapper.xml @@ -3,6 +3,18 @@ <mapper namespace="org.sonar.db.ce.CeActivityMapper"> + + <!--assumes query includes an left left outer join on table scanner_context with alias ct --> + <sql id="hasScannerContextColumn" databaseId="mssql"> + cast(case when ct.analysis_uuid is null then 0 else 1 end as bit) as hasScannerContext + </sql> + <sql id="hasScannerContextColumn" databaseId="oracle"> + case when ct.analysis_uuid is null then 0 else 1 end as hasScannerContext + </sql> + <sql id="hasScannerContextColumn"> + ct.analysis_uuid is not null as hasScannerContext + </sql> + <sql id="columns"> ca.id, ca.uuid, @@ -19,7 +31,8 @@ ca.is_last as isLast, ca.is_last_key as isLastKey, ca.execution_time_ms as executionTimeMs, - ca.error_message as errorMessage + ca.error_message as errorMessage, + <include refid="hasScannerContextColumn"/> </sql> <select id="selectByUuid" parameterType="String" resultType="org.sonar.db.ce.CeActivityDto"> @@ -27,6 +40,7 @@ <include refid="columns"/>, ca.error_stacktrace as errorStacktrace from ce_activity ca + left outer join scanner_context ct on ca.analysis_uuid = ct.analysis_uuid where ca.uuid=#{uuid} </select> @@ -78,6 +92,7 @@ <sql id="sqlSelectByQuery"> from ce_activity ca + left outer join scanner_context ct on ct.analysis_uuid = ca.analysis_uuid <where> <if test="query.onlyCurrents"> and ca.is_last=${_true} @@ -107,15 +122,21 @@ </sql> <select id="selectOlderThan" parameterType="long" resultType="org.sonar.db.ce.CeActivityDto"> - select <include refid="columns"/> + select + <include refid="columns"/> from ce_activity ca - where ca.created_at < #{beforeDate,jdbcType=BIGINT} + left outer join scanner_context ct on ct.analysis_uuid = ca.analysis_uuid + where + ca.created_at < #{beforeDate,jdbcType=BIGINT} </select> <select id="countLastByStatusAndComponentUuid" resultType="int"> - select count(1) - from ce_activity - where status=#{status} + select + count(1) + from + ce_activity + where + status=#{status} and is_last=${_true} <if test="componentUuid!=null"> and component_uuid=#{componentUuid} diff --git a/sonar-db/src/test/java/org/sonar/db/ce/CeActivityDaoTest.java b/sonar-db/src/test/java/org/sonar/db/ce/CeActivityDaoTest.java index fed7575080f..147d5d76fb6 100644 --- a/sonar-db/src/test/java/org/sonar/db/ce/CeActivityDaoTest.java +++ b/sonar-db/src/test/java/org/sonar/db/ce/CeActivityDaoTest.java @@ -53,7 +53,7 @@ public class CeActivityDaoTest { @Test public void test_insert() { - insert("TASK_1", REPORT, "PROJECT_1", CeActivityDto.Status.SUCCESS); + CeActivityDto inserted = insert("TASK_1", REPORT, "PROJECT_1", CeActivityDto.Status.SUCCESS); Optional<CeActivityDto> saved = underTest.selectByUuid(db.getSession(), "TASK_1"); assertThat(saved.isPresent()).isTrue(); @@ -69,16 +69,17 @@ public class CeActivityDaoTest { assertThat(dto.getStartedAt()).isEqualTo(1_500_000_000_000L); assertThat(dto.getExecutedAt()).isEqualTo(1_500_000_000_500L); assertThat(dto.getExecutionTimeMs()).isEqualTo(500L); - assertThat(dto.getAnalysisUuid()).isEqualTo("U1"); + assertThat(dto.getAnalysisUuid()).isEqualTo(inserted.getAnalysisUuid()); assertThat(dto.toString()).isNotEmpty(); assertThat(dto.getErrorMessage()).isNull(); assertThat(dto.getErrorStacktrace()).isNull(); + assertThat(dto.isHasScannerContext()).isFalse(); } @Test public void test_insert_of_errorMessage_of_1_000_chars() { CeActivityDto dto = createActivityDto("TASK_1", REPORT, "PROJECT_1", CeActivityDto.Status.FAILED) - .setErrorMessage(Strings.repeat("x", 1_000)); + .setErrorMessage(Strings.repeat("x", 1_000)); underTest.insert(db.getSession(), dto); Optional<CeActivityDto> saved = underTest.selectByUuid(db.getSession(), "TASK_1"); @@ -89,7 +90,7 @@ public class CeActivityDaoTest { public void test_insert_of_errorMessage_of_1_001_chars_is_truncated_to_1000() { String expected = Strings.repeat("x", 1_000); CeActivityDto dto = createActivityDto("TASK_1", REPORT, "PROJECT_1", CeActivityDto.Status.FAILED) - .setErrorMessage(expected + "y"); + .setErrorMessage(expected + "y"); underTest.insert(db.getSession(), dto); Optional<CeActivityDto> saved = underTest.selectByUuid(db.getSession(), "TASK_1"); @@ -99,7 +100,7 @@ public class CeActivityDaoTest { @Test public void test_insert_error_message_and_stacktrace() { CeActivityDto dto = createActivityDto("TASK_1", REPORT, "PROJECT_1", CeActivityDto.Status.FAILED) - .setErrorStacktrace("error stack"); + .setErrorStacktrace("error stack"); underTest.insert(db.getSession(), dto); Optional<CeActivityDto> saved = underTest.selectByUuid(db.getSession(), "TASK_1"); @@ -187,8 +188,20 @@ public class CeActivityDaoTest { List<CeActivityDto> dtos = underTest.selectByQuery(db.getSession(), new CeTaskQuery().setComponentUuid("PROJECT_1"), 0, 100); assertThat(dtos) - .hasSize(2) - .extracting("errorStacktrace").containsOnly((String) null); + .hasSize(2) + .extracting("errorStacktrace").containsOnly((String) null); + } + + @Test + public void selectByQuery_populates_hasScannerContext_flag() { + insert("TASK_1", REPORT, "PROJECT_1", SUCCESS); + CeActivityDto dto2 = insert("TASK_2", REPORT, "PROJECT_2", SUCCESS); + insertScannerContext(dto2.getAnalysisUuid()); + + CeActivityDto dto = underTest.selectByQuery(db.getSession(), new CeTaskQuery().setComponentUuid("PROJECT_1"), 0, 100).iterator().next(); + assertThat(dto.isHasScannerContext()).isFalse(); + dto = underTest.selectByQuery(db.getSession(), new CeTaskQuery().setComponentUuid("PROJECT_2"), 0, 100).iterator().next(); + assertThat(dto.isHasScannerContext()).isTrue(); } @Test @@ -259,6 +272,17 @@ public class CeActivityDaoTest { } @Test + public void selectOlder_populates_hasScannerContext_flag() { + insertWithCreationDate("TASK_1", 1_450_000_000_000L); + CeActivityDto dto2 = insertWithCreationDate("TASK_2", 1_450_000_000_000L); + insertScannerContext(dto2.getAnalysisUuid()); + + List<CeActivityDto> dtos = underTest.selectOlderThan(db.getSession(), 1_465_000_000_000L); + assertThat(dtos).hasSize(2); + dtos.forEach((dto) -> assertThat(dto.isHasScannerContext()).isEqualTo(dto.getUuid().equals("TASK_2"))); + } + + @Test public void selectOlderThan_does_not_populate_errorStacktrace() { insert("TASK_1", REPORT, "PROJECT_1", FAILED); underTest.insert(db.getSession(), createActivityDto("TASK_2", REPORT, "PROJECT_1", FAILED).setErrorStacktrace("some stack")); @@ -266,8 +290,8 @@ public class CeActivityDaoTest { List<CeActivityDto> dtos = underTest.selectOlderThan(db.getSession(), system2.now() + 1_000_000L); assertThat(dtos) - .hasSize(2) - .extracting("errorStacktrace").containsOnly((String) null); + .hasSize(2) + .extracting("errorStacktrace").containsOnly((String) null); } @Test @@ -306,9 +330,10 @@ public class CeActivityDaoTest { assertThat(underTest.countLastByStatusAndComponentUuid(dbSession, SUCCESS, null)).isEqualTo(2); } - private void insert(String uuid, String type, String componentUuid, CeActivityDto.Status status) { + private CeActivityDto insert(String uuid, String type, String componentUuid, CeActivityDto.Status status) { CeActivityDto dto = createActivityDto(uuid, type, componentUuid, status); underTest.insert(db.getSession(), dto); + return dto; } private CeActivityDto createActivityDto(String uuid, String type, String componentUuid, CeActivityDto.Status status) { @@ -324,7 +349,7 @@ public class CeActivityDaoTest { dto.setStartedAt(1_500_000_000_000L); dto.setExecutedAt(1_500_000_000_500L); dto.setExecutionTimeMs(500L); - dto.setAnalysisUuid(AN_ANALYSIS_UUID); + dto.setAnalysisUuid(uuid + "_2"); if (status == FAILED) { dto.setErrorMessage("error msg for " + uuid); } @@ -338,6 +363,7 @@ public class CeActivityDaoTest { CeActivityDto dto = new CeActivityDto(queueDto); dto.setStatus(CeActivityDto.Status.SUCCESS); + dto.setAnalysisUuid(uuid + "_AA"); system2.setNow(date); underTest.insert(db.getSession(), dto); return dto; |