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.api.posttask;
22 import com.google.common.collect.ImmutableMap;
23 import com.tngtech.java.junit.dataprovider.DataProvider;
24 import com.tngtech.java.junit.dataprovider.DataProviderRunner;
25 import com.tngtech.java.junit.dataprovider.UseDataProvider;
26 import java.util.Date;
27 import java.util.List;
28 import org.junit.Before;
29 import org.junit.Rule;
30 import org.junit.Test;
31 import org.junit.runner.RunWith;
32 import org.mockito.ArgumentCaptor;
33 import org.mockito.InOrder;
34 import org.sonar.api.ce.posttask.PostProjectAnalysisTask;
35 import org.sonar.api.ce.posttask.Project;
36 import org.sonar.api.utils.System2;
37 import org.sonar.ce.queue.CeTask;
38 import org.sonar.scanner.protocol.output.ScannerReport;
39 import org.sonar.server.computation.task.projectanalysis.analysis.AnalysisMetadataHolderRule;
40 import org.sonar.server.computation.task.projectanalysis.batch.BatchReportReaderRule;
41 import org.sonar.server.computation.task.projectanalysis.metric.Metric;
42 import org.sonar.server.computation.task.projectanalysis.qualitygate.Condition;
43 import org.sonar.server.computation.task.projectanalysis.qualitygate.ConditionStatus;
44 import org.sonar.server.computation.task.projectanalysis.qualitygate.MutableQualityGateHolderRule;
45 import org.sonar.server.computation.task.projectanalysis.qualitygate.MutableQualityGateStatusHolderRule;
46 import org.sonar.server.computation.task.projectanalysis.qualitygate.QualityGate;
47 import org.sonar.server.computation.task.projectanalysis.qualitygate.QualityGateStatus;
49 import static com.google.common.collect.ImmutableList.of;
50 import static java.util.Arrays.asList;
51 import static org.assertj.core.api.Assertions.assertThat;
52 import static org.assertj.core.data.MapEntry.entry;
53 import static org.mockito.Matchers.any;
54 import static org.mockito.Mockito.doThrow;
55 import static org.mockito.Mockito.inOrder;
56 import static org.mockito.Mockito.mock;
57 import static org.mockito.Mockito.verify;
58 import static org.mockito.Mockito.when;
60 @RunWith(DataProviderRunner.class)
61 public class PostProjectAnalysisTasksExecutorTest {
62 private static final long QUALITY_GATE_ID = 98451;
63 private static final String QUALITY_GATE_NAME = "qualityGate name";
64 private static final Condition CONDITION_1 = createCondition("metric key 1");
65 private static final Condition CONDITION_2 = createCondition("metric key 2");
68 public AnalysisMetadataHolderRule analysisMetadataHolder = new AnalysisMetadataHolderRule();
70 public MutableQualityGateHolderRule qualityGateHolder = new MutableQualityGateHolderRule();
72 public MutableQualityGateStatusHolderRule qualityGateStatusHolder = new MutableQualityGateStatusHolderRule();
74 public BatchReportReaderRule reportReader = new BatchReportReaderRule();
76 private System2 system2 = mock(System2.class);
77 private ArgumentCaptor<PostProjectAnalysisTask.ProjectAnalysis> projectAnalysisArgumentCaptor = ArgumentCaptor.forClass(PostProjectAnalysisTask.ProjectAnalysis.class);
78 private CeTask ceTask = new CeTask.Builder()
79 .setOrganizationUuid("org1")
82 .setComponentKey("component key")
83 .setComponentName("component name")
84 .setComponentUuid("component uuid")
86 private PostProjectAnalysisTask postProjectAnalysisTask = mock(PostProjectAnalysisTask.class);
87 private PostProjectAnalysisTasksExecutor underTest = new PostProjectAnalysisTasksExecutor(
88 ceTask, analysisMetadataHolder, qualityGateHolder, qualityGateStatusHolder,
89 reportReader, system2,
90 new PostProjectAnalysisTask[] {postProjectAnalysisTask});
93 public void setUp() throws Exception {
94 qualityGateHolder.setQualityGate(new QualityGate(QUALITY_GATE_ID, QUALITY_GATE_NAME, of(CONDITION_1, CONDITION_2)));
95 qualityGateStatusHolder.setStatus(QualityGateStatus.OK, ImmutableMap.of(
96 CONDITION_1, ConditionStatus.create(ConditionStatus.EvaluationStatus.OK, "value"),
97 CONDITION_2, ConditionStatus.NO_VALUE_STATUS));
101 @UseDataProvider("booleanValues")
102 public void does_not_fail_when_there_is_no_PostProjectAnalysisTasksExecutor(boolean allStepsExecuted) {
103 new PostProjectAnalysisTasksExecutor(ceTask, analysisMetadataHolder, qualityGateHolder, qualityGateStatusHolder, reportReader, system2)
104 .finished(allStepsExecuted);
108 @UseDataProvider("booleanValues")
109 public void finished_calls_all_PostProjectAnalysisTask_in_order_of_the_array_and_passes_the_same_object_to_all(boolean allStepsExecuted) {
110 PostProjectAnalysisTask postProjectAnalysisTask1 = mock(PostProjectAnalysisTask.class);
111 PostProjectAnalysisTask postProjectAnalysisTask2 = mock(PostProjectAnalysisTask.class);
112 InOrder inOrder = inOrder(postProjectAnalysisTask1, postProjectAnalysisTask2);
114 new PostProjectAnalysisTasksExecutor(
115 ceTask, analysisMetadataHolder, qualityGateHolder, qualityGateStatusHolder, reportReader,
116 system2, new PostProjectAnalysisTask[] {postProjectAnalysisTask1, postProjectAnalysisTask2})
117 .finished(allStepsExecuted);
119 inOrder.verify(postProjectAnalysisTask1).finished(projectAnalysisArgumentCaptor.capture());
120 inOrder.verify(postProjectAnalysisTask2).finished(projectAnalysisArgumentCaptor.capture());
121 inOrder.verifyNoMoreInteractions();
123 List<PostProjectAnalysisTask.ProjectAnalysis> allValues = projectAnalysisArgumentCaptor.getAllValues();
124 assertThat(allValues).hasSize(2);
125 assertThat(allValues.get(0)).isSameAs(allValues.get(1));
129 @UseDataProvider("booleanValues")
130 public void CeTask_status_depends_on_finished_method_argument_is_true_or_false(boolean allStepsExecuted) {
131 underTest.finished(allStepsExecuted);
133 verify(postProjectAnalysisTask).finished(projectAnalysisArgumentCaptor.capture());
135 assertThat(projectAnalysisArgumentCaptor.getValue().getCeTask().getStatus())
137 allStepsExecuted ? org.sonar.api.ce.posttask.CeTask.Status.SUCCESS : org.sonar.api.ce.posttask.CeTask.Status.FAILED);
141 public void ceTask_uuid_is_UUID_of_CeTask() {
142 underTest.finished(true);
144 verify(postProjectAnalysisTask).finished(projectAnalysisArgumentCaptor.capture());
146 assertThat(projectAnalysisArgumentCaptor.getValue().getCeTask().getId())
147 .isEqualTo(ceTask.getUuid());
151 public void project_uuid_key_and_name_come_from_CeTask() {
152 underTest.finished(true);
154 verify(postProjectAnalysisTask).finished(projectAnalysisArgumentCaptor.capture());
156 Project project = projectAnalysisArgumentCaptor.getValue().getProject();
157 assertThat(project.getUuid()).isEqualTo(ceTask.getComponentUuid());
158 assertThat(project.getKey()).isEqualTo(ceTask.getComponentKey());
159 assertThat(project.getName()).isEqualTo(ceTask.getComponentName());
163 public void date_comes_from_AnalysisMetadataHolder() {
164 analysisMetadataHolder.setAnalysisDate(8465132498L);
166 underTest.finished(true);
168 verify(postProjectAnalysisTask).finished(projectAnalysisArgumentCaptor.capture());
170 assertThat(projectAnalysisArgumentCaptor.getValue().getDate())
171 .isEqualTo(new Date(analysisMetadataHolder.getAnalysisDate()));
175 public void date_comes_from_system2_if_not_set_in_AnalysisMetadataHolder() {
176 long now = 1_999_663L;
177 when(system2.now()).thenReturn(now);
179 underTest.finished(false);
181 verify(postProjectAnalysisTask).finished(projectAnalysisArgumentCaptor.capture());
183 assertThat(projectAnalysisArgumentCaptor.getValue().getDate()).isEqualTo(new Date(now));
187 public void analysisDate_comes_from_AnalysisMetadataHolder_when_set() {
188 analysisMetadataHolder.setAnalysisDate(8465132498L);
190 underTest.finished(true);
192 verify(postProjectAnalysisTask).finished(projectAnalysisArgumentCaptor.capture());
194 assertThat(projectAnalysisArgumentCaptor.getValue().getAnalysisDate())
195 .contains(new Date(analysisMetadataHolder.getAnalysisDate()));
199 public void analysisDate_is_empty_when_not_set_in_AnalysisMetadataHolder() {
200 underTest.finished(false);
202 verify(postProjectAnalysisTask).finished(projectAnalysisArgumentCaptor.capture());
204 assertThat(projectAnalysisArgumentCaptor.getValue().getAnalysisDate()).isEmpty();
208 public void qualityGate_is_null_when_finished_method_argument_is_false() {
209 underTest.finished(false);
211 verify(postProjectAnalysisTask).finished(projectAnalysisArgumentCaptor.capture());
213 assertThat(projectAnalysisArgumentCaptor.getValue().getQualityGate()).isNull();
217 public void qualityGate_is_populated_when_finished_method_argument_is_true() {
218 underTest.finished(true);
220 verify(postProjectAnalysisTask).finished(projectAnalysisArgumentCaptor.capture());
222 org.sonar.api.ce.posttask.QualityGate qualityGate = projectAnalysisArgumentCaptor.getValue().getQualityGate();
223 assertThat(qualityGate.getStatus()).isEqualTo(org.sonar.api.ce.posttask.QualityGate.Status.OK);
224 assertThat(qualityGate.getId()).isEqualTo(String.valueOf(QUALITY_GATE_ID));
225 assertThat(qualityGate.getName()).isEqualTo(QUALITY_GATE_NAME);
226 assertThat(qualityGate.getConditions()).hasSize(2);
230 public void scannerContext_loads_properties_from_scanner_report() {
231 reportReader.putContextProperties(asList(ScannerReport.ContextProperty.newBuilder().setKey("foo").setValue("bar").build()));
232 underTest.finished(true);
234 verify(postProjectAnalysisTask).finished(projectAnalysisArgumentCaptor.capture());
236 org.sonar.api.ce.posttask.ScannerContext scannerContext = projectAnalysisArgumentCaptor.getValue().getScannerContext();
237 assertThat(scannerContext.getProperties()).containsExactly(entry("foo", "bar"));
241 @UseDataProvider("booleanValues")
242 public void finished_does_not_fail_if_listener_throws_exception_and_execute_subsequent_listeners(boolean allStepsExecuted) {
243 PostProjectAnalysisTask postProjectAnalysisTask1 = mock(PostProjectAnalysisTask.class);
244 PostProjectAnalysisTask postProjectAnalysisTask2 = mock(PostProjectAnalysisTask.class);
245 PostProjectAnalysisTask postProjectAnalysisTask3 = mock(PostProjectAnalysisTask.class);
246 InOrder inOrder = inOrder(postProjectAnalysisTask1, postProjectAnalysisTask2, postProjectAnalysisTask3);
248 doThrow(new RuntimeException("Faking a listener throws an exception"))
249 .when(postProjectAnalysisTask2)
250 .finished(any(PostProjectAnalysisTask.ProjectAnalysis.class));
252 new PostProjectAnalysisTasksExecutor(
253 ceTask, analysisMetadataHolder, qualityGateHolder, qualityGateStatusHolder, reportReader,
254 system2, new PostProjectAnalysisTask[] {postProjectAnalysisTask1, postProjectAnalysisTask2, postProjectAnalysisTask3})
255 .finished(allStepsExecuted);
257 inOrder.verify(postProjectAnalysisTask1).finished(projectAnalysisArgumentCaptor.capture());
258 inOrder.verify(postProjectAnalysisTask2).finished(projectAnalysisArgumentCaptor.capture());
259 inOrder.verify(postProjectAnalysisTask3).finished(projectAnalysisArgumentCaptor.capture());
260 inOrder.verifyNoMoreInteractions();
264 public static Object[][] booleanValues() {
265 return new Object[][] {
271 private static Condition createCondition(String metricKey) {
272 Metric metric = mock(Metric.class);
273 when(metric.getKey()).thenReturn(metricKey);
274 return new Condition(metric, Condition.Operator.EQUALS.getDbValue(), "error threshold", "warn threshold", false);