]> source.dussan.org Git - sonarqube.git/blob
3169ada19ed85f65e6c8a8e51489d68613306888
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2017 SonarSource SA
4  * mailto:info AT sonarsource DOT com
5  *
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.
10  *
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.
15  *
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.
19  */
20 package org.sonar.server.computation.task.projectanalysis.step;
21
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;
43
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;
50
51 public class LoadReportAnalysisMetadataHolderStepTest {
52
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;
56
57   @Rule
58   public DbTester dbTester = DbTester.create(System2.INSTANCE);
59   @Rule
60   public BatchReportReaderRule reportReader = new BatchReportReaderRule();
61   @Rule
62   public MutableAnalysisMetadataHolderRule analysisMetadataHolder = new MutableAnalysisMetadataHolderRule();
63   @Rule
64   public ExpectedException expectedException = ExpectedException.none();
65
66   private DbClient dbClient = dbTester.getDbClient();
67   private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(dbTester);
68   private BillingValidationsProxy billingValidations = mock(BillingValidationsProxy.class);
69   private ComputationStep underTest;
70
71   @Before
72   public void setUp() {
73     CeTask defaultOrgCeTask = createCeTask(PROJECT_KEY, dbTester.getDefaultOrganization().getUuid());
74     underTest = createStep(defaultOrgCeTask);
75   }
76
77   @Test
78   public void set_root_component_ref() {
79     reportReader.setMetadata(
80       newBatchReportBuilder()
81         .setRootComponentRef(1)
82         .build());
83
84     underTest.execute();
85
86     assertThat(analysisMetadataHolder.getRootComponentRef()).isEqualTo(1);
87   }
88
89   @Test
90   public void set_analysis_date() {
91     reportReader.setMetadata(
92       newBatchReportBuilder()
93         .setAnalysisDate(ANALYSIS_DATE)
94         .build());
95
96     underTest.execute();
97
98     assertThat(analysisMetadataHolder.getAnalysisDate()).isEqualTo(ANALYSIS_DATE);
99   }
100
101   @Test
102   public void set_branch() {
103     reportReader.setMetadata(
104       newBatchReportBuilder()
105         .setBranch(BRANCH)
106         .build());
107
108     CeTask ceTask = createCeTask(PROJECT_KEY + ":" + BRANCH, dbTester.getDefaultOrganization().getUuid());
109     ComputationStep underTest = createStep(ceTask);
110
111     underTest.execute();
112
113     assertThat(analysisMetadataHolder.getBranch()).isEqualTo(BRANCH);
114   }
115
116   @Test
117   public void set_null_branch_when_nothing_in_the_report() {
118     reportReader.setMetadata(
119       newBatchReportBuilder()
120         .build());
121
122     underTest.execute();
123
124     assertThat(analysisMetadataHolder.getBranch()).isNull();
125   }
126
127   @Test
128   public void set_cross_project_duplication_to_true() {
129     reportReader.setMetadata(
130       newBatchReportBuilder()
131         .setCrossProjectDuplicationActivated(true)
132         .build());
133
134     underTest.execute();
135
136     assertThat(analysisMetadataHolder.isCrossProjectDuplicationEnabled()).isEqualTo(true);
137   }
138
139   @Test
140   public void set_cross_project_duplication_to_false() {
141     reportReader.setMetadata(
142       newBatchReportBuilder()
143         .setCrossProjectDuplicationActivated(false)
144         .build());
145
146     underTest.execute();
147
148     assertThat(analysisMetadataHolder.isCrossProjectDuplicationEnabled()).isEqualTo(false);
149   }
150   
151   @Test
152   public void set_incremental_analysis_to_true() {
153     reportReader.setMetadata(
154       newBatchReportBuilder()
155         .setIncremental(true)
156         .build());
157
158     underTest.execute();
159
160     assertThat(analysisMetadataHolder.isIncrementalAnalysis()).isTrue();
161   }
162   
163   @Test
164   public void set_incremental_analysis_to_false() {
165     reportReader.setMetadata(
166       newBatchReportBuilder()
167       .setIncremental(false)
168         .build());
169
170     underTest.execute();
171
172     assertThat(analysisMetadataHolder.isIncrementalAnalysis()).isFalse();
173   }
174
175
176   @Test
177   public void set_cross_project_duplication_to_false_when_nothing_in_the_report() {
178     reportReader.setMetadata(
179       newBatchReportBuilder()
180         .build());
181
182     underTest.execute();
183
184     assertThat(analysisMetadataHolder.isCrossProjectDuplicationEnabled()).isEqualTo(false);
185   }
186
187   @Test
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());
192
193     ComputationStep underTest = createStep(res);
194
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.");
197
198     underTest.execute();
199   }
200
201   @Test
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")
206         .build());
207
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 + ")");
210
211     underTest.execute();
212   }
213
214   @Test
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)
220         .build());
221
222     try {
223       underTest.execute();
224     } catch (MessageException e) {
225       assertThat(analysisMetadataHolder.getAnalysisDate()).isEqualTo(ANALYSIS_DATE);
226     }
227   }
228
229   @Test
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()
233         .build());
234     OrganizationDto nonDefaultOrganizationDto = dbTester.organizations().insert();
235
236     ComputationStep underTest = createStep(createCeTask(PROJECT_KEY, nonDefaultOrganizationDto.getUuid()));
237
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() + ")");
241
242     underTest.execute();
243   }
244
245   @Test
246   public void execute_set_organization_from_ce_task_when_organizationKey_is_not_set_in_report() {
247     reportReader.setMetadata(
248       newBatchReportBuilder()
249         .build());
250
251     underTest.execute();
252
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());
258   }
259
260   @Test
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())
265         .build());
266
267     underTest.execute();
268
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());
274   }
275
276   @Test
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())
282         .build());
283
284     ComputationStep underTest = createStep(createCeTask(PROJECT_KEY, nonDefaultOrganizationDto.getUuid()));
285
286     underTest.execute();
287
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());
292   }
293
294   @Test
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());
301
302     dbTester.qualityProfiles().insert(organization, p -> p.setLanguage("js").setKee("p1"));
303
304     ComputationStep underTest = createStep(createCeTask(PROJECT_KEY, organization.getUuid()));
305
306     // no errors
307     underTest.execute();
308   }
309
310   @Test
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());
319
320     dbTester.qualityProfiles().insert(organization1, p -> p.setLanguage("js").setKee("jsInOrg1"));
321     dbTester.qualityProfiles().insert(organization2, p -> p.setLanguage("php").setKee("phpInOrg2"));
322
323     ComputationStep underTest = createStep(createCeTask(PROJECT_KEY, organization1.getUuid()));
324
325     expectedException.expect(MessageException.class);
326     expectedException.expectMessage("Quality profiles with following keys don't exist in organization [" + organization1.getKey() + "]: phpInOrg2");
327
328     underTest.execute();
329   }
330
331   @Test
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());
338
339     ComputationStep underTest = createStep(createCeTask(PROJECT_KEY, organization.getUuid()));
340
341     underTest.execute();
342   }
343
344   @Test
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())
349       .build());
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));
353
354     expectedException.expect(MessageException.class);
355     expectedException.expectMessage("This organization cannot execute project analysis");
356
357     underTest.execute();
358   }
359
360   @Test
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())
365       .build());
366     ComputationStep underTest = createStep(createCeTask(PROJECT_KEY, organization.getUuid()));
367
368     underTest.execute();
369
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());
374   }
375
376   private LoadReportAnalysisMetadataHolderStep createStep(CeTask ceTask) {
377     return new LoadReportAnalysisMetadataHolderStep(ceTask, reportReader, analysisMetadataHolder, defaultOrganizationProvider, dbClient, billingValidations);
378   }
379
380   private static ScannerReport.Metadata.Builder newBatchReportBuilder() {
381     return ScannerReport.Metadata.newBuilder()
382       .setProjectKey(PROJECT_KEY);
383   }
384
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);
389     return res;
390   }
391
392 }