From 745818998a1d73e9f50caacea56d89f6e0f01bb6 Mon Sep 17 00:00:00 2001 From: "antoine.vinot" Date: Tue, 3 Dec 2024 10:22:23 +0100 Subject: SONAR-23432 Fix failing tests on Windows in scanner-engine --- .../mediumtest/bootstrap/BootstrapMediumIT.java | 87 +++++++++++++++------- .../scanner/mediumtest/fs/FileSystemMediumIT.java | 4 +- .../sonar/scanner/scan/filesystem/FileIndexer.java | 2 +- .../bootstrap/ScannerLogbackEncoderTest.java | 8 +- .../ExternalIssueReportParserTest.java | 6 +- ...ModuleCoverageAndDuplicationExclusionsTest.java | 5 +- .../scan/filesystem/LanguageDetectionTest.java | 7 +- .../scanner/sensor/DefaultSensorStorageTest.java | 30 +++++--- 8 files changed, 97 insertions(+), 52 deletions(-) (limited to 'sonar-scanner-engine') diff --git a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/bootstrap/BootstrapMediumIT.java b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/bootstrap/BootstrapMediumIT.java index 06033ba21dd..ac110567e85 100644 --- a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/bootstrap/BootstrapMediumIT.java +++ b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/bootstrap/BootstrapMediumIT.java @@ -19,15 +19,17 @@ */ package org.sonar.scanner.mediumtest.bootstrap; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import com.github.tomakehurst.wiremock.junit5.WireMockExtension; import java.io.ByteArrayInputStream; import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.junit.jupiter.api.io.TempDir; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ValueSource; import org.slf4j.event.Level; import org.sonar.api.testfixtures.log.LogTesterJUnit5; import org.sonar.scanner.bootstrap.ScannerMain; @@ -41,6 +43,11 @@ import static com.github.tomakehurst.wiremock.client.WireMock.okJson; import static com.github.tomakehurst.wiremock.client.WireMock.post; import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; +import static org.sonar.scanner.mediumtest.bootstrap.BootstrapMediumIT.ScannerProperties.SONAR_HOST_URL; +import static org.sonar.scanner.mediumtest.bootstrap.BootstrapMediumIT.ScannerProperties.SONAR_PROJECT_BASE_DIR; +import static org.sonar.scanner.mediumtest.bootstrap.BootstrapMediumIT.ScannerProperties.SONAR_PROJECT_KEY; +import static org.sonar.scanner.mediumtest.bootstrap.BootstrapMediumIT.ScannerProperties.SONAR_VERBOSE; import static testutils.TestUtils.protobufBody; class BootstrapMediumIT { @@ -143,11 +150,10 @@ class BootstrapMediumIT { */ @Test void should_complete_successfully(@TempDir Path baseDir) { - var exitCode = ScannerMain.run(new ByteArrayInputStream(("{\"scannerProperties\": [" - + "{\"key\": \"sonar.host.url\", \"value\": \"" + sonarqube.baseUrl() + "\"}," - + "{\"key\": \"sonar.projectKey\", \"value\": \"" + PROJECT_KEY + "\"}," - + "{\"key\": \"sonar.projectBaseDir\", \"value\": \"" + baseDir + "\"}" - + "]}").getBytes())); + var exitCode = runScannerEngine(new ScannerProperties() + .addProperty(SONAR_HOST_URL, sonarqube.baseUrl()) + .addProperty(SONAR_PROJECT_KEY, PROJECT_KEY) + .addProperty(SONAR_PROJECT_BASE_DIR, baseDir.toString())); assertThat(exitCode).isZero(); assertThat(logTester.logs()).contains("SonarScanner Engine completed successfully"); @@ -155,10 +161,9 @@ class BootstrapMediumIT { @Test void should_unwrap_message_exception_without_stacktrace(@TempDir Path baseDir) { - var exitCode = ScannerMain.run(new ByteArrayInputStream(("{\"scannerProperties\": [" - + "{\"key\": \"sonar.host.url\", \"value\": \"" + sonarqube.baseUrl() + "\"}," - + "{\"key\": \"sonar.projectBaseDir\", \"value\": \"" + baseDir + "\"}" - + "]}").getBytes())); + int exitCode = runScannerEngine(new ScannerProperties() + .addProperty(SONAR_HOST_URL, sonarqube.baseUrl()) + .addProperty(SONAR_PROJECT_BASE_DIR, baseDir.toString())); assertThat(exitCode).isEqualTo(1); assertThat(logTester.getLogs(Level.ERROR)).hasSize(1); @@ -168,11 +173,10 @@ class BootstrapMediumIT { @Test void should_show_message_exception_stacktrace_in_debug(@TempDir Path baseDir) { - var exitCode = ScannerMain.run(new ByteArrayInputStream(("{\"scannerProperties\": [" - + "{\"key\": \"sonar.host.url\", \"value\": \"" + sonarqube.baseUrl() + "\"}," - + "{\"key\": \"sonar.projectBaseDir\", \"value\": \"" + baseDir + "\"}," - + "{\"key\": \"sonar.verbose\", \"value\": \"true\"}" - + "]}").getBytes())); + int exitCode = runScannerEngine(new ScannerProperties() + .addProperty(SONAR_HOST_URL, sonarqube.baseUrl()) + .addProperty(SONAR_PROJECT_BASE_DIR, baseDir.toString()) + .addProperty(SONAR_VERBOSE, "true")); assertThat(exitCode).isEqualTo(1); assertThat(logTester.getLogs(Level.ERROR)).hasSize(1); @@ -182,22 +186,49 @@ class BootstrapMediumIT { @Test void should_enable_verbose(@TempDir Path baseDir) { - - ScannerMain.run(new ByteArrayInputStream(("{\"scannerProperties\": [" - + "{\"key\": \"sonar.host.url\", \"value\": \"" + sonarqube.baseUrl() + "\"}," - + "{\"key\": \"sonar.projectKey\", \"value\": \"" + PROJECT_KEY + "\"}," - + "{\"key\": \"sonar.projectBaseDir\", \"value\": \"" + baseDir + "\"}" - + "]}").getBytes())); + var properties = new ScannerProperties() + .addProperty(SONAR_HOST_URL, sonarqube.baseUrl()) + .addProperty(SONAR_PROJECT_KEY, PROJECT_KEY) + .addProperty(SONAR_PROJECT_BASE_DIR, baseDir.toString()); + runScannerEngine(properties); assertThat(logTester.logs(Level.DEBUG)).isEmpty(); - ScannerMain.run(new ByteArrayInputStream(("{\"scannerProperties\": [" - + "{\"key\": \"sonar.host.url\", \"value\": \"" + sonarqube.baseUrl() + "\"}," - + "{\"key\": \"sonar.projectKey\", \"value\": \"" + PROJECT_KEY + "\"}," - + "{\"key\": \"sonar.projectBaseDir\", \"value\": \"" + baseDir + "\"}," - + "{\"key\": \"sonar.verbose\", \"value\": \"true\"}" - + "]}").getBytes())); + properties.addProperty(SONAR_VERBOSE, "true"); + runScannerEngine(properties); assertThat(logTester.logs(Level.DEBUG)).isNotEmpty(); } + + private int runScannerEngine(ScannerProperties scannerProperties) { + return ScannerMain.run(new ByteArrayInputStream(scannerProperties.toJson().getBytes())); + } + + static class ScannerProperties { + static final String SONAR_HOST_URL = "sonar.host.url"; + static final String SONAR_PROJECT_KEY = "sonar.projectKey"; + static final String SONAR_PROJECT_BASE_DIR = "sonar.projectBaseDir"; + static final String SONAR_VERBOSE = "sonar.verbose"; + + public List scannerProperties = new ArrayList<>(); + + ScannerProperties addProperty(String key, String value) { + scannerProperties.add(new ScannerProperty(key, value)); + return this; + } + + String toJson() { + try { + ObjectMapper objectMapper = new ObjectMapper(); + return objectMapper.writeValueAsString(this); + } catch (JsonProcessingException e) { + fail("Failed to serialize scanner properties", e); + return ""; + } + } + } + + record ScannerProperty(String key, String value) { + + } } diff --git a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/fs/FileSystemMediumIT.java b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/fs/FileSystemMediumIT.java index efae70e8f09..89525248097 100644 --- a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/fs/FileSystemMediumIT.java +++ b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/fs/FileSystemMediumIT.java @@ -229,7 +229,7 @@ public class FileSystemMediumIT { .execute(); assertThat(logTester.logs()).contains("1 file indexed"); - assertThat(logTester.logs()).contains("'src" + File.separator + "sample.unknown' indexed with no language"); + assertThat(logTester.logs()).contains("'src/sample.unknown' indexed with no language"); assertThat(logTester.logs()).contains("'src/sample.unknown' generated metadata with charset 'UTF-8'"); DefaultInputFile inputFile = (DefaultInputFile) result.inputFile("src/sample.unknown"); assertThat(result.getReportComponent(inputFile)).isNotNull(); @@ -261,7 +261,7 @@ public class FileSystemMediumIT { .build()) .execute(); - assertThat(logTester.logs()).containsOnlyOnce("'src" + File.separator + "myfile.binary' indexed with no language"); + assertThat(logTester.logs()).containsOnlyOnce("'src/myfile.binary' indexed with no language"); assertThat(logTester.logs()).doesNotContain("Evaluate issue exclusions for 'src/myfile.binary'"); assertThat(logTester.logs()).containsOnlyOnce("Evaluate issue exclusions for 'src/sample.xoo'"); } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/FileIndexer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/FileIndexer.java index 9b84a719520..6afd6163619 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/FileIndexer.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/FileIndexer.java @@ -118,7 +118,7 @@ public class FileIndexer { issueExclusionsLoader.addMulticriteriaPatterns(inputFile); String langStr = inputFile.language() != null ? format("with language '%s'", inputFile.language()) : "with no language"; if (LOG.isDebugEnabled()) { - LOG.debug("'{}' indexed {}{}", projectRelativePath, type == Type.TEST ? "as test " : "", langStr); + LOG.debug("'{}' indexed {}{}", inputFile, type == Type.TEST ? "as test " : "", langStr); } evaluateCoverageExclusions(moduleCoverageAndDuplicationExclusions, inputFile); evaluateDuplicationExclusions(moduleCoverageAndDuplicationExclusions, inputFile); diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ScannerLogbackEncoderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ScannerLogbackEncoderTest.java index d752b67b4c5..ea0028bf90a 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ScannerLogbackEncoderTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ScannerLogbackEncoderTest.java @@ -70,9 +70,11 @@ class ScannerLogbackEncoderTest { var bytes = underTest.encode(logEvent); - assertThat(new String(bytes, StandardCharsets.UTF_8)) - .startsWith( - "{\"level\":\"DEBUG\",\"message\":\"message\",\"stacktrace\":\"java.lang.IllegalArgumentException: foo\\n\\tat org.sonar.scanner.bootstrap.ScannerLogbackEncoderTest.should_encode_with_stacktrace"); + String encodedLog = new String(bytes, StandardCharsets.UTF_8); + assertThat(encodedLog).contains("\"level\":\"DEBUG\"") + .contains("\"message\":\"message\"") + .contains("\"stacktrace\":\"java.lang.IllegalArgumentException: foo") + .contains("at org.sonar.scanner.bootstrap.ScannerLogbackEncoderTest.should_encode_with_stacktrace"); } } diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/ExternalIssueReportParserTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/ExternalIssueReportParserTest.java index ffefbd51751..a207bde260e 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/ExternalIssueReportParserTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/ExternalIssueReportParserTest.java @@ -23,6 +23,7 @@ import java.nio.file.Path; import java.nio.file.Paths; import org.junit.Test; +import static java.io.File.separator; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.ArgumentMatchers.any; @@ -71,10 +72,11 @@ public class ExternalIssueReportParserTest { public void parse_whenInvalidDeprecatedFormat_shouldFail() { reportPath = Paths.get(DEPRECATED_REPORTS_LOCATION + "report_invalid_json.json"); + String expectedReportPath = String.join(separator, "src", "test", "resources", "org", "sonar", "scanner", "externalissue", "report_invalid_json.json"); assertThatThrownBy(() -> externalIssueReportParser.parse(reportPath)) .isInstanceOf(IllegalStateException.class) - .hasMessage("Failed to read external issues report 'src/test/resources/org/sonar/scanner/externalissue/report_invalid_json.json': " + - "invalid JSON syntax"); + .hasMessage(String.format("Failed to read external issues report '%s': " + + "invalid JSON syntax", expectedReportPath)); } @Test diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/ModuleCoverageAndDuplicationExclusionsTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/ModuleCoverageAndDuplicationExclusionsTest.java index 20b60cf0d26..48b77adf39b 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/ModuleCoverageAndDuplicationExclusionsTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/ModuleCoverageAndDuplicationExclusionsTest.java @@ -44,7 +44,10 @@ public class ModuleCoverageAndDuplicationExclusionsTest { @Before public void prepare() throws Exception { - baseDir = temp.newFolder(); + // On Windows, 'temp.newFolder()' would return a 8.3 filename (or short filename). + // We need to convert it to long filename version, otherwise the path will be different and the resolution of the relative path will not work as intended. + // See https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/18e63b13-ba43-4f5f-a5b7-11e871b71f14 + baseDir = temp.newFolder().toPath().toRealPath().toFile(); } @Test diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/LanguageDetectionTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/LanguageDetectionTest.java index e81120bee32..1bf8599da5d 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/LanguageDetectionTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/LanguageDetectionTest.java @@ -39,6 +39,7 @@ import org.sonar.api.utils.MessageException; import org.sonar.scanner.mediumtest.FakeLanguagesLoader; import org.sonar.scanner.repository.language.DefaultLanguagesRepository; +import static java.io.File.separator; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.ArgumentMatchers.any; @@ -193,8 +194,8 @@ public class LanguageDetectionTest { assertThat(detectLanguageKey(detection, "Foo.java")).isEqualTo("java"); assertThat(detectLanguageKey(detection, "Foo.java")).isEqualTo("java"); - verify(languageCacheSpy, times(1)).put(endsWith("/Foo.java"), any(org.sonar.scanner.repository.language.Language.class)); - verify(languageCacheSpy, times(2)).get(endsWith("/Foo.java")); + verify(languageCacheSpy, times(1)).put(endsWith(separator + "Foo.java"), any(org.sonar.scanner.repository.language.Language.class)); + verify(languageCacheSpy, times(2)).get(endsWith(separator + "Foo.java")); } private static Map spyInternalLanguageCache(LanguageDetection detection) { @@ -239,7 +240,7 @@ public class LanguageDetectionTest { @Override public String getName() { - return key; + return getKey(); } @Override diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSensorStorageTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSensorStorageTest.java index 28f783a7452..a0d785bd163 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSensorStorageTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSensorStorageTest.java @@ -146,11 +146,11 @@ class DefaultSensorStorageTest { @Test void shouldFailIfUnknownMetric() { InputFile file = new TestInputFileBuilder("foo", "src/Foo.php").build(); - - assertThatThrownBy(() -> underTest.store(new DefaultMeasure() + DefaultMeasure defaultMeasure = new DefaultMeasure() .on(file) .forMetric(CoreMetrics.LINES) - .withValue(10))) + .withValue(10); + assertThatThrownBy(() -> underTest.store(defaultMeasure)) .isInstanceOf(UnsupportedOperationException.class) .hasMessage("Unknown metric: lines"); } @@ -257,9 +257,11 @@ class DefaultSensorStorageTest { .forMetric(CoreMetrics.NCLOC) .withValue(10)); - ScannerReport.Measure m = reportReader.readComponentMeasures(file.scannerId()).next(); - assertThat(m.getIntValue().getValue()).isEqualTo(10); - assertThat(m.getMetricKey()).isEqualTo(CoreMetrics.NCLOC_KEY); + try (CloseableIterator measureCloseableIterator = reportReader.readComponentMeasures(file.scannerId())) { + ScannerReport.Measure m = measureCloseableIterator.next(); + assertThat(m.getIntValue().getValue()).isEqualTo(10); + assertThat(m.getMetricKey()).isEqualTo(CoreMetrics.NCLOC_KEY); + } } @Test @@ -272,9 +274,11 @@ class DefaultSensorStorageTest { .forMetric(CoreMetrics.NCLOC) .withValue(10)); - ScannerReport.Measure m = reportReader.readComponentMeasures(file.scannerId()).next(); - assertThat(m.getIntValue().getValue()).isEqualTo(10); - assertThat(m.getMetricKey()).isEqualTo(CoreMetrics.NCLOC_KEY); + try (CloseableIterator measureCloseableIterator = reportReader.readComponentMeasures(file.scannerId())) { + ScannerReport.Measure m = measureCloseableIterator.next(); + assertThat(m.getIntValue().getValue()).isEqualTo(10); + assertThat(m.getMetricKey()).isEqualTo(CoreMetrics.NCLOC_KEY); + } } @Test @@ -314,9 +318,11 @@ class DefaultSensorStorageTest { .forMetric(CoreMetrics.NCLOC) .withValue(10)); - ScannerReport.Measure m = reportReader.readComponentMeasures(module.scannerId()).next(); - assertThat(m.getIntValue().getValue()).isEqualTo(10); - assertThat(m.getMetricKey()).isEqualTo(CoreMetrics.NCLOC_KEY); + try (CloseableIterator measureCloseableIterator = reportReader.readComponentMeasures(module.scannerId())) { + ScannerReport.Measure m = measureCloseableIterator.next(); + assertThat(m.getIntValue().getValue()).isEqualTo(10); + assertThat(m.getMetricKey()).isEqualTo(CoreMetrics.NCLOC_KEY); + } } @Test -- cgit v1.2.3