]> source.dussan.org Git - sonarqube.git/blob
0b698b616021a2f93fa7659cbd95090d020d8100
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2019 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.ce.task.projectanalysis.duplication;
21
22 import org.junit.Rule;
23 import org.junit.Test;
24 import org.sonar.ce.task.projectanalysis.component.FileAttributes;
25 import org.sonar.ce.task.projectanalysis.component.TreeRootHolderRule;
26 import org.sonar.ce.task.projectanalysis.measure.MeasureRepositoryRule;
27 import org.sonar.ce.task.projectanalysis.metric.MetricRepositoryRule;
28
29 import static com.google.common.base.Preconditions.checkArgument;
30 import static org.assertj.core.api.Assertions.assertThat;
31 import static org.mockito.Mockito.mock;
32 import static org.mockito.Mockito.when;
33 import static org.sonar.api.measures.CoreMetrics.DUPLICATED_BLOCKS;
34 import static org.sonar.api.measures.CoreMetrics.DUPLICATED_BLOCKS_KEY;
35 import static org.sonar.api.measures.CoreMetrics.DUPLICATED_FILES;
36 import static org.sonar.api.measures.CoreMetrics.DUPLICATED_FILES_KEY;
37 import static org.sonar.api.measures.CoreMetrics.DUPLICATED_LINES;
38 import static org.sonar.api.measures.CoreMetrics.DUPLICATED_LINES_DENSITY;
39 import static org.sonar.api.measures.CoreMetrics.DUPLICATED_LINES_DENSITY_KEY;
40 import static org.sonar.api.measures.CoreMetrics.DUPLICATED_LINES_KEY;
41 import static org.sonar.ce.task.projectanalysis.component.Component.Type.DIRECTORY;
42 import static org.sonar.ce.task.projectanalysis.component.Component.Type.FILE;
43 import static org.sonar.ce.task.projectanalysis.component.Component.Type.PROJECT;
44 import static org.sonar.ce.task.projectanalysis.component.ReportComponent.builder;
45 import static org.sonar.ce.task.projectanalysis.measure.Measure.newMeasureBuilder;
46
47 public class DuplicationMeasuresTest {
48   private static final int ROOT_REF = 1;
49   private static final int DIRECTORY_REF = 1234;
50   private static final int FILE_1_REF = 12341;
51   private static final int FILE_2_REF = 12342;
52   private static final int FILE_3_REF = 1261;
53   private static final int FILE_4_REF = 1262;
54   private static final FileAttributes FILE_1_ATTRS = mock(FileAttributes.class);
55   private static final FileAttributes FILE_2_ATTRS = mock(FileAttributes.class);
56   private static final FileAttributes FILE_3_ATTRS = mock(FileAttributes.class);
57   private static final FileAttributes FILE_4_ATTRS = mock(FileAttributes.class);
58
59   private static final String SOME_FILE_KEY = "some file key";
60
61   @Rule
62   public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule()
63     .setRoot(
64       builder(PROJECT, ROOT_REF)
65         .addChildren(
66           builder(DIRECTORY, DIRECTORY_REF)
67             .addChildren(
68               builder(FILE, FILE_1_REF).setFileAttributes(FILE_1_ATTRS).build(),
69               builder(FILE, FILE_2_REF).setFileAttributes(FILE_2_ATTRS).build())
70             .build(),
71           builder(FILE, FILE_3_REF).setFileAttributes(FILE_3_ATTRS).build(),
72           builder(FILE, FILE_4_REF).setFileAttributes(FILE_4_ATTRS).build())
73         .build());
74   @Rule
75   public MetricRepositoryRule metricRepository = new MetricRepositoryRule()
76     .add(DUPLICATED_BLOCKS)
77     .add(DUPLICATED_FILES)
78     .add(DUPLICATED_LINES)
79     .add(DUPLICATED_LINES_DENSITY);
80   @Rule
81   public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository);
82   @Rule
83   public DuplicationRepositoryRule duplicationRepository = DuplicationRepositoryRule.create(treeRootHolder);
84
85   private DuplicationMeasures underTest = new DuplicationMeasures(treeRootHolder, metricRepository, measureRepository, duplicationRepository);
86
87   @Test
88   public void compute_duplicated_blocks_one_for_original_one_for_each_InnerDuplicate() {
89     TextBlock original = new TextBlock(1, 1);
90     duplicationRepository.addDuplication(FILE_1_REF, original, new TextBlock(2, 2), new TextBlock(3, 3), new TextBlock(2, 3));
91
92     underTest.execute();
93
94     assertRawMeasureValue(FILE_1_REF, DUPLICATED_BLOCKS_KEY, 4);
95   }
96
97   @Test
98   public void compute_duplicated_blocks_does_not_count_blocks_only_once_it_assumes_consistency_from_duplication_data() {
99     duplicationRepository.addDuplication(FILE_1_REF, new TextBlock(1, 1), new TextBlock(3, 3));
100     duplicationRepository.addDuplication(FILE_1_REF, new TextBlock(2, 2), new TextBlock(3, 3));
101
102     underTest.execute();
103
104     assertRawMeasureValue(FILE_1_REF, DUPLICATED_BLOCKS_KEY, 4);
105   }
106
107   @Test
108   public void compute_duplicated_blocks_one_for_original_and_ignores_InProjectDuplicate() {
109     duplicationRepository.addDuplication(FILE_1_REF, new TextBlock(1, 1), FILE_2_REF, new TextBlock(2, 2));
110
111     underTest.execute();
112
113     assertRawMeasureValue(FILE_1_REF, DUPLICATED_BLOCKS_KEY, 1);
114   }
115
116   @Test
117   public void compute_duplicated_blocks_one_for_original_and_ignores_CrossProjectDuplicate() {
118     duplicationRepository.addCrossProjectDuplication(FILE_1_REF, new TextBlock(1, 1), SOME_FILE_KEY, new TextBlock(2, 2));
119
120     underTest.execute();
121
122     assertRawMeasureValue(FILE_1_REF, DUPLICATED_BLOCKS_KEY, 1);
123   }
124
125   @Test
126   public void compute_and_aggregate_duplicated_blocks_from_single_duplication() {
127     addDuplicatedBlock(FILE_1_REF, 10);
128     addDuplicatedBlock(FILE_2_REF, 40);
129     addDuplicatedBlock(FILE_4_REF, 5);
130
131     underTest.execute();
132
133     assertRawMeasureValue(FILE_1_REF, DUPLICATED_BLOCKS_KEY, 10);
134     assertRawMeasureValue(FILE_2_REF, DUPLICATED_BLOCKS_KEY, 40);
135     assertRawMeasureValue(FILE_3_REF, DUPLICATED_BLOCKS_KEY, 0);
136     assertRawMeasureValue(FILE_4_REF, DUPLICATED_BLOCKS_KEY, 5);
137     assertRawMeasureValue(DIRECTORY_REF, DUPLICATED_BLOCKS_KEY, 50);
138     assertRawMeasureValue(ROOT_REF, DUPLICATED_BLOCKS_KEY, 55);
139   }
140
141   @Test
142   public void compute_and_aggregate_duplicated_blocks_to_zero_when_no_duplication() {
143     underTest.execute();
144
145     assertComputedAndAggregatedToZeroInt(DUPLICATED_BLOCKS_KEY);
146   }
147
148   @Test
149   public void compute_duplicated_lines_counts_lines_from_original_and_InnerDuplicate_of_a_single_line() {
150     TextBlock original = new TextBlock(1, 1);
151     duplicationRepository.addDuplication(FILE_1_REF, original, new TextBlock(2, 2));
152
153     underTest.execute();
154
155     assertRawMeasureValue(FILE_1_REF, DUPLICATED_LINES_KEY, 2);
156   }
157
158   @Test
159   public void compute_duplicated_lines_counts_lines_from_original_and_ignores_InProjectDuplicate() {
160     TextBlock original = new TextBlock(1, 1);
161     duplicationRepository.addDuplication(FILE_1_REF, original, FILE_2_REF, new TextBlock(2, 2));
162
163     underTest.execute();
164
165     assertRawMeasureValue(FILE_1_REF, DUPLICATED_LINES_KEY, 1);
166   }
167
168   @Test
169   public void compute_duplicated_lines_counts_lines_from_original_and_ignores_CrossProjectDuplicate() {
170     TextBlock original = new TextBlock(1, 1);
171     duplicationRepository.addCrossProjectDuplication(FILE_1_REF, original, SOME_FILE_KEY, new TextBlock(2, 2));
172
173     underTest.execute();
174
175     assertRawMeasureValue(FILE_1_REF, DUPLICATED_LINES_KEY, 1);
176   }
177
178   @Test
179   public void compute_duplicated_lines_counts_lines_from_original_and_InnerDuplicate() {
180     TextBlock original = new TextBlock(1, 5);
181     duplicationRepository.addDuplication(FILE_1_REF, original, new TextBlock(10, 11));
182
183     underTest.execute();
184
185     assertRawMeasureValue(FILE_1_REF, DUPLICATED_LINES_KEY, 7);
186   }
187
188   @Test
189   public void compute_duplicated_lines_counts_lines_from_original_and_InnerDuplicate_only_once() {
190     TextBlock original = new TextBlock(1, 12);
191     duplicationRepository.addDuplication(FILE_1_REF, original, new TextBlock(10, 11), new TextBlock(11, 15));
192     duplicationRepository.addDuplication(FILE_1_REF, new TextBlock(2, 2), new TextBlock(96, 96));
193
194     underTest.execute();
195
196     assertRawMeasureValue(FILE_1_REF, DUPLICATED_LINES_KEY, 16);
197   }
198
199   @Test
200   public void compute_and_aggregate_duplicated_files() {
201     addDuplicatedBlock(FILE_1_REF, 2);
202     addDuplicatedBlock(FILE_3_REF, 10);
203     addDuplicatedBlock(FILE_4_REF, 50);
204
205     underTest.execute();
206
207     assertRawMeasureValue(FILE_1_REF, DUPLICATED_FILES_KEY, 1);
208     assertRawMeasureValue(FILE_2_REF, DUPLICATED_FILES_KEY, 0);
209     assertRawMeasureValue(FILE_3_REF, DUPLICATED_FILES_KEY, 1);
210     assertRawMeasureValue(FILE_4_REF, DUPLICATED_FILES_KEY, 1);
211     assertRawMeasureValue(DIRECTORY_REF, DUPLICATED_FILES_KEY, 1);
212     assertRawMeasureValue(ROOT_REF, DUPLICATED_FILES_KEY, 3);
213   }
214
215   @Test
216   public void compute_and_aggregate_zero_duplicated_files_when_no_duplication_data() {
217     underTest.execute();
218
219     assertComputedAndAggregatedToZeroInt(DUPLICATED_FILES_KEY);
220   }
221
222   @Test
223   public void compute_and_aggregate_duplicated_lines() {
224     addDuplicatedBlock(FILE_1_REF, 10);
225     addDuplicatedBlock(FILE_2_REF, 9);
226     addDuplicatedBlock(FILE_4_REF, 7);
227
228     underTest.execute();
229
230     assertRawMeasureValue(FILE_1_REF, DUPLICATED_LINES_KEY, 10);
231     assertRawMeasureValue(FILE_2_REF, DUPLICATED_LINES_KEY, 9);
232     assertRawMeasureValue(FILE_3_REF, DUPLICATED_LINES_KEY, 0);
233     assertRawMeasureValue(FILE_4_REF, DUPLICATED_LINES_KEY, 7);
234     assertRawMeasureValue(DIRECTORY_REF, DUPLICATED_LINES_KEY, 19);
235     assertRawMeasureValue(ROOT_REF, DUPLICATED_LINES_KEY, 26);
236   }
237
238   @Test
239   public void compute_and_aggregate_zero_duplicated_line_when_no_duplication() {
240     underTest.execute();
241
242     assertComputedAndAggregatedToZeroInt(DUPLICATED_LINES_KEY);
243   }
244
245   @Test
246   public void compute_and_aggregate_duplicated_lines_density_using_lines() {
247     addDuplicatedBlock(FILE_1_REF, 2);
248     addDuplicatedBlock(FILE_2_REF, 3);
249
250     when(FILE_1_ATTRS.getLines()).thenReturn(10);
251     when(FILE_2_ATTRS.getLines()).thenReturn(40);
252
253     underTest.execute();
254
255     assertRawMeasureValue(FILE_1_REF, DUPLICATED_LINES_DENSITY_KEY, 20d);
256     assertRawMeasureValue(FILE_2_REF, DUPLICATED_LINES_DENSITY_KEY, 7.5d);
257     assertNoRawMeasure(FILE_3_REF, DUPLICATED_LINES_DENSITY_KEY);
258     assertNoRawMeasure(FILE_4_REF, DUPLICATED_LINES_DENSITY_KEY);
259     assertRawMeasureValue(DIRECTORY_REF, DUPLICATED_LINES_DENSITY_KEY, 10d);
260     assertRawMeasureValue(ROOT_REF, DUPLICATED_LINES_DENSITY_KEY, 10d);
261   }
262
263   @Test
264   public void compute_zero_percent_duplicated_lines_density_when_there_is_no_duplication() {
265     when(FILE_1_ATTRS.getLines()).thenReturn(10);
266     when(FILE_2_ATTRS.getLines()).thenReturn(40);
267
268     underTest.execute();
269
270     assertRawMeasureValue(FILE_1_REF, DUPLICATED_LINES_DENSITY_KEY, 0d);
271     assertRawMeasureValue(FILE_2_REF, DUPLICATED_LINES_DENSITY_KEY, 0d);
272     assertNoRawMeasure(FILE_3_REF, DUPLICATED_LINES_DENSITY_KEY);
273     assertNoRawMeasure(FILE_4_REF, DUPLICATED_LINES_DENSITY_KEY);
274     assertRawMeasureValue(DIRECTORY_REF, DUPLICATED_LINES_DENSITY_KEY, 0d);
275     assertRawMeasureValue(ROOT_REF, DUPLICATED_LINES_DENSITY_KEY, 0d);
276   }
277
278   @Test
279   public void not_compute_duplicated_lines_density_when_lines_is_zero() {
280     when(FILE_1_ATTRS.getLines()).thenReturn(0);
281     when(FILE_2_ATTRS.getLines()).thenReturn(0);
282     underTest.execute();
283     assertNoRawMeasures(DUPLICATED_LINES_DENSITY_KEY);
284   }
285
286   @Test
287   public void compute_100_percent_duplicated_lines_density() {
288     addDuplicatedBlock(FILE_1_REF, 2);
289     addDuplicatedBlock(FILE_2_REF, 3);
290
291     when(FILE_1_ATTRS.getLines()).thenReturn(2);
292     when(FILE_2_ATTRS.getLines()).thenReturn(3);
293
294     underTest.execute();
295
296     assertRawMeasureValue(FILE_1_REF, DUPLICATED_LINES_DENSITY_KEY, 100d);
297     assertRawMeasureValue(FILE_2_REF, DUPLICATED_LINES_DENSITY_KEY, 100d);
298     assertNoRawMeasure(FILE_3_REF, DUPLICATED_LINES_DENSITY_KEY);
299     assertNoRawMeasure(FILE_4_REF, DUPLICATED_LINES_DENSITY_KEY);
300     assertRawMeasureValue(DIRECTORY_REF, DUPLICATED_LINES_DENSITY_KEY, 100d);
301     assertRawMeasureValue(ROOT_REF, DUPLICATED_LINES_DENSITY_KEY, 100d);
302   }
303
304   /**
305    * Adds duplication blocks of a single line (each line is specific to its block).
306    * This is a very simple use case, convenient for unit tests but more realistic and complex use cases must be tested separately.
307    */
308   private void addDuplicatedBlock(int fileRef, int blockCount) {
309     checkArgument(blockCount > 1, "BlockCount can not be less than 2");
310     TextBlock original = new TextBlock(1, 1);
311     TextBlock[] duplicates = new TextBlock[blockCount - 1];
312     for (int i = 10; i < blockCount + 9; i++) {
313       duplicates[i - 10] = new TextBlock(i, i);
314     }
315     duplicationRepository.addDuplication(fileRef, original, duplicates);
316   }
317
318   private void addRawMeasure(int componentRef, String metricKey, int value) {
319     measureRepository.addRawMeasure(componentRef, metricKey, newMeasureBuilder().create(value));
320   }
321
322   private void assertNoRawMeasures(String metricKey) {
323     assertThat(measureRepository.getAddedRawMeasures(FILE_1_REF).get(metricKey)).isEmpty();
324     assertThat(measureRepository.getAddedRawMeasures(FILE_2_REF).get(metricKey)).isEmpty();
325     assertThat(measureRepository.getAddedRawMeasures(DIRECTORY_REF).get(metricKey)).isEmpty();
326     assertThat(measureRepository.getAddedRawMeasures(ROOT_REF).get(metricKey)).isEmpty();
327   }
328
329   private void assertNoRawMeasure(int componentRef, String metricKey) {
330     assertThat(measureRepository.getAddedRawMeasure(componentRef, metricKey)).isNotPresent();
331   }
332
333   private void assertRawMeasureValue(int componentRef, String metricKey, int value) {
334     assertThat(measureRepository.getAddedRawMeasure(componentRef, metricKey).get().getIntValue()).isEqualTo(value);
335   }
336
337   private void assertRawMeasureValue(int componentRef, String metricKey, double value) {
338     assertThat(measureRepository.getAddedRawMeasure(componentRef, metricKey).get().getDoubleValue()).isEqualTo(value);
339   }
340
341   private void assertComputedAndAggregatedToZeroInt(String metricKey) {
342     assertRawMeasureValue(FILE_1_REF, metricKey, 0);
343     assertRawMeasureValue(FILE_2_REF, metricKey, 0);
344     assertRawMeasureValue(FILE_3_REF, metricKey, 0);
345     assertRawMeasureValue(FILE_4_REF, metricKey, 0);
346     assertRawMeasureValue(DIRECTORY_REF, metricKey, 0);
347     assertRawMeasureValue(ROOT_REF, metricKey, 0);
348   }
349
350 }