3 * Copyright (C) 2009-2017 SonarSource SA
4 * mailto:info AT sonarsource DOT com
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.
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.
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.
20 package org.sonar.server.computation.task.projectanalysis.issue;
22 import com.google.common.collect.Iterators;
23 import java.util.Collection;
24 import org.junit.Rule;
25 import org.junit.Test;
26 import org.sonar.api.issue.Issue;
27 import org.sonar.api.rule.RuleKey;
28 import org.sonar.api.rule.Severity;
29 import org.sonar.core.issue.DefaultIssue;
30 import org.sonar.core.issue.tracking.Input;
31 import org.sonar.scanner.protocol.Constants;
32 import org.sonar.scanner.protocol.output.ScannerReport;
33 import org.sonar.scanner.protocol.output.ScannerReport.TextRange;
34 import org.sonar.server.computation.task.projectanalysis.batch.BatchReportReaderRule;
35 import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolderRule;
36 import org.sonar.server.computation.task.projectanalysis.component.Component;
37 import org.sonar.server.computation.task.projectanalysis.component.ReportComponent;
38 import org.sonar.server.computation.task.projectanalysis.issue.commonrule.CommonRuleEngine;
39 import org.sonar.server.computation.task.projectanalysis.issue.filter.IssueFilter;
40 import org.sonar.server.computation.task.projectanalysis.source.SourceLinesRepositoryRule;
41 import org.sonar.server.rule.CommonRuleKeys;
43 import static java.util.Arrays.asList;
44 import static org.assertj.core.api.Assertions.assertThat;
45 import static org.mockito.Matchers.any;
46 import static org.mockito.Matchers.eq;
47 import static org.mockito.Mockito.mock;
48 import static org.mockito.Mockito.when;
50 public class TrackerRawInputFactoryTest {
52 static int FILE_REF = 2;
54 static ReportComponent PROJECT = ReportComponent.builder(Component.Type.PROJECT, 1).setKey("PROJECT_KEY_2").setUuid("PROJECT_UUID_1").build();
55 static ReportComponent FILE = ReportComponent.builder(Component.Type.FILE, FILE_REF).setKey("FILE_KEY_2").setUuid("FILE_UUID_2").build();
58 public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule().setRoot(PROJECT);
61 public BatchReportReaderRule reportReader = new BatchReportReaderRule();
64 public SourceLinesRepositoryRule fileSourceRepository = new SourceLinesRepositoryRule();
66 CommonRuleEngine commonRuleEngine = mock(CommonRuleEngine.class);
68 IssueFilter issueFilter = mock(IssueFilter.class);
70 TrackerRawInputFactory underTest = new TrackerRawInputFactory(treeRootHolder, reportReader, fileSourceRepository, commonRuleEngine, issueFilter);
73 public void load_source_hash_sequences() throws Exception {
74 fileSourceRepository.addLines(FILE_REF, "line 1;", "line 2;");
75 Input<DefaultIssue> input = underTest.create(FILE);
77 assertThat(input.getLineHashSequence()).isNotNull();
78 assertThat(input.getLineHashSequence().getHashForLine(1)).isNotEmpty();
79 assertThat(input.getLineHashSequence().getHashForLine(2)).isNotEmpty();
80 assertThat(input.getLineHashSequence().getHashForLine(3)).isEmpty();
82 assertThat(input.getBlockHashSequence()).isNotNull();
86 public void load_source_hash_sequences_only_on_files() throws Exception {
87 Input<DefaultIssue> input = underTest.create(PROJECT);
89 assertThat(input.getLineHashSequence()).isNotNull();
90 assertThat(input.getBlockHashSequence()).isNotNull();
94 public void load_issues_from_report() throws Exception {
95 when(issueFilter.accept(any(DefaultIssue.class), eq(FILE))).thenReturn(true);
96 fileSourceRepository.addLines(FILE_REF, "line 1;", "line 2;");
97 ScannerReport.Issue reportIssue = ScannerReport.Issue.newBuilder()
98 .setTextRange(TextRange.newBuilder().setStartLine(2).build())
99 .setMsg("the message")
100 .setRuleRepository("java")
102 .setSeverity(Constants.Severity.BLOCKER)
105 reportReader.putIssues(FILE.getReportAttributes().getRef(), asList(reportIssue));
106 Input<DefaultIssue> input = underTest.create(FILE);
108 Collection<DefaultIssue> issues = input.getIssues();
109 assertThat(issues).hasSize(1);
110 DefaultIssue issue = Iterators.getOnlyElement(issues.iterator());
112 // fields set by analysis report
113 assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("java", "S001"));
114 assertThat(issue.severity()).isEqualTo(Severity.BLOCKER);
115 assertThat(issue.line()).isEqualTo(2);
116 assertThat(issue.effortToFix()).isEqualTo(3.14);
117 assertThat(issue.gap()).isEqualTo(3.14);
118 assertThat(issue.message()).isEqualTo("the message");
120 // fields set by compute engine
121 assertThat(issue.checksum()).isEqualTo(input.getLineHashSequence().getHashForLine(2));
122 assertThat(issue.tags()).isEmpty();
123 assertInitializedIssue(issue);
127 public void ignore_issue_from_report() throws Exception {
128 when(issueFilter.accept(any(DefaultIssue.class), eq(FILE))).thenReturn(false);
129 fileSourceRepository.addLines(FILE_REF, "line 1;", "line 2;");
130 ScannerReport.Issue reportIssue = ScannerReport.Issue.newBuilder()
131 .setTextRange(TextRange.newBuilder().setStartLine(2).build())
132 .setMsg("the message")
133 .setRuleRepository("java")
135 .setSeverity(Constants.Severity.BLOCKER)
138 reportReader.putIssues(FILE.getReportAttributes().getRef(), asList(reportIssue));
139 Input<DefaultIssue> input = underTest.create(FILE);
141 Collection<DefaultIssue> issues = input.getIssues();
142 assertThat(issues).isEmpty();
146 public void ignore_report_issues_on_common_rules() throws Exception {
147 fileSourceRepository.addLines(FILE_REF, "line 1;", "line 2;");
148 ScannerReport.Issue reportIssue = ScannerReport.Issue.newBuilder()
149 .setMsg("the message")
150 .setRuleRepository(CommonRuleKeys.commonRepositoryForLang("java"))
152 .setSeverity(Constants.Severity.BLOCKER)
154 reportReader.putIssues(FILE.getReportAttributes().getRef(), asList(reportIssue));
156 Input<DefaultIssue> input = underTest.create(FILE);
158 assertThat(input.getIssues()).isEmpty();
162 public void load_issues_of_compute_engine_common_rules() throws Exception {
163 when(issueFilter.accept(any(DefaultIssue.class), eq(FILE))).thenReturn(true);
164 fileSourceRepository.addLines(FILE_REF, "line 1;", "line 2;");
165 DefaultIssue ceIssue = new DefaultIssue()
166 .setRuleKey(RuleKey.of(CommonRuleKeys.commonRepositoryForLang("java"), "InsufficientCoverage"))
167 .setMessage("not enough coverage")
169 when(commonRuleEngine.process(FILE)).thenReturn(asList(ceIssue));
171 Input<DefaultIssue> input = underTest.create(FILE);
173 assertThat(input.getIssues()).containsOnly(ceIssue);
174 assertInitializedIssue(input.getIssues().iterator().next());
178 public void ignore_issue_from_common_rule() throws Exception {
179 when(issueFilter.accept(any(DefaultIssue.class), eq(FILE))).thenReturn(false);
180 fileSourceRepository.addLines(FILE_REF, "line 1;", "line 2;");
181 DefaultIssue ceIssue = new DefaultIssue()
182 .setRuleKey(RuleKey.of(CommonRuleKeys.commonRepositoryForLang("java"), "InsufficientCoverage"))
183 .setMessage("not enough coverage")
185 when(commonRuleEngine.process(FILE)).thenReturn(asList(ceIssue));
187 Input<DefaultIssue> input = underTest.create(FILE);
189 assertThat(input.getIssues()).isEmpty();
192 private void assertInitializedIssue(DefaultIssue issue) {
193 assertThat(issue.componentKey()).isEqualTo(FILE.getKey());
194 assertThat(issue.componentUuid()).isEqualTo(FILE.getUuid());
195 assertThat(issue.resolution()).isNull();
196 assertThat(issue.status()).isEqualTo(Issue.STATUS_OPEN);
197 assertThat(issue.key()).isNull();
198 assertThat(issue.authorLogin()).isNull();
199 assertThat(issue.debt()).isNull();