]> source.dussan.org Git - sonarqube.git/blob
f76530bf9214a7a9ab390c0d3011eda9001094de
[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.qualitymodel;
21
22 import java.util.Arrays;
23 import java.util.Date;
24 import org.junit.Rule;
25 import org.junit.Test;
26 import org.sonar.api.rules.RuleType;
27 import org.sonar.api.utils.Duration;
28 import org.sonar.ce.task.projectanalysis.component.Component;
29 import org.sonar.ce.task.projectanalysis.component.FileAttributes;
30 import org.sonar.ce.task.projectanalysis.component.ReportComponent;
31 import org.sonar.ce.task.projectanalysis.component.TreeRootHolderRule;
32 import org.sonar.ce.task.projectanalysis.component.VisitorsCrawler;
33 import org.sonar.ce.task.projectanalysis.issue.ComponentIssuesRepositoryRule;
34 import org.sonar.ce.task.projectanalysis.issue.FillComponentIssuesVisitorRule;
35 import org.sonar.ce.task.projectanalysis.measure.MeasureAssert;
36 import org.sonar.ce.task.projectanalysis.measure.MeasureRepositoryRule;
37 import org.sonar.ce.task.projectanalysis.metric.MetricRepositoryRule;
38 import org.sonar.ce.task.projectanalysis.period.Period;
39 import org.sonar.ce.task.projectanalysis.period.PeriodHolderRule;
40 import org.sonar.core.issue.DefaultIssue;
41 import org.sonar.core.util.Uuids;
42 import org.sonar.server.measure.Rating;
43
44 import static org.assertj.core.api.Assertions.assertThat;
45 import static org.sonar.api.issue.Issue.RESOLUTION_FIXED;
46 import static org.sonar.api.measures.CoreMetrics.NEW_RELIABILITY_RATING;
47 import static org.sonar.api.measures.CoreMetrics.NEW_RELIABILITY_RATING_KEY;
48 import static org.sonar.api.measures.CoreMetrics.NEW_SECURITY_RATING;
49 import static org.sonar.api.measures.CoreMetrics.NEW_SECURITY_RATING_KEY;
50 import static org.sonar.api.rule.Severity.BLOCKER;
51 import static org.sonar.api.rule.Severity.CRITICAL;
52 import static org.sonar.api.rule.Severity.INFO;
53 import static org.sonar.api.rule.Severity.MAJOR;
54 import static org.sonar.api.rule.Severity.MINOR;
55 import static org.sonar.api.rules.RuleType.BUG;
56 import static org.sonar.api.rules.RuleType.CODE_SMELL;
57 import static org.sonar.api.rules.RuleType.VULNERABILITY;
58 import static org.sonar.ce.task.projectanalysis.component.Component.Type.DIRECTORY;
59 import static org.sonar.ce.task.projectanalysis.component.Component.Type.FILE;
60 import static org.sonar.ce.task.projectanalysis.component.Component.Type.PROJECT;
61 import static org.sonar.ce.task.projectanalysis.component.ReportComponent.builder;
62 import static org.sonar.server.measure.Rating.A;
63 import static org.sonar.server.measure.Rating.B;
64 import static org.sonar.server.measure.Rating.C;
65 import static org.sonar.server.measure.Rating.D;
66 import static org.sonar.server.measure.Rating.E;
67
68 public class NewReliabilityAndSecurityRatingMeasuresVisitorTest {
69
70   private static final long LEAK_PERIOD_SNAPSHOT_IN_MILLISEC = 12323l;
71   private static final Date DEFAULT_ISSUE_CREATION_DATE = new Date(1000l);
72   private static final Date BEFORE_LEAK_PERIOD_DATE = new Date(LEAK_PERIOD_SNAPSHOT_IN_MILLISEC - 5000L);
73   private static final Date AFTER_LEAK_PERIOD_DATE = new Date(LEAK_PERIOD_SNAPSHOT_IN_MILLISEC + 5000L);
74
75   static final String LANGUAGE_KEY_1 = "lKey1";
76
77   static final int PROJECT_REF = 1;
78   static final int DIR_REF = 12;
79   static final int DIRECTORY_REF = 123;
80   static final int FILE_1_REF = 1231;
81   static final int FILE_2_REF = 1232;
82
83   static final Component ROOT_PROJECT = builder(Component.Type.PROJECT, PROJECT_REF).setKey("project")
84     .addChildren(
85       builder(DIRECTORY, DIR_REF).setKey("dir")
86         .addChildren(
87           builder(DIRECTORY, DIRECTORY_REF).setKey("directory")
88             .addChildren(
89               builder(FILE, FILE_1_REF).setFileAttributes(new FileAttributes(false, LANGUAGE_KEY_1, 1)).setKey("file1").build(),
90               builder(FILE, FILE_2_REF).setFileAttributes(new FileAttributes(false, LANGUAGE_KEY_1, 1)).setKey("file2").build())
91             .build())
92         .build())
93     .build();
94
95   @Rule
96   public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
97
98   @Rule
99   public MetricRepositoryRule metricRepository = new MetricRepositoryRule()
100     .add(NEW_SECURITY_RATING)
101     .add(NEW_RELIABILITY_RATING);
102
103   @Rule
104   public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository);
105
106   @Rule
107   public PeriodHolderRule periodsHolder = new PeriodHolderRule().setPeriod(new Period("mode", null, LEAK_PERIOD_SNAPSHOT_IN_MILLISEC, "UUID"));
108
109   @Rule
110   public ComponentIssuesRepositoryRule componentIssuesRepositoryRule = new ComponentIssuesRepositoryRule(treeRootHolder);
111
112   @Rule
113   public FillComponentIssuesVisitorRule fillComponentIssuesVisitorRule = new FillComponentIssuesVisitorRule(componentIssuesRepositoryRule, treeRootHolder);
114
115   private VisitorsCrawler underTest = new VisitorsCrawler(Arrays.asList(fillComponentIssuesVisitorRule,
116     new NewReliabilityAndSecurityRatingMeasuresVisitor(metricRepository, measureRepository, componentIssuesRepositoryRule, periodsHolder)));
117
118   @Test
119   public void measures_created_for_project_are_all_A_when_they_have_no_FILE_child() {
120     ReportComponent root = builder(PROJECT, 1).build();
121     treeRootHolder.setRoot(root);
122
123     underTest.visit(root);
124
125     verifyAddedRawMeasureOnLeakPeriod(1, NEW_SECURITY_RATING_KEY, A);
126     verifyAddedRawMeasureOnLeakPeriod(1, NEW_RELIABILITY_RATING_KEY, A);
127   }
128
129   @Test
130   public void no_measure_if_there_is_no_period() {
131     periodsHolder.setPeriod(null);
132     treeRootHolder.setRoot(builder(PROJECT, 1).build());
133
134     underTest.visit(treeRootHolder.getRoot());
135
136     assertThat(measureRepository.getAddedRawMeasures(1).values()).isEmpty();
137   }
138
139   @Test
140   public void compute_new_security_rating() {
141     treeRootHolder.setRoot(ROOT_PROJECT);
142     fillComponentIssuesVisitorRule.setIssues(FILE_1_REF,
143       newVulnerabilityIssue(10L, MAJOR).setCreationDate(AFTER_LEAK_PERIOD_DATE),
144       // Should not be taken into account
145       newVulnerabilityIssue(1L, MAJOR).setCreationDate(BEFORE_LEAK_PERIOD_DATE),
146       newBugIssue(1L, MAJOR).setCreationDate(AFTER_LEAK_PERIOD_DATE));
147     fillComponentIssuesVisitorRule.setIssues(FILE_2_REF,
148       newVulnerabilityIssue(2L, CRITICAL).setCreationDate(AFTER_LEAK_PERIOD_DATE),
149       newVulnerabilityIssue(3L, MINOR).setCreationDate(AFTER_LEAK_PERIOD_DATE),
150       // Should not be taken into account
151       newVulnerabilityIssue(10L, BLOCKER).setCreationDate(AFTER_LEAK_PERIOD_DATE).setResolution(RESOLUTION_FIXED));
152     fillComponentIssuesVisitorRule.setIssues(DIR_REF,
153       newVulnerabilityIssue(7L, BLOCKER).setCreationDate(AFTER_LEAK_PERIOD_DATE));
154
155     underTest.visit(ROOT_PROJECT);
156
157     verifyAddedRawMeasureOnLeakPeriod(FILE_1_REF, NEW_SECURITY_RATING_KEY, C);
158     verifyAddedRawMeasureOnLeakPeriod(FILE_2_REF, NEW_SECURITY_RATING_KEY, D);
159     verifyAddedRawMeasureOnLeakPeriod(DIRECTORY_REF, NEW_SECURITY_RATING_KEY, D);
160     verifyAddedRawMeasureOnLeakPeriod(DIR_REF, NEW_SECURITY_RATING_KEY, E);
161     verifyAddedRawMeasureOnLeakPeriod(PROJECT_REF, NEW_SECURITY_RATING_KEY, E);
162   }
163
164   @Test
165   public void compute_new_security_rating_to_A_when_no_issue() {
166     treeRootHolder.setRoot(ROOT_PROJECT);
167     fillComponentIssuesVisitorRule.setIssues(FILE_1_REF);
168
169     underTest.visit(ROOT_PROJECT);
170
171     verifyAddedRawMeasureOnLeakPeriod(FILE_1_REF, NEW_SECURITY_RATING_KEY, A);
172     verifyAddedRawMeasureOnLeakPeriod(FILE_2_REF, NEW_SECURITY_RATING_KEY, A);
173     verifyAddedRawMeasureOnLeakPeriod(DIRECTORY_REF, NEW_SECURITY_RATING_KEY, A);
174     verifyAddedRawMeasureOnLeakPeriod(DIR_REF, NEW_SECURITY_RATING_KEY, A);
175     verifyAddedRawMeasureOnLeakPeriod(PROJECT_REF, NEW_SECURITY_RATING_KEY, A);
176   }
177
178   @Test
179   public void compute_new_security_rating_to_A_when_no_new_issue() {
180     treeRootHolder.setRoot(ROOT_PROJECT);
181     fillComponentIssuesVisitorRule.setIssues(FILE_1_REF,
182       newVulnerabilityIssue(1L, MAJOR).setCreationDate(BEFORE_LEAK_PERIOD_DATE));
183
184     underTest.visit(ROOT_PROJECT);
185
186     verifyAddedRawMeasureOnLeakPeriod(FILE_1_REF, NEW_SECURITY_RATING_KEY, A);
187     verifyAddedRawMeasureOnLeakPeriod(FILE_2_REF, NEW_SECURITY_RATING_KEY, A);
188     verifyAddedRawMeasureOnLeakPeriod(DIRECTORY_REF, NEW_SECURITY_RATING_KEY, A);
189     verifyAddedRawMeasureOnLeakPeriod(DIR_REF, NEW_SECURITY_RATING_KEY, A);
190     verifyAddedRawMeasureOnLeakPeriod(PROJECT_REF, NEW_SECURITY_RATING_KEY, A);
191   }
192
193   @Test
194   public void compute_new_reliability_rating() {
195     treeRootHolder.setRoot(ROOT_PROJECT);
196     fillComponentIssuesVisitorRule.setIssues(FILE_1_REF,
197       newBugIssue(10L, MAJOR).setCreationDate(AFTER_LEAK_PERIOD_DATE),
198       // Should not be taken into account
199       newBugIssue(1L, MAJOR).setCreationDate(BEFORE_LEAK_PERIOD_DATE),
200       newVulnerabilityIssue(1L, MAJOR).setCreationDate(AFTER_LEAK_PERIOD_DATE));
201     fillComponentIssuesVisitorRule.setIssues(FILE_2_REF,
202       newBugIssue(2L, CRITICAL).setCreationDate(AFTER_LEAK_PERIOD_DATE),
203       newBugIssue(3L, MINOR).setCreationDate(AFTER_LEAK_PERIOD_DATE),
204       // Should not be taken into account
205       newBugIssue(10L, BLOCKER).setCreationDate(AFTER_LEAK_PERIOD_DATE).setResolution(RESOLUTION_FIXED));
206     fillComponentIssuesVisitorRule.setIssues(DIR_REF,
207       newBugIssue(7L, BLOCKER).setCreationDate(AFTER_LEAK_PERIOD_DATE));
208
209     underTest.visit(ROOT_PROJECT);
210
211     verifyAddedRawMeasureOnLeakPeriod(FILE_1_REF, NEW_RELIABILITY_RATING_KEY, C);
212     verifyAddedRawMeasureOnLeakPeriod(FILE_2_REF, NEW_RELIABILITY_RATING_KEY, D);
213     verifyAddedRawMeasureOnLeakPeriod(DIRECTORY_REF, NEW_RELIABILITY_RATING_KEY, D);
214     verifyAddedRawMeasureOnLeakPeriod(DIR_REF, NEW_RELIABILITY_RATING_KEY, E);
215     verifyAddedRawMeasureOnLeakPeriod(PROJECT_REF, NEW_RELIABILITY_RATING_KEY, E);
216   }
217
218   @Test
219   public void compute_new_reliability_rating_to_A_when_no_issue() {
220     treeRootHolder.setRoot(ROOT_PROJECT);
221     fillComponentIssuesVisitorRule.setIssues(FILE_1_REF);
222
223     underTest.visit(ROOT_PROJECT);
224
225     verifyAddedRawMeasureOnLeakPeriod(FILE_1_REF, NEW_RELIABILITY_RATING_KEY, A);
226     verifyAddedRawMeasureOnLeakPeriod(FILE_2_REF, NEW_RELIABILITY_RATING_KEY, A);
227     verifyAddedRawMeasureOnLeakPeriod(DIRECTORY_REF, NEW_RELIABILITY_RATING_KEY, A);
228     verifyAddedRawMeasureOnLeakPeriod(DIR_REF, NEW_RELIABILITY_RATING_KEY, A);
229     verifyAddedRawMeasureOnLeakPeriod(PROJECT_REF, NEW_RELIABILITY_RATING_KEY, A);
230   }
231
232   @Test
233   public void compute_new_reliability_rating_to_A_when_no_new_issue() {
234     treeRootHolder.setRoot(ROOT_PROJECT);
235     fillComponentIssuesVisitorRule.setIssues(FILE_1_REF,
236       newBugIssue(1L, MAJOR).setCreationDate(BEFORE_LEAK_PERIOD_DATE));
237
238     underTest.visit(ROOT_PROJECT);
239
240     verifyAddedRawMeasureOnLeakPeriod(FILE_1_REF, NEW_RELIABILITY_RATING_KEY, A);
241     verifyAddedRawMeasureOnLeakPeriod(FILE_2_REF, NEW_RELIABILITY_RATING_KEY, A);
242     verifyAddedRawMeasureOnLeakPeriod(DIRECTORY_REF, NEW_RELIABILITY_RATING_KEY, A);
243     verifyAddedRawMeasureOnLeakPeriod(DIR_REF, NEW_RELIABILITY_RATING_KEY, A);
244     verifyAddedRawMeasureOnLeakPeriod(PROJECT_REF, NEW_RELIABILITY_RATING_KEY, A);
245   }
246
247   @Test
248   public void compute_E_reliability_and_security_rating_on_blocker_issue() {
249     treeRootHolder.setRoot(ROOT_PROJECT);
250     fillComponentIssuesVisitorRule.setIssues(FILE_1_REF,
251       newBugIssue(10L, BLOCKER).setCreationDate(AFTER_LEAK_PERIOD_DATE),
252       newVulnerabilityIssue(1L, BLOCKER).setCreationDate(AFTER_LEAK_PERIOD_DATE),
253       // Should not be taken into account
254       newBugIssue(1L, MAJOR).setCreationDate(AFTER_LEAK_PERIOD_DATE));
255
256     underTest.visit(ROOT_PROJECT);
257
258     verifyAddedRawMeasureOnLeakPeriod(PROJECT_REF, NEW_RELIABILITY_RATING_KEY, E);
259     verifyAddedRawMeasureOnLeakPeriod(PROJECT_REF, NEW_SECURITY_RATING_KEY, E);
260   }
261
262   @Test
263   public void compute_D_reliability_and_security_rating_on_critical_issue() {
264     treeRootHolder.setRoot(ROOT_PROJECT);
265     fillComponentIssuesVisitorRule.setIssues(FILE_1_REF,
266       newBugIssue(10L, CRITICAL).setCreationDate(AFTER_LEAK_PERIOD_DATE),
267       newVulnerabilityIssue(15L, CRITICAL).setCreationDate(AFTER_LEAK_PERIOD_DATE),
268       // Should not be taken into account
269       newCodeSmellIssue(1L, MAJOR).setCreationDate(AFTER_LEAK_PERIOD_DATE));
270
271     underTest.visit(ROOT_PROJECT);
272
273     verifyAddedRawMeasureOnLeakPeriod(PROJECT_REF, NEW_RELIABILITY_RATING_KEY, D);
274     verifyAddedRawMeasureOnLeakPeriod(PROJECT_REF, NEW_SECURITY_RATING_KEY, D);
275   }
276
277   @Test
278   public void compute_C_reliability_and_security_rating_on_major_issue() {
279     treeRootHolder.setRoot(ROOT_PROJECT);
280     fillComponentIssuesVisitorRule.setIssues(FILE_1_REF,
281       newBugIssue(10L, MAJOR).setCreationDate(AFTER_LEAK_PERIOD_DATE),
282       newVulnerabilityIssue(15L, MAJOR).setCreationDate(AFTER_LEAK_PERIOD_DATE),
283       // Should not be taken into account
284       newCodeSmellIssue(1L, MAJOR).setCreationDate(AFTER_LEAK_PERIOD_DATE));
285
286     underTest.visit(ROOT_PROJECT);
287
288     verifyAddedRawMeasureOnLeakPeriod(PROJECT_REF, NEW_RELIABILITY_RATING_KEY, C);
289     verifyAddedRawMeasureOnLeakPeriod(PROJECT_REF, NEW_SECURITY_RATING_KEY, C);
290   }
291
292   @Test
293   public void compute_B_reliability_and_security_rating_on_minor_issue() {
294     treeRootHolder.setRoot(ROOT_PROJECT);
295     fillComponentIssuesVisitorRule.setIssues(FILE_1_REF,
296       newBugIssue(10L, MINOR).setCreationDate(AFTER_LEAK_PERIOD_DATE),
297       newVulnerabilityIssue(15L, MINOR).setCreationDate(AFTER_LEAK_PERIOD_DATE),
298       // Should not be taken into account
299       newCodeSmellIssue(1L, MAJOR).setCreationDate(AFTER_LEAK_PERIOD_DATE));
300
301     underTest.visit(ROOT_PROJECT);
302
303     verifyAddedRawMeasureOnLeakPeriod(PROJECT_REF, NEW_RELIABILITY_RATING_KEY, B);
304     verifyAddedRawMeasureOnLeakPeriod(PROJECT_REF, NEW_SECURITY_RATING_KEY, B);
305   }
306
307   @Test
308   public void compute_A_reliability_and_security_rating_on_info_issue() {
309     treeRootHolder.setRoot(ROOT_PROJECT);
310     fillComponentIssuesVisitorRule.setIssues(FILE_1_REF,
311       newBugIssue(10L, INFO).setCreationDate(AFTER_LEAK_PERIOD_DATE),
312       newVulnerabilityIssue(15L, INFO).setCreationDate(AFTER_LEAK_PERIOD_DATE),
313       // Should not be taken into account
314       newCodeSmellIssue(1L, MAJOR).setCreationDate(AFTER_LEAK_PERIOD_DATE));
315
316     underTest.visit(ROOT_PROJECT);
317
318     verifyAddedRawMeasureOnLeakPeriod(PROJECT_REF, NEW_RELIABILITY_RATING_KEY, A);
319     verifyAddedRawMeasureOnLeakPeriod(PROJECT_REF, NEW_SECURITY_RATING_KEY, A);
320   }
321
322   private void verifyAddedRawMeasureOnLeakPeriod(int componentRef, String metricKey, Rating rating) {
323     MeasureAssert.assertThat(measureRepository.getAddedRawMeasure(componentRef, metricKey))
324       .hasVariation(rating.getIndex());
325   }
326
327   private static DefaultIssue newBugIssue(long effort, String severity) {
328     return newIssue(effort, severity, BUG);
329   }
330
331   private static DefaultIssue newVulnerabilityIssue(long effort, String severity) {
332     return newIssue(effort, severity, VULNERABILITY);
333   }
334
335   private static DefaultIssue newCodeSmellIssue(long effort, String severity) {
336     return newIssue(effort, severity, CODE_SMELL);
337   }
338
339   private static DefaultIssue newIssue(long effort, String severity, RuleType type) {
340     return newIssue(severity, type)
341       .setEffort(Duration.create(effort));
342   }
343
344   private static DefaultIssue newIssue(String severity, RuleType type) {
345     return new DefaultIssue()
346       .setKey(Uuids.create())
347       .setSeverity(severity)
348       .setType(type)
349       .setCreationDate(DEFAULT_ISSUE_CREATION_DATE);
350   }
351
352 }