3 * Copyright (C) 2009-2017 SonarSource SA
4 * mailto:info AT sonarsource DOT com
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 3 of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 package org.sonar.server.computation.task.projectanalysis.step;
22 import org.junit.Before;
23 import org.junit.Rule;
24 import org.junit.Test;
25 import org.junit.rules.ExpectedException;
26 import org.mockito.ArgumentCaptor;
27 import org.sonar.api.utils.MessageException;
28 import org.sonar.api.utils.System2;
29 import org.sonar.ce.queue.CeTask;
30 import org.sonar.db.DbClient;
31 import org.sonar.db.DbTester;
32 import org.sonar.db.organization.OrganizationDto;
33 import org.sonar.scanner.protocol.output.ScannerReport;
34 import org.sonar.server.computation.task.projectanalysis.analysis.MutableAnalysisMetadataHolderRule;
35 import org.sonar.server.computation.task.projectanalysis.analysis.Organization;
36 import org.sonar.server.computation.task.projectanalysis.batch.BatchReportReaderRule;
37 import org.sonar.server.computation.task.step.ComputationStep;
38 import org.sonar.server.organization.BillingValidations;
39 import org.sonar.server.organization.BillingValidations.BillingValidationsException;
40 import org.sonar.server.organization.BillingValidationsProxy;
41 import org.sonar.server.organization.DefaultOrganizationProvider;
42 import org.sonar.server.organization.TestDefaultOrganizationProvider;
44 import static org.assertj.core.api.Assertions.assertThat;
45 import static org.mockito.Matchers.any;
46 import static org.mockito.Mockito.doThrow;
47 import static org.mockito.Mockito.mock;
48 import static org.mockito.Mockito.verify;
49 import static org.mockito.Mockito.when;
51 public class LoadReportAnalysisMetadataHolderStepTest {
53 private static final String PROJECT_KEY = "project_key";
54 private static final String BRANCH = "origin/master";
55 private static final long ANALYSIS_DATE = 123456789L;
58 public DbTester dbTester = DbTester.create(System2.INSTANCE);
60 public BatchReportReaderRule reportReader = new BatchReportReaderRule();
62 public MutableAnalysisMetadataHolderRule analysisMetadataHolder = new MutableAnalysisMetadataHolderRule();
64 public ExpectedException expectedException = ExpectedException.none();
66 private DbClient dbClient = dbTester.getDbClient();
67 private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(dbTester);
68 private BillingValidationsProxy billingValidations = mock(BillingValidationsProxy.class);
69 private ComputationStep underTest;
73 CeTask defaultOrgCeTask = createCeTask(PROJECT_KEY, dbTester.getDefaultOrganization().getUuid());
74 underTest = createStep(defaultOrgCeTask);
78 public void set_root_component_ref() {
79 reportReader.setMetadata(
80 newBatchReportBuilder()
81 .setRootComponentRef(1)
86 assertThat(analysisMetadataHolder.getRootComponentRef()).isEqualTo(1);
90 public void set_analysis_date() {
91 reportReader.setMetadata(
92 newBatchReportBuilder()
93 .setAnalysisDate(ANALYSIS_DATE)
98 assertThat(analysisMetadataHolder.getAnalysisDate()).isEqualTo(ANALYSIS_DATE);
102 public void set_branch() {
103 reportReader.setMetadata(
104 newBatchReportBuilder()
108 CeTask ceTask = createCeTask(PROJECT_KEY + ":" + BRANCH, dbTester.getDefaultOrganization().getUuid());
109 ComputationStep underTest = createStep(ceTask);
113 assertThat(analysisMetadataHolder.getBranch()).isEqualTo(BRANCH);
117 public void set_null_branch_when_nothing_in_the_report() {
118 reportReader.setMetadata(
119 newBatchReportBuilder()
124 assertThat(analysisMetadataHolder.getBranch()).isNull();
128 public void set_cross_project_duplication_to_true() {
129 reportReader.setMetadata(
130 newBatchReportBuilder()
131 .setCrossProjectDuplicationActivated(true)
136 assertThat(analysisMetadataHolder.isCrossProjectDuplicationEnabled()).isEqualTo(true);
140 public void set_cross_project_duplication_to_false() {
141 reportReader.setMetadata(
142 newBatchReportBuilder()
143 .setCrossProjectDuplicationActivated(false)
148 assertThat(analysisMetadataHolder.isCrossProjectDuplicationEnabled()).isEqualTo(false);
152 public void set_incremental_analysis_to_true() {
153 reportReader.setMetadata(
154 newBatchReportBuilder()
155 .setIncremental(true)
160 assertThat(analysisMetadataHolder.isIncrementalAnalysis()).isTrue();
164 public void set_incremental_analysis_to_false() {
165 reportReader.setMetadata(
166 newBatchReportBuilder()
167 .setIncremental(false)
172 assertThat(analysisMetadataHolder.isIncrementalAnalysis()).isFalse();
177 public void set_cross_project_duplication_to_false_when_nothing_in_the_report() {
178 reportReader.setMetadata(
179 newBatchReportBuilder()
184 assertThat(analysisMetadataHolder.isCrossProjectDuplicationEnabled()).isEqualTo(false);
188 public void execute_fails_with_MessageException_if_projectKey_is_null_in_CE_task() {
189 CeTask res = mock(CeTask.class);
190 when(res.getComponentUuid()).thenReturn("prj_uuid");
191 reportReader.setMetadata(ScannerReport.Metadata.newBuilder().build());
193 ComputationStep underTest = createStep(res);
195 expectedException.expect(MessageException.class);
196 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.");
202 public void execute_fails_with_MessageException_when_projectKey_in_report_is_different_from_componentKey_in_CE_task() {
203 reportReader.setMetadata(
204 ScannerReport.Metadata.newBuilder()
205 .setProjectKey("some other key")
208 expectedException.expect(MessageException.class);
209 expectedException.expectMessage("ProjectKey in report (some other key) is not consistent with projectKey under which the report as been submitted (" + PROJECT_KEY + ")");
215 public void execute_sets_analysis_date_even_if_MessageException_is_thrown_because_projectKey_is_different_from_componentKey_in_CE_task() {
216 reportReader.setMetadata(
217 ScannerReport.Metadata.newBuilder()
218 .setProjectKey("some other key")
219 .setAnalysisDate(ANALYSIS_DATE)
224 } catch (MessageException e) {
225 assertThat(analysisMetadataHolder.getAnalysisDate()).isEqualTo(ANALYSIS_DATE);
230 public void execute_fails_with_MessageException_when_report_has_no_organizationKey_but_does_not_belong_to_the_default_organization() {
231 reportReader.setMetadata(
232 newBatchReportBuilder()
234 OrganizationDto nonDefaultOrganizationDto = dbTester.organizations().insert();
236 ComputationStep underTest = createStep(createCeTask(PROJECT_KEY, nonDefaultOrganizationDto.getUuid()));
238 expectedException.expect(MessageException.class);
239 expectedException.expectMessage("Report does not specify an OrganizationKey but it has been submitted to another organization (" +
240 nonDefaultOrganizationDto.getKey() + ") than the default one (" + dbTester.getDefaultOrganization().getKey() + ")");
246 public void execute_set_organization_from_ce_task_when_organizationKey_is_not_set_in_report() {
247 reportReader.setMetadata(
248 newBatchReportBuilder()
253 Organization organization = analysisMetadataHolder.getOrganization();
254 OrganizationDto defaultOrganization = dbTester.getDefaultOrganization();
255 assertThat(organization.getUuid()).isEqualTo(defaultOrganization.getUuid());
256 assertThat(organization.getKey()).isEqualTo(defaultOrganization.getKey());
257 assertThat(organization.getName()).isEqualTo(defaultOrganization.getName());
261 public void execute_set_organization_from_ce_task_when_organizationKey_is_set_in_report() {
262 reportReader.setMetadata(
263 newBatchReportBuilder()
264 .setOrganizationKey(dbTester.getDefaultOrganization().getKey())
269 Organization organization = analysisMetadataHolder.getOrganization();
270 OrganizationDto defaultOrganization = dbTester.getDefaultOrganization();
271 assertThat(organization.getUuid()).isEqualTo(defaultOrganization.getUuid());
272 assertThat(organization.getKey()).isEqualTo(defaultOrganization.getKey());
273 assertThat(organization.getName()).isEqualTo(defaultOrganization.getName());
277 public void execute_set_non_default_organization_from_ce_task() {
278 OrganizationDto nonDefaultOrganizationDto = dbTester.organizations().insert();
279 reportReader.setMetadata(
280 newBatchReportBuilder()
281 .setOrganizationKey(nonDefaultOrganizationDto.getKey())
284 ComputationStep underTest = createStep(createCeTask(PROJECT_KEY, nonDefaultOrganizationDto.getUuid()));
288 Organization organization = analysisMetadataHolder.getOrganization();
289 assertThat(organization.getUuid()).isEqualTo(nonDefaultOrganizationDto.getUuid());
290 assertThat(organization.getKey()).isEqualTo(nonDefaultOrganizationDto.getKey());
291 assertThat(organization.getName()).isEqualTo(nonDefaultOrganizationDto.getName());
295 public void execute_ensures_that_report_has_quality_profiles_matching_the_project_organization() {
296 OrganizationDto organization = dbTester.organizations().insert();
297 ScannerReport.Metadata.Builder metadataBuilder = newBatchReportBuilder();
298 metadataBuilder.setOrganizationKey(organization.getKey());
299 metadataBuilder.getMutableQprofilesPerLanguage().put("js", ScannerReport.Metadata.QProfile.newBuilder().setKey("p1").setName("Sonar way").setLanguage("js").build());
300 reportReader.setMetadata(metadataBuilder.build());
302 dbTester.qualityProfiles().insert(organization, p -> p.setLanguage("js").setKee("p1"));
304 ComputationStep underTest = createStep(createCeTask(PROJECT_KEY, organization.getUuid()));
311 public void execute_fails_with_MessageException_when_report_has_quality_profiles_on_other_organizations() {
312 OrganizationDto organization1 = dbTester.organizations().insert();
313 OrganizationDto organization2 = dbTester.organizations().insert();
314 ScannerReport.Metadata.Builder metadataBuilder = newBatchReportBuilder();
315 metadataBuilder.setOrganizationKey(organization1.getKey());
316 metadataBuilder.getMutableQprofilesPerLanguage().put("js", ScannerReport.Metadata.QProfile.newBuilder().setKey("jsInOrg1").setName("Sonar way").setLanguage("js").build());
317 metadataBuilder.getMutableQprofilesPerLanguage().put("php", ScannerReport.Metadata.QProfile.newBuilder().setKey("phpInOrg2").setName("PHP way").setLanguage("php").build());
318 reportReader.setMetadata(metadataBuilder.build());
320 dbTester.qualityProfiles().insert(organization1, p -> p.setLanguage("js").setKee("jsInOrg1"));
321 dbTester.qualityProfiles().insert(organization2, p -> p.setLanguage("php").setKee("phpInOrg2"));
323 ComputationStep underTest = createStep(createCeTask(PROJECT_KEY, organization1.getUuid()));
325 expectedException.expect(MessageException.class);
326 expectedException.expectMessage("Quality profiles with following keys don't exist in organization [" + organization1.getKey() + "]: phpInOrg2");
332 public void execute_does_not_fail_when_report_has_a_quality_profile_that_does_not_exist_anymore() {
333 OrganizationDto organization = dbTester.organizations().insert();
334 ScannerReport.Metadata.Builder metadataBuilder = newBatchReportBuilder();
335 metadataBuilder.setOrganizationKey(organization.getKey());
336 metadataBuilder.getMutableQprofilesPerLanguage().put("js", ScannerReport.Metadata.QProfile.newBuilder().setKey("p1").setName("Sonar way").setLanguage("js").build());
337 reportReader.setMetadata(metadataBuilder.build());
339 ComputationStep underTest = createStep(createCeTask(PROJECT_KEY, organization.getUuid()));
345 public void execute_fails_with_MessageException_when_organization_is_not_allowed_to_execute_analysis() {
346 OrganizationDto organization = dbTester.organizations().insert();
347 reportReader.setMetadata(newBatchReportBuilder()
348 .setOrganizationKey(organization.getKey())
350 ComputationStep underTest = createStep(createCeTask(PROJECT_KEY, organization.getUuid()));
351 doThrow(new BillingValidationsException("This organization cannot execute project analysis")).when(billingValidations)
352 .checkOnProjectAnalysis(any(BillingValidations.Organization.class));
354 expectedException.expect(MessageException.class);
355 expectedException.expectMessage("This organization cannot execute project analysis");
361 public void execute_does_no_fails_when_organization_is_allowed_to_execute_analysis() {
362 OrganizationDto organization = dbTester.organizations().insert();
363 reportReader.setMetadata(newBatchReportBuilder()
364 .setOrganizationKey(organization.getKey())
366 ComputationStep underTest = createStep(createCeTask(PROJECT_KEY, organization.getUuid()));
370 ArgumentCaptor<BillingValidations.Organization> argumentCaptor = ArgumentCaptor.forClass(BillingValidations.Organization.class);
371 verify(billingValidations).checkOnProjectAnalysis(argumentCaptor.capture());
372 assertThat(argumentCaptor.getValue().getKey()).isEqualTo(organization.getKey());
373 assertThat(argumentCaptor.getValue().getUuid()).isEqualTo(organization.getUuid());
376 private LoadReportAnalysisMetadataHolderStep createStep(CeTask ceTask) {
377 return new LoadReportAnalysisMetadataHolderStep(ceTask, reportReader, analysisMetadataHolder, defaultOrganizationProvider, dbClient, billingValidations);
380 private static ScannerReport.Metadata.Builder newBatchReportBuilder() {
381 return ScannerReport.Metadata.newBuilder()
382 .setProjectKey(PROJECT_KEY);
385 private CeTask createCeTask(String projectKey, String organizationUuid) {
386 CeTask res = mock(CeTask.class);
387 when(res.getOrganizationUuid()).thenReturn(organizationUuid);
388 when(res.getComponentKey()).thenReturn(projectKey);