From 27fb5c0e4fad811bae8028a4e13267fdc083f8b3 Mon Sep 17 00:00:00 2001 From: Wojtek Wajerowicz <115081248+wojciech-wajerowicz-sonarsource@users.noreply.github.com> Date: Thu, 15 Jun 2023 17:04:02 +0200 Subject: SONAR-19522 Fail-fast if SARIF file doesn't exist. (#8587) --- .../java/org/sonar/core/sarif/SarifSerializer.java | 3 +- .../org/sonar/core/sarif/SarifSerializerImpl.java | 7 +- .../sonar/core/sarif/SarifSerializerImplTest.java | 183 +++++++++++++++++++++ .../org/sonar/core/sarif/SarifSerializerTest.java | 183 --------------------- .../sarif/SarifIssuesImportSensor.java | 8 +- .../sarif/SarifIssuesImportSensorTest.java | 46 ++++-- 6 files changed, 230 insertions(+), 200 deletions(-) create mode 100644 sonar-core/src/test/java/org/sonar/core/sarif/SarifSerializerImplTest.java delete mode 100644 sonar-core/src/test/java/org/sonar/core/sarif/SarifSerializerTest.java diff --git a/sonar-core/src/main/java/org/sonar/core/sarif/SarifSerializer.java b/sonar-core/src/main/java/org/sonar/core/sarif/SarifSerializer.java index fb9777a6bbc..a20b18f280a 100644 --- a/sonar-core/src/main/java/org/sonar/core/sarif/SarifSerializer.java +++ b/sonar-core/src/main/java/org/sonar/core/sarif/SarifSerializer.java @@ -19,11 +19,12 @@ */ package org.sonar.core.sarif; +import java.nio.file.NoSuchFileException; import java.nio.file.Path; public interface SarifSerializer { String serialize(Sarif210 sarif210); - Sarif210 deserialize(Path sarifPath); + Sarif210 deserialize(Path sarifPath) throws NoSuchFileException; } diff --git a/sonar-core/src/main/java/org/sonar/core/sarif/SarifSerializerImpl.java b/sonar-core/src/main/java/org/sonar/core/sarif/SarifSerializerImpl.java index 487f81cf10a..202dd59bad4 100644 --- a/sonar-core/src/main/java/org/sonar/core/sarif/SarifSerializerImpl.java +++ b/sonar-core/src/main/java/org/sonar/core/sarif/SarifSerializerImpl.java @@ -25,6 +25,7 @@ import com.google.gson.JsonIOException; import com.google.gson.JsonSyntaxException; import java.io.IOException; import java.io.Reader; +import java.nio.file.NoSuchFileException; import java.nio.file.Path; import javax.inject.Inject; import org.sonar.api.ce.ComputeEngineSide; @@ -58,17 +59,17 @@ public class SarifSerializerImpl implements SarifSerializer { } @Override - public Sarif210 deserialize(Path reportPath) { + public Sarif210 deserialize(Path reportPath) throws NoSuchFileException { try (Reader reader = newBufferedReader(reportPath, UTF_8)) { Sarif210 sarif = gson.fromJson(reader, Sarif210.class); SarifVersionValidator.validateSarifVersion(sarif.getVersion()); return sarif; + } catch (NoSuchFileException e) { + throw e; } catch (JsonIOException | IOException e) { throw new IllegalStateException(format(SARIF_REPORT_ERROR, reportPath), e); } catch (JsonSyntaxException e) { throw new IllegalStateException(format(SARIF_JSON_SYNTAX_ERROR, reportPath), e); - } catch (IllegalStateException e) { - throw new IllegalStateException(e.getMessage(), e); } } } diff --git a/sonar-core/src/test/java/org/sonar/core/sarif/SarifSerializerImplTest.java b/sonar-core/src/test/java/org/sonar/core/sarif/SarifSerializerImplTest.java new file mode 100644 index 00000000000..3a240cfe73e --- /dev/null +++ b/sonar-core/src/test/java/org/sonar/core/sarif/SarifSerializerImplTest.java @@ -0,0 +1,183 @@ +/* + * SonarQube + * Copyright (C) 2009-2023 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.core.sarif; + +import java.net.URISyntaxException; +import java.net.URL; +import java.nio.file.NoSuchFileException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Set; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.junit.MockitoJUnitRunner; + +import static java.lang.String.format; +import static java.util.Objects.requireNonNull; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.assertj.core.api.Assertions.fail; +import static org.sonar.core.sarif.SarifVersionValidator.UNSUPPORTED_VERSION_MESSAGE_TEMPLATE; + +@RunWith(MockitoJUnitRunner.class) +public class SarifSerializerImplTest { + + private static final String SARIF_JSON = "{\"version\":\"2.1.0\",\"$schema\":\"http://json.schemastore.org/sarif-2.1.0-rtm.4\",\"runs\":[{\"results\":[]}]}"; + + private final SarifSerializerImpl serializer = new SarifSerializerImpl(); + + @Test + public void serialize() { + Run.builder().results(Set.of()).build(); + Sarif210 sarif210 = new Sarif210("http://json.schemastore.org/sarif-2.1.0-rtm.4", Run.builder().results(Set.of()).build()); + + String result = serializer.serialize(sarif210); + + assertThat(result).isEqualTo(SARIF_JSON); + } + + @Test + public void deserialize() throws URISyntaxException, NoSuchFileException { + URL sarifResource = requireNonNull(getClass().getResource("eslint-sarif210.json")); + Path sarif = Paths.get(sarifResource.toURI()); + + Sarif210 deserializationResult = serializer.deserialize(sarif); + + verifySarif(deserializationResult); + } + + @Test + public void deserialize_shouldFail_whenFileCantBeFound() { + String file = "wrongPathToFile"; + Path sarif = Paths.get(file); + + assertThatThrownBy(() -> serializer.deserialize(sarif)) + .isInstanceOf(NoSuchFileException.class); + } + + @Test + public void deserialize_shouldFail_whenJsonSyntaxIsIncorrect() throws URISyntaxException { + URL sarifResource = requireNonNull(getClass().getResource("invalid-json-syntax.json")); + Path sarif = Paths.get(sarifResource.toURI()); + + assertThatThrownBy(() -> serializer.deserialize(sarif)) + .isInstanceOf(IllegalStateException.class) + .hasMessage(format("Failed to read SARIF report at '%s': invalid JSON syntax or file is not UTF-8 encoded", sarif)); + } + + @Test + public void deserialize_whenFileIsNotUtf8encoded_shouldFail() throws URISyntaxException { + URL sarifResource = requireNonNull(getClass().getResource("sarif210-nonUtf8.json")); + Path sarif = Paths.get(sarifResource.toURI()); + + assertThatThrownBy(() -> serializer.deserialize(sarif)) + .isInstanceOf(IllegalStateException.class) + .hasMessage(format("Failed to read SARIF report at '%s': invalid JSON syntax or file is not UTF-8 encoded", sarif)); + } + + @Test + public void deserialize_shouldFail_whenSarifVersionIsNotSupported() throws URISyntaxException { + URL sarifResource = requireNonNull(getClass().getResource("unsupported-sarif-version-abc.json")); + Path sarif = Paths.get(sarifResource.toURI()); + + assertThatThrownBy(() -> serializer.deserialize(sarif)) + .isInstanceOf(IllegalStateException.class) + .hasMessage(format(UNSUPPORTED_VERSION_MESSAGE_TEMPLATE, "A.B.C")); + } + + private void verifySarif(Sarif210 deserializationResult) { + Sarif210 expected = buildExpectedSarif210(); + + assertThat(deserializationResult).isNotNull(); + assertThat(deserializationResult).usingRecursiveComparison().ignoringFields("runs").isEqualTo(expected); + + Run run = getRun(deserializationResult); + Run expectedRun = getRun(expected); + assertThat(run).usingRecursiveComparison().ignoringFields("results", "tool.driver.rules").isEqualTo(expectedRun); + + Result result = getResult(run); + Result expectedResult = getResult(expectedRun); + assertThat(result).usingRecursiveComparison().isEqualTo(expectedResult); + + Rule rule = getRule(run); + Rule expectedRule = getRule(expectedRun); + assertThat(rule).usingRecursiveComparison().ignoringFields("properties").isEqualTo(expectedRule); + } + + private static Sarif210 buildExpectedSarif210() { + return new Sarif210("http://json.schemastore.org/sarif-2.1.0-rtm.4", buildExpectedRun()); + } + + private static Run buildExpectedRun() { + Tool tool = new Tool(buildExpectedDriver()); + return Run.builder() + .tool(tool) + .results(Set.of(buildExpectedResult())).build(); + } + + private static Driver buildExpectedDriver() { + return Driver.builder() + .name("ESLint") + .rules(Set.of(buildExpectedRule())) + .build(); + } + + private static Rule buildExpectedRule() { + return Rule.builder() + .id("no-unused-vars") + .shortDescription("disallow unused variables") + .build(); + } + + private static Result buildExpectedResult() { + return Result.builder() + .ruleId("no-unused-vars") + .locations(Set.of(buildExpectedLocation())) + .message("'x' is assigned a value but never used.") + .level("error") + .build(); + } + + private static Location buildExpectedLocation() { + ArtifactLocation artifactLocation = new ArtifactLocation(null, "file:///C:/dev/sarif/sarif-tutorials/samples/Introduction/simple-example.js"); + PhysicalLocation physicalLocation = PhysicalLocation.of(artifactLocation, buildExpectedRegion()); + return Location.of(physicalLocation); + } + + private static Region buildExpectedRegion() { + return Region.builder() + .startLine(1) + .startColumn(5) + .build(); + } + + private static Run getRun(Sarif210 sarif210) { + return sarif210.getRuns().stream().findFirst().orElseGet(() -> fail("runs property is missing")); + } + + private static Result getResult(Run run) { + return run.getResults().stream().findFirst().orElseGet(() -> fail("results property is missing")); + } + + private static Rule getRule(Run run) { + return run.getTool().getDriver().getRules().stream().findFirst().orElseGet(() -> fail("rules property is missing")); + } + +} diff --git a/sonar-core/src/test/java/org/sonar/core/sarif/SarifSerializerTest.java b/sonar-core/src/test/java/org/sonar/core/sarif/SarifSerializerTest.java deleted file mode 100644 index 24532267883..00000000000 --- a/sonar-core/src/test/java/org/sonar/core/sarif/SarifSerializerTest.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2023 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.core.sarif; - -import java.net.URISyntaxException; -import java.net.URL; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Set; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.junit.MockitoJUnitRunner; - -import static java.lang.String.format; -import static java.util.Objects.requireNonNull; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.assertj.core.api.Assertions.fail; -import static org.sonar.core.sarif.SarifVersionValidator.UNSUPPORTED_VERSION_MESSAGE_TEMPLATE; - -@RunWith(MockitoJUnitRunner.class) -public class SarifSerializerTest { - - private static final String SARIF_JSON = "{\"version\":\"2.1.0\",\"$schema\":\"http://json.schemastore.org/sarif-2.1.0-rtm.4\",\"runs\":[{\"results\":[]}]}"; - - private final SarifSerializerImpl serializer = new SarifSerializerImpl(); - - @Test - public void serialize() { - Run.builder().results(Set.of()).build(); - Sarif210 sarif210 = new Sarif210("http://json.schemastore.org/sarif-2.1.0-rtm.4", Run.builder().results(Set.of()).build()); - - String result = serializer.serialize(sarif210); - - assertThat(result).isEqualTo(SARIF_JSON); - } - - @Test - public void deserialize() throws URISyntaxException { - URL sarifResource = requireNonNull(getClass().getResource("eslint-sarif210.json")); - Path sarif = Paths.get(sarifResource.toURI()); - - Sarif210 deserializationResult = serializer.deserialize(sarif); - - verifySarif(deserializationResult); - } - - @Test - public void deserialize_shouldFail_whenFileCantBeFound() { - String file = "wrongPathToFile"; - Path sarif = Paths.get(file); - - assertThatThrownBy(() -> serializer.deserialize(sarif)) - .isInstanceOf(IllegalStateException.class) - .hasMessage(format("Failed to read SARIF report at '%s'", file)); - } - - @Test - public void deserialize_shouldFail_whenJsonSyntaxIsIncorrect() throws URISyntaxException { - URL sarifResource = requireNonNull(getClass().getResource("invalid-json-syntax.json")); - Path sarif = Paths.get(sarifResource.toURI()); - - assertThatThrownBy(() -> serializer.deserialize(sarif)) - .isInstanceOf(IllegalStateException.class) - .hasMessage(format("Failed to read SARIF report at '%s': invalid JSON syntax or file is not UTF-8 encoded", sarif)); - } - - @Test - public void deserialize_whenFileIsNotUtf8encoded_shouldFail() throws URISyntaxException { - URL sarifResource = requireNonNull(getClass().getResource("sarif210-nonUtf8.json")); - Path sarif = Paths.get(sarifResource.toURI()); - - assertThatThrownBy(() -> serializer.deserialize(sarif)) - .isInstanceOf(IllegalStateException.class) - .hasMessage(format("Failed to read SARIF report at '%s': invalid JSON syntax or file is not UTF-8 encoded", sarif)); - } - - @Test - public void deserialize_shouldFail_whenSarifVersionIsNotSupported() throws URISyntaxException { - URL sarifResource = requireNonNull(getClass().getResource("unsupported-sarif-version-abc.json")); - Path sarif = Paths.get(sarifResource.toURI()); - - assertThatThrownBy(() -> serializer.deserialize(sarif)) - .isInstanceOf(IllegalStateException.class) - .hasMessage(format(UNSUPPORTED_VERSION_MESSAGE_TEMPLATE, "A.B.C")); - } - - private void verifySarif(Sarif210 deserializationResult) { - Sarif210 expected = buildExpectedSarif210(); - - assertThat(deserializationResult).isNotNull(); - assertThat(deserializationResult).usingRecursiveComparison().ignoringFields("runs").isEqualTo(expected); - - Run run = getRun(deserializationResult); - Run expectedRun = getRun(expected); - assertThat(run).usingRecursiveComparison().ignoringFields("results", "tool.driver.rules").isEqualTo(expectedRun); - - Result result = getResult(run); - Result expectedResult = getResult(expectedRun); - assertThat(result).usingRecursiveComparison().isEqualTo(expectedResult); - - Rule rule = getRule(run); - Rule expectedRule = getRule(expectedRun); - assertThat(rule).usingRecursiveComparison().ignoringFields("properties").isEqualTo(expectedRule); - } - - private static Sarif210 buildExpectedSarif210() { - return new Sarif210("http://json.schemastore.org/sarif-2.1.0-rtm.4", buildExpectedRun()); - } - - private static Run buildExpectedRun() { - Tool tool = new Tool(buildExpectedDriver()); - return Run.builder() - .tool(tool) - .results(Set.of(buildExpectedResult())).build(); - } - - private static Driver buildExpectedDriver() { - return Driver.builder() - .name("ESLint") - .rules(Set.of(buildExpectedRule())) - .build(); - } - - private static Rule buildExpectedRule() { - return Rule.builder() - .id("no-unused-vars") - .shortDescription("disallow unused variables") - .build(); - } - - private static Result buildExpectedResult() { - return Result.builder() - .ruleId("no-unused-vars") - .locations(Set.of(buildExpectedLocation())) - .message("'x' is assigned a value but never used.") - .level("error") - .build(); - } - - private static Location buildExpectedLocation() { - ArtifactLocation artifactLocation = new ArtifactLocation(null, "file:///C:/dev/sarif/sarif-tutorials/samples/Introduction/simple-example.js"); - PhysicalLocation physicalLocation = PhysicalLocation.of(artifactLocation, buildExpectedRegion()); - return Location.of(physicalLocation); - } - - private static Region buildExpectedRegion() { - return Region.builder() - .startLine(1) - .startColumn(5) - .build(); - } - - private static Run getRun(Sarif210 sarif210) { - return sarif210.getRuns().stream().findFirst().orElseGet(() -> fail("runs property is missing")); - } - - private static Result getResult(Run run) { - return run.getResults().stream().findFirst().orElseGet(() -> fail("results property is missing")); - } - - private static Rule getRule(Run run) { - return run.getTool().getDriver().getRules().stream().findFirst().orElseGet(() -> fail("rules property is missing")); - } - -} diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/externalissue/sarif/SarifIssuesImportSensor.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/externalissue/sarif/SarifIssuesImportSensor.java index 346cb727f7d..53a2a651dde 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/externalissue/sarif/SarifIssuesImportSensor.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/externalissue/sarif/SarifIssuesImportSensor.java @@ -19,6 +19,7 @@ */ package org.sonar.scanner.externalissue.sarif; +import java.nio.file.NoSuchFileException; import java.nio.file.Path; import java.util.Arrays; import java.util.Collections; @@ -37,9 +38,12 @@ import org.sonar.api.config.PropertyDefinition; import org.sonar.api.resources.Qualifiers; import org.sonar.api.scanner.ScannerSide; import org.sonar.api.scanner.sensor.ProjectSensor; +import org.sonar.api.utils.MessageException; import org.sonar.core.sarif.Sarif210; import org.sonar.core.sarif.SarifSerializer; +import static java.lang.String.format; + @ScannerSide public class SarifIssuesImportSensor implements ProjectSensor { @@ -81,6 +85,8 @@ public class SarifIssuesImportSensor implements ProjectSensor { try { SarifImportResults sarifImportResults = processReport(context, reportPath); filePathToImportResults.put(reportPath, sarifImportResults); + } catch (NoSuchFileException e) { + throw MessageException.of(format("SARIF report file not found: %s", e.getFile())); } catch (Exception exception) { LOG.warn("Failed to process SARIF report from file '{}', error: '{}'", reportPath, exception.getMessage()); } @@ -92,7 +98,7 @@ public class SarifIssuesImportSensor implements ProjectSensor { return Arrays.stream(config.getStringArray(SARIF_REPORT_PATHS_PROPERTY_KEY)).collect(Collectors.toSet()); } - private SarifImportResults processReport(SensorContext context, String reportPath) { + private SarifImportResults processReport(SensorContext context, String reportPath) throws NoSuchFileException { LOG.debug("Importing SARIF issues from '{}'", reportPath); Path reportFilePath = context.fileSystem().resolvePath(reportPath).toPath(); Sarif210 sarifReport = sarifSerializer.deserialize(reportFilePath); diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/sarif/SarifIssuesImportSensorTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/sarif/SarifIssuesImportSensorTest.java index 6a85b604a86..f3181825034 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/sarif/SarifIssuesImportSensorTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/sarif/SarifIssuesImportSensorTest.java @@ -20,6 +20,7 @@ package org.sonar.scanner.externalissue.sarif; import com.google.common.collect.MoreCollectors; +import java.nio.file.NoSuchFileException; import java.nio.file.Path; import java.util.Optional; import org.junit.Before; @@ -33,11 +34,13 @@ import org.sonar.api.batch.sensor.internal.SensorContextTester; import org.sonar.api.config.internal.MapSettings; import org.sonar.api.testfixtures.log.LogAndArguments; import org.sonar.api.testfixtures.log.LogTester; +import org.sonar.api.utils.MessageException; import org.sonar.api.utils.log.LoggerLevel; import org.sonar.core.sarif.Sarif210; import org.sonar.core.sarif.SarifSerializer; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -68,7 +71,7 @@ public class SarifIssuesImportSensorTest { private final SensorContextTester sensorContext = SensorContextTester.create(Path.of(".")); @Test - public void execute_whenSingleFileIsSpecified_shouldImportResults() { + public void execute_whenSingleFileIsSpecified_shouldImportResults() throws NoSuchFileException { sensorSettings.setProperty("sonar.sarifReportPaths", FILE_1); ReportAndResults reportAndResults = mockSuccessfulReportAndResults(FILE_1); @@ -83,7 +86,7 @@ public class SarifIssuesImportSensorTest { } @Test - public void execute_whenMultipleFilesAreSpecified_shouldImportResults() { + public void execute_whenMultipleFilesAreSpecified_shouldImportResults() throws NoSuchFileException { sensorSettings.setProperty("sonar.sarifReportPaths", SARIF_REPORT_PATHS_PARAM); ReportAndResults reportAndResults1 = mockSuccessfulReportAndResults(FILE_1); ReportAndResults reportAndResults2 = mockSuccessfulReportAndResults(FILE_2); @@ -99,7 +102,7 @@ public class SarifIssuesImportSensorTest { } @Test - public void execute_whenFileContainsOnlySuccessfulRuns_shouldLogCorrectMessage() { + public void execute_whenFileContainsOnlySuccessfulRuns_shouldLogCorrectMessage() throws NoSuchFileException { sensorSettings.setProperty("sonar.sarifReportPaths", FILE_1); ReportAndResults reportAndResults = mockSuccessfulReportAndResults(FILE_1); @@ -110,7 +113,7 @@ public class SarifIssuesImportSensorTest { } @Test - public void execute_whenFileContainsOnlyFailedRuns_shouldLogCorrectMessage() { + public void execute_whenFileContainsOnlyFailedRuns_shouldLogCorrectMessage() throws NoSuchFileException { sensorSettings.setProperty("sonar.sarifReportPaths", FILE_1); ReportAndResults reportAndResults = mockFailedReportAndResults(FILE_1); @@ -122,7 +125,7 @@ public class SarifIssuesImportSensorTest { } @Test - public void execute_whenFileContainsFailedAndSuccessfulRuns_shouldLogCorrectMessage() { + public void execute_whenFileContainsFailedAndSuccessfulRuns_shouldLogCorrectMessage() throws NoSuchFileException { sensorSettings.setProperty("sonar.sarifReportPaths", FILE_1); @@ -137,7 +140,7 @@ public class SarifIssuesImportSensorTest { } @Test - public void execute_whenImportFails_shouldSkipReport() { + public void execute_whenImportFails_shouldSkipReport() throws NoSuchFileException { sensorSettings.setProperty("sonar.sarifReportPaths", SARIF_REPORT_PATHS_PARAM); ReportAndResults reportAndResults1 = mockFailedReportAndResults(FILE_1); @@ -154,7 +157,7 @@ public class SarifIssuesImportSensorTest { } @Test - public void execute_whenDeserializationFails_shouldSkipReport() { + public void execute_whenDeserializationFails_shouldSkipReport() throws NoSuchFileException { sensorSettings.setProperty("sonar.sarifReportPaths", SARIF_REPORT_PATHS_PARAM); failDeserializingReport(FILE_1); @@ -168,12 +171,31 @@ public class SarifIssuesImportSensorTest { assertSummaryIsCorrectlyDisplayedForSuccessfulFile(FILE_2, reportAndResults2.getSarifImportResults()); } - private void failDeserializingReport(String path) { + @Test + public void execute_whenDeserializationThrowsMessageException_shouldRethrow() throws NoSuchFileException { + sensorSettings.setProperty("sonar.sarifReportPaths", FILE_1); + + NoSuchFileException e = new NoSuchFileException("non-existent"); + failDeserializingReportWithException(FILE_1, e); + + SarifIssuesImportSensor sensor = new SarifIssuesImportSensor(sarifSerializer, sarifImporter, sensorSettings.asConfig()); + assertThatThrownBy(() -> sensor.execute(sensorContext)) + .isInstanceOf(MessageException.class) + .hasMessage("SARIF report file not found: non-existent"); + + } + + private void failDeserializingReport(String path) throws NoSuchFileException { Path reportFilePath = sensorContext.fileSystem().resolvePath(path).toPath(); when(sarifSerializer.deserialize(reportFilePath)).thenThrow(new NullPointerException("deserialization failed")); } - private ReportAndResults mockSuccessfulReportAndResults(String path) { + private void failDeserializingReportWithException(String path, Exception exception) throws NoSuchFileException { + Path reportFilePath = sensorContext.fileSystem().resolvePath(path).toPath(); + when(sarifSerializer.deserialize(reportFilePath)).thenThrow(exception); + } + + private ReportAndResults mockSuccessfulReportAndResults(String path) throws NoSuchFileException { Sarif210 report = mockSarifReport(path); SarifImportResults sarifImportResults = mock(SarifImportResults.class); @@ -185,14 +207,14 @@ public class SarifIssuesImportSensorTest { return new ReportAndResults(report, sarifImportResults); } - private Sarif210 mockSarifReport(String path) { + private Sarif210 mockSarifReport(String path) throws NoSuchFileException { Sarif210 report = mock(Sarif210.class); Path reportFilePath = sensorContext.fileSystem().resolvePath(path).toPath(); when(sarifSerializer.deserialize(reportFilePath)).thenReturn(report); return report; } - private ReportAndResults mockFailedReportAndResults(String path) { + private ReportAndResults mockFailedReportAndResults(String path) throws NoSuchFileException { Sarif210 report = mockSarifReport(path); SarifImportResults sarifImportResults = mock(SarifImportResults.class); @@ -203,7 +225,7 @@ public class SarifIssuesImportSensorTest { return new ReportAndResults(report, sarifImportResults); } - private ReportAndResults mockMixedReportAndResults(String path) { + private ReportAndResults mockMixedReportAndResults(String path) throws NoSuchFileException { Sarif210 report = mockSarifReport(path); SarifImportResults sarifImportResults = mock(SarifImportResults.class); -- cgit v1.2.3