]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-8971 check consistency of Quality profiles in Compute Engine
authorSimon Brandhof <simon.brandhof@sonarsource.com>
Tue, 21 Mar 2017 21:17:57 +0000 (22:17 +0100)
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Thu, 23 Mar 2017 16:38:34 +0000 (17:38 +0100)
server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/LoadReportAnalysisMetadataHolderStep.java
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/LoadReportAnalysisMetadataHolderStepTest.java

index 754f992225aa0f6c25be5bab5581b624fb9daf07..c106f554eb5c761ef289e3283dcb2558423d8338 100644 (file)
 package org.sonar.server.computation.task.projectanalysis.step;
 
 import com.google.common.base.Function;
+import com.google.common.base.Joiner;
 import java.util.Date;
+import java.util.List;
 import java.util.Optional;
 import javax.annotation.Nullable;
 import org.sonar.api.utils.MessageException;
 import org.sonar.ce.queue.CeTask;
+import org.sonar.core.util.stream.Collectors;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.db.organization.OrganizationDto;
+import org.sonar.db.qualityprofile.QualityProfileDto;
 import org.sonar.scanner.protocol.output.ScannerReport;
 import org.sonar.scanner.protocol.output.ScannerReport.Metadata.QProfile;
 import org.sonar.server.computation.task.projectanalysis.analysis.MutableAnalysisMetadataHolder;
@@ -41,6 +45,7 @@ import static com.google.common.base.Preconditions.checkState;
 import static com.google.common.collect.Maps.transformValues;
 import static java.lang.String.format;
 import static org.apache.commons.lang.StringUtils.isNotEmpty;
+import static org.sonar.core.util.stream.Collectors.toList;
 
 /**
  * Feed analysis metadata holder with metadata from the analysis report.
@@ -79,6 +84,7 @@ public class LoadReportAnalysisMetadataHolderStep implements ComputationStep {
     checkProjectKeyConsistency(reportMetadata);
     Organization organization = toOrganization(ceTask.getOrganizationUuid());
     checkOrganizationKeyConsistency(reportMetadata, organization);
+    checkQualityProfilesConsistency(reportMetadata, organization);
 
     mutableAnalysisMetadataHolder.setRootComponentRef(reportMetadata.getRootComponentRef());
     mutableAnalysisMetadataHolder.setBranch(isNotEmpty(reportMetadata.getBranch()) ? reportMetadata.getBranch() : null);
@@ -87,6 +93,25 @@ public class LoadReportAnalysisMetadataHolderStep implements ComputationStep {
     mutableAnalysisMetadataHolder.setOrganization(organization);
   }
 
+  /**
+   * Check that the Quality profiles sent by scanner correctly relate to the project organization.
+   */
+  private void checkQualityProfilesConsistency(ScannerReport.Metadata metadata, Organization organization) {
+    List<String> profileKeys = metadata.getQprofilesPerLanguage().values().stream()
+      .map(QProfile::getKey)
+      .collect(toList(metadata.getQprofilesPerLanguage().size()));
+    try (DbSession dbSession = dbClient.openSession(false)) {
+      List<QualityProfileDto> profiles = dbClient.qualityProfileDao().selectByKeys(dbSession, profileKeys);
+      String badKeys = profiles.stream()
+        .filter(p -> !p.getOrganizationUuid().equals(organization.getUuid()))
+        .map(p -> p.getKey())
+        .collect(Collectors.join(Joiner.on(", ")));
+      if (!badKeys.isEmpty()) {
+        throw MessageException.of(format("Quality profiles with following keys don't exist in organization [%s]: %s", organization.getKey(), badKeys));
+      }
+    }
+  }
+
   private void checkProjectKeyConsistency(ScannerReport.Metadata reportMetadata) {
     String reportProjectKey = projectKeyFromReport(reportMetadata);
     String componentKey = ceTask.getComponentKey();
index 0ead8bd64b24c761a396bca8679fa2bb9c9ea4e8..8ae21842cc78e02bd817ab1f2126e709b56ad026 100644 (file)
@@ -61,13 +61,13 @@ public class LoadReportAnalysisMetadataHolderStepTest {
   private ComputationStep underTest;
 
   @Before
-  public void setUp() throws Exception {
+  public void setUp() {
     CeTask defaultOrgCeTask = createCeTask(PROJECT_KEY, dbTester.getDefaultOrganization().getUuid());
     underTest = createStep(defaultOrgCeTask);
   }
 
   @Test
-  public void set_root_component_ref() throws Exception {
+  public void set_root_component_ref() {
     reportReader.setMetadata(
       newBatchReportBuilder()
         .setRootComponentRef(1)
@@ -79,7 +79,7 @@ public class LoadReportAnalysisMetadataHolderStepTest {
   }
 
   @Test
-  public void set_analysis_date() throws Exception {
+  public void set_analysis_date() {
     reportReader.setMetadata(
       newBatchReportBuilder()
         .setAnalysisDate(ANALYSIS_DATE)
@@ -91,7 +91,7 @@ public class LoadReportAnalysisMetadataHolderStepTest {
   }
 
   @Test
-  public void set_branch() throws Exception {
+  public void set_branch() {
     reportReader.setMetadata(
       newBatchReportBuilder()
         .setBranch(BRANCH)
@@ -106,7 +106,7 @@ public class LoadReportAnalysisMetadataHolderStepTest {
   }
 
   @Test
-  public void set_null_branch_when_nothing_in_the_report() throws Exception {
+  public void set_null_branch_when_nothing_in_the_report() {
     reportReader.setMetadata(
       newBatchReportBuilder()
         .build());
@@ -117,7 +117,7 @@ public class LoadReportAnalysisMetadataHolderStepTest {
   }
 
   @Test
-  public void set_cross_project_duplication_to_true() throws Exception {
+  public void set_cross_project_duplication_to_true() {
     reportReader.setMetadata(
       newBatchReportBuilder()
         .setCrossProjectDuplicationActivated(true)
@@ -129,7 +129,7 @@ public class LoadReportAnalysisMetadataHolderStepTest {
   }
 
   @Test
-  public void set_cross_project_duplication_to_false() throws Exception {
+  public void set_cross_project_duplication_to_false() {
     reportReader.setMetadata(
       newBatchReportBuilder()
         .setCrossProjectDuplicationActivated(false)
@@ -141,7 +141,7 @@ public class LoadReportAnalysisMetadataHolderStepTest {
   }
 
   @Test
-  public void set_cross_project_duplication_to_false_when_nothing_in_the_report() throws Exception {
+  public void set_cross_project_duplication_to_false_when_nothing_in_the_report() {
     reportReader.setMetadata(
       newBatchReportBuilder()
         .build());
@@ -207,7 +207,6 @@ public class LoadReportAnalysisMetadataHolderStepTest {
       nonDefaultOrganizationDto.getKey() + ") than the default one (" + dbTester.getDefaultOrganization().getKey() + ")");
 
     underTest.execute();
-
   }
 
   @Test
@@ -259,6 +258,56 @@ public class LoadReportAnalysisMetadataHolderStepTest {
     assertThat(organization.getName()).isEqualTo(nonDefaultOrganizationDto.getName());
   }
 
+  @Test
+  public void execute_ensures_that_report_has_quality_profiles_matching_the_project_organization() {
+    OrganizationDto organization = dbTester.organizations().insert();
+    ScannerReport.Metadata.Builder metadataBuilder = newBatchReportBuilder();
+    metadataBuilder.setOrganizationKey(organization.getKey());
+    metadataBuilder.getMutableQprofilesPerLanguage().put("js", ScannerReport.Metadata.QProfile.newBuilder().setKey("p1").setName("Sonar way").setLanguage("js").build());
+    reportReader.setMetadata(metadataBuilder.build());
+
+    dbTester.qualityProfiles().insert(organization, p -> p.setLanguage("js"), p -> p.setKey("p1"));
+
+    ComputationStep underTest = createStep(createCeTask(PROJECT_KEY, organization.getUuid()));
+
+    // no errors
+    underTest.execute();
+  }
+
+  @Test
+  public void execute_fails_with_MessageException_when_report_has_quality_profiles_on_other_organizations() {
+    OrganizationDto organization1 = dbTester.organizations().insert();
+    OrganizationDto organization2 = dbTester.organizations().insert();
+    ScannerReport.Metadata.Builder metadataBuilder = newBatchReportBuilder();
+    metadataBuilder.setOrganizationKey(organization1.getKey());
+    metadataBuilder.getMutableQprofilesPerLanguage().put("js", ScannerReport.Metadata.QProfile.newBuilder().setKey("jsInOrg1").setName("Sonar way").setLanguage("js").build());
+    metadataBuilder.getMutableQprofilesPerLanguage().put("php", ScannerReport.Metadata.QProfile.newBuilder().setKey("phpInOrg2").setName("PHP way").setLanguage("php").build());
+    reportReader.setMetadata(metadataBuilder.build());
+
+    dbTester.qualityProfiles().insert(organization1, p -> p.setLanguage("js"), p -> p.setKey("jsInOrg1"));
+    dbTester.qualityProfiles().insert(organization2, p -> p.setLanguage("php"), p -> p.setKey("phpInOrg2"));
+
+    ComputationStep underTest = createStep(createCeTask(PROJECT_KEY, organization1.getUuid()));
+
+    expectedException.expect(MessageException.class);
+    expectedException.expectMessage("Quality profiles with following keys don't exist in organization [" + organization1.getKey() + "]: phpInOrg2");
+
+    underTest.execute();
+  }
+
+  @Test
+  public void execute_does_not_fail_when_report_has_a_quality_profile_that_does_not_exist_anymore() {
+    OrganizationDto organization = dbTester.organizations().insert();
+    ScannerReport.Metadata.Builder metadataBuilder = newBatchReportBuilder();
+    metadataBuilder.setOrganizationKey(organization.getKey());
+    metadataBuilder.getMutableQprofilesPerLanguage().put("js", ScannerReport.Metadata.QProfile.newBuilder().setKey("p1").setName("Sonar way").setLanguage("js").build());
+    reportReader.setMetadata(metadataBuilder.build());
+
+    ComputationStep underTest = createStep(createCeTask(PROJECT_KEY, organization.getUuid()));
+
+    underTest.execute();
+  }
+
   private LoadReportAnalysisMetadataHolderStep createStep(CeTask ceTask) {
     return new LoadReportAnalysisMetadataHolderStep(ceTask, reportReader, analysisMetadataHolder, defaultOrganizationProvider, dbClient);
   }