aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-scanner-engine/src/test/java
diff options
context:
space:
mode:
Diffstat (limited to 'sonar-scanner-engine/src/test/java')
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/batch/bootstrapper/BatchTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/batch/bootstrapper/EnvironmentInformationTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/batch/bootstrapper/LogCallbackAppenderTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/batch/bootstrapper/LoggingConfigurationTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/batch/bootstrapper/LoggingConfiguratorTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/DefaultFileLinesContextTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/FakeJava.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/ProjectInfoTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/WsTestUtil.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/analysis/AnalysisTempFolderProviderTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/EnvironmentConfigTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ExtensionInstallerTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ExtensionUtilsTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/GlobalConfigurationProviderTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/GlobalTempFolderProviderTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ModuleSensorExtensionDictionaryTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/PluginFilesTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/PostJobExtensionDictionaryTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ScannerLogbackEncoderTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ScannerPluginInstallerTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ScannerPluginJarExploderTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ScannerPluginRepositoryTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ScannerPropertiesTest.java8
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/SonarUserHomeProviderTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/SpringGlobalContainerTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/cache/AnalysisCacheEnabledTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/cache/AnalysisCacheMemoryStorageTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/cache/AnalysisCacheProviderTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/cache/DefaultAnalysisCacheLoaderTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/cache/ReadCacheImplTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/cache/WriteCacheImplTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/CiConfigurationImplTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/CiConfigurationProviderTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/AppVeyorTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/AwsCodeBuildTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/AzureDevopsTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/BambooTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/BitbucketPipelinesTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/BitriseTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/BuildkiteTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/CircleCiTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/CirrusCiTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/CodeMagicTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/DroneCiTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/GithubActionsTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/GitlabCiTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/JenkinsTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/SemaphoreCiTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/TravisCiTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/config/DefaultConfigurationTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/CpdExecutorTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/CpdSettingsTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/DuplicationPredicatesTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/JavaCpdBlockIndexerSensorTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/deprecated/test/DefaultTestCaseTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/extension/ScannerCoreExtensionsInstallerTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/ExternalIssueImporterTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/ExternalIssueReportParserTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/ExternalIssueReportValidatorTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/sarif/DefaultSarif210ImporterTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/sarif/LocationMapperTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/sarif/RegionMapperTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/sarif/ResultMapperTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/sarif/RuleMapperTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/sarif/RulesSeverityDetectorTest.java61
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/sarif/RunMapperTest.java72
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/sarif/SarifIssuesImportSensorTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericCoverageReportParserTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericCoverageSensorTest.java47
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericTestExecutionReportParserTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericTestExecutionSensorTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/StaxParserTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/http/DefaultScannerWsClientTest.java8
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/http/ScannerWsClientProviderTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/DefaultFilterableIssueTest.java3
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/DefaultIssueFilterChainTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ImpactMapperTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/IssuePublisherTest.java60
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/EnforceIssuesFilterTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/IgnoreIssuesFilterTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/pattern/IssueExclusionPatternInitializerTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/pattern/IssueInclusionPatternInitializerTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/pattern/IssuePatternTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/pattern/LineRangeTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsLoaderTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/notifications/DefaultAnalysisWarningsTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/ModuleCoverageAndDuplicationExclusionsTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/ModuleSensorsExecutorTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/PostJobsExecutorTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/ProjectCoverageExclusionsTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/platform/DefaultServerTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/postjob/DefaultPostJobContextTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/postjob/PostJobOptimizerTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/qualitygate/QualityGateCheckTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ActiveRulesPublisherTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/report/AnalysisCachePublisherTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/report/AnalysisContextReportPublisherTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/report/AnalysisWarningsPublisherTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/report/CeTaskReportDataHolderTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ChangedLinesPublisherTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ComponentsPublisherTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ContextPropertiesPublisherTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/report/JavaArchitectureInformationProviderTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/report/MetadataPublisherTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ReportPublisherTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/report/SourcePublisherTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/report/TelemetryPublisherTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/ContextPropertiesCacheTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/DefaultMetricsRepositoryLoaderTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/DefaultNewCodePeriodLoaderTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/DefaultProjectRepositoriesLoaderTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/DefaultQualityProfileLoaderTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/MultiModuleProjectRepositoryTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/ProjectRepositoriesProviderTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/QualityProfileProviderTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/ReferenceBranchSupplierTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/SingleProjectRepositoryTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/TelemetryCacheTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/featureflags/DefaultFeatureFlagsLoaderTest.java85
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/featureflags/DefaultFeatureFlagsRepositoryTest.java49
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/language/DefaultLanguagesRepositoryTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/language/LanguageTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/settings/AbstractSettingsLoaderTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/settings/DefaultGlobalSettingsLoaderTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/settings/DefaultProjectSettingsLoaderTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/rule/ActiveRulesBuilderTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/rule/ActiveRulesProviderTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/rule/DefaultActiveRulesLoaderTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/rule/LoadedActiveRuleTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/rule/QProfileTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/rule/QProfileVerifierTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/sca/CliCacheServiceTest.java307
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/sca/CliServiceTest.java376
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/sca/ScaExecutorTest.java180
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/sca/ScaPropertiesTest.java100
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/DefaultInputModuleHierarchyTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/DeprecatedPropertiesWarningGeneratorTest.java27
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/DirectoryLockTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ModuleConfigurationProviderTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ModuleIndexerTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ProjectBuildersExecutorTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ProjectConfigurationProviderTest.java16
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ProjectLockTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ProjectReactorBuilderTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ProjectReactorValidatorTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ScanPropertiesTest.java22
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/SonarGlobalPropertiesFilterTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/SpringProjectScanContainerTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/WorkDirectoriesInitializerTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/branch/BranchConfigurationProviderTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/branch/ProjectBranchesProviderTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/branch/ProjectBranchesTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/AbstractExclusionFiltersTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/AdditionalFilePredicatesTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ByteCharsetDetectorTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/CharsetDetectorTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/CharsetValidationTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/DirectoryFileVisitorTest.java55
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/HiddenFilesProjectDataTest.java160
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/HiddenFilesVisitorHelperTest.java315
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputComponentStoreTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputFileFilterRepositoryTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/LanguageDetectionTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ModuleInputComponentStoreTest.java159
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/MutableFileSystemTest.java101
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ProjectExclusionFiltersTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/StatusDetectionTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/DefaultBlameOutputTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/ScmChangedFilesProviderTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/ScmChangedFilesTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/ScmConfigurationTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/ScmRevisionImplTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/AbstractSensorOptimizerTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSensorStorageTest.java8
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/ModuleSensorContextTest.java6
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/ModuleSensorOptimizerTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/ProjectSensorContextTest.java16
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/SensorIdTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/UnchangedFilesHandlerTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/util/ProgressReportTest.java25
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/util/ScannerUtilsTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scm/git/ChangedFileTest.java4
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scm/git/ChangedLinesComputerTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scm/git/CompositeBlameCommandIT.java3
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scm/git/CompositeBlameCommandTest.java3
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scm/git/GitIgnoreCommandTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scm/git/GitScmProviderTest.java34
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scm/git/GitScmSupportTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scm/git/GitThreadFactoryTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scm/git/GitUtils.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scm/git/JGitBlameCommandTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scm/git/JGitUtilsTest.java101
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scm/git/NativeGitBlameCommandTest.java131
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scm/git/ProcessWrapperFactoryTest.java52
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scm/git/Utils.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scm/git/strategy/DefaultBlameStrategyTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scm/svn/ChangedLinesComputerTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scm/svn/SvnConfigurationTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scm/svn/SvnScmProviderTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scm/svn/SvnScmSupportTest.java2
202 files changed, 2412 insertions, 522 deletions
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/batch/bootstrapper/BatchTest.java b/sonar-scanner-engine/src/test/java/org/sonar/batch/bootstrapper/BatchTest.java
index aedaef25432..d19d6e8c51e 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/batch/bootstrapper/BatchTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/batch/bootstrapper/BatchTest.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/test/java/org/sonar/batch/bootstrapper/EnvironmentInformationTest.java b/sonar-scanner-engine/src/test/java/org/sonar/batch/bootstrapper/EnvironmentInformationTest.java
index abfb64b85e0..c1aec9a17ea 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/batch/bootstrapper/EnvironmentInformationTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/batch/bootstrapper/EnvironmentInformationTest.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/test/java/org/sonar/batch/bootstrapper/LogCallbackAppenderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/batch/bootstrapper/LogCallbackAppenderTest.java
index a108517c36d..5cb8bdafa8d 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/batch/bootstrapper/LogCallbackAppenderTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/batch/bootstrapper/LogCallbackAppenderTest.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/test/java/org/sonar/batch/bootstrapper/LoggingConfigurationTest.java b/sonar-scanner-engine/src/test/java/org/sonar/batch/bootstrapper/LoggingConfigurationTest.java
index e29ad5ae14a..57f3e3d20f1 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/batch/bootstrapper/LoggingConfigurationTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/batch/bootstrapper/LoggingConfigurationTest.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/test/java/org/sonar/batch/bootstrapper/LoggingConfiguratorTest.java b/sonar-scanner-engine/src/test/java/org/sonar/batch/bootstrapper/LoggingConfiguratorTest.java
index d2291439908..785a2be7b68 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/batch/bootstrapper/LoggingConfiguratorTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/batch/bootstrapper/LoggingConfiguratorTest.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/test/java/org/sonar/scanner/DefaultFileLinesContextTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/DefaultFileLinesContextTest.java
index f386dc40d5c..a9f21841de0 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/DefaultFileLinesContextTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/DefaultFileLinesContextTest.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/test/java/org/sonar/scanner/FakeJava.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/FakeJava.java
index 99554f11e72..7a9a478f3c0 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/FakeJava.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/FakeJava.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/test/java/org/sonar/scanner/ProjectInfoTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ProjectInfoTest.java
index 47139b3e9de..e297649b7d7 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/ProjectInfoTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ProjectInfoTest.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/test/java/org/sonar/scanner/WsTestUtil.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/WsTestUtil.java
index 6fb5829eb80..a781dd1b630 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/WsTestUtil.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/WsTestUtil.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/test/java/org/sonar/scanner/analysis/AnalysisTempFolderProviderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/analysis/AnalysisTempFolderProviderTest.java
index 91dc27af6f3..5cad06cd4b0 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/analysis/AnalysisTempFolderProviderTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/analysis/AnalysisTempFolderProviderTest.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/test/java/org/sonar/scanner/bootstrap/EnvironmentConfigTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/EnvironmentConfigTest.java
index 26f62d4f6d0..1c649cf975f 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/EnvironmentConfigTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/EnvironmentConfigTest.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/test/java/org/sonar/scanner/bootstrap/ExtensionInstallerTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ExtensionInstallerTest.java
index e8159ed92ba..9e730b38827 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ExtensionInstallerTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ExtensionInstallerTest.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/test/java/org/sonar/scanner/bootstrap/ExtensionUtilsTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ExtensionUtilsTest.java
index 3e5211bc6d4..0099106d60a 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ExtensionUtilsTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ExtensionUtilsTest.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/test/java/org/sonar/scanner/bootstrap/GlobalConfigurationProviderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/GlobalConfigurationProviderTest.java
index ba85eda6c1b..29c8ade3e30 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/GlobalConfigurationProviderTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/GlobalConfigurationProviderTest.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/test/java/org/sonar/scanner/bootstrap/GlobalTempFolderProviderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/GlobalTempFolderProviderTest.java
index 2a27b7c5653..22b5f531cff 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/GlobalTempFolderProviderTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/GlobalTempFolderProviderTest.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/test/java/org/sonar/scanner/bootstrap/ModuleSensorExtensionDictionaryTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ModuleSensorExtensionDictionaryTest.java
index 28adaaabec6..381af30f4e0 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ModuleSensorExtensionDictionaryTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ModuleSensorExtensionDictionaryTest.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/test/java/org/sonar/scanner/bootstrap/PluginFilesTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/PluginFilesTest.java
index 30472694f71..7340e55e565 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/PluginFilesTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/PluginFilesTest.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/test/java/org/sonar/scanner/bootstrap/PostJobExtensionDictionaryTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/PostJobExtensionDictionaryTest.java
index 68aad3353ec..3593e6a97b8 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/PostJobExtensionDictionaryTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/PostJobExtensionDictionaryTest.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/test/java/org/sonar/scanner/bootstrap/ScannerLogbackEncoderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ScannerLogbackEncoderTest.java
index ea0028bf90a..a050bad9551 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
@@ -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/test/java/org/sonar/scanner/bootstrap/ScannerPluginInstallerTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ScannerPluginInstallerTest.java
index 210c5228bd9..c6636483ec8 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ScannerPluginInstallerTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ScannerPluginInstallerTest.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/test/java/org/sonar/scanner/bootstrap/ScannerPluginJarExploderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ScannerPluginJarExploderTest.java
index 4ded7fb0901..8e10268145a 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ScannerPluginJarExploderTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ScannerPluginJarExploderTest.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/test/java/org/sonar/scanner/bootstrap/ScannerPluginRepositoryTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ScannerPluginRepositoryTest.java
index 131c0a1aa3b..05f04823a03 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ScannerPluginRepositoryTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ScannerPluginRepositoryTest.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/test/java/org/sonar/scanner/bootstrap/ScannerPropertiesTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ScannerPropertiesTest.java
index cb218245de4..32cf45c475a 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ScannerPropertiesTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ScannerPropertiesTest.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
@@ -34,7 +34,7 @@ class ScannerPropertiesTest {
LogTesterJUnit5 logTester = new LogTesterJUnit5();
@Test
- public void initialization() {
+ void initialization() {
ImmutableMap<String, String> map = ImmutableMap.<String, String>builder()
.put("prop-1", "{b64}Zm9v")
.put("sonar.projectKey", "my-project")
@@ -49,7 +49,7 @@ class ScannerPropertiesTest {
}
@Test
- public void encryption_fail() {
+ void encryption_fail() {
ImmutableMap<String, String> map = ImmutableMap.<String, String>builder()
.put("prop-1", "{aes}Zm9vzxc")
.build();
@@ -59,7 +59,7 @@ class ScannerPropertiesTest {
}
@Test
- public void encryption_ok() {
+ void encryption_ok() {
ImmutableMap<String, String> map = ImmutableMap.<String, String>builder()
.put("prop-1", "{b64}Zm9v")
.build();
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/SonarUserHomeProviderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/SonarUserHomeProviderTest.java
index e499029b6bc..12cc65c5d86 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/SonarUserHomeProviderTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/SonarUserHomeProviderTest.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/test/java/org/sonar/scanner/bootstrap/SpringGlobalContainerTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/SpringGlobalContainerTest.java
index 5380b90947b..f3e55481520 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/SpringGlobalContainerTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/SpringGlobalContainerTest.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/test/java/org/sonar/scanner/cache/AnalysisCacheEnabledTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/cache/AnalysisCacheEnabledTest.java
index 38d9885dd75..72b4b99baa9 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/cache/AnalysisCacheEnabledTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/cache/AnalysisCacheEnabledTest.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/test/java/org/sonar/scanner/cache/AnalysisCacheMemoryStorageTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/cache/AnalysisCacheMemoryStorageTest.java
index 4ae89272f93..df728f72b59 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/cache/AnalysisCacheMemoryStorageTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/cache/AnalysisCacheMemoryStorageTest.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/test/java/org/sonar/scanner/cache/AnalysisCacheProviderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/cache/AnalysisCacheProviderTest.java
index 8b60acf8e29..c38e1e4bf7a 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/cache/AnalysisCacheProviderTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/cache/AnalysisCacheProviderTest.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/test/java/org/sonar/scanner/cache/DefaultAnalysisCacheLoaderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/cache/DefaultAnalysisCacheLoaderTest.java
index aaf4783ac61..757b898b209 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/cache/DefaultAnalysisCacheLoaderTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/cache/DefaultAnalysisCacheLoaderTest.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/test/java/org/sonar/scanner/cache/ReadCacheImplTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/cache/ReadCacheImplTest.java
index e5690f1d481..b2be88587d1 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/cache/ReadCacheImplTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/cache/ReadCacheImplTest.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/test/java/org/sonar/scanner/cache/WriteCacheImplTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/cache/WriteCacheImplTest.java
index 242b2b5009d..291ab34a5bc 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/cache/WriteCacheImplTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/cache/WriteCacheImplTest.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/test/java/org/sonar/scanner/ci/CiConfigurationImplTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/CiConfigurationImplTest.java
index 719b50e7236..1c03bb67608 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/CiConfigurationImplTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/CiConfigurationImplTest.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/test/java/org/sonar/scanner/ci/CiConfigurationProviderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/CiConfigurationProviderTest.java
index 33439b0c2a2..d6839abfdf4 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/CiConfigurationProviderTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/CiConfigurationProviderTest.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/test/java/org/sonar/scanner/ci/vendors/AppVeyorTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/AppVeyorTest.java
index 0f87e5d9071..1298127169e 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/AppVeyorTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/AppVeyorTest.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/test/java/org/sonar/scanner/ci/vendors/AwsCodeBuildTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/AwsCodeBuildTest.java
index 3463d082f8d..df6fd4a27f6 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/AwsCodeBuildTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/AwsCodeBuildTest.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/test/java/org/sonar/scanner/ci/vendors/AzureDevopsTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/AzureDevopsTest.java
index 85096070faa..8d739a75562 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/AzureDevopsTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/AzureDevopsTest.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/test/java/org/sonar/scanner/ci/vendors/BambooTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/BambooTest.java
index 91f6fc4af4f..9c11e2c8a98 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/BambooTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/BambooTest.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/test/java/org/sonar/scanner/ci/vendors/BitbucketPipelinesTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/BitbucketPipelinesTest.java
index a13a894670f..c3f89ff9bc3 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/BitbucketPipelinesTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/BitbucketPipelinesTest.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/test/java/org/sonar/scanner/ci/vendors/BitriseTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/BitriseTest.java
index 668896aba1b..93b6e295e15 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/BitriseTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/BitriseTest.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/test/java/org/sonar/scanner/ci/vendors/BuildkiteTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/BuildkiteTest.java
index 09c07c954b3..4438d1bf31e 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/BuildkiteTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/BuildkiteTest.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/test/java/org/sonar/scanner/ci/vendors/CircleCiTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/CircleCiTest.java
index 9d4c403e099..5ea3d922963 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/CircleCiTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/CircleCiTest.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/test/java/org/sonar/scanner/ci/vendors/CirrusCiTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/CirrusCiTest.java
index a6574822819..0683fda34a5 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/CirrusCiTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/CirrusCiTest.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/test/java/org/sonar/scanner/ci/vendors/CodeMagicTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/CodeMagicTest.java
index c4afbe739b7..abdd007f8da 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/CodeMagicTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/CodeMagicTest.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/test/java/org/sonar/scanner/ci/vendors/DroneCiTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/DroneCiTest.java
index eb960e671f5..066e6fea41d 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/DroneCiTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/DroneCiTest.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/test/java/org/sonar/scanner/ci/vendors/GithubActionsTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/GithubActionsTest.java
index 57a1b3cc4c1..6e1cb07416c 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/GithubActionsTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/GithubActionsTest.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/test/java/org/sonar/scanner/ci/vendors/GitlabCiTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/GitlabCiTest.java
index 45808ab403d..7dada4e12c5 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/GitlabCiTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/GitlabCiTest.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/test/java/org/sonar/scanner/ci/vendors/JenkinsTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/JenkinsTest.java
index ccaf4dcb41a..c4bb8a4ceb6 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/JenkinsTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/JenkinsTest.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/test/java/org/sonar/scanner/ci/vendors/SemaphoreCiTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/SemaphoreCiTest.java
index 058ca88fe0c..40743479d16 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/SemaphoreCiTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/SemaphoreCiTest.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/test/java/org/sonar/scanner/ci/vendors/TravisCiTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/TravisCiTest.java
index 9f85306b173..8634e22511a 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/TravisCiTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/TravisCiTest.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/test/java/org/sonar/scanner/config/DefaultConfigurationTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/config/DefaultConfigurationTest.java
index c1e638fb764..79f9b7bab33 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/config/DefaultConfigurationTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/config/DefaultConfigurationTest.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/test/java/org/sonar/scanner/cpd/CpdExecutorTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/CpdExecutorTest.java
index 8d31c0342d0..b64fe6d2710 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/CpdExecutorTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/CpdExecutorTest.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/test/java/org/sonar/scanner/cpd/CpdSettingsTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/CpdSettingsTest.java
index 8120d711e6f..28b12fa36c1 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/CpdSettingsTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/CpdSettingsTest.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/test/java/org/sonar/scanner/cpd/DuplicationPredicatesTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/DuplicationPredicatesTest.java
index 9a7788e105c..57b70f098b3 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/DuplicationPredicatesTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/DuplicationPredicatesTest.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/test/java/org/sonar/scanner/cpd/JavaCpdBlockIndexerSensorTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/JavaCpdBlockIndexerSensorTest.java
index b1074bc99d1..5800ee87031 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/JavaCpdBlockIndexerSensorTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/JavaCpdBlockIndexerSensorTest.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/test/java/org/sonar/scanner/deprecated/test/DefaultTestCaseTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/deprecated/test/DefaultTestCaseTest.java
index e7770a9aaf1..5f23bb2761f 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/deprecated/test/DefaultTestCaseTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/deprecated/test/DefaultTestCaseTest.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/test/java/org/sonar/scanner/extension/ScannerCoreExtensionsInstallerTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/extension/ScannerCoreExtensionsInstallerTest.java
index d044ee5fc79..104c66707a7 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/extension/ScannerCoreExtensionsInstallerTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/extension/ScannerCoreExtensionsInstallerTest.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/test/java/org/sonar/scanner/externalissue/ExternalIssueImporterTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/ExternalIssueImporterTest.java
index b5794aeea43..4f318a488e8 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/ExternalIssueImporterTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/ExternalIssueImporterTest.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/test/java/org/sonar/scanner/externalissue/ExternalIssueReportParserTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/ExternalIssueReportParserTest.java
index a207bde260e..63885295f3b 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
@@ -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/test/java/org/sonar/scanner/externalissue/ExternalIssueReportValidatorTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/ExternalIssueReportValidatorTest.java
index 0cdacfbf2c5..1d7eb5927d1 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/ExternalIssueReportValidatorTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/ExternalIssueReportValidatorTest.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/test/java/org/sonar/scanner/externalissue/sarif/DefaultSarif210ImporterTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/sarif/DefaultSarif210ImporterTest.java
index 689e3671af1..2bd129235ca 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/sarif/DefaultSarif210ImporterTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/sarif/DefaultSarif210ImporterTest.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/test/java/org/sonar/scanner/externalissue/sarif/LocationMapperTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/sarif/LocationMapperTest.java
index 01a9222699a..338490b90b3 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/sarif/LocationMapperTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/sarif/LocationMapperTest.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/test/java/org/sonar/scanner/externalissue/sarif/RegionMapperTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/sarif/RegionMapperTest.java
index 6417ba175f5..f61a007e9b7 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/sarif/RegionMapperTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/sarif/RegionMapperTest.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/test/java/org/sonar/scanner/externalissue/sarif/ResultMapperTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/sarif/ResultMapperTest.java
index 3efc8c51228..cbdb2def0b5 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/sarif/ResultMapperTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/sarif/ResultMapperTest.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/test/java/org/sonar/scanner/externalissue/sarif/RuleMapperTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/sarif/RuleMapperTest.java
index 5dbf2c36aad..ef833fdcaa5 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/sarif/RuleMapperTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/sarif/RuleMapperTest.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/test/java/org/sonar/scanner/externalissue/sarif/RulesSeverityDetectorTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/sarif/RulesSeverityDetectorTest.java
index e0bc3df54b0..f5d88016944 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/sarif/RulesSeverityDetectorTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/sarif/RulesSeverityDetectorTest.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
@@ -22,12 +22,16 @@ package org.sonar.scanner.externalissue.sarif;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import javax.annotation.Nullable;
import org.assertj.core.api.Assertions;
import org.assertj.core.groups.Tuple;
-import org.junit.Before;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.NullAndEmptySource;
import org.slf4j.event.Level;
-import org.sonar.api.testfixtures.log.LogTester;
+import org.sonar.api.testfixtures.log.LogTesterJUnit5;
import org.sonar.sarif.pojo.ReportingConfiguration;
import org.sonar.sarif.pojo.ReportingDescriptor;
import org.sonar.sarif.pojo.Result;
@@ -44,12 +48,12 @@ import static org.sonar.sarif.pojo.Result.Level.WARNING;
import static org.sonar.scanner.externalissue.sarif.ResultMapper.DEFAULT_IMPACT_SEVERITY;
import static org.sonar.scanner.externalissue.sarif.ResultMapper.DEFAULT_SEVERITY;
-public class RulesSeverityDetectorTest {
+class RulesSeverityDetectorTest {
private static final String DRIVER_NAME = "Test";
private static final String RULE_ID = "RULE_ID";
- @org.junit.Rule
- public LogTester logTester = new LogTester().setLevel(Level.TRACE);
+ @RegisterExtension
+ private final LogTesterJUnit5 logTester = new LogTesterJUnit5();
private final Run run = mock(Run.class);
private final ReportingDescriptor rule = mock(ReportingDescriptor.class);
@@ -59,8 +63,8 @@ public class RulesSeverityDetectorTest {
private final ToolComponent extension = mock(ToolComponent.class);
private final ReportingConfiguration defaultConfiguration = mock(ReportingConfiguration.class);
- @Before
- public void setUp() {
+ @BeforeEach
+ void setUp() {
when(run.getResults()).thenReturn(List.of(result));
when(run.getTool()).thenReturn(tool);
when(tool.getDriver()).thenReturn(driver);
@@ -68,8 +72,8 @@ public class RulesSeverityDetectorTest {
// We keep this test for backward compatibility until we remove the deprecated severity
@Test
- public void detectRulesSeverities_detectsCorrectlyResultDefinedRuleSeverities() {
- Run run = mockResultDefinedRuleSeverities();
+ void detectRulesSeverities_detectsCorrectlyResultDefinedRuleSeverities() {
+ mockResultDefinedRuleSeverities();
Map<String, Result.Level> rulesSeveritiesByRuleId = RulesSeverityDetector.detectRulesSeverities(run, DRIVER_NAME);
@@ -78,8 +82,8 @@ public class RulesSeverityDetectorTest {
}
@Test
- public void detectRulesSeveritiesForNewTaxonomy_shouldReturnsEmptyMapAndLogsWarning_whenOnlyResultDefinedRuleSeverities() {
- Run run = mockResultDefinedRuleSeverities();
+ void detectRulesSeveritiesForNewTaxonomy_shouldReturnsEmptyMapAndLogsWarning_whenOnlyResultDefinedRuleSeverities() {
+ mockResultDefinedRuleSeverities();
Map<String, Result.Level> rulesSeveritiesByRuleId = RulesSeverityDetector.detectRulesSeveritiesForNewTaxonomy(run, DRIVER_NAME);
@@ -88,8 +92,8 @@ public class RulesSeverityDetectorTest {
}
@Test
- public void detectRulesSeverities_detectsCorrectlyDriverDefinedRuleSeverities() {
- Run run = mockDriverDefinedRuleSeverities();
+ void detectRulesSeverities_detectsCorrectlyDriverDefinedRuleSeverities() {
+ mockDriverDefinedRuleSeverities();
Map<String, Result.Level> rulesSeveritiesByRuleId = RulesSeverityDetector.detectRulesSeveritiesForNewTaxonomy(run, DRIVER_NAME);
@@ -103,9 +107,13 @@ public class RulesSeverityDetectorTest {
assertDetectedRuleSeverities(rulesSeveritiesByRuleId, tuple(RULE_ID, WARNING));
}
- @Test
- public void detectRulesSeverities_detectsCorrectlyExtensionsDefinedRuleSeverities() {
- Run run = mockExtensionsDefinedRuleSeverities();
+
+
+ @ParameterizedTest
+ @NullAndEmptySource
+ void detectRulesSeverities_detectsCorrectlyExtensionsDefinedRuleSeverities(@Nullable Set<ReportingDescriptor> rules) {
+ when(driver.getRules()).thenReturn(rules);
+ mockExtensionsDefinedRuleSeverities();
Map<String, Result.Level> rulesSeveritiesByRuleId = RulesSeverityDetector.detectRulesSeveritiesForNewTaxonomy(run, DRIVER_NAME);
@@ -120,8 +128,8 @@ public class RulesSeverityDetectorTest {
}
@Test
- public void detectRulesSeverities_returnsEmptyMapAndLogsWarning_whenUnableToDetectSeverities() {
- Run run = mockUnsupportedRuleSeveritiesDefinition();
+ void detectRulesSeverities_returnsEmptyMapAndLogsWarning_whenUnableToDetectSeverities() {
+ mockUnsupportedRuleSeveritiesDefinition();
Map<String, Result.Level> rulesSeveritiesByRuleId = RulesSeverityDetector.detectRulesSeveritiesForNewTaxonomy(run, DRIVER_NAME);
@@ -135,38 +143,33 @@ public class RulesSeverityDetectorTest {
assertDetectedRuleSeverities(rulesSeveritiesByRuleId);
}
- private Run mockResultDefinedRuleSeverities() {
+ private void mockResultDefinedRuleSeverities() {
when(run.getResults()).thenReturn(List.of(result));
when(result.getLevel()).thenReturn(WARNING);
when(result.getRuleId()).thenReturn(RULE_ID);
- return run;
}
- private Run mockDriverDefinedRuleSeverities() {
+ private void mockDriverDefinedRuleSeverities() {
when(driver.getRules()).thenReturn(Set.of(rule));
when(rule.getId()).thenReturn(RULE_ID);
when(rule.getDefaultConfiguration()).thenReturn(defaultConfiguration);
when(defaultConfiguration.getLevel()).thenReturn(ReportingConfiguration.Level.WARNING);
- return run;
}
- private Run mockExtensionsDefinedRuleSeverities() {
- when(driver.getRules()).thenReturn(Set.of());
+ private void mockExtensionsDefinedRuleSeverities() {
when(tool.getExtensions()).thenReturn(Set.of(extension));
when(extension.getRules()).thenReturn(Set.of(rule));
when(rule.getId()).thenReturn(RULE_ID);
when(rule.getDefaultConfiguration()).thenReturn(defaultConfiguration);
when(defaultConfiguration.getLevel()).thenReturn(ReportingConfiguration.Level.WARNING);
- return run;
}
- private Run mockUnsupportedRuleSeveritiesDefinition() {
+ private void mockUnsupportedRuleSeveritiesDefinition() {
when(run.getTool()).thenReturn(tool);
when(tool.getDriver()).thenReturn(driver);
when(driver.getRules()).thenReturn(Set.of());
when(tool.getExtensions()).thenReturn(Set.of(extension));
when(extension.getRules()).thenReturn(Set.of());
- return run;
}
private void assertNoLogs() {
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/sarif/RunMapperTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/sarif/RunMapperTest.java
index 407c229e31b..164787f8cde 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/sarif/RunMapperTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/sarif/RunMapperTest.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
@@ -22,19 +22,19 @@ package org.sonar.scanner.externalissue.sarif;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.extension.RegisterExtension;
import org.mockito.Answers;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockedStatic;
-import org.mockito.junit.MockitoJUnitRunner;
+import org.mockito.junit.jupiter.MockitoExtension;
import org.slf4j.event.Level;
import org.sonar.api.batch.sensor.issue.NewExternalIssue;
import org.sonar.api.batch.sensor.rule.NewAdHocRule;
-import org.sonar.api.testfixtures.log.LogTester;
+import org.sonar.api.testfixtures.log.LogTesterJUnit5;
import org.sonar.sarif.pojo.ReportingDescriptor;
import org.sonar.sarif.pojo.Result;
import org.sonar.sarif.pojo.Run;
@@ -44,13 +44,14 @@ import org.sonar.scanner.externalissue.sarif.RunMapper.RunMapperResult;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.assertj.core.api.Assertions.assertThatNoException;
+import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.when;
import static org.sonar.sarif.pojo.Result.Level.WARNING;
-@RunWith(MockitoJUnitRunner.class)
-public class RunMapperTest {
+@ExtendWith(MockitoExtension.class)
+class RunMapperTest {
private static final String TEST_DRIVER = "Test driver";
public static final String RULE_ID = "ruleId";
@@ -66,21 +67,21 @@ public class RunMapperTest {
@Mock
private ReportingDescriptor rule;
- @Rule
- public LogTester logTester = new LogTester();
+ @RegisterExtension
+ public LogTesterJUnit5 logTester = new LogTesterJUnit5();
@InjectMocks
private RunMapper runMapper;
- @Before
- public void setUp() {
- when(run.getTool().getDriver().getName()).thenReturn(TEST_DRIVER);
- when(run.getTool().getExtensions()).thenReturn(null);
- when(rule.getId()).thenReturn(RULE_ID);
+ @BeforeEach
+ void setUp() {
+ lenient().when(run.getTool().getDriver().getName()).thenReturn(TEST_DRIVER);
+ lenient().when(run.getTool().getExtensions()).thenReturn(null);
+ lenient().when(rule.getId()).thenReturn(RULE_ID);
}
@Test
- public void mapRun_shouldMapExternalIssues() {
+ void mapRun_shouldMapExternalIssues() {
Result result1 = mock(Result.class);
Result result2 = mock(Result.class);
when(run.getResults()).thenReturn(List.of(result1, result2));
@@ -99,7 +100,7 @@ public class RunMapperTest {
}
@Test
- public void mapRun_shouldMapExternalRules_whenDriverHasRulesAndNoExtensions() {
+ void mapRun_shouldMapExternalRules_whenDriverHasRulesAndNoExtensions() {
when(run.getTool().getDriver().getRules()).thenReturn(Set.of(rule));
NewAdHocRule externalRule = mockMappedExternalRule();
@@ -115,7 +116,7 @@ public class RunMapperTest {
}
@Test
- public void mapRun_shouldMapExternalRules_whenRulesInExtensions() {
+ void mapRun_shouldMapExternalRules_whenRulesInExtensions() {
when(run.getTool().getDriver().getRules()).thenReturn(Set.of());
ToolComponent extension = mock(ToolComponent.class);
when(extension.getRules()).thenReturn(Set.of(rule));
@@ -134,7 +135,7 @@ public class RunMapperTest {
}
@Test
- public void mapRun_shouldNotFail_whenExtensionsDontHaveRules() {
+ void mapRun_shouldNotFail_whenExtensionsDontHaveRules() {
when(run.getTool().getDriver().getRules()).thenReturn(Set.of(rule));
ToolComponent extension = mock(ToolComponent.class);
when(extension.getRules()).thenReturn(null);
@@ -149,7 +150,7 @@ public class RunMapperTest {
}
@Test
- public void mapRun_shouldNotFail_whenExtensionsHaveEmptyRules() {
+ void mapRun_shouldNotFail_whenExtensionsHaveEmptyRules() {
when(run.getTool().getDriver().getRules()).thenReturn(Set.of(rule));
ToolComponent extension = mock(ToolComponent.class);
when(extension.getRules()).thenReturn(Set.of());
@@ -164,7 +165,7 @@ public class RunMapperTest {
}
@Test
- public void mapRun_ifRunIsEmpty_returnsEmptyList() {
+ void mapRun_ifRunIsEmpty_returnsEmptyList() {
when(run.getResults()).thenReturn(List.of());
RunMapperResult runMapperResult = runMapper.mapRun(run);
@@ -173,7 +174,7 @@ public class RunMapperTest {
}
@Test
- public void mapRun_ifExceptionThrownByResultMapper_logsThemAndContinueProcessing() {
+ void mapRun_ifExceptionThrownByResultMapper_logsThemAndContinueProcessing() {
Result result1 = mock(Result.class);
Result result2 = mock(Result.class);
when(run.getResults()).thenReturn(List.of(result1, result2));
@@ -194,7 +195,7 @@ public class RunMapperTest {
}
@Test
- public void mapRun_failsIfToolNotSet() {
+ void mapRun_failsIfToolNotSet() {
when(run.getTool()).thenReturn(null);
assertThatIllegalArgumentException()
@@ -203,7 +204,7 @@ public class RunMapperTest {
}
@Test
- public void mapRun_failsIfDriverNotSet() {
+ void mapRun_failsIfDriverNotSet() {
when(run.getTool().getDriver()).thenReturn(null);
assertThatIllegalArgumentException()
@@ -212,7 +213,7 @@ public class RunMapperTest {
}
@Test
- public void mapRun_failsIfDriverNameIsNotSet() {
+ void mapRun_failsIfDriverNameIsNotSet() {
when(run.getTool().getDriver().getName()).thenReturn(null);
assertThatIllegalArgumentException()
@@ -220,6 +221,25 @@ public class RunMapperTest {
.withMessage("The run does not have a tool driver name defined.");
}
+ @Test
+ void mapRun_shouldNotFail_whenDriverRulesNullAndExtensionsRulesNotNull() {
+ when(run.getTool().getDriver().getRules()).thenReturn(null);
+ ToolComponent extension = mock(ToolComponent.class);
+ when(extension.getRules()).thenReturn(Set.of(rule));
+ when(run.getTool().getExtensions()).thenReturn(Set.of(extension));
+ NewAdHocRule expectedRule = mock(NewAdHocRule.class);
+ when(ruleMapper.mapRule(rule, TEST_DRIVER, WARNING, WARNING)).thenReturn(expectedRule);
+
+ try (MockedStatic<RulesSeverityDetector> detector = mockStatic(RulesSeverityDetector.class)) {
+ detector.when(() -> RulesSeverityDetector.detectRulesSeverities(run, TEST_DRIVER)).thenReturn(Map.of(RULE_ID, WARNING));
+ detector.when(() -> RulesSeverityDetector.detectRulesSeveritiesForNewTaxonomy(run, TEST_DRIVER)).thenReturn(Map.of(RULE_ID, WARNING));
+
+ RunMapperResult runMapperResult = runMapper.mapRun(run);
+ assertThat(runMapperResult.getNewAdHocRules()).hasSize(1);
+ assertThat(runMapperResult.getNewAdHocRules().get(0)).isEqualTo(expectedRule);
+ }
+ }
+
private NewExternalIssue mockMappedExternalIssue(Result result) {
NewExternalIssue externalIssue = mock(NewExternalIssue.class);
when(result.getRuleId()).thenReturn(RULE_ID);
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 d5d458118d1..0f34825be27 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
@@ -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/test/java/org/sonar/scanner/genericcoverage/GenericCoverageReportParserTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericCoverageReportParserTest.java
index 46e75360b6f..3d8fdd6b569 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericCoverageReportParserTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericCoverageReportParserTest.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/test/java/org/sonar/scanner/genericcoverage/GenericCoverageSensorTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericCoverageSensorTest.java
index be46d38ab9e..5f30363972d 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericCoverageSensorTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericCoverageSensorTest.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
@@ -19,19 +19,28 @@
*/
package org.sonar.scanner.genericcoverage;
+import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.junit.Rule;
import org.junit.Test;
+import org.slf4j.event.Level;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.DefaultFileSystem;
+import org.sonar.api.batch.sensor.internal.SensorContextTester;
import org.sonar.api.config.PropertyDefinitions;
import org.sonar.api.config.internal.Encryption;
-import org.sonar.api.utils.System2;
import org.sonar.api.testfixtures.log.LogTester;
+import org.sonar.api.utils.System2;
import org.sonar.scanner.config.DefaultConfiguration;
import org.sonar.scanner.scan.ProjectConfiguration;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
public class GenericCoverageSensorTest {
@@ -49,4 +58,38 @@ public class GenericCoverageSensorTest {
assertThat(reportPaths).containsOnly("report.xml", "report2.xml");
}
+
+ @Test
+ public void should_log_info_message_when_unknown_files_exist() throws Exception {
+ logTester.setLevel(Level.INFO);
+ DefaultConfiguration config = mock(DefaultConfiguration.class);
+
+ // Create a temporary file to simulate the report file
+ Path tempReportFile = Files.createTempFile("report", ".xml");
+ // Write valid content with version information to the temporary file
+ Files.write(tempReportFile, "<coverage version=\"1\"><file path=\"unknownFile\"/></coverage>".getBytes());
+
+ // Use the temporary file path in the configuration mock
+ when(config.getStringArray(GenericCoverageSensor.REPORT_PATHS_PROPERTY_KEY)).thenReturn(new String[] {tempReportFile.toString()});
+
+ GenericCoverageSensor sensor = new GenericCoverageSensor(config);
+ SensorContextTester context = SensorContextTester.create(new File("."));
+ DefaultFileSystem fileSystem = context.fileSystem();
+
+ // Mock the input file instead of using DefaultInputFile
+ InputFile inputFile = mock(InputFile.class);
+ when(inputFile.language()).thenReturn("java");
+ when(inputFile.type()).thenReturn(InputFile.Type.MAIN);
+ when(inputFile.filename()).thenReturn("unknownFile");
+
+ fileSystem.add(inputFile);
+
+ sensor.execute(context);
+
+ assertThat(logTester.logs(Level.INFO)).contains("Coverage data ignored for 1 unknown files, including:\nunknownFile");
+
+ // Clean up the temporary file
+ Files.delete(tempReportFile);
+ }
+
}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericTestExecutionReportParserTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericTestExecutionReportParserTest.java
index caad591b76d..2e903a9af2a 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericTestExecutionReportParserTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericTestExecutionReportParserTest.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/test/java/org/sonar/scanner/genericcoverage/GenericTestExecutionSensorTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericTestExecutionSensorTest.java
index cebfab7585d..fb4fb130425 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericTestExecutionSensorTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericTestExecutionSensorTest.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/test/java/org/sonar/scanner/genericcoverage/StaxParserTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/StaxParserTest.java
index dd9e744a1a2..feaeaa7318d 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/StaxParserTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/StaxParserTest.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/test/java/org/sonar/scanner/http/DefaultScannerWsClientTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/http/DefaultScannerWsClientTest.java
index 35b5f356f93..a833986c940 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/http/DefaultScannerWsClientTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/http/DefaultScannerWsClientTest.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
@@ -145,7 +145,7 @@ public class DefaultScannerWsClientTest {
assertThatThrownBy(() -> client.call(request))
.isInstanceOf(MessageException.class)
.hasMessage("Not authorized. Analyzing this project requires authentication. Please check the user token in the property 'sonar.token' " +
- "or the credentials in the properties 'sonar.login' and 'sonar.password'.");
+ "or 'sonar.login' (deprecated).");
List<String> debugLogs = logTester.logs(Level.DEBUG);
assertThat(debugLogs).hasSize(3);
@@ -165,7 +165,7 @@ public class DefaultScannerWsClientTest {
assertThatThrownBy(() -> client.call(request))
.isInstanceOf(MessageException.class)
.hasMessage("Not authorized. Analyzing this project requires authentication. Please check the user token in the property 'sonar.token' " +
- "or the credentials in the properties 'sonar.login' and 'sonar.password'.");
+ "or 'sonar.login' (deprecated).");
}
@Test
@@ -180,7 +180,7 @@ public class DefaultScannerWsClientTest {
new GlobalAnalysisMode(new ScannerProperties(Collections.emptyMap())), analysisWarnings);
assertThatThrownBy(() -> client.call(request))
.isInstanceOf(MessageException.class)
- .hasMessage("Not authorized. Please check the user token in the property 'sonar.token' or the credentials in the properties 'sonar.login' and 'sonar.password'.");
+ .hasMessage("Not authorized. Please check the user token in the property 'sonar.token' or 'sonar.login' (deprecated).");
}
@Test
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/http/ScannerWsClientProviderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/http/ScannerWsClientProviderTest.java
index 63a52e51cd7..f4f492f11c1 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/http/ScannerWsClientProviderTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/http/ScannerWsClientProviderTest.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/test/java/org/sonar/scanner/issue/DefaultFilterableIssueTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/DefaultFilterableIssueTest.java
index 6145aec1c11..094b53880d8 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/DefaultFilterableIssueTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/DefaultFilterableIssueTest.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
@@ -23,7 +23,6 @@ import org.junit.Before;
import org.junit.Test;
import org.sonar.api.batch.fs.InputComponent;
import org.sonar.api.batch.fs.internal.DefaultInputProject;
-import org.sonar.scanner.protocol.Constants.Severity;
import org.sonar.scanner.protocol.output.ScannerReport.Issue;
import org.sonar.scanner.protocol.output.ScannerReport.TextRange;
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/DefaultIssueFilterChainTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/DefaultIssueFilterChainTest.java
index 3957b01c45c..e6604609ba6 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/DefaultIssueFilterChainTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/DefaultIssueFilterChainTest.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/test/java/org/sonar/scanner/issue/ImpactMapperTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ImpactMapperTest.java
index f543b023c75..394c1c24bae 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ImpactMapperTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ImpactMapperTest.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/test/java/org/sonar/scanner/issue/IssuePublisherTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/IssuePublisherTest.java
index 0132e1d7ecc..24ce368bd7e 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/IssuePublisherTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/IssuePublisherTest.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
@@ -19,14 +19,15 @@
*/
package org.sonar.scanner.issue;
-import java.io.IOException;
+import java.io.File;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.junit.MockitoJUnitRunner;
@@ -65,14 +66,13 @@ import static org.sonar.api.issue.impact.SoftwareQuality.MAINTAINABILITY;
import static org.sonar.api.issue.impact.SoftwareQuality.RELIABILITY;
@RunWith(MockitoJUnitRunner.class)
-public class IssuePublisherTest {
+class IssuePublisherTest {
private static final RuleKey JAVA_RULE_KEY = RuleKey.of("java", "AvoidCycle");
- private static final RuleKey NOSONAR_RULE_KEY = RuleKey.of("java", "NoSonarCheck");
private DefaultInputProject project;
- @Rule
- public TemporaryFolder temp = new TemporaryFolder();
+ @TempDir
+ public File temp;
public IssueFilters filters = mock(IssueFilters.class);
private final ActiveRulesBuilder activeRulesBuilder = new ActiveRulesBuilder();
@@ -80,12 +80,12 @@ public class IssuePublisherTest {
private final DefaultInputFile file = new TestInputFileBuilder("foo", "src/Foo.php").initMetadata("Foo\nBar\nBiz\n").build();
private final ReportPublisher reportPublisher = mock(ReportPublisher.class, RETURNS_DEEP_STUBS);
- @Before
- public void prepare() throws IOException {
+ @BeforeEach
+ void prepare() {
project = new DefaultInputProject(ProjectDefinition.create()
.setKey("foo")
- .setBaseDir(temp.newFolder())
- .setWorkDir(temp.newFolder()));
+ .setBaseDir(temp)
+ .setWorkDir(temp));
activeRulesBuilder.addRule(new NewActiveRule.Builder()
.setRuleKey(JAVA_RULE_KEY)
@@ -96,12 +96,12 @@ public class IssuePublisherTest {
}
@Test
- public void ignore_null_active_rule() {
- RuleKey INACTIVE_RULE_KEY = RuleKey.of("repo", "inactive");
+ void ignore_null_active_rule() {
+ RuleKey inactiveRuleKey = RuleKey.of("repo", "inactive");
initModuleIssues();
DefaultIssue issue = new DefaultIssue(project)
.at(new DefaultIssueLocation().on(file).at(file.selectLine(3)).message("Foo"))
- .forRule(INACTIVE_RULE_KEY);
+ .forRule(inactiveRuleKey);
boolean added = moduleIssues.initAndAddIssue(issue);
assertThat(added).isFalse();
@@ -109,7 +109,7 @@ public class IssuePublisherTest {
}
@Test
- public void ignore_null_rule_of_active_rule() {
+ void ignore_null_rule_of_active_rule() {
initModuleIssues();
DefaultIssue issue = new DefaultIssue(project)
@@ -122,7 +122,7 @@ public class IssuePublisherTest {
}
@Test
- public void add_issue_to_cache() {
+ void add_issue_to_cache() {
initModuleIssues();
final String ruleDescriptionContextKey = "spring";
@@ -156,7 +156,7 @@ public class IssuePublisherTest {
}
@Test
- public void add_issue_flows_to_cache() {
+ void add_issue_flows_to_cache() {
initModuleIssues();
DefaultMessageFormatting messageFormatting = new DefaultMessageFormatting().start(0).end(4).type(CODE);
@@ -198,7 +198,7 @@ public class IssuePublisherTest {
}
@Test
- public void add_external_issue_to_cache() {
+ void add_external_issue_to_cache() {
initModuleIssues();
DefaultExternalIssue issue = new DefaultExternalIssue(project)
@@ -215,7 +215,7 @@ public class IssuePublisherTest {
}
@Test
- public void initAndAddExternalIssue_whenImpactAndCleanCodeAttributeProvided_shouldPopulateReportFields() {
+ void initAndAddExternalIssue_whenImpactAndCleanCodeAttributeProvided_shouldPopulateReportFields() {
initModuleIssues();
DefaultExternalIssue issue = new DefaultExternalIssue(project)
@@ -234,7 +234,7 @@ public class IssuePublisherTest {
}
@Test
- public void dont_store_severity_if_no_severity_override_on_issue() {
+ void dont_store_severity_if_no_severity_override_on_issue() {
initModuleIssues();
DefaultIssue issue = new DefaultIssue(project)
@@ -250,7 +250,7 @@ public class IssuePublisherTest {
}
@Test
- public void filter_issue() {
+ void filter_issue() {
DefaultIssue issue = new DefaultIssue(project)
.at(new DefaultIssueLocation().on(file).at(file.selectLine(3)).message(""))
.forRule(JAVA_RULE_KEY);
@@ -264,7 +264,7 @@ public class IssuePublisherTest {
}
@Test
- public void should_ignore_lines_commented_with_nosonar() {
+ void should_ignore_lines_commented_with_nosonar() {
initModuleIssues();
DefaultIssue issue = new DefaultIssue(project)
@@ -279,11 +279,13 @@ public class IssuePublisherTest {
verifyNoInteractions(reportPublisher);
}
- @Test
- public void should_accept_issues_on_no_sonar_rules() {
+ @ParameterizedTest
+ @ValueSource(strings = {"NoSonarCheck", "S1291", "S1291Check"})
+ void should_accept_issues_on_no_sonar_rules(String noSonarRule) {
+ RuleKey noSonarRuleKey = RuleKey.of("java", noSonarRule);
// The "No Sonar" rule logs violations on the lines that are flagged with "NOSONAR" !!
activeRulesBuilder.addRule(new NewActiveRule.Builder()
- .setRuleKey(NOSONAR_RULE_KEY)
+ .setRuleKey(noSonarRuleKey)
.setSeverity(Severity.INFO)
.setQProfileKey("qp-1")
.build());
@@ -293,7 +295,7 @@ public class IssuePublisherTest {
DefaultIssue issue = new DefaultIssue(project)
.at(new DefaultIssueLocation().on(file).at(file.selectLine(3)).message(""))
- .forRule(NOSONAR_RULE_KEY);
+ .forRule(noSonarRuleKey);
when(filters.accept(any(InputComponent.class), any(ScannerReport.Issue.class), anyString())).thenReturn(true);
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/EnforceIssuesFilterTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/EnforceIssuesFilterTest.java
index 955ad6d31ef..faffd2ffc71 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/EnforceIssuesFilterTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/EnforceIssuesFilterTest.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/test/java/org/sonar/scanner/issue/ignore/IgnoreIssuesFilterTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/IgnoreIssuesFilterTest.java
index 208fdc7c93f..3a36ce87077 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/IgnoreIssuesFilterTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/IgnoreIssuesFilterTest.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/test/java/org/sonar/scanner/issue/ignore/pattern/IssueExclusionPatternInitializerTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/pattern/IssueExclusionPatternInitializerTest.java
index 0f6bcfb30f2..8a6162b9119 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/pattern/IssueExclusionPatternInitializerTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/pattern/IssueExclusionPatternInitializerTest.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/test/java/org/sonar/scanner/issue/ignore/pattern/IssueInclusionPatternInitializerTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/pattern/IssueInclusionPatternInitializerTest.java
index e83f810b44c..dc72e720d1c 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/pattern/IssueInclusionPatternInitializerTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/pattern/IssueInclusionPatternInitializerTest.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/test/java/org/sonar/scanner/issue/ignore/pattern/IssuePatternTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/pattern/IssuePatternTest.java
index 29c84925d13..0d9bbb00492 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/pattern/IssuePatternTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/pattern/IssuePatternTest.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/test/java/org/sonar/scanner/issue/ignore/pattern/LineRangeTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/pattern/LineRangeTest.java
index a9eb896166e..0fc2f514140 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/pattern/LineRangeTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/pattern/LineRangeTest.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/test/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsLoaderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsLoaderTest.java
index 88abb67c747..5be7449d83b 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsLoaderTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsLoaderTest.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/test/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest.java
index e22128143f7..b9dc87dffad 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest.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/test/java/org/sonar/scanner/notifications/DefaultAnalysisWarningsTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/notifications/DefaultAnalysisWarningsTest.java
index c3dc7622211..415d09a9fd0 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/notifications/DefaultAnalysisWarningsTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/notifications/DefaultAnalysisWarningsTest.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/test/java/org/sonar/scanner/phases/ModuleCoverageAndDuplicationExclusionsTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/ModuleCoverageAndDuplicationExclusionsTest.java
index 48b77adf39b..2c3ad211e3a 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
@@ -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/test/java/org/sonar/scanner/phases/ModuleSensorsExecutorTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/ModuleSensorsExecutorTest.java
index bfdecc89e49..3b81d77d641 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/ModuleSensorsExecutorTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/ModuleSensorsExecutorTest.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/test/java/org/sonar/scanner/phases/PostJobsExecutorTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/PostJobsExecutorTest.java
index 6bd64e7f4cd..1b376bb78e2 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/PostJobsExecutorTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/PostJobsExecutorTest.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/test/java/org/sonar/scanner/phases/ProjectCoverageExclusionsTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/ProjectCoverageExclusionsTest.java
index 0623a21b316..d4c70a6c660 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/ProjectCoverageExclusionsTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/ProjectCoverageExclusionsTest.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/test/java/org/sonar/scanner/platform/DefaultServerTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/platform/DefaultServerTest.java
index b9bb8f112b8..c8873310661 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/platform/DefaultServerTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/platform/DefaultServerTest.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/test/java/org/sonar/scanner/postjob/DefaultPostJobContextTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/postjob/DefaultPostJobContextTest.java
index 7a4f74f8a25..6557254d85e 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/postjob/DefaultPostJobContextTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/postjob/DefaultPostJobContextTest.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/test/java/org/sonar/scanner/postjob/PostJobOptimizerTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/postjob/PostJobOptimizerTest.java
index 5e72e68cb0d..4ceee858858 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/postjob/PostJobOptimizerTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/postjob/PostJobOptimizerTest.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/test/java/org/sonar/scanner/qualitygate/QualityGateCheckTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/qualitygate/QualityGateCheckTest.java
index b31249ff815..15f465a804e 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/qualitygate/QualityGateCheckTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/qualitygate/QualityGateCheckTest.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/test/java/org/sonar/scanner/report/ActiveRulesPublisherTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ActiveRulesPublisherTest.java
index 8c4db588240..11c933362d2 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ActiveRulesPublisherTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ActiveRulesPublisherTest.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/test/java/org/sonar/scanner/report/AnalysisCachePublisherTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/AnalysisCachePublisherTest.java
index f54ac6231bd..3e8c512935b 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/AnalysisCachePublisherTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/AnalysisCachePublisherTest.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/test/java/org/sonar/scanner/report/AnalysisContextReportPublisherTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/AnalysisContextReportPublisherTest.java
index 0d7b061ccb4..c40699de708 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/AnalysisContextReportPublisherTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/AnalysisContextReportPublisherTest.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/test/java/org/sonar/scanner/report/AnalysisWarningsPublisherTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/AnalysisWarningsPublisherTest.java
index fd14aec52d0..0704f797093 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/AnalysisWarningsPublisherTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/AnalysisWarningsPublisherTest.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/test/java/org/sonar/scanner/report/CeTaskReportDataHolderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/CeTaskReportDataHolderTest.java
index eb8854804fc..b99dab0aa34 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/CeTaskReportDataHolderTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/CeTaskReportDataHolderTest.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/test/java/org/sonar/scanner/report/ChangedLinesPublisherTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ChangedLinesPublisherTest.java
index 47f191d99c1..a81c62629f8 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ChangedLinesPublisherTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ChangedLinesPublisherTest.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/test/java/org/sonar/scanner/report/ComponentsPublisherTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ComponentsPublisherTest.java
index 06d692f2950..0e13c5929c8 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ComponentsPublisherTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ComponentsPublisherTest.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/test/java/org/sonar/scanner/report/ContextPropertiesPublisherTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ContextPropertiesPublisherTest.java
index 746d98be7fa..88c31e3eb43 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ContextPropertiesPublisherTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ContextPropertiesPublisherTest.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/test/java/org/sonar/scanner/report/JavaArchitectureInformationProviderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/JavaArchitectureInformationProviderTest.java
index 4977c3b0b3b..7841e58be0b 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/JavaArchitectureInformationProviderTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/JavaArchitectureInformationProviderTest.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/test/java/org/sonar/scanner/report/MetadataPublisherTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/MetadataPublisherTest.java
index 129a3c79450..65fbabb8309 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/MetadataPublisherTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/MetadataPublisherTest.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/test/java/org/sonar/scanner/report/ReportPublisherTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ReportPublisherTest.java
index 40910a0f364..416867a29a5 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ReportPublisherTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ReportPublisherTest.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/test/java/org/sonar/scanner/report/SourcePublisherTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/SourcePublisherTest.java
index d426aeffe13..36911cdb33e 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/SourcePublisherTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/SourcePublisherTest.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/test/java/org/sonar/scanner/report/TelemetryPublisherTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/TelemetryPublisherTest.java
index f71e9a8f8c5..1b235e8c0bc 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/TelemetryPublisherTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/TelemetryPublisherTest.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/test/java/org/sonar/scanner/repository/ContextPropertiesCacheTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/ContextPropertiesCacheTest.java
index 936c0665220..8ed3100fc47 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/ContextPropertiesCacheTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/ContextPropertiesCacheTest.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/test/java/org/sonar/scanner/repository/DefaultMetricsRepositoryLoaderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/DefaultMetricsRepositoryLoaderTest.java
index f0b61cf71dd..9af77efa829 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/DefaultMetricsRepositoryLoaderTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/DefaultMetricsRepositoryLoaderTest.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/test/java/org/sonar/scanner/repository/DefaultNewCodePeriodLoaderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/DefaultNewCodePeriodLoaderTest.java
index 856bb82823a..7ddc6634113 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/DefaultNewCodePeriodLoaderTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/DefaultNewCodePeriodLoaderTest.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/test/java/org/sonar/scanner/repository/DefaultProjectRepositoriesLoaderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/DefaultProjectRepositoriesLoaderTest.java
index e55fb9880d0..dac5c93c71a 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/DefaultProjectRepositoriesLoaderTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/DefaultProjectRepositoriesLoaderTest.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/test/java/org/sonar/scanner/repository/DefaultQualityProfileLoaderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/DefaultQualityProfileLoaderTest.java
index 8c0253fbe9d..0354656baa4 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/DefaultQualityProfileLoaderTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/DefaultQualityProfileLoaderTest.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/test/java/org/sonar/scanner/repository/MultiModuleProjectRepositoryTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/MultiModuleProjectRepositoryTest.java
index f937379af8d..2ff3e8dadeb 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/MultiModuleProjectRepositoryTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/MultiModuleProjectRepositoryTest.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/test/java/org/sonar/scanner/repository/ProjectRepositoriesProviderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/ProjectRepositoriesProviderTest.java
index 0538cb6f0a8..2a46bb205fc 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/ProjectRepositoriesProviderTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/ProjectRepositoriesProviderTest.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/test/java/org/sonar/scanner/repository/QualityProfileProviderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/QualityProfileProviderTest.java
index d89d5e2222c..5250b0dbdc6 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/QualityProfileProviderTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/QualityProfileProviderTest.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/test/java/org/sonar/scanner/repository/ReferenceBranchSupplierTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/ReferenceBranchSupplierTest.java
index d8807130d2c..7f242dd2d5d 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/ReferenceBranchSupplierTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/ReferenceBranchSupplierTest.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/test/java/org/sonar/scanner/repository/SingleProjectRepositoryTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/SingleProjectRepositoryTest.java
index 6164d465986..d184dddaaa6 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/SingleProjectRepositoryTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/SingleProjectRepositoryTest.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/test/java/org/sonar/scanner/repository/TelemetryCacheTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/TelemetryCacheTest.java
index dc6fe24b18b..20d0589aa61 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/TelemetryCacheTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/TelemetryCacheTest.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/test/java/org/sonar/scanner/repository/featureflags/DefaultFeatureFlagsLoaderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/featureflags/DefaultFeatureFlagsLoaderTest.java
new file mode 100644
index 00000000000..59a73e86f16
--- /dev/null
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/featureflags/DefaultFeatureFlagsLoaderTest.java
@@ -0,0 +1,85 @@
+/*
+ * 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.repository.featureflags;
+
+import com.google.gson.Gson;
+import java.io.Reader;
+import java.io.StringReader;
+import java.util.List;
+import java.util.Set;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.sonar.api.utils.MessageException;
+import org.sonar.scanner.WsTestUtil;
+import org.sonar.scanner.http.DefaultScannerWsClient;
+import org.sonar.scanner.scan.branch.BranchConfiguration;
+import wiremock.org.apache.hc.core5.http.HttpException;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatException;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+class DefaultFeatureFlagsLoaderTest {
+
+ private DefaultFeatureFlagsLoader loader;
+ private DefaultScannerWsClient wsClient;
+
+ @BeforeEach
+ void setUp() {
+ wsClient = mock(DefaultScannerWsClient.class);
+ BranchConfiguration branchConfig = mock(BranchConfiguration.class);
+ when(branchConfig.isPullRequest()).thenReturn(false);
+ loader = new DefaultFeatureFlagsLoader(wsClient);
+ }
+
+ @Test
+ void load_shouldRequestFeatureFlagsAndParseResponse() {
+ WsTestUtil.mockReader(wsClient, "/api/features/list", response());
+
+ Set<String> features = loader.load();
+ assertThat(features).containsExactlyInAnyOrder("feature1", "feature2");
+
+ WsTestUtil.verifyCall(wsClient, "/api/features/list");
+
+ verifyNoMoreInteractions(wsClient);
+ }
+
+ @Test
+ void load_whenHasSomeError_shouldThrowIllegalStateException() {
+ when(wsClient.call(any())).thenThrow(MessageException.of("You're not authorized"));
+
+ assertThatException().isThrownBy(loader::load)
+ .isInstanceOf(IllegalStateException.class)
+ .withMessage("Unable to load feature flags");
+ }
+
+ private Reader response() {
+ return toReader(List.of("feature1", "feature2"));
+ }
+
+ private static Reader toReader(List<String> featureFlags) {
+ String json = new Gson().toJson(featureFlags);
+ return new StringReader(json);
+ }
+
+}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/featureflags/DefaultFeatureFlagsRepositoryTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/featureflags/DefaultFeatureFlagsRepositoryTest.java
new file mode 100644
index 00000000000..e043fcfdd2f
--- /dev/null
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/featureflags/DefaultFeatureFlagsRepositoryTest.java
@@ -0,0 +1,49 @@
+/*
+ * 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.repository.featureflags;
+
+import java.util.Set;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+class DefaultFeatureFlagsRepositoryTest {
+
+ private DefaultFeatureFlagsRepository underTest;
+
+ @BeforeEach
+ void prepare() {
+ var loader = mock(FeatureFlagsLoader.class);
+ when(loader.load()).thenReturn(Set.of("feature1"));
+ underTest = new DefaultFeatureFlagsRepository(loader);
+ }
+
+ @Test
+ void start_shouldReturnFlagStatus() {
+ underTest.start();
+
+ assertThat(underTest.isEnabled("feature1")).isTrue();
+ assertThat(underTest.isEnabled("feature2")).isFalse();
+ }
+
+}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/language/DefaultLanguagesRepositoryTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/language/DefaultLanguagesRepositoryTest.java
index 294e4763d2e..8a2149c5a75 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/language/DefaultLanguagesRepositoryTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/language/DefaultLanguagesRepositoryTest.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/test/java/org/sonar/scanner/repository/language/LanguageTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/language/LanguageTest.java
index 84e6654bcd0..6db64e4debb 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/language/LanguageTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/language/LanguageTest.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/test/java/org/sonar/scanner/repository/settings/AbstractSettingsLoaderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/settings/AbstractSettingsLoaderTest.java
index 1510a90ccf0..4928d6b6720 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/settings/AbstractSettingsLoaderTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/settings/AbstractSettingsLoaderTest.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/test/java/org/sonar/scanner/repository/settings/DefaultGlobalSettingsLoaderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/settings/DefaultGlobalSettingsLoaderTest.java
index 0b3d1bb23b1..3f3843ffb3b 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/settings/DefaultGlobalSettingsLoaderTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/settings/DefaultGlobalSettingsLoaderTest.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/test/java/org/sonar/scanner/repository/settings/DefaultProjectSettingsLoaderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/settings/DefaultProjectSettingsLoaderTest.java
index c1694faa9a1..819a595f415 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/settings/DefaultProjectSettingsLoaderTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/settings/DefaultProjectSettingsLoaderTest.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/test/java/org/sonar/scanner/rule/ActiveRulesBuilderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/rule/ActiveRulesBuilderTest.java
index e4ad8642286..db4be9b680e 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/rule/ActiveRulesBuilderTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/rule/ActiveRulesBuilderTest.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/test/java/org/sonar/scanner/rule/ActiveRulesProviderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/rule/ActiveRulesProviderTest.java
index c5f3fceedbc..d118234f1ec 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/rule/ActiveRulesProviderTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/rule/ActiveRulesProviderTest.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/test/java/org/sonar/scanner/rule/DefaultActiveRulesLoaderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/rule/DefaultActiveRulesLoaderTest.java
index cf66faeb655..23ac91da048 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/rule/DefaultActiveRulesLoaderTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/rule/DefaultActiveRulesLoaderTest.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/test/java/org/sonar/scanner/rule/LoadedActiveRuleTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/rule/LoadedActiveRuleTest.java
index 735e48e9473..4b22dfdf441 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/rule/LoadedActiveRuleTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/rule/LoadedActiveRuleTest.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/test/java/org/sonar/scanner/rule/QProfileTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/rule/QProfileTest.java
index cfc0cc30e84..4cd1ba67dda 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/rule/QProfileTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/rule/QProfileTest.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/test/java/org/sonar/scanner/rule/QProfileVerifierTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/rule/QProfileVerifierTest.java
index b029707f107..519f9de5726 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/rule/QProfileVerifierTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/rule/QProfileVerifierTest.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/test/java/org/sonar/scanner/sca/CliCacheServiceTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sca/CliCacheServiceTest.java
new file mode 100644
index 00000000000..6615ba4e4e4
--- /dev/null
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sca/CliCacheServiceTest.java
@@ -0,0 +1,307 @@
+/*
+ * 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.sca;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringReader;
+import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang.SystemUtils;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.extension.RegisterExtension;
+import org.junit.jupiter.api.io.TempDir;
+import org.mockito.Mock;
+import org.mockito.MockedStatic;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.slf4j.event.Level;
+import org.sonar.api.testfixtures.log.LogTesterJUnit5;
+import org.sonar.api.utils.System2;
+import org.sonar.scanner.WsTestUtil;
+import org.sonar.scanner.bootstrap.SonarUserHome;
+import org.sonar.scanner.http.DefaultScannerWsClient;
+import org.sonar.scanner.repository.TelemetryCache;
+import org.sonarqube.ws.client.HttpException;
+import org.sonarqube.ws.client.WsResponse;
+
+import static java.lang.String.format;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.lenient;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.mockStatic;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.sonar.scanner.sca.CliCacheService.CLI_WS_URL;
+
+@ExtendWith(MockitoExtension.class)
+class CliCacheServiceTest {
+ @Mock
+ private SonarUserHome sonarUserHome;
+ @Mock
+ private DefaultScannerWsClient scannerWsClient;
+ @Mock
+ private System2 system2;
+ @Mock
+ private TelemetryCache telemetryCache;
+ @RegisterExtension
+ private final LogTesterJUnit5 logTester = new LogTesterJUnit5();
+ @TempDir
+ public Path cacheDir;
+
+ private CliCacheService underTest;
+
+ @BeforeEach
+ void setup() {
+ lenient().when(sonarUserHome.getPath()).thenReturn(cacheDir);
+ lenient().when(telemetryCache.put(any(), any())).thenReturn(telemetryCache);
+
+ underTest = new CliCacheService(sonarUserHome, scannerWsClient, telemetryCache, system2);
+ }
+
+ @Test
+ void cacheCli_shouldDownloadCli_whenCacheDoesNotExist() {
+ String checksum = "checksum";
+ String id = "tidelift";
+ WsTestUtil.mockReader(scannerWsClient, CLI_WS_URL, new StringReader("""
+ [
+ {
+ "id": "%s",
+ "filename": "tidelift_darwin",
+ "sha256": "%s",
+ "os": "mac",
+ "arch": "x64_86"
+ }
+ ]""".formatted(id, checksum)));
+
+ WsTestUtil.mockStream(scannerWsClient, CLI_WS_URL + "/" + id, new ByteArrayInputStream("cli content".getBytes()));
+
+ assertThat(cacheDir).isEmptyDirectory();
+
+ File generatedFile = underTest.cacheCli();
+
+ assertThat(generatedFile).exists().isExecutable();
+ assertThat(cacheDir.resolve("cache").resolve(checksum)).exists().isNotEmptyDirectory();
+
+ verify(telemetryCache).put(eq("scanner.sca.download.cli.duration"), any());
+ verify(telemetryCache).put("scanner.sca.download.cli.success", "true");
+ verify(telemetryCache).put("scanner.sca.get.cli.cache.hit", "false");
+ verify(telemetryCache).put("scanner.sca.get.cli.success", "true");
+ }
+
+ @Test
+ void cacheCli_shouldThrowException_whenMultipleMetadatas() {
+ WsTestUtil.mockReader(scannerWsClient, CLI_WS_URL, new StringReader("""
+ [
+ {
+ "id": "tidelift",
+ "filename": "tidelift_darwin",
+ "sha256": "1",
+ "os": "mac",
+ "arch": "x64_86"
+ },
+ {
+ "id": "tidelift_other",
+ "filename": "tidelift",
+ "sha256": "2",
+ "os": "mac",
+ "arch": "x64_86"
+ }
+ ]"""));
+
+ assertThatThrownBy(underTest::cacheCli).isInstanceOf(IllegalStateException.class)
+ .hasMessageContaining("Multiple CLI matches found. Unable to correctly cache CLI.");
+
+ verify(telemetryCache).put("scanner.sca.get.cli.success", "false");
+
+ }
+
+ @Test
+ void cacheCli_shouldThrowException_whenNoMetadata() {
+ WsTestUtil.mockReader(scannerWsClient, CLI_WS_URL, new StringReader("[]"));
+
+ assertThatThrownBy(underTest::cacheCli).isInstanceOf(IllegalStateException.class)
+ .hasMessageMatching("Could not find CLI for .+ .+");
+
+ verify(telemetryCache).put("scanner.sca.get.cli.success", "false");
+
+ }
+
+ @Test
+ void cacheCli_shouldThrowException_whenServerError() {
+ HttpException http = new HttpException("url", 500, "some error message");
+ IllegalStateException e = new IllegalStateException("http error", http);
+ WsTestUtil.mockException(scannerWsClient, e);
+
+ assertThatThrownBy(underTest::cacheCli).isInstanceOf(IllegalStateException.class)
+ .hasMessageContaining("http error");
+
+ verify(telemetryCache).put("scanner.sca.get.cli.success", "false");
+ }
+
+ @Test
+ void cacheCli_shouldNotOverwrite_whenCachedFileExists() throws IOException {
+ String checksum = "checksum";
+ WsTestUtil.mockReader(scannerWsClient, CLI_WS_URL, new StringReader("""
+ [
+ {
+ "id": "tidelift",
+ "filename": "tidelift_darwin",
+ "sha256": "%s",
+ "os": "mac",
+ "arch": "x64_86"
+ }
+ ]""".formatted(checksum)));
+ when(system2.isOsWindows()).thenReturn(false);
+
+ String fileContent = "test content";
+ File existingFile = underTest.cacheDir().resolve(checksum).resolve("tidelift").toFile();
+ FileUtils.createParentDirectories(existingFile);
+ FileUtils.writeStringToFile(existingFile, fileContent, Charset.defaultCharset());
+
+ assertThat(existingFile).exists();
+ if (!SystemUtils.IS_OS_WINDOWS) {
+ assertThat(existingFile.canExecute()).isFalse();
+ }
+ assertThat(FileUtils.readFileToString(existingFile, Charset.defaultCharset())).isEqualTo(fileContent);
+
+ underTest.cacheCli();
+
+ WsTestUtil.verifyCall(scannerWsClient, CLI_WS_URL);
+ assertThat(existingFile).exists();
+ if (!SystemUtils.IS_OS_WINDOWS) {
+ assertThat(existingFile.canExecute()).isFalse();
+ }
+ assertThat(FileUtils.readFileToString(existingFile, Charset.defaultCharset())).isEqualTo(fileContent);
+
+ verify(telemetryCache).put("scanner.sca.get.cli.cache.hit", "true");
+ verify(telemetryCache).put("scanner.sca.get.cli.success", "true");
+ }
+
+ @Test
+ void cacheCli_shouldAllowLocationOverride(@TempDir Path tempDir) throws IOException {
+ File alternateCliFile = tempDir.resolve("alternate_cli").toFile();
+ FileUtils.writeStringToFile(alternateCliFile, "alternate cli content", Charset.defaultCharset());
+ when(system2.envVariable("TIDELIFT_CLI_LOCATION")).thenReturn(alternateCliFile.getAbsolutePath());
+
+ var returnedFile = underTest.cacheCli();
+
+ assertThat(returnedFile.getAbsolutePath()).isEqualTo(alternateCliFile.getAbsolutePath());
+ assertThat(logTester.logs(Level.INFO)).contains("Using alternate location for Tidelift CLI: " + alternateCliFile.getAbsolutePath());
+ verify(scannerWsClient, never()).call(any());
+ }
+
+ @Test
+ void cacheCli_whenOverrideDoesntExist_shouldRaiseError() {
+ var location = "incorrect_location";
+ when(system2.envVariable("TIDELIFT_CLI_LOCATION")).thenReturn(location);
+
+ assertThatThrownBy(underTest::cacheCli).isInstanceOf(IllegalStateException.class)
+ .hasMessageMatching("Alternate location for Tidelift CLI has been set but no file was found at " + location);
+
+ assertThat(logTester.logs(Level.INFO)).contains("Using alternate location for Tidelift CLI: " + location);
+ verify(scannerWsClient, never()).call(any());
+ }
+
+ @Test
+ void apiOsName_shouldReturnApiCompatibleName() {
+ when(system2.isOsWindows()).thenReturn(true);
+ when(system2.isOsMac()).thenReturn(false);
+ assertThat(underTest.apiOsName()).isEqualTo("windows");
+ reset(system2);
+
+ when(system2.isOsWindows()).thenReturn(false);
+ when(system2.isOsMac()).thenReturn(true);
+ assertThat(underTest.apiOsName()).isEqualTo("mac");
+
+ reset(system2);
+ when(system2.isOsWindows()).thenReturn(false);
+ when(system2.isOsMac()).thenReturn(false);
+ assertThat(underTest.apiOsName()).isEqualTo("linux");
+ }
+
+ @Test
+ void createTempDir_shouldReturnExistingDir() throws IOException {
+ Path dir = sonarUserHome.getPath().resolve("_tmp");
+ Files.createDirectory(dir);
+
+ assertThat(underTest.createTempDir()).isEqualTo(dir);
+ }
+
+ @Test
+ void createTempDir_shouldHandleIOException() {
+ try (MockedStatic<Files> mockFilesClass = mockStatic(Files.class)) {
+ mockFilesClass.when(() -> Files.createDirectory(any(Path.class))).thenThrow(IOException.class);
+
+ Path expectedDir = sonarUserHome.getPath().resolve("_tmp");
+ assertThatThrownBy(underTest::createTempDir).isInstanceOf(IllegalStateException.class)
+ .hasMessageContaining(format("Unable to create temp directory at %s", expectedDir));
+ }
+ }
+
+ @Test
+ void moveFile_shouldHandleIOException(@TempDir Path sourceFile, @TempDir Path targetFile) {
+ try (MockedStatic<Files> mockFilesClass = mockStatic(Files.class)) {
+ mockFilesClass.when(() -> Files.move(sourceFile, targetFile, StandardCopyOption.ATOMIC_MOVE)).thenThrow(IOException.class);
+ mockFilesClass.when(() -> Files.move(sourceFile, targetFile)).thenThrow(IOException.class);
+
+ assertThatThrownBy(() -> CliCacheService.moveFile(sourceFile, targetFile)).isInstanceOf(IllegalStateException.class)
+ .hasMessageContaining(format("Fail to move %s to %s", sourceFile, targetFile));
+
+ assertThat(logTester.logs(Level.WARN)).contains(format("Unable to rename %s to %s", sourceFile, targetFile));
+ assertThat(logTester.logs(Level.WARN)).contains("A copy/delete will be tempted but with no guarantee of atomicity");
+ }
+ }
+
+ @Test
+ void mkdir_shouldHandleIOException(@TempDir Path dir) {
+ try (MockedStatic<Files> mockFilesClass = mockStatic(Files.class)) {
+ mockFilesClass.when(() -> Files.createDirectories(dir)).thenThrow(IOException.class);
+
+ assertThatThrownBy(() -> CliCacheService.mkdir(dir)).isInstanceOf(IllegalStateException.class)
+ .hasMessageContaining(format("Fail to create cache directory: %s", dir));
+ }
+ }
+
+ @Test
+ void downloadBinaryTo_shouldHandleIOException(@TempDir Path downloadLocation) {
+ WsResponse mockResponse = mock(WsResponse.class);
+ InputStream mockStream = mock(InputStream.class);
+ when(mockResponse.contentStream()).thenReturn(mockStream);
+
+ try (MockedStatic<FileUtils> mockFileUtils = mockStatic(FileUtils.class)) {
+ mockFileUtils.when(() -> FileUtils.copyInputStreamToFile(mockStream, downloadLocation.toFile())).thenThrow(IOException.class);
+
+ assertThatThrownBy(() -> CliCacheService.downloadBinaryTo(downloadLocation, mockResponse)).isInstanceOf(IllegalStateException.class)
+ .hasMessageContaining(format("Fail to download SCA CLI into %s", downloadLocation));
+ }
+ }
+}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sca/CliServiceTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sca/CliServiceTest.java
new file mode 100644
index 00000000000..33cf6c146e6
--- /dev/null
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sca/CliServiceTest.java
@@ -0,0 +1,376 @@
+/*
+ * 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.sca;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.lang3.SystemUtils;
+import org.junit.jupiter.api.AfterEach;
+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.mockito.MockedStatic;
+import org.sonar.api.batch.bootstrap.ProjectDefinition;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.DefaultInputModule;
+import org.sonar.api.batch.scm.ScmProvider;
+import org.sonar.api.platform.Server;
+import org.sonar.api.testfixtures.log.LogTesterJUnit5;
+import org.sonar.api.utils.System2;
+import org.sonar.core.util.ProcessWrapperFactory;
+import org.sonar.scanner.config.DefaultConfiguration;
+import org.sonar.scanner.repository.TelemetryCache;
+import org.sonar.scanner.scan.filesystem.ProjectExclusionFilters;
+import org.sonar.scanner.scm.ScmConfiguration;
+import org.sonar.scm.git.GitScmProvider;
+import org.sonar.scm.git.JGitUtils;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.CALLS_REAL_METHODS;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.slf4j.event.Level.DEBUG;
+import static org.slf4j.event.Level.INFO;
+
+class CliServiceTest {
+ private TelemetryCache telemetryCache;
+ private DefaultInputModule rootInputModule;
+ private final Server server = mock(Server.class);
+ @RegisterExtension
+ private final LogTesterJUnit5 logTester = new LogTesterJUnit5();
+ @TempDir
+ Path rootModuleDir;
+ private final ScmConfiguration scmConfiguration = mock(ScmConfiguration.class);
+ private final ScmProvider scmProvider = mock(GitScmProvider.class);
+ ProcessWrapperFactory processWrapperFactory = mock(ProcessWrapperFactory.class, CALLS_REAL_METHODS);
+ private MockedStatic<JGitUtils> jGitUtilsMock;
+ DefaultConfiguration configuration = mock(DefaultConfiguration.class);
+ ProjectExclusionFilters projectExclusionFilters = mock(ProjectExclusionFilters.class);
+
+ private CliService underTest;
+
+ @BeforeEach
+ void setup() throws IOException {
+ telemetryCache = new TelemetryCache();
+ Path workDir = rootModuleDir.resolve(".scannerwork");
+ Files.createDirectories(workDir);
+ rootInputModule = new DefaultInputModule(
+ ProjectDefinition.create().setBaseDir(rootModuleDir.toFile()).setWorkDir(workDir.toFile()));
+ when(scmConfiguration.provider()).thenReturn(scmProvider);
+ when(scmProvider.key()).thenReturn("git");
+ when(scmConfiguration.isExclusionDisabled()).thenReturn(false);
+ jGitUtilsMock = org.mockito.Mockito.mockStatic(JGitUtils.class);
+ jGitUtilsMock.when(() -> JGitUtils.getAllIgnoredPaths(any(Path.class))).thenReturn(List.of("ignored.txt"));
+ when(server.getVersion()).thenReturn("1.0.0");
+ logTester.setLevel(INFO);
+ when(projectExclusionFilters.getExclusionsConfig(InputFile.Type.MAIN)).thenReturn(new String[0]);
+ when(configuration.getStringArray(CliService.SCA_EXCLUSIONS_KEY)).thenReturn(new String[0]);
+ when(configuration.getStringArray(CliService.LEGACY_SCA_EXCLUSIONS_KEY)).thenReturn(new String[0]);
+
+ underTest = new CliService(processWrapperFactory, telemetryCache, System2.INSTANCE, server, scmConfiguration, projectExclusionFilters);
+ }
+
+ @AfterEach
+ void teardown() {
+ if (jGitUtilsMock != null) {
+ jGitUtilsMock.close();
+ }
+ }
+
+ @Test
+ void generateManifestsArchive_shouldCallProcessCorrectly_andRegisterTelemetry() throws IOException, URISyntaxException {
+ assertThat(rootModuleDir.resolve("test_file").toFile().createNewFile()).isTrue();
+
+ when(configuration.getProperties()).thenReturn(Map.of(CliService.SCA_EXCLUSIONS_KEY, "foo,bar,baz/**"));
+ when(configuration.getStringArray(CliService.SCA_EXCLUSIONS_KEY)).thenReturn(new String[] {"foo", "bar", "baz/**"});
+
+ File producedArchive = underTest.generateManifestsArchive(rootInputModule, scriptDir(), configuration);
+
+ assertThat(producedArchive).exists();
+
+ var expectedArguments = List.of(
+ "projects",
+ "save-lockfiles",
+ "--xz",
+ "--xz-filename",
+ rootInputModule.getWorkDir().resolve("dependency-files.tar.xz").toString(),
+ "--directory",
+ rootInputModule.getBaseDir().toString(),
+ "--recursive",
+ "--exclude",
+ "foo,bar,baz/**,ignored.txt,.scannerwork/**");
+
+ assertThat(logTester.logs(INFO))
+ .contains("Arguments Passed In: " + String.join(" ", expectedArguments))
+ .contains("TIDELIFT_SKIP_UPDATE_CHECK=1")
+ .contains("TIDELIFT_ALLOW_MANIFEST_FAILURES=1")
+ .contains("Generated manifests archive file: " + producedArchive.getName());
+
+ assertThat(telemetryCache.getAll()).containsKey("scanner.sca.execution.cli.duration").isNotNull();
+ assertThat(telemetryCache.getAll()).containsEntry("scanner.sca.execution.cli.success", "true");
+ }
+
+ @Test
+ void generateManifestsArchive_whenDebugLogLevelAndScaDebugNotEnabled_shouldWriteDebugLogsToDebugStream() throws IOException, URISyntaxException {
+ logTester.setLevel(DEBUG);
+
+ assertThat(rootModuleDir.resolve("test_file").toFile().createNewFile()).isTrue();
+
+ underTest.generateManifestsArchive(rootInputModule, scriptDir(), configuration);
+
+ var expectedArguments = List.of(
+ "projects",
+ "save-lockfiles",
+ "--xz",
+ "--xz-filename",
+ rootInputModule.getWorkDir().resolve("dependency-files.tar.xz").toString(),
+ "--directory",
+ rootInputModule.getBaseDir().toString(),
+ "--recursive",
+ "--exclude",
+ "ignored.txt,.scannerwork/**",
+ "--debug");
+
+ assertThat(logTester.logs(INFO))
+ .contains("Arguments Passed In: " + String.join(" ", expectedArguments));
+ }
+
+ @Test
+ void generateManifestsArchive_whenScaDebugEnabled_shouldWriteDebugLogsToInfoStream() throws IOException, URISyntaxException {
+ assertThat(rootModuleDir.resolve("test_file").toFile().createNewFile()).isTrue();
+
+ underTest.generateManifestsArchive(rootInputModule, scriptDir(), configuration);
+
+ var expectedArguments = List.of(
+ "projects",
+ "save-lockfiles",
+ "--xz",
+ "--xz-filename",
+ rootInputModule.getWorkDir().resolve("dependency-files.tar.xz").toString(),
+ "--directory",
+ rootInputModule.getBaseDir().toString(),
+ "--recursive",
+ "--exclude",
+ "ignored.txt,.scannerwork/**");
+
+ assertThat(logTester.logs(INFO))
+ .contains("Arguments Passed In: " + String.join(" ", expectedArguments));
+ }
+
+ @Test
+ void generateManifestsArchive_shouldSendSQEnvVars() throws IOException, URISyntaxException {
+ underTest.generateManifestsArchive(rootInputModule, scriptDir(), configuration);
+
+ assertThat(logTester.logs(INFO))
+ .contains("TIDELIFT_CLI_INSIDE_SCANNER_ENGINE=1")
+ .contains("TIDELIFT_CLI_SQ_SERVER_VERSION=1.0.0");
+ }
+
+ @Test
+ void generateManifestsArchive_includesIgnoredPathsFromGitProvider() throws Exception {
+ underTest.generateManifestsArchive(rootInputModule, scriptDir(), configuration);
+
+ var expectedArguments = List.of(
+ "projects",
+ "save-lockfiles",
+ "--xz",
+ "--xz-filename",
+ rootInputModule.getWorkDir().resolve("dependency-files.tar.xz").toString(),
+ "--directory",
+ rootInputModule.getBaseDir().toString(),
+ "--recursive",
+ "--exclude",
+ "ignored.txt,.scannerwork/**");
+
+ assertThat(logTester.logs(INFO))
+ .contains("Arguments Passed In: " + String.join(" ", expectedArguments))
+ .contains("TIDELIFT_SKIP_UPDATE_CHECK=1")
+ .contains("TIDELIFT_ALLOW_MANIFEST_FAILURES=1")
+ .contains("TIDELIFT_CLI_INSIDE_SCANNER_ENGINE=1")
+ .contains("TIDELIFT_CLI_SQ_SERVER_VERSION=1.0.0");
+
+ }
+
+ @Test
+ void generateManifestsArchive_withNoScm_doesNotIncludeScmIgnoredPaths() throws Exception {
+ when(scmConfiguration.provider()).thenReturn(null);
+
+ underTest.generateManifestsArchive(rootInputModule, scriptDir(), configuration);
+
+ String capturedArgs = logTester.logs().stream().filter(log -> log.contains("Arguments Passed In:")).findFirst().get();
+ assertThat(capturedArgs).contains("--exclude .scannerwork/**");
+ }
+
+ @Test
+ void generateManifestsArchive_withNonGit_doesNotIncludeScmIgnoredPaths() throws Exception {
+ when(scmProvider.key()).thenReturn("notgit");
+
+ underTest.generateManifestsArchive(rootInputModule, scriptDir(), configuration);
+
+ String capturedArgs = logTester.logs().stream().filter(log -> log.contains("Arguments Passed In:")).findFirst().get();
+ assertThat(capturedArgs).contains("--exclude .scannerwork/**");
+ }
+
+ @Test
+ void generateManifestsArchive_withScmExclusionDisabled_doesNotIncludeScmIgnoredPaths() throws Exception {
+ when(scmConfiguration.isExclusionDisabled()).thenReturn(true);
+
+ underTest.generateManifestsArchive(rootInputModule, scriptDir(), configuration);
+
+ String capturedArgs = logTester.logs().stream().filter(log -> log.contains("Arguments Passed In:")).findFirst().get();
+ assertThat(capturedArgs).contains("--exclude .scannerwork/**");
+ }
+
+ @Test
+ void generateManifestsArchive_withNoScmIgnores_doesNotIncludeScmIgnoredPaths() throws Exception {
+ jGitUtilsMock.when(() -> JGitUtils.getAllIgnoredPaths(any(Path.class))).thenReturn(List.of());
+
+ underTest.generateManifestsArchive(rootInputModule, scriptDir(), configuration);
+
+ String capturedArgs = logTester.logs().stream().filter(log -> log.contains("Arguments Passed In:")).findFirst().get();
+ assertThat(capturedArgs).contains("--exclude .scannerwork/**");
+ }
+
+ @Test
+ void generateManifestsArchive_withExcludedManifests_appendsScmIgnoredPaths() throws Exception {
+ when(configuration.getStringArray(CliService.SCA_EXCLUSIONS_KEY)).thenReturn(new String[] {"**/test/**"});
+
+ underTest.generateManifestsArchive(rootInputModule, scriptDir(), configuration);
+
+ String capturedArgs = logTester.logs().stream().filter(log -> log.contains("Arguments Passed In:")).findFirst().get();
+ assertThat(capturedArgs).contains("--exclude **/test/**,ignored.txt,.scannerwork/**");
+ }
+
+ @Test
+ void generateManifestsArchive_withExcludedManifestsContainingBadCharacters_handlesTheBadCharacters() throws Exception {
+ when(configuration.getStringArray(CliService.SCA_EXCLUSIONS_KEY)).thenReturn(new String[] {
+ "**/test/**", "**/path with spaces/**", "**/path'with'quotes/**", "**/path\"with\"double\"quotes/**"});
+
+ underTest.generateManifestsArchive(rootInputModule, scriptDir(), configuration);
+
+ String capturedArgs = logTester.logs().stream().filter(log -> log.contains("Arguments Passed In:")).findFirst().get();
+
+ String expectedExcludeFlag = """
+ --exclude **/test/**,**/path with spaces/**,**/path'with'quotes/**,"**/path""with""double""quotes/**",ignored.txt
+ """.strip();
+ if (SystemUtils.IS_OS_WINDOWS) {
+ expectedExcludeFlag = """
+ --exclude "**/test/**,**/path with spaces/**,**/path'with'quotes/**,"**/path""with""double""quotes/**",ignored.txt
+ """.strip();
+ }
+ assertThat(capturedArgs).contains(expectedExcludeFlag);
+ }
+
+ @Test
+ void generateManifestsArchive_withExcludedManifestsContainingDupes_dedupes() throws Exception {
+ when(configuration.getStringArray(CliService.SCA_EXCLUSIONS_KEY)).thenReturn(new String[] {"**/test1/**", "**/test2/**", "**/test1/**"});
+ when(configuration.getStringArray(CliService.LEGACY_SCA_EXCLUSIONS_KEY)).thenReturn(new String[] {"**/test1/**", "**/test3/**"});
+
+ underTest.generateManifestsArchive(rootInputModule, scriptDir(), configuration);
+
+ String capturedArgs = logTester.logs().stream().filter(log -> log.contains("Arguments Passed In:")).findFirst().get();
+ assertThat(capturedArgs).contains("--exclude **/test1/**,**/test2/**,**/test3/**,ignored.txt,.scannerwork/**");
+ }
+
+ @Test
+ void generateManifestsArchive_withExcludedManifestsAndSonarExcludesContainingDupes_mergesAndDedupes() throws Exception {
+ when(projectExclusionFilters.getExclusionsConfig(InputFile.Type.MAIN)).thenReturn(new String[] {"**/test1/**", "**/test4/**"});
+ when(configuration.getStringArray(CliService.SCA_EXCLUSIONS_KEY)).thenReturn(new String[] {"**/test1/**", "**/test2/**", "**/test1/**"});
+ when(configuration.getStringArray(CliService.LEGACY_SCA_EXCLUSIONS_KEY)).thenReturn(new String[] {"**/test1/**", "**/test3/**"});
+
+ underTest.generateManifestsArchive(rootInputModule, scriptDir(), configuration);
+
+ String capturedArgs = logTester.logs().stream().filter(log -> log.contains("Arguments Passed In:")).findFirst().get();
+ assertThat(capturedArgs).contains("--exclude **/test1/**,**/test4/**,**/test2/**,**/test3/**,ignored.txt,.scannerwork/**");
+ }
+
+ @Test
+ void generateManifestsArchive_withScmIgnoresContainingBadCharacters_handlesTheBadCharacters() throws Exception {
+ jGitUtilsMock.when(() -> JGitUtils.getAllIgnoredPaths(any(Path.class)))
+ .thenReturn(List.of("**/test/**", "**/path with spaces/**", "**/path'with'quotes/**", "**/path\"with\"double\"quotes/**"));
+
+ underTest.generateManifestsArchive(rootInputModule, scriptDir(), configuration);
+
+ String capturedArgs = logTester.logs().stream().filter(log -> log.contains("Arguments Passed In:")).findFirst().get();
+
+ String expectedExcludeFlag = """
+ --exclude **/test/**,**/path with spaces/**,**/path'with'quotes/**,"**/path""with""double""quotes/**"
+ """.strip();
+ if (SystemUtils.IS_OS_WINDOWS) {
+ expectedExcludeFlag = """
+ --exclude "**/test/**,**/path with spaces/**,**/path'with'quotes/**,"**/path""with""double""quotes/**"
+ """.strip();
+ }
+ assertThat(capturedArgs).contains(expectedExcludeFlag);
+ }
+
+ @Test
+ void generateManifestsArchive_withIgnoredDirectories_GlobifiesDirectories() throws Exception {
+ String ignoredDirectory = "directory1";
+ Files.createDirectories(rootModuleDir.resolve(ignoredDirectory));
+ String ignoredFile = "directory2/file.txt";
+ Path ignoredFilePath = rootModuleDir.resolve(ignoredFile);
+ Files.createDirectories(ignoredFilePath.getParent());
+ Files.createFile(ignoredFilePath);
+
+ jGitUtilsMock.when(() -> JGitUtils.getAllIgnoredPaths(any(Path.class))).thenReturn(List.of(ignoredDirectory, ignoredFile));
+ underTest.generateManifestsArchive(rootInputModule, scriptDir(), configuration);
+
+ String capturedArgs = logTester.logs().stream().filter(log -> log.contains("Arguments Passed In:")).findFirst().get();
+ assertThat(capturedArgs).contains("--exclude directory1/**,directory2/file.txt");
+ }
+
+ @Test
+ void generateManifestsArchive_withExternalWorkDir_DoesNotExcludeWorkingDir() throws URISyntaxException, IOException {
+ Path externalWorkDir = Files.createTempDirectory("externalWorkDir");
+ try {
+ rootInputModule = new DefaultInputModule(ProjectDefinition.create().setBaseDir(rootModuleDir.toFile()).setWorkDir(externalWorkDir.toFile()));
+ underTest.generateManifestsArchive(rootInputModule, scriptDir(), configuration);
+ String capturedArgs = logTester.logs().stream().filter(log -> log.contains("Arguments Passed In:")).findFirst().get();
+
+ // externalWorkDir is not present in the exclude flag
+ assertThat(capturedArgs).contains("--exclude ignored.txt");
+ } finally {
+ externalWorkDir.toFile().delete();
+ }
+ }
+
+ private URL scriptUrl() {
+ // There is a custom test Bash script available in src/test/resources/org/sonar/scanner/sca that
+ // will serve as our "CLI". This script will output some messages about what arguments were passed
+ // to it and will try to generate an archive file in the location the process specifies. This allows us
+ // to simulate a real CLI call without needing an OS specific CLI executable to run on a real project.
+ URL scriptUrl = CliServiceTest.class.getResource(SystemUtils.IS_OS_WINDOWS ? "echo_args.bat" : "echo_args.sh");
+ assertThat(scriptUrl).isNotNull();
+ return scriptUrl;
+ }
+
+ private File scriptDir() throws URISyntaxException {
+ return new File(scriptUrl().toURI());
+ }
+}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sca/ScaExecutorTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sca/ScaExecutorTest.java
new file mode 100644
index 00000000000..ebe6007a1c1
--- /dev/null
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sca/ScaExecutorTest.java
@@ -0,0 +1,180 @@
+/*
+ * 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.sca;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Optional;
+import org.assertj.core.util.Files;
+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.slf4j.event.Level;
+import org.sonar.api.batch.bootstrap.ProjectDefinition;
+import org.sonar.api.batch.fs.internal.DefaultInputModule;
+import org.sonar.api.testfixtures.log.LogTesterJUnit5;
+import org.sonar.scanner.config.DefaultConfiguration;
+import org.sonar.scanner.protocol.output.ScannerReportWriter;
+import org.sonar.scanner.report.ReportPublisher;
+import org.sonar.scanner.repository.featureflags.FeatureFlagsRepository;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoInteractions;
+import static org.mockito.Mockito.when;
+
+class ScaExecutorTest {
+ private final CliService cliService = mock(CliService.class);
+ private final CliCacheService cliCacheService = mock(CliCacheService.class);
+ private final ReportPublisher reportPublisher = mock(ReportPublisher.class);
+ private final FeatureFlagsRepository featureFlagsRepository = mock(FeatureFlagsRepository.class);
+ private final DefaultConfiguration configuration = mock(DefaultConfiguration.class);
+ @RegisterExtension
+ private final LogTesterJUnit5 logTester = new LogTesterJUnit5();
+ private final ScaExecutor underTest = new ScaExecutor(cliCacheService, cliService, reportPublisher, featureFlagsRepository, configuration);
+ @TempDir
+ File rootModuleDir;
+ private DefaultInputModule root;
+
+ @BeforeEach
+ void before() {
+ when(featureFlagsRepository.isEnabled("sca")).thenReturn(true);
+ root = new DefaultInputModule(
+ ProjectDefinition.create().setBaseDir(rootModuleDir).setWorkDir(rootModuleDir.toPath().getRoot().toFile()));
+ }
+
+ @Test
+ void execute_shouldCallCliAndPublisher() throws IOException {
+ File mockCliFile = Files.newTemporaryFile();
+ File mockManifestZip = Files.newTemporaryFile();
+ ScannerReportWriter mockReportWriter = mock(ScannerReportWriter.class);
+ when(cliCacheService.cacheCli()).thenReturn(mockCliFile);
+ when(cliService.generateManifestsArchive(root, mockCliFile, configuration)).thenReturn(mockManifestZip);
+ when(reportPublisher.getWriter()).thenReturn(mockReportWriter);
+
+ logTester.setLevel(Level.DEBUG);
+
+ underTest.execute(root);
+
+ verify(cliService).generateManifestsArchive(root, mockCliFile, configuration);
+ verify(mockReportWriter).writeScaFile(mockManifestZip);
+ assertThat(logTester.logs(Level.DEBUG)).contains("Zip ready for report: " + mockManifestZip);
+ assertThat(logTester.logs(Level.DEBUG)).contains("Manifest zip written to report");
+ }
+
+ @Test
+ void execute_whenIOException_shouldHandleException() throws IOException {
+ File mockCliFile = Files.newTemporaryFile();
+ when(cliCacheService.cacheCli()).thenReturn(mockCliFile);
+ doThrow(IOException.class).when(cliService).generateManifestsArchive(root, mockCliFile, configuration);
+
+ logTester.setLevel(Level.INFO);
+
+ underTest.execute(root);
+
+ verify(cliService).generateManifestsArchive(root, mockCliFile, configuration);
+ assertThat(logTester.logs(Level.ERROR)).contains("Error gathering manifests");
+ }
+
+ @Test
+ void execute_whenIllegalStateException_shouldHandleException() throws IOException {
+ File mockCliFile = Files.newTemporaryFile();
+ when(cliCacheService.cacheCli()).thenReturn(mockCliFile);
+ doThrow(IllegalStateException.class).when(cliService).generateManifestsArchive(root, mockCliFile, configuration);
+
+ logTester.setLevel(Level.INFO);
+
+ underTest.execute(root);
+
+ verify(cliService).generateManifestsArchive(root, mockCliFile, configuration);
+ assertThat(logTester.logs(Level.ERROR)).contains("Error gathering manifests");
+ }
+
+ @Test
+ void execute_whenNoCliFound_shouldSkipAnalysis() throws IOException {
+ File mockCliFile = new File("");
+ when(cliCacheService.cacheCli()).thenReturn(mockCliFile);
+
+ underTest.execute(root);
+
+ verify(cliService, never()).generateManifestsArchive(root, mockCliFile, configuration);
+ }
+
+ @Test
+ void execute_whenGlobalFeatureDisabled_skips() {
+ when(featureFlagsRepository.isEnabled("sca")).thenReturn(false);
+ logTester.setLevel(Level.DEBUG);
+
+ underTest.execute(root);
+
+ assertThat(logTester.logs()).contains("Dependency analysis skipped");
+ verifyNoInteractions(cliService, cliCacheService);
+ }
+
+ @Test
+ void execute_whenProjectPropertyDisabled_skips() {
+ when(configuration.getBoolean("sonar.sca.enabled")).thenReturn(Optional.of(false));
+ logTester.setLevel(Level.DEBUG);
+
+ underTest.execute(root);
+
+ assertThat(logTester.logs()).contains("Dependency analysis disabled for this project");
+ verifyNoInteractions(cliService, cliCacheService);
+ }
+
+ @Test
+ void execute_whenProjectPropertyExplicitlyEnabled_CallsCli() throws IOException {
+ when(configuration.getBoolean("sonar.sca.enabled")).thenReturn(Optional.of(true));
+ File mockCliFile = Files.newTemporaryFile();
+ File mockManifestZip = Files.newTemporaryFile();
+ ScannerReportWriter mockReportWriter = mock(ScannerReportWriter.class);
+ when(cliCacheService.cacheCli()).thenReturn(mockCliFile);
+ when(cliService.generateManifestsArchive(root, mockCliFile, configuration)).thenReturn(mockManifestZip);
+ when(reportPublisher.getWriter()).thenReturn(mockReportWriter);
+ logTester.setLevel(Level.DEBUG);
+
+ underTest.execute(root);
+
+ verify(cliService).generateManifestsArchive(root, mockCliFile, configuration);
+ verify(mockReportWriter).writeScaFile(mockManifestZip);
+ assertThat(logTester.logs(Level.DEBUG)).contains("Zip ready for report: " + mockManifestZip);
+ assertThat(logTester.logs(Level.DEBUG)).contains("Manifest zip written to report");
+ }
+
+ @Test
+ void execute_printsRuntime() throws IOException {
+ File mockCliFile = Files.newTemporaryFile();
+ File mockManifestZip = Files.newTemporaryFile();
+ ScannerReportWriter mockReportWriter = mock(ScannerReportWriter.class);
+ when(cliCacheService.cacheCli()).thenReturn(mockCliFile);
+ when(cliService.generateManifestsArchive(root, mockCliFile, configuration)).thenReturn(mockManifestZip);
+ when(reportPublisher.getWriter()).thenReturn(mockReportWriter);
+
+ logTester.setLevel(Level.INFO);
+
+ underTest.execute(root);
+
+ assertThat(logTester.logs(Level.INFO)).anyMatch(l -> l.matches("Load SCA project dependencies \\(done\\) \\| time=\\d+ms"));
+ }
+}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sca/ScaPropertiesTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sca/ScaPropertiesTest.java
new file mode 100644
index 00000000000..70e7a6b6e53
--- /dev/null
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sca/ScaPropertiesTest.java
@@ -0,0 +1,100 @@
+/*
+ * 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.sca;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+import org.junit.jupiter.api.Test;
+import org.sonar.scanner.config.DefaultConfiguration;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+class ScaPropertiesTest {
+ private final DefaultConfiguration configuration = mock(DefaultConfiguration.class);
+
+ @Test
+ void buildFromScannerProperties_withNoProperties_returnsEmptyMap() {
+ when(configuration.get(anyString())).thenReturn(Optional.empty());
+
+ var result = ScaProperties.buildFromScannerProperties(configuration);
+
+ assertThat(result).isEqualTo(Map.of());
+ }
+
+ @Test
+ void buildFromScannerProperties_withUnmappedProperties_ignoresProperties() {
+ var inputProperties = new HashMap<String, String>();
+ inputProperties.put("sonar.sca.pythonBinary", "/usr/bin/python3");
+ inputProperties.put("sonar.sca.unknownProperty", "value");
+ inputProperties.put("sonar.somethingElse", "dont-include-non-sca");
+ inputProperties.put("sonar.sca.recursiveManifestSearch", "ignore-me");
+ when(configuration.getProperties()).thenReturn(inputProperties);
+ when(configuration.get(anyString())).thenAnswer(i -> Optional.ofNullable(inputProperties.get(i.getArgument(0, String.class))));
+
+ var result = ScaProperties.buildFromScannerProperties(configuration);
+
+ assertThat(result).containsExactly(
+ Map.entry("TIDELIFT_PYTHON_BINARY", "/usr/bin/python3"),
+ Map.entry("TIDELIFT_UNKNOWN_PROPERTY", "value"));
+ }
+
+ @Test
+ void buildFromScannerProperties_withLotsOfProperties_mapsAllProperties() {
+ var inputProperties = new HashMap<String, String>();
+ inputProperties.put("sonar.sca.goNoResolve", "true");
+ inputProperties.put("sonar.sca.gradleConfigurationPattern", "pattern");
+ inputProperties.put("sonar.sca.gradleNoResolve", "false");
+ inputProperties.put("sonar.sca.mavenForceDepPlugin", "plugin");
+ inputProperties.put("sonar.sca.mavenNoResolve", "true");
+ inputProperties.put("sonar.sca.mavenIgnoreWrapper", "false");
+ inputProperties.put("sonar.sca.mavenOptions", "-DskipTests");
+ inputProperties.put("sonar.sca.npmEnableScripts", "true");
+ inputProperties.put("sonar.sca.npmNoResolve", "true");
+ inputProperties.put("sonar.sca.nugetNoResolve", "false");
+ inputProperties.put("sonar.sca.pythonBinary", "/usr/bin/python3");
+ inputProperties.put("sonar.sca.pythonNoResolve", "true");
+ inputProperties.put("sonar.sca.pythonResolveLocal", "false");
+ when(configuration.getProperties()).thenReturn(inputProperties);
+ when(configuration.get(anyString())).thenAnswer(i -> Optional.ofNullable(inputProperties.get(i.getArgument(0, String.class))));
+
+ var expectedProperties = new HashMap<String, String>();
+ expectedProperties.put("TIDELIFT_GO_NO_RESOLVE", "true");
+ expectedProperties.put("TIDELIFT_GRADLE_CONFIGURATION_PATTERN", "pattern");
+ expectedProperties.put("TIDELIFT_GRADLE_NO_RESOLVE", "false");
+ expectedProperties.put("TIDELIFT_MAVEN_FORCE_DEP_PLUGIN", "plugin");
+ expectedProperties.put("TIDELIFT_MAVEN_NO_RESOLVE", "true");
+ expectedProperties.put("TIDELIFT_MAVEN_IGNORE_WRAPPER", "false");
+ expectedProperties.put("TIDELIFT_MAVEN_OPTIONS", "-DskipTests");
+ expectedProperties.put("TIDELIFT_NPM_ENABLE_SCRIPTS", "true");
+ expectedProperties.put("TIDELIFT_NPM_NO_RESOLVE", "true");
+ expectedProperties.put("TIDELIFT_NUGET_NO_RESOLVE", "false");
+ expectedProperties.put("TIDELIFT_PYTHON_BINARY", "/usr/bin/python3");
+ expectedProperties.put("TIDELIFT_PYTHON_NO_RESOLVE", "true");
+ expectedProperties.put("TIDELIFT_PYTHON_RESOLVE_LOCAL", "false");
+
+ var result = ScaProperties.buildFromScannerProperties(configuration);
+
+ assertThat(result).containsExactlyInAnyOrderEntriesOf(expectedProperties);
+ }
+}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/DefaultInputModuleHierarchyTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/DefaultInputModuleHierarchyTest.java
index b1f7b42910e..3eab59b4c47 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/DefaultInputModuleHierarchyTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/DefaultInputModuleHierarchyTest.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/test/java/org/sonar/scanner/scan/DeprecatedPropertiesWarningGeneratorTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/DeprecatedPropertiesWarningGeneratorTest.java
index 3e9a49706c5..97697a601dd 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/DeprecatedPropertiesWarningGeneratorTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/DeprecatedPropertiesWarningGeneratorTest.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
@@ -36,7 +36,6 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.when;
import static org.sonar.scanner.scan.DeprecatedPropertiesWarningGenerator.LOGIN_WARN_MESSAGE;
-import static org.sonar.scanner.scan.DeprecatedPropertiesWarningGenerator.PASSWORD_WARN_MESSAGE;
import static org.sonar.scanner.scan.DeprecatedPropertiesWarningGenerator.SCANNER_DOTNET_WARN_MESSAGE;
public class DeprecatedPropertiesWarningGeneratorTest {
@@ -54,7 +53,6 @@ public class DeprecatedPropertiesWarningGeneratorTest {
@Before
public void setUp() throws Exception {
settings.removeProperty(CoreProperties.LOGIN);
- settings.removeProperty(CoreProperties.PASSWORD);
when(environmentInformation.getKey()).thenReturn("ScannerCLI");
}
@@ -69,17 +67,6 @@ public class DeprecatedPropertiesWarningGeneratorTest {
}
@Test
- public void execute_whenUsingPassword_shouldAddWarning() {
- settings.setProperty(CoreProperties.LOGIN, "test");
- settings.setProperty(CoreProperties.PASSWORD, "winner winner chicken dinner");
-
- underTest.execute();
-
- verify(analysisWarnings, times(1)).addUnique(PASSWORD_WARN_MESSAGE);
- Assertions.assertThat(logger.logs(Level.WARN)).contains(PASSWORD_WARN_MESSAGE);
- }
-
- @Test
public void execute_whenUsingLoginAndDotNetScanner_shouldAddWarning() {
settings.setProperty(CoreProperties.LOGIN, "test");
when(environmentInformation.getKey()).thenReturn("ScannerMSBuild");
@@ -91,18 +78,6 @@ public class DeprecatedPropertiesWarningGeneratorTest {
}
@Test
- public void execute_whenUsingPasswordAndDotNetScanner_shouldAddWarning() {
- settings.setProperty(CoreProperties.LOGIN, "test");
- settings.setProperty(CoreProperties.PASSWORD, "winner winner chicken dinner");
- when(environmentInformation.getKey()).thenReturn("ScannerMSBuild");
-
- underTest.execute();
-
- verify(analysisWarnings, times(1)).addUnique(PASSWORD_WARN_MESSAGE + SCANNER_DOTNET_WARN_MESSAGE);
- Assertions.assertThat(logger.logs(Level.WARN)).contains(PASSWORD_WARN_MESSAGE + SCANNER_DOTNET_WARN_MESSAGE);
- }
-
- @Test
public void execute_whenNotUsingLoginOrPassword_shouldNotAddWarning() {
underTest.execute();
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/DirectoryLockTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/DirectoryLockTest.java
index 62a5dbf33cc..e247685c8a0 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/DirectoryLockTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/DirectoryLockTest.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/test/java/org/sonar/scanner/scan/ModuleConfigurationProviderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ModuleConfigurationProviderTest.java
index 80cab3a8a5c..338d553629d 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ModuleConfigurationProviderTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ModuleConfigurationProviderTest.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/test/java/org/sonar/scanner/scan/ModuleIndexerTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ModuleIndexerTest.java
index a66ed1f1456..0f586d09513 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ModuleIndexerTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ModuleIndexerTest.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/test/java/org/sonar/scanner/scan/ProjectBuildersExecutorTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ProjectBuildersExecutorTest.java
index 347c8072810..b755d6a882b 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ProjectBuildersExecutorTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ProjectBuildersExecutorTest.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/test/java/org/sonar/scanner/scan/ProjectConfigurationProviderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ProjectConfigurationProviderTest.java
index e2e1b9d84cd..3e3066e76e2 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ProjectConfigurationProviderTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ProjectConfigurationProviderTest.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
@@ -52,10 +52,9 @@ public class ProjectConfigurationProviderTest {
private static final Map<String, String> PROJECT_SERVER_PROPERTIES = Map.of(NON_GLOBAL_KEY_PROPERTIES_1, NON_GLOBAL_VALUE_PROPERTIES_1);
private static final Map<String, String> DEFAULT_PROJECT_PROPERTIES = Map.of(DEFAULT_KEY_PROPERTIES_1, DEFAULT_VALUE_1);
- private static final Map<String, String> ALL_PROPERTIES_MAP =
- Stream.of(GLOBAL_SERVER_PROPERTIES, PROJECT_SERVER_PROPERTIES, DEFAULT_PROJECT_PROPERTIES)
- .flatMap(map -> map.entrySet().stream())
- .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
+ private static final Map<String, String> ALL_PROPERTIES_MAP = Stream.of(GLOBAL_SERVER_PROPERTIES, PROJECT_SERVER_PROPERTIES, DEFAULT_PROJECT_PROPERTIES)
+ .flatMap(map -> map.entrySet().stream())
+ .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
private static final Map<String, String> PROPERTIES_AFTER_FILTERING = Map.of("aKey", "aValue");
@@ -66,8 +65,6 @@ public class ProjectConfigurationProviderTest {
@Mock
private GlobalConfiguration globalConfiguration;
@Mock
- private MutableProjectSettings mutableProjectSettings;
- @Mock
private DefaultInputProject defaultInputProject;
@Mock
private SonarGlobalPropertiesFilter sonarGlobalPropertiesFilter;
@@ -75,7 +72,6 @@ public class ProjectConfigurationProviderTest {
@InjectMocks
private ProjectConfigurationProvider provider;
-
@Before
public void init() {
when(globalConfiguration.getDefinitions()).thenReturn(new PropertyDefinitions(System2.INSTANCE));
@@ -89,11 +85,11 @@ public class ProjectConfigurationProviderTest {
when(sonarGlobalPropertiesFilter.enforceOnlyServerSideSonarGlobalPropertiesAreUsed(ALL_PROPERTIES_MAP, GLOBAL_SERVER_PROPERTIES))
.thenReturn(PROPERTIES_AFTER_FILTERING);
- ProjectConfiguration provide = provider.provide(defaultInputProject, globalConfiguration, globalServerSettings, projectServerSettings, mutableProjectSettings);
+ ProjectConfiguration provide = provider.provide(defaultInputProject, globalConfiguration, globalServerSettings, projectServerSettings);
verify(sonarGlobalPropertiesFilter).enforceOnlyServerSideSonarGlobalPropertiesAreUsed(ALL_PROPERTIES_MAP, GLOBAL_SERVER_PROPERTIES);
assertThat(provide.getOriginalProperties()).containsExactlyEntriesOf(PROPERTIES_AFTER_FILTERING);
}
-} \ No newline at end of file
+}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ProjectLockTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ProjectLockTest.java
index efe60b25106..d84723632a7 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ProjectLockTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ProjectLockTest.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/test/java/org/sonar/scanner/scan/ProjectReactorBuilderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ProjectReactorBuilderTest.java
index 4092d2f7e0f..ae4d32d4456 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ProjectReactorBuilderTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ProjectReactorBuilderTest.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/test/java/org/sonar/scanner/scan/ProjectReactorValidatorTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ProjectReactorValidatorTest.java
index 40d785b4c51..4fd7165ce77 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ProjectReactorValidatorTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ProjectReactorValidatorTest.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/test/java/org/sonar/scanner/scan/ScanPropertiesTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ScanPropertiesTest.java
index 37f15a87a71..3de53c7a56a 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ScanPropertiesTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ScanPropertiesTest.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
@@ -99,4 +99,24 @@ public class ScanPropertiesTest {
.isInstanceOf(MessageException.class)
.hasMessage("Property 'sonar.scanner.metadataFilePath' must point to an absolute path: relative");
}
+
+ @Test
+ public void validate_fails_if_sonar_branch_is_set() {
+ settings.setProperty("sonar.branch", "anything");
+
+ assertThatThrownBy(underTest::validate)
+ .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
+ public void validate_fails_if_sonar_password_is_set() {
+ settings.setProperty("sonar.password", "anything");
+
+ assertThatThrownBy(underTest::validate)
+ .isInstanceOf(MessageException.class)
+ .hasMessage("The property 'sonar.password' is no longer supported. " +
+ "Please pass a token with the 'sonar.token' property instead.");
+ }
}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/SonarGlobalPropertiesFilterTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/SonarGlobalPropertiesFilterTest.java
index 5f08e31817c..6a09d11947f 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/SonarGlobalPropertiesFilterTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/SonarGlobalPropertiesFilterTest.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/test/java/org/sonar/scanner/scan/SpringProjectScanContainerTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/SpringProjectScanContainerTest.java
index 3f02637c302..4a0d8210400 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/SpringProjectScanContainerTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/SpringProjectScanContainerTest.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/test/java/org/sonar/scanner/scan/WorkDirectoriesInitializerTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/WorkDirectoriesInitializerTest.java
index d402acc42bb..542a50c4e9c 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/WorkDirectoriesInitializerTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/WorkDirectoriesInitializerTest.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/test/java/org/sonar/scanner/scan/branch/BranchConfigurationProviderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/branch/BranchConfigurationProviderTest.java
index 7dc853b3b23..9b96e828e37 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/branch/BranchConfigurationProviderTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/branch/BranchConfigurationProviderTest.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/test/java/org/sonar/scanner/scan/branch/ProjectBranchesProviderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/branch/ProjectBranchesProviderTest.java
index 6e11f10364d..89dd5f16146 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/branch/ProjectBranchesProviderTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/branch/ProjectBranchesProviderTest.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/test/java/org/sonar/scanner/scan/branch/ProjectBranchesTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/branch/ProjectBranchesTest.java
index 050dddafbdd..4ccd66fb6d5 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/branch/ProjectBranchesTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/branch/ProjectBranchesTest.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/test/java/org/sonar/scanner/scan/filesystem/AbstractExclusionFiltersTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/AbstractExclusionFiltersTest.java
index fc039bc675c..faea9c001fe 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/AbstractExclusionFiltersTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/AbstractExclusionFiltersTest.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/test/java/org/sonar/scanner/scan/filesystem/AdditionalFilePredicatesTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/AdditionalFilePredicatesTest.java
index 03759916869..270cd42dbf8 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/AdditionalFilePredicatesTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/AdditionalFilePredicatesTest.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/test/java/org/sonar/scanner/scan/filesystem/ByteCharsetDetectorTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ByteCharsetDetectorTest.java
index 59d0a292e35..d5f384440c3 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ByteCharsetDetectorTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ByteCharsetDetectorTest.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/test/java/org/sonar/scanner/scan/filesystem/CharsetDetectorTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/CharsetDetectorTest.java
index 64d7a67e1f3..5cfeb8f1851 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/CharsetDetectorTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/CharsetDetectorTest.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/test/java/org/sonar/scanner/scan/filesystem/CharsetValidationTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/CharsetValidationTest.java
index 382eae972e8..437e7ab2014 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/CharsetValidationTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/CharsetValidationTest.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/test/java/org/sonar/scanner/scan/filesystem/DirectoryFileVisitorTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/DirectoryFileVisitorTest.java
index 59bc00a3654..277fc0dc68a 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/DirectoryFileVisitorTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/DirectoryFileVisitorTest.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
@@ -27,20 +27,26 @@ import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
+import java.util.Optional;
import org.apache.commons.lang3.SystemUtils;
+import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.internal.DefaultInputModule;
+import org.sonar.scanner.bootstrap.SonarUserHome;
import org.sonar.scanner.fs.InputModuleHierarchy;
+import org.sonar.scanner.scan.ModuleConfiguration;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
public class DirectoryFileVisitorTest {
@@ -48,33 +54,57 @@ public class DirectoryFileVisitorTest {
public static TemporaryFolder temp = new TemporaryFolder();
private final DefaultInputModule module = mock();
+ private final ModuleConfiguration moduleConfiguration = mock();
private final ModuleExclusionFilters moduleExclusionFilters = mock();
private final InputModuleHierarchy inputModuleHierarchy = mock();
private final InputFile.Type type = mock();
+ private final SonarUserHome sonarUserHome = mock();
+ private HiddenFilesProjectData hiddenFilesProjectData;
+
+ @Before
+ public void before() throws IOException {
+ Path sonarUserHomePath = temp.newFolder().toPath();
+ when(sonarUserHome.getPath()).thenReturn(sonarUserHomePath);
+ File workDir = temp.newFolder();
+ when(module.getWorkDir()).thenReturn(workDir.toPath());
+ hiddenFilesProjectData = spy(new HiddenFilesProjectData(sonarUserHome));
+ }
@Test
- public void visit_hidden_file() throws IOException {
+ public void should_not_visit_hidden_file() throws IOException {
+ when(moduleConfiguration.getBoolean("sonar.scanner.excludeHiddenFiles")).thenReturn(Optional.of(true));
DirectoryFileVisitor.FileVisitAction action = mock(DirectoryFileVisitor.FileVisitAction.class);
- File hidden = temp.newFile(".hidden");
- if (SystemUtils.IS_OS_WINDOWS) {
- Files.setAttribute(hidden.toPath(), "dos:hidden", true, LinkOption.NOFOLLOW_LINKS);
- }
-
+ File hidden = temp.newFile(".hiddenNotVisited");
+ setAsHiddenOnWindows(hidden);
- DirectoryFileVisitor underTest = new DirectoryFileVisitor(action, module, moduleExclusionFilters, inputModuleHierarchy, type);
+ DirectoryFileVisitor underTest = new DirectoryFileVisitor(action, module, moduleConfiguration, moduleExclusionFilters, inputModuleHierarchy, type, hiddenFilesProjectData);
underTest.visitFile(hidden.toPath(), Files.readAttributes(hidden.toPath(), BasicFileAttributes.class));
verify(action, never()).execute(any(Path.class));
}
@Test
+ public void should_visit_hidden_file() throws IOException {
+ when(moduleConfiguration.getBoolean("sonar.scanner.excludeHiddenFiles")).thenReturn(Optional.of(false));
+ DirectoryFileVisitor.FileVisitAction action = mock(DirectoryFileVisitor.FileVisitAction.class);
+
+ File hidden = temp.newFile(".hiddenVisited");
+ setAsHiddenOnWindows(hidden);
+
+ DirectoryFileVisitor underTest = new DirectoryFileVisitor(action, module, moduleConfiguration, moduleExclusionFilters, inputModuleHierarchy, type, hiddenFilesProjectData);
+ underTest.visitFile(hidden.toPath(), Files.readAttributes(hidden.toPath(), BasicFileAttributes.class));
+
+ verify(action).execute(any(Path.class));
+ }
+
+ @Test
public void test_visit_file_failed_generic_io_exception() throws IOException {
DirectoryFileVisitor.FileVisitAction action = mock(DirectoryFileVisitor.FileVisitAction.class);
File file = temp.newFile("failed");
- DirectoryFileVisitor underTest = new DirectoryFileVisitor(action, module, moduleExclusionFilters, inputModuleHierarchy, type);
+ DirectoryFileVisitor underTest = new DirectoryFileVisitor(action, module, moduleConfiguration, moduleExclusionFilters, inputModuleHierarchy, type, hiddenFilesProjectData);
assertThrows(IOException.class, () -> underTest.visitFileFailed(file.toPath(), new IOException()));
}
@@ -84,10 +114,15 @@ public class DirectoryFileVisitorTest {
File file = temp.newFile("symlink");
- DirectoryFileVisitor underTest = new DirectoryFileVisitor(action, module, moduleExclusionFilters, inputModuleHierarchy, type);
+ DirectoryFileVisitor underTest = new DirectoryFileVisitor(action, module, moduleConfiguration, moduleExclusionFilters, inputModuleHierarchy, type, hiddenFilesProjectData);
FileVisitResult result = underTest.visitFileFailed(file.toPath(), new FileSystemLoopException(file.getPath()));
assertThat(result).isEqualTo(FileVisitResult.CONTINUE);
}
+ private static void setAsHiddenOnWindows(File file) throws IOException {
+ if (SystemUtils.IS_OS_WINDOWS) {
+ Files.setAttribute(file.toPath(), "dos:hidden", true, LinkOption.NOFOLLOW_LINKS);
+ }
+ }
}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/HiddenFilesProjectDataTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/HiddenFilesProjectDataTest.java
new file mode 100644
index 00000000000..d5a6e4ff843
--- /dev/null
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/HiddenFilesProjectDataTest.java
@@ -0,0 +1,160 @@
+/*
+ * 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.scan.filesystem;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.LinkOption;
+import java.nio.file.Path;
+import org.apache.commons.lang3.SystemUtils;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.sonar.api.batch.fs.internal.DefaultInputModule;
+import org.sonar.scanner.bootstrap.SonarUserHome;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+public class HiddenFilesProjectDataTest {
+
+ @ClassRule
+ public static TemporaryFolder temp = new TemporaryFolder();
+
+ private static final SonarUserHome sonarUserHome = mock(SonarUserHome.class);
+ private final DefaultInputModule inputModule = mock(DefaultInputModule.class);
+ private final DefaultInputModule secondInputModule = mock(DefaultInputModule.class);
+ private HiddenFilesProjectData underTest;
+
+ @BeforeClass
+ public static void setUp() throws IOException {
+ File userHomeFolder = temp.newFolder(".userhome");
+ setAsHiddenOnWindows(userHomeFolder);
+ when(sonarUserHome.getPath()).thenReturn(userHomeFolder.toPath());
+ }
+
+ @Before
+ public void before() {
+ underTest = spy(new HiddenFilesProjectData(sonarUserHome));
+ }
+
+ @Test
+ public void shouldContainNoMarkedHiddenFileOnConstruction() {
+ assertThat(underTest.hiddenFilesByModule).isEmpty();
+ }
+
+ @Test
+ public void shouldMarkWithCorrectAssociatedInputModule() {
+ Path myFile = Path.of("myFile");
+ Path myFile2 = Path.of("myFile2");
+ underTest.markAsHiddenFile(myFile, inputModule);
+ underTest.markAsHiddenFile(myFile2, inputModule);
+
+ assertThat(underTest.hiddenFilesByModule).hasSize(1);
+ assertThat(underTest.getIsMarkedAsHiddenFileAndRemoveVisibilityInformation(myFile, inputModule)).isTrue();
+ assertThat(underTest.getIsMarkedAsHiddenFileAndRemoveVisibilityInformation(myFile2, inputModule)).isTrue();
+ assertThat(underTest.getIsMarkedAsHiddenFileAndRemoveVisibilityInformation(myFile, secondInputModule)).isFalse();
+ assertThat(underTest.getIsMarkedAsHiddenFileAndRemoveVisibilityInformation(myFile2, secondInputModule)).isFalse();
+ }
+
+ @Test
+ public void shouldMarkWithCorrectAssociatedInputModuleForTwoDifferentModules() {
+ Path myFile = Path.of("myFile");
+ Path myFile2 = Path.of("myFile2");
+ underTest.markAsHiddenFile(myFile, inputModule);
+ underTest.markAsHiddenFile(myFile2, secondInputModule);
+
+ assertThat(underTest.hiddenFilesByModule).hasSize(2);
+ assertThat(underTest.getIsMarkedAsHiddenFileAndRemoveVisibilityInformation(myFile, inputModule)).isTrue();
+ assertThat(underTest.getIsMarkedAsHiddenFileAndRemoveVisibilityInformation(myFile2, inputModule)).isFalse();
+ assertThat(underTest.getIsMarkedAsHiddenFileAndRemoveVisibilityInformation(myFile, secondInputModule)).isFalse();
+ assertThat(underTest.getIsMarkedAsHiddenFileAndRemoveVisibilityInformation(myFile2, secondInputModule)).isTrue();
+ }
+
+ @Test
+ public void shouldNotShowAsHiddenFileWhenInputModuleIsNotExistingInData() {
+ Path myFile = Path.of("myFile");
+ Path notMarkedFile = Path.of("notMarkedFile");
+ underTest.markAsHiddenFile(myFile, inputModule);
+
+ assertThat(underTest.hiddenFilesByModule).isNotEmpty();
+ assertThat(underTest.getIsMarkedAsHiddenFileAndRemoveVisibilityInformation(notMarkedFile, secondInputModule)).isFalse();
+ }
+
+ @Test
+ public void shouldClearMap() {
+ Path myFile = Path.of("myFile");
+ Path myFile2 = Path.of("myFile2");
+ underTest.markAsHiddenFile(myFile, inputModule);
+ underTest.markAsHiddenFile(myFile2, secondInputModule);
+
+ assertThat(underTest.hiddenFilesByModule).hasSize(2);
+
+ underTest.clearHiddenFilesData();
+ assertThat(underTest.hiddenFilesByModule).isEmpty();
+ }
+
+ @Test
+ public void shouldRemoveVisibilityAfterQuerying() {
+ Path myFile = Path.of("myFile");
+ Path myFile2 = Path.of("myFile2");
+ underTest.markAsHiddenFile(myFile, inputModule);
+ underTest.markAsHiddenFile(myFile2, inputModule);
+
+ assertThat(underTest.hiddenFilesByModule).hasSize(1);
+ assertThat(underTest.getIsMarkedAsHiddenFileAndRemoveVisibilityInformation(myFile, inputModule)).isTrue();
+ assertThat(underTest.getIsMarkedAsHiddenFileAndRemoveVisibilityInformation(myFile2, inputModule)).isTrue();
+
+ assertThat(underTest.hiddenFilesByModule).hasSize(1);
+ assertThat(underTest.hiddenFilesByModule.get(inputModule)).isEmpty();
+ assertThat(underTest.getIsMarkedAsHiddenFileAndRemoveVisibilityInformation(myFile, inputModule)).isFalse();
+ assertThat(underTest.getIsMarkedAsHiddenFileAndRemoveVisibilityInformation(myFile2, inputModule)).isFalse();
+ }
+
+ @Test
+ public void shouldOnlyRemoveModuleIfAllFilesAreRemoved() {
+ Path myFile = Path.of("myFile");
+ Path myFile2 = Path.of("myFile2");
+ underTest.markAsHiddenFile(myFile, inputModule);
+ underTest.markAsHiddenFile(myFile2, inputModule);
+
+ assertThat(underTest.hiddenFilesByModule).hasSize(1);
+ assertThat(underTest.getIsMarkedAsHiddenFileAndRemoveVisibilityInformation(myFile, inputModule)).isTrue();
+
+ assertThat(underTest.hiddenFilesByModule).isNotEmpty();
+ }
+
+ @Test
+ public void shouldNotFailOnUserPathResolving() throws IOException {
+ Path expectedPath = sonarUserHome.getPath().toRealPath(LinkOption.NOFOLLOW_LINKS).toAbsolutePath().normalize();
+ assertThat(underTest.getCachedSonarUserHomePath()).isEqualTo(expectedPath);
+ }
+
+ private static void setAsHiddenOnWindows(File file) throws IOException {
+ if (SystemUtils.IS_OS_WINDOWS) {
+ Files.setAttribute(file.toPath(), "dos:hidden", true, LinkOption.NOFOLLOW_LINKS);
+ }
+ }
+}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/HiddenFilesVisitorHelperTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/HiddenFilesVisitorHelperTest.java
new file mode 100644
index 00000000000..8c111c7ea15
--- /dev/null
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/HiddenFilesVisitorHelperTest.java
@@ -0,0 +1,315 @@
+/*
+ * 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.scan.filesystem;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.LinkOption;
+import java.nio.file.Path;
+import java.util.Optional;
+import org.apache.commons.lang3.SystemUtils;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.sonar.api.batch.fs.internal.DefaultInputModule;
+import org.sonar.scanner.bootstrap.SonarUserHome;
+import org.sonar.scanner.scan.ModuleConfiguration;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class HiddenFilesVisitorHelperTest {
+
+ @ClassRule
+ public static TemporaryFolder temp = new TemporaryFolder();
+
+ private static final SonarUserHome sonarUserHome = mock(SonarUserHome.class);
+ private static final DefaultInputModule inputModule = mock(DefaultInputModule.class);
+
+ private final ModuleConfiguration moduleConfig = mock(ModuleConfiguration.class);
+ private final HiddenFilesProjectData hiddenFilesProjectData = spy(new HiddenFilesProjectData(sonarUserHome));
+ private HiddenFilesVisitorHelper underTest;
+
+ @BeforeClass
+ public static void setUp() throws IOException {
+ File userHomeFolder = temp.newFolder(".userhome");
+ setAsHiddenOnWindows(userHomeFolder);
+ when(sonarUserHome.getPath()).thenReturn(userHomeFolder.toPath());
+
+ File workDir = temp.newFolder(".sonar");
+ setAsHiddenOnWindows(workDir);
+ when(inputModule.getWorkDir()).thenReturn(workDir.toPath());
+ }
+
+ @Before
+ public void before() {
+ hiddenFilesProjectData.clearHiddenFilesData();
+ underTest = spy(new HiddenFilesVisitorHelper(hiddenFilesProjectData, inputModule, moduleConfig));
+ }
+
+ @Test
+ public void verifyDefaultOnConstruction() {
+ assertThat(underTest.excludeHiddenFiles).isFalse();
+ assertThat(underTest.rootHiddenDir).isNull();
+ }
+
+ @Test
+ public void excludeHiddenFilesShouldBeSetToFalseFromConfigurationWhenNotConfigured() {
+ when(moduleConfig.getBoolean("sonar.scanner.excludeHiddenFiles")).thenReturn(Optional.empty());
+ HiddenFilesVisitorHelper configuredVisitorHelper = spy(new HiddenFilesVisitorHelper(hiddenFilesProjectData, inputModule, moduleConfig));
+
+ assertThat(configuredVisitorHelper.excludeHiddenFiles).isFalse();
+ }
+
+ @Test
+ public void excludeHiddenFilesShouldBeSetToFalseFromConfigurationWhenDisabled() {
+ when(moduleConfig.getBoolean("sonar.scanner.excludeHiddenFiles")).thenReturn(Optional.of(false));
+ HiddenFilesVisitorHelper configuredVisitorHelper = spy(new HiddenFilesVisitorHelper(hiddenFilesProjectData, inputModule, moduleConfig));
+
+ assertThat(configuredVisitorHelper.excludeHiddenFiles).isFalse();
+ }
+
+ @Test
+ public void excludeHiddenFilesShouldBeSetToTrueFromConfigurationWhenEnabled() {
+ when(moduleConfig.getBoolean("sonar.scanner.excludeHiddenFiles")).thenReturn(Optional.of(true));
+ HiddenFilesVisitorHelper configuredVisitorHelper = spy(new HiddenFilesVisitorHelper(hiddenFilesProjectData, inputModule, moduleConfig));
+
+ assertThat(configuredVisitorHelper.excludeHiddenFiles).isTrue();
+ }
+
+ @Test
+ public void shouldVisitHiddenDirectory() throws IOException {
+ File hiddenDir = temp.newFolder(".hiddenVisited");
+ setAsHiddenOnWindows(hiddenDir);
+
+ boolean visitDir = underTest.shouldVisitDir(hiddenDir.toPath());
+
+ assertThat(visitDir).isTrue();
+ assertThat(underTest.insideHiddenDirectory()).isTrue();
+ assertThat(underTest.rootHiddenDir).isEqualTo(hiddenDir.toPath());
+ verify(underTest).enterHiddenDirectory(hiddenDir.toPath());
+ }
+
+ @Test
+ public void shouldNotVisitHiddenDirectoryWhenHiddenFilesVisitIsExcluded() throws IOException {
+ when(moduleConfig.getBoolean("sonar.scanner.excludeHiddenFiles")).thenReturn(Optional.of(true));
+ HiddenFilesVisitorHelper configuredVisitorHelper = spy(new HiddenFilesVisitorHelper(hiddenFilesProjectData, inputModule, moduleConfig));
+
+ File hidden = temp.newFolder(".hiddenNotVisited");
+ setAsHiddenOnWindows(hidden);
+
+ boolean visitDir = configuredVisitorHelper.shouldVisitDir(hidden.toPath());
+
+ assertThat(visitDir).isFalse();
+ assertThat(configuredVisitorHelper.insideHiddenDirectory()).isFalse();
+ verify(configuredVisitorHelper, never()).enterHiddenDirectory(any());
+ }
+
+ @Test
+ public void shouldVisitNonHiddenDirectoryWhenHiddenFilesVisitIsExcluded() throws IOException {
+ when(moduleConfig.getBoolean("sonar.scanner.excludeHiddenFiles")).thenReturn(Optional.of(true));
+ HiddenFilesVisitorHelper configuredVisitorHelper = spy(new HiddenFilesVisitorHelper(hiddenFilesProjectData, inputModule, moduleConfig));
+
+ File nonHiddenFolder = temp.newFolder();
+
+ boolean visitDir = configuredVisitorHelper.shouldVisitDir(nonHiddenFolder.toPath());
+
+ assertThat(visitDir).isTrue();
+ assertThat(configuredVisitorHelper.insideHiddenDirectory()).isFalse();
+ verify(configuredVisitorHelper, never()).enterHiddenDirectory(any());
+ }
+
+ @Test
+ public void shouldVisitNonHiddenDirectory() throws IOException {
+ File nonHiddenFolder = temp.newFolder();
+
+ boolean visitDir = underTest.shouldVisitDir(nonHiddenFolder.toPath());
+
+ assertThat(visitDir).isTrue();
+ assertThat(underTest.insideHiddenDirectory()).isFalse();
+ verify(underTest, never()).enterHiddenDirectory(any());
+ assertThat(underTest.excludeHiddenFiles).isFalse();
+ }
+
+ @Test
+ public void shouldNotVisitModuleWorkDir() throws IOException {
+ Path workingDirectory = inputModule.getWorkDir().toRealPath(LinkOption.NOFOLLOW_LINKS).toAbsolutePath().normalize();
+ boolean visitDir = underTest.shouldVisitDir(workingDirectory);
+
+ assertThat(visitDir).isFalse();
+ assertThat(underTest.insideHiddenDirectory()).isFalse();
+ verify(underTest, never()).enterHiddenDirectory(any());
+ }
+
+ @Test
+ public void shouldNotVisitSonarUserHome() throws IOException {
+ Path userHome = sonarUserHome.getPath().toRealPath(LinkOption.NOFOLLOW_LINKS).toAbsolutePath().normalize();
+ boolean visitDir = underTest.shouldVisitDir(userHome);
+
+ assertThat(visitDir).isFalse();
+ assertThat(underTest.insideHiddenDirectory()).isFalse();
+ verify(underTest, never()).enterHiddenDirectory(any());
+ }
+
+ @Test
+ public void hiddenFileShouldBeVisited() throws IOException {
+ File hiddenFile = temp.newFile(".hiddenFileShouldBeVisited");
+ setAsHiddenOnWindows(hiddenFile);
+
+ assertThat(underTest.insideHiddenDirectory()).isFalse();
+ boolean visitFile = underTest.shouldVisitFile(hiddenFile.toPath());
+
+ assertThat(visitFile).isTrue();
+ verify(hiddenFilesProjectData).markAsHiddenFile(hiddenFile.toPath(), inputModule);
+ }
+
+ @Test
+ public void nonHiddenFileShouldBeVisitedInHiddenFolder() throws IOException {
+ File hidden = temp.newFolder(".hiddenFolder");
+ setAsHiddenOnWindows(hidden);
+
+ File nonHiddenFile = temp.newFile();
+
+ underTest.shouldVisitDir(hidden.toPath());
+ assertThat(underTest.insideHiddenDirectory()).isTrue();
+
+ boolean shouldVisitFile = underTest.shouldVisitFile(nonHiddenFile.toPath());
+
+ assertThat(shouldVisitFile).isTrue();
+ verify(hiddenFilesProjectData).markAsHiddenFile(nonHiddenFile.toPath(), inputModule);
+ }
+
+ @Test
+ public void shouldNotSetAsRootHiddenDirectoryWhenAlreadyEnteredHiddenDirectory() throws IOException {
+ File hidden = temp.newFolder(".outerHiddenFolder");
+ File nestedHiddenFolder = temp.newFolder(".outerHiddenFolder", ".nestedHiddenFolder");
+ setAsHiddenOnWindows(hidden);
+ setAsHiddenOnWindows(nestedHiddenFolder);
+
+ underTest.shouldVisitDir(hidden.toPath());
+ assertThat(underTest.insideHiddenDirectory()).isTrue();
+
+ boolean shouldVisitNestedDir = underTest.shouldVisitDir(nestedHiddenFolder.toPath());
+
+ assertThat(shouldVisitNestedDir).isTrue();
+ assertThat(underTest.rootHiddenDir).isEqualTo(hidden.toPath());
+ verify(underTest).enterHiddenDirectory(nestedHiddenFolder.toPath());
+ }
+
+ @Test
+ public void hiddenFileShouldNotBeVisitedWhenHiddenFileVisitExcluded() throws IOException {
+ when(moduleConfig.getBoolean("sonar.scanner.excludeHiddenFiles")).thenReturn(Optional.of(true));
+ HiddenFilesVisitorHelper configuredVisitorHelper = spy(new HiddenFilesVisitorHelper(hiddenFilesProjectData, inputModule, moduleConfig));
+
+ File hiddenFile = temp.newFile(".hiddenFileNotVisited");
+ setAsHiddenOnWindows(hiddenFile);
+
+ assertThat(configuredVisitorHelper.insideHiddenDirectory()).isFalse();
+
+ configuredVisitorHelper.shouldVisitFile(hiddenFile.toPath());
+ boolean shouldVisitFile = configuredVisitorHelper.shouldVisitFile(hiddenFile.toPath());
+
+ assertThat(shouldVisitFile).isFalse();
+ verify(hiddenFilesProjectData, never()).markAsHiddenFile(hiddenFile.toPath(), inputModule);
+ }
+
+ @Test
+ public void shouldCorrectlyExitHiddenFolderOnlyOnHiddenFolderThatEntered() throws IOException {
+ File hiddenFolder = temp.newFolder(".hiddenRootFolder");
+ setAsHiddenOnWindows(hiddenFolder);
+
+ boolean shouldVisitDir = underTest.shouldVisitDir(hiddenFolder.toPath());
+
+ assertThat(shouldVisitDir).isTrue();
+ assertThat(underTest.insideHiddenDirectory()).isTrue();
+ assertThat(underTest.rootHiddenDir).isEqualTo(hiddenFolder.toPath());
+ verify(underTest).enterHiddenDirectory(hiddenFolder.toPath());
+
+ File folder1 = temp.newFolder(".hiddenRootFolder", "myFolderExit");
+ File folder2 = temp.newFolder("myFolderExit");
+ File folder3 = temp.newFolder(".myFolderExit");
+ setAsHiddenOnWindows(folder3);
+
+ underTest.exitDirectory(folder1.toPath());
+ underTest.exitDirectory(folder2.toPath());
+ underTest.exitDirectory(folder3.toPath());
+
+ assertThat(underTest.insideHiddenDirectory()).isTrue();
+ assertThat(underTest.rootHiddenDir).isEqualTo(hiddenFolder.toPath());
+ verify(underTest, never()).resetRootHiddenDir();
+
+ underTest.exitDirectory(hiddenFolder.toPath());
+ assertThat(underTest.insideHiddenDirectory()).isFalse();
+ assertThat(underTest.rootHiddenDir).isNull();
+ verify(underTest).resetRootHiddenDir();
+ }
+
+ @Test
+ public void shouldNotInitiateResetRootDirWhenNotInHiddenDirectory() throws IOException {
+ File hiddenFolder = temp.newFolder(".hiddenFolderNonRoot");
+ setAsHiddenOnWindows(hiddenFolder);
+
+ underTest.exitDirectory(hiddenFolder.toPath());
+
+ verify(underTest, never()).resetRootHiddenDir();
+ }
+
+ @Test
+ public void filesShouldBeCorrectlyMarkedAsHidden() throws IOException {
+ File hiddenFolder = temp.newFolder(".hiddenFolderRoot");
+ setAsHiddenOnWindows(hiddenFolder);
+
+ File file1 = temp.newFile();
+ File file2 = temp.newFile();
+ File file3 = temp.newFile(".markedHiddenFile");
+ setAsHiddenOnWindows(file3);
+ File file4 = temp.newFile();
+ File file5 = temp.newFile(".markedHiddenFile2");
+ setAsHiddenOnWindows(file5);
+
+ underTest.shouldVisitFile(file1.toPath());
+ underTest.shouldVisitDir(hiddenFolder.toPath());
+ underTest.shouldVisitFile(file2.toPath());
+ underTest.shouldVisitFile(file3.toPath());
+ underTest.exitDirectory(hiddenFolder.toPath());
+ underTest.shouldVisitFile(file4.toPath());
+ underTest.shouldVisitFile(file5.toPath());
+
+ verify(hiddenFilesProjectData, never()).markAsHiddenFile(file1.toPath(), inputModule);
+ verify(hiddenFilesProjectData).markAsHiddenFile(file2.toPath(), inputModule);
+ verify(hiddenFilesProjectData).markAsHiddenFile(file3.toPath(), inputModule);
+ verify(hiddenFilesProjectData, never()).markAsHiddenFile(file4.toPath(), inputModule);
+ verify(hiddenFilesProjectData).markAsHiddenFile(file5.toPath(), inputModule);
+ }
+
+ private static void setAsHiddenOnWindows(File file) throws IOException {
+ if (SystemUtils.IS_OS_WINDOWS) {
+ Files.setAttribute(file.toPath(), "dos:hidden", true, LinkOption.NOFOLLOW_LINKS);
+ }
+ }
+}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputComponentStoreTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputComponentStoreTest.java
index 91b1695a0ef..ddabaaeeb1e 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputComponentStoreTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputComponentStoreTest.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/test/java/org/sonar/scanner/scan/filesystem/InputFileFilterRepositoryTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputFileFilterRepositoryTest.java
index 7be01e0a79f..41c54320025 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputFileFilterRepositoryTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputFileFilterRepositoryTest.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/test/java/org/sonar/scanner/scan/filesystem/LanguageDetectionTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/LanguageDetectionTest.java
index 1bf8599da5d..4a368f4b1c5 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
@@ -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/test/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorTest.java
index 2f5e5c75df5..53009584158 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorTest.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/test/java/org/sonar/scanner/scan/filesystem/ModuleInputComponentStoreTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ModuleInputComponentStoreTest.java
index 24b17271be5..07f7afec036 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ModuleInputComponentStoreTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ModuleInputComponentStoreTest.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
@@ -19,80 +19,151 @@
*/
package org.sonar.scanner.scan.filesystem;
-import java.io.IOException;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
+import java.io.File;
+import java.util.List;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.io.TempDir;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
import org.sonar.api.SonarRuntime;
import org.sonar.api.batch.fs.InputFile;
-import org.sonar.api.batch.fs.InputModule;
import org.sonar.api.batch.fs.internal.SensorStrategy;
-import org.sonar.api.batch.fs.internal.DefaultInputProject;
import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
+import org.sonar.api.batch.sensor.internal.SensorContextTester;
import org.sonar.scanner.scan.branch.BranchConfiguration;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-public class ModuleInputComponentStoreTest {
- @Rule
- public TemporaryFolder temp = new TemporaryFolder();
+@ExtendWith(MockitoExtension.class)
+class ModuleInputComponentStoreTest {
+
+ @TempDir
+ private File projectBaseDir;
+
+ @Mock
+ BranchConfiguration branchConfiguration;
+
+ @Mock
+ SonarRuntime sonarRuntime;
+
+ @Mock
+ InputComponentStore mockedInputComponentStore;
private InputComponentStore componentStore;
+ private SensorContextTester sensorContextTester;
private final String projectKey = "dummy key";
- @Before
- public void setUp() throws IOException {
- DefaultInputProject root = TestInputFileBuilder.newDefaultInputProject(projectKey, temp.newFolder());
- componentStore = new InputComponentStore(mock(BranchConfiguration.class), mock(SonarRuntime.class));
+ @BeforeEach
+ void setUp() {
+ TestInputFileBuilder.newDefaultInputProject(projectKey, projectBaseDir);
+ File moduleBaseDir = new File(projectBaseDir, "module");
+ moduleBaseDir.mkdir();
+ sensorContextTester = SensorContextTester.create(moduleBaseDir);
+ componentStore = spy(new InputComponentStore(branchConfiguration, sonarRuntime));
}
@Test
- public void should_cache_files_by_filename() {
+ void should_cache_module_files_by_filename() {
ModuleInputComponentStore store = newModuleInputComponentStore();
String filename = "some name";
- InputFile inputFile1 = new TestInputFileBuilder(projectKey, "some/path/" + filename).build();
+ InputFile inputFile1 = new TestInputFileBuilder(projectKey, "module/some/path/" + filename).build();
store.doAdd(inputFile1);
- InputFile inputFile2 = new TestInputFileBuilder(projectKey, "other/path/" + filename).build();
+ InputFile inputFile2 = new TestInputFileBuilder(projectKey, "module/other/path/" + filename).build();
store.doAdd(inputFile2);
- InputFile dummyInputFile = new TestInputFileBuilder(projectKey, "some/path/Dummy.java").build();
+ InputFile dummyInputFile = new TestInputFileBuilder(projectKey, "module/some/path/Dummy.java").build();
store.doAdd(dummyInputFile);
assertThat(store.getFilesByName(filename)).containsExactlyInAnyOrder(inputFile1, inputFile2);
}
@Test
- public void should_cache_files_by_extension() {
+ void should_cache_filtered_module_files_by_filename() {
+ ModuleInputComponentStore store = newModuleInputComponentStore();
+
+ String filename = "some name";
+ InputFile inputFile1 = new TestInputFileBuilder(projectKey, "some/path/" + filename).build();
+ InputFile inputFile2 = new TestInputFileBuilder(projectKey, "module/other/path/" + filename).build();
+ store.doAdd(inputFile2);
+
+ when(componentStore.getFilesByName(filename)).thenReturn(List.of(inputFile1, inputFile2));
+
+ assertThat(store.getFilesByName(filename)).containsOnly(inputFile2);
+ }
+
+ @Test
+ void should_cache_module_files_by_filename_global_strategy() {
+ ModuleInputComponentStore store = new ModuleInputComponentStore(sensorContextTester.module(), componentStore, new SensorStrategy());
+
+ String filename = "some name";
+ // None in the module
+ InputFile inputFile1 = new TestInputFileBuilder(projectKey, "some/path/" + filename).build();
+ InputFile inputFile2 = new TestInputFileBuilder(projectKey, "other/path/" + filename).build();
+
+ when(componentStore.getFilesByName(filename)).thenReturn(List.of(inputFile1, inputFile2));
+
+ assertThat(store.getFilesByName(filename)).containsExactlyInAnyOrder(inputFile1, inputFile2);
+ }
+
+ @Test
+ void should_cache_module_files_by_extension() {
ModuleInputComponentStore store = newModuleInputComponentStore();
- InputFile inputFile1 = new TestInputFileBuilder(projectKey, "some/path/Program.java").build();
+ InputFile inputFile1 = new TestInputFileBuilder(projectKey, "module/some/path/Program.java").build();
store.doAdd(inputFile1);
- InputFile inputFile2 = new TestInputFileBuilder(projectKey, "other/path/Utils.java").build();
+ InputFile inputFile2 = new TestInputFileBuilder(projectKey, "module/other/path/Utils.java").build();
store.doAdd(inputFile2);
- InputFile dummyInputFile = new TestInputFileBuilder(projectKey, "some/path/NotJava.cpp").build();
+ InputFile dummyInputFile = new TestInputFileBuilder(projectKey, "module/some/path/NotJava.cpp").build();
store.doAdd(dummyInputFile);
assertThat(store.getFilesByExtension("java")).containsExactlyInAnyOrder(inputFile1, inputFile2);
}
@Test
- public void should_not_cache_duplicates() {
+ void should_cache_filtered_module_files_by_extension() {
+ ModuleInputComponentStore store = newModuleInputComponentStore();
+
+ InputFile inputFile1 = new TestInputFileBuilder(projectKey, "some/path/NotInModule.java").build();
+ InputFile inputFile2 = new TestInputFileBuilder(projectKey, "module/some/path/Other.java").build();
+ store.doAdd(inputFile2);
+
+ when(componentStore.getFilesByExtension("java")).thenReturn(List.of(inputFile1, inputFile2));
+
+ assertThat(store.getFilesByExtension("java")).containsOnly(inputFile2);
+ }
+
+ @Test
+ void should_cache_module_files_by_extension_global_strategy() {
+ ModuleInputComponentStore store = new ModuleInputComponentStore(sensorContextTester.module(), componentStore, new SensorStrategy());
+
+ // None in the module
+ InputFile inputFile1 = new TestInputFileBuilder(projectKey, "some/path/NotInModule.java").build();
+ InputFile inputFile2 = new TestInputFileBuilder(projectKey, "some/path/Other.java").build();
+
+ when(componentStore.getFilesByExtension("java")).thenReturn(List.of(inputFile1, inputFile2));
+
+ assertThat(store.getFilesByExtension("java")).containsExactlyInAnyOrder(inputFile1, inputFile2);
+ }
+
+ @Test
+ void should_not_cache_duplicates() {
ModuleInputComponentStore store = newModuleInputComponentStore();
String ext = "java";
String filename = "Program." + ext;
- InputFile inputFile = new TestInputFileBuilder(projectKey, "some/path/" + filename).build();
+ InputFile inputFile = new TestInputFileBuilder(projectKey, "module/some/path/" + filename).build();
store.doAdd(inputFile);
store.doAdd(inputFile);
store.doAdd(inputFile);
@@ -102,12 +173,12 @@ public class ModuleInputComponentStoreTest {
}
@Test
- public void should_get_empty_iterable_on_cache_miss() {
+ void should_get_empty_iterable_on_cache_miss() {
ModuleInputComponentStore store = newModuleInputComponentStore();
String ext = "java";
String filename = "Program." + ext;
- InputFile inputFile = new TestInputFileBuilder(projectKey, "some/path/" + filename).build();
+ InputFile inputFile = new TestInputFileBuilder(projectKey, "module/some/path/" + filename).build();
store.doAdd(inputFile);
assertThat(store.getFilesByName("nonexistent")).isEmpty();
@@ -115,48 +186,42 @@ public class ModuleInputComponentStoreTest {
}
private ModuleInputComponentStore newModuleInputComponentStore() {
- InputModule module = mock(InputModule.class);
- when(module.key()).thenReturn("moduleKey");
- return new ModuleInputComponentStore(module, componentStore, mock(SensorStrategy.class));
+ SensorStrategy strategy = new SensorStrategy();
+ strategy.setGlobal(false);
+ return new ModuleInputComponentStore(sensorContextTester.module(), componentStore, strategy);
}
@Test
- public void should_find_module_components_with_non_global_strategy() {
- InputComponentStore inputComponentStore = mock(InputComponentStore.class);
+ void should_find_module_components_with_non_global_strategy() {
SensorStrategy strategy = new SensorStrategy();
- InputModule module = mock(InputModule.class);
- when(module.key()).thenReturn("foo");
- ModuleInputComponentStore store = new ModuleInputComponentStore(module, inputComponentStore, strategy);
+ ModuleInputComponentStore store = new ModuleInputComponentStore(sensorContextTester.module(), mockedInputComponentStore, strategy);
strategy.setGlobal(false);
store.inputFiles();
- verify(inputComponentStore).filesByModule("foo");
+ verify(mockedInputComponentStore).filesByModule(sensorContextTester.module().key());
String relativePath = "somepath";
store.inputFile(relativePath);
- verify(inputComponentStore).getFile(any(String.class), eq(relativePath));
+ verify(mockedInputComponentStore).getFile(any(String.class), eq(relativePath));
store.languages();
- verify(inputComponentStore).languages(any(String.class));
+ verify(mockedInputComponentStore).languages(any(String.class));
}
@Test
- public void should_find_all_components_with_global_strategy() {
- InputComponentStore inputComponentStore = mock(InputComponentStore.class);
+ void should_find_all_components_with_global_strategy() {
SensorStrategy strategy = new SensorStrategy();
- ModuleInputComponentStore store = new ModuleInputComponentStore(mock(InputModule.class), inputComponentStore, strategy);
-
- strategy.setGlobal(true);
+ ModuleInputComponentStore store = new ModuleInputComponentStore(sensorContextTester.module(), mockedInputComponentStore, strategy);
store.inputFiles();
- verify(inputComponentStore).inputFiles();
+ verify(mockedInputComponentStore).inputFiles();
String relativePath = "somepath";
store.inputFile(relativePath);
- verify(inputComponentStore).inputFile(relativePath);
+ verify(mockedInputComponentStore).inputFile(relativePath);
store.languages();
- verify(inputComponentStore).languages();
+ verify(mockedInputComponentStore).languages();
}
}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/MutableFileSystemTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/MutableFileSystemTest.java
index 89a01da4130..485708c9936 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/MutableFileSystemTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/MutableFileSystemTest.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,6 +28,9 @@ import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
public class MutableFileSystemTest {
@@ -44,9 +47,15 @@ public class MutableFileSystemTest {
}
@Test
- public void return_all_files_when_not_restricted() {
+ public void restriction_and_hidden_file_should_be_disabled_on_default() {
+ assertThat(underTest.restrictToChangedFiles).isFalse();
+ assertThat(underTest.allowHiddenFileAnalysis).isFalse();
+ }
+
+ @Test
+ public void return_all_non_hidden_files_when_not_restricted_and_disabled() {
assertThat(underTest.inputFiles(underTest.predicates().all())).isEmpty();
- addFileWithAllStatus();
+ addFilesWithAllStatus();
underTest.setRestrictToChangedFiles(false);
assertThat(underTest.inputFiles(underTest.predicates().all())).hasSize(3);
@@ -58,7 +67,7 @@ public class MutableFileSystemTest {
@Test
public void return_only_changed_files_when_restricted() {
assertThat(underTest.inputFiles(underTest.predicates().all())).isEmpty();
- addFileWithAllStatus();
+ addFilesWithAllStatus();
underTest.setRestrictToChangedFiles(true);
assertThat(underTest.inputFiles(underTest.predicates().all())).hasSize(2);
@@ -67,19 +76,95 @@ public class MutableFileSystemTest {
assertThat(underTest.inputFile(underTest.predicates().hasFilename(generateFilename(InputFile.Status.CHANGED)))).isNotNull();
}
- private void addFileWithAllStatus() {
+ @Test
+ public void return_all_files_when_allowing_hidden_files_analysis() {
+ assertThat(underTest.inputFiles(underTest.predicates().all())).isEmpty();
+ addFilesWithVisibility();
+ underTest.setAllowHiddenFileAnalysis(true);
+
+ assertThat(underTest.inputFiles(underTest.predicates().all())).hasSize(2);
+ assertThat(underTest.inputFile(underTest.predicates().hasFilename(generateFilename(true)))).isNotNull();
+ assertThat(underTest.inputFile(underTest.predicates().hasFilename(generateFilename(false)))).isNotNull();
+ }
+
+ @Test
+ public void return_only_non_hidden_files_when_not_allowing_hidden_files_analysis() {
+ assertThat(underTest.inputFiles(underTest.predicates().all())).isEmpty();
+ addFilesWithVisibility();
+ underTest.setAllowHiddenFileAnalysis(false);
+
+ assertThat(underTest.inputFiles(underTest.predicates().all())).hasSize(1);
+ assertThat(underTest.inputFile(underTest.predicates().hasFilename(generateFilename(true)))).isNull();
+ assertThat(underTest.inputFile(underTest.predicates().hasFilename(generateFilename(false)))).isNotNull();
+ }
+
+ @Test
+ public void hidden_file_predicate_should_preserve_predicate_optimization() {
+ addFilesWithVisibility();
+ var anotherHiddenFile = spy(new TestInputFileBuilder("foo", String.format("src/%s", ".myHiddenFile.txt"))
+ .setLanguage(LANGUAGE).setStatus(InputFile.Status.ADDED).setHidden(true).build());
+ underTest.add(anotherHiddenFile);
+ underTest.setAllowHiddenFileAnalysis(false);
+
+ assertThat(underTest.inputFile(underTest.predicates().hasFilename(generateFilename(true)))).isNull();
+ assertThat(underTest.inputFile(underTest.predicates().hasFilename(generateFilename(false)))).isNotNull();
+ // Verify that predicate optimization is still effective
+ verify(anotherHiddenFile, never()).isHidden();
+
+ // This predicate can't be optimized
+ assertThat(underTest.inputFiles(underTest.predicates().all())).hasSize(1);
+ verify(anotherHiddenFile).isHidden();
+ }
+
+ @Test
+ public void hidden_file_predicate_should_be_applied_first_for_non_optimized_predicates() {
+ // Checking the file type is not very costly, but it is not optimized. In real life, something more costly would be reading the file
+ // content, for example.
+ addFilesWithVisibility();
+ var anotherHiddenFile = spy(new TestInputFileBuilder("foo", String.format("src/%s", ".myHiddenFile." + LANGUAGE))
+ .setLanguage(LANGUAGE).setType(InputFile.Type.MAIN).setStatus(InputFile.Status.ADDED).setHidden(true).build());
+ underTest.add(anotherHiddenFile);
+ underTest.setAllowHiddenFileAnalysis(false);
+
+ assertThat(underTest.inputFiles(underTest.predicates().hasType(InputFile.Type.MAIN))).hasSize(1);
+ // Verify that the file type has not been evaluated
+ verify(anotherHiddenFile, never()).type();
+ }
+
+ private void addFilesWithVisibility() {
+ addFile(true);
+ addFile(false);
+ }
+
+ private void addFilesWithAllStatus() {
addFile(InputFile.Status.ADDED);
addFile(InputFile.Status.CHANGED);
addFile(InputFile.Status.SAME);
}
private void addFile(InputFile.Status status) {
- underTest.add(new TestInputFileBuilder("foo", String.format("src/%s", generateFilename(status)))
- .setLanguage(LANGUAGE).setStatus(status).build());
+ addFile(status, false);
+ }
+
+ private void addFile(boolean hidden) {
+ addFile(InputFile.Status.SAME, hidden);
+ }
+
+ private void addFile(InputFile.Status status, boolean hidden) {
+ underTest.add(new TestInputFileBuilder("foo", String.format("src/%s", generateFilename(status, hidden)))
+ .setLanguage(LANGUAGE).setType(InputFile.Type.MAIN).setStatus(status).setHidden(hidden).build());
+ }
+
+ private String generateFilename(boolean hidden) {
+ return generateFilename(InputFile.Status.SAME, hidden);
}
private String generateFilename(InputFile.Status status) {
- return String.format("%s.%s", status.name().toLowerCase(Locale.ROOT), LANGUAGE);
+ return generateFilename(status, false);
+ }
+
+ private String generateFilename(InputFile.Status status, boolean hidden) {
+ return String.format("%s.%s.%s", status.name().toLowerCase(Locale.ROOT), hidden, LANGUAGE);
}
}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ProjectExclusionFiltersTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ProjectExclusionFiltersTest.java
index 995b0f1ac17..7b3520b0abb 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ProjectExclusionFiltersTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ProjectExclusionFiltersTest.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/test/java/org/sonar/scanner/scan/filesystem/StatusDetectionTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/StatusDetectionTest.java
index 22ca2771b06..bb0f515152f 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/StatusDetectionTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/StatusDetectionTest.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/test/java/org/sonar/scanner/scm/DefaultBlameOutputTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/DefaultBlameOutputTest.java
index d52e21bc110..6dffc938113 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/DefaultBlameOutputTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/DefaultBlameOutputTest.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/test/java/org/sonar/scanner/scm/ScmChangedFilesProviderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/ScmChangedFilesProviderTest.java
index 49e91a6dc88..146b9943f6f 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/ScmChangedFilesProviderTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/ScmChangedFilesProviderTest.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/test/java/org/sonar/scanner/scm/ScmChangedFilesTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/ScmChangedFilesTest.java
index be8b214bd73..7461f20061a 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/ScmChangedFilesTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/ScmChangedFilesTest.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/test/java/org/sonar/scanner/scm/ScmConfigurationTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/ScmConfigurationTest.java
index 9250b6680e9..a4d9ba0ca4d 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/ScmConfigurationTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/ScmConfigurationTest.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/test/java/org/sonar/scanner/scm/ScmRevisionImplTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/ScmRevisionImplTest.java
index 28cec113cd8..bf1615d493a 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/ScmRevisionImplTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/ScmRevisionImplTest.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/test/java/org/sonar/scanner/sensor/AbstractSensorOptimizerTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/AbstractSensorOptimizerTest.java
index a0a81ede6a5..7f41d12af57 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/AbstractSensorOptimizerTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/AbstractSensorOptimizerTest.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/test/java/org/sonar/scanner/sensor/DefaultSensorStorageTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSensorStorageTest.java
index 5a6f8f66a1f..355fb2cde0e 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
@@ -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
@@ -97,7 +97,6 @@ class DefaultSensorStorageTest {
public void prepare() {
MetricFinder metricFinder = mock(MetricFinder.class);
when(metricFinder.<Integer>findByKey(CoreMetrics.NCLOC_KEY)).thenReturn(CoreMetrics.NCLOC);
- when(metricFinder.<String>findByKey(CoreMetrics.FUNCTION_COMPLEXITY_DISTRIBUTION_KEY)).thenReturn(CoreMetrics.FUNCTION_COMPLEXITY_DISTRIBUTION);
when(metricFinder.<Integer>findByKey(CoreMetrics.LINES_TO_COVER_KEY)).thenReturn(CoreMetrics.LINES_TO_COVER);
settings = new MapSettings();
@@ -112,8 +111,9 @@ class DefaultSensorStorageTest {
branchConfiguration = mock(BranchConfiguration.class);
- underTest = new DefaultSensorStorage(metricFinder,
- moduleIssues, settings.asConfig(), reportPublisher, mock(SonarCpdBlockIndex.class), contextPropertiesCache, telemetryCache, new ScannerMetrics(), branchConfiguration);
+ underTest = new DefaultSensorStorage(
+ metricFinder, moduleIssues, settings.asConfig(), reportPublisher, mock(SonarCpdBlockIndex.class), contextPropertiesCache, telemetryCache, new ScannerMetrics(),
+ branchConfiguration);
project = new DefaultInputProject(ProjectDefinition.create()
.setKey("foo")
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/ModuleSensorContextTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/ModuleSensorContextTest.java
index feb5c1ddb17..3a0ff7fb4c2 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/ModuleSensorContextTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/ModuleSensorContextTest.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
@@ -68,7 +68,7 @@ class ModuleSensorContextTest {
@BeforeEach
void prepare() {
fs = new DefaultFileSystem(temp);
- underTest = new ModuleSensorContext(mock(DefaultInputProject.class), mock(InputModule.class), settings.asConfig(), settings, fs, activeRules, sensorStorage, runtime,
+ underTest = new ModuleSensorContext(mock(DefaultInputProject.class), mock(InputModule.class), settings.asConfig(), fs, activeRules, sensorStorage, runtime,
branchConfiguration, writeCache, readCache, analysisCacheEnabled, unchangedFilesHandler, executingSensorContext, pluginRepository);
}
@@ -104,7 +104,7 @@ class ModuleSensorContextTest {
@Test
void pull_request_can_skip_unchanged_files() {
when(branchConfiguration.isPullRequest()).thenReturn(true);
- underTest = new ModuleSensorContext(mock(DefaultInputProject.class), mock(InputModule.class), settings.asConfig(), settings, fs, activeRules, sensorStorage, runtime,
+ underTest = new ModuleSensorContext(mock(DefaultInputProject.class), mock(InputModule.class), settings.asConfig(), fs, activeRules, sensorStorage, runtime,
branchConfiguration, writeCache, readCache, analysisCacheEnabled, unchangedFilesHandler, executingSensorContext, pluginRepository);
assertThat(underTest.canSkipUnchangedFiles()).isTrue();
}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/ModuleSensorOptimizerTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/ModuleSensorOptimizerTest.java
index 12a04d50098..448e5104f72 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/ModuleSensorOptimizerTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/ModuleSensorOptimizerTest.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/test/java/org/sonar/scanner/sensor/ProjectSensorContextTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/ProjectSensorContextTest.java
index 5d25250e8bb..01c337a5ed0 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/ProjectSensorContextTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/ProjectSensorContextTest.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
@@ -59,8 +59,8 @@ class ProjectSensorContextTest {
private ExecutingSensorContext executingSensorContext = mock(ExecutingSensorContext.class);
private ScannerPluginRepository pluginRepository = mock(ScannerPluginRepository.class);
- private ProjectSensorContext underTest = new ProjectSensorContext(mock(DefaultInputProject.class), settings.asConfig(), settings, fs, activeRules, sensorStorage, runtime,
- branchConfiguration, writeCache, readCache, analysisCacheEnabled, unchangedFilesHandler, executingSensorContext, pluginRepository);
+ private ProjectSensorContext underTest = new ProjectSensorContext(mock(DefaultInputProject.class), settings.asConfig(), fs, activeRules, sensorStorage, runtime,
+ branchConfiguration, writeCache, readCache, analysisCacheEnabled, unchangedFilesHandler, executingSensorContext, pluginRepository);
private static final String PLUGIN_KEY = "org.sonarsource.pluginKey";
@@ -69,7 +69,6 @@ class ProjectSensorContextTest {
when(executingSensorContext.getSensorExecuting()).thenReturn(new SensorId(PLUGIN_KEY, "sensorName"));
}
-
@Test
void addTelemetryProperty_whenTheOrganizationIsSonarSource_mustStoreTheTelemetry() {
@@ -77,16 +76,21 @@ class ProjectSensorContextTest {
underTest.addTelemetryProperty("key", "value");
- //then verify that the defaultStorage is called with the telemetry property once
+ // then verify that the defaultStorage is called with the telemetry property once
verify(sensorStorage).storeTelemetry("key", "value");
}
@Test
- void addTelemetryProperty_whenTheOrganizationIsNotSonarSource_mustThrowExcaption() {
+ void addTelemetryProperty_whenTheOrganizationIsNotSonarSource_mustThrowException() {
when(pluginRepository.getPluginInfo(PLUGIN_KEY)).thenReturn(new PluginInfo(PLUGIN_KEY).setOrganizationName("notSonarsource"));
assertThrows(IllegalStateException.class, () -> underTest.addTelemetryProperty("key", "value"));
verifyNoInteractions(sensorStorage);
}
+
+ @Test
+ void settings_throwsUnsupportedOperationException() {
+ assertThrows(UnsupportedOperationException.class, () -> underTest.settings());
+ }
}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/SensorIdTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/SensorIdTest.java
index 11660111479..66130ee3fc7 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/SensorIdTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/SensorIdTest.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/test/java/org/sonar/scanner/sensor/UnchangedFilesHandlerTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/UnchangedFilesHandlerTest.java
index 71cd70f8f74..51336d5e5e1 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/UnchangedFilesHandlerTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/UnchangedFilesHandlerTest.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/test/java/org/sonar/scanner/util/ProgressReportTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/util/ProgressReportTest.java
index 71a3fd644a1..c064e517551 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/util/ProgressReportTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/util/ProgressReportTest.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
@@ -42,7 +42,7 @@ public class ProgressReportTest {
@Rule
public LogTester logTester = new LogTester();
- private ProgressReport underTest = new ProgressReport(THREAD_NAME, 1);
+ private final ProgressReport underTest = new ProgressReport(THREAD_NAME, 1);
@Test
public void stop_thread_on_stop() {
@@ -66,15 +66,28 @@ public class ProgressReportTest {
underTest.message("Some message");
boolean logged = false;
while (!logged) {
- logged = containsWithRetry("Some message");
+ logged = waitForMessageStartingWith("Some message");
}
underTest.stop("stop");
- assertThat(containsWithRetry("stop")).isTrue();
+ assertThat(waitForMessageStartingWith("stop")).isTrue();
}
- private boolean containsWithRetry(String message) {
+ @Test
+ public void do_log_message_supplier() {
+ logTester.setLevel(Level.DEBUG);
+ underTest.start("start");
+ underTest.message(() -> "Some message " + System.currentTimeMillis());
+ boolean logged = false;
+ while (!logged) {
+ logged = waitForMessageStartingWith("Some message ");
+ }
+ underTest.stop("stop");
+ assertThat(waitForMessageStartingWith("stop")).isTrue();
+ }
+
+ private boolean waitForMessageStartingWith(String message) {
try {
- Awaitility.await().atMost(5, TimeUnit.SECONDS).until(() -> logTester.logs().contains(message));
+ Awaitility.await().atMost(5, TimeUnit.SECONDS).until(() -> logTester.logs().stream().anyMatch(s -> s.startsWith(message)));
} catch (ConditionTimeoutException e) {
return false;
}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/util/ScannerUtilsTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/util/ScannerUtilsTest.java
index cfbd153c5b4..72185c83416 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/util/ScannerUtilsTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/util/ScannerUtilsTest.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/test/java/org/sonar/scm/git/ChangedFileTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scm/git/ChangedFileTest.java
index d6e7fef0d5e..91f59b964b9 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scm/git/ChangedFileTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scm/git/ChangedFileTest.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
@@ -88,7 +88,7 @@ public class ChangedFileTest {
secure().next(5),
Integer.parseInt(secure().nextNumeric(5)),
new SensorStrategy(),
- oldRelativePath);
+ oldRelativePath, false);
}
}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scm/git/ChangedLinesComputerTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scm/git/ChangedLinesComputerTest.java
index 346f35af705..502482b275d 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scm/git/ChangedLinesComputerTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scm/git/ChangedLinesComputerTest.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/test/java/org/sonar/scm/git/CompositeBlameCommandIT.java b/sonar-scanner-engine/src/test/java/org/sonar/scm/git/CompositeBlameCommandIT.java
index ca666a6d866..775fe3d05b2 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scm/git/CompositeBlameCommandIT.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scm/git/CompositeBlameCommandIT.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
@@ -47,6 +47,7 @@ import org.sonar.api.batch.scm.BlameLine;
import org.sonar.api.notifications.AnalysisWarnings;
import org.sonar.api.scan.filesystem.PathResolver;
import org.sonar.api.utils.System2;
+import org.sonar.core.util.ProcessWrapperFactory;
import org.sonar.scm.git.strategy.DefaultBlameStrategy.BlameAlgorithmEnum;
import static org.assertj.core.api.Assertions.assertThat;
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scm/git/CompositeBlameCommandTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scm/git/CompositeBlameCommandTest.java
index f628ef8a5ac..a1a4cae8b4d 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scm/git/CompositeBlameCommandTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scm/git/CompositeBlameCommandTest.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
@@ -54,6 +54,7 @@ import org.sonar.api.testfixtures.log.LogTester;
import org.sonar.api.utils.DateUtils;
import org.sonar.api.utils.MessageException;
import org.sonar.api.utils.System2;
+import org.sonar.core.util.ProcessWrapperFactory;
import org.sonar.scm.git.strategy.BlameStrategy;
import org.sonar.scm.git.strategy.DefaultBlameStrategy.BlameAlgorithmEnum;
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scm/git/GitIgnoreCommandTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scm/git/GitIgnoreCommandTest.java
index 8ede2a9739d..e725b201b98 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scm/git/GitIgnoreCommandTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scm/git/GitIgnoreCommandTest.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/test/java/org/sonar/scm/git/GitScmProviderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scm/git/GitScmProviderTest.java
index 884253a7e4f..058c274013d 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scm/git/GitScmProviderTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scm/git/GitScmProviderTest.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
@@ -52,6 +52,7 @@ import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
+import org.slf4j.event.Level;
import org.sonar.api.config.Configuration;
import org.sonar.api.notifications.AnalysisWarnings;
import org.sonar.api.scan.filesystem.PathResolver;
@@ -60,6 +61,7 @@ import org.sonar.api.testfixtures.log.LogTester;
import org.sonar.api.utils.MessageException;
import org.sonar.api.utils.System2;
import org.sonar.core.documentation.DocumentationLinkGenerator;
+import org.sonar.core.util.ProcessWrapperFactory;
import org.sonar.scm.git.strategy.DefaultBlameStrategy;
import static java.lang.String.format;
@@ -246,6 +248,36 @@ public class GitScmProviderTest {
}
@Test
+ public void branchChangedLinesWithFileMovementDetection_should_return_null_when_mergeBaseCommit_is_empty() throws IOException, GitAPIException {
+ logs.setLevel(Level.WARN);
+
+ git.checkout().setOrphan(true).setName("orphan-branch").call();
+ createAndCommitFile("file3.txt");
+
+ Map<Path, ChangedFile> changedFiles = Map.of(
+ worktree.resolve("file1.txt"), ChangedFile.of(worktree.resolve("file1.txt"), null),
+ worktree.resolve("file2-renamed.txt"), ChangedFile.of(worktree.resolve("file2-renamed.txt"), "file2.txt"));
+
+ Map<Path, Set<Integer>> result = newScmProvider().branchChangedLinesWithFileMovementDetection("master", worktree, changedFiles);
+
+ assertThat(logs.logs(Level.WARN)).contains("No merge base found between HEAD and refs/heads/master");
+ assertThat(result).isNull();
+ }
+
+ @Test
+ public void branchChangedFilesWithFileMovementDetection_should_return_null_when_mergeBaseCommit_is_empty() throws IOException, GitAPIException {
+ logs.setLevel(Level.WARN);
+
+ git.checkout().setOrphan(true).setName("orphan-branch").call();
+ createAndCommitFile("file3.txt");
+
+ Set<ChangedFile> result = newScmProvider().branchChangedFilesWithFileMovementDetection("master", worktree);
+
+ assertThat(logs.logs(Level.WARN)).contains("No merge base found between HEAD and refs/heads/master");
+ assertThat(result).isNull();
+ }
+
+ @Test
public void branchChangedFiles_should_not_fail_with_patience_diff_algo() throws IOException {
Path gitConfig = worktree.resolve(".git").resolve("config");
Files.write(gitConfig, "[diff]\nalgorithm = patience\n".getBytes(StandardCharsets.UTF_8));
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scm/git/GitScmSupportTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scm/git/GitScmSupportTest.java
index 27ec0629aca..d89657a7ba0 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scm/git/GitScmSupportTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scm/git/GitScmSupportTest.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/test/java/org/sonar/scm/git/GitThreadFactoryTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scm/git/GitThreadFactoryTest.java
index 59297f25461..4593909cf3e 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scm/git/GitThreadFactoryTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scm/git/GitThreadFactoryTest.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/test/java/org/sonar/scm/git/GitUtils.java b/sonar-scanner-engine/src/test/java/org/sonar/scm/git/GitUtils.java
index 9e70db06250..f64cd1de741 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scm/git/GitUtils.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scm/git/GitUtils.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/test/java/org/sonar/scm/git/JGitBlameCommandTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scm/git/JGitBlameCommandTest.java
index a5a028702bb..9ddfb3ac968 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scm/git/JGitBlameCommandTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scm/git/JGitBlameCommandTest.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/test/java/org/sonar/scm/git/JGitUtilsTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scm/git/JGitUtilsTest.java
new file mode 100644
index 00000000000..d8264a5745b
--- /dev/null
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scm/git/JGitUtilsTest.java
@@ -0,0 +1,101 @@
+/*
+ * 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.scm.git;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.List;
+import org.apache.commons.lang.SystemUtils;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+import org.sonar.api.utils.MessageException;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+class JGitUtilsTest {
+
+ @TempDir
+ Path rootModuleDir;
+
+ @Test
+ void getAllIgnoredPaths_ReturnsIgnoredFiles() throws Exception {
+ setupTestDirectory();
+
+ List<String> result = JGitUtils.getAllIgnoredPaths(rootModuleDir);
+
+ // in directory1, the entire directory is ignored without listing each file
+ // in directory2, specific files are ignored, so those files are listed
+ // in directory3, specific files are ignored via a separate .gitignore file
+ if (SystemUtils.IS_OS_WINDOWS) {
+ assertThat(result).isEqualTo(List.of("directory1", "directory2\\file_a.txt", "directory3\\file_b.txt"));
+ } else {
+ assertThat(result).isEqualTo(List.of("directory1", "directory2/file_a.txt", "directory3/file_b.txt"));
+ }
+ }
+
+ @Test
+ void getIgnoredPaths_WithNonGitDirectory_ThrowsException() {
+ assertThatThrownBy(() -> JGitUtils.getAllIgnoredPaths(rootModuleDir))
+ .isInstanceOf(MessageException.class)
+ .hasMessageStartingWith("Not inside a Git work tree: ");
+ }
+
+ @Test
+ void getIgnoredPaths_WithDifferentBaseDir_ReturnsIgnoredFilesRelativeToBaseDir() throws Exception {
+ Path baseDir = rootModuleDir.resolve("directory2");
+ setupTestDirectory();
+
+ List<String> result = JGitUtils.getAllIgnoredPaths(baseDir);
+
+ assertThat(result).isEqualTo(List.of("file_a.txt"));
+ }
+
+ @Test
+ void getIgnoredPaths_WithSubDirBaseDirContainingGitIgnore_ReturnsIgnoredFilesRelativeToBaseDir() throws Exception {
+ Path baseDir = rootModuleDir.resolve("directory3");
+ setupTestDirectory();
+
+ List<String> result = JGitUtils.getAllIgnoredPaths(baseDir);
+
+ assertThat(result).isEqualTo(List.of("file_b.txt"));
+ }
+
+ private void setupTestDirectory() throws GitAPIException, IOException {
+ Git.init().setDirectory(rootModuleDir.toFile()).call();
+
+ var directories = List.of("directory1", "directory2", "directory3");
+ var fileNames = List.of("file_a.txt", "file_b.txt");
+
+ for (String dir : directories) {
+ Path directoryPath = rootModuleDir.resolve(dir);
+ Files.createDirectories(directoryPath);
+ for (String fileName : fileNames) {
+ Files.write(directoryPath.resolve(fileName), "content".getBytes());
+ }
+ }
+
+ Files.write(rootModuleDir.resolve(".gitignore"), "ignored.txt\ndirectory1\ndirectory2/file_a.txt".getBytes());
+ Files.write(rootModuleDir.resolve("directory3/.gitignore"), "file_b.txt".getBytes());
+ }
+}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scm/git/NativeGitBlameCommandTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scm/git/NativeGitBlameCommandTest.java
index bec6e0425f8..23d5e6ca5f0 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scm/git/NativeGitBlameCommandTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scm/git/NativeGitBlameCommandTest.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
@@ -19,7 +19,6 @@
*/
package org.sonar.scm.git;
-import com.tngtech.java.junit.dataprovider.DataProviderRunner;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
@@ -32,21 +31,21 @@ import java.util.function.Consumer;
import java.util.stream.Stream;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.junit.runner.RunWith;
+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.slf4j.event.Level;
import org.sonar.api.batch.scm.BlameLine;
+import org.sonar.api.testfixtures.log.LogTesterJUnit5;
import org.sonar.api.utils.DateUtils;
import org.sonar.api.utils.System2;
-import org.sonar.api.testfixtures.log.LogTester;
-import org.sonar.scm.git.ProcessWrapperFactory.ProcessWrapper;
+import org.sonar.core.util.ProcessWrapperFactory;
+import org.sonar.core.util.ProcessWrapperFactory.ProcessWrapper;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
-import static org.junit.Assume.assumeTrue;
+import static org.junit.jupiter.api.Assumptions.assumeTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
@@ -54,32 +53,31 @@ import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import static org.sonar.scm.git.GitUtils.createFile;
+import static org.sonar.scm.git.GitUtils.createRepository;
import static org.sonar.scm.git.NativeGitBlameCommand.BLAME_COMMAND;
import static org.sonar.scm.git.NativeGitBlameCommand.GIT_DIR_ARGUMENT;
import static org.sonar.scm.git.NativeGitBlameCommand.GIT_DIR_FLAG;
import static org.sonar.scm.git.NativeGitBlameCommand.GIT_DIR_FORCE_FLAG;
-import static org.sonar.scm.git.GitUtils.createFile;
-import static org.sonar.scm.git.GitUtils.createRepository;
import static org.sonar.scm.git.Utils.javaUnzip;
-@RunWith(DataProviderRunner.class)
-public class NativeGitBlameCommandTest {
+class NativeGitBlameCommandTest {
private static final String DUMMY_JAVA = "src/main/java/org/dummy/Dummy.java";
- @Rule
- public TemporaryFolder temp = new TemporaryFolder();
- @Rule
- public LogTester logTester = new LogTester();
+ @TempDir
+ private Path tempDir;
+ @RegisterExtension
+ private final LogTesterJUnit5 logTester = new LogTesterJUnit5();
private final ProcessWrapperFactory processWrapperFactory = new ProcessWrapperFactory();
private final NativeGitBlameCommand blameCommand = new NativeGitBlameCommand(System2.INSTANCE, processWrapperFactory);
- @Before
- public void skipTestsIfNoGitFound() {
+ @BeforeEach
+ void skipTestsIfNoGitFound() {
assumeTrue(blameCommand.checkIfEnabled());
}
@Test
- public void should_read_lines_only_based_on_new_line() throws Exception {
+ void should_read_lines_only_based_on_new_line() throws Exception {
Path baseDir = createNewTempFolder().toPath();
String filePath = "file.txt";
createFile(filePath, "test1\rtest2\r\ttest3", baseDir);
@@ -92,7 +90,7 @@ public class NativeGitBlameCommandTest {
}
@Test
- public void blame_collects_all_lines() throws Exception {
+ void blame_collects_all_lines() throws Exception {
File projectDir = createNewTempFolder();
javaUnzip("dummy-git.zip", projectDir);
File baseDir = new File(projectDir, "dummy-git");
@@ -123,7 +121,7 @@ public class NativeGitBlameCommandTest {
}
@Test
- public void blame_different_author_and_committer() throws Exception {
+ void blame_different_author_and_committer() throws Exception {
File projectDir = createNewTempFolder();
javaUnzip("dummy-git-different-committer.zip", projectDir);
File baseDir = new File(projectDir, "dummy-git");
@@ -154,21 +152,21 @@ public class NativeGitBlameCommandTest {
}
@Test
- public void git_blame_uses_safe_local_repository() throws Exception {
+ void git_blame_uses_safe_local_repository() throws Exception {
File projectDir = createNewTempFolder();
File baseDir = new File(projectDir, "dummy-git");
ProcessWrapperFactory mockFactory = mock(ProcessWrapperFactory.class);
ProcessWrapper mockProcess = mock(ProcessWrapper.class);
String gitCommand = "git";
- when(mockFactory.create(any(), any(), anyString(), anyString(), anyString(), anyString(),
+ when(mockFactory.create(any(), any(), any(), anyString(), anyString(), anyString(), anyString(),
anyString(), anyString(), anyString(), anyString(), anyString(), anyString()))
- .then(invocation -> mockProcess);
+ .then(invocation -> mockProcess);
NativeGitBlameCommand blameCommand = new NativeGitBlameCommand(gitCommand, System2.INSTANCE, mockFactory);
blameCommand.blame(baseDir.toPath(), DUMMY_JAVA);
- verify(mockFactory).create(any(), any(), eq(gitCommand),
+ verify(mockFactory).create(any(), any(), any(), eq(gitCommand),
eq(GIT_DIR_FLAG),
eq(String.format(GIT_DIR_ARGUMENT, baseDir.toPath())),
eq(GIT_DIR_FORCE_FLAG),
@@ -178,7 +176,7 @@ public class NativeGitBlameCommandTest {
}
@Test
- public void modified_file_returns_no_blame() throws Exception {
+ void modified_file_returns_no_blame() throws Exception {
File projectDir = createNewTempFolder();
javaUnzip("dummy-git.zip", projectDir);
@@ -191,9 +189,8 @@ public class NativeGitBlameCommandTest {
}
@Test
- public void throw_exception_if_symlink_found() throws Exception {
+ void throw_exception_if_symlink_found(@TempDir File projectDir) throws Exception {
assumeTrue(!System2.INSTANCE.isOsWindows());
- File projectDir = temp.newFolder();
javaUnzip("dummy-git.zip", projectDir);
Path baseDir = projectDir.toPath().resolve("dummy-git");
@@ -207,69 +204,66 @@ public class NativeGitBlameCommandTest {
}
@Test
- public void git_should_be_detected() {
+ void git_should_be_detected() {
NativeGitBlameCommand blameCommand = new NativeGitBlameCommand(System2.INSTANCE, processWrapperFactory);
assertThat(blameCommand.checkIfEnabled()).isTrue();
}
@Test
- public void git_should_not_be_detected() {
+ void git_should_not_be_detected() {
NativeGitBlameCommand blameCommand = new NativeGitBlameCommand("randomcmdthatwillneverbefound", System2.INSTANCE, processWrapperFactory);
assertThat(blameCommand.checkIfEnabled()).isFalse();
}
@Test
- public void git_should_not_be_enabled_if_version_command_is_not_found() {
+ void git_should_not_be_enabled_if_version_command_is_not_found() {
ProcessWrapperFactory mockedCmd = mockGitVersionCommand("error: unknown option `version'");
NativeGitBlameCommand blameCommand = new NativeGitBlameCommand(System2.INSTANCE, mockedCmd);
assertThat(blameCommand.checkIfEnabled()).isFalse();
}
@Test
- public void git_should_not_be_enabled_if_version_command_does_not_return_string_output() {
+ void git_should_not_be_enabled_if_version_command_does_not_return_string_output() {
ProcessWrapperFactory mockedCmd = mockGitVersionCommand(null);
NativeGitBlameCommand blameCommand = new NativeGitBlameCommand(System2.INSTANCE, mockedCmd);
assertThat(blameCommand.checkIfEnabled()).isFalse();
}
@Test
- public void git_should_be_enabled_if_version_is_equal_or_greater_than_required_minimum() {
+ void git_should_be_enabled_if_version_is_equal_or_greater_than_required_minimum() {
Stream.of(
"git version 2.24.0",
"git version 2.25.2.1",
"git version 2.24.1.1.windows.2",
- "git version 2.25.1.msysgit.2"
- ).forEach(output -> {
- ProcessWrapperFactory mockedCmd = mockGitVersionCommand(output);
- mockGitWhereOnWindows(mockedCmd);
- when(mockedCmd.create(isNull(), any(), eq("C:\\mockGit.exe"), eq("--version"))).then(invocation -> {
- var argument = (Consumer<String>) invocation.getArgument(1);
- argument.accept(output);
- return mock(ProcessWrapper.class);
+ "git version 2.25.1.msysgit.2").forEach(output -> {
+ ProcessWrapperFactory mockedCmd = mockGitVersionCommand(output);
+ mockGitWhereOnWindows(mockedCmd);
+ when(mockedCmd.create(isNull(), any(), any(), eq("C:\\mockGit.exe"), eq("--version"))).then(invocation -> {
+ var argument = (Consumer<String>) invocation.getArgument(1);
+ argument.accept(output);
+ return mock(ProcessWrapper.class);
+ });
+
+ NativeGitBlameCommand blameCommand = new NativeGitBlameCommand(System2.INSTANCE, mockedCmd);
+ assertThat(blameCommand.checkIfEnabled()).isTrue();
});
-
- NativeGitBlameCommand blameCommand = new NativeGitBlameCommand(System2.INSTANCE, mockedCmd);
- assertThat(blameCommand.checkIfEnabled()).isTrue();
- });
}
@Test
- public void git_should_not_be_enabled_if_version_is_less_than_required_minimum() {
+ void git_should_not_be_enabled_if_version_is_less_than_required_minimum() {
ProcessWrapperFactory mockFactory = mockGitVersionCommand("git version 1.9.0");
NativeGitBlameCommand blameCommand = new NativeGitBlameCommand(System2.INSTANCE, mockFactory);
assertThat(blameCommand.checkIfEnabled()).isFalse();
}
@Test
- public void throw_exception_if_command_fails() throws Exception {
- Path baseDir = temp.newFolder().toPath();
+ void throw_exception_if_command_fails(@TempDir Path baseDir) {
NativeGitBlameCommand blameCommand = new NativeGitBlameCommand("randomcmdthatwillneverbefound", System2.INSTANCE, processWrapperFactory);
assertThatThrownBy(() -> blameCommand.blame(baseDir, "file")).isInstanceOf(IOException.class);
}
@Test
- public void blame_without_email_doesnt_fail() throws Exception {
- Path baseDir = temp.newFolder().toPath();
+ void blame_without_email_doesnt_fail(@TempDir Path baseDir) throws Exception {
Git git = createRepository(baseDir);
String filePath = "file.txt";
createFile(filePath, "line", baseDir);
@@ -286,8 +280,7 @@ public class NativeGitBlameCommandTest {
}
@Test
- public void blame_mail_with_spaces_doesnt_fail() throws Exception {
- Path baseDir = temp.newFolder().toPath();
+ void blame_mail_with_spaces_doesnt_fail(@TempDir Path baseDir) throws Exception {
Git git = createRepository(baseDir);
String filePath = "file.txt";
createFile(filePath, "line", baseDir);
@@ -301,25 +294,7 @@ public class NativeGitBlameCommandTest {
}
@Test
- public void do_not_execute() throws Exception {
- Path baseDir = temp.newFolder().toPath();
- Git git = createRepository(baseDir);
- String filePath = "file.txt";
- createFile(filePath, "line", baseDir);
- commitWithNoEmail(git, filePath);
-
- NativeGitBlameCommand blameCommand = new NativeGitBlameCommand(System2.INSTANCE, processWrapperFactory);
- assertThat(blameCommand.checkIfEnabled()).isTrue();
- List<BlameLine> blame = blameCommand.blame(baseDir, filePath);
- assertThat(blame).hasSize(1);
- BlameLine blameLine = blame.get(0);
- assertThat(blameLine.author()).isNull();
- assertThat(blameLine.revision()).isNotNull();
- assertThat(blameLine.date()).isNotNull();
- }
-
- @Test
- public void execution_on_windows_should_fallback_to_full_path() {
+ void execution_on_windows_should_fallback_to_full_path() {
logTester.setLevel(Level.DEBUG);
System2 system2 = mock(System2.class);
when(system2.isOsWindows()).thenReturn(true);
@@ -328,7 +303,7 @@ public class NativeGitBlameCommandTest {
ProcessWrapper mockProcess = mock(ProcessWrapper.class);
mockGitWhereOnWindows(mockFactory);
- when(mockFactory.create(isNull(), any(), eq("C:\\mockGit.exe"), eq("--version"))).then(invocation -> {
+ when(mockFactory.create(isNull(), any(), any(), eq("C:\\mockGit.exe"), eq("--version"))).then(invocation -> {
var argument = (Consumer<String>) invocation.getArgument(1);
argument.accept("git version 2.30.1");
return mockProcess;
@@ -340,7 +315,7 @@ public class NativeGitBlameCommandTest {
}
@Test
- public void execution_on_windows_is_disabled_if_git_not_on_path() {
+ void execution_on_windows_is_disabled_if_git_not_on_path() {
System2 system2 = mock(System2.class);
when(system2.isOsWindows()).thenReturn(true);
when(system2.property("PATH")).thenReturn("C:\\some-path;C:\\some-another-path");
@@ -367,11 +342,11 @@ public class NativeGitBlameCommandTest {
private File createNewTempFolder() throws IOException {
// This is needed for Windows, otherwise the created File point to invalid (shortened by Windows) temp folder path
- return temp.newFolder().toPath().toRealPath(LinkOption.NOFOLLOW_LINKS).toFile();
+ return tempDir.toRealPath(LinkOption.NOFOLLOW_LINKS).toFile();
}
private void mockGitWhereOnWindows(ProcessWrapperFactory processWrapperFactory) {
- when(processWrapperFactory.create(isNull(), any(), eq("C:\\Windows\\System32\\where.exe"), eq("$PATH:git.exe"))).then(invocation -> {
+ when(processWrapperFactory.create(isNull(), any(), any(), eq("C:\\Windows\\System32\\where.exe"), eq("$PATH:git.exe"))).then(invocation -> {
var argument = (Consumer<String>) invocation.getArgument(1);
argument.accept("C:\\mockGit.exe");
return mock(ProcessWrapper.class);
@@ -382,7 +357,7 @@ public class NativeGitBlameCommandTest {
ProcessWrapperFactory mockFactory = mock(ProcessWrapperFactory.class);
ProcessWrapper mockProcess = mock(ProcessWrapper.class);
- when(mockFactory.create(isNull(), any(), eq("git"), eq("--version"))).then(invocation -> {
+ when(mockFactory.create(isNull(), any(), any(), eq("git"), eq("--version"))).then(invocation -> {
var argument = (Consumer<String>) invocation.getArgument(1);
argument.accept(commandOutput);
return mockProcess;
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scm/git/ProcessWrapperFactoryTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scm/git/ProcessWrapperFactoryTest.java
deleted file mode 100644
index ed7b600cd25..00000000000
--- a/sonar-scanner-engine/src/test/java/org/sonar/scm/git/ProcessWrapperFactoryTest.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2024 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.scm.git;
-
-import java.io.IOException;
-import java.util.Map;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.slf4j.event.Level;
-import org.sonar.api.testfixtures.log.LogTester;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-
-public class ProcessWrapperFactoryTest {
-
- @Rule
- public TemporaryFolder temp = new TemporaryFolder();
- @Rule
- public LogTester logTester = new LogTester();
- private final ProcessWrapperFactory underTest = new ProcessWrapperFactory();
-
- @Test
- public void should_log_error_output_in_debug_mode() throws IOException {
- logTester.setLevel(Level.DEBUG);
- var root = temp.newFolder().toPath();
- var processWrapper = underTest.create(root, v -> {}, Map.of("LANG", "en_US"), "git", "blame");
- assertThatThrownBy(processWrapper::execute)
- .isInstanceOf(IllegalStateException.class);
-
- assertThat(logTester.logs(Level.DEBUG).get(0)).startsWith("fatal:");
- }
-
-}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scm/git/Utils.java b/sonar-scanner-engine/src/test/java/org/sonar/scm/git/Utils.java
index d81394769af..0c6dae20923 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scm/git/Utils.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scm/git/Utils.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/test/java/org/sonar/scm/git/strategy/DefaultBlameStrategyTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scm/git/strategy/DefaultBlameStrategyTest.java
index 46c6b38272f..b15b95a9290 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scm/git/strategy/DefaultBlameStrategyTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scm/git/strategy/DefaultBlameStrategyTest.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/test/java/org/sonar/scm/svn/ChangedLinesComputerTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scm/svn/ChangedLinesComputerTest.java
index f55ba21efc7..c6e0d6b0f56 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scm/svn/ChangedLinesComputerTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scm/svn/ChangedLinesComputerTest.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/test/java/org/sonar/scm/svn/SvnConfigurationTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scm/svn/SvnConfigurationTest.java
index c7c3b597fd6..8759cf6a8a7 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scm/svn/SvnConfigurationTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scm/svn/SvnConfigurationTest.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/test/java/org/sonar/scm/svn/SvnScmProviderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scm/svn/SvnScmProviderTest.java
index 89dc17cf905..0ce98997831 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scm/svn/SvnScmProviderTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scm/svn/SvnScmProviderTest.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/test/java/org/sonar/scm/svn/SvnScmSupportTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scm/svn/SvnScmSupportTest.java
index 9b7d75a9da7..59534340fa2 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scm/svn/SvnScmSupportTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scm/svn/SvnScmSupportTest.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