aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-scanner-engine/src/it
diff options
context:
space:
mode:
Diffstat (limited to 'sonar-scanner-engine/src/it')
-rw-r--r--sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/analysisdata/AnalysisDataIT.java68
-rw-r--r--sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/bootstrap/BootstrapMediumIT.java23
-rw-r--r--sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/branch/BranchMediumIT.java2
-rw-r--r--sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/coverage/CoverageMediumIT.java2
-rw-r--r--sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/coverage/GenericCoverageMediumIT.java2
-rw-r--r--sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/cpd/CpdMediumIT.java2
-rw-r--r--sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/fs/FileSystemMediumIT.java474
-rw-r--r--sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/fs/NoLanguagesPluginsMediumIT.java2
-rw-r--r--sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/fs/ProjectBuilderMediumIT.java2
-rw-r--r--sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/highlighting/HighlightingMediumIT.java2
-rw-r--r--sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/issues/ChecksMediumIT.java2
-rw-r--r--sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/issues/ExternalIssuesMediumIT.java2
-rw-r--r--sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/issues/IssuesMediumIT.java2
-rw-r--r--sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/issues/IssuesOnDirMediumIT.java2
-rw-r--r--sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/issues/IssuesOnModuleMediumIT.java2
-rw-r--r--sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/issues/MultilineIssuesMediumIT.java2
-rw-r--r--sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/issues/PreviewMediumIT.java2
-rw-r--r--sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/log/ExceptionHandlingMediumIT.java2
-rw-r--r--sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/log/LogListenerIT.java4
-rw-r--r--sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/measures/MeasuresMediumIT.java2
-rw-r--r--sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/optionalplugins/OptionalPluginsMediumIT.java2
-rw-r--r--sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/properties/PropertiesMediumIT.java2
-rw-r--r--sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/properties/UnsupportedPropertiesMediumIT.java (renamed from sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/branch/DeprecatedBranchMediumIT.java)43
-rw-r--r--sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/scm/ScmMediumIT.java4
-rw-r--r--sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/symbol/SymbolMediumIT.java2
-rw-r--r--sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/tasks/TasksMediumIT.java2
-rw-r--r--sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/tests/GenericTestExecutionMediumIT.java2
-rw-r--r--sonar-scanner-engine/src/it/java/org/sonar/scm/svn/SvnBlameCommandIT.java2
-rw-r--r--sonar-scanner-engine/src/it/java/org/sonar/scm/svn/SvnTester.java2
-rw-r--r--sonar-scanner-engine/src/it/java/org/sonar/scm/svn/SvnTesterIT.java2
-rw-r--r--sonar-scanner-engine/src/it/java/testutils/TestUtils.java2
31 files changed, 556 insertions, 110 deletions
diff --git a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/analysisdata/AnalysisDataIT.java b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/analysisdata/AnalysisDataIT.java
new file mode 100644
index 00000000000..94ccedfa946
--- /dev/null
+++ b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/analysisdata/AnalysisDataIT.java
@@ -0,0 +1,68 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2025 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.mediumtest.analysisdata;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.io.File;
+import java.util.List;
+import org.apache.commons.io.FileUtils;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.sonar.api.testfixtures.log.LogTester;
+import org.sonar.core.platform.PluginInfo;
+import org.sonar.scanner.mediumtest.AnalysisResult;
+import org.sonar.scanner.mediumtest.ScannerMediumTester;
+import org.sonar.scanner.protocol.output.ScannerReport;
+import org.sonar.xoo.Xoo;
+import org.sonar.xoo.XooPlugin;
+
+public class AnalysisDataIT {
+
+ @Rule
+ public TemporaryFolder temp = new TemporaryFolder();
+
+ @Rule
+ public LogTester logTester = new LogTester();
+
+ @Rule
+ public ScannerMediumTester tester = new ScannerMediumTester()
+ .registerPlugin(new PluginInfo("xoo").setOrganizationName("SonarSource"), new XooPlugin())
+ .addDefaultQProfile("xoo", "Sonar Way");
+
+ @Test
+ public void whenScanningWithXoo_thenArchitectureGraphIsInReport() throws Exception {
+ // given
+ File projectDir = new File("test-resources/mediumtest/xoo/sample");
+ File tmpDir = temp.newFolder();
+ FileUtils.copyDirectory(projectDir, tmpDir);
+
+ // when
+ AnalysisResult result = tester
+ .newAnalysis(new File(tmpDir, "sonar-project.properties"))
+ .execute();
+
+ // then
+ List<ScannerReport.AnalysisData> analysisData = result.analysisData();
+ assertThat(analysisData)
+ .anyMatch(data -> data.getKey().startsWith("architecture.graph."));
+ }
+}
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 5df0d03b111..6cfd6ea5f94 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
@@ -1,6 +1,6 @@
/*
* SonarQube
- * Copyright (C) 2009-2024 SonarSource SA
+ * Copyright (C) 2009-2025 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
@@ -92,6 +92,11 @@ class BootstrapMediumIT {
}
""")));
+ sonarqube.stubFor(get("/api/features/list")
+ .willReturn(okJson("""
+ []
+ """)));
+
sonarqube.stubFor(get("/api/metrics/search?ps=500&p=1")
.willReturn(okJson("""
{
@@ -112,7 +117,7 @@ class BootstrapMediumIT {
void should_fail_if_invalid_json_input() {
var in = new ByteArrayInputStream("}".getBytes());
- var exitCode = ScannerMain.run(in);
+ var exitCode = ScannerMain.run(in, System.out);
assertThat(exitCode).isEqualTo(1);
assertThat(logTester.getLogs(Level.ERROR)).hasSize(1);
@@ -123,7 +128,7 @@ class BootstrapMediumIT {
@Test
void should_warn_if_null_property_key() {
ScannerMain.run(new ByteArrayInputStream("""
- {"scannerProperties": [{"value": "aValueWithoutKey"}]}""".getBytes()));
+ {"scannerProperties": [{"value": "aValueWithoutKey"}]}""".getBytes()), System.out);
assertThat(logTester.logs(Level.WARN)).contains("Ignoring property with null key. Value='aValueWithoutKey'");
}
@@ -131,7 +136,7 @@ class BootstrapMediumIT {
@Test
void should_warn_if_null_property_value() {
ScannerMain.run(new ByteArrayInputStream("""
- {"scannerProperties": [{"key": "aKey", "value": null}]}""".getBytes()));
+ {"scannerProperties": [{"key": "aKey", "value": null}]}""".getBytes()), System.out);
assertThat(logTester.logs(Level.WARN)).contains("Ignoring property with null value. Key='aKey'");
}
@@ -139,7 +144,7 @@ class BootstrapMediumIT {
@Test
void should_warn_if_not_provided_property_value() {
ScannerMain.run(new ByteArrayInputStream("""
- {"scannerProperties": [{"key": "aKey"}]}""".getBytes()));
+ {"scannerProperties": [{"key": "aKey"}]}""".getBytes()), System.out);
assertThat(logTester.logs(Level.WARN)).contains("Ignoring property with null value. Key='aKey'");
}
@@ -147,7 +152,7 @@ class BootstrapMediumIT {
@Test
void should_warn_if_duplicate_property_keys() {
ScannerMain.run(new ByteArrayInputStream("""
- {"scannerProperties": [{"key": "aKey", "value": "aValue"}, {"key": "aKey", "value": "aValue"}]}""".getBytes()));
+ {"scannerProperties": [{"key": "aKey", "value": "aValue"}, {"key": "aKey", "value": "aValue"}]}""".getBytes()), System.out);
assertThat(logTester.logs(Level.WARN)).contains("Duplicated properties. Key='aKey'");
}
@@ -155,7 +160,7 @@ class BootstrapMediumIT {
@Test
void should_warn_if_null_property() {
ScannerMain.run(new ByteArrayInputStream("""
- {"scannerProperties": [{"key": "aKey", "value": "aValue"},]}""".getBytes()));
+ {"scannerProperties": [{"key": "aKey", "value": "aValue"},]}""".getBytes()), System.out);
assertThat(logTester.logs(Level.WARN)).contains("Ignoring null or empty property");
}
@@ -163,7 +168,7 @@ class BootstrapMediumIT {
@Test
void should_warn_if_empty_property() {
ScannerMain.run(new ByteArrayInputStream("""
- {"scannerProperties": [{}]}""".getBytes()));
+ {"scannerProperties": [{}]}""".getBytes()), System.out);
assertThat(logTester.logs(Level.WARN)).contains("Ignoring null or empty property");
}
@@ -224,7 +229,7 @@ class BootstrapMediumIT {
}
private int runScannerEngine(ScannerProperties scannerProperties) {
- return ScannerMain.run(new ByteArrayInputStream(scannerProperties.toJson().getBytes()));
+ return ScannerMain.run(new ByteArrayInputStream(scannerProperties.toJson().getBytes()), System.out);
}
static class ScannerProperties {
diff --git a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/branch/BranchMediumIT.java b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/branch/BranchMediumIT.java
index 31f2bcbfef0..b1322c5af39 100644
--- a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/branch/BranchMediumIT.java
+++ b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/branch/BranchMediumIT.java
@@ -1,6 +1,6 @@
/*
* SonarQube
- * Copyright (C) 2009-2024 SonarSource SA
+ * Copyright (C) 2009-2025 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
diff --git a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/coverage/CoverageMediumIT.java b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/coverage/CoverageMediumIT.java
index 2d0c1852d2c..c3ebea00518 100644
--- a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/coverage/CoverageMediumIT.java
+++ b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/coverage/CoverageMediumIT.java
@@ -1,6 +1,6 @@
/*
* SonarQube
- * Copyright (C) 2009-2024 SonarSource SA
+ * Copyright (C) 2009-2025 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
diff --git a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/coverage/GenericCoverageMediumIT.java b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/coverage/GenericCoverageMediumIT.java
index 188ee29016d..7f2eaab77f1 100644
--- a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/coverage/GenericCoverageMediumIT.java
+++ b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/coverage/GenericCoverageMediumIT.java
@@ -1,6 +1,6 @@
/*
* SonarQube
- * Copyright (C) 2009-2024 SonarSource SA
+ * Copyright (C) 2009-2025 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
diff --git a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/cpd/CpdMediumIT.java b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/cpd/CpdMediumIT.java
index 27df471d1f0..a4ee3d6647d 100644
--- a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/cpd/CpdMediumIT.java
+++ b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/cpd/CpdMediumIT.java
@@ -1,6 +1,6 @@
/*
* SonarQube
- * Copyright (C) 2009-2024 SonarSource SA
+ * Copyright (C) 2009-2025 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
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 dc7057f85fc..babeadf518e 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
@@ -1,6 +1,6 @@
/*
* SonarQube
- * Copyright (C) 2009-2024 SonarSource SA
+ * Copyright (C) 2009-2025 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
@@ -28,14 +28,21 @@ import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.util.List;
+import java.util.Map;
import java.util.Random;
+import java.util.Set;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.SystemUtils;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.DisabledOnOs;
+import org.junit.jupiter.api.condition.OS;
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.CoreProperties;
import org.sonar.api.SonarEdition;
@@ -49,17 +56,17 @@ import org.sonar.api.utils.System2;
import org.sonar.scanner.mediumtest.AnalysisResult;
import org.sonar.scanner.mediumtest.ScannerMediumTester;
import org.sonar.scanner.mediumtest.ScannerMediumTester.AnalysisBuilder;
+import org.sonar.scanner.protocol.output.ScannerReport;
import org.sonar.xoo.XooPlugin;
import org.sonar.xoo.global.DeprecatedGlobalSensor;
import org.sonar.xoo.global.GlobalProjectSensor;
import org.sonar.xoo.rule.XooRulesDefinition;
-import static java.lang.String.format;
import static java.nio.file.Files.createDirectory;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.Assertions.tuple;
-import static org.junit.jupiter.api.Assumptions.assumeFalse;
+import static org.assertj.core.api.AssertionsForClassTypes.catchThrowableOfType;
import static org.junit.jupiter.api.Assumptions.assumeTrue;
import static org.slf4j.event.Level.DEBUG;
@@ -150,7 +157,7 @@ class FileSystemMediumIT {
.build())
.execute();
- assertThat(logTester.logs()).contains("2 files indexed");
+ assertThat(logTester.logs()).anyMatch(log -> log.startsWith("2 files indexed (done) | time="));
assertThat(logTester.logs()).contains("'src/sample.xoo' generated metadata with charset 'UTF-8'");
assertThat(String.join("\n", logTester.logs())).doesNotContain("'src/sample.java' generated metadata");
}
@@ -173,7 +180,7 @@ class FileSystemMediumIT {
.build())
.execute();
- assertThat(logTester.logs()).contains("2 files indexed");
+ assertThat(logTester.logs()).anyMatch(log -> log.startsWith("2 files indexed (done) | time="));
assertThat(logTester.logs()).contains("'src/sample.xoo' generated metadata with charset 'UTF-8'");
assertThat(logTester.logs()).contains("'src/sample.java' generated metadata with charset 'UTF-8'");
}
@@ -200,7 +207,7 @@ class FileSystemMediumIT {
.execute();
assertThat(logTester.logs()).containsAnyOf("'src/main/sample.java' indexed with no language", "'src\\main\\sample.java' indexed with no language");
- assertThat(logTester.logs()).contains("3 files indexed");
+ assertThat(logTester.logs()).anyMatch(log -> log.startsWith("3 files indexed (done) | time="));
assertThat(logTester.logs()).contains("'src/main/sample.xoo' generated metadata with charset 'UTF-8'");
assertThat(logTester.logs()).doesNotContain("'src/main/sample.java' generated metadata", "'src\\main\\sample.java' generated metadata");
assertThat(logTester.logs()).doesNotContain("'src/test/sample.java' generated metadata", "'src\\test\\sample.java' generated metadata");
@@ -231,7 +238,7 @@ class FileSystemMediumIT {
.build())
.execute();
- assertThat(logTester.logs()).contains("1 file indexed");
+ assertThat(logTester.logs()).anyMatch(log -> log.startsWith("1 file indexed (done) | time="));
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");
@@ -456,32 +463,130 @@ class FileSystemMediumIT {
}
@Test
- void analysisFailsSymbolicLinkWithoutTargetIsInTheFolder() throws IOException {
- assumeFalse(SystemUtils.IS_OS_WINDOWS);
+ @DisabledOnOs(OS.WINDOWS)
+ void analysisDoesNotFailOnBrokenSymlink() throws IOException {
+ prepareBrokenSymlinkTestScenario();
+
+ AnalysisBuilder analysisBuilder = tester.newAnalysis().properties(builder.build());
+
+ assertThat(catchThrowableOfType(Exception.class, analysisBuilder::execute)).isNull();
+ }
+
+ @Test
+ @DisabledOnOs(OS.WINDOWS)
+ void analysisWarnsAndIgnoresBrokenSymlink() throws IOException {
+ Path link = prepareBrokenSymlinkTestScenario();
+
+ AnalysisResult result = tester.newAnalysis().properties(builder.build()).execute();
+
+ String logMessage = String.format("File '%s' is ignored. It is a symbolic link targeting a file that does not exist.", link.toRealPath(LinkOption.NOFOLLOW_LINKS));
+ assertThat(logTester.logs(Level.WARN)).contains(logMessage);
+ InputFile fileA = result.inputFile("src/target_link.xoo");
+ assertThat(fileA).isNull();
+ }
+
+ @Test
+ @DisabledOnOs(OS.WINDOWS)
+ void analysisIgnoresSymbolicLinkWithTargetOutsideBaseDir() throws IOException {
File srcDir = new File(baseDir, "src");
assertThat(srcDir.mkdir()).isTrue();
- File target = writeFile(srcDir, "target.xoo");
+ File otherDir = createDirectory(temp.toPath().resolve("other_dir")).toFile();
+ File targetOutside = writeFile(otherDir, "target_outside.xoo");
+
Path link = Paths.get(srcDir.getPath(), "target_link.xoo");
+ Files.createSymbolicLink(link, targetOutside.toPath());
+
+ AnalysisResult result = tester.newAnalysis().properties(builder.build()).execute();
+
+ String logMessage = String.format("File '%s' is ignored. It is a symbolic link targeting a file not located in project basedir.", link.toRealPath(LinkOption.NOFOLLOW_LINKS));
+ assertThat(logTester.logs(Level.WARN)).contains(logMessage);
+ InputFile fileA = result.inputFile("src/target_link.xoo");
+ assertThat(fileA).isNull();
+ }
+
+ @Test
+ @DisabledOnOs(OS.WINDOWS)
+ void analysisIgnoresSymbolicLinkWithRelativeTargetOutsideBaseDir() throws IOException {
+ File srcDir = new File(baseDir, "src");
+ assertThat(srcDir.mkdir()).isTrue();
+
+ File otherDir = createDirectory(temp.toPath().resolve("other_dir")).toFile();
+ writeFile(otherDir, "target_outside.xoo");
+
+ Path linkPath = srcDir.toPath().resolve("target_link");
+ Path link = Files.createSymbolicLink(linkPath, Paths.get("../../other_dir/target_outside.xoo"));
+
+ tester.newAnalysis().properties(builder.build()).execute();
+
+ String logMessage = String.format("File '%s' is ignored. It is a symbolic link targeting a file not located in project basedir.", link.toRealPath(LinkOption.NOFOLLOW_LINKS));
+ assertThat(logTester.logs(Level.WARN)).contains(logMessage);
+ }
+
+ @Test
+ @DisabledOnOs(OS.WINDOWS)
+ void analysisIgnoresSymbolicLinkWithTargetOutsideModule() throws IOException {
+ File srcDirA = createModuleWithSubdirectory("module_a", "src");
+ File srcDirB = createModuleWithSubdirectory("module_b", "src");
+
+ File target = writeFile(srcDirA, "target.xoo", "Sample xoo\ncontent");
+ Path link = Paths.get(srcDirB.getPath(), "target_link.xoo");
Files.createSymbolicLink(link, target.toPath());
- Files.delete(target.toPath());
- AnalysisBuilder analysis = tester.newAnalysis()
- .properties(builder.build());
+ builder.put("sonar.modules", "module_a,module_b");
- assertThatThrownBy(analysis::execute)
- .isExactlyInstanceOf(IllegalStateException.class)
- .hasMessageEndingWith(format("Unable to read file %s", link));
+ AnalysisResult result = tester.newAnalysis().properties(builder.build()).execute();
+
+ String logMessage = String.format("File '%s' is ignored. It is a symbolic link targeting a file not located in module basedir.", link.toRealPath(LinkOption.NOFOLLOW_LINKS));
+ assertThat(logTester.logs(Level.INFO)).contains(logMessage);
+ InputFile fileA = result.inputFile("module_b/src/target_link.xoo");
+ assertThat(fileA).isNull();
+ }
+
+ @Test
+ @DisabledOnOs(OS.WINDOWS)
+ void analysisIgnoresSymbolicLinkWithRelativeTargetOutsideModule() throws IOException {
+ File srcA = createModuleWithSubdirectory("module_a", "src");
+ File srcB = createModuleWithSubdirectory("module_b", "src");
+
+ Path target = srcB.toPath().resolve("target.xoo");
+ FileUtils.write(target.toFile(), "Sample xoo\ncontent", StandardCharsets.UTF_8);
+ Path link = srcA.toPath().resolve("target_link");
+ Files.createSymbolicLink(link, Paths.get("../../module_b/src/target.xoo"));
+
+ builder.put("sonar.modules", "module_a,module_b");
+
+ AnalysisResult result = tester.newAnalysis().properties(builder.build()).execute();
+
+ String logMessage = String.format("File '%s' is ignored. It is a symbolic link targeting a file not located in module basedir.", link.toRealPath(LinkOption.NOFOLLOW_LINKS));
+ assertThat(logTester.logs(Level.INFO)).contains(logMessage);
+ InputFile fileA = result.inputFile("module_b/src/target.xoo");
+ assertThat(fileA).isNotNull();
+ }
+
+ @Test
+ @DisabledOnOs(OS.WINDOWS)
+ void analysisDoesNotIgnoreSymbolicLinkWithRelativePath() throws IOException {
+ File src = createModuleWithSubdirectory("module_a", "src");
+ Path target = src.toPath().resolve("target.xoo");
+ FileUtils.write(target.toFile(), "Sample xoo\ncontent", StandardCharsets.UTF_8);
+ Path link = src.toPath().resolve("target_link");
+ Files.createSymbolicLink(link, Paths.get("target.xoo"));
+
+ builder.put("sonar.modules", "module_a");
+
+ AnalysisResult result = tester.newAnalysis().properties(builder.build()).execute();
+
+ InputFile targetFile = result.inputFile("module_a/src/target.xoo");
+ assertThat(targetFile).isNotNull();
+ String logMessage = String.format("File '%s' is ignored. It is a symbolic link targeting a file that does not exist.", link.toRealPath(LinkOption.NOFOLLOW_LINKS));
+ assertThat(logTester.logs(Level.WARN)).doesNotContain(logMessage);
}
@Test
void test_inclusions_on_multi_modules() throws IOException {
- File baseDirModuleA = new File(baseDir, "moduleA");
- File baseDirModuleB = new File(baseDir, "moduleB");
- File srcDirA = new File(baseDirModuleA, "tests");
- assertThat(srcDirA.mkdirs()).isTrue();
- File srcDirB = new File(baseDirModuleB, "tests");
- assertThat(srcDirB.mkdirs()).isTrue();
+ File srcDirA = createModuleWithSubdirectory("moduleA", "tests");
+ File srcDirB = createModuleWithSubdirectory("moduleB", "tests");
writeFile(srcDirA, "sampleTestA.xoo", "Sample xoo\ncontent");
writeFile(srcDirB, "sampleTestB.xoo", "Sample xoo\ncontent");
@@ -522,12 +627,8 @@ class FileSystemMediumIT {
@Test
void test_module_level_inclusions_override_parent_on_multi_modules() throws IOException {
- File baseDirModuleA = new File(baseDir, "moduleA");
- File baseDirModuleB = new File(baseDir, "moduleB");
- File srcDirA = new File(baseDirModuleA, "src");
- assertThat(srcDirA.mkdirs()).isTrue();
- File srcDirB = new File(baseDirModuleB, "src");
- assertThat(srcDirB.mkdirs()).isTrue();
+ File srcDirA = createModuleWithSubdirectory("moduleA", "src");
+ File srcDirB = createModuleWithSubdirectory("moduleB", "src");
writeFile(srcDirA, "sampleA.xoo", "Sample xoo\ncontent");
writeFile(srcDirB, "sampleB.xoo", "Sample xoo\ncontent");
@@ -559,12 +660,8 @@ class FileSystemMediumIT {
@Test
void warn_user_for_outdated_scanner_side_inherited_exclusions_for_multi_module_project() throws IOException {
- File baseDirModuleA = new File(baseDir, "moduleA");
- File baseDirModuleB = new File(baseDir, "moduleB");
- File srcDirA = new File(baseDirModuleA, "src");
- assertThat(srcDirA.mkdirs()).isTrue();
- File srcDirB = new File(baseDirModuleB, "src");
- assertThat(srcDirB.mkdirs()).isTrue();
+ File srcDirA = createModuleWithSubdirectory("moduleA", "src");
+ File srcDirB = createModuleWithSubdirectory("moduleB", "src");
writeFile(srcDirA, "sample.xoo", "Sample xoo\ncontent");
writeFile(srcDirB, "sample.xoo", "Sample xoo\ncontent");
@@ -592,12 +689,8 @@ class FileSystemMediumIT {
@Test
void support_global_server_side_exclusions_for_multi_module_project() throws IOException {
- File baseDirModuleA = new File(baseDir, "moduleA");
- File baseDirModuleB = new File(baseDir, "moduleB");
- File srcDirA = new File(baseDirModuleA, "src");
- assertThat(srcDirA.mkdirs()).isTrue();
- File srcDirB = new File(baseDirModuleB, "src");
- assertThat(srcDirB.mkdirs()).isTrue();
+ File srcDirA = createModuleWithSubdirectory("moduleA", "src");
+ File srcDirB = createModuleWithSubdirectory("moduleB", "src");
writeFile(srcDirA, "sample.xoo", "Sample xoo\ncontent");
writeFile(srcDirB, "sample.xoo", "Sample xoo\ncontent");
@@ -622,12 +715,8 @@ class FileSystemMediumIT {
@Test
void support_global_server_side_global_exclusions_for_multi_module_project() throws IOException {
- File baseDirModuleA = new File(baseDir, "moduleA");
- File baseDirModuleB = new File(baseDir, "moduleB");
- File srcDirA = new File(baseDirModuleA, "src");
- assertThat(srcDirA.mkdirs()).isTrue();
- File srcDirB = new File(baseDirModuleB, "src");
- assertThat(srcDirB.mkdirs()).isTrue();
+ File srcDirA = createModuleWithSubdirectory("moduleA", "src");
+ File srcDirB = createModuleWithSubdirectory("moduleB", "src");
writeFile(srcDirA, "sample.xoo", "Sample xoo\ncontent");
writeFile(srcDirB, "sample.xoo", "Sample xoo\ncontent");
@@ -652,12 +741,8 @@ class FileSystemMediumIT {
@Test
void warn_user_for_outdated_server_side_inherited_exclusions_for_multi_module_project() throws IOException {
- File baseDirModuleA = new File(baseDir, "moduleA");
- File baseDirModuleB = new File(baseDir, "moduleB");
- File srcDirA = new File(baseDirModuleA, "src");
- assertThat(srcDirA.mkdirs()).isTrue();
- File srcDirB = new File(baseDirModuleB, "src");
- assertThat(srcDirB.mkdirs()).isTrue();
+ File srcDirA = createModuleWithSubdirectory("moduleA", "src");
+ File srcDirB = createModuleWithSubdirectory("moduleB", "src");
writeFile(srcDirA, "sample.xoo", "Sample xoo\ncontent");
writeFile(srcDirB, "sample.xoo", "Sample xoo\ncontent");
@@ -930,12 +1015,8 @@ class FileSystemMediumIT {
@Test
void log_all_exclusions_properties_per_modules() throws IOException {
- File baseDirModuleA = new File(baseDir, "moduleA");
- File baseDirModuleB = new File(baseDir, "moduleB");
- File srcDirA = new File(baseDirModuleA, "src");
- assertThat(srcDirA.mkdirs()).isTrue();
- File srcDirB = new File(baseDirModuleB, "src");
- assertThat(srcDirB.mkdirs()).isTrue();
+ File srcDirA = createModuleWithSubdirectory("moduleA", "src");
+ File srcDirB = createModuleWithSubdirectory("moduleB", "src");
writeFile(srcDirA, "sample.xoo", "Sample xoo\ncontent");
writeFile(srcDirB, "sample.xoo", "Sample xoo\ncontent");
@@ -964,7 +1045,7 @@ class FileSystemMediumIT {
" Excluded sources for coverage: **/coverage.exclusions",
" Excluded sources for duplication: **/cpd.exclusions",
"Indexing files of module 'moduleA'",
- " Base dir: " + baseDirModuleA.toPath().toRealPath(LinkOption.NOFOLLOW_LINKS),
+ " Base dir: " + srcDirA.toPath().getParent().toRealPath(LinkOption.NOFOLLOW_LINKS),
" Included sources: **/global.inclusions",
" Excluded sources: **/global.exclusions, **/global.test.inclusions",
" Included tests: **/global.test.inclusions",
@@ -972,7 +1053,7 @@ class FileSystemMediumIT {
" Excluded sources for coverage: **/coverage.exclusions",
" Excluded sources for duplication: **/cpd.exclusions",
"Indexing files of module 'moduleB'",
- " Base dir: " + baseDirModuleB.toPath().toRealPath(LinkOption.NOFOLLOW_LINKS),
+ " Base dir: " + srcDirB.toPath().getParent().toRealPath(LinkOption.NOFOLLOW_LINKS),
" Included sources: **/global.inclusions",
" Excluded sources: **/global.exclusions, **/global.test.inclusions",
" Included tests: **/global.test.inclusions",
@@ -1098,7 +1179,7 @@ class FileSystemMediumIT {
.build())
.execute();
- assertThat(logTester.logs()).contains("1 file indexed");
+ assertThat(logTester.logs()).anyMatch(log -> log.startsWith("1 file indexed (done) | time="));
assertThat(result.inputFile("sample.xoo")).isNotNull();
}
@@ -1265,6 +1346,200 @@ class FileSystemMediumIT {
.hasMessageEndingWith("Failed to preprocess files");
}
+ @ParameterizedTest
+ @ValueSource(booleans = {
+ true,
+ false
+ })
+ void shouldScanAndAnalyzeAllHiddenFiles(boolean setHiddenFileScanningExplicitly) throws IOException {
+ prepareHiddenFileProject();
+ File projectDir = new File("test-resources/mediumtest/xoo/sample-with-hidden-files");
+ AnalysisBuilder analysisBuilder = tester
+ .addRules(new XooRulesDefinition())
+ .addActiveRule("xoo", "OneIssuePerFile", null, "Issue Per File", "MAJOR", null, "xoo")
+ .newAnalysis(new File(projectDir, "sonar-project.properties"))
+ .property("sonar.exclusions", "**/*.ignore")
+ .property("sonar.oneIssuePerFile.enableHiddenFileProcessing", "true");
+
+ if (setHiddenFileScanningExplicitly) {
+ // default is assumed to be false, here we set it explicitly
+ analysisBuilder.property("sonar.scanner.excludeHiddenFiles", "false");
+ }
+
+ AnalysisResult result = analysisBuilder.execute();
+
+ for (Map.Entry<String, Boolean> pathToHiddenStatus : hiddenFileProjectExpectedHiddenStatus().entrySet()) {
+ String filePath = pathToHiddenStatus.getKey();
+ boolean expectedIsHidden = pathToHiddenStatus.getValue();
+ assertHiddenFileScan(result, filePath, expectedIsHidden, true);
+ // we expect the sensor to process all files, regardless of visibility
+ assertFileIssue(result, filePath, true);
+ }
+ assertThat(result.inputFiles()).hasSize(10);
+ }
+
+ @Test
+ void shouldScanAllFilesAndOnlyAnalyzeNonHiddenFiles() throws IOException {
+ prepareHiddenFileProject();
+ File projectDir = new File("test-resources/mediumtest/xoo/sample-with-hidden-files");
+ AnalysisResult result = tester
+ .addRules(new XooRulesDefinition())
+ .addActiveRule("xoo", "OneIssuePerFile", null, "Issue Per File", "MAJOR", null, "xoo")
+ .newAnalysis(new File(projectDir, "sonar-project.properties"))
+ .property("sonar.exclusions", "**/*.ignore")
+ .property("sonar.oneIssuePerFile.enableHiddenFileProcessing", "false")
+ .execute();
+
+ for (Map.Entry<String, Boolean> pathToHiddenStatus : hiddenFileProjectExpectedHiddenStatus().entrySet()) {
+ String filePath = pathToHiddenStatus.getKey();
+ boolean expectedHiddenStatus = pathToHiddenStatus.getValue();
+ assertHiddenFileScan(result, filePath, expectedHiddenStatus, true);
+ // sensor should not process hidden files, we only expect issues on non-hidden files
+ assertFileIssue(result, filePath, !expectedHiddenStatus);
+ }
+ assertThat(result.inputFiles()).hasSize(10);
+ }
+
+ @ParameterizedTest
+ @ValueSource(booleans = {
+ true,
+ false
+ })
+ void shouldNotScanAndAnalyzeHiddenFilesWhenHiddenFileScanningIsDisabled(boolean sensorHiddenFileProcessingEnabled) throws IOException {
+ prepareHiddenFileProject();
+ File projectDir = new File("test-resources/mediumtest/xoo/sample-with-hidden-files");
+ AnalysisResult result = tester
+ .addRules(new XooRulesDefinition())
+ .addActiveRule("xoo", "OneIssuePerFile", null, "Issue Per File", "MAJOR", null, "xoo")
+ .newAnalysis(new File(projectDir, "sonar-project.properties"))
+ .property("sonar.exclusions", "**/*.ignore")
+ .property("sonar.scanner.excludeHiddenFiles", "true")
+ // hidden files are not scanned, so issues can't be raised on them regardless if the sensor wants to process them
+ .property("sonar.oneIssuePerFile.enableHiddenFileProcessing", String.valueOf(sensorHiddenFileProcessingEnabled))
+ .execute();
+
+ for (Map.Entry<String, Boolean> pathToHiddenStatus : hiddenFileProjectExpectedHiddenStatus().entrySet()) {
+ String filePath = pathToHiddenStatus.getKey();
+ boolean expectedHiddenStatus = pathToHiddenStatus.getValue();
+ assertHiddenFileScan(result, filePath, expectedHiddenStatus, false);
+ if (!expectedHiddenStatus) {
+ assertFileIssue(result, filePath, true);
+ }
+ }
+ assertThat(result.inputFiles()).hasSize(1);
+ }
+
+ @Test
+ void hiddenFilesAssignedToALanguageShouldNotBePublishedByDefault() throws IOException {
+ tester
+ .addRules(new XooRulesDefinition());
+
+ File srcDir = new File(baseDir, "src");
+ assertThat(srcDir.mkdir()).isTrue();
+
+ File hiddenFile = writeFile(srcDir, ".xoo", "Sample xoo\ncontent");
+ setFileAsHiddenOnWindows(hiddenFile.toPath());
+ File hiddenFileWithoutLanguage = writeFile(srcDir, ".bar", "Sample bar\ncontent");
+ setFileAsHiddenOnWindows(hiddenFileWithoutLanguage.toPath());
+ writeFile(srcDir, "file.xoo", "Sample xoo\ncontent");
+
+ AnalysisResult result = tester.newAnalysis()
+ .properties(builder
+ .put("sonar.sources", "src")
+ .build())
+ .execute();
+
+ DefaultInputFile hiddenInputFile = (DefaultInputFile) result.inputFile("src/.xoo");
+
+ assertThat(hiddenInputFile).isNotNull();
+ assertThat(hiddenInputFile.isPublished()).isFalse();
+ assertThatThrownBy(() -> result.getReportComponent(hiddenInputFile))
+ .isInstanceOf(IllegalStateException.class)
+ .hasMessageContaining("Unable to find report for component");
+
+ DefaultInputFile hiddenInputFileWithoutLanguage = (DefaultInputFile) result.inputFile("src/.bar");
+ assertThat(hiddenInputFileWithoutLanguage).isNotNull();
+ assertThat(hiddenInputFileWithoutLanguage.isPublished()).isFalse();
+ assertThatThrownBy(() -> result.getReportComponent(hiddenInputFileWithoutLanguage))
+ .isInstanceOf(IllegalStateException.class)
+ .hasMessageContaining("Unable to find report for component");
+
+ DefaultInputFile visibleInputFile = (DefaultInputFile) result.inputFile("src/file.xoo");
+ assertThat(visibleInputFile).isNotNull();
+ assertThat(visibleInputFile.isPublished()).isTrue();
+ assertThat(result.getReportComponent(visibleInputFile)).isNotNull();
+ }
+
+ @Test
+ void shouldDetectHiddenFilesFromMultipleModules() throws IOException {
+ File srcDirA = createModuleWithSubdirectory("moduleA", "src");
+ File srcDirB = createModuleWithSubdirectory("moduleB", "src");
+
+ File fileModuleA = writeFile(srcDirA, ".xoo", "Sample xoo\ncontent");
+ setFileAsHiddenOnWindows(fileModuleA.toPath());
+ File fileModuleB = writeFile(srcDirB, ".xoo", "Sample xoo\ncontent");
+ setFileAsHiddenOnWindows(fileModuleB.toPath());
+
+ AnalysisResult result = tester.newAnalysis()
+ .properties(ImmutableMap.<String, String>builder()
+ .put("sonar.projectBaseDir", baseDir.getAbsolutePath())
+ .put("sonar.projectKey", "com.foo.project")
+ .put("sonar.sources", "src")
+ .put("sonar.modules", "moduleA,moduleB")
+ .build())
+ .execute();
+
+ assertHiddenFileScan(result, "moduleA/src/.xoo", true, true);
+ assertHiddenFileScan(result, "moduleB/src/.xoo", true, true);
+ }
+
+ @Test
+ void shouldScanAndAnalyzeAllHiddenFilesWithRespectToExclusions() throws IOException {
+ prepareHiddenFileProject();
+ File projectDir = new File("test-resources/mediumtest/xoo/sample-with-hidden-files");
+
+
+ AnalysisResult result = tester
+ .addRules(new XooRulesDefinition())
+ .addActiveRule("xoo", "OneIssuePerFile", null, "Issue Per File", "MAJOR", null, "xoo")
+ .newAnalysis(new File(projectDir, "sonar-project.properties"))
+ .property("sonar.scm.provider", "xoo")
+ .property("sonar.oneIssuePerFile.enableHiddenFileProcessing", "true")
+ .property("sonar.exclusions", "**/.nestedHidden/**,**/*.ignore")
+ .execute();
+
+ Set<String> excludedFiles = Set.of(
+ // sonar.exclusions
+ "xources/.hidden/.nestedHidden/.xoo",
+ "xources/.hidden/.nestedHidden/Class.xoo",
+ "xources/.hidden/.nestedHidden/visibleInHiddenFolder/.xoo",
+ "xources/.hidden/.nestedHidden/visibleInHiddenFolder/.xoo.ignore",
+ "xources/.hidden/.nestedHidden/visibleInHiddenFolder/Class.xoo",
+ // scm ignore
+ "xources/nonHidden/.hiddenInVisibleFolder/.xoo");
+
+ for (Map.Entry<String, Boolean> pathToHiddenStatus : hiddenFileProjectExpectedHiddenStatus().entrySet()) {
+ String filePath = pathToHiddenStatus.getKey();
+ boolean expectedIsHidden = pathToHiddenStatus.getValue();
+
+ if (excludedFiles.contains(filePath)) {
+ assertThat(result.inputFile(filePath)).isNull();
+ } else {
+ assertHiddenFileScan(result, filePath, expectedIsHidden, true);
+ // we expect the sensor to process all non-excluded files, regardless of visibility
+ assertFileIssue(result, filePath, true);
+ }
+ }
+ assertThat(result.inputFiles()).hasSize(5);
+ }
+
+ private File createModuleWithSubdirectory(String moduleName, String subDirName) {
+ File moduleBaseDir = new File(baseDir, moduleName);
+ File srcDir = moduleBaseDir.toPath().resolve(subDirName).toFile();
+ assertThat(srcDir.mkdirs()).isTrue();
+ return srcDir;
+ }
+
private static void assertAnalysedFiles(AnalysisResult result, String... files) {
assertThat(result.inputFiles().stream().map(InputFile::toString).toList()).contains(files);
}
@@ -1291,4 +1566,81 @@ class FileSystemMediumIT {
return file;
}
+ private Path prepareBrokenSymlinkTestScenario() throws IOException {
+ File srcDir = new File(baseDir, "src");
+ assertThat(srcDir.mkdir()).isTrue();
+
+ File target = writeFile(srcDir, "target.xoo");
+ Path link = Paths.get(srcDir.getPath(), "target_link.xoo");
+ Files.createSymbolicLink(link, target.toPath());
+ Files.delete(target.toPath());
+
+ return link;
+ }
+
+ private Map<String, Boolean> hiddenFileProjectExpectedHiddenStatus() {
+ return Map.of(
+ "xources/.hidden/.xoo", true,
+ "xources/.hidden/Class.xoo", true,
+ "xources/.hidden/.nestedHidden/.xoo", true,
+ "xources/.hidden/.nestedHidden/Class.xoo", true,
+ "xources/.hidden/.nestedHidden/visibleInHiddenFolder/.xoo", true,
+ "xources/.hidden/.nestedHidden/visibleInHiddenFolder/Class.xoo", true,
+ "xources/nonHidden/.xoo", true,
+ "xources/nonHidden/Class.xoo", false,
+ "xources/nonHidden/.hiddenInVisibleFolder/.xoo", true,
+ "xources/nonHidden/.hiddenInVisibleFolder/Class.xoo", true);
+ }
+
+ private static void prepareHiddenFileProject() throws IOException {
+ if (!SystemUtils.IS_OS_WINDOWS) {
+ return;
+ }
+
+ // On Windows, we need to set the hidden attribute on the file system
+ Set<String> dirAndFilesToHideOnWindows = Set.of(
+ "xources/.hidden",
+ "xources/.hidden/.xoo",
+ "xources/.hidden/.nestedHidden",
+ "xources/.hidden/.nestedHidden/.xoo",
+ "xources/.hidden/.nestedHidden/visibleInHiddenFolder/.xoo",
+ "xources/nonHidden/.xoo",
+ "xources/nonHidden/.hiddenInVisibleFolder",
+ "xources/nonHidden/.hiddenInVisibleFolder/.xoo");
+
+ for (String path : dirAndFilesToHideOnWindows) {
+ Path pathFromResources = Path.of("test-resources/mediumtest/xoo/sample-with-hidden-files", path);
+ setFileAsHiddenOnWindows(pathFromResources);
+ }
+ }
+
+ private static void setFileAsHiddenOnWindows(Path path) throws IOException {
+ if (SystemUtils.IS_OS_WINDOWS) {
+ Files.setAttribute(path, "dos:hidden", true, LinkOption.NOFOLLOW_LINKS);
+ }
+ }
+
+ private static void assertHiddenFileScan(AnalysisResult result, String filePath, boolean expectedHiddenStatus, boolean hiddenFilesShouldBeScanned) {
+ InputFile file = result.inputFile(filePath);
+
+ if (!hiddenFilesShouldBeScanned && expectedHiddenStatus) {
+ assertThat(file).isNull();
+ } else {
+ assertThat(file).withFailMessage(String.format("File \"%s\" was not analyzed", filePath)).isNotNull();
+ assertThat(file.isHidden())
+ .withFailMessage(String.format("Expected file \"%s\" hidden status to be \"%s\", however was \"%s\"", filePath, expectedHiddenStatus, file.isHidden()))
+ .isEqualTo(expectedHiddenStatus);
+ }
+ }
+
+ private static void assertFileIssue(AnalysisResult result, String filePath, boolean expectToHaveIssue) {
+ InputFile file = result.inputFile(filePath);
+ assertThat(file).isNotNull();
+ List<ScannerReport.Issue> issues = result.issuesFor(file);
+ if (expectToHaveIssue) {
+ assertThat(issues).hasSize(1);
+ } else {
+ assertThat(issues).isEmpty();
+ }
+ }
}
diff --git a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/fs/NoLanguagesPluginsMediumIT.java b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/fs/NoLanguagesPluginsMediumIT.java
index db2d45e5904..a18ba763ab8 100644
--- a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/fs/NoLanguagesPluginsMediumIT.java
+++ b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/fs/NoLanguagesPluginsMediumIT.java
@@ -1,6 +1,6 @@
/*
* SonarQube
- * Copyright (C) 2009-2024 SonarSource SA
+ * Copyright (C) 2009-2025 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
diff --git a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/fs/ProjectBuilderMediumIT.java b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/fs/ProjectBuilderMediumIT.java
index ca7cc3134be..1041bd4219a 100644
--- a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/fs/ProjectBuilderMediumIT.java
+++ b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/fs/ProjectBuilderMediumIT.java
@@ -1,6 +1,6 @@
/*
* SonarQube
- * Copyright (C) 2009-2024 SonarSource SA
+ * Copyright (C) 2009-2025 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
diff --git a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/highlighting/HighlightingMediumIT.java b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/highlighting/HighlightingMediumIT.java
index 87d2350f476..11e190911a3 100644
--- a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/highlighting/HighlightingMediumIT.java
+++ b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/highlighting/HighlightingMediumIT.java
@@ -1,6 +1,6 @@
/*
* SonarQube
- * Copyright (C) 2009-2024 SonarSource SA
+ * Copyright (C) 2009-2025 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
diff --git a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/issues/ChecksMediumIT.java b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/issues/ChecksMediumIT.java
index 035267f43fe..8b1d525c9fe 100644
--- a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/issues/ChecksMediumIT.java
+++ b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/issues/ChecksMediumIT.java
@@ -1,6 +1,6 @@
/*
* SonarQube
- * Copyright (C) 2009-2024 SonarSource SA
+ * Copyright (C) 2009-2025 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
diff --git a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/issues/ExternalIssuesMediumIT.java b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/issues/ExternalIssuesMediumIT.java
index a660aa0ec7d..d2e70483145 100644
--- a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/issues/ExternalIssuesMediumIT.java
+++ b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/issues/ExternalIssuesMediumIT.java
@@ -1,6 +1,6 @@
/*
* SonarQube
- * Copyright (C) 2009-2024 SonarSource SA
+ * Copyright (C) 2009-2025 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
diff --git a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/issues/IssuesMediumIT.java b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/issues/IssuesMediumIT.java
index 2ae6379db66..74742eea9d0 100644
--- a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/issues/IssuesMediumIT.java
+++ b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/issues/IssuesMediumIT.java
@@ -1,6 +1,6 @@
/*
* SonarQube
- * Copyright (C) 2009-2024 SonarSource SA
+ * Copyright (C) 2009-2025 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
diff --git a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/issues/IssuesOnDirMediumIT.java b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/issues/IssuesOnDirMediumIT.java
index d000e03239d..0cbd5e1e340 100644
--- a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/issues/IssuesOnDirMediumIT.java
+++ b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/issues/IssuesOnDirMediumIT.java
@@ -1,6 +1,6 @@
/*
* SonarQube
- * Copyright (C) 2009-2024 SonarSource SA
+ * Copyright (C) 2009-2025 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
diff --git a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/issues/IssuesOnModuleMediumIT.java b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/issues/IssuesOnModuleMediumIT.java
index 0edc7d06e97..63588eff056 100644
--- a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/issues/IssuesOnModuleMediumIT.java
+++ b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/issues/IssuesOnModuleMediumIT.java
@@ -1,6 +1,6 @@
/*
* SonarQube
- * Copyright (C) 2009-2024 SonarSource SA
+ * Copyright (C) 2009-2025 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
diff --git a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/issues/MultilineIssuesMediumIT.java b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/issues/MultilineIssuesMediumIT.java
index 1a3535d858d..ecfabaad3b4 100644
--- a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/issues/MultilineIssuesMediumIT.java
+++ b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/issues/MultilineIssuesMediumIT.java
@@ -1,6 +1,6 @@
/*
* SonarQube
- * Copyright (C) 2009-2024 SonarSource SA
+ * Copyright (C) 2009-2025 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
diff --git a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/issues/PreviewMediumIT.java b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/issues/PreviewMediumIT.java
index f28dc028da1..1ad2bb24e13 100644
--- a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/issues/PreviewMediumIT.java
+++ b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/issues/PreviewMediumIT.java
@@ -1,6 +1,6 @@
/*
* SonarQube
- * Copyright (C) 2009-2024 SonarSource SA
+ * Copyright (C) 2009-2025 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
diff --git a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/log/ExceptionHandlingMediumIT.java b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/log/ExceptionHandlingMediumIT.java
index 5b7cd7d631b..b5dbc404cbe 100644
--- a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/log/ExceptionHandlingMediumIT.java
+++ b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/log/ExceptionHandlingMediumIT.java
@@ -1,6 +1,6 @@
/*
* SonarQube
- * Copyright (C) 2009-2024 SonarSource SA
+ * Copyright (C) 2009-2025 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
diff --git a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/log/LogListenerIT.java b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/log/LogListenerIT.java
index e574be69487..588181a456d 100644
--- a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/log/LogListenerIT.java
+++ b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/log/LogListenerIT.java
@@ -1,6 +1,6 @@
/*
* SonarQube
- * Copyright (C) 2009-2024 SonarSource SA
+ * Copyright (C) 2009-2025 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
@@ -124,7 +124,7 @@ public class LogListenerIT {
}
Matcher matcher = simpleTimePattern.matcher(msg);
- assertThat(matcher.find()).isFalse();
+ assertThat(matcher.find()).as("Offending log message: " + msg).isFalse();
}
@Test
diff --git a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/measures/MeasuresMediumIT.java b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/measures/MeasuresMediumIT.java
index 7c43370d423..727d1dc5a58 100644
--- a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/measures/MeasuresMediumIT.java
+++ b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/measures/MeasuresMediumIT.java
@@ -1,6 +1,6 @@
/*
* SonarQube
- * Copyright (C) 2009-2024 SonarSource SA
+ * Copyright (C) 2009-2025 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
diff --git a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/optionalplugins/OptionalPluginsMediumIT.java b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/optionalplugins/OptionalPluginsMediumIT.java
index e618719d72d..54b71f52d23 100644
--- a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/optionalplugins/OptionalPluginsMediumIT.java
+++ b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/optionalplugins/OptionalPluginsMediumIT.java
@@ -1,6 +1,6 @@
/*
* SonarQube
- * Copyright (C) 2009-2024 SonarSource SA
+ * Copyright (C) 2009-2025 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
diff --git a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/properties/PropertiesMediumIT.java b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/properties/PropertiesMediumIT.java
index fe54129e805..0e615e9b628 100644
--- a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/properties/PropertiesMediumIT.java
+++ b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/properties/PropertiesMediumIT.java
@@ -1,6 +1,6 @@
/*
* SonarQube
- * Copyright (C) 2009-2024 SonarSource SA
+ * Copyright (C) 2009-2025 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
diff --git a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/branch/DeprecatedBranchMediumIT.java b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/properties/UnsupportedPropertiesMediumIT.java
index a8ccd819f7d..bf05151bb3c 100644
--- a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/branch/DeprecatedBranchMediumIT.java
+++ b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/properties/UnsupportedPropertiesMediumIT.java
@@ -1,6 +1,6 @@
/*
* SonarQube
- * Copyright (C) 2009-2024 SonarSource SA
+ * Copyright (C) 2009-2025 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
@@ -17,7 +17,7 @@
* 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.mediumtest.branch;
+package org.sonar.scanner.mediumtest.properties;
import com.google.common.collect.ImmutableMap;
import java.io.File;
@@ -33,9 +33,10 @@ import org.sonar.scanner.mediumtest.ScannerMediumTester;
import org.sonar.xoo.XooPlugin;
import org.sonar.xoo.rule.XooRulesDefinition;
+import static java.nio.charset.StandardCharsets.UTF_8;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
-class DeprecatedBranchMediumIT {
+class UnsupportedPropertiesMediumIT {
@TempDir
private File temp;
@@ -69,20 +70,40 @@ class DeprecatedBranchMediumIT {
@Test
void scanProjectWithBranch() throws IOException {
- File srcDir = new File(baseDir, "src");
- srcDir.mkdir();
+ prepareContent();
- File xooFile = new File(srcDir, "sample.xoo");
- FileUtils.write(xooFile, "Sample xoo\ncontent");
-
- assertThatThrownBy(() -> tester.newAnalysis()
+ ScannerMediumTester.AnalysisBuilder analysisBuilder = tester.newAnalysis()
.properties(ImmutableMap.<String, String>builder()
.putAll(commonProps)
.put("sonar.branch", "branch")
- .build())
- .execute())
+ .build());
+
+ assertThatThrownBy(analysisBuilder::execute)
.isInstanceOf(MessageException.class)
.hasMessage("The 'sonar.branch' parameter is no longer supported. You should stop using it. " +
"Branch analysis is available in Developer Edition and above. See https://www.sonarsource.com/plans-and-pricing/developer/ for more information.");
}
+
+ @Test
+ void scanProjectWithPassword() throws IOException {
+ prepareContent();
+
+ ScannerMediumTester.AnalysisBuilder analysisBuilder = tester.newAnalysis()
+ .properties(ImmutableMap.<String, String>builder()
+ .putAll(commonProps)
+ .put("sonar.password", "anything")
+ .build());
+
+ assertThatThrownBy(analysisBuilder::execute)
+ .isInstanceOf(MessageException.class)
+ .hasMessage("The property 'sonar.password' is no longer supported. Please pass a token with the 'sonar.token' property instead.");
+ }
+
+ private void prepareContent() throws IOException {
+ File srcDir = new File(baseDir, "src");
+ srcDir.mkdir();
+
+ File xooFile = new File(srcDir, "sample.xoo");
+ FileUtils.write(xooFile, "Sample xoo\ncontent", UTF_8);
+ }
}
diff --git a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/scm/ScmMediumIT.java b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/scm/ScmMediumIT.java
index 59ee1ee8f81..904e09cc5c5 100644
--- a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/scm/ScmMediumIT.java
+++ b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/scm/ScmMediumIT.java
@@ -1,6 +1,6 @@
/*
* SonarQube
- * Copyright (C) 2009-2024 SonarSource SA
+ * Copyright (C) 2009-2025 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
@@ -241,7 +241,7 @@ public class ScmMediumIT {
assertThat(getChangesets(baseDir, NO_BLAME_SCM_ON_SERVER_XOO)).isNull();
// 5 .xoo files + 3 .scm files, but only 4 marked for publishing. 1 file is SAME so not included in the total
- assertThat(logTester.logs()).containsSubsequence("8 files indexed");
+ assertThat(logTester.logs()).anyMatch(s -> s.startsWith("8 files indexed (done) | time="));
assertThat(logTester.logs()).containsSubsequence("SCM Publisher 4 source files to be analyzed");
assertThat(logTester.logs().stream().anyMatch(s -> Pattern.matches("SCM Publisher 3/4 source files have been analyzed \\(done\\) \\| time=[0-9]+ms", s))).isTrue();
assertThat(logTester.logs()).containsSubsequence(MISSING_BLAME_INFORMATION_FOR_THE_FOLLOWING_FILES, " * src/no_blame_scm_on_server.xoo");
diff --git a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/symbol/SymbolMediumIT.java b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/symbol/SymbolMediumIT.java
index 27a2bec551e..aad8278c66b 100644
--- a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/symbol/SymbolMediumIT.java
+++ b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/symbol/SymbolMediumIT.java
@@ -1,6 +1,6 @@
/*
* SonarQube
- * Copyright (C) 2009-2024 SonarSource SA
+ * Copyright (C) 2009-2025 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
diff --git a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/tasks/TasksMediumIT.java b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/tasks/TasksMediumIT.java
index 117a5c18761..22e58f2cdc3 100644
--- a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/tasks/TasksMediumIT.java
+++ b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/tasks/TasksMediumIT.java
@@ -1,6 +1,6 @@
/*
* SonarQube
- * Copyright (C) 2009-2024 SonarSource SA
+ * Copyright (C) 2009-2025 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
diff --git a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/tests/GenericTestExecutionMediumIT.java b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/tests/GenericTestExecutionMediumIT.java
index a6393e54b2c..50a05bb5438 100644
--- a/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/tests/GenericTestExecutionMediumIT.java
+++ b/sonar-scanner-engine/src/it/java/org/sonar/scanner/mediumtest/tests/GenericTestExecutionMediumIT.java
@@ -1,6 +1,6 @@
/*
* SonarQube
- * Copyright (C) 2009-2024 SonarSource SA
+ * Copyright (C) 2009-2025 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
diff --git a/sonar-scanner-engine/src/it/java/org/sonar/scm/svn/SvnBlameCommandIT.java b/sonar-scanner-engine/src/it/java/org/sonar/scm/svn/SvnBlameCommandIT.java
index 808b98537e5..b86dc641e4d 100644
--- a/sonar-scanner-engine/src/it/java/org/sonar/scm/svn/SvnBlameCommandIT.java
+++ b/sonar-scanner-engine/src/it/java/org/sonar/scm/svn/SvnBlameCommandIT.java
@@ -1,6 +1,6 @@
/*
* SonarQube
- * Copyright (C) 2009-2024 SonarSource SA
+ * Copyright (C) 2009-2025 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
diff --git a/sonar-scanner-engine/src/it/java/org/sonar/scm/svn/SvnTester.java b/sonar-scanner-engine/src/it/java/org/sonar/scm/svn/SvnTester.java
index 43df806b0de..b5ba8d5c59d 100644
--- a/sonar-scanner-engine/src/it/java/org/sonar/scm/svn/SvnTester.java
+++ b/sonar-scanner-engine/src/it/java/org/sonar/scm/svn/SvnTester.java
@@ -1,6 +1,6 @@
/*
* SonarQube
- * Copyright (C) 2009-2024 SonarSource SA
+ * Copyright (C) 2009-2025 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
diff --git a/sonar-scanner-engine/src/it/java/org/sonar/scm/svn/SvnTesterIT.java b/sonar-scanner-engine/src/it/java/org/sonar/scm/svn/SvnTesterIT.java
index 09093e7fe95..47b21c98399 100644
--- a/sonar-scanner-engine/src/it/java/org/sonar/scm/svn/SvnTesterIT.java
+++ b/sonar-scanner-engine/src/it/java/org/sonar/scm/svn/SvnTesterIT.java
@@ -1,6 +1,6 @@
/*
* SonarQube
- * Copyright (C) 2009-2024 SonarSource SA
+ * Copyright (C) 2009-2025 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
diff --git a/sonar-scanner-engine/src/it/java/testutils/TestUtils.java b/sonar-scanner-engine/src/it/java/testutils/TestUtils.java
index 9240d366256..838881854e6 100644
--- a/sonar-scanner-engine/src/it/java/testutils/TestUtils.java
+++ b/sonar-scanner-engine/src/it/java/testutils/TestUtils.java
@@ -1,6 +1,6 @@
/*
* SonarQube
- * Copyright (C) 2009-2024 SonarSource SA
+ * Copyright (C) 2009-2025 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or