/* * SonarQube * Copyright (C) 2009-2017 SonarSource SA * mailto:info AT sonarsource DOT com * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package org.sonar.scanner.protocol.output; import com.google.common.collect.Iterators; import java.io.File; import org.apache.commons.io.FileUtils; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.sonar.core.util.CloseableIterator; import org.sonar.core.util.Protobuf; import org.sonar.scanner.protocol.output.ScannerReport.Component.ComponentType; import org.sonar.scanner.protocol.output.ScannerReport.Measure.DoubleValue; import org.sonar.scanner.protocol.output.ScannerReport.SyntaxHighlightingRule.HighlightingType; import static java.util.Arrays.asList; import static org.assertj.core.api.Assertions.assertThat; public class ScannerReportWriterTest { @Rule public TemporaryFolder temp = new TemporaryFolder(); File dir; ScannerReportWriter underTest; @Before public void setUp() throws Exception { dir = temp.newFolder(); underTest = new ScannerReportWriter(dir); } @Test public void create_dir_if_does_not_exist() { FileUtils.deleteQuietly(dir); underTest = new ScannerReportWriter(dir); assertThat(dir).isDirectory().exists(); } @Test public void write_metadata() { ScannerReport.Metadata.Builder metadata = ScannerReport.Metadata.newBuilder() .setAnalysisDate(15000000L) .setProjectKey("PROJECT_A") .setRootComponentRef(1); underTest.writeMetadata(metadata.build()); ScannerReport.Metadata read = Protobuf.read(underTest.getFileStructure().metadataFile(), ScannerReport.Metadata.parser()); assertThat(read.getAnalysisDate()).isEqualTo(15000000L); assertThat(read.getProjectKey()).isEqualTo("PROJECT_A"); assertThat(read.getRootComponentRef()).isEqualTo(1); } @Test public void write_component() { // no data yet assertThat(underTest.hasComponentData(FileStructure.Domain.COMPONENT, 1)).isFalse(); // write data ScannerReport.Component.Builder component = ScannerReport.Component.newBuilder() .setRef(1) .setLanguage("java") .setPath("src/Foo.java") .setType(ComponentType.FILE) .setIsTest(false) .addChildRef(5) .addChildRef(42); underTest.writeComponent(component.build()); assertThat(underTest.hasComponentData(FileStructure.Domain.COMPONENT, 1)).isTrue(); File file = underTest.getFileStructure().fileFor(FileStructure.Domain.COMPONENT, 1); assertThat(file).exists().isFile(); ScannerReport.Component read = Protobuf.read(file, ScannerReport.Component.parser()); assertThat(read.getRef()).isEqualTo(1); assertThat(read.getChildRefList()).containsOnly(5, 42); assertThat(read.getName()).isEmpty(); assertThat(read.getIsTest()).isFalse(); } @Test public void write_issues() { // no data yet assertThat(underTest.hasComponentData(FileStructure.Domain.ISSUES, 1)).isFalse(); // write data ScannerReport.Issue issue = ScannerReport.Issue.newBuilder() .setMsg("the message") .build(); underTest.writeComponentIssues(1, asList(issue)); assertThat(underTest.hasComponentData(FileStructure.Domain.ISSUES, 1)).isTrue(); File file = underTest.getFileStructure().fileFor(FileStructure.Domain.ISSUES, 1); assertThat(file).exists().isFile(); try (CloseableIterator<ScannerReport.Issue> read = Protobuf.readStream(file, ScannerReport.Issue.parser())) { assertThat(Iterators.size(read)).isEqualTo(1); } } @Test public void write_measures() { assertThat(underTest.hasComponentData(FileStructure.Domain.MEASURES, 1)).isFalse(); ScannerReport.Measure measure = ScannerReport.Measure.newBuilder() .setDoubleValue(DoubleValue.newBuilder().setValue(2.5d).setData("text-value")) .build(); underTest.writeComponentMeasures(1, asList(measure)); assertThat(underTest.hasComponentData(FileStructure.Domain.MEASURES, 1)).isTrue(); File file = underTest.getFileStructure().fileFor(FileStructure.Domain.MEASURES, 1); assertThat(file).exists().isFile(); try (CloseableIterator<ScannerReport.Measure> read = Protobuf.readStream(file, ScannerReport.Measure.parser())) { assertThat(Iterators.size(read)).isEqualTo(1); } } @Test public void write_scm() { assertThat(underTest.hasComponentData(FileStructure.Domain.CHANGESETS, 1)).isFalse(); ScannerReport.Changesets scm = ScannerReport.Changesets.newBuilder() .setComponentRef(1) .addChangesetIndexByLine(0) .addChangeset(ScannerReport.Changesets.Changeset.newBuilder() .setRevision("123-456-789") .setAuthor("author") .setDate(123_456_789L)) .build(); underTest.writeComponentChangesets(scm); assertThat(underTest.hasComponentData(FileStructure.Domain.CHANGESETS, 1)).isTrue(); File file = underTest.getFileStructure().fileFor(FileStructure.Domain.CHANGESETS, 1); assertThat(file).exists().isFile(); ScannerReport.Changesets read = Protobuf.read(file, ScannerReport.Changesets.parser()); assertThat(read.getComponentRef()).isEqualTo(1); assertThat(read.getChangesetCount()).isEqualTo(1); assertThat(read.getChangesetList()).hasSize(1); assertThat(read.getChangeset(0).getDate()).isEqualTo(123_456_789L); } @Test public void write_duplications() { assertThat(underTest.hasComponentData(FileStructure.Domain.DUPLICATIONS, 1)).isFalse(); ScannerReport.Duplication duplication = ScannerReport.Duplication.newBuilder() .setOriginPosition(ScannerReport.TextRange.newBuilder() .setStartLine(1) .setEndLine(5) .build()) .addDuplicate(ScannerReport.Duplicate.newBuilder() .setOtherFileRef(2) .setRange(ScannerReport.TextRange.newBuilder() .setStartLine(6) .setEndLine(10) .build()) .build()) .build(); underTest.writeComponentDuplications(1, asList(duplication)); assertThat(underTest.hasComponentData(FileStructure.Domain.DUPLICATIONS, 1)).isTrue(); File file = underTest.getFileStructure().fileFor(FileStructure.Domain.DUPLICATIONS, 1); assertThat(file).exists().isFile(); try (CloseableIterator<ScannerReport.Duplication> duplications = Protobuf.readStream(file, ScannerReport.Duplication.parser())) { ScannerReport.Duplication dup = duplications.next(); assertThat(dup.getOriginPosition()).isNotNull(); assertThat(dup.getDuplicateList()).hasSize(1); } } @Test public void write_duplication_blocks() { assertThat(underTest.hasComponentData(FileStructure.Domain.CPD_TEXT_BLOCKS, 1)).isFalse(); ScannerReport.CpdTextBlock duplicationBlock = ScannerReport.CpdTextBlock.newBuilder() .setHash("abcdefghijklmnop") .setStartLine(1) .setEndLine(2) .setStartTokenIndex(10) .setEndTokenIndex(15) .build(); underTest.writeCpdTextBlocks(1, asList(duplicationBlock)); assertThat(underTest.hasComponentData(FileStructure.Domain.CPD_TEXT_BLOCKS, 1)).isTrue(); File file = underTest.getFileStructure().fileFor(FileStructure.Domain.CPD_TEXT_BLOCKS, 1); assertThat(file).exists().isFile(); try (CloseableIterator<ScannerReport.CpdTextBlock> duplicationBlocks = Protobuf.readStream(file, ScannerReport.CpdTextBlock.parser())) { ScannerReport.CpdTextBlock duplicationBlockResult = duplicationBlocks.next(); assertThat(duplicationBlockResult.getHash()).isEqualTo("abcdefghijklmnop"); assertThat(duplicationBlockResult.getStartLine()).isEqualTo(1); assertThat(duplicationBlockResult.getEndLine()).isEqualTo(2); assertThat(duplicationBlockResult.getStartTokenIndex()).isEqualTo(10); assertThat(duplicationBlockResult.getEndTokenIndex()).isEqualTo(15); } } @Test public void write_symbols() { // no data yet assertThat(underTest.hasComponentData(FileStructure.Domain.SYMBOLS, 1)).isFalse(); // write data ScannerReport.Symbol symbol = ScannerReport.Symbol.newBuilder() .setDeclaration(ScannerReport.TextRange.newBuilder() .setStartLine(1) .setStartOffset(3) .setEndLine(1) .setEndOffset(5) .build()) .addReference(ScannerReport.TextRange.newBuilder() .setStartLine(10) .setStartOffset(15) .setEndLine(11) .setEndOffset(2) .build()) .build(); underTest.writeComponentSymbols(1, asList(symbol)); assertThat(underTest.hasComponentData(FileStructure.Domain.SYMBOLS, 1)).isTrue(); File file = underTest.getFileStructure().fileFor(FileStructure.Domain.SYMBOLS, 1); assertThat(file).exists().isFile(); try (CloseableIterator<ScannerReport.Symbol> read = Protobuf.readStream(file, ScannerReport.Symbol.parser())) { assertThat(read).hasSize(1); } } @Test public void write_syntax_highlighting() { // no data yet assertThat(underTest.hasComponentData(FileStructure.Domain.SYNTAX_HIGHLIGHTINGS, 1)).isFalse(); underTest.writeComponentSyntaxHighlighting(1, asList( ScannerReport.SyntaxHighlightingRule.newBuilder() .setRange(ScannerReport.TextRange.newBuilder() .setStartLine(1) .setEndLine(1) .build()) .setType(HighlightingType.ANNOTATION) .build())); assertThat(underTest.hasComponentData(FileStructure.Domain.SYNTAX_HIGHLIGHTINGS, 1)).isTrue(); } @Test public void write_coverage() { // no data yet assertThat(underTest.hasComponentData(FileStructure.Domain.COVERAGES, 1)).isFalse(); underTest.writeComponentCoverage(1, asList( ScannerReport.LineCoverage.newBuilder() .setLine(1) .setConditions(1) .setHits(true) .setCoveredConditions(1) .build())); assertThat(underTest.hasComponentData(FileStructure.Domain.COVERAGES, 1)).isTrue(); } @Test public void write_tests() { assertThat(underTest.hasComponentData(FileStructure.Domain.TESTS, 1)).isFalse(); underTest.writeTests(1, asList( ScannerReport.Test.getDefaultInstance())); assertThat(underTest.hasComponentData(FileStructure.Domain.TESTS, 1)).isTrue(); } @Test public void write_coverage_details() { assertThat(underTest.hasComponentData(FileStructure.Domain.COVERAGE_DETAILS, 1)).isFalse(); underTest.writeCoverageDetails(1, asList( ScannerReport.CoverageDetail.getDefaultInstance())); assertThat(underTest.hasComponentData(FileStructure.Domain.COVERAGE_DETAILS, 1)).isTrue(); } }