aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-ce-task-projectanalysis
diff options
context:
space:
mode:
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>2018-09-26 08:58:59 +0200
committerSonarTech <sonartech@sonarsource.com>2018-10-04 20:20:56 +0200
commit2c540713f9289d8cfd14a65f3b4c3c33a4696e20 (patch)
tree6f880db9407f37ccaf479cc79a8bf1c777a92b15 /server/sonar-ce-task-projectanalysis
parente80c0f3d1e5cd459f88b7e0c41a2d9a7519e260f (diff)
downloadsonarqube-2c540713f9289d8cfd14a65f3b4c3c33a4696e20.tar.gz
sonarqube-2c540713f9289d8cfd14a65f3b4c3c33a4696e20.zip
SONAR-11310 add temporary columns to CE tables
- add main_component_uuid temporary columns to CE_QUEUE - add main_last_key and main_component_uuid columns to CE_ACTIVITY - back to initial paradigm in Compute Engine: even for branches/PRs, the row in table PROJECTS a task belongs to is created in api/ce/submit - add main component concept to CeTask - improved consistency check when processing a report task to account for row in PROJECTS now being the one of the branche/PR - stronger validation of characteristics passed to api/ce/submit - add api/system/migrate_data for SonarCloud online data migration
Diffstat (limited to 'server/sonar-ce-task-projectanalysis')
-rw-r--r--server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/api/posttask/PostProjectAnalysisTasksExecutor.java10
-rw-r--r--server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/BranchLoader.java15
-rw-r--r--server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/BranchPersisterImpl.java54
-rw-r--r--server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/dbmigration/PopulateFileSourceLineCount.java7
-rw-r--r--server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/LoadReportAnalysisMetadataHolderStep.java28
-rw-r--r--server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/api/posttask/PostProjectAnalysisTasksExecutorTest.java12
-rw-r--r--server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/BranchPersisterImplTest.java128
-rw-r--r--server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/dbmigration/PopulateFileSourceLineCountTest.java18
-rw-r--r--server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/LoadReportAnalysisMetadataHolderStepTest.java41
9 files changed, 214 insertions, 99 deletions
diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/api/posttask/PostProjectAnalysisTasksExecutor.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/api/posttask/PostProjectAnalysisTasksExecutor.java
index 3c6f89c7c85..fbd3db946d2 100644
--- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/api/posttask/PostProjectAnalysisTasksExecutor.java
+++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/api/posttask/PostProjectAnalysisTasksExecutor.java
@@ -148,10 +148,12 @@ public class PostProjectAnalysisTasksExecutor implements ComputationStepExecutor
}
private static Project createProject(org.sonar.ce.task.CeTask ceTask) {
- return new ProjectImpl(
- ceTask.getComponentUuid(),
- ceTask.getComponentKey(),
- ceTask.getComponentName());
+ return ceTask.getMainComponent()
+ .map(c -> new ProjectImpl(
+ c.getUuid(),
+ c.getKey().orElseThrow(() -> new IllegalStateException("Missing project key")),
+ c.getName().orElseThrow(() -> new IllegalStateException("Missing project name"))))
+ .orElseThrow(() -> new IllegalStateException("Report processed for a task of a deleted component"));
}
@CheckForNull
diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/BranchLoader.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/BranchLoader.java
index 9341e29a09d..e6629463e6c 100644
--- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/BranchLoader.java
+++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/BranchLoader.java
@@ -21,10 +21,11 @@ package org.sonar.ce.task.projectanalysis.component;
import javax.annotation.Nullable;
import org.sonar.api.utils.MessageException;
-import org.sonar.scanner.protocol.output.ScannerReport;
import org.sonar.ce.task.projectanalysis.analysis.MutableAnalysisMetadataHolder;
+import org.sonar.scanner.protocol.output.ScannerReport;
import static org.apache.commons.lang.StringUtils.trimToNull;
+import static org.sonar.scanner.protocol.output.ScannerReport.Metadata.BranchType.UNSET;
public class BranchLoader {
private final MutableAnalysisMetadataHolder metadataHolder;
@@ -47,10 +48,22 @@ public class BranchLoader {
throw MessageException.of("Properties sonar.branch and sonar.branch.name can't be set together");
}
+ if (delegate == null && hasBranchProperties(metadata)) {
+ throw MessageException.of("Current edition does not support branch feature");
+ }
+
if (delegate != null && deprecatedBranch == null) {
delegate.load(metadata);
} else {
metadataHolder.setBranch(new DefaultBranchImpl(deprecatedBranch));
}
}
+
+ private static boolean hasBranchProperties(ScannerReport.Metadata metadata) {
+ return !metadata.getBranchName().isEmpty()
+ || !metadata.getPullRequestKey().isEmpty()
+ || !metadata.getMergeBranchName().isEmpty()
+ || metadata.getBranchType() != UNSET;
+ }
+
}
diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/BranchPersisterImpl.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/BranchPersisterImpl.java
index 8af513738c0..6efa7d0d9a1 100644
--- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/BranchPersisterImpl.java
+++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/BranchPersisterImpl.java
@@ -19,10 +19,7 @@
*/
package org.sonar.ce.task.projectanalysis.component;
-import java.util.Date;
-import java.util.Optional;
import javax.annotation.Nullable;
-import org.sonar.api.utils.System2;
import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolder;
import org.sonar.ce.task.projectanalysis.analysis.Branch;
import org.sonar.db.DbClient;
@@ -32,18 +29,16 @@ import org.sonar.db.component.BranchType;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.protobuf.DbProjectBranches;
-import static org.sonar.db.component.ComponentDto.UUID_PATH_OF_ROOT;
-import static org.sonar.db.component.ComponentDto.UUID_PATH_SEPARATOR;
-
+/**
+ * Creates or updates the data in table {@code PROJECT_BRANCHES} for the current root.
+ */
public class BranchPersisterImpl implements BranchPersister {
private final DbClient dbClient;
- private final System2 system2;
private final TreeRootHolder treeRootHolder;
private final AnalysisMetadataHolder analysisMetadataHolder;
- public BranchPersisterImpl(DbClient dbClient, System2 system2, TreeRootHolder treeRootHolder, AnalysisMetadataHolder analysisMetadataHolder) {
+ public BranchPersisterImpl(DbClient dbClient, TreeRootHolder treeRootHolder, AnalysisMetadataHolder analysisMetadataHolder) {
this.dbClient = dbClient;
- this.system2 = system2;
this.treeRootHolder = treeRootHolder;
this.analysisMetadataHolder = analysisMetadataHolder;
}
@@ -52,32 +47,14 @@ public class BranchPersisterImpl implements BranchPersister {
Branch branch = analysisMetadataHolder.getBranch();
String branchUuid = treeRootHolder.getRoot().getUuid();
- Optional<ComponentDto> branchComponentDtoOpt = dbClient.componentDao().selectByUuid(dbSession, branchUuid);
-
- ComponentDto branchComponentDto;
- if (branch.isMain()) {
- checkState(branchComponentDtoOpt.isPresent(), "Project has been deleted by end-user during analysis");
- branchComponentDto = branchComponentDtoOpt.get();
- } else {
- // inserts new row in table projects if it's the first time branch is analyzed
- branchComponentDto = branchComponentDtoOpt.orElseGet(() -> insertIntoProjectsTable(dbSession, branchUuid));
- }
+ ComponentDto branchComponentDto = dbClient.componentDao().selectByUuid(dbSession, branchUuid)
+ .orElseThrow(() -> new IllegalStateException("Component has been deleted by end-user during analysis"));
// insert or update in table project_branches
dbClient.branchDao().upsert(dbSession, toBranchDto(branchComponentDto, branch));
}
- private static void checkState(boolean condition, String msg) {
- if (!condition) {
- throw new IllegalStateException(msg);
- }
- }
-
- private static <T> T firstNonNull(@Nullable T first, T second) {
- return (first != null) ? first : second;
- }
-
- private BranchDto toBranchDto(ComponentDto componentDto, Branch branch) {
+ protected BranchDto toBranchDto(ComponentDto componentDto, Branch branch) {
BranchDto dto = new BranchDto();
dto.setUuid(componentDto.uuid());
@@ -103,19 +80,8 @@ public class BranchPersisterImpl implements BranchPersister {
return dto;
}
- private ComponentDto insertIntoProjectsTable(DbSession dbSession, String branchUuid) {
- String mainBranchProjectUuid = analysisMetadataHolder.getProject().getUuid();
- ComponentDto project = dbClient.componentDao().selectOrFailByUuid(dbSession, mainBranchProjectUuid);
- ComponentDto branchDto = project.copy();
- branchDto.setUuid(branchUuid);
- branchDto.setProjectUuid(branchUuid);
- branchDto.setRootUuid(branchUuid);
- branchDto.setUuidPath(UUID_PATH_OF_ROOT);
- branchDto.setModuleUuidPath(UUID_PATH_SEPARATOR + branchUuid + UUID_PATH_SEPARATOR);
- branchDto.setMainBranchProjectUuid(mainBranchProjectUuid);
- branchDto.setDbKey(treeRootHolder.getRoot().getDbKey());
- branchDto.setCreatedAt(new Date(system2.now()));
- dbClient.componentDao().insert(dbSession, branchDto);
- return branchDto;
+ private static <T> T firstNonNull(@Nullable T first, T second) {
+ return (first != null) ? first : second;
}
+
}
diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/dbmigration/PopulateFileSourceLineCount.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/dbmigration/PopulateFileSourceLineCount.java
index 6de4c30557a..80963133fc5 100644
--- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/dbmigration/PopulateFileSourceLineCount.java
+++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/dbmigration/PopulateFileSourceLineCount.java
@@ -41,18 +41,19 @@ public class PopulateFileSourceLineCount extends DataChange implements ProjectAn
@Override
protected void execute(Context context) throws SQLException {
+ String componentUuid = ceTask.getComponent().get().getUuid();
Long unInitializedFileSources = context.prepareSelect("select count(1) from file_sources where line_count = ? and project_uuid = ?")
.setInt(1, LINE_COUNT_NOT_POPULATED)
- .setString(2, ceTask.getComponentUuid())
+ .setString(2, componentUuid)
.get(row -> row.getLong(1));
if (unInitializedFileSources != null && unInitializedFileSources > 0) {
MassUpdate massUpdate = context.prepareMassUpdate();
massUpdate.select("select id,line_hashes from file_sources where line_count = ? and project_uuid = ?")
.setInt(1, LINE_COUNT_NOT_POPULATED)
- .setString(2, ceTask.getComponentUuid());
+ .setString(2, componentUuid);
massUpdate.update("update file_sources set line_count = ? where id = ?");
- massUpdate.rowPluralName("line counts of sources of project " + ceTask.getComponentUuid());
+ massUpdate.rowPluralName("line counts of sources of project " + componentUuid);
massUpdate.execute(PopulateFileSourceLineCount::handle);
}
}
diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/LoadReportAnalysisMetadataHolderStep.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/LoadReportAnalysisMetadataHolderStep.java
index 9a0c3b1592e..99709304ebd 100644
--- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/LoadReportAnalysisMetadataHolderStep.java
+++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/LoadReportAnalysisMetadataHolderStep.java
@@ -104,30 +104,40 @@ public class LoadReportAnalysisMetadataHolderStep implements ComputationStep {
*/
private Runnable loadProject(ScannerReport.Metadata reportMetadata, Organization organization) {
String reportProjectKey = projectKeyFromReport(reportMetadata);
- String componentKey = ceTask.getComponentKey();
- if (componentKey == null) {
- throw MessageException.of(format(
+ CeTask.Component mainComponent = mandatoryComponent(ceTask.getMainComponent());
+ String mainComponentKey = mainComponent.getKey()
+ .orElseThrow(() -> MessageException.of(format(
+ "Compute Engine task main component key is null. Project with UUID %s must have been deleted since report was uploaded. Can not proceed.",
+ mainComponent.getUuid())));
+ CeTask.Component component = mandatoryComponent(ceTask.getComponent());
+ String componentKey = component.getKey()
+ .orElseThrow(() -> MessageException.of(format(
"Compute Engine task component key is null. Project with UUID %s must have been deleted since report was uploaded. Can not proceed.",
- ceTask.getComponentUuid()));
- }
+ component.getUuid())));
ComponentDto dto = toProject(reportProjectKey);
+
analysisMetadata.setProject(Project.from(dto));
return () -> {
- if (!componentKey.equals(reportProjectKey)) {
+ if (!mainComponentKey.equals(reportProjectKey)) {
throw MessageException.of(format(
"ProjectKey in report (%s) is not consistent with projectKey under which the report has been submitted (%s)",
reportProjectKey,
- componentKey));
+ mainComponentKey));
}
if (!dto.getOrganizationUuid().equals(organization.getUuid())) {
throw MessageException.of(format("Project is not in the expected organization: %s", organization.getKey()));
}
- if (dto.getMainBranchProjectUuid() != null) {
- throw MessageException.of("Project should not reference a branch");
+ if (componentKey.equals(mainComponentKey) && dto.getMainBranchProjectUuid() != null) {
+ throw MessageException.of("Component should not reference a branch");
}
};
}
+ private static CeTask.Component mandatoryComponent(Optional<CeTask.Component> mainComponent) {
+ return mainComponent
+ .orElseThrow(() -> new IllegalStateException("component missing on ce task"));
+ }
+
private Organization loadOrganization(ScannerReport.Metadata reportMetadata) {
try (DbSession dbSession = dbClient.openSession(false)) {
Organization organization = toOrganization(dbSession, ceTask.getOrganizationUuid());
diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/api/posttask/PostProjectAnalysisTasksExecutorTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/api/posttask/PostProjectAnalysisTasksExecutorTest.java
index fabd35b9dbc..af0eafd471e 100644
--- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/api/posttask/PostProjectAnalysisTasksExecutorTest.java
+++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/api/posttask/PostProjectAnalysisTasksExecutorTest.java
@@ -87,13 +87,13 @@ public class PostProjectAnalysisTasksExecutorTest {
private String organizationName = organizationUuid + "_name";
private System2 system2 = mock(System2.class);
private ArgumentCaptor<PostProjectAnalysisTask.ProjectAnalysis> projectAnalysisArgumentCaptor = ArgumentCaptor.forClass(PostProjectAnalysisTask.ProjectAnalysis.class);
+ private CeTask.Component component = new CeTask.Component("component uuid", "component key", "component name");
private CeTask ceTask = new CeTask.Builder()
.setOrganizationUuid(organizationUuid)
.setType("type")
.setUuid("uuid")
- .setComponentKey("component key")
- .setComponentName("component name")
- .setComponentUuid("component uuid")
+ .setComponent(component)
+ .setMainComponent(component)
.build();
private PostProjectAnalysisTask postProjectAnalysisTask = mock(PostProjectAnalysisTask.class);
private PostProjectAnalysisTasksExecutor underTest = new PostProjectAnalysisTasksExecutor(
@@ -203,9 +203,9 @@ public class PostProjectAnalysisTasksExecutorTest {
verify(postProjectAnalysisTask).finished(projectAnalysisArgumentCaptor.capture());
Project project = projectAnalysisArgumentCaptor.getValue().getProject();
- assertThat(project.getUuid()).isEqualTo(ceTask.getComponentUuid());
- assertThat(project.getKey()).isEqualTo(ceTask.getComponentKey());
- assertThat(project.getName()).isEqualTo(ceTask.getComponentName());
+ assertThat(project.getUuid()).isEqualTo(ceTask.getComponent().get().getUuid());
+ assertThat(project.getKey()).isEqualTo(ceTask.getComponent().get().getKey().get());
+ assertThat(project.getName()).isEqualTo(ceTask.getComponent().get().getName().get());
}
@Test
diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/BranchPersisterImplTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/BranchPersisterImplTest.java
index 237b7b3efc1..7cfcbd5c116 100644
--- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/BranchPersisterImplTest.java
+++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/BranchPersisterImplTest.java
@@ -19,25 +19,36 @@
*/
package org.sonar.ce.task.projectanalysis.component;
+import com.tngtech.java.junit.dataprovider.DataProvider;
+import com.tngtech.java.junit.dataprovider.DataProviderRunner;
+import com.tngtech.java.junit.dataprovider.UseDataProvider;
import java.util.Optional;
+import javax.annotation.Nullable;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
import org.sonar.api.utils.System2;
import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolderRule;
import org.sonar.ce.task.projectanalysis.analysis.Branch;
import org.sonar.db.DbTester;
+import org.sonar.db.component.BranchDto;
import org.sonar.db.component.BranchType;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.ComponentTesting;
+import org.sonar.db.protobuf.DbProjectBranches;
import org.sonar.server.project.Project;
+import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.sonar.ce.task.projectanalysis.component.Component.Type.PROJECT;
import static org.sonar.ce.task.projectanalysis.component.ReportComponent.builder;
+import static org.sonar.db.component.BranchType.LONG;
+import static org.sonar.db.component.BranchType.PULL_REQUEST;
+@RunWith(DataProviderRunner.class)
public class BranchPersisterImplTest {
private final static Component MAIN = builder(PROJECT, 1).setUuid("PROJECT_UUID").setKey("PROJECT_KEY").build();
private final static Component BRANCH = builder(PROJECT, 1).setUuid("BRANCH_UUID").setKey("BRANCH_KEY").build();
@@ -51,66 +62,133 @@ public class BranchPersisterImplTest {
@Rule
public ExpectedException exception = ExpectedException.none();
- BranchPersister underTest = new BranchPersisterImpl(dbTester.getDbClient(), System2.INSTANCE, treeRootHolder, analysisMetadataHolder);
+ BranchPersister underTest = new BranchPersisterImpl(dbTester.getDbClient(), treeRootHolder, analysisMetadataHolder);
@Test
- public void fail_if_no_component_for_main_branches() {
- analysisMetadataHolder.setBranch(createBranch(BranchType.LONG, true, "master"));
+ public void persist_fails_with_ISE_if_no_component_for_main_branches() {
+ analysisMetadataHolder.setBranch(createBranch(LONG, true, "master"));
treeRootHolder.setRoot(MAIN);
- exception.expect(IllegalStateException.class);
- exception.expectMessage("Project has been deleted by end-user during analysis");
+ expectMissingComponentISE();
+
+ underTest.persist(dbTester.getSession());
+ }
+
+ @Test
+ public void persist_fails_with_ISE_if_no_component_for_long_branches() {
+ analysisMetadataHolder.setBranch(createBranch(LONG, false, "foo"));
+ treeRootHolder.setRoot(BRANCH);
+
+ expectMissingComponentISE();
underTest.persist(dbTester.getSession());
}
@Test
- public void persist_secondary_branch() {
- analysisMetadataHolder.setBranch(createBranch(BranchType.LONG, false, "branch"));
+ public void persist_fails_with_ISE_if_no_component_for_short_branches() {
+ analysisMetadataHolder.setBranch(createBranch(BranchType.SHORT, false, "foo"));
treeRootHolder.setRoot(BRANCH);
- // add main branch in project table and in metadata
- ComponentDto dto = ComponentTesting.newPrivateProjectDto(dbTester.organizations().insert(), MAIN.getUuid()).setDbKey(MAIN.getDbKey());
- analysisMetadataHolder.setProject(Project.from(dto));
- dbTester.getDbClient().componentDao().insert(dbTester.getSession(), dto);
+ expectMissingComponentISE();
+
+ underTest.persist(dbTester.getSession());
+ }
+
+ @Test
+ public void persist_fails_with_ISE_if_no_component_for_pull_request() {
+ analysisMetadataHolder.setBranch(createBranch(BranchType.PULL_REQUEST, false, "12"));
+ treeRootHolder.setRoot(BRANCH);
+
+ expectMissingComponentISE();
+
+ underTest.persist(dbTester.getSession());
+ }
+
+ @Test
+ @UseDataProvider("nullOrNotNullString")
+ public void persist_creates_row_in_PROJECTS_BRANCHES_for_long_branch(@Nullable String mergeBranchUuid) {
+ String branchName = "branch";
+
+ // add project and branch in table PROJECTS
+ ComponentDto mainComponent = ComponentTesting.newPrivateProjectDto(dbTester.organizations().insert(), MAIN.getUuid()).setDbKey(MAIN.getKey());
+ ComponentDto component = ComponentTesting.newProjectBranch(mainComponent, new BranchDto().setUuid(BRANCH.getUuid()).setKey(BRANCH.getKey()).setBranchType(LONG));
+ dbTester.getDbClient().componentDao().insert(dbTester.getSession(), mainComponent, component);
+ dbTester.commit();
+ // set project in metadata
+ treeRootHolder.setRoot(BRANCH);
+ analysisMetadataHolder.setBranch(createBranch(LONG, false, branchName, mergeBranchUuid));
+ analysisMetadataHolder.setProject(Project.from(mainComponent));
- // this should add new columns in project and project_branches
underTest.persist(dbTester.getSession());
dbTester.getSession().commit();
assertThat(dbTester.countRowsOfTable("projects")).isEqualTo(2);
- assertThat(dbTester.countRowsOfTable("project_branches")).isEqualTo(1);
+ Optional<BranchDto> branchDto = dbTester.getDbClient().branchDao().selectByUuid(dbTester.getSession(), BRANCH.getUuid());
+ assertThat(branchDto).isPresent();
+ assertThat(branchDto.get().getBranchType()).isEqualTo(LONG);
+ assertThat(branchDto.get().getKey()).isEqualTo(branchName);
+ assertThat(branchDto.get().getMergeBranchUuid()).isEqualTo(mergeBranchUuid);
+ assertThat(branchDto.get().getProjectUuid()).isEqualTo(MAIN.getUuid());
+ assertThat(branchDto.get().getPullRequestData()).isNull();
+ }
+
+ @DataProvider
+ public static Object[][] nullOrNotNullString() {
+ return new Object[][] {
+ {null},
+ {randomAlphabetic(12)}
+ };
}
@Test
- public void persist_pull_request_data() {
+ @UseDataProvider("nullOrNotNullString")
+ public void persist_creates_row_in_PROJECTS_BRANCHES_for_pull_request(@Nullable String mergeBranchUuid) {
String pullRequestId = "pr-123";
- analysisMetadataHolder.setBranch(createBranch(BranchType.PULL_REQUEST, false, pullRequestId));
- analysisMetadataHolder.setPullRequestKey(pullRequestId);
- treeRootHolder.setRoot(BRANCH);
- // add main branch in project table and in metadata
- ComponentDto dto = ComponentTesting.newPrivateProjectDto(dbTester.organizations().insert(), MAIN.getUuid()).setDbKey(MAIN.getDbKey());
- analysisMetadataHolder.setProject(Project.from(dto));
- dbTester.getDbClient().componentDao().insert(dbTester.getSession(), dto);
+ // add project and branch in table PROJECTS
+ ComponentDto mainComponent = ComponentTesting.newPrivateProjectDto(dbTester.organizations().insert(), MAIN.getUuid()).setDbKey(MAIN.getKey());
+ ComponentDto component = ComponentTesting.newProjectBranch(mainComponent, new BranchDto().setUuid(BRANCH.getUuid()).setKey(BRANCH.getKey()).setBranchType(PULL_REQUEST));
+ dbTester.getDbClient().componentDao().insert(dbTester.getSession(), mainComponent, component);
+ dbTester.commit();
+ // set project in metadata
+ treeRootHolder.setRoot(BRANCH);
+ analysisMetadataHolder.setBranch(createBranch(PULL_REQUEST, false, pullRequestId, mergeBranchUuid));
+ analysisMetadataHolder.setProject(Project.from(mainComponent));
+ analysisMetadataHolder.setPullRequestKey(pullRequestId);
- // this should add new columns in project and project_branches
underTest.persist(dbTester.getSession());
dbTester.getSession().commit();
assertThat(dbTester.countRowsOfTable("projects")).isEqualTo(2);
- assertThat(dbTester.countRowsOfTable("project_branches")).isEqualTo(1);
- assertThat(dbTester.countSql("select count(*) from project_branches where pull_request_binary is not null")).isEqualTo(1);
+ Optional<BranchDto> branchDto = dbTester.getDbClient().branchDao().selectByUuid(dbTester.getSession(), BRANCH.getUuid());
+ assertThat(branchDto).isPresent();
+ assertThat(branchDto.get().getBranchType()).isEqualTo(PULL_REQUEST);
+ assertThat(branchDto.get().getKey()).isEqualTo(pullRequestId);
+ assertThat(branchDto.get().getMergeBranchUuid()).isEqualTo(mergeBranchUuid);
+ assertThat(branchDto.get().getProjectUuid()).isEqualTo(MAIN.getUuid());
+ assertThat(branchDto.get().getPullRequestData()).isEqualTo(DbProjectBranches.PullRequestData.newBuilder()
+ .setBranch(pullRequestId)
+ .setTitle(pullRequestId)
+ .build());
}
private static Branch createBranch(BranchType type, boolean isMain, String name) {
+ return createBranch(type, isMain, name, null);
+ }
+
+ private static Branch createBranch(BranchType type, boolean isMain, String name, @Nullable String mergeBranchUuid) {
Branch branch = mock(Branch.class);
when(branch.getType()).thenReturn(type);
when(branch.getName()).thenReturn(name);
when(branch.isMain()).thenReturn(isMain);
- when(branch.getMergeBranchUuid()).thenReturn(Optional.empty());
+ when(branch.getMergeBranchUuid()).thenReturn(Optional.ofNullable(mergeBranchUuid));
return branch;
}
+
+ private void expectMissingComponentISE() {
+ exception.expect(IllegalStateException.class);
+ exception.expectMessage("Component has been deleted by end-user during analysis");
+ }
}
diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/dbmigration/PopulateFileSourceLineCountTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/dbmigration/PopulateFileSourceLineCountTest.java
index 2b103c4b3a9..502d6aa0e0f 100644
--- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/dbmigration/PopulateFileSourceLineCountTest.java
+++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/dbmigration/PopulateFileSourceLineCountTest.java
@@ -23,6 +23,7 @@ import com.tngtech.java.junit.dataprovider.DataProvider;
import com.tngtech.java.junit.dataprovider.DataProviderRunner;
import com.tngtech.java.junit.dataprovider.UseDataProvider;
import java.sql.SQLException;
+import java.util.Optional;
import java.util.Random;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
@@ -57,6 +58,9 @@ public class PopulateFileSourceLineCountTest {
@Test
public void execute_has_no_effect_on_empty_table() throws SQLException {
+ String projectUuid = randomAlphanumeric(4);
+ when(ceTask.getComponent()).thenReturn(newComponent(projectUuid));
+
underTest.execute();
}
@@ -65,7 +69,7 @@ public class PopulateFileSourceLineCountTest {
public void execute_populates_line_count_of_any_type(String type) throws SQLException {
String projectUuid = randomAlphanumeric(4);
String fileUuid = randomAlphanumeric(5);
- when(ceTask.getComponentUuid()).thenReturn(projectUuid);
+ when(ceTask.getComponent()).thenReturn(newComponent(projectUuid));
int lineCount = 1 + random.nextInt(15);
insertUnpopulatedFileSource(projectUuid, fileUuid, type, lineCount);
assertThat(getLineCountByFileUuid(fileUuid)).isEqualTo(LINE_COUNT_NOT_POPULATED);
@@ -86,7 +90,7 @@ public class PopulateFileSourceLineCountTest {
int lineCountFile2 = 50 + random.nextInt(15);
int lineCountFile3 = 150 + random.nextInt(15);
- when(ceTask.getComponentUuid()).thenReturn(projectUuid);
+ when(ceTask.getComponent()).thenReturn(newComponent(projectUuid));
insertPopulatedFileSource(projectUuid, fileUuid1, type, lineCountFile1);
int badLineCountFile2 = insertInconsistentPopulatedFileSource(projectUuid, fileUuid2, type, lineCountFile2);
insertUnpopulatedFileSource(projectUuid, fileUuid3, type, lineCountFile3);
@@ -111,7 +115,7 @@ public class PopulateFileSourceLineCountTest {
int lineCountFile1 = 100 + random.nextInt(15);
int lineCountFile2 = 30 + random.nextInt(15);
- when(ceTask.getComponentUuid()).thenReturn(projectUuid1);
+ when(ceTask.getComponent()).thenReturn(newComponent(projectUuid1));
insertUnpopulatedFileSource(projectUuid1, fileUuid1, type, lineCountFile1);
insertUnpopulatedFileSource(projectUuid2, fileUuid2, type, lineCountFile2);
@@ -127,7 +131,7 @@ public class PopulateFileSourceLineCountTest {
String projectUuid = randomAlphanumeric(4);
String fileUuid1 = randomAlphanumeric(5);
- when(ceTask.getComponentUuid()).thenReturn(projectUuid);
+ when(ceTask.getComponent()).thenReturn(newComponent(projectUuid));
insertFileSource(projectUuid, fileUuid1, type, null, LINE_COUNT_NOT_POPULATED);
underTest.execute();
@@ -141,7 +145,7 @@ public class PopulateFileSourceLineCountTest {
String projectUuid = randomAlphanumeric(4);
String fileUuid1 = randomAlphanumeric(5);
- when(ceTask.getComponentUuid()).thenReturn(projectUuid);
+ when(ceTask.getComponent()).thenReturn(newComponent(projectUuid));
insertFileSource(projectUuid, fileUuid1, type, "", LINE_COUNT_NOT_POPULATED);
underTest.execute();
@@ -204,4 +208,8 @@ public class PopulateFileSourceLineCountTest {
"UPDATED_AT", 1_222_333L);
db.commit();
}
+
+ private static Optional<CeTask.Component> newComponent(String projectUuid) {
+ return Optional.of(new CeTask.Component(projectUuid, "key_" + projectUuid, "name_" + projectUuid));
+ }
}
diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/LoadReportAnalysisMetadataHolderStepTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/LoadReportAnalysisMetadataHolderStepTest.java
index 41e3a4f8b73..3bf4c6fa7fe 100644
--- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/LoadReportAnalysisMetadataHolderStepTest.java
+++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/LoadReportAnalysisMetadataHolderStepTest.java
@@ -25,6 +25,7 @@ import com.tngtech.java.junit.dataprovider.UseDataProvider;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
+import java.util.Optional;
import org.assertj.core.api.Assertions;
import org.junit.Before;
import org.junit.Rule;
@@ -166,9 +167,43 @@ public class LoadReportAnalysisMetadataHolderStepTest {
}
@Test
+ public void execute_fails_with_ISE_if_component_is_null_in_CE_task() {
+ CeTask res = mock(CeTask.class);
+ when(res.getComponent()).thenReturn(Optional.empty());
+ when(res.getOrganizationUuid()).thenReturn(defaultOrganizationProvider.get().getUuid());
+ reportReader.setMetadata(ScannerReport.Metadata.newBuilder().build());
+
+ ComputationStep underTest = createStep(res);
+
+ expectedException.expect(IllegalStateException.class);
+ expectedException.expectMessage("component missing on ce task");
+
+ underTest.execute(new TestComputationStepContext());
+ }
+
+ @Test
+ public void execute_fails_with_MessageException_if_main_projectKey_is_null_in_CE_task() {
+ CeTask res = mock(CeTask.class);
+ Optional<CeTask.Component> component = Optional.of(new CeTask.Component("main_prj_uuid", null, null));
+ when(res.getComponent()).thenReturn(component);
+ when(res.getMainComponent()).thenReturn(component);
+ when(res.getOrganizationUuid()).thenReturn(defaultOrganizationProvider.get().getUuid());
+ reportReader.setMetadata(ScannerReport.Metadata.newBuilder().build());
+
+ ComputationStep underTest = createStep(res);
+
+ expectedException.expect(MessageException.class);
+ expectedException.expectMessage("Compute Engine task main component key is null. Project with UUID main_prj_uuid must have been deleted since report was uploaded. Can not proceed.");
+
+ underTest.execute(new TestComputationStepContext());
+ }
+
+ @Test
public void execute_fails_with_MessageException_if_projectKey_is_null_in_CE_task() {
CeTask res = mock(CeTask.class);
- when(res.getComponentUuid()).thenReturn("prj_uuid");
+ Optional<CeTask.Component> component = Optional.of(new CeTask.Component("prj_uuid", null, null));
+ when(res.getComponent()).thenReturn(component);
+ when(res.getMainComponent()).thenReturn(Optional.of(new CeTask.Component("main_prj_uuid", "main_prj_key", null)));
when(res.getOrganizationUuid()).thenReturn(defaultOrganizationProvider.get().getUuid());
reportReader.setMetadata(ScannerReport.Metadata.newBuilder().build());
@@ -407,8 +442,10 @@ public class LoadReportAnalysisMetadataHolderStepTest {
private CeTask createCeTask(String projectKey, String organizationUuid) {
CeTask res = mock(CeTask.class);
+ Optional<CeTask.Component> component = Optional.of(new CeTask.Component(projectKey + "_uuid", projectKey, projectKey + "_name"));
when(res.getOrganizationUuid()).thenReturn(organizationUuid);
- when(res.getComponentKey()).thenReturn(projectKey);
+ when(res.getComponent()).thenReturn(component);
+ when(res.getMainComponent()).thenReturn(component);
return res;
}