From 9eed1177fe7e25d2705561896a1ddad5ebccabda Mon Sep 17 00:00:00 2001 From: =?utf8?q?S=C3=A9bastien=20Lesaint?= Date: Mon, 9 Jan 2017 15:17:08 +0100 Subject: [PATCH] SONAR-8594 enforce report has same organization key as component --- .../analysis/AnalysisMetadataHolder.java | 6 +- .../analysis/AnalysisMetadataHolderImpl.java | 16 +-- .../MutableAnalysisMetadataHolder.java | 2 +- .../analysis/Organization.java | 81 ++++++++++++++ .../LoadReportAnalysisMetadataHolderStep.java | 56 +++++++++- .../step/PersistComponentsStep.java | 2 +- .../AnalysisMetadataHolderImplTest.java | 22 ++-- .../analysis/AnalysisMetadataHolderRule.java | 23 ++-- .../MutableAnalysisMetadataHolderRule.java | 8 +- .../analysis/OrganizationTest.java | 104 ++++++++++++++++++ ...dReportAnalysisMetadataHolderStepTest.java | 94 ++++++++++++++-- .../step/ReportPersistComponentsStepTest.java | 11 +- .../step/ViewsPersistComponentsStepTest.java | 13 ++- .../src/test/java/org/sonar/db/DbTester.java | 10 +- 14 files changed, 390 insertions(+), 58 deletions(-) create mode 100644 server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/analysis/Organization.java create mode 100644 server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/analysis/OrganizationTest.java diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/analysis/AnalysisMetadataHolder.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/analysis/AnalysisMetadataHolder.java index ac17a209995..597afc55789 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/analysis/AnalysisMetadataHolder.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/analysis/AnalysisMetadataHolder.java @@ -26,10 +26,10 @@ import org.sonar.server.qualityprofile.QualityProfile; public interface AnalysisMetadataHolder { /** - * Returns the UUID of the organization the analysis belongs to. - * @throws IllegalStateException if organization uuid has not been set + * Returns the organization the analysis belongs to. + * @throws IllegalStateException if organization has not been set */ - String getOrganizationUuid(); + Organization getOrganization(); /** * Returns the UUID generated for this analysis. diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/analysis/AnalysisMetadataHolderImpl.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/analysis/AnalysisMetadataHolderImpl.java index a7cbc2b0c11..5e8f2480c8e 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/analysis/AnalysisMetadataHolderImpl.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/analysis/AnalysisMetadataHolderImpl.java @@ -31,7 +31,7 @@ import static java.util.Objects.requireNonNull; public class AnalysisMetadataHolderImpl implements MutableAnalysisMetadataHolder { - private final InitializedProperty organizationUuid = new InitializedProperty<>(); + private final InitializedProperty organization = new InitializedProperty<>(); private final InitializedProperty uuid = new InitializedProperty<>(); private final InitializedProperty analysisDate = new InitializedProperty<>(); private final InitializedProperty baseProjectSnapshot = new InitializedProperty<>(); @@ -41,17 +41,17 @@ public class AnalysisMetadataHolderImpl implements MutableAnalysisMetadataHolder private final InitializedProperty> qProfilesPerLanguage = new InitializedProperty<>(); @Override - public MutableAnalysisMetadataHolder setOrganizationUuid(String organizationUuid) { - checkState(!this.organizationUuid.isInitialized(), "Organization uuid has already been set"); - requireNonNull(organizationUuid, "Organization uuid can't be null"); - this.organizationUuid.setProperty(organizationUuid); + public MutableAnalysisMetadataHolder setOrganization(Organization organization) { + checkState(!this.organization.isInitialized(), "Organization has already been set"); + requireNonNull(organization, "Organization can't be null"); + this.organization.setProperty(organization); return this; } @Override - public String getOrganizationUuid() { - checkState(organizationUuid.isInitialized(), "Organization uuid has not been set"); - return organizationUuid.getProperty(); + public Organization getOrganization() { + checkState(organization.isInitialized(), "Organization has not been set"); + return organization.getProperty(); } @Override diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/analysis/MutableAnalysisMetadataHolder.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/analysis/MutableAnalysisMetadataHolder.java index a2eb10b3362..0f235618d9c 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/analysis/MutableAnalysisMetadataHolder.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/analysis/MutableAnalysisMetadataHolder.java @@ -28,7 +28,7 @@ public interface MutableAnalysisMetadataHolder extends AnalysisMetadataHolder { /** * @throws IllegalStateException if the organization uuid has already been set */ - MutableAnalysisMetadataHolder setOrganizationUuid(String organizationUuid); + MutableAnalysisMetadataHolder setOrganization(Organization organization); /** * @throws IllegalStateException if the analysis uuid has already been set diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/analysis/Organization.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/analysis/Organization.java new file mode 100644 index 00000000000..14c30476971 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/analysis/Organization.java @@ -0,0 +1,81 @@ +/* + * 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.server.computation.task.projectanalysis.analysis; + +import javax.annotation.concurrent.Immutable; +import org.sonar.db.organization.OrganizationDto; + +import static java.util.Objects.requireNonNull; + +@Immutable +public class Organization { + private final String uuid; + private final String key; + private final String name; + + private Organization(String uuid, String key, String name) { + this.uuid = requireNonNull(uuid, "uuid can't be null"); + this.key = requireNonNull(key, "key can't be null"); + this.name = requireNonNull(name, "name can't be null"); + } + + public String getUuid() { + return uuid; + } + + public String getKey() { + return key; + } + + public String getName() { + return name; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Organization that = (Organization) o; + return uuid.equals(that.uuid); + } + + @Override + public int hashCode() { + return uuid.hashCode(); + } + + @Override + public String toString() { + return "Organization{" + + "uuid='" + uuid + '\'' + + ", key='" + key + '\'' + + ", name='" + name + '\'' + + '}'; + } + + public static Organization from(OrganizationDto organizationDto) { + return new Organization(organizationDto.getUuid(), organizationDto.getKey(), organizationDto.getName()); + } + +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/LoadReportAnalysisMetadataHolderStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/LoadReportAnalysisMetadataHolderStep.java index a462ea286af..7e5688c3aa6 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/LoadReportAnalysisMetadataHolderStep.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/LoadReportAnalysisMetadataHolderStep.java @@ -21,15 +21,23 @@ package org.sonar.server.computation.task.projectanalysis.step; import com.google.common.base.Function; import java.util.Date; +import java.util.Optional; +import javax.annotation.Nullable; import org.sonar.api.utils.MessageException; import org.sonar.ce.queue.CeTask; +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; +import org.sonar.db.organization.OrganizationDto; 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; +import org.sonar.server.computation.task.projectanalysis.analysis.Organization; import org.sonar.server.computation.task.projectanalysis.batch.BatchReportReader; import org.sonar.server.computation.task.step.ComputationStep; +import org.sonar.server.organization.DefaultOrganizationProvider; import org.sonar.server.qualityprofile.QualityProfile; +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; @@ -51,11 +59,16 @@ public class LoadReportAnalysisMetadataHolderStep implements ComputationStep { private final CeTask ceTask; private final BatchReportReader reportReader; private final MutableAnalysisMetadataHolder mutableAnalysisMetadataHolder; + private final DefaultOrganizationProvider defaultOrganizationProvider; + private final DbClient dbClient; - public LoadReportAnalysisMetadataHolderStep(CeTask ceTask, BatchReportReader reportReader, MutableAnalysisMetadataHolder mutableAnalysisMetadataHolder) { + public LoadReportAnalysisMetadataHolderStep(CeTask ceTask, BatchReportReader reportReader, MutableAnalysisMetadataHolder mutableAnalysisMetadataHolder, + DefaultOrganizationProvider defaultOrganizationProvider, DbClient dbClient) { this.ceTask = ceTask; this.reportReader = reportReader; this.mutableAnalysisMetadataHolder = mutableAnalysisMetadataHolder; + this.defaultOrganizationProvider = defaultOrganizationProvider; + this.dbClient = dbClient; } @Override @@ -64,12 +77,14 @@ public class LoadReportAnalysisMetadataHolderStep implements ComputationStep { mutableAnalysisMetadataHolder.setAnalysisDate(reportMetadata.getAnalysisDate()); checkProjectKeyConsistency(reportMetadata); + Organization organization = toOrganization(ceTask.getOrganizationUuid()); + checkOrganizationKeyConsistency(reportMetadata, organization); mutableAnalysisMetadataHolder.setRootComponentRef(reportMetadata.getRootComponentRef()); mutableAnalysisMetadataHolder.setBranch(isNotEmpty(reportMetadata.getBranch()) ? reportMetadata.getBranch() : null); mutableAnalysisMetadataHolder.setCrossProjectDuplicationEnabled(reportMetadata.getCrossProjectDuplicationActivated()); mutableAnalysisMetadataHolder.setQProfilesByLanguage(transformValues(reportMetadata.getQprofilesPerLanguage(), TO_COMPUTE_QPROFILE)); - mutableAnalysisMetadataHolder.setOrganizationUuid(ceTask.getOrganizationUuid()); + mutableAnalysisMetadataHolder.setOrganization(organization); } private void checkProjectKeyConsistency(ScannerReport.Metadata reportMetadata) { @@ -88,6 +103,43 @@ public class LoadReportAnalysisMetadataHolderStep implements ComputationStep { } } + private void checkOrganizationKeyConsistency(ScannerReport.Metadata reportMetadata, Organization organization) { + String organizationKey = reportMetadata.getOrganizationKey(); + String resolveReportOrganizationKey = resolveReportOrganizationKey(organizationKey); + if (!resolveReportOrganizationKey.equals(organization.getKey())) { + if (reportBelongsToDefaultOrganization(organizationKey)) { + throw MessageException.of(format( + "Report does not specify an OrganizationKey but it has been submitted to another organization (%s) than the default one (%s)", + organization.getKey(), + defaultOrganizationProvider.get().getKey())); + } else { + throw MessageException.of(format( + "OrganizationKey in report (%s) is not consistent with organizationKey under which the report as been submitted (%s)", + resolveReportOrganizationKey, + organization.getKey())); + } + } + } + + private String resolveReportOrganizationKey(@Nullable String organizationKey) { + if (reportBelongsToDefaultOrganization(organizationKey)) { + return defaultOrganizationProvider.get().getKey(); + } + return organizationKey; + } + + private static boolean reportBelongsToDefaultOrganization(@Nullable String organizationKey) { + return organizationKey == null || organizationKey.isEmpty(); + } + + private Organization toOrganization(String organizationUuid) { + try (DbSession dbSession = dbClient.openSession(false)) { + Optional organizationDto = dbClient.organizationDao().selectByUuid(dbSession, organizationUuid); + checkState(organizationDto.isPresent(), "Organization with uuid '{}' can't be found", organizationUuid); + return Organization.from(organizationDto.get()); + } + } + private static String projectKeyFromReport(ScannerReport.Metadata reportMetadata) { if (isNotEmpty(reportMetadata.getBranch())) { return reportMetadata.getProjectKey() + ":" + reportMetadata.getBranch(); diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/PersistComponentsStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/PersistComponentsStep.java index f2aca095f74..d37be056897 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/PersistComponentsStep.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/PersistComponentsStep.java @@ -348,7 +348,7 @@ public class PersistComponentsStep implements ComputationStep { String componentUuid = component.getUuid(); ComponentDto componentDto = new ComponentDto(); - componentDto.setOrganizationUuid(analysisMetadataHolder.getOrganizationUuid()); + componentDto.setOrganizationUuid(analysisMetadataHolder.getOrganization().getUuid()); componentDto.setUuid(componentUuid); componentDto.setKey(componentKey); componentDto.setDeprecatedKey(componentKey); diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/analysis/AnalysisMetadataHolderImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/analysis/AnalysisMetadataHolderImplTest.java index cbf7871a050..d5cf696cc17 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/analysis/AnalysisMetadataHolderImplTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/analysis/AnalysisMetadataHolderImplTest.java @@ -22,6 +22,7 @@ package org.sonar.server.computation.task.projectanalysis.analysis; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; +import org.sonar.db.organization.OrganizationDto; import static org.assertj.core.api.Assertions.assertThat; @@ -40,29 +41,30 @@ public class AnalysisMetadataHolderImplTest { private AnalysisMetadataHolderImpl underTest = new AnalysisMetadataHolderImpl(); @Test - public void getOrganizationUuid_throws_ISE_if_organization_uuid_is_not_set() { + public void getOrganization_throws_ISE_if_organization_is_not_set() { expectedException.expect(IllegalStateException.class); - expectedException.expectMessage("Organization uuid has not been set"); + expectedException.expectMessage("Organization has not been set"); - underTest.getOrganizationUuid(); + underTest.getOrganization(); } @Test - public void setOrganizationUuid_throws_NPE_is_parameter_is_null() { + public void setOrganization_throws_NPE_is_parameter_is_null() { expectedException.expect(NullPointerException.class); - expectedException.expectMessage("Organization uuid can't be null"); + expectedException.expectMessage("Organization can't be null"); - underTest.setOrganizationUuid(null); + underTest.setOrganization(null); } @Test - public void setOrganizationUuid_throws_ISE_if_called_twice() { - underTest.setOrganizationUuid("org1"); + public void setOrganization_throws_ISE_if_called_twice() { + Organization organization = Organization.from(new OrganizationDto().setUuid("uuid").setKey("key").setName("name")); + underTest.setOrganization(organization); expectedException.expect(IllegalStateException.class); - expectedException.expectMessage("Organization uuid has already been set"); + expectedException.expectMessage("Organization has already been set"); - underTest.setOrganizationUuid("org1"); + underTest.setOrganization(organization); } @Test diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/analysis/AnalysisMetadataHolderRule.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/analysis/AnalysisMetadataHolderRule.java index da9e4cf68c6..5762e130723 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/analysis/AnalysisMetadataHolderRule.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/analysis/AnalysisMetadataHolderRule.java @@ -21,19 +21,20 @@ package org.sonar.server.computation.task.projectanalysis.analysis; import java.util.Date; import java.util.Map; -import java.util.Objects; import javax.annotation.CheckForNull; import javax.annotation.Nullable; import org.junit.rules.ExternalResource; +import org.sonar.db.organization.OrganizationDto; import org.sonar.server.computation.util.InitializedProperty; import org.sonar.server.qualityprofile.QualityProfile; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; +import static java.util.Objects.requireNonNull; public class AnalysisMetadataHolderRule extends ExternalResource implements MutableAnalysisMetadataHolder { - private final InitializedProperty organizationUuid = new InitializedProperty<>(); + private final InitializedProperty organization = new InitializedProperty<>(); private final InitializedProperty uuid = new InitializedProperty<>(); @@ -50,16 +51,22 @@ public class AnalysisMetadataHolderRule extends ExternalResource implements Muta private final InitializedProperty> qProfilesPerLanguage = new InitializedProperty<>(); @Override - public AnalysisMetadataHolderRule setOrganizationUuid(String organizationUuid) { - Objects.requireNonNull(organizationUuid, "organizationUuid can't be null"); - this.organizationUuid.setProperty(organizationUuid); + public AnalysisMetadataHolderRule setOrganization(Organization organization) { + requireNonNull(organization, "organization can't be null"); + this.organization.setProperty(organization); + return this; + } + + public AnalysisMetadataHolderRule setOrganizationUuid(String uuid) { + requireNonNull(uuid, "organization uuid can't be null"); + this.organization.setProperty(Organization.from(new OrganizationDto().setUuid(uuid).setKey("key_" + uuid).setName("name_" + uuid))); return this; } @Override - public String getOrganizationUuid() { - checkState(organizationUuid.isInitialized(), "Organization UUID has not been set"); - return this.organizationUuid.getProperty(); + public Organization getOrganization() { + checkState(organization.isInitialized(), "Organization has not been set"); + return this.organization.getProperty(); } @Override diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/analysis/MutableAnalysisMetadataHolderRule.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/analysis/MutableAnalysisMetadataHolderRule.java index 46a2a4b017b..b94948895d1 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/analysis/MutableAnalysisMetadataHolderRule.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/analysis/MutableAnalysisMetadataHolderRule.java @@ -35,13 +35,13 @@ public class MutableAnalysisMetadataHolderRule extends ExternalResource implemen } @Override - public MutableAnalysisMetadataHolder setOrganizationUuid(String organizationUuid) { - return delegate.setOrganizationUuid(organizationUuid); + public MutableAnalysisMetadataHolder setOrganization(Organization organization) { + return delegate.setOrganization(organization); } @Override - public String getOrganizationUuid() { - return delegate.getOrganizationUuid(); + public Organization getOrganization() { + return delegate.getOrganization(); } public MutableAnalysisMetadataHolderRule setUuid(String s) { diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/analysis/OrganizationTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/analysis/OrganizationTest.java new file mode 100644 index 00000000000..b0e91368799 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/analysis/OrganizationTest.java @@ -0,0 +1,104 @@ +/* + * 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.server.computation.task.projectanalysis.analysis; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.db.organization.OrganizationDto; + +import static org.assertj.core.api.Assertions.assertThat; + +public class OrganizationTest { + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + private OrganizationDto underTest = new OrganizationDto(); + + @Test + public void build_throws_NPE_if_dto_is_null() { + expectedException.expect(NullPointerException.class); + + Organization.from(null); + } + + @Test + public void build_throws_NPE_if_uuid_is_null() { + expectedException.expect(NullPointerException.class); + expectedException.expectMessage("uuid can't be null"); + + Organization.from(underTest); + } + + @Test + public void build_throws_NPE_if_key_is_null() { + underTest.setUuid("uuid"); + + expectedException.expect(NullPointerException.class); + expectedException.expectMessage("key can't be null"); + + Organization.from(underTest); + } + + @Test + public void build_throws_NPE_if_name_is_null() { + underTest.setUuid("uuid").setKey("key"); + + expectedException.expect(NullPointerException.class); + expectedException.expectMessage("name can't be null"); + + Organization.from(underTest); + } + + @Test + public void verify_getters() { + Organization organization = Organization.from(underTest.setUuid("uuid").setKey("key").setName("name")); + + assertThat(organization.getUuid()).isEqualTo("uuid"); + assertThat(organization.getKey()).isEqualTo("key"); + assertThat(organization.getName()).isEqualTo("name"); + } + + @Test + public void verify_toString() { + Organization organization = Organization.from(underTest.setUuid("uuid").setKey("key").setName("name")); + + assertThat(organization.toString()).isEqualTo("Organization{uuid='uuid', key='key', name='name'}"); + } + + @Test + public void equals_is_based_on_uuid_only() { + Organization organization = Organization.from(underTest.setUuid("uuid").setKey("key").setName("name")); + + assertThat(organization).isEqualTo(Organization.from(underTest.setUuid("uuid").setKey("key").setName("name"))); + assertThat(organization).isEqualTo(Organization.from(underTest.setUuid("uuid").setKey("other key").setName("name"))); + assertThat(organization).isEqualTo(Organization.from(underTest.setUuid("uuid").setKey("key").setName("other name"))); + assertThat(organization).isNotEqualTo(Organization.from(underTest.setUuid("other uuid").setKey("key").setName("name"))); + assertThat(organization).isNotEqualTo(null); + assertThat(organization).isNotEqualTo("toto"); + } + + @Test + public void hashcode_is_based_on_uuid_only() { + Organization organization = Organization.from(underTest.setUuid("uuid").setKey("key").setName("name")); + + assertThat(organization.hashCode()).isEqualTo("uuid".hashCode()); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/LoadReportAnalysisMetadataHolderStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/LoadReportAnalysisMetadataHolderStepTest.java index d8447d71b5f..fd19dbb75ba 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/LoadReportAnalysisMetadataHolderStepTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/LoadReportAnalysisMetadataHolderStepTest.java @@ -19,15 +19,23 @@ */ package org.sonar.server.computation.task.projectanalysis.step; +import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.sonar.api.utils.MessageException; +import org.sonar.api.utils.System2; import org.sonar.ce.queue.CeTask; +import org.sonar.db.DbClient; +import org.sonar.db.DbTester; +import org.sonar.db.organization.OrganizationDto; import org.sonar.scanner.protocol.output.ScannerReport; import org.sonar.server.computation.task.projectanalysis.analysis.MutableAnalysisMetadataHolderRule; +import org.sonar.server.computation.task.projectanalysis.analysis.Organization; import org.sonar.server.computation.task.projectanalysis.batch.BatchReportReaderRule; import org.sonar.server.computation.task.step.ComputationStep; +import org.sonar.server.organization.DefaultOrganizationProvider; +import org.sonar.server.organization.TestDefaultOrganizationProvider; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; @@ -39,6 +47,8 @@ public class LoadReportAnalysisMetadataHolderStepTest { private static final String BRANCH = "origin/master"; private static final long ANALYSIS_DATE = 123456789L; + @Rule + public DbTester dbTester = DbTester.create(System2.INSTANCE); @Rule public BatchReportReaderRule reportReader = new BatchReportReaderRule(); @Rule @@ -46,8 +56,15 @@ public class LoadReportAnalysisMetadataHolderStepTest { @Rule public ExpectedException expectedException = ExpectedException.none(); - private CeTask ceTask = createCeTask(PROJECT_KEY); - private ComputationStep underTest = new LoadReportAnalysisMetadataHolderStep(ceTask, reportReader, analysisMetadataHolder); + private DbClient dbClient = dbTester.getDbClient(); + private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(dbTester); + private ComputationStep underTest; + + @Before + public void setUp() throws Exception { + CeTask defaultOrgCeTask = createCeTask(PROJECT_KEY, dbTester.getDefaultOrganization().getUuid()); + underTest = createStep(defaultOrgCeTask); + } @Test public void set_root_component_ref() throws Exception { @@ -80,8 +97,8 @@ public class LoadReportAnalysisMetadataHolderStepTest { .setBranch(BRANCH) .build()); - CeTask ceTask = createCeTask(PROJECT_KEY + ":" + BRANCH); - ComputationStep underTest = new LoadReportAnalysisMetadataHolderStep(ceTask, reportReader, analysisMetadataHolder); + CeTask ceTask = createCeTask(PROJECT_KEY + ":" + BRANCH, dbTester.getDefaultOrganization().getUuid()); + ComputationStep underTest = createStep(ceTask); underTest.execute(); @@ -140,7 +157,7 @@ public class LoadReportAnalysisMetadataHolderStepTest { when(res.getComponentUuid()).thenReturn("prj_uuid"); reportReader.setMetadata(ScannerReport.Metadata.newBuilder().build()); - ComputationStep underTest = new LoadReportAnalysisMetadataHolderStep(res, reportReader, analysisMetadataHolder); + ComputationStep underTest = createStep(res); expectedException.expect(MessageException.class); expectedException.expectMessage("Compute Engine task component key is null. Project with UUID prj_uuid must have been deleted since report was uploaded. Can not proceed."); @@ -177,14 +194,73 @@ public class LoadReportAnalysisMetadataHolderStepTest { } @Test - public void execute_set_organization_uuid_from_ce_task() { + public void execute_fails_with_MessageException_when_report_has_no_organizationKey_but_does_not_belong_to_the_default_organization() { + reportReader.setMetadata( + newBatchReportBuilder() + .build()); + OrganizationDto nonDefaultOrganizationDto = dbTester.organizations().insert(); + + ComputationStep underTest = createStep(createCeTask(PROJECT_KEY, nonDefaultOrganizationDto.getUuid())); + + expectedException.expect(MessageException.class); + expectedException.expectMessage("Report does not specify an OrganizationKey but it has been submitted to another organization (" + + nonDefaultOrganizationDto.getKey() + ") than the default one (" + dbTester.getDefaultOrganization().getKey() + ")"); + + underTest.execute(); + + } + + @Test + public void execute_set_organization_from_ce_task_when_organizationKey_is_not_set_in_report() { + reportReader.setMetadata( + newBatchReportBuilder() + .build()); + + underTest.execute(); + + Organization organization = analysisMetadataHolder.getOrganization(); + OrganizationDto defaultOrganization = dbTester.getDefaultOrganization(); + assertThat(organization.getUuid()).isEqualTo(defaultOrganization.getUuid()); + assertThat(organization.getKey()).isEqualTo(defaultOrganization.getKey()); + assertThat(organization.getName()).isEqualTo(defaultOrganization.getName()); + } + + @Test + public void execute_set_organization_from_ce_task_when_organizationKey_is_set_in_report() { + reportReader.setMetadata( + newBatchReportBuilder() + .setOrganizationKey(dbTester.getDefaultOrganization().getKey()) + .build()); + + underTest.execute(); + + Organization organization = analysisMetadataHolder.getOrganization(); + OrganizationDto defaultOrganization = dbTester.getDefaultOrganization(); + assertThat(organization.getUuid()).isEqualTo(defaultOrganization.getUuid()); + assertThat(organization.getKey()).isEqualTo(defaultOrganization.getKey()); + assertThat(organization.getName()).isEqualTo(defaultOrganization.getName()); + } + + @Test + public void execute_set_non_default_organization_from_ce_task() { + OrganizationDto nonDefaultOrganizationDto = dbTester.organizations().insert(); reportReader.setMetadata( newBatchReportBuilder() + .setOrganizationKey(nonDefaultOrganizationDto.getKey()) .build()); + ComputationStep underTest = createStep(createCeTask(PROJECT_KEY, nonDefaultOrganizationDto.getUuid())); + underTest.execute(); - assertThat(analysisMetadataHolder.getOrganizationUuid()).isEqualTo(ceTask.getOrganizationUuid()); + Organization organization = analysisMetadataHolder.getOrganization(); + assertThat(organization.getUuid()).isEqualTo(nonDefaultOrganizationDto.getUuid()); + assertThat(organization.getKey()).isEqualTo(nonDefaultOrganizationDto.getKey()); + assertThat(organization.getName()).isEqualTo(nonDefaultOrganizationDto.getName()); + } + + private LoadReportAnalysisMetadataHolderStep createStep(CeTask ceTask) { + return new LoadReportAnalysisMetadataHolderStep(ceTask, reportReader, analysisMetadataHolder, defaultOrganizationProvider, dbClient); } private static ScannerReport.Metadata.Builder newBatchReportBuilder() { @@ -192,9 +268,9 @@ public class LoadReportAnalysisMetadataHolderStepTest { .setProjectKey(PROJECT_KEY); } - private CeTask createCeTask(String projectKey) { + private CeTask createCeTask(String projectKey, String organizationUuid) { CeTask res = mock(CeTask.class); - when(res.getOrganizationUuid()).thenReturn("org1"); + when(res.getOrganizationUuid()).thenReturn(organizationUuid); when(res.getComponentKey()).thenReturn(projectKey); return res; } diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/ReportPersistComponentsStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/ReportPersistComponentsStepTest.java index 11cbcef29ae..3c6c83ddea8 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/ReportPersistComponentsStepTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/ReportPersistComponentsStepTest.java @@ -56,6 +56,7 @@ public class ReportPersistComponentsStepTest extends BaseStepTest { private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd"); private static final String PROJECT_KEY = "PROJECT_KEY"; private static final String MODULE_KEY = "MODULE_KEY"; + private static final String ORGANIZATION_UUID = "org1"; @Rule public DbTester dbTester = DbTester.create(System2.INSTANCE); @@ -65,7 +66,7 @@ public class ReportPersistComponentsStepTest extends BaseStepTest { public MutableDbIdsRepositoryRule dbIdsRepository = MutableDbIdsRepositoryRule.create(treeRootHolder); @Rule public AnalysisMetadataHolderRule analysisMetadataHolder = new AnalysisMetadataHolderRule() - .setOrganizationUuid("org1"); + .setOrganizationUuid(ORGANIZATION_UUID); private System2 system2 = mock(System2.class); private DbClient dbClient = dbTester.getDbClient(); @@ -114,7 +115,7 @@ public class ReportPersistComponentsStepTest extends BaseStepTest { assertThat(dbTester.countRowsOfTable("projects")).isEqualTo(4); ComponentDto projectDto = dbClient.componentDao().selectByKey(dbTester.getSession(), PROJECT_KEY).get(); - assertThat(projectDto.getOrganizationUuid()).isEqualTo(analysisMetadataHolder.getOrganizationUuid()); + assertThat(projectDto.getOrganizationUuid()).isEqualTo(ORGANIZATION_UUID); assertThat(projectDto.name()).isEqualTo("Project"); assertThat(projectDto.description()).isEqualTo("Project description"); assertThat(projectDto.path()).isNull(); @@ -129,7 +130,7 @@ public class ReportPersistComponentsStepTest extends BaseStepTest { assertThat(projectDto.getCreatedAt()).isEqualTo(now); ComponentDto moduleDto = dbClient.componentDao().selectByKey(dbTester.getSession(), MODULE_KEY).get(); - assertThat(moduleDto.getOrganizationUuid()).isEqualTo(analysisMetadataHolder.getOrganizationUuid()); + assertThat(moduleDto.getOrganizationUuid()).isEqualTo(ORGANIZATION_UUID); assertThat(moduleDto.name()).isEqualTo("Module"); assertThat(moduleDto.description()).isEqualTo("Module description"); assertThat(moduleDto.path()).isEqualTo("module"); @@ -144,7 +145,7 @@ public class ReportPersistComponentsStepTest extends BaseStepTest { assertThat(moduleDto.getCreatedAt()).isEqualTo(now); ComponentDto directoryDto = dbClient.componentDao().selectByKey(dbTester.getSession(), "MODULE_KEY:src/main/java/dir").get(); - assertThat(directoryDto.getOrganizationUuid()).isEqualTo(analysisMetadataHolder.getOrganizationUuid()); + assertThat(directoryDto.getOrganizationUuid()).isEqualTo(ORGANIZATION_UUID); assertThat(directoryDto.name()).isEqualTo("src/main/java/dir"); assertThat(directoryDto.description()).isNull(); assertThat(directoryDto.path()).isEqualTo("src/main/java/dir"); @@ -159,7 +160,7 @@ public class ReportPersistComponentsStepTest extends BaseStepTest { assertThat(directoryDto.getCreatedAt()).isEqualTo(now); ComponentDto fileDto = dbClient.componentDao().selectByKey(dbTester.getSession(), "MODULE_KEY:src/main/java/dir/Foo.java").get(); - assertThat(fileDto.getOrganizationUuid()).isEqualTo(analysisMetadataHolder.getOrganizationUuid()); + assertThat(fileDto.getOrganizationUuid()).isEqualTo(ORGANIZATION_UUID); assertThat(fileDto.name()).isEqualTo("Foo.java"); assertThat(fileDto.description()).isNull(); assertThat(fileDto.path()).isEqualTo("src/main/java/dir/Foo.java"); diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/ViewsPersistComponentsStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/ViewsPersistComponentsStepTest.java index 9ae3035e18b..d8fd3c2df60 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/ViewsPersistComponentsStepTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/ViewsPersistComponentsStepTest.java @@ -65,6 +65,7 @@ public class ViewsPersistComponentsStepTest extends BaseStepTest { private static final String PROJECT_VIEW_1_KEY = "PV1_KEY"; private static final String PROJECT_VIEW_1_NAME = "PV1_NAME"; private static final String PROJECT_VIEW_1_UUID = "PV1_UUID"; + private static final String ORGANIZATION_UUID = "org1"; @Rule public DbTester dbTester = DbTester.create(System2.INSTANCE); @@ -74,7 +75,7 @@ public class ViewsPersistComponentsStepTest extends BaseStepTest { public MutableDbIdsRepositoryRule dbIdsRepository = MutableDbIdsRepositoryRule.create(treeRootHolder); @Rule public AnalysisMetadataHolderRule analysisMetadataHolder = new AnalysisMetadataHolderRule() - .setOrganizationUuid("org1"); + .setOrganizationUuid(ORGANIZATION_UUID); private System2 system2 = mock(System2.class); private DbClient dbClient = dbTester.getDbClient(); @@ -250,7 +251,7 @@ public class ViewsPersistComponentsStepTest extends BaseStepTest { ComponentDto project = newProjectDto(); persistComponents(view, project); ComponentDto projectView = ComponentTesting.newProjectCopy(PROJECT_VIEW_1_UUID, project, view) - .setOrganizationUuid(analysisMetadataHolder.getOrganizationUuid()) + .setOrganizationUuid(ORGANIZATION_UUID) .setKey(PROJECT_VIEW_1_KEY) .setName("Old name") .setCreatedAt(now); @@ -336,7 +337,7 @@ public class ViewsPersistComponentsStepTest extends BaseStepTest { private ComponentDto newViewDto() { return ComponentTesting.newView(VIEW_UUID) - .setOrganizationUuid(analysisMetadataHolder.getOrganizationUuid()) + .setOrganizationUuid(ORGANIZATION_UUID) .setKey(VIEW_KEY) .setName(VIEW_NAME); } @@ -345,7 +346,7 @@ public class ViewsPersistComponentsStepTest extends BaseStepTest { * Assertions to verify the DTO created from {@link #createViewBuilder()} */ private void assertDtoIsView(ComponentDto projectDto) { - assertThat(projectDto.getOrganizationUuid()).isEqualTo(analysisMetadataHolder.getOrganizationUuid()); + assertThat(projectDto.getOrganizationUuid()).isEqualTo(ORGANIZATION_UUID); assertThat(projectDto.name()).isEqualTo(VIEW_NAME); assertThat(projectDto.longName()).isEqualTo(VIEW_NAME); assertThat(projectDto.description()).isEqualTo(VIEW_DESCRIPTION); @@ -365,7 +366,7 @@ public class ViewsPersistComponentsStepTest extends BaseStepTest { * Assertions to verify the DTO created from {@link #createProjectView1Builder(ComponentDto, Long)} */ private void assertDtoIsSubView1(ComponentDto viewDto, ComponentDto sv1Dto) { - assertThat(sv1Dto.getOrganizationUuid()).isEqualTo(analysisMetadataHolder.getOrganizationUuid()); + assertThat(sv1Dto.getOrganizationUuid()).isEqualTo(ORGANIZATION_UUID); assertThat(sv1Dto.name()).isEqualTo(SUBVIEW_1_NAME); assertThat(sv1Dto.longName()).isEqualTo(SUBVIEW_1_NAME); assertThat(sv1Dto.description()).isEqualTo(SUBVIEW_1_DESCRIPTION); @@ -382,7 +383,7 @@ public class ViewsPersistComponentsStepTest extends BaseStepTest { } private void assertDtoIsProjectView1(ComponentDto pv1Dto, ComponentDto viewDto, ComponentDto parentViewDto, ComponentDto project) { - assertThat(pv1Dto.getOrganizationUuid()).isEqualTo(analysisMetadataHolder.getOrganizationUuid()); + assertThat(pv1Dto.getOrganizationUuid()).isEqualTo(ORGANIZATION_UUID); assertThat(pv1Dto.name()).isEqualTo(PROJECT_VIEW_1_NAME); assertThat(pv1Dto.longName()).isEqualTo(PROJECT_VIEW_1_NAME); assertThat(pv1Dto.description()).isNull(); diff --git a/sonar-db/src/test/java/org/sonar/db/DbTester.java b/sonar-db/src/test/java/org/sonar/db/DbTester.java index 970e8756171..b17260ca654 100644 --- a/sonar-db/src/test/java/org/sonar/db/DbTester.java +++ b/sonar-db/src/test/java/org/sonar/db/DbTester.java @@ -84,6 +84,7 @@ import static com.google.common.collect.Lists.newArrayList; import static com.google.common.collect.Maps.newHashMap; import static java.sql.ResultSetMetaData.columnNoNulls; import static java.sql.ResultSetMetaData.columnNullable; +import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.fail; @@ -100,6 +101,7 @@ public class DbTester extends ExternalResource { private DbSession session = null; private boolean disableDefaultOrganization = false; private boolean started = false; + private String defaultOrganizationUuid = randomAlphanumeric(40); private OrganizationDto defaultOrganization; private final UserDbTester userTester; @@ -163,6 +165,12 @@ public class DbTester extends ExternalResource { return this; } + public DbTester setDefaultOrganizationUuid(String uuid) { + checkState(!started, "DbTester is already started"); + this.defaultOrganizationUuid = uuid; + return this; + } + @Override protected void before() throws Throwable { db.start(); @@ -175,7 +183,7 @@ public class DbTester extends ExternalResource { } private void insertDefaultOrganization() { - defaultOrganization = OrganizationTesting.newOrganizationDto(); + defaultOrganization = OrganizationTesting.newOrganizationDto().setUuid(defaultOrganizationUuid); try (DbSession dbSession = db.getMyBatis().openSession(false)) { client.organizationDao().insert(dbSession, defaultOrganization); client.internalPropertiesDao().save(dbSession, "organization.default", defaultOrganization.getUuid()); -- 2.39.5