Browse Source

SONAR-7691 table CE_ACTIVITY should use analysis UUID

tags/6.0-RC1
Simon Brandhof 8 years ago
parent
commit
d1349c48d4
37 changed files with 687 additions and 108 deletions
  1. 3
    4
      server/sonar-server/src/main/java/org/sonar/ce/queue/CeTaskResult.java
  2. 2
    2
      server/sonar-server/src/main/java/org/sonar/server/ce/ws/TaskFormatter.java
  3. 3
    3
      server/sonar-server/src/main/java/org/sonar/server/computation/queue/InternalCeQueueImpl.java
  4. 11
    14
      server/sonar-server/src/main/java/org/sonar/server/computation/step/PublishTaskResultStep.java
  5. 8
    19
      server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/ProjectStatusAction.java
  6. 8
    0
      server/sonar-server/src/main/java/org/sonar/server/ws/WsUtils.java
  7. 4
    5
      server/sonar-server/src/test/java/org/sonar/server/ce/ws/ActivityActionTest.java
  8. 4
    4
      server/sonar-server/src/test/java/org/sonar/server/ce/ws/ComponentActionTest.java
  9. 5
    5
      server/sonar-server/src/test/java/org/sonar/server/ce/ws/TaskActionTest.java
  10. 4
    4
      server/sonar-server/src/test/java/org/sonar/server/ce/ws/TaskFormatterTest.java
  11. 9
    8
      server/sonar-server/src/test/java/org/sonar/server/computation/queue/InternalCeQueueImplTest.java
  12. 8
    15
      server/sonar-server/src/test/java/org/sonar/server/computation/step/PublishTaskResultStepTest.java
  13. 6
    5
      server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/ProjectStatusActionTest.java
  14. 29
    0
      server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1232_add_analysis_uuid_column_to_ce_activity.rb
  15. 29
    0
      server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1233_populate_analysis_uuid_column_on_ce_activity.rb
  16. 29
    0
      server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1234_drop_snapshot_id_column_from_ce_activity.rb
  17. 6
    5
      sonar-db/src/main/java/org/sonar/db/ce/CeActivityDto.java
  18. 13
    0
      sonar-db/src/main/java/org/sonar/db/component/SnapshotDao.java
  19. 2
    0
      sonar-db/src/main/java/org/sonar/db/component/SnapshotMapper.java
  20. 1
    1
      sonar-db/src/main/java/org/sonar/db/version/DatabaseVersion.java
  21. 10
    2
      sonar-db/src/main/java/org/sonar/db/version/MigrationStepModule.java
  22. 45
    0
      sonar-db/src/main/java/org/sonar/db/version/v60/AddAnalysisUuidColumnToCeActivity.java
  23. 44
    0
      sonar-db/src/main/java/org/sonar/db/version/v60/DropSnapshotIdColumnFromCeActivity.java
  24. 54
    0
      sonar-db/src/main/java/org/sonar/db/version/v60/PopulateAnalysisUuidColumnOnCeActivity.java
  25. 4
    3
      sonar-db/src/main/resources/org/sonar/db/ce/CeActivityMapper.xml
  26. 7
    0
      sonar-db/src/main/resources/org/sonar/db/component/SnapshotMapper.xml
  27. 3
    0
      sonar-db/src/main/resources/org/sonar/db/version/rows-h2.sql
  28. 1
    1
      sonar-db/src/main/resources/org/sonar/db/version/schema-h2.ddl
  29. 4
    2
      sonar-db/src/test/java/org/sonar/db/ce/CeActivityDaoTest.java
  30. 14
    5
      sonar-db/src/test/java/org/sonar/db/component/SnapshotDaoTest.java
  31. 1
    1
      sonar-db/src/test/java/org/sonar/db/version/MigrationStepModuleTest.java
  32. 84
    0
      sonar-db/src/test/java/org/sonar/db/version/v60/AddAnalysisUuidColumnToCeActivityTest.java
  33. 47
    0
      sonar-db/src/test/java/org/sonar/db/version/v60/DropSnapshotIdColumnFromCeActivityTest.java
  34. 115
    0
      sonar-db/src/test/java/org/sonar/db/version/v60/PopulateAnalysisUuidColumnOnCeActivityTest.java
  35. 17
    0
      sonar-db/src/test/resources/org/sonar/db/version/v60/AddAnalysisUuidColumnToCeActivityTest/old_ce_activity.sql
  36. 1
    0
      sonar-db/src/test/resources/org/sonar/db/version/v60/AddComponentUuidColumnsToSnapshotsTest/old_snapshots.sql
  37. 52
    0
      sonar-db/src/test/resources/org/sonar/db/version/v60/PopulateAnalysisUuidColumnOnCeActivityTest/in_progress_ce_activity.sql

+ 3
- 4
server/sonar-server/src/main/java/org/sonar/ce/queue/CeTaskResult.java View File

@@ -19,7 +19,7 @@
*/
package org.sonar.ce.queue;

import javax.annotation.CheckForNull;
import java.util.Optional;
import org.sonar.ce.taskprocessor.CeTaskProcessor;

/**
@@ -30,8 +30,7 @@ import org.sonar.ce.taskprocessor.CeTaskProcessor;
@FunctionalInterface
public interface CeTaskResult {
/**
* The id of the snapshot created, if any, for the Component in {@link CeTask}
* The UUID of the analysis created, if any, for the Component in {@link CeTask}
*/
@CheckForNull
Long getSnapshotId();
Optional<String> getAnalysisUuid();
}

+ 2
- 2
server/sonar-server/src/main/java/org/sonar/server/ce/ws/TaskFormatter.java View File

@@ -111,8 +111,8 @@ public class TaskFormatter {
builder.setComponentId(dto.getComponentUuid());
buildComponent(builder, componentDtoCache.get(dto.getComponentUuid()));
}
if (dto.getSnapshotId() != null) {
builder.setAnalysisId(String.valueOf(dto.getSnapshotId()));
if (dto.getAnalysisUuid() != null) {
builder.setAnalysisId(dto.getAnalysisUuid());
}
if (dto.getSubmitterLogin() != null) {
builder.setSubmitterLogin(dto.getSubmitterLogin());

+ 3
- 3
server/sonar-server/src/main/java/org/sonar/server/computation/queue/InternalCeQueueImpl.java View File

@@ -101,9 +101,9 @@ public class InternalCeQueueImpl extends CeQueueImpl implements InternalCeQueue

private static void updateTaskResult(CeActivityDto activityDto, @Nullable CeTaskResult taskResult) {
if (taskResult != null) {
Long snapshotId = taskResult.getSnapshotId();
if (snapshotId != null) {
activityDto.setSnapshotId(snapshotId);
java.util.Optional<String> analysisUuid = taskResult.getAnalysisUuid();
if (analysisUuid.isPresent()) {
activityDto.setAnalysisUuid(analysisUuid.get());
}
}
}

+ 11
- 14
server/sonar-server/src/main/java/org/sonar/server/computation/step/PublishTaskResultStep.java View File

@@ -19,21 +19,19 @@
*/
package org.sonar.server.computation.step;

import java.util.Optional;
import javax.annotation.concurrent.Immutable;
import org.sonar.server.computation.component.DbIdsRepository;
import org.sonar.server.computation.component.TreeRootHolder;
import org.sonar.ce.queue.CeTaskResult;
import org.sonar.server.computation.analysis.AnalysisMetadataHolder;
import org.sonar.server.computation.taskprocessor.MutableTaskResultHolder;

public class PublishTaskResultStep implements ComputationStep {
private final MutableTaskResultHolder taskResultHolder;
private final TreeRootHolder treeRootHolder;
private final DbIdsRepository dbIdsRepository;
private final AnalysisMetadataHolder analysisMetadataHolder;

public PublishTaskResultStep(MutableTaskResultHolder taskResultHolder, TreeRootHolder treeRootHolder, DbIdsRepository dbIdsRepository) {
public PublishTaskResultStep(MutableTaskResultHolder taskResultHolder, AnalysisMetadataHolder analysisMetadataHolder) {
this.taskResultHolder = taskResultHolder;
this.treeRootHolder = treeRootHolder;
this.dbIdsRepository = dbIdsRepository;
this.analysisMetadataHolder = analysisMetadataHolder;
}

@Override
@@ -43,21 +41,20 @@ public class PublishTaskResultStep implements ComputationStep {

@Override
public void execute() {
long snapshotId = dbIdsRepository.getSnapshotId(treeRootHolder.getRoot());
taskResultHolder.setResult(new CeTaskResultImpl(snapshotId));
taskResultHolder.setResult(new CeTaskResultImpl(analysisMetadataHolder.getUuid()));
}

@Immutable
private static class CeTaskResultImpl implements CeTaskResult {
private final long snapshotId;
private final String analysisUuid;

public CeTaskResultImpl(long snapshotId) {
this.snapshotId = snapshotId;
public CeTaskResultImpl(String analysisUuid) {
this.analysisUuid = analysisUuid;
}

@Override
public Long getSnapshotId() {
return snapshotId;
public Optional<String> getAnalysisUuid() {
return Optional.of(analysisUuid);
}
}
}

+ 8
- 19
server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/ProjectStatusAction.java View File

@@ -49,7 +49,7 @@ import org.sonarqube.ws.client.qualitygate.ProjectStatusWsRequest;

import static com.google.common.base.Strings.isNullOrEmpty;
import static org.sonar.server.user.AbstractUserSession.insufficientPrivilegesException;
import static org.sonar.server.ws.WsUtils.checkFound;
import static org.sonar.server.ws.WsUtils.checkFoundWithOptional;
import static org.sonar.server.ws.WsUtils.checkRequest;
import static org.sonar.server.ws.WsUtils.writeProtobuf;
import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.PARAM_ANALYSIS_ID;
@@ -97,7 +97,7 @@ public class ProjectStatusAction implements QGateWsAction {

action.createParam(PARAM_ANALYSIS_ID)
.setDescription("Analysis id")
.setExampleValue("2963");
.setExampleValue(Uuids.UUID_EXAMPLE_04);

action.createParam(PARAM_PROJECT_ID)
.setSince("5.4")
@@ -132,9 +132,9 @@ public class ProjectStatusAction implements QGateWsAction {
}

private ProjectAndSnapshot getProjectAndSnapshot(DbSession dbSession, ProjectStatusWsRequest request) {
String snapshotId = request.getAnalysisId();
String analysisUuid = request.getAnalysisId();
if (!isNullOrEmpty(request.getAnalysisId())) {
return getSnapshotThenProject(dbSession, snapshotId);
return getSnapshotThenProject(dbSession, analysisUuid);
} else if (!isNullOrEmpty(request.getProjectId()) ^ !isNullOrEmpty(request.getProjectKey())) {
return getProjectThenSnapshot(dbSession, request);
}
@@ -154,20 +154,9 @@ public class ProjectStatusAction implements QGateWsAction {
return new ProjectAndSnapshot(projectDto, snapshotDto);
}

private SnapshotDto getSnapshot(DbSession dbSession, String snapshotIdFromRequest) {
Long snapshotId = null;
try {
snapshotId = Long.parseLong(snapshotIdFromRequest);
} catch (NumberFormatException e) {
// checks String is a long
}

SnapshotDto snapshotDto = null;
if (snapshotId != null) {
snapshotDto = dbClient.snapshotDao().selectById(dbSession, snapshotId);
}

return checkFound(snapshotDto, "Analysis with id '%s' is not found", snapshotIdFromRequest);
private SnapshotDto getSnapshot(DbSession dbSession, String analysisUuidFromRequest) {
java.util.Optional<SnapshotDto> snapshotDto = dbClient.snapshotDao().selectByUuid(dbSession, analysisUuidFromRequest);
return checkFoundWithOptional(snapshotDto, "Analysis with id '%s' is not found", analysisUuidFromRequest);
}

private Optional<String> getQualityGateDetailsMeasureData(DbSession dbSession, Optional<SnapshotDto> snapshotDto) {
@@ -179,7 +168,7 @@ public class ProjectStatusAction implements QGateWsAction {
Collections.singleton(CoreMetrics.QUALITY_GATE_DETAILS_KEY), dbSession);

return measures.isEmpty()
? Optional.<String>absent()
? Optional.absent()
: Optional.fromNullable(measures.get(0).getData());
}


+ 8
- 0
server/sonar-server/src/main/java/org/sonar/server/ws/WsUtils.java View File

@@ -99,4 +99,12 @@ public class WsUtils {

return value.get();
}

public static <T> T checkFoundWithOptional(java.util.Optional<T> value, String message, Object... messageArguments) {
if (!value.isPresent()) {
throw new NotFoundException(format(message, messageArguments));
}

return value.get();
}
}

+ 4
- 5
server/sonar-server/src/test/java/org/sonar/server/ce/ws/ActivityActionTest.java View File

@@ -22,7 +22,6 @@ package org.sonar.server.ce.ws;

import com.google.common.base.Optional;
import com.google.common.base.Throwables;
import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.Date;
@@ -89,7 +88,7 @@ public class ActivityActionTest {

@Before
public void setUp() {
when(ceLogging.getFile(any(LogFileRef.class))).thenReturn(Optional.<File>absent());
when(ceLogging.getFile(any(LogFileRef.class))).thenReturn(Optional.absent());
}

@Test
@@ -106,7 +105,7 @@ public class ActivityActionTest {
assertThat(activityResponse.getTasks(0).getId()).isEqualTo("T2");
assertThat(activityResponse.getTasks(0).getStatus()).isEqualTo(WsCe.TaskStatus.FAILED);
assertThat(activityResponse.getTasks(0).getComponentId()).isEqualTo("PROJECT_2");
assertThat(activityResponse.getTasks(0).getAnalysisId()).isEqualTo("123456");
assertThat(activityResponse.getTasks(0).getAnalysisId()).isEqualTo("U1");
assertThat(activityResponse.getTasks(0).getExecutionTimeMs()).isEqualTo(500L);
assertThat(activityResponse.getTasks(0).getLogs()).isFalse();
assertThat(activityResponse.getTasks(1).getId()).isEqualTo("T1");
@@ -182,7 +181,7 @@ public class ActivityActionTest {
assertPage(1, asList("T3"));
assertPage(2, asList("T3", "T2"));
assertPage(10, asList("T3", "T2", "T1"));
assertPage(0, Collections.<String>emptyList());
assertPage(0, Collections.emptyList());
}

private void assertPage(int pageSize, List<String> expectedOrderedTaskIds) {
@@ -364,7 +363,7 @@ public class ActivityActionTest {
activityDto.setStatus(status);
activityDto.setExecutionTimeMs(500L);
activityDto.setExecutedAt(EXECUTED_AT);
activityDto.setSnapshotId(123_456L);
activityDto.setAnalysisUuid("U1");
dbTester.getDbClient().ceActivityDao().insert(dbTester.getSession(), activityDto);
dbTester.commit();
return activityDto;

+ 4
- 4
server/sonar-server/src/test/java/org/sonar/server/ce/ws/ComponentActionTest.java View File

@@ -26,17 +26,17 @@ import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.utils.System2;
import org.sonar.api.web.UserRole;
import org.sonar.ce.log.CeLogging;
import org.sonar.ce.log.LogFileRef;
import org.sonar.core.util.Protobuf;
import org.sonar.db.DbTester;
import org.sonar.db.ce.CeActivityDto;
import org.sonar.db.ce.CeQueueDto;
import org.sonar.db.ce.CeTaskTypes;
import org.sonar.ce.log.CeLogging;
import org.sonar.ce.log.LogFileRef;
import org.sonarqube.ws.MediaTypes;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.TestResponse;
import org.sonar.server.ws.WsActionTester;
import org.sonarqube.ws.MediaTypes;
import org.sonarqube.ws.WsCe;

import static org.assertj.core.api.Assertions.assertThat;
@@ -139,7 +139,7 @@ public class ComponentActionTest {
CeActivityDto activityDto = new CeActivityDto(queueDto);
activityDto.setStatus(status);
activityDto.setExecutionTimeMs(500L);
activityDto.setSnapshotId(123_456L);
activityDto.setAnalysisUuid("U1");
dbTester.getDbClient().ceActivityDao().insert(dbTester.getSession(), activityDto);
dbTester.getSession().commit();
return activityDto;

+ 5
- 5
server/sonar-server/src/test/java/org/sonar/server/ce/ws/TaskActionTest.java View File

@@ -26,6 +26,8 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.utils.System2;
import org.sonar.ce.log.CeLogging;
import org.sonar.ce.log.LogFileRef;
import org.sonar.core.util.Protobuf;
import org.sonar.db.DbTester;
import org.sonar.db.ce.CeActivityDto;
@@ -33,8 +35,6 @@ import org.sonar.db.ce.CeQueueDto;
import org.sonar.db.ce.CeTaskTypes;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.ComponentTesting;
import org.sonar.ce.log.CeLogging;
import org.sonar.ce.log.LogFileRef;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.tester.UserSessionRule;
@@ -118,7 +118,7 @@ public class TaskActionTest {
CeActivityDto activityDto = new CeActivityDto(queueDto);
activityDto.setStatus(CeActivityDto.Status.FAILED);
activityDto.setExecutionTimeMs(500L);
activityDto.setSnapshotId(123_456L);
activityDto.setAnalysisUuid("U1");
dbTester.getDbClient().ceActivityDao().insert(dbTester.getSession(), activityDto);
dbTester.commit();

@@ -134,7 +134,7 @@ public class TaskActionTest {
assertThat(task.getComponentId()).isEqualTo(PROJECT.uuid());
assertThat(task.getComponentKey()).isEqualTo(PROJECT.key());
assertThat(task.getComponentName()).isEqualTo(PROJECT.name());
assertThat(task.getAnalysisId()).isEqualTo("123456");
assertThat(task.getAnalysisId()).isEqualTo("U1");
assertThat(task.getExecutionTimeMs()).isEqualTo(500L);
assertThat(task.getLogs()).isFalse();
}
@@ -230,7 +230,7 @@ public class TaskActionTest {
CeActivityDto activityDto = new CeActivityDto(queueDto);
activityDto.setStatus(CeActivityDto.Status.FAILED);
activityDto.setExecutionTimeMs(500L);
activityDto.setSnapshotId(123_456L);
activityDto.setAnalysisUuid("U1");
activityDto.setComponentUuid(PROJECT.uuid());
dbTester.getDbClient().ceActivityDao().insert(dbTester.getSession(), activityDto);
dbTester.commit();

+ 4
- 4
server/sonar-server/src/test/java/org/sonar/server/ce/ws/TaskFormatterTest.java View File

@@ -29,13 +29,13 @@ import org.mockito.Mockito;
import org.sonar.api.resources.Qualifiers;
import org.sonar.api.utils.DateUtils;
import org.sonar.api.utils.System2;
import org.sonar.ce.log.CeLogging;
import org.sonar.ce.log.LogFileRef;
import org.sonar.db.DbTester;
import org.sonar.db.ce.CeActivityDto;
import org.sonar.db.ce.CeQueueDto;
import org.sonar.db.ce.CeTaskTypes;
import org.sonar.db.component.ComponentDto;
import org.sonar.ce.log.CeLogging;
import org.sonar.ce.log.LogFileRef;
import org.sonarqube.ws.WsCe;

import static java.util.Arrays.asList;
@@ -176,7 +176,7 @@ public class TaskFormatterTest {
assertThat(wsTask.getLogs()).isFalse();
assertThat(wsTask.getSubmittedAt()).isEqualTo(DateUtils.formatDateTime(new Date(1_450_000_000_000L)));
assertThat(wsTask.getExecutionTimeMs()).isEqualTo(500L);
assertThat(wsTask.getAnalysisId()).isEqualTo("123456");
assertThat(wsTask.getAnalysisId()).isEqualTo("U1");
assertThat(wsTask.getLogs()).isFalse();
}

@@ -209,7 +209,7 @@ public class TaskFormatterTest {
CeActivityDto activityDto = new CeActivityDto(queueDto);
activityDto.setStatus(status);
activityDto.setExecutionTimeMs(500L);
activityDto.setSnapshotId(123_456L);
activityDto.setAnalysisUuid("U1");
return activityDto;
}
}

+ 9
- 8
server/sonar-server/src/test/java/org/sonar/server/computation/queue/InternalCeQueueImplTest.java View File

@@ -55,6 +55,8 @@ import static org.mockito.Mockito.when;

public class InternalCeQueueImplTest {

private static final String AN_ANALYSIS_UUID = "U1";

@Rule
public ExpectedException expectedException = ExpectedException.none();

@@ -149,13 +151,13 @@ public class InternalCeQueueImplTest {
assertThat(history.isPresent()).isTrue();
assertThat(history.get().getStatus()).isEqualTo(CeActivityDto.Status.SUCCESS);
assertThat(history.get().getIsLast()).isTrue();
assertThat(history.get().getSnapshotId()).isNull();
assertThat(history.get().getAnalysisUuid()).isNull();

verify(listener).onRemoved(task, CeActivityDto.Status.SUCCESS);
}

@Test
public void remove_does_not_set_snapshotId_in_CeActivity_when_CeTaskResult_has_no_snapshot_id() {
public void remove_does_not_set_analysisUuid_in_CeActivity_when_CeTaskResult_has_no_analysis_uuid() {
CeTask task = submit(CeTaskTypes.REPORT, "PROJECT_1");
Optional<CeTask> peek = underTest.peek();
underTest.remove(peek.get(), CeActivityDto.Status.SUCCESS, newTaskResult(null));
@@ -163,21 +165,20 @@ public class InternalCeQueueImplTest {
// available in history
Optional<CeActivityDto> history = dbTester.getDbClient().ceActivityDao().selectByUuid(dbTester.getSession(), task.getUuid());
assertThat(history.isPresent()).isTrue();
assertThat(history.get().getSnapshotId()).isNull();
assertThat(history.get().getAnalysisUuid()).isNull();
}

@Test
public void remove_sets_snapshotId_in_CeActivity_when_CeTaskResult_has_no_snapshot_id() {
CeTask task = submit(CeTaskTypes.REPORT, "PROJECT_1");
long snapshotId = 663L;

Optional<CeTask> peek = underTest.peek();
underTest.remove(peek.get(), CeActivityDto.Status.SUCCESS, newTaskResult(snapshotId));
underTest.remove(peek.get(), CeActivityDto.Status.SUCCESS, newTaskResult(AN_ANALYSIS_UUID));

// available in history
Optional<CeActivityDto> history = dbTester.getDbClient().ceActivityDao().selectByUuid(dbTester.getSession(), task.getUuid());
assertThat(history.isPresent()).isTrue();
assertThat(history.get().getSnapshotId()).isEqualTo(snapshotId);
assertThat(history.get().getAnalysisUuid()).isEqualTo("U1");
}

@Test
@@ -326,9 +327,9 @@ public class InternalCeQueueImplTest {
return submission.build();
}

private CeTaskResult newTaskResult(Long snapshotId) {
private CeTaskResult newTaskResult(@Nullable String analysisUuid) {
CeTaskResult taskResult = mock(CeTaskResult.class);
when(taskResult.getSnapshotId()).thenReturn(snapshotId);
when(taskResult.getAnalysisUuid()).thenReturn(java.util.Optional.ofNullable(analysisUuid));
return taskResult;
}


+ 8
- 15
server/sonar-server/src/test/java/org/sonar/server/computation/step/PublishTaskResultStepTest.java View File

@@ -21,27 +21,22 @@ package org.sonar.server.computation.step;

import org.junit.Rule;
import org.junit.Test;
import org.sonar.server.computation.batch.TreeRootHolderRule;
import org.sonar.server.computation.component.Component;
import org.sonar.server.computation.component.DbIdsRepository;
import org.sonar.server.computation.analysis.MutableAnalysisMetadataHolderRule;
import org.sonar.server.computation.taskprocessor.MutableTaskResultHolder;
import org.sonar.server.computation.taskprocessor.MutableTaskResultHolderImpl;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class PublishTaskResultStepTest {
private static final Component ROOT_COMPONENT = mock(Component.class);

@Rule
public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule()
.setRoot(ROOT_COMPONENT);
private static final String AN_ANALYSIS_UUID = "U1";

private DbIdsRepository dbIdsRepository = mock(DbIdsRepository.class);
private MutableTaskResultHolder taskResultHolder = new MutableTaskResultHolderImpl();

private PublishTaskResultStep underTest = new PublishTaskResultStep(taskResultHolder, treeRootHolder, dbIdsRepository);
@Rule
public MutableAnalysisMetadataHolderRule analysisMetadataHolder = new MutableAnalysisMetadataHolderRule();

private PublishTaskResultStep underTest = new PublishTaskResultStep(taskResultHolder, analysisMetadataHolder);

@Test
public void verify_getDescription() {
@@ -50,12 +45,10 @@ public class PublishTaskResultStepTest {

@Test
public void execute_populate_TaskResultHolder_with_a_TaskResult_with_snapshot_id_of_the_root_taken_from_DbIdsRepository() {
long snapshotId = 1233L;

when(dbIdsRepository.getSnapshotId(ROOT_COMPONENT)).thenReturn(snapshotId);
analysisMetadataHolder.setUuid(AN_ANALYSIS_UUID);

underTest.execute();

assertThat(taskResultHolder.getResult().getSnapshotId()).isEqualTo(snapshotId);
assertThat(taskResultHolder.getResult().getAnalysisUuid().get()).isEqualTo(AN_ANALYSIS_UUID);
}
}

+ 6
- 5
server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/ProjectStatusActionTest.java View File

@@ -60,6 +60,7 @@ import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.PARAM

public class ProjectStatusActionTest {
private static final String ANALYSIS_ID = "task-uuid";

@Rule
public ExpectedException expectedException = ExpectedException.none();
@Rule
@@ -103,7 +104,7 @@ public class ProjectStatusActionTest {
dbSession.commit();

String response = ws.newRequest()
.setParam("analysisId", snapshot.getId().toString())
.setParam("analysisId", snapshot.getUuid())
.execute().getInput();

assertJson(response).isSimilarTo(getClass().getResource("project_status-example.json"));
@@ -175,7 +176,7 @@ public class ProjectStatusActionTest {
SnapshotDto snapshot = dbClient.snapshotDao().insert(dbSession, newSnapshotForProject(project));
dbSession.commit();

ProjectStatusWsResponse result = call(snapshot.getId().toString());
ProjectStatusWsResponse result = call(snapshot.getUuid());

assertThat(result.getProjectStatus().getStatus()).isEqualTo(Status.NONE);
assertThat(result.getProjectStatus().getConditionsCount()).isEqualTo(0);
@@ -200,7 +201,7 @@ public class ProjectStatusActionTest {
SnapshotDto snapshot = dbClient.snapshotDao().insert(dbSession, newSnapshotForProject(project));
dbSession.commit();

call(snapshot.getId().toString());
call(snapshot.getUuid());
}

@Test
@@ -211,7 +212,7 @@ public class ProjectStatusActionTest {
SnapshotDto snapshot = dbClient.snapshotDao().insert(dbSession, newSnapshotForProject(project));
dbSession.commit();

call(snapshot.getId().toString());
call(snapshot.getUuid());
}

@Test
@@ -233,7 +234,7 @@ public class ProjectStatusActionTest {
dbSession.commit();

expectedException.expect(ForbiddenException.class);
call(snapshot.getId().toString());
call(snapshot.getUuid());
}

@Test

+ 29
- 0
server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1232_add_analysis_uuid_column_to_ce_activity.rb View File

@@ -0,0 +1,29 @@
#
# SonarQube, open source software quality management tool.
# Copyright (C) 2008-2014 SonarSource
# mailto:contact AT sonarsource DOT com
#
# SonarQube is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 3 of the License, or (at your option) any later version.
#
# SonarQube is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#

#
# SonarQube 6.0
#
class AddAnalysisUuidColumnToCeActivity < ActiveRecord::Migration

def self.up
execute_java_migration('org.sonar.db.version.v60.AddAnalysisUuidColumnToCeActivity')
end
end

+ 29
- 0
server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1233_populate_analysis_uuid_column_on_ce_activity.rb View File

@@ -0,0 +1,29 @@
#
# SonarQube, open source software quality management tool.
# Copyright (C) 2008-2014 SonarSource
# mailto:contact AT sonarsource DOT com
#
# SonarQube is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 3 of the License, or (at your option) any later version.
#
# SonarQube is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#

#
# SonarQube 6.0
#
class PopulateAnalysisUuidColumnOnCeActivity < ActiveRecord::Migration

def self.up
execute_java_migration('org.sonar.db.version.v60.PopulateAnalysisUuidColumnOnCeActivity')
end
end

+ 29
- 0
server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1234_drop_snapshot_id_column_from_ce_activity.rb View File

@@ -0,0 +1,29 @@
#
# SonarQube, open source software quality management tool.
# Copyright (C) 2008-2014 SonarSource
# mailto:contact AT sonarsource DOT com
#
# SonarQube is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 3 of the License, or (at your option) any later version.
#
# SonarQube is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#

#
# SonarQube 6.0
#
class DropSnapshotIdColumnFromCeActivity < ActiveRecord::Migration

def self.up
execute_java_migration('org.sonar.db.version.v60.DropSnapshotIdColumnFromCeActivity')
end
end

+ 6
- 5
sonar-db/src/main/java/org/sonar/db/ce/CeActivityDto.java View File

@@ -35,7 +35,7 @@ public class CeActivityDto {

private String uuid;
private String componentUuid;
private Long snapshotId;
private String analysisUuid;
private Status status;
private String taskType;
private boolean isLast;
@@ -178,12 +178,12 @@ public class CeActivityDto {
}

@CheckForNull
public Long getSnapshotId() {
return snapshotId;
public String getAnalysisUuid() {
return analysisUuid;
}

public CeActivityDto setSnapshotId(@Nullable Long snapshotId) {
this.snapshotId = snapshotId;
public CeActivityDto setAnalysisUuid(@Nullable String s) {
this.analysisUuid = s;
return this;
}

@@ -193,6 +193,7 @@ public class CeActivityDto {
.add("uuid", uuid)
.add("taskType", taskType)
.add("componentUuid", componentUuid)
.add("analysisUuid", analysisUuid)
.add("status", status)
.add("isLast", isLast)
.add("isLastKey", isLastKey)

+ 13
- 0
sonar-db/src/main/java/org/sonar/db/component/SnapshotDao.java View File

@@ -23,6 +23,7 @@ import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.apache.ibatis.session.RowBounds;
@@ -42,11 +43,19 @@ public class SnapshotDao implements Dao {
return previousLastSnapshot == null || previousLastSnapshot.getCreatedAt() < snapshotTested.getCreatedAt();
}

/**
* @deprecated use {@link #selectByUuid(DbSession, String)}
*/
@Deprecated
@CheckForNull
public SnapshotDto selectById(DbSession session, long id) {
return mapper(session).selectByKey(id);
}

/**
* @deprecated use {@link #selectByUuid(DbSession, String)}
*/
@Deprecated
public SnapshotDto selectOrFailById(DbSession session, long id) {
SnapshotDto value = selectById(session, id);
if (value == null) {
@@ -100,6 +109,10 @@ public class SnapshotDao implements Dao {
return mapper(session).selectSnapshotAndChildrenOfScope(snapshotId, Scopes.PROJECT);
}

public Optional<SnapshotDto> selectByUuid(DbSession dbSession, String analysisUuid) {
return Optional.ofNullable(mapper(dbSession).selectByUuid(analysisUuid));
}

public int updateSnapshotAndChildrenLastFlagAndStatus(DbSession session, SnapshotDto snapshot, boolean isLast, String status) {
Long rootId = snapshot.getId();
String path = Strings.nullToEmpty(snapshot.getPath()) + snapshot.getId() + ".%";

+ 2
- 0
sonar-db/src/main/java/org/sonar/db/component/SnapshotMapper.java View File

@@ -56,4 +56,6 @@ public interface SnapshotMapper {

List<ViewsSnapshotDto> selectSnapshotBefore(@Param("componentUuid") String componentUuid, @Param("date") long date);

@CheckForNull
SnapshotDto selectByUuid(String analysisUuid);
}

+ 1
- 1
sonar-db/src/main/java/org/sonar/db/version/DatabaseVersion.java View File

@@ -30,7 +30,7 @@ import org.sonar.db.MyBatis;

public class DatabaseVersion {

public static final int LAST_VERSION = 1_231;
public static final int LAST_VERSION = 1_234;

/**
* The minimum supported version which can be upgraded. Lower

+ 10
- 2
sonar-db/src/main/java/org/sonar/db/version/MigrationStepModule.java View File

@@ -83,6 +83,7 @@ import org.sonar.db.version.v55.FeedRulesLongDateColumns;
import org.sonar.db.version.v55.FeedRulesTypes;
import org.sonar.db.version.v56.FixLengthOfIssuesMessageOnOracle;
import org.sonar.db.version.v56.FixTypeOfRuleTypeOnMysql;
import org.sonar.db.version.v60.AddAnalysisUuidColumnToCeActivity;
import org.sonar.db.version.v60.AddComponentUuidColumnToMeasures;
import org.sonar.db.version.v60.AddComponentUuidColumnsToSnapshots;
import org.sonar.db.version.v60.AddUuidColumnToSnapshots;
@@ -97,17 +98,19 @@ import org.sonar.db.version.v60.DropIdColumnsFromResourceIndex;
import org.sonar.db.version.v60.DropIdColumnsFromSnapshots;
import org.sonar.db.version.v60.DropProjectIdColumnFromMeasures;
import org.sonar.db.version.v60.DropRememberMeColumnsFromUsers;
import org.sonar.db.version.v60.DropSnapshotIdColumnFromCeActivity;
import org.sonar.db.version.v60.DropUnusedMeasuresColumns;
import org.sonar.db.version.v60.MakeComponentUuidColumnsNotNullOnSnapshots;
import org.sonar.db.version.v60.MakeComponentUuidNotNullOnMeasures;
import org.sonar.db.version.v60.MakeUuidColumnNotNullOnSnapshots;
import org.sonar.db.version.v60.MakeUuidColumnsNotNullOnProjects;
import org.sonar.db.version.v60.MakeUuidColumnsNotNullOnResourceIndex;
import org.sonar.db.version.v60.PopulateAnalysisUuidColumnOnCeActivity;
import org.sonar.db.version.v60.PopulateComponentUuidColumnsOfSnapshots;
import org.sonar.db.version.v60.PopulateComponentUuidOfMeasures;
import org.sonar.db.version.v60.PopulateUuidColumnOnSnapshots;
import org.sonar.db.version.v60.PopulateUuidColumnsOfProjects;
import org.sonar.db.version.v60.PopulateUuidColumnsOfResourceIndex;
import org.sonar.db.version.v60.PopulateComponentUuidColumnsOfSnapshots;

public class MigrationStepModule extends Module {
@Override
@@ -219,7 +222,12 @@ public class MigrationStepModule extends Module {
// SNAPSHOTS.UUID
AddUuidColumnToSnapshots.class,
PopulateUuidColumnOnSnapshots.class,
MakeUuidColumnNotNullOnSnapshots.class
MakeUuidColumnNotNullOnSnapshots.class,

// CE_ACTIVITY.ANALYSIS_UUID
AddAnalysisUuidColumnToCeActivity.class,
PopulateAnalysisUuidColumnOnCeActivity.class,
DropSnapshotIdColumnFromCeActivity.class
);
}
}

+ 45
- 0
sonar-db/src/main/java/org/sonar/db/version/v60/AddAnalysisUuidColumnToCeActivity.java View File

@@ -0,0 +1,45 @@
/*
* SonarQube
* Copyright (C) 2009-2016 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.db.version.v60;

import java.sql.SQLException;
import org.sonar.db.Database;
import org.sonar.db.version.AddColumnsBuilder;
import org.sonar.db.version.DdlChange;

import static org.sonar.db.version.VarcharColumnDef.UUID_VARCHAR_SIZE;
import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;

public class AddAnalysisUuidColumnToCeActivity extends DdlChange {

private static final String TABLE_CE_ACTIVITY = "ce_activity";

public AddAnalysisUuidColumnToCeActivity(Database db) {
super(db);
}

@Override
public void execute(Context context) throws SQLException {
context.execute(new AddColumnsBuilder(getDatabase().getDialect(), TABLE_CE_ACTIVITY)
.addColumn(newVarcharColumnDefBuilder().setColumnName("analysis_uuid").setLimit(UUID_VARCHAR_SIZE).setIsNullable(true).build())
.build());
}

}

+ 44
- 0
sonar-db/src/main/java/org/sonar/db/version/v60/DropSnapshotIdColumnFromCeActivity.java View File

@@ -0,0 +1,44 @@
/*
* SonarQube
* Copyright (C) 2009-2016 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.db.version.v60;

import java.sql.SQLException;
import org.sonar.db.Database;
import org.sonar.db.version.DdlChange;
import org.sonar.db.version.DropColumnsBuilder;

public class DropSnapshotIdColumnFromCeActivity extends DdlChange {

private static final String TABLE_CE_ACTIVITY = "ce_activity";

public DropSnapshotIdColumnFromCeActivity(Database db) {
super(db);
}

@Override
public void execute(Context context) throws SQLException {
context.execute(
new DropColumnsBuilder(
getDatabase().getDialect(), TABLE_CE_ACTIVITY,
"snapshot_id")
.build());
}

}

+ 54
- 0
sonar-db/src/main/java/org/sonar/db/version/v60/PopulateAnalysisUuidColumnOnCeActivity.java View File

@@ -0,0 +1,54 @@
/*
* SonarQube
* Copyright (C) 2009-2016 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.db.version.v60;

import java.sql.SQLException;
import org.sonar.db.Database;
import org.sonar.db.version.BaseDataChange;
import org.sonar.db.version.MassUpdate;
import org.sonar.db.version.Select;
import org.sonar.db.version.SqlStatement;

public class PopulateAnalysisUuidColumnOnCeActivity extends BaseDataChange {

public PopulateAnalysisUuidColumnOnCeActivity(Database db) {
super(db);
}

@Override
public void execute(Context context) throws SQLException {
MassUpdate massUpdate = context.prepareMassUpdate();
massUpdate.select("SELECT a.id, s.uuid from ce_activity a inner join snapshots s on s.id=a.snapshot_id where a.snapshot_id is not null and a.analysis_uuid is null");
massUpdate.update("UPDATE ce_activity SET analysis_uuid=? WHERE id=?");
massUpdate.rowPluralName("ce_activity");
massUpdate.execute((row, update) -> this.handle(row, update));
}

private boolean handle(Select.Row row, SqlStatement update) throws SQLException {
long id = row.getLong(1);
String analysisUuid = row.getString(2);

update.setString(1, analysisUuid);
update.setLong(2, id);

return true;
}

}

+ 4
- 3
sonar-db/src/main/resources/org/sonar/db/ce/CeActivityMapper.xml View File

@@ -8,7 +8,7 @@
ca.uuid,
ca.task_type as taskType,
ca.component_uuid as componentUuid,
ca.snapshot_id as snapshotId,
ca.analysis_uuid as analysisUuid,
ca.status as status,
ca.submitter_login as submitterLogin,
ca.submitted_at as submittedAt,
@@ -122,12 +122,13 @@

<insert id="insert" parameterType="org.sonar.db.ce.CeActivityDto" useGeneratedKeys="false">
insert into ce_activity
(uuid, component_uuid, snapshot_id, status, task_type, is_last, is_last_key, submitter_login, submitted_at, started_at,
(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)
values (
#{uuid,jdbcType=VARCHAR},
#{componentUuid,jdbcType=VARCHAR},
#{snapshotId,jdbcType=BIGINT},
#{analysisUuid,jdbcType=VARCHAR},
#{status,jdbcType=VARCHAR},
#{taskType,jdbcType=VARCHAR},
#{isLast,jdbcType=BOOLEAN},

+ 7
- 0
sonar-db/src/main/resources/org/sonar/db/component/SnapshotMapper.xml View File

@@ -50,6 +50,13 @@
</where>
</select>

<select id="selectByUuid" parameterType="String" resultType="Snapshot">
SELECT
<include refid="snapshotColumns"/>
FROM snapshots s
WHERE s.uuid=#{uuid}
</select>

<select id="selectByIds" parameterType="Long" resultType="Snapshot">
SELECT
<include refid="snapshotColumns" />

+ 3
- 0
sonar-db/src/main/resources/org/sonar/db/version/rows-h2.sql View File

@@ -438,6 +438,9 @@ INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1228');
INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1229');
INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1230');
INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1231');
INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1232');
INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1233');
INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1234');

INSERT INTO USERS(ID, LOGIN, NAME, EMAIL, EXTERNAL_IDENTITY, EXTERNAL_IDENTITY_PROVIDER, USER_LOCAL, CRYPTED_PASSWORD, SALT, CREATED_AT, UPDATED_AT) VALUES (1, 'admin', 'Administrator', '', 'admin', 'sonarqube', true, 'a373a0e667abb2604c1fd571eb4ad47fe8cc0878', '48bc4b0d93179b5103fd3885ea9119498e9d161b', '1418215735482', '1418215735482');
ALTER TABLE USERS ALTER COLUMN ID RESTART WITH 2;

+ 1
- 1
sonar-db/src/main/resources/org/sonar/db/version/schema-h2.ddl View File

@@ -513,7 +513,7 @@ CREATE TABLE "CE_ACTIVITY" (
"UUID" VARCHAR(40) NOT NULL,
"TASK_TYPE" VARCHAR(15) NOT NULL,
"COMPONENT_UUID" VARCHAR(40) NULL,
"SNAPSHOT_ID" INTEGER NULL,
"ANALYSIS_UUID" VARCHAR(50) NULL,
"STATUS" VARCHAR(15) NOT NULL,
"IS_LAST" BOOLEAN NOT NULL,
"IS_LAST_KEY" VARCHAR(55) NOT NULL,

+ 4
- 2
sonar-db/src/test/java/org/sonar/db/ce/CeActivityDaoTest.java View File

@@ -39,6 +39,8 @@ import static org.sonar.db.ce.CeTaskTypes.REPORT;

public class CeActivityDaoTest {

private static final String AN_ANALYSIS_UUID = "U1";

TestSystem2 system2 = new TestSystem2().setNow(1_450_000_000_000L);

@Rule
@@ -64,7 +66,7 @@ public class CeActivityDaoTest {
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().getSnapshotId()).isEqualTo(123_456);
assertThat(saved.get().getAnalysisUuid()).isEqualTo("U1");
assertThat(saved.get().toString()).isNotEmpty();
}

@@ -244,7 +246,7 @@ public class CeActivityDaoTest {
dto.setStartedAt(1_500_000_000_000L);
dto.setExecutedAt(1_500_000_000_500L);
dto.setExecutionTimeMs(500L);
dto.setSnapshotId(123_456L);
dto.setAnalysisUuid(AN_ANALYSIS_UUID);
underTest.insert(db.getSession(), dto);
}


+ 14
- 5
sonar-db/src/test/java/org/sonar/db/component/SnapshotDaoTest.java View File

@@ -21,6 +21,7 @@ package org.sonar.db.component;

import java.util.Date;
import java.util.List;
import java.util.Optional;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
@@ -41,7 +42,6 @@ import static org.sonar.db.component.SnapshotQuery.SORT_ORDER.ASC;
import static org.sonar.db.component.SnapshotQuery.SORT_ORDER.DESC;
import static org.sonar.db.component.SnapshotTesting.newSnapshotForProject;


public class SnapshotDaoTest {

@Rule
@@ -56,7 +56,17 @@ public class SnapshotDaoTest {
SnapshotDao underTest = dbClient.snapshotDao();

@Test
public void get_by_key() {
public void test_selectByUuid() {
db.prepareDbUnit(getClass(), "shared.xml");

Optional<SnapshotDto> result = underTest.selectByUuid(db.getSession(), "u3");
assertThat(result.isPresent()).isTrue();

assertThat(underTest.selectByUuid(db.getSession(), "DOES_NOT_EXIST").isPresent()).isFalse();
}

@Test
public void test_selectById() {
db.prepareDbUnit(getClass(), "shared.xml");

SnapshotDto result = underTest.selectById(db.getSession(), 3L);
@@ -99,7 +109,7 @@ public class SnapshotDaoTest {
}

@Test
public void select_by_ids() {
public void test_selectByIds() {
SnapshotDto snapshot1 = componentDb.insertProjectAndSnapshot(newProjectDto());
SnapshotDto snapshot2 = componentDb.insertProjectAndSnapshot(newProjectDto());
SnapshotDto snapshot3 = componentDb.insertProjectAndSnapshot(newProjectDto());
@@ -226,8 +236,7 @@ public class SnapshotDaoTest {
db.getDbClient().snapshotDao().insert(dbSession,
newSnapshotForProject(project).setCreatedAt(5L),
newSnapshotForProject(project).setCreatedAt(2L),
newSnapshotForProject(project).setCreatedAt(1L)
);
newSnapshotForProject(project).setCreatedAt(1L));
dbSession.commit();

SnapshotDto dto = underTest.selectOldestSnapshot(dbSession, project.uuid());

+ 1
- 1
sonar-db/src/test/java/org/sonar/db/version/MigrationStepModuleTest.java View File

@@ -29,6 +29,6 @@ public class MigrationStepModuleTest {
public void verify_count_of_added_MigrationStep_types() {
ComponentContainer container = new ComponentContainer();
new MigrationStepModule().configure(container);
assertThat(container.size()).isEqualTo(90);
assertThat(container.size()).isEqualTo(93);
}
}

+ 84
- 0
sonar-db/src/test/java/org/sonar/db/version/v60/AddAnalysisUuidColumnToCeActivityTest.java View File

@@ -0,0 +1,84 @@
/*
* SonarQube
* Copyright (C) 2009-2016 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.db.version.v60;

import java.sql.SQLException;
import java.sql.Types;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.utils.System2;
import org.sonar.db.DbTester;

import static java.lang.String.valueOf;

public class AddAnalysisUuidColumnToCeActivityTest {

private static final long A_DATE = 123_456L;

@Rule
public DbTester db = DbTester.createForSchema(System2.INSTANCE, AddAnalysisUuidColumnToCeActivityTest.class, "old_ce_activity.sql");
@Rule
public ExpectedException expectedException = ExpectedException.none();

private AddAnalysisUuidColumnToCeActivity underTest = new AddAnalysisUuidColumnToCeActivity(db.database());

@Test
public void migration_adds_column_to_empty_table() throws SQLException {
underTest.execute();

verifyAddedColumns();
}

@Test
public void migration_adds_column_to_populated_table() throws SQLException {
for (int i = 0; i < 9; i++) {
db.executeInsert(
"ce_activity",
"uuid", valueOf(i),
"task_type", "REPORT",
"status", "SUCCESS",
"is_last", valueOf(true),
"is_last_key", valueOf(i + 100),
"created_at", valueOf(A_DATE),
"updated_at", valueOf(A_DATE),
"submitted_at", valueOf(A_DATE));
}
db.commit();

underTest.execute();

verifyAddedColumns();
}

@Test
public void migration_is_not_reentrant() throws SQLException {
underTest.execute();

expectedException.expect(IllegalStateException.class);
expectedException.expectMessage("Fail to execute ");
underTest.execute();
}

private void verifyAddedColumns() {
db.assertColumnDefinition("ce_activity", "analysis_uuid", Types.VARCHAR, 50, true);
}

}

+ 47
- 0
sonar-db/src/test/java/org/sonar/db/version/v60/DropSnapshotIdColumnFromCeActivityTest.java View File

@@ -0,0 +1,47 @@
/*
* SonarQube
* Copyright (C) 2009-2016 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.db.version.v60;

import java.sql.SQLException;
import org.junit.Test;
import org.sonar.db.Database;
import org.sonar.db.dialect.PostgreSql;
import org.sonar.db.version.DdlChange;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

public class DropSnapshotIdColumnFromCeActivityTest {

private Database database = mock(Database.class);
private DropSnapshotIdColumnFromCeActivity underTest = new DropSnapshotIdColumnFromCeActivity(database);

@Test
public void verify_generated_sql_on_postgresql() throws SQLException {
when(database.getDialect()).thenReturn(new PostgreSql());

DdlChange.Context context = mock(DdlChange.Context.class);
underTest.execute(context);

verify(context).execute("ALTER TABLE ce_activity DROP COLUMN snapshot_id");
}

}

+ 115
- 0
sonar-db/src/test/java/org/sonar/db/version/v60/PopulateAnalysisUuidColumnOnCeActivityTest.java View File

@@ -0,0 +1,115 @@
/*
* SonarQube
* Copyright (C) 2009-2016 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.db.version.v60;

import java.sql.SQLException;
import java.util.Map;
import javax.annotation.Nullable;
import org.apache.commons.lang.RandomStringUtils;
import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.utils.System2;
import org.sonar.db.DbTester;

import static java.lang.String.valueOf;
import static org.assertj.core.api.Assertions.assertThat;

public class PopulateAnalysisUuidColumnOnCeActivityTest {

private static final long A_DATE = 123_456L;
private static final String TABLE_CE_ACTIVITY = "ce_activity";
private static final String TABLE_SNAPSHOTS = "snapshots";

@Rule
public DbTester db = DbTester.createForSchema(System2.INSTANCE, PopulateAnalysisUuidColumnOnCeActivityTest.class,
"in_progress_ce_activity.sql");

private PopulateAnalysisUuidColumnOnCeActivity underTest = new PopulateAnalysisUuidColumnOnCeActivity(db.database());

@Test
public void migration_has_no_effect_on_empty_tables() throws SQLException {
underTest.execute();

assertThat(db.countRowsOfTable(TABLE_CE_ACTIVITY)).isEqualTo(0);
}

@Test
public void migration_generates_uuids() throws SQLException {
insertSnapshot(1, "U1");
insertSnapshot(2, "U2");
insertCeActivity(1, null);
insertCeActivity(2, 1L);
insertCeActivity(3, 2L);
db.commit();

underTest.execute();

verifyAnalysisUuid(1, null);
verifyAnalysisUuid(2, "U1");
verifyAnalysisUuid(3, "U2");
}

@Test
public void migration_is_reentrant() throws SQLException {
insertSnapshot(1, "U1");
insertCeActivity(1, null);
insertCeActivity(2, 1L);

underTest.execute();
verifyAnalysisUuid(1, null);
verifyAnalysisUuid(2, "U1");

underTest.execute();
verifyAnalysisUuid(1, null);
verifyAnalysisUuid(2, "U1");
}

private void verifyAnalysisUuid(int activityId, @Nullable String expectedAnalysisUuid) {
Map<String, Object> rows = db.selectFirst("select analysis_uuid as \"analysisUuid\" from ce_activity where id=" + activityId);
assertThat(rows.get("analysisUuid")).isEqualTo(expectedAnalysisUuid);
}

private String insertSnapshot(long id, String uuid) {
db.executeInsert(
TABLE_SNAPSHOTS,
"ID", valueOf(id),
"UUID", uuid,
"COMPONENT_UUID", valueOf(id + 10),
"ROOT_COMPONENT_UUID", valueOf(id + 100),
"SCOPE", "PRJ",
"QUALIFIER", "FIL");
return uuid;
}

private void insertCeActivity(long id, @Nullable Long snapshotId) {
db.executeInsert(
TABLE_CE_ACTIVITY,
"uuid", valueOf(id),
"snapshot_id", snapshotId == null ? null : valueOf(snapshotId),
"task_type", "REPORT",
"status", "SUCCESS",
"is_last", valueOf(true),
"is_last_key", RandomStringUtils.randomAlphabetic(10),
"created_at", valueOf(A_DATE),
"updated_at", valueOf(A_DATE),
"submitted_at", valueOf(A_DATE));
}

}

+ 17
- 0
sonar-db/src/test/resources/org/sonar/db/version/v60/AddAnalysisUuidColumnToCeActivityTest/old_ce_activity.sql View File

@@ -0,0 +1,17 @@
CREATE TABLE "CE_ACTIVITY" (
"ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
"UUID" VARCHAR(40) NOT NULL,
"TASK_TYPE" VARCHAR(15) NOT NULL,
"COMPONENT_UUID" VARCHAR(40) NULL,
"SNAPSHOT_ID" INTEGER NULL,
"STATUS" VARCHAR(15) NOT NULL,
"IS_LAST" BOOLEAN NOT NULL,
"IS_LAST_KEY" VARCHAR(55) NOT NULL,
"SUBMITTER_LOGIN" VARCHAR(255) NULL,
"SUBMITTED_AT" BIGINT NOT NULL,
"STARTED_AT" BIGINT NULL,
"EXECUTED_AT" BIGINT NULL,
"CREATED_AT" BIGINT NOT NULL,
"UPDATED_AT" BIGINT NOT NULL,
"EXECUTION_TIME_MS" BIGINT NULL
);

+ 1
- 0
sonar-db/src/test/resources/org/sonar/db/version/v60/AddComponentUuidColumnsToSnapshotsTest/old_snapshots.sql View File

@@ -30,3 +30,4 @@ CREATE TABLE "SNAPSHOTS" (
"PERIOD5_PARAM" VARCHAR(100),
"PERIOD5_DATE" BIGINT
);


+ 52
- 0
sonar-db/src/test/resources/org/sonar/db/version/v60/PopulateAnalysisUuidColumnOnCeActivityTest/in_progress_ce_activity.sql View File

@@ -0,0 +1,52 @@
CREATE TABLE "CE_ACTIVITY" (
"ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
"UUID" VARCHAR(40) NOT NULL,
"TASK_TYPE" VARCHAR(15) NOT NULL,
"COMPONENT_UUID" VARCHAR(40) NULL,
"SNAPSHOT_ID" INTEGER NULL,
"ANALYSIS_UUID" VARCHAR(50) NULL,
"STATUS" VARCHAR(15) NOT NULL,
"IS_LAST" BOOLEAN NOT NULL,
"IS_LAST_KEY" VARCHAR(55) NOT NULL,
"SUBMITTER_LOGIN" VARCHAR(255) NULL,
"SUBMITTED_AT" BIGINT NOT NULL,
"STARTED_AT" BIGINT NULL,
"EXECUTED_AT" BIGINT NULL,
"CREATED_AT" BIGINT NOT NULL,
"UPDATED_AT" BIGINT NOT NULL,
"EXECUTION_TIME_MS" BIGINT NULL
);

CREATE TABLE "SNAPSHOTS" (
"ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
"UUID" VARCHAR(50) NOT NULL,
"CREATED_AT" BIGINT,
"BUILD_DATE" BIGINT,
"COMPONENT_UUID" VARCHAR(50) NOT NULL,
"PARENT_SNAPSHOT_ID" INTEGER,
"STATUS" VARCHAR(4) NOT NULL DEFAULT 'U',
"PURGE_STATUS" INTEGER,
"ISLAST" BOOLEAN NOT NULL DEFAULT FALSE,
"SCOPE" VARCHAR(3),
"QUALIFIER" VARCHAR(10),
"ROOT_SNAPSHOT_ID" INTEGER,
"VERSION" VARCHAR(500),
"PATH" VARCHAR(500),
"DEPTH" INTEGER,
"ROOT_COMPONENT_UUID" VARCHAR(50) NOT NULL,
"PERIOD1_MODE" VARCHAR(100),
"PERIOD1_PARAM" VARCHAR(100),
"PERIOD1_DATE" BIGINT,
"PERIOD2_MODE" VARCHAR(100),
"PERIOD2_PARAM" VARCHAR(100),
"PERIOD2_DATE" BIGINT,
"PERIOD3_MODE" VARCHAR(100),
"PERIOD3_PARAM" VARCHAR(100),
"PERIOD3_DATE" BIGINT,
"PERIOD4_MODE" VARCHAR(100),
"PERIOD4_PARAM" VARCHAR(100),
"PERIOD4_DATE" BIGINT,
"PERIOD5_MODE" VARCHAR(100),
"PERIOD5_PARAM" VARCHAR(100),
"PERIOD5_DATE" BIGINT
);

Loading…
Cancel
Save