]> source.dussan.org Git - sonarqube.git/blob
4a4d303f024dbdbd4c73329bcbc4531be66fa352
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2016 SonarSource SA
4  * mailto:contact 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.sonar.api.utils.System2;
26 import org.sonar.db.DbClient;
27 import org.sonar.db.DbSession;
28 import org.sonar.db.DbTester;
29 import org.sonar.db.component.ComponentDto;
30 import org.sonar.db.component.ComponentTesting;
31 import org.sonar.db.component.SnapshotDto;
32 import org.sonar.db.measure.MeasureDto;
33 import org.sonar.server.computation.task.projectanalysis.batch.BatchReportReaderRule;
34 import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolderRule;
35 import org.sonar.server.computation.task.projectanalysis.component.Component;
36 import org.sonar.server.computation.task.projectanalysis.component.DumbDeveloper;
37 import org.sonar.server.computation.task.projectanalysis.component.ReportComponent;
38 import org.sonar.server.computation.task.projectanalysis.measure.Measure;
39 import org.sonar.server.computation.task.projectanalysis.measure.MeasureRepositoryRule;
40 import org.sonar.server.computation.task.projectanalysis.measure.MeasureVariations;
41 import org.sonar.server.computation.task.projectanalysis.metric.Metric;
42 import org.sonar.server.computation.task.projectanalysis.metric.MetricImpl;
43 import org.sonar.server.computation.task.projectanalysis.metric.MetricRepositoryRule;
44 import org.sonar.server.computation.task.projectanalysis.period.Period;
45 import org.sonar.server.computation.task.projectanalysis.period.PeriodsHolderRule;
46
47 import static org.assertj.core.api.Assertions.assertThat;
48 import static org.sonar.db.component.SnapshotTesting.newAnalysis;
49 import static org.sonar.server.computation.task.projectanalysis.measure.Measure.newMeasureBuilder;
50
51 public class ReportComputeMeasureVariationsStepTest {
52
53   private static final Metric ISSUES_METRIC = new MetricImpl(1, "violations", "violations", Metric.MetricType.INT);
54   private static final Metric DEBT_METRIC = new MetricImpl(2, "sqale_index", "sqale_index", Metric.MetricType.WORK_DUR);
55   private static final Metric FILE_COMPLEXITY_METRIC = new MetricImpl(3, "file_complexity", "file_complexity", Metric.MetricType.FLOAT);
56   private static final Metric BUILD_BREAKER_METRIC = new MetricImpl(4, "build_breaker", "build_breaker", Metric.MetricType.BOOL);
57   private static final Metric NEW_DEBT = new MetricImpl(5, "new_debt", "new_debt", Metric.MetricType.WORK_DUR);
58   private static final String PROJECT_UUID = "prj uuid";
59   private static final int PROJECT_REF = 1;
60   private static final Component PROJECT = ReportComponent.builder(Component.Type.PROJECT, PROJECT_REF).setUuid(PROJECT_UUID).build();
61
62
63   @Rule
64   public DbTester dbTester = DbTester.create(System2.INSTANCE);
65   @Rule
66   public BatchReportReaderRule reportReader = new BatchReportReaderRule();
67   @Rule
68   public PeriodsHolderRule periodsHolder = new PeriodsHolderRule();
69   @Rule
70   public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
71   @Rule
72   public MetricRepositoryRule metricRepository = new MetricRepositoryRule()
73     .add(ISSUES_METRIC)
74     .add(DEBT_METRIC)
75     .add(FILE_COMPLEXITY_METRIC)
76     .add(BUILD_BREAKER_METRIC)
77     .add(NEW_DEBT);
78   @Rule
79   public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository);
80
81   private ComponentDto project;
82
83   DbSession session = dbTester.getSession();
84
85   DbClient dbClient = dbTester.getDbClient();
86
87   ComputeMeasureVariationsStep underTest;
88
89   @Before
90   public void setUp() {
91     project = dbTester.components().insertProject(dbTester.organizations().insert(), PROJECT_UUID);
92
93     underTest = new ComputeMeasureVariationsStep(dbClient, treeRootHolder, periodsHolder, metricRepository, measureRepository);
94   }
95
96   @Test
97   public void do_nothing_when_no_raw_measure() {
98     SnapshotDto period1ProjectSnapshot = newAnalysis(project);
99     dbClient.snapshotDao().insert(session, period1ProjectSnapshot);
100     dbClient.measureDao().insert(session, newMeasureDto(ISSUES_METRIC.getId(), PROJECT_UUID, period1ProjectSnapshot.getUuid(), 60d));
101     session.commit();
102
103     periodsHolder.setPeriods(newPeriod(1, period1ProjectSnapshot));
104
105     treeRootHolder.setRoot(PROJECT);
106
107     underTest.execute();
108
109     assertThat(measureRepository.getRawMeasures(PROJECT).keys()).isEmpty();
110   }
111
112   @Test
113   public void do_nothing_when_no_period() {
114     Component project = ReportComponent.builder(Component.Type.PROJECT, 1).setUuid(PROJECT_UUID).build();
115     treeRootHolder.setRoot(project);
116     periodsHolder.setPeriods();
117
118     underTest.execute();
119
120     assertThat(measureRepository.getRawMeasures(project).keys()).isEmpty();
121   }
122
123   @Test
124   public void set_variation() {
125     // Project
126     SnapshotDto period1Snapshot = newAnalysis(project);
127     dbClient.snapshotDao().insert(session, period1Snapshot);
128     dbClient.measureDao().insert(session, newMeasureDto(ISSUES_METRIC.getId(), PROJECT_UUID, period1Snapshot.getUuid(), 60d));
129
130     // Directory
131     ComponentDto directoryDto = ComponentTesting.newDirectory(project, "dir");
132     dbClient.componentDao().insert(session, directoryDto);
133     dbClient.measureDao().insert(session, newMeasureDto(ISSUES_METRIC.getId(), directoryDto.uuid(), period1Snapshot.getUuid(), 10d));
134     session.commit();
135
136     periodsHolder.setPeriods(newPeriod(1, period1Snapshot));
137
138     Component directory = ReportComponent.builder(Component.Type.DIRECTORY, 2).setUuid(directoryDto.uuid()).build();
139     Component project = ReportComponent.builder(Component.Type.PROJECT, 1).setUuid(PROJECT_UUID).addChildren(directory).build();
140     treeRootHolder.setRoot(project);
141
142     addRawMeasure(project, ISSUES_METRIC, newMeasureBuilder().create(80, null));
143     addRawMeasure(directory, ISSUES_METRIC, newMeasureBuilder().create(20, null));
144
145     underTest.execute();
146
147     assertThat(measureRepository.getRawMeasure(project, ISSUES_METRIC).get().getVariations().getVariation1()).isEqualTo(20d);
148     assertThat(measureRepository.getRawMeasure(directory, ISSUES_METRIC).get().getVariations().getVariation1()).isEqualTo(10d);
149   }
150
151   @Test
152   public void set_zero_variation_when_no_change() {
153     // Project
154     SnapshotDto period1Snapshot = newAnalysis(project);
155     dbClient.snapshotDao().insert(session, period1Snapshot);
156     dbClient.measureDao().insert(session, newMeasureDto(ISSUES_METRIC.getId(), PROJECT_UUID, period1Snapshot.getUuid(), 60d));
157
158     // Directory
159     ComponentDto directoryDto = ComponentTesting.newDirectory(project, "dir");
160     dbClient.componentDao().insert(session, directoryDto);
161     dbClient.measureDao().insert(session, newMeasureDto(ISSUES_METRIC.getId(), directoryDto.uuid(), period1Snapshot.getUuid(), 10d));
162     session.commit();
163
164     periodsHolder.setPeriods(newPeriod(1, period1Snapshot));
165
166     Component directory = ReportComponent.builder(Component.Type.DIRECTORY, 2).setUuid(directoryDto.uuid()).build();
167     Component project = ReportComponent.builder(Component.Type.PROJECT, 1).setUuid(PROJECT_UUID).addChildren(directory).build();
168     treeRootHolder.setRoot(project);
169
170     addRawMeasure(project, ISSUES_METRIC, newMeasureBuilder().create(60, null));
171     addRawMeasure(directory, ISSUES_METRIC, newMeasureBuilder().create(10, null));
172
173     underTest.execute();
174
175     assertThat(measureRepository.getRawMeasure(project, ISSUES_METRIC).get().getVariations().getVariation1()).isEqualTo(0d);
176     assertThat(measureRepository.getRawMeasure(directory, ISSUES_METRIC).get().getVariations().getVariation1()).isEqualTo(0d);
177   }
178
179   @Test
180   public void set_variation_to_raw_value_on_new_component() throws Exception {
181     // Project
182     SnapshotDto past1ProjectSnapshot = newAnalysis(project).setCreatedAt(1000_000_000L);
183     SnapshotDto currentProjectSnapshot = newAnalysis(project).setCreatedAt(2000_000_000L);
184     dbClient.snapshotDao().insert(session, past1ProjectSnapshot);
185     dbClient.snapshotDao().insert(session, currentProjectSnapshot);
186     dbClient.measureDao().insert(session, newMeasureDto(ISSUES_METRIC.getId(), PROJECT_UUID, past1ProjectSnapshot.getUuid(), 60d));
187     dbClient.measureDao().insert(session, newMeasureDto(ISSUES_METRIC.getId(), PROJECT_UUID, currentProjectSnapshot.getUuid(), 60d));
188     session.commit();
189
190     periodsHolder.setPeriods(newPeriod(1, past1ProjectSnapshot));
191
192     // Directory has just been added => no snapshot
193     Component directory = ReportComponent.builder(Component.Type.DIRECTORY, 2).setUuid("DIRECTORY").build();
194     Component project = ReportComponent.builder(Component.Type.PROJECT, 1).setUuid(PROJECT_UUID).addChildren(directory).build();
195     treeRootHolder.setRoot(project);
196
197     addRawMeasure(project, ISSUES_METRIC, newMeasureBuilder().create(90, null));
198     addRawMeasure(directory, ISSUES_METRIC, newMeasureBuilder().create(10, null));
199
200     underTest.execute();
201
202     assertThat(measureRepository.getRawMeasure(project, ISSUES_METRIC).get().getVariations().getVariation1()).isEqualTo(30d);
203     // Variation should be the raw value
204     assertThat(measureRepository.getRawMeasure(directory, ISSUES_METRIC).get().getVariations().getVariation1()).isEqualTo(10d);
205   }
206
207   @Test
208   public void set_variations_on_all_periods() {
209     SnapshotDto period1ProjectSnapshot = newAnalysis(project).setLast(false);
210     SnapshotDto period2ProjectSnapshot = newAnalysis(project).setLast(false);
211     SnapshotDto period3ProjectSnapshot = newAnalysis(project).setLast(false);
212     SnapshotDto period4ProjectSnapshot = newAnalysis(project).setLast(false);
213     SnapshotDto period5ProjectSnapshot = newAnalysis(project).setLast(false);
214     dbClient.snapshotDao().insert(session, period1ProjectSnapshot, period2ProjectSnapshot, period3ProjectSnapshot, period4ProjectSnapshot, period5ProjectSnapshot);
215
216     dbClient.measureDao().insert(session,
217       newMeasureDto(ISSUES_METRIC.getId(), PROJECT_UUID, period1ProjectSnapshot.getUuid(), 0d),
218       newMeasureDto(ISSUES_METRIC.getId(), PROJECT_UUID, period2ProjectSnapshot.getUuid(), 20d),
219       newMeasureDto(ISSUES_METRIC.getId(), PROJECT_UUID, period3ProjectSnapshot.getUuid(), 40d),
220       newMeasureDto(ISSUES_METRIC.getId(), PROJECT_UUID, period4ProjectSnapshot.getUuid(), 80d),
221       newMeasureDto(ISSUES_METRIC.getId(), PROJECT_UUID, period5ProjectSnapshot.getUuid(), 100d));
222     session.commit();
223
224     periodsHolder.setPeriods(newPeriod(1, period1ProjectSnapshot),
225       newPeriod(2, period2ProjectSnapshot),
226       newPeriod(3, period3ProjectSnapshot),
227       newPeriod(4, period4ProjectSnapshot),
228       newPeriod(5, period5ProjectSnapshot));
229
230     treeRootHolder.setRoot(PROJECT);
231
232     addRawMeasure(PROJECT, ISSUES_METRIC, newMeasureBuilder().create(80, null));
233
234     underTest.execute();
235
236     assertThat(measureRepository.getRawMeasures(PROJECT).keys()).hasSize(1);
237
238     Measure measure = measureRepository.getRawMeasure(PROJECT, ISSUES_METRIC).get();
239     assertThat(measure.hasVariations()).isTrue();
240     assertThat(measure.getVariations().getVariation1()).isEqualTo(80d);
241     assertThat(measure.getVariations().getVariation2()).isEqualTo(60d);
242     assertThat(measure.getVariations().getVariation3()).isEqualTo(40d);
243     assertThat(measure.getVariations().getVariation4()).isEqualTo(0d);
244     assertThat(measure.getVariations().getVariation5()).isEqualTo(-20d);
245   }
246
247   @Test
248   public void set_variation_on_all_numeric_metrics() {
249     SnapshotDto period1ProjectSnapshot = newAnalysis(project);
250     dbClient.snapshotDao().insert(session, period1ProjectSnapshot);
251     dbClient.measureDao().insert(session,
252       newMeasureDto(ISSUES_METRIC.getId(), PROJECT_UUID, period1ProjectSnapshot.getUuid(), 60d),
253       newMeasureDto(DEBT_METRIC.getId(), PROJECT_UUID, period1ProjectSnapshot.getUuid(), 10d),
254       newMeasureDto(FILE_COMPLEXITY_METRIC.getId(), PROJECT_UUID, period1ProjectSnapshot.getUuid(), 2d),
255       newMeasureDto(BUILD_BREAKER_METRIC.getId(), PROJECT_UUID, period1ProjectSnapshot.getUuid(), 1d));
256     session.commit();
257
258     periodsHolder.setPeriods(newPeriod(1, period1ProjectSnapshot));
259
260     treeRootHolder.setRoot(PROJECT);
261
262     addRawMeasure(PROJECT, ISSUES_METRIC, newMeasureBuilder().create(80, null));
263     addRawMeasure(PROJECT, DEBT_METRIC, newMeasureBuilder().create(5L, null));
264     addRawMeasure(PROJECT, FILE_COMPLEXITY_METRIC, newMeasureBuilder().create(3d, 1, null));
265     addRawMeasure(PROJECT, BUILD_BREAKER_METRIC, newMeasureBuilder().create(false, null));
266
267     underTest.execute();
268
269     assertThat(measureRepository.getRawMeasures(PROJECT).keys()).hasSize(4);
270
271     assertThat(measureRepository.getRawMeasure(PROJECT, ISSUES_METRIC).get().getVariations().getVariation1()).isEqualTo(20d);
272     assertThat(measureRepository.getRawMeasure(PROJECT, DEBT_METRIC).get().getVariations().getVariation1()).isEqualTo(-5d);
273     assertThat(measureRepository.getRawMeasure(PROJECT, FILE_COMPLEXITY_METRIC).get().getVariations().getVariation1()).isEqualTo(1d);
274     assertThat(measureRepository.getRawMeasure(PROJECT, BUILD_BREAKER_METRIC).get().getVariations().getVariation1()).isEqualTo(-1d);
275   }
276
277   @Test
278   public void do_not_set_variations_on_numeric_metric_for_developer() {
279     SnapshotDto period1ProjectSnapshot = newAnalysis(project);
280     dbClient.snapshotDao().insert(session, period1ProjectSnapshot);
281     dbClient.measureDao().insert(session,
282       newMeasureDto(ISSUES_METRIC.getId(), PROJECT_UUID, period1ProjectSnapshot.getUuid(), 60d));
283     session.commit();
284
285     periodsHolder.setPeriods(newPeriod(1, period1ProjectSnapshot));
286
287     treeRootHolder.setRoot(PROJECT);
288
289     DumbDeveloper developer = new DumbDeveloper("a");
290     measureRepository.addRawMeasure(PROJECT_REF, ISSUES_METRIC.getKey(), newMeasureBuilder().forDeveloper(developer).create(80, null));
291
292     underTest.execute();
293
294     assertThat(measureRepository.getRawMeasures(PROJECT).keys()).hasSize(1);
295
296     assertThat(measureRepository.getRawMeasure(PROJECT, ISSUES_METRIC, developer).get().hasVariations()).isFalse();
297   }
298
299   @Test
300   public void does_not_update_existing_variations() throws Exception {
301     SnapshotDto period1ProjectSnapshot = newAnalysis(project);
302     dbClient.snapshotDao().insert(session, period1ProjectSnapshot);
303     dbClient.measureDao().insert(session, newMeasureDto(NEW_DEBT.getId(), PROJECT_UUID, period1ProjectSnapshot.getUuid(), 60d));
304     session.commit();
305     periodsHolder.setPeriods(newPeriod(1, period1ProjectSnapshot));
306     treeRootHolder.setRoot(PROJECT);
307
308     addRawMeasure(PROJECT, NEW_DEBT, newMeasureBuilder().setVariations(new MeasureVariations(10d)).createNoValue());
309
310     underTest.execute();
311
312     // As the measure has already variations it has been ignored, then variations will be the same
313     assertThat(measureRepository.getRawMeasure(PROJECT, NEW_DEBT).get().getVariations().getVariation1()).isEqualTo(10d);
314   }
315
316   private static MeasureDto newMeasureDto(int metricId, String componentUuid, String analysisUuid, double value) {
317     return new MeasureDto()
318       .setMetricId(metricId)
319       .setComponentUuid(componentUuid)
320       .setAnalysisUuid(analysisUuid)
321       .setValue(value);
322   }
323
324   private static Period newPeriod(int index, SnapshotDto snapshotDto) {
325     return new Period(index, "mode", null, snapshotDto.getCreatedAt(), snapshotDto.getUuid());
326   }
327
328   private void addRawMeasure(Component component, Metric metric, Measure measure) {
329     measureRepository.addRawMeasure(component.getReportAttributes().getRef(), metric.getKey(), measure);
330   }
331 }