]> source.dussan.org Git - sonarqube.git/blob
83b89c79d96151762180068566487d5962357b55
[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.issue;
21
22 import java.util.Collections;
23 import java.util.List;
24 import org.junit.Before;
25 import org.junit.Rule;
26 import org.junit.Test;
27 import org.junit.rules.TemporaryFolder;
28 import org.mockito.ArgumentCaptor;
29 import org.sonar.api.issue.Issue;
30 import org.sonar.api.rule.RuleKey;
31 import org.sonar.api.rule.Severity;
32 import org.sonar.api.utils.System2;
33 import org.sonar.core.issue.DefaultIssue;
34 import org.sonar.core.issue.tracking.Tracker;
35 import org.sonar.db.DbTester;
36 import org.sonar.db.component.ComponentDto;
37 import org.sonar.db.component.ComponentTesting;
38 import org.sonar.db.issue.IssueDto;
39 import org.sonar.db.rule.RuleDto;
40 import org.sonar.db.rule.RuleTesting;
41 import org.sonar.scanner.protocol.Constants;
42 import org.sonar.scanner.protocol.output.ScannerReport;
43 import org.sonar.server.computation.batch.BatchReportReaderRule;
44 import org.sonar.server.computation.batch.TreeRootHolderRule;
45 import org.sonar.server.computation.component.Component;
46 import org.sonar.server.computation.component.TypeAwareVisitor;
47 import org.sonar.server.computation.issue.commonrule.CommonRuleEngineImpl;
48 import org.sonar.server.computation.qualityprofile.ActiveRulesHolderRule;
49 import org.sonar.server.computation.source.SourceLinesRepositoryRule;
50 import org.sonar.server.issue.IssueTesting;
51
52 import static com.google.common.collect.Lists.newArrayList;
53 import static com.google.common.collect.Sets.newHashSet;
54 import static java.util.Arrays.asList;
55 import static org.assertj.core.api.Assertions.assertThat;
56 import static org.mockito.Matchers.eq;
57 import static org.mockito.Mockito.mock;
58 import static org.mockito.Mockito.verify;
59 import static org.sonar.server.computation.component.ReportComponent.builder;
60
61 public class IntegrateIssuesVisitorTest {
62
63   static final String FILE_UUID = "FILE_UUID";
64   static final String FILE_KEY = "FILE_KEY";
65   static final int FILE_REF = 2;
66   static final Component FILE = builder(Component.Type.FILE, FILE_REF)
67     .setKey(FILE_KEY)
68     .setUuid(FILE_UUID)
69     .build();
70
71   static final String PROJECT_KEY = "PROJECT_KEY";
72   static final String PROJECT_UUID = "PROJECT_UUID";
73   static final int PROJECT_REF = 1;
74   static final Component PROJECT = builder(Component.Type.PROJECT, PROJECT_REF)
75     .setKey(PROJECT_KEY)
76     .setUuid(PROJECT_UUID)
77     .addChildren(FILE)
78     .build();
79
80   @Rule
81   public TemporaryFolder temp = new TemporaryFolder();
82
83   @Rule
84   public DbTester dbTester = DbTester.create(System2.INSTANCE);
85
86   @Rule
87   public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
88
89   @Rule
90   public BatchReportReaderRule reportReader = new BatchReportReaderRule();
91
92   @Rule
93   public ActiveRulesHolderRule activeRulesHolderRule = new ActiveRulesHolderRule();
94
95   @Rule
96   public RuleRepositoryRule ruleRepositoryRule = new RuleRepositoryRule();
97
98   @Rule
99   public ComponentIssuesRepositoryRule componentIssuesRepository = new ComponentIssuesRepositoryRule(treeRootHolder);
100
101   @Rule
102   public SourceLinesRepositoryRule fileSourceRepository = new SourceLinesRepositoryRule();
103
104   ArgumentCaptor<DefaultIssue> defaultIssueCaptor = ArgumentCaptor.forClass(DefaultIssue.class);
105
106   BaseIssuesLoader baseIssuesLoader = new BaseIssuesLoader(treeRootHolder, dbTester.getDbClient(), ruleRepositoryRule, activeRulesHolderRule);
107   TrackerExecution tracker = new TrackerExecution(new TrackerBaseInputFactory(baseIssuesLoader, dbTester.getDbClient()), new TrackerRawInputFactory(treeRootHolder, reportReader,
108     fileSourceRepository, new CommonRuleEngineImpl()), new Tracker<DefaultIssue, DefaultIssue>());
109   IssueCache issueCache;
110
111   IssueLifecycle issueLifecycle = mock(IssueLifecycle.class);
112   IssueVisitor issueVisitor = mock(IssueVisitor.class);
113   IssueVisitors issueVisitors = new IssueVisitors(new IssueVisitor[]{issueVisitor});
114   ComponentsWithUnprocessedIssues componentsWithUnprocessedIssues = new ComponentsWithUnprocessedIssues();
115
116   TypeAwareVisitor underTest;
117
118   @Before
119   public void setUp() throws Exception {
120     treeRootHolder.setRoot(PROJECT);
121     issueCache = new IssueCache(temp.newFile(), System2.INSTANCE);
122     underTest = new IntegrateIssuesVisitor(tracker, issueCache, issueLifecycle, issueVisitors, componentsWithUnprocessedIssues, componentIssuesRepository);
123   }
124
125   @Test
126   public void process_new_issue() throws Exception {
127     componentsWithUnprocessedIssues.setUuids(Collections.<String>emptySet());
128
129     ScannerReport.Issue reportIssue = ScannerReport.Issue.newBuilder()
130       .setMsg("the message")
131       .setRuleRepository("xoo")
132       .setRuleKey("S001")
133       .setSeverity(Constants.Severity.BLOCKER)
134       .build();
135     reportReader.putIssues(FILE_REF, asList(reportIssue));
136     fileSourceRepository.addLine(FILE_REF, "line1");
137
138     underTest.visitAny(FILE);
139
140     verify(issueLifecycle).initNewOpenIssue(defaultIssueCaptor.capture());
141     assertThat(defaultIssueCaptor.getValue().ruleKey().rule()).isEqualTo("S001");
142
143     verify(issueLifecycle).doAutomaticTransition(defaultIssueCaptor.capture());
144     assertThat(defaultIssueCaptor.getValue().ruleKey().rule()).isEqualTo("S001");
145
146     assertThat(newArrayList(issueCache.traverse())).hasSize(1);
147     assertThat(componentsWithUnprocessedIssues.getUuids()).isEmpty();
148   }
149
150   @Test
151   public void process_existing_issue() throws Exception {
152     componentsWithUnprocessedIssues.setUuids(newHashSet(FILE_UUID));
153
154     RuleKey ruleKey = RuleTesting.XOO_X1;
155     // Issue from db has severity major
156     addBaseIssue(ruleKey);
157
158     // Issue from report has severity blocker
159     ScannerReport.Issue reportIssue = ScannerReport.Issue.newBuilder()
160       .setMsg("the message")
161       .setRuleRepository(ruleKey.repository())
162       .setRuleKey(ruleKey.rule())
163       .setSeverity(Constants.Severity.BLOCKER)
164       .build();
165     reportReader.putIssues(FILE_REF, asList(reportIssue));
166     fileSourceRepository.addLine(FILE_REF, "line1");
167
168     underTest.visitAny(FILE);
169
170     ArgumentCaptor<DefaultIssue> rawIssueCaptor = ArgumentCaptor.forClass(DefaultIssue.class);
171     ArgumentCaptor<DefaultIssue> baseIssueCaptor = ArgumentCaptor.forClass(DefaultIssue.class);
172     verify(issueLifecycle).mergeExistingOpenIssue(rawIssueCaptor.capture(), baseIssueCaptor.capture());
173     assertThat(rawIssueCaptor.getValue().severity()).isEqualTo(Severity.BLOCKER);
174     assertThat(baseIssueCaptor.getValue().severity()).isEqualTo(Severity.MAJOR);
175
176     verify(issueLifecycle).doAutomaticTransition(defaultIssueCaptor.capture());
177     assertThat(defaultIssueCaptor.getValue().ruleKey()).isEqualTo(ruleKey);
178     List<DefaultIssue> issues = newArrayList(issueCache.traverse());
179     assertThat(issues).hasSize(1);
180     assertThat(issues.get(0).severity()).isEqualTo(Severity.BLOCKER);
181
182     assertThat(componentsWithUnprocessedIssues.getUuids()).isEmpty();
183   }
184
185   @Test
186   public void process_manual_issue() throws Exception {
187     componentsWithUnprocessedIssues.setUuids(newHashSet(FILE_UUID));
188
189     RuleKey ruleKey = RuleKey.of(RuleKey.MANUAL_REPOSITORY_KEY, "architecture");
190     addBaseIssue(ruleKey);
191
192     underTest.visitAny(FILE);
193
194     verify(issueLifecycle).moveOpenManualIssue(defaultIssueCaptor.capture(), eq((Integer) null));
195     assertThat(defaultIssueCaptor.getValue().ruleKey()).isEqualTo(ruleKey);
196
197     verify(issueLifecycle).doAutomaticTransition(defaultIssueCaptor.capture());
198     assertThat(defaultIssueCaptor.getValue().ruleKey()).isEqualTo(ruleKey);
199     List<DefaultIssue> issues = newArrayList(issueCache.traverse());
200     assertThat(issues).hasSize(1);
201
202     assertThat(componentsWithUnprocessedIssues.getUuids()).isEmpty();
203   }
204
205   @Test
206   public void execute_issue_visitors() throws Exception {
207     componentsWithUnprocessedIssues.setUuids(Collections.<String>emptySet());
208     ScannerReport.Issue reportIssue = ScannerReport.Issue.newBuilder()
209       .setMsg("the message")
210       .setRuleRepository("xoo")
211       .setRuleKey("S001")
212       .setSeverity(Constants.Severity.BLOCKER)
213       .build();
214     reportReader.putIssues(FILE_REF, asList(reportIssue));
215     fileSourceRepository.addLine(FILE_REF, "line1");
216
217     underTest.visitAny(FILE);
218
219     verify(issueVisitor).beforeComponent(FILE);
220     verify(issueVisitor).afterComponent(FILE);
221     verify(issueVisitor).onIssue(eq(FILE), defaultIssueCaptor.capture());
222     assertThat(defaultIssueCaptor.getValue().ruleKey().rule()).isEqualTo("S001");
223   }
224
225   @Test
226   public void close_unmatched_base_issue() throws Exception {
227     componentsWithUnprocessedIssues.setUuids(newHashSet(FILE_UUID));
228     RuleKey ruleKey = RuleTesting.XOO_X1;
229     addBaseIssue(ruleKey);
230
231     // No issue in the report
232
233     underTest.visitAny(FILE);
234
235     verify(issueLifecycle).doAutomaticTransition(defaultIssueCaptor.capture());
236     assertThat(defaultIssueCaptor.getValue().isBeingClosed()).isTrue();
237     List<DefaultIssue> issues = newArrayList(issueCache.traverse());
238     assertThat(issues).hasSize(1);
239
240     assertThat(componentsWithUnprocessedIssues.getUuids()).isEmpty();
241   }
242
243   @Test
244   public void feed_component_issues_repo() throws Exception {
245     componentsWithUnprocessedIssues.setUuids(Collections.<String>emptySet());
246
247     ScannerReport.Issue reportIssue = ScannerReport.Issue.newBuilder()
248       .setMsg("the message")
249       .setRuleRepository("xoo")
250       .setRuleKey("S001")
251       .setSeverity(Constants.Severity.BLOCKER)
252       .build();
253     reportReader.putIssues(FILE_REF, asList(reportIssue));
254     fileSourceRepository.addLine(FILE_REF, "line1");
255
256     underTest.visitAny(FILE);
257
258     assertThat(componentIssuesRepository.getIssues(FILE_REF)).hasSize(1);
259   }
260
261   @Test
262   public void empty_component_issues_repo_when_no_issue() throws Exception {
263     componentsWithUnprocessedIssues.setUuids(Collections.<String>emptySet());
264
265     ScannerReport.Issue reportIssue = ScannerReport.Issue.newBuilder()
266       .setMsg("the message")
267       .setRuleRepository("xoo")
268       .setRuleKey("S001")
269       .setSeverity(Constants.Severity.BLOCKER)
270       .build();
271     reportReader.putIssues(FILE_REF, asList(reportIssue));
272     fileSourceRepository.addLine(FILE_REF, "line1");
273
274     underTest.visitAny(FILE);
275     assertThat(componentIssuesRepository.getIssues(FILE_REF)).hasSize(1);
276
277     underTest.visitAny(PROJECT);
278     assertThat(componentIssuesRepository.getIssues(PROJECT)).isEmpty();
279   }
280
281   private void addBaseIssue(RuleKey ruleKey) {
282     ComponentDto project = ComponentTesting.newProjectDto(PROJECT_UUID).setKey(PROJECT_KEY);
283     ComponentDto file = ComponentTesting.newFileDto(project, FILE_UUID).setKey(FILE_KEY);
284     dbTester.getDbClient().componentDao().insert(dbTester.getSession(), project, file);
285
286     RuleDto ruleDto = RuleTesting.newDto(ruleKey);
287     dbTester.getDbClient().ruleDao().insert(dbTester.getSession(), ruleDto);
288     ruleRepositoryRule.add(ruleKey);
289
290     IssueDto issue = IssueTesting.newDto(ruleDto, file, project)
291       .setKee("ISSUE")
292       .setStatus(Issue.STATUS_OPEN)
293       .setSeverity(Severity.MAJOR);
294     dbTester.getDbClient().issueDao().insert(dbTester.getSession(), issue);
295     dbTester.getSession().commit();
296   }
297
298 }