]> source.dussan.org Git - sonarqube.git/blob
7f69d94b10b477c66ba40df256b7cc4973e999a6
[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
21 package org.sonar.server.computation.task.projectanalysis.qualitymodel;
22
23 import java.util.Arrays;
24 import java.util.Date;
25 import org.junit.Rule;
26 import org.junit.Test;
27 import org.sonar.api.rules.RuleType;
28 import org.sonar.api.utils.Duration;
29 import org.sonar.core.issue.DefaultIssue;
30 import org.sonar.core.util.Uuids;
31 import org.sonar.server.computation.task.projectanalysis.component.Component;
32 import org.sonar.server.computation.task.projectanalysis.component.FileAttributes;
33 import org.sonar.server.computation.task.projectanalysis.component.ReportComponent;
34 import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolderRule;
35 import org.sonar.server.computation.task.projectanalysis.component.VisitorsCrawler;
36 import org.sonar.server.computation.task.projectanalysis.issue.ComponentIssuesRepositoryRule;
37 import org.sonar.server.computation.task.projectanalysis.issue.FillComponentIssuesVisitorRule;
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.metric.MetricRepositoryRule;
41
42 import static org.assertj.core.api.Assertions.assertThat;
43 import static org.sonar.api.issue.Issue.RESOLUTION_FIXED;
44 import static org.sonar.api.measures.CoreMetrics.RELIABILITY_RATING;
45 import static org.sonar.api.measures.CoreMetrics.RELIABILITY_RATING_KEY;
46 import static org.sonar.api.measures.CoreMetrics.SECURITY_RATING;
47 import static org.sonar.api.measures.CoreMetrics.SECURITY_RATING_KEY;
48 import static org.sonar.api.rule.Severity.BLOCKER;
49 import static org.sonar.api.rule.Severity.CRITICAL;
50 import static org.sonar.api.rule.Severity.INFO;
51 import static org.sonar.api.rule.Severity.MAJOR;
52 import static org.sonar.api.rule.Severity.MINOR;
53 import static org.sonar.api.rules.RuleType.BUG;
54 import static org.sonar.api.rules.RuleType.CODE_SMELL;
55 import static org.sonar.api.rules.RuleType.VULNERABILITY;
56 import static org.sonar.server.computation.task.projectanalysis.component.Component.Type.DIRECTORY;
57 import static org.sonar.server.computation.task.projectanalysis.component.Component.Type.FILE;
58 import static org.sonar.server.computation.task.projectanalysis.component.Component.Type.MODULE;
59 import static org.sonar.server.computation.task.projectanalysis.component.Component.Type.PROJECT;
60 import static org.sonar.server.computation.task.projectanalysis.component.ReportComponent.builder;
61 import static org.sonar.server.computation.task.projectanalysis.measure.Measure.newMeasureBuilder;
62 import static org.sonar.server.computation.task.projectanalysis.measure.MeasureRepoEntry.entryOf;
63 import static org.sonar.server.computation.task.projectanalysis.measure.MeasureRepoEntry.toEntries;
64 import static org.sonar.server.computation.task.projectanalysis.qualitymodel.RatingGrid.Rating;
65 import static org.sonar.server.computation.task.projectanalysis.qualitymodel.RatingGrid.Rating.A;
66 import static org.sonar.server.computation.task.projectanalysis.qualitymodel.RatingGrid.Rating.B;
67 import static org.sonar.server.computation.task.projectanalysis.qualitymodel.RatingGrid.Rating.C;
68 import static org.sonar.server.computation.task.projectanalysis.qualitymodel.RatingGrid.Rating.D;
69 import static org.sonar.server.computation.task.projectanalysis.qualitymodel.RatingGrid.Rating.E;
70
71 public class ReliabilityAndSecurityRatingMeasuresVisitorForReportTest {
72
73   static final String LANGUAGE_KEY_1 = "lKey1";
74
75   static final int PROJECT_REF = 1;
76   static final int MODULE_REF = 12;
77   static final int DIRECTORY_REF = 123;
78   static final int FILE_1_REF = 1231;
79   static final int FILE_2_REF = 1232;
80
81   static final Component ROOT_PROJECT = builder(Component.Type.PROJECT, PROJECT_REF).setKey("project")
82     .addChildren(
83       builder(MODULE, MODULE_REF).setKey("module")
84         .addChildren(
85           builder(DIRECTORY, DIRECTORY_REF).setKey("directory")
86             .addChildren(
87               builder(FILE, FILE_1_REF).setFileAttributes(new FileAttributes(false, LANGUAGE_KEY_1)).setKey("file1").build(),
88               builder(FILE, FILE_2_REF).setFileAttributes(new FileAttributes(false, LANGUAGE_KEY_1)).setKey("file2").build())
89             .build())
90         .build())
91     .build();
92
93   @Rule
94   public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
95
96   @Rule
97   public MetricRepositoryRule metricRepository = new MetricRepositoryRule()
98     .add(RELIABILITY_RATING)
99     .add(SECURITY_RATING);
100
101   @Rule
102   public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository);
103
104   @Rule
105   public ComponentIssuesRepositoryRule componentIssuesRepositoryRule = new ComponentIssuesRepositoryRule(treeRootHolder);
106
107   @Rule
108   public FillComponentIssuesVisitorRule fillComponentIssuesVisitorRule = new FillComponentIssuesVisitorRule(componentIssuesRepositoryRule, treeRootHolder);
109
110   VisitorsCrawler underTest = new VisitorsCrawler(
111     Arrays.asList(fillComponentIssuesVisitorRule, new ReliabilityAndSecurityRatingMeasuresVisitor(metricRepository, measureRepository, componentIssuesRepositoryRule)));
112
113   @Test
114   public void measures_created_for_project_are_all_A_when_they_have_no_FILE_child() {
115     ReportComponent root = builder(PROJECT, 1).build();
116     treeRootHolder.setRoot(root);
117
118     underTest.visit(root);
119
120     assertThat(toEntries(measureRepository.getRawMeasures(root)))
121       .containsOnly(
122         entryOf(RELIABILITY_RATING_KEY, createRatingMeasure(A)),
123         entryOf(SECURITY_RATING_KEY, createRatingMeasure(A)));
124   }
125
126   @Test
127   public void compute_reliability_rating() throws Exception {
128     treeRootHolder.setRoot(ROOT_PROJECT);
129     fillComponentIssuesVisitorRule.setIssues(FILE_1_REF, newBugIssue(10L, MAJOR), newBugIssue(1L, MAJOR),
130       // Should not be taken into account
131       newVulnerabilityIssue(5L, MINOR));
132     fillComponentIssuesVisitorRule.setIssues(FILE_2_REF, newBugIssue(2L, CRITICAL), newBugIssue(3L, MINOR),
133       // Should not be taken into account
134       newBugIssue(10L, BLOCKER).setResolution(RESOLUTION_FIXED));
135     fillComponentIssuesVisitorRule.setIssues(MODULE_REF, newBugIssue(7L, BLOCKER));
136
137     underTest.visit(ROOT_PROJECT);
138
139     verifyAddedRawMeasure(FILE_1_REF, RELIABILITY_RATING_KEY, C);
140     verifyAddedRawMeasure(FILE_2_REF, RELIABILITY_RATING_KEY, D);
141     verifyAddedRawMeasure(DIRECTORY_REF, RELIABILITY_RATING_KEY, D);
142     verifyAddedRawMeasure(MODULE_REF, RELIABILITY_RATING_KEY, E);
143     verifyAddedRawMeasure(PROJECT_REF, RELIABILITY_RATING_KEY, E);
144   }
145
146   @Test
147   public void compute_security_rating() throws Exception {
148     treeRootHolder.setRoot(ROOT_PROJECT);
149     fillComponentIssuesVisitorRule.setIssues(FILE_1_REF, newVulnerabilityIssue(10L, MAJOR), newVulnerabilityIssue(1L, MAJOR),
150       // Should not be taken into account
151       newBugIssue(1L, MAJOR));
152     fillComponentIssuesVisitorRule.setIssues(FILE_2_REF, newVulnerabilityIssue(2L, CRITICAL), newVulnerabilityIssue(3L, MINOR),
153       // Should not be taken into account
154       newVulnerabilityIssue(10L, BLOCKER).setResolution(RESOLUTION_FIXED));
155     fillComponentIssuesVisitorRule.setIssues(MODULE_REF, newVulnerabilityIssue(7L, BLOCKER));
156
157     underTest.visit(ROOT_PROJECT);
158
159     verifyAddedRawMeasure(FILE_1_REF, SECURITY_RATING_KEY, C);
160     verifyAddedRawMeasure(FILE_2_REF, SECURITY_RATING_KEY, D);
161     verifyAddedRawMeasure(DIRECTORY_REF, SECURITY_RATING_KEY, D);
162     verifyAddedRawMeasure(MODULE_REF, SECURITY_RATING_KEY, E);
163     verifyAddedRawMeasure(PROJECT_REF, SECURITY_RATING_KEY, E);
164   }
165
166   @Test
167   public void compute_E_reliability_and_security_rating_on_blocker_issue() throws Exception {
168     treeRootHolder.setRoot(ROOT_PROJECT);
169     fillComponentIssuesVisitorRule.setIssues(FILE_1_REF, newBugIssue(10L, BLOCKER), newVulnerabilityIssue(1L, BLOCKER),
170       // Should not be taken into account
171       newBugIssue(1L, MAJOR));
172
173     underTest.visit(ROOT_PROJECT);
174
175     verifyAddedRawMeasure(PROJECT_REF, RELIABILITY_RATING_KEY, E);
176     verifyAddedRawMeasure(PROJECT_REF, SECURITY_RATING_KEY, E);
177   }
178
179   @Test
180   public void compute_D_reliability_and_security_rating_on_critical_issue() throws Exception {
181     treeRootHolder.setRoot(ROOT_PROJECT);
182     fillComponentIssuesVisitorRule.setIssues(FILE_1_REF, newBugIssue(10L, CRITICAL), newVulnerabilityIssue(15L, CRITICAL),
183       // Should not be taken into account
184       newCodeSmellIssue(1L, MAJOR));
185
186     underTest.visit(ROOT_PROJECT);
187
188     verifyAddedRawMeasure(PROJECT_REF, RELIABILITY_RATING_KEY, D);
189     verifyAddedRawMeasure(PROJECT_REF, SECURITY_RATING_KEY, D);
190   }
191
192   @Test
193   public void compute_C_reliability_and_security_rating_on_major_issue() throws Exception {
194     treeRootHolder.setRoot(ROOT_PROJECT);
195     fillComponentIssuesVisitorRule.setIssues(FILE_1_REF, newBugIssue(10L, MAJOR), newVulnerabilityIssue(15L, MAJOR),
196       // Should not be taken into account
197       newCodeSmellIssue(1L, MAJOR));
198
199     underTest.visit(ROOT_PROJECT);
200
201     verifyAddedRawMeasure(PROJECT_REF, RELIABILITY_RATING_KEY, C);
202     verifyAddedRawMeasure(PROJECT_REF, SECURITY_RATING_KEY, C);
203   }
204
205   @Test
206   public void compute_B_reliability_and_security_rating_on_minor_issue() throws Exception {
207     treeRootHolder.setRoot(ROOT_PROJECT);
208     fillComponentIssuesVisitorRule.setIssues(FILE_1_REF, newBugIssue(10L, MINOR), newVulnerabilityIssue(15L, MINOR),
209       // Should not be taken into account
210       newCodeSmellIssue(1L, MAJOR));
211
212     underTest.visit(ROOT_PROJECT);
213
214     verifyAddedRawMeasure(PROJECT_REF, RELIABILITY_RATING_KEY, B);
215     verifyAddedRawMeasure(PROJECT_REF, SECURITY_RATING_KEY, B);
216   }
217
218   @Test
219   public void compute_A_reliability_and_security_rating_on_info_issue() throws Exception {
220     treeRootHolder.setRoot(ROOT_PROJECT);
221     fillComponentIssuesVisitorRule.setIssues(FILE_1_REF, newBugIssue(10L, INFO), newVulnerabilityIssue(15L, INFO),
222       // Should not be taken into account
223       newCodeSmellIssue(1L, MAJOR));
224
225     underTest.visit(ROOT_PROJECT);
226
227     verifyAddedRawMeasure(PROJECT_REF, RELIABILITY_RATING_KEY, A);
228     verifyAddedRawMeasure(PROJECT_REF, SECURITY_RATING_KEY, A);
229   }
230
231   private void verifyAddedRawMeasure(int componentRef, String metricKey, Rating rating) {
232     assertThat(toEntries(measureRepository.getAddedRawMeasures(componentRef))).contains(entryOf(metricKey, newMeasureBuilder().create(rating.getIndex(), rating.name())));
233   }
234
235   private static Measure createRatingMeasure(Rating rating) {
236     return newMeasureBuilder().create(rating.getIndex(), rating.name());
237   }
238
239   private static DefaultIssue newBugIssue(long effort, String severity) {
240     return newIssue(effort, severity, BUG);
241   }
242
243   private static DefaultIssue newVulnerabilityIssue(long effort, String severity) {
244     return newIssue(effort, severity, VULNERABILITY);
245   }
246
247   private static DefaultIssue newCodeSmellIssue(long effort, String severity) {
248     return newIssue(effort, severity, CODE_SMELL);
249   }
250
251   private static DefaultIssue newIssue(long effort, String severity, RuleType type) {
252     return newIssue(severity, type)
253       .setEffort(Duration.create(effort));
254   }
255
256   private static DefaultIssue newIssue(String severity, RuleType type) {
257     return new DefaultIssue()
258       .setKey(Uuids.create())
259       .setSeverity(severity)
260       .setType(type)
261       .setCreationDate(new Date(1000l));
262   }
263
264 }