From 12d9bb1c9a523ba995eef45e2ebd6ccce039c746 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Lesaint?= Date: Tue, 16 Aug 2016 19:35:36 +0200 Subject: [PATCH] SONAR-7842 support error message in DAO and CeActivityDto --- .../java/org/sonar/db/ce/CeActivityDto.java | 42 +++++++++ .../org/sonar/db/ce/CeActivityMapper.xml | 58 ++++++++----- .../org/sonar/db/ce/CeActivityDaoTest.java | 86 ++++++++++++++++--- 3 files changed, 152 insertions(+), 34 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 89755133065e..34e4a4237df8 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 @@ -23,6 +23,7 @@ import com.google.common.base.Strings; import javax.annotation.CheckForNull; import javax.annotation.Nullable; +import org.sonar.db.DbSession; import static com.google.common.base.Preconditions.checkArgument; import static java.lang.String.format; @@ -47,6 +48,24 @@ public enum Status { private long createdAt; private long updatedAt; private Long executionTimeMs; + /** + * The error message of the activity. Shall be non null only when status is FAILED. When status is FAILED, can be null + * (eg. for activity created before the column has been introduced). + *

+ * This property is populated when inserting AND when reading + *

+ */ + private String errorMessage; + /** + * The error stacktrace (if any). Shall be non null only when status is FAILED. When status is FAILED, can be null + * because exception such as MessageException do not have a stacktrace (ie. functional exceptions). + *

+ * This property can be populated when inserting but is populated only when reading by a specific UUID. + *

+ * + * @see CeActivityDao#selectByUuid(DbSession, String) + */ + private String errorStacktrace; CeActivityDto() { // required for MyBatis @@ -187,6 +206,27 @@ public CeActivityDto setAnalysisUuid(@Nullable String s) { return this; } + @CheckForNull + public String getErrorMessage() { + return errorMessage; + } + + public CeActivityDto setErrorMessage(@Nullable String errorMessage) { + this.errorMessage = errorMessage; + return this; + } + + @CheckForNull + public String getErrorStacktrace() { + return errorStacktrace; + } + + @CheckForNull + public CeActivityDto setErrorStacktrace(@Nullable String errorStacktrace) { + this.errorStacktrace = errorStacktrace; + return this; + } + @Override public String toString() { return MoreObjects.toStringHelper(this) @@ -204,6 +244,8 @@ public String toString() { .add("createdAt", createdAt) .add("updatedAt", updatedAt) .add("executionTimeMs", executionTimeMs) + .add("errorMessage", errorMessage) + .add("errorStacktrace", errorStacktrace) .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 ac826f15c3cb..d07903498ba2 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 @@ -18,12 +18,14 @@ ca.updated_at as updatedAt, ca.is_last as isLast, ca.is_last_key as isLastKey, - ca.execution_time_ms as executionTimeMs + ca.execution_time_ms as executionTimeMs, + ca.error_message as errorMessage @@ -121,25 +123,41 @@ - insert into ce_activity - (uuid, component_uuid, analysis_uuid, status, task_type, is_last, is_last_key, submitter_login, submitted_at, - started_at, - executed_at, created_at, updated_at, execution_time_ms) + insert into ce_activity ( + uuid, + component_uuid, + analysis_uuid, + status, + task_type, + is_last, + is_last_key, + submitter_login, + submitted_at, + started_at, + executed_at, + created_at, + updated_at, + execution_time_ms, + error_message, + error_stacktrace + ) values ( - #{uuid,jdbcType=VARCHAR}, - #{componentUuid,jdbcType=VARCHAR}, - #{analysisUuid,jdbcType=VARCHAR}, - #{status,jdbcType=VARCHAR}, - #{taskType,jdbcType=VARCHAR}, - #{isLast,jdbcType=BOOLEAN}, - #{isLastKey,jdbcType=VARCHAR}, - #{submitterLogin,jdbcType=VARCHAR}, - #{submittedAt,jdbcType=BIGINT}, - #{startedAt,jdbcType=BIGINT}, - #{executedAt,jdbcType=BIGINT}, - #{createdAt,jdbcType=BIGINT}, - #{updatedAt,jdbcType=BIGINT}, - #{executionTimeMs,jdbcType=BIGINT} + #{uuid,jdbcType=VARCHAR}, + #{componentUuid,jdbcType=VARCHAR}, + #{analysisUuid,jdbcType=VARCHAR}, + #{status,jdbcType=VARCHAR}, + #{taskType,jdbcType=VARCHAR}, + #{isLast,jdbcType=BOOLEAN}, + #{isLastKey,jdbcType=VARCHAR}, + #{submitterLogin,jdbcType=VARCHAR}, + #{submittedAt,jdbcType=BIGINT}, + #{startedAt,jdbcType=BIGINT}, + #{executedAt,jdbcType=BIGINT}, + #{createdAt,jdbcType=BIGINT}, + #{updatedAt,jdbcType=BIGINT}, + #{executionTimeMs,jdbcType=BIGINT}, + #{errorMessage,jdbcType=VARCHAR}, + #{errorStacktrace,jdbcType=CLOB} ) 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 bfff8a777d32..edd626386a21 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 @@ -55,19 +55,45 @@ public void test_insert() { Optional saved = underTest.selectByUuid(db.getSession(), "TASK_1"); assertThat(saved.isPresent()).isTrue(); - assertThat(saved.get().getUuid()).isEqualTo("TASK_1"); - assertThat(saved.get().getComponentUuid()).isEqualTo("PROJECT_1"); - assertThat(saved.get().getStatus()).isEqualTo(CeActivityDto.Status.SUCCESS); - assertThat(saved.get().getSubmitterLogin()).isEqualTo("henri"); - assertThat(saved.get().getIsLast()).isTrue(); - assertThat(saved.get().getIsLastKey()).isEqualTo("REPORTPROJECT_1"); - assertThat(saved.get().getSubmittedAt()).isEqualTo(1_300_000_000_000L); - assertThat(saved.get().getCreatedAt()).isEqualTo(1_450_000_000_000L); - assertThat(saved.get().getStartedAt()).isEqualTo(1_500_000_000_000L); - assertThat(saved.get().getExecutedAt()).isEqualTo(1_500_000_000_500L); - assertThat(saved.get().getExecutionTimeMs()).isEqualTo(500L); - assertThat(saved.get().getAnalysisUuid()).isEqualTo("U1"); - assertThat(saved.get().toString()).isNotEmpty(); + CeActivityDto dto = saved.get(); + assertThat(dto.getUuid()).isEqualTo("TASK_1"); + assertThat(dto.getComponentUuid()).isEqualTo("PROJECT_1"); + assertThat(dto.getStatus()).isEqualTo(CeActivityDto.Status.SUCCESS); + assertThat(dto.getSubmitterLogin()).isEqualTo("henri"); + assertThat(dto.getIsLast()).isTrue(); + assertThat(dto.getIsLastKey()).isEqualTo("REPORTPROJECT_1"); + assertThat(dto.getSubmittedAt()).isEqualTo(1_300_000_000_000L); + assertThat(dto.getCreatedAt()).isEqualTo(1_450_000_000_000L); + 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.toString()).isNotEmpty(); + assertThat(dto.getErrorMessage()).isNull(); + assertThat(dto.getErrorStacktrace()).isNull(); + } + + @Test + public void test_insert_error_message_and_stacktrace() { + CeActivityDto dto = createActivityDto("TASK_1", REPORT, "PROJECT_1", CeActivityDto.Status.FAILED) + .setErrorStacktrace("error stack"); + underTest.insert(db.getSession(), dto); + + Optional saved = underTest.selectByUuid(db.getSession(), "TASK_1"); + CeActivityDto read = saved.get(); + assertThat(read.getErrorMessage()).isEqualTo(dto.getErrorMessage()); + assertThat(read.getErrorStacktrace()).isEqualTo(dto.getErrorStacktrace()); + } + + @Test + public void test_insert_error_message_only() { + CeActivityDto dto = createActivityDto("TASK_1", REPORT, "PROJECT_1", CeActivityDto.Status.FAILED); + underTest.insert(db.getSession(), dto); + + Optional saved = underTest.selectByUuid(db.getSession(), "TASK_1"); + CeActivityDto read = saved.get(); + assertThat(read.getErrorMessage()).isEqualTo(read.getErrorMessage()); + assertThat(read.getErrorStacktrace()).isNull(); } @Test @@ -130,6 +156,18 @@ public void test_selectByQuery() { assertThat(dtos).extracting("uuid").containsExactly("TASK_2"); } + @Test + public void selectByQuery_does_not_populate_errorStacktrace_field() { + insert("TASK_1", REPORT, "PROJECT_1", FAILED); + underTest.insert(db.getSession(), createActivityDto("TASK_2", REPORT, "PROJECT_1", FAILED).setErrorStacktrace("some stack")); + + List dtos = underTest.selectByQuery(db.getSession(), new CeTaskQuery().setComponentUuid("PROJECT_1"), 0, 100); + + assertThat(dtos) + .hasSize(2) + .extracting("errorStacktrace").containsOnly((String) null); + } + @Test public void selectByQuery_is_paginated_and_return_results_sorted_from_last_to_first() { insert("TASK_1", REPORT, "PROJECT_1", CeActivityDto.Status.SUCCESS); @@ -197,6 +235,18 @@ public void selectOlderThan() { assertThat(dtos).extracting("uuid").containsOnly("TASK_1", "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")); + + List dtos = underTest.selectOlderThan(db.getSession(), system2.now() + 1_000_000L); + + assertThat(dtos) + .hasSize(2) + .extracting("errorStacktrace").containsOnly((String) null); + } + @Test public void deleteByUuid() { insert("TASK_1", "REPORT", "COMPONENT1", CeActivityDto.Status.SUCCESS); @@ -234,6 +284,11 @@ public void count_last_by_status_and_component_uuid() { } private void insert(String uuid, String type, String componentUuid, CeActivityDto.Status status) { + CeActivityDto dto = createActivityDto(uuid, type, componentUuid, status); + underTest.insert(db.getSession(), dto); + } + + private CeActivityDto createActivityDto(String uuid, String type, String componentUuid, CeActivityDto.Status status) { CeQueueDto queueDto = new CeQueueDto(); queueDto.setUuid(uuid); queueDto.setTaskType(type); @@ -247,7 +302,10 @@ private void insert(String uuid, String type, String componentUuid, CeActivityDt dto.setExecutedAt(1_500_000_000_500L); dto.setExecutionTimeMs(500L); dto.setAnalysisUuid(AN_ANALYSIS_UUID); - underTest.insert(db.getSession(), dto); + if (status == FAILED) { + dto.setErrorMessage("error msg for " + uuid); + } + return dto; } private void insertWithCreationDate(String uuid, long date) {