3 * Copyright (C) 2009-2024 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.ce.task.projectanalysis.batch;
22 import com.google.common.collect.ImmutableList;
24 import java.io.IOException;
25 import org.apache.commons.io.FileUtils;
26 import org.junit.Before;
27 import org.junit.Rule;
28 import org.junit.Test;
29 import org.sonar.api.impl.utils.JUnitTempFolder;
30 import org.sonar.core.util.CloseableIterator;
31 import org.sonar.scanner.protocol.output.FileStructure;
32 import org.sonar.scanner.protocol.output.ScannerReport;
33 import org.sonar.scanner.protocol.output.ScannerReport.Cve;
34 import org.sonar.scanner.protocol.output.ScannerReportWriter;
36 import static com.google.common.collect.ImmutableList.of;
37 import static org.assertj.core.api.Assertions.assertThat;
38 import static org.assertj.core.api.Assertions.assertThatThrownBy;
40 public class BatchReportReaderImplTest {
41 private static final int COMPONENT_REF = 1;
42 private static final ScannerReport.Changesets CHANGESETS = ScannerReport.Changesets.newBuilder().setComponentRef(COMPONENT_REF).build();
43 private static final ScannerReport.Measure MEASURE = ScannerReport.Measure.newBuilder().build();
44 private static final ScannerReport.Component COMPONENT = ScannerReport.Component.newBuilder().setRef(COMPONENT_REF).build();
45 private static final ScannerReport.Issue ISSUE = ScannerReport.Issue.newBuilder().build();
46 private static final ScannerReport.Duplication DUPLICATION = ScannerReport.Duplication.newBuilder().build();
47 private static final ScannerReport.CpdTextBlock DUPLICATION_BLOCK = ScannerReport.CpdTextBlock.newBuilder().build();
48 private static final ScannerReport.Symbol SYMBOL = ScannerReport.Symbol.newBuilder().build();
49 private static final ScannerReport.SyntaxHighlightingRule SYNTAX_HIGHLIGHTING_1 = ScannerReport.SyntaxHighlightingRule.newBuilder().build();
50 private static final ScannerReport.SyntaxHighlightingRule SYNTAX_HIGHLIGHTING_2 = ScannerReport.SyntaxHighlightingRule.newBuilder().build();
51 private static final ScannerReport.LineCoverage COVERAGE_1 = ScannerReport.LineCoverage.newBuilder().build();
52 private static final ScannerReport.LineCoverage COVERAGE_2 = ScannerReport.LineCoverage.newBuilder().build();
55 public JUnitTempFolder tempFolder = new JUnitTempFolder();
57 private ScannerReportWriter writer;
58 private BatchReportReaderImpl underTest;
62 BatchReportDirectoryHolder holder = new ImmutableBatchReportDirectoryHolder(tempFolder.newDir());
63 underTest = new BatchReportReaderImpl(holder);
64 FileStructure fileStructure = new FileStructure(holder.getDirectory());
65 writer = new ScannerReportWriter(fileStructure);
69 public void readMetadata_throws_ISE_if_no_metadata() {
70 assertThatThrownBy(() -> underTest.readMetadata())
71 .isInstanceOf(IllegalStateException.class);
75 public void readMetadata_result_is_cached() {
76 ScannerReport.Metadata metadata = ScannerReport.Metadata.newBuilder().build();
78 writer.writeMetadata(metadata);
80 ScannerReport.Metadata res = underTest.readMetadata();
81 assertThat(res).isEqualTo(metadata);
82 assertThat(underTest.readMetadata()).isSameAs(res);
86 public void readScannerLogs() throws IOException {
87 File scannerLogFile = writer.getFileStructure().analysisLog();
88 FileUtils.write(scannerLogFile, "log1\nlog2");
90 CloseableIterator<String> logs = underTest.readScannerLogs();
91 assertThat(logs).toIterable().containsExactly("log1", "log2");
95 public void readScannerLogs_no_logs() {
96 CloseableIterator<String> logs = underTest.readScannerLogs();
97 assertThat(logs.hasNext()).isFalse();
101 public void readComponentMeasures_returns_empty_list_if_there_is_no_measure() {
102 assertThat(underTest.readComponentMeasures(COMPONENT_REF)).isExhausted();
106 public void verify_readComponentMeasures_returns_measures() {
107 writer.appendComponentMeasure(COMPONENT_REF, MEASURE);
109 try (CloseableIterator<ScannerReport.Measure> measures = underTest.readComponentMeasures(COMPONENT_REF)) {
110 assertThat(measures.next()).isEqualTo(MEASURE);
111 assertThat(measures.hasNext()).isFalse();
116 public void readComponentMeasures_is_not_cached() {
117 writer.appendComponentMeasure(COMPONENT_REF, MEASURE);
119 assertThat(underTest.readComponentMeasures(COMPONENT_REF)).isNotSameAs(underTest.readComponentMeasures(COMPONENT_REF));
123 public void readChangesets_returns_null_if_no_changeset() {
124 assertThat(underTest.readChangesets(COMPONENT_REF)).isNull();
128 public void verify_readChangesets_returns_changesets() {
129 writer.writeComponentChangesets(CHANGESETS);
131 ScannerReport.Changesets res = underTest.readChangesets(COMPONENT_REF);
132 assertThat(res).isEqualTo(CHANGESETS);
136 public void readChangesets_is_not_cached() {
137 writer.writeComponentChangesets(CHANGESETS);
139 assertThat(underTest.readChangesets(COMPONENT_REF)).isNotSameAs(underTest.readChangesets(COMPONENT_REF));
143 public void readComponent_throws_ISE_if_file_does_not_exist() {
144 assertThatThrownBy(() -> underTest.readComponent(COMPONENT_REF))
145 .isInstanceOf(IllegalStateException.class);
149 public void verify_readComponent_returns_Component() {
150 writer.writeComponent(COMPONENT);
152 assertThat(underTest.readComponent(COMPONENT_REF)).isEqualTo(COMPONENT);
156 public void readComponent_is_not_cached() {
157 writer.writeComponent(COMPONENT);
159 assertThat(underTest.readComponent(COMPONENT_REF)).isNotSameAs(underTest.readComponent(COMPONENT_REF));
163 public void readComponentIssues_returns_empty_list_if_file_does_not_exist() {
164 assertThat(underTest.readComponentIssues(COMPONENT_REF)).isExhausted();
168 public void verify_readComponentIssues_returns_Issues() {
169 writer.writeComponentIssues(COMPONENT_REF, of(ISSUE));
171 try (CloseableIterator<ScannerReport.Issue> res = underTest.readComponentIssues(COMPONENT_REF)) {
172 assertThat(res.next()).isEqualTo(ISSUE);
173 assertThat(res.hasNext()).isFalse();
178 public void readComponentIssues_it_not_cached() {
179 writer.writeComponentIssues(COMPONENT_REF, of(ISSUE));
181 assertThat(underTest.readComponentIssues(COMPONENT_REF)).isNotSameAs(underTest.readComponentIssues(COMPONENT_REF));
185 public void readComponentDuplications_returns_empty_list_if_file_does_not_exist() {
186 assertThat(underTest.readComponentDuplications(COMPONENT_REF)).isExhausted();
190 public void verify_readComponentDuplications_returns_Issues() {
191 writer.writeComponentDuplications(COMPONENT_REF, of(DUPLICATION));
193 try (CloseableIterator<ScannerReport.Duplication> res = underTest.readComponentDuplications(COMPONENT_REF)) {
194 assertThat(res.next()).isEqualTo(DUPLICATION);
195 assertThat(res.hasNext()).isFalse();
200 public void readComponentDuplications_it_not_cached() {
201 writer.writeComponentDuplications(COMPONENT_REF, of(DUPLICATION));
203 assertThat(underTest.readComponentDuplications(COMPONENT_REF)).isNotSameAs(underTest.readComponentDuplications(COMPONENT_REF));
207 public void readComponentDuplicationBlocks_returns_empty_list_if_file_does_not_exist() {
208 assertThat(underTest.readCpdTextBlocks(COMPONENT_REF)).isExhausted();
212 public void verify_readComponentDuplicationBlocks_returns_Issues() {
213 writer.writeCpdTextBlocks(COMPONENT_REF, of(DUPLICATION_BLOCK));
215 try (CloseableIterator<ScannerReport.CpdTextBlock> res = underTest.readCpdTextBlocks(COMPONENT_REF)) {
216 assertThat(res.next()).isEqualTo(DUPLICATION_BLOCK);
217 assertThat(res.hasNext()).isFalse();
222 public void readComponentDuplicationBlocks_is_not_cached() {
223 writer.writeCpdTextBlocks(COMPONENT_REF, of(DUPLICATION_BLOCK));
225 assertThat(underTest.readCpdTextBlocks(COMPONENT_REF)).isNotSameAs(underTest.readCpdTextBlocks(COMPONENT_REF));
229 public void readComponentSymbols_returns_empty_list_if_file_does_not_exist() {
230 assertThat(underTest.readComponentSymbols(COMPONENT_REF)).isExhausted();
234 public void verify_readComponentSymbols_returns_Issues() {
235 writer.writeComponentSymbols(COMPONENT_REF, of(SYMBOL));
237 try (CloseableIterator<ScannerReport.Symbol> res = underTest.readComponentSymbols(COMPONENT_REF)) {
238 assertThat(res.next()).isEqualTo(SYMBOL);
239 assertThat(res.hasNext()).isFalse();
244 public void readComponentSymbols_it_not_cached() {
245 writer.writeComponentSymbols(COMPONENT_REF, of(SYMBOL));
247 assertThat(underTest.readComponentSymbols(COMPONENT_REF)).isNotSameAs(underTest.readComponentSymbols(COMPONENT_REF));
251 public void readComponentSyntaxHighlighting_returns_empty_CloseableIterator_when_file_does_not_exist() {
252 assertThat(underTest.readComponentSyntaxHighlighting(COMPONENT_REF)).isExhausted();
256 public void verify_readComponentSyntaxHighlighting() {
257 writer.writeComponentSyntaxHighlighting(COMPONENT_REF, of(SYNTAX_HIGHLIGHTING_1, SYNTAX_HIGHLIGHTING_2));
259 CloseableIterator<ScannerReport.SyntaxHighlightingRule> res = underTest.readComponentSyntaxHighlighting(COMPONENT_REF);
260 assertThat(res).toIterable().containsExactly(SYNTAX_HIGHLIGHTING_1, SYNTAX_HIGHLIGHTING_2);
265 public void readComponentCoverage_returns_empty_CloseableIterator_when_file_does_not_exist() {
266 assertThat(underTest.readComponentCoverage(COMPONENT_REF)).isExhausted();
270 public void verify_readComponentCoverage() {
271 writer.writeComponentCoverage(COMPONENT_REF, of(COVERAGE_1, COVERAGE_2));
273 CloseableIterator<ScannerReport.LineCoverage> res = underTest.readComponentCoverage(COMPONENT_REF);
274 assertThat(res).toIterable().containsExactly(COVERAGE_1, COVERAGE_2);
279 public void readFileSource_returns_absent_optional_when_file_does_not_exist() {
280 assertThat(underTest.readFileSource(COMPONENT_REF)).isEmpty();
284 public void verify_readFileSource() throws IOException {
285 File file = writer.getSourceFile(COMPONENT_REF);
286 FileUtils.writeLines(file, of("1", "2", "3"));
288 CloseableIterator<String> res = underTest.readFileSource(COMPONENT_REF).get();
289 assertThat(res).toIterable().containsExactly("1", "2", "3");
294 public void verify_readAnalysisWarnings() {
295 ScannerReport.AnalysisWarning warning1 = ScannerReport.AnalysisWarning.newBuilder().setText("warning 1").build();
296 ScannerReport.AnalysisWarning warning2 = ScannerReport.AnalysisWarning.newBuilder().setText("warning 2").build();
297 ImmutableList<ScannerReport.AnalysisWarning> warnings = of(warning1, warning2);
298 writer.writeAnalysisWarnings(warnings);
300 CloseableIterator<ScannerReport.AnalysisWarning> res = underTest.readAnalysisWarnings();
301 assertThat(res).toIterable().containsExactlyElementsOf(warnings);
306 public void readCves_shouldReturnCves() {
307 Cve cve1 = builCve("1").build();
308 writer.appendCve(cve1);
309 Cve cve2 = builCve("2").build();
310 writer.appendCve(cve2);
312 CloseableIterator<Cve> cveCloseableIterator = underTest.readCves();
314 assertThat(cveCloseableIterator).toIterable().containsExactlyInAnyOrder(cve1, cve2);
317 private Cve.Builder builCve(String suffix) {
318 return Cve.newBuilder()
319 .setCveId("CVE-" + suffix)
320 .addCwe("CWE-" + suffix)
321 .setDescription("Some CVE description " + suffix)
324 .setEpssPercentile(0.1F)
325 .setLastModifiedDate(1L)
326 .setPublishedDate(2L);