From b7afbcb9ba7bf3f9321949ecdd9de65d48fc9fce Mon Sep 17 00:00:00 2001 From: Duarte Meneses Date: Wed, 6 Jun 2018 09:17:31 +0200 Subject: [PATCH] SONAR-10206 Allow to configure the location where scanner writes report-task.txt --- .../scanner/report/MetadataPublisher.java | 14 +-- .../sonar/scanner/report/ReportPublisher.java | 48 ++++---- .../DefaultQualityProfileLoader.java | 33 ++---- .../scanner/scan/ProjectScanContainer.java | 10 +- .../sonar/scanner/scan/ScanProperties.java | 89 +++++++++++++++ .../scan/filesystem/InputFileBuilder.java | 8 +- .../mediumtest/ScannerMediumTester.java | 4 +- .../scanner/report/MetadataPublisherTest.java | 30 ++--- .../scanner/report/ReportPublisherTest.java | 99 ++++++---------- .../DefaultQualityProfileLoaderTest.java | 12 +- .../scanner/scan/ScanPropertiesTest.java | 108 ++++++++++++++++++ .../scan/filesystem/InputFileBuilderTest.java | 5 +- 12 files changed, 306 insertions(+), 154 deletions(-) create mode 100644 sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ScanProperties.java create mode 100644 sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ScanPropertiesTest.java diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/MetadataPublisher.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/MetadataPublisher.java index a17c691f8bb..4cb964ab2c4 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/MetadataPublisher.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/MetadataPublisher.java @@ -28,7 +28,6 @@ import javax.annotation.Nullable; import org.sonar.api.batch.fs.internal.DefaultInputModule; import org.sonar.api.batch.fs.internal.InputModuleHierarchy; import org.sonar.api.batch.scm.ScmProvider; -import org.sonar.api.config.Configuration; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.scanner.ProjectAnalysisInfo; @@ -40,6 +39,7 @@ import org.sonar.scanner.protocol.output.ScannerReport.Metadata.BranchType; import org.sonar.scanner.protocol.output.ScannerReportWriter; import org.sonar.scanner.rule.ModuleQProfiles; import org.sonar.scanner.rule.QProfile; +import org.sonar.scanner.scan.ScanProperties; import org.sonar.scanner.scan.branch.BranchConfiguration; import org.sonar.scanner.scm.ScmConfiguration; @@ -49,7 +49,7 @@ public class MetadataPublisher implements ReportPublisherStep { private static final Logger LOG = Loggers.get(MetadataPublisher.class); - private final Configuration settings; + private final ScanProperties properties; private final ModuleQProfiles qProfiles; private final ProjectAnalysisInfo projectAnalysisInfo; private final InputModuleHierarchy moduleHierarchy; @@ -60,12 +60,12 @@ public class MetadataPublisher implements ReportPublisherStep { @Nullable private final ScmConfiguration scmConfiguration; - public MetadataPublisher(ProjectAnalysisInfo projectAnalysisInfo, InputModuleHierarchy moduleHierarchy, Configuration settings, + public MetadataPublisher(ProjectAnalysisInfo projectAnalysisInfo, InputModuleHierarchy moduleHierarchy, ScanProperties properties, ModuleQProfiles qProfiles, CpdSettings cpdSettings, ScannerPluginRepository pluginRepository, BranchConfiguration branchConfiguration, @Nullable ScmConfiguration scmConfiguration) { this.projectAnalysisInfo = projectAnalysisInfo; this.moduleHierarchy = moduleHierarchy; - this.settings = settings; + this.properties = properties; this.qProfiles = qProfiles; this.cpdSettings = cpdSettings; this.pluginRepository = pluginRepository; @@ -73,9 +73,9 @@ public class MetadataPublisher implements ReportPublisherStep { this.scmConfiguration = scmConfiguration; } - public MetadataPublisher(ProjectAnalysisInfo projectAnalysisInfo, InputModuleHierarchy moduleHierarchy, Configuration settings, + public MetadataPublisher(ProjectAnalysisInfo projectAnalysisInfo, InputModuleHierarchy moduleHierarchy, ScanProperties properties, ModuleQProfiles qProfiles, CpdSettings cpdSettings, ScannerPluginRepository pluginRepository, BranchConfiguration branchConfiguration) { - this(projectAnalysisInfo, moduleHierarchy, settings, qProfiles, cpdSettings, pluginRepository, branchConfiguration, null); + this(projectAnalysisInfo, moduleHierarchy, properties, qProfiles, cpdSettings, pluginRepository, branchConfiguration, null); } @Override @@ -88,7 +88,7 @@ public class MetadataPublisher implements ReportPublisherStep { .setCrossProjectDuplicationActivated(cpdSettings.isCrossProjectDuplicationEnabled()) .setRootComponentRef(rootProject.batchId()); - settings.get(ORGANIZATION).ifPresent(builder::setOrganizationKey); + properties.organizationKey().ifPresent(builder::setOrganizationKey); if (branchConfiguration.branchName() != null) { addBranchInformation(builder); diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ReportPublisher.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ReportPublisher.java index 714199de09c..11cd6a0f63d 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ReportPublisher.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ReportPublisher.java @@ -38,7 +38,6 @@ import org.apache.commons.io.FileUtils; import org.picocontainer.Startable; import org.sonar.api.batch.ScannerSide; import org.sonar.api.batch.fs.internal.InputModuleHierarchy; -import org.sonar.api.config.Configuration; import org.sonar.api.platform.Server; import org.sonar.api.utils.MessageException; import org.sonar.api.utils.TempFolder; @@ -48,6 +47,7 @@ import org.sonar.api.utils.log.Loggers; import org.sonar.scanner.bootstrap.GlobalAnalysisMode; import org.sonar.scanner.bootstrap.ScannerWsClient; import org.sonar.scanner.protocol.output.ScannerReportWriter; +import org.sonar.scanner.scan.ScanProperties; import org.sonar.scanner.scan.branch.BranchConfiguration; import org.sonarqube.ws.Ce; import org.sonarqube.ws.MediaTypes; @@ -58,8 +58,6 @@ import org.sonarqube.ws.client.WsResponse; import static java.net.URLEncoder.encode; import static org.apache.commons.lang.StringUtils.EMPTY; import static org.apache.commons.lang.StringUtils.isBlank; -import static org.sonar.core.config.ScannerProperties.BRANCH_NAME; -import static org.sonar.core.config.ScannerProperties.ORGANIZATION; import static org.sonar.core.util.FileUtils.deleteQuietly; import static org.sonar.scanner.scan.branch.BranchType.LONG; import static org.sonar.scanner.scan.branch.BranchType.PULL_REQUEST; @@ -69,18 +67,12 @@ import static org.sonar.scanner.scan.branch.BranchType.SHORT; public class ReportPublisher implements Startable { private static final Logger LOG = Loggers.get(ReportPublisher.class); - - public static final String KEEP_REPORT_PROP_KEY = "sonar.scanner.keepReport"; - public static final String VERBOSE_KEY = "sonar.verbose"; - public static final String METADATA_DUMP_FILENAME = "report-task.txt"; private static final String CHARACTERISTIC = "characteristic"; - private static final String DASHBOARD = "dashboard"; private static final String BRANCH = "branch"; private static final String ID = "id"; private static final String RESOLVED = "resolved"; - private final Configuration settings; private final ScannerWsClient wsClient; private final AnalysisContextReportPublisher contextPublisher; private final InputModuleHierarchy moduleHierarchy; @@ -89,13 +81,13 @@ public class ReportPublisher implements Startable { private final ReportPublisherStep[] publishers; private final Server server; private final BranchConfiguration branchConfiguration; + private final ScanProperties properties; private Path reportDir; private ScannerReportWriter writer; - public ReportPublisher(Configuration settings, ScannerWsClient wsClient, Server server, AnalysisContextReportPublisher contextPublisher, + public ReportPublisher(ScanProperties properties, ScannerWsClient wsClient, Server server, AnalysisContextReportPublisher contextPublisher, InputModuleHierarchy moduleHierarchy, GlobalAnalysisMode analysisMode, TempFolder temp, ReportPublisherStep[] publishers, BranchConfiguration branchConfiguration) { - this.settings = settings; this.wsClient = wsClient; this.server = server; this.contextPublisher = contextPublisher; @@ -104,6 +96,7 @@ public class ReportPublisher implements Startable { this.temp = temp; this.publishers = publishers; this.branchConfiguration = branchConfiguration; + this.properties = properties; } @Override @@ -122,7 +115,7 @@ public class ReportPublisher implements Startable { @Override public void stop() { - if (!shouldKeepReport()) { + if (!properties.shouldKeepReport()) { deleteQuietly(reportDir); } } @@ -140,7 +133,7 @@ public class ReportPublisher implements Startable { String taskId = null; if (!analysisMode.isIssues()) { File report = generateReportFile(); - if (shouldKeepReport()) { + if (properties.shouldKeepReport()) { LOG.info("Analysis report generated in " + reportDir); } if (!analysisMode.isMediumTest()) { @@ -150,10 +143,6 @@ public class ReportPublisher implements Startable { logSuccess(taskId); } - private boolean shouldKeepReport() { - return settings.getBoolean(KEEP_REPORT_PROP_KEY).orElse(false) || settings.getBoolean(VERBOSE_KEY).orElse(false); - } - private File generateReportFile() { try { long startTime = System.currentTimeMillis(); @@ -184,7 +173,7 @@ public class ReportPublisher implements Startable { PostRequest.Part filePart = new PostRequest.Part(MediaTypes.ZIP, report); PostRequest post = new PostRequest("api/ce/submit") .setMediaType(MediaTypes.PROTOBUF) - .setParam("organization", settings.get(ORGANIZATION).orElse(null)) + .setParam("organization", properties.organizationKey().orElse(null)) .setParam("projectKey", moduleHierarchy.root().key()) .setParam("projectName", moduleHierarchy.root().getOriginalName()) .setParam("projectBranch", moduleHierarchy.root().getBranch()) @@ -225,11 +214,11 @@ public class ReportPublisher implements Startable { Map metadata = new LinkedHashMap<>(); String effectiveKey = moduleHierarchy.root().getKeyWithBranch(); - settings.get(ORGANIZATION).ifPresent(org -> metadata.put("organization", org)); + properties.organizationKey().ifPresent(org -> metadata.put("organization", org)); metadata.put("projectKey", effectiveKey); metadata.put("serverUrl", server.getPublicRootUrl()); metadata.put("serverVersion", server.getVersion()); - settings.get(BRANCH_NAME).ifPresent(branch -> metadata.put(BRANCH, branch)); + properties.branch().ifPresent(branch -> metadata.put("branch", branch)); URL dashboardUrl = buildDashboardUrl(server.getPublicRootUrl(), effectiveKey); metadata.put("dashboardUrl", dashboardUrl.toExternalForm()); @@ -311,7 +300,7 @@ public class ReportPublisher implements Startable { } private static String encoded(@Nullable String queryParameter) { - if (isBlank(queryParameter)){ + if (isBlank(queryParameter)) { return EMPTY; } try { @@ -322,13 +311,16 @@ public class ReportPublisher implements Startable { } private void dumpMetadata(Map metadata) { - Path file = moduleHierarchy.root().getWorkDir().resolve(METADATA_DUMP_FILENAME); - try (Writer output = Files.newBufferedWriter(file, StandardCharsets.UTF_8)) { - for (Map.Entry entry : metadata.entrySet()) { - output.write(entry.getKey()); - output.write("="); - output.write(entry.getValue()); - output.write("\n"); + Path file = properties.metadataFilePath(); + try { + Files.createDirectories(file.getParent()); + try (Writer output = Files.newBufferedWriter(file, StandardCharsets.UTF_8)) { + for (Map.Entry entry : metadata.entrySet()) { + output.write(entry.getKey()); + output.write("="); + output.write(entry.getValue()); + output.write("\n"); + } } LOG.debug("Report metadata written to {}", file); diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/DefaultQualityProfileLoader.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/DefaultQualityProfileLoader.java index d8b31de2393..0b2be6f39e9 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/DefaultQualityProfileLoader.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/DefaultQualityProfileLoader.java @@ -25,30 +25,27 @@ import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.function.BinaryOperator; import javax.annotation.Nullable; -import org.apache.commons.io.IOUtils; -import org.sonar.api.config.Configuration; import org.sonar.api.utils.MessageException; import org.sonar.scanner.bootstrap.ScannerWsClient; +import org.sonar.scanner.scan.ScanProperties; import org.sonarqube.ws.Qualityprofiles.SearchWsResponse; import org.sonarqube.ws.Qualityprofiles.SearchWsResponse.QualityProfile; import org.sonarqube.ws.client.GetRequest; import static java.util.function.Function.identity; import static java.util.stream.Collectors.toMap; -import static org.sonar.core.config.ScannerProperties.ORGANIZATION; import static org.sonar.scanner.util.ScannerUtils.encodeForUrl; public class DefaultQualityProfileLoader implements QualityProfileLoader { private static final String WS_URL = "/api/qualityprofiles/search.protobuf"; - private final Configuration settings; private final ScannerWsClient wsClient; + private final ScanProperties properties; - public DefaultQualityProfileLoader(Configuration settings, ScannerWsClient wsClient) { - this.settings = settings; + public DefaultQualityProfileLoader(ScanProperties properties, ScannerWsClient wsClient) { + this.properties = properties; this.wsClient = wsClient; } @@ -65,13 +62,13 @@ public class DefaultQualityProfileLoader implements QualityProfileLoader { } private List loadAndOverrideIfNeeded(@Nullable String profileName, StringBuilder url) { - getOrganizationKey().ifPresent(k -> url.append("&organization=").append(encodeForUrl(k))); + properties.organizationKey().ifPresent(k -> url.append("&organization=").append(encodeForUrl(k))); Map result = call(url.toString()); if (profileName != null) { StringBuilder urlForName = new StringBuilder(WS_URL + "?profileName="); urlForName.append(encodeForUrl(profileName)); - getOrganizationKey().ifPresent(k -> urlForName.append("&organization=").append(encodeForUrl(k))); + properties.organizationKey().ifPresent(k -> urlForName.append("&organization=").append(encodeForUrl(k))); result.putAll(call(urlForName.toString())); } if (result.isEmpty()) { @@ -81,26 +78,16 @@ public class DefaultQualityProfileLoader implements QualityProfileLoader { return new ArrayList<>(result.values()); } - private Optional getOrganizationKey() { - return settings.get(ORGANIZATION); - } - private Map call(String url) { GetRequest getRequest = new GetRequest(url); - InputStream is = wsClient.call(getRequest).contentStream(); - SearchWsResponse profiles; - - try { - profiles = SearchWsResponse.parseFrom(is); + try (InputStream is = wsClient.call(getRequest).contentStream()) { + SearchWsResponse profiles = SearchWsResponse.parseFrom(is); + List profilesList = profiles.getProfilesList(); + return profilesList.stream().collect(toMap(QualityProfile::getLanguage, identity(), throwingMerger(), LinkedHashMap::new)); } catch (IOException e) { throw new IllegalStateException("Failed to load quality profiles", e); - } finally { - IOUtils.closeQuietly(is); } - List profilesList = profiles.getProfilesList(); - return profilesList.stream() - .collect(toMap(QualityProfile::getLanguage, identity(), throwingMerger(), LinkedHashMap::new)); } private static BinaryOperator throwingMerger() { diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java index c81845047b1..a44ac36b0ec 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java @@ -134,6 +134,7 @@ public class ProjectScanContainer extends ComponentContainer { add( props, ProjectReactorBuilder.class, + ScanProperties.class, WorkDirectoriesInitializer.class, new MutableProjectReactorProvider(), ProjectBuildersExecutor.class, @@ -197,6 +198,7 @@ public class ProjectScanContainer extends ComponentContainer { SensorStrategy.class, MutableProjectSettings.class, + ScannerProperties.class, new ProjectSettingsProvider(), // Report @@ -244,13 +246,13 @@ public class ProjectScanContainer extends ComponentContainer { protected void doAfterStart() { GlobalAnalysisMode analysisMode = getComponentByType(GlobalAnalysisMode.class); InputModuleHierarchy tree = getComponentByType(InputModuleHierarchy.class); + ScanProperties properties = getComponentByType(ScanProperties.class); + properties.validate(); LOG.info("Project key: {}", tree.root().key()); LOG.info("Project base dir: {}", tree.root().getBaseDir()); - String organization = props.property("sonar.organization"); - if (StringUtils.isNotEmpty(organization)) { - LOG.info("Organization key: {}", organization); - } + properties.organizationKey().ifPresent(k -> LOG.info("Organization key: {}", k)); + String branch = tree.root().definition().getBranch(); if (branch != null) { LOG.info("Branch key: {}", branch); diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ScanProperties.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ScanProperties.java new file mode 100644 index 00000000000..e7cd97e2e74 --- /dev/null +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ScanProperties.java @@ -0,0 +1,89 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 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; + +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Optional; +import org.sonar.api.batch.ScannerSide; +import org.sonar.api.batch.fs.internal.InputModuleHierarchy; +import org.sonar.api.config.Configuration; +import org.sonar.api.utils.MessageException; + +import static org.sonar.core.config.ScannerProperties.BRANCH_NAME; +import static org.sonar.core.config.ScannerProperties.ORGANIZATION; + +/** + * Properties that can be passed to the scanners and are not exposed in SonarQube. + */ +@ScannerSide +public class ScanProperties { + public static final String METADATA_FILE_PATH_KEY = "sonar.scanner.metadataFilePath"; + public static final String KEEP_REPORT_PROP_KEY = "sonar.scanner.keepReport"; + public static final String VERBOSE_KEY = "sonar.verbose"; + public static final String METADATA_DUMP_FILENAME = "report-task.txt"; + public static final String SONAR_REPORT_EXPORT_PATH = "sonar.report.export.path"; + public static final String PRELOAD_FILE_METADATA_KEY = "sonar.preloadFileMetadata"; + public static final String FORCE_RELOAD_KEY = "sonar.scm.forceReloadAll"; + + private final Configuration configuration; + private final InputModuleHierarchy moduleHierarchy; + + public ScanProperties(Configuration configuration, InputModuleHierarchy moduleHierarchy) { + this.configuration = configuration; + this.moduleHierarchy = moduleHierarchy; + } + + public boolean shouldKeepReport() { + return configuration.getBoolean(KEEP_REPORT_PROP_KEY).orElse(false) || configuration.getBoolean(VERBOSE_KEY).orElse(false); + } + + public boolean preloadFileMetadata() { + return configuration.getBoolean(PRELOAD_FILE_METADATA_KEY).orElse(false); + } + + public Optional organizationKey() { + return configuration.get(ORGANIZATION); + } + + public Optional branch() { + return configuration.get(BRANCH_NAME); + } + + public Path metadataFilePath() { + Optional metadataFilePath = configuration.get(METADATA_FILE_PATH_KEY); + if (metadataFilePath.isPresent()) { + Path metadataPath = Paths.get(metadataFilePath.get()); + if (!metadataPath.isAbsolute()) { + throw MessageException.of(String.format("Property '%s' must point to an absolute path: %s", METADATA_FILE_PATH_KEY, metadataFilePath.get())); + } + return moduleHierarchy.root().getBaseDir().resolve(metadataPath); + } else { + return moduleHierarchy.root().getWorkDir().resolve(METADATA_DUMP_FILENAME); + } + } + + /** + * This should be called in the beginning of the analysis to fail fast + */ + public void validate() { + metadataFilePath(); + } +} diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputFileBuilder.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputFileBuilder.java index 33e3bcbf3d1..b6bf1899b6f 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputFileBuilder.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputFileBuilder.java @@ -27,11 +27,10 @@ import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.fs.internal.DefaultInputModule; import org.sonar.api.batch.fs.internal.InputModuleHierarchy; import org.sonar.api.batch.fs.internal.SensorStrategy; -import org.sonar.api.config.Configuration; import org.sonar.api.utils.PathUtils; +import org.sonar.scanner.scan.ScanProperties; public class InputFileBuilder { - public static final String PRELOAD_FILE_METADATA_KEY = "sonar.preloadFileMetadata"; private final String moduleKey; private final Path moduleBaseDir; private final BatchIdGenerator idGenerator; @@ -42,7 +41,8 @@ public class InputFileBuilder { private final SensorStrategy sensorStrategy; public InputFileBuilder(DefaultInputModule module, MetadataGenerator metadataGenerator, - BatchIdGenerator idGenerator, Configuration settings, ModuleFileSystemInitializer moduleFileSystemInitializer, InputModuleHierarchy hierarchy, SensorStrategy sensorStrategy) { + BatchIdGenerator idGenerator, ScanProperties properties, ModuleFileSystemInitializer moduleFileSystemInitializer, InputModuleHierarchy hierarchy, + SensorStrategy sensorStrategy) { this.sensorStrategy = sensorStrategy; this.projectBaseDir = hierarchy.root().getBaseDir(); this.moduleFileSystemInitializer = moduleFileSystemInitializer; @@ -50,7 +50,7 @@ public class InputFileBuilder { this.moduleBaseDir = module.getBaseDir(); this.metadataGenerator = metadataGenerator; this.idGenerator = idGenerator; - this.preloadMetadata = settings.getBoolean(PRELOAD_FILE_METADATA_KEY).orElse(false); + this.preloadMetadata = properties.preloadFileMetadata(); } DefaultInputFile create(InputFile.Type type, Path absolutePath, @Nullable String language) { diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/ScannerMediumTester.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/ScannerMediumTester.java index eb28ba1a3d0..896df555431 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/ScannerMediumTester.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/ScannerMediumTester.java @@ -53,6 +53,7 @@ import org.sonar.api.utils.DateUtils; import org.sonar.batch.bootstrapper.Batch; import org.sonar.batch.bootstrapper.EnvironmentInformation; import org.sonar.batch.bootstrapper.LogOutput; +import org.sonar.core.config.ScannerProperties; import org.sonar.scanner.bootstrap.GlobalAnalysisMode; import org.sonar.scanner.issue.tracking.ServerLineHashesLoader; import org.sonar.scanner.protocol.input.ScannerInput.ServerIssue; @@ -68,6 +69,7 @@ import org.sonar.scanner.repository.settings.SettingsLoader; import org.sonar.scanner.rule.ActiveRulesLoader; import org.sonar.scanner.rule.LoadedActiveRule; import org.sonar.scanner.rule.RulesLoader; +import org.sonar.scanner.scan.ScanProperties; import org.sonar.scanner.scan.branch.BranchConfiguration; import org.sonar.scanner.scan.branch.BranchConfigurationLoader; import org.sonar.scanner.scan.branch.BranchType; @@ -243,7 +245,7 @@ public class ScannerMediumTester extends ExternalResource { } registerCoreMetrics(); globalProperties.put(GlobalAnalysisMode.MEDIUM_TEST_ENABLED, "true"); - globalProperties.put(ReportPublisher.KEEP_REPORT_PROP_KEY, "true"); + globalProperties.put(ScanProperties.KEEP_REPORT_PROP_KEY, "true"); globalProperties.put("sonar.userHome", userHome.toString()); } 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 f8af70d532c..46290e6a4bf 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 @@ -25,6 +25,7 @@ import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Date; +import java.util.Optional; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -46,6 +47,7 @@ import org.sonar.scanner.protocol.output.ScannerReportReader; import org.sonar.scanner.protocol.output.ScannerReportWriter; import org.sonar.scanner.rule.ModuleQProfiles; import org.sonar.scanner.rule.QProfile; +import org.sonar.scanner.scan.ScanProperties; import org.sonar.scanner.scan.branch.BranchConfiguration; import org.sonar.scanner.scan.branch.BranchType; import org.sonar.scanner.scm.ScmConfiguration; @@ -65,26 +67,19 @@ public class MetadataPublisherTest { private DefaultInputModule rootModule; private MetadataPublisher underTest; - private MapSettings settings; - private ModuleQProfiles qProfiles; - private ProjectAnalysisInfo projectAnalysisInfo; - private CpdSettings cpdSettings; + private ScanProperties properties = mock(ScanProperties.class); + private ModuleQProfiles qProfiles = mock(ModuleQProfiles.class); + private ProjectAnalysisInfo projectAnalysisInfo = mock(ProjectAnalysisInfo.class); + private CpdSettings cpdSettings = mock(CpdSettings.class); private InputModuleHierarchy inputModuleHierarchy; - private ScannerPluginRepository pluginRepository; + private ScannerPluginRepository pluginRepository = mock(ScannerPluginRepository.class); private BranchConfiguration branches; private ScmConfiguration scmConfiguration; - private ScmProvider scmProvider; + private ScmProvider scmProvider = mock(ScmProvider.class); @Before public void prepare() throws IOException { - projectAnalysisInfo = mock(ProjectAnalysisInfo.class); - cpdSettings = mock(CpdSettings.class); when(projectAnalysisInfo.analysisDate()).thenReturn(new Date(1234567L)); - settings = new MapSettings(); - qProfiles = mock(ModuleQProfiles.class); - pluginRepository = mock(ScannerPluginRepository.class); - - scmProvider = mock(ScmProvider.class); when(scmProvider.relativePathFromScmRoot(any(Path.class))).thenReturn(Paths.get("dummy/path")); when(scmProvider.revisionId(any(Path.class))).thenReturn("dummy-sha1"); @@ -99,13 +94,12 @@ public class MetadataPublisherTest { branches = mock(BranchConfiguration.class); scmConfiguration = mock(ScmConfiguration.class); when(scmConfiguration.provider()).thenReturn(scmProvider); - underTest = new MetadataPublisher(projectAnalysisInfo, inputModuleHierarchy, settings.asConfig(), qProfiles, cpdSettings, + underTest = new MetadataPublisher(projectAnalysisInfo, inputModuleHierarchy, properties, qProfiles, cpdSettings, pluginRepository, branches, scmConfiguration); } @Test public void write_metadata() throws Exception { - settings.setProperty(CoreProperties.CPD_CROSS_PROJECT, "true"); Date date = new Date(); when(qProfiles.findAll()).thenReturn(asList(new QProfile("q1", "Q1", "java", date))); when(pluginRepository.getPluginsByKey()).thenReturn(ImmutableMap.of( @@ -140,8 +134,6 @@ public class MetadataPublisherTest { @Test public void write_project_branch() throws Exception { when(cpdSettings.isCrossProjectDuplicationEnabled()).thenReturn(false); - settings.setProperty(CoreProperties.CPD_CROSS_PROJECT, "true"); - settings.setProperty(CoreProperties.PROJECT_BRANCH_PROPERTY, "myBranch"); ProjectDefinition projectDef = ProjectDefinition.create() .setKey("foo") @@ -163,7 +155,7 @@ public class MetadataPublisherTest { @Test public void write_project_organization() throws Exception { - settings.setProperty(ScannerProperties.ORGANIZATION, "SonarSource"); + when(properties.organizationKey()).thenReturn(Optional.of("SonarSource")); File outputDir = temp.newFolder(); ScannerReportWriter writer = new ScannerReportWriter(outputDir); @@ -172,7 +164,7 @@ public class MetadataPublisherTest { ScannerReportReader reader = new ScannerReportReader(outputDir); ScannerReport.Metadata metadata = reader.readMetadata(); - assertThat(metadata.getOrganizationKey()).isEqualTo("SonarSource"); + assertThat(properties.organizationKey()).isEqualTo(Optional.of("SonarSource")); } @Test 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 9213c5d0146..43293b246e1 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 @@ -19,12 +19,13 @@ */ package org.sonar.scanner.report; -import java.io.File; import java.io.IOException; import java.io.PipedInputStream; import java.io.PipedOutputStream; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; +import java.util.Optional; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -35,17 +36,14 @@ import org.mockito.Mockito; import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.batch.fs.internal.DefaultInputModule; import org.sonar.api.batch.fs.internal.InputModuleHierarchy; -import org.sonar.api.config.PropertyDefinitions; -import org.sonar.api.config.internal.MapSettings; import org.sonar.api.platform.Server; import org.sonar.api.utils.MessageException; import org.sonar.api.utils.TempFolder; import org.sonar.api.utils.log.LogTester; import org.sonar.api.utils.log.LoggerLevel; -import org.sonar.core.config.CorePropertyDefinitions; -import org.sonar.core.config.ScannerProperties; import org.sonar.scanner.bootstrap.GlobalAnalysisMode; import org.sonar.scanner.bootstrap.ScannerWsClient; +import org.sonar.scanner.scan.ScanProperties; import org.sonar.scanner.scan.branch.BranchConfiguration; import org.sonarqube.ws.Ce; import org.sonarqube.ws.client.HttpException; @@ -54,7 +52,6 @@ import org.sonarqube.ws.client.WsResponse; import static org.apache.commons.io.FileUtils.readFileToString; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.entry; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -75,29 +72,30 @@ public class ReportPublisherTest { public ExpectedException exception = ExpectedException.none(); GlobalAnalysisMode mode = mock(GlobalAnalysisMode.class); - MapSettings settings = new MapSettings(new PropertyDefinitions(CorePropertyDefinitions.all())); - ScannerWsClient wsClient; + ScanProperties properties = mock(ScanProperties.class); + ScannerWsClient wsClient = mock(ScannerWsClient.class, Mockito.RETURNS_DEEP_STUBS); Server server = mock(Server.class); InputModuleHierarchy moduleHierarchy = mock(InputModuleHierarchy.class); DefaultInputModule root; AnalysisContextReportPublisher contextPublisher = mock(AnalysisContextReportPublisher.class); BranchConfiguration branchConfiguration = mock(BranchConfiguration.class); + ReportPublisher underTest = new ReportPublisher(properties, wsClient, server, contextPublisher, moduleHierarchy, mode, mock(TempFolder.class), + new ReportPublisherStep[0], branchConfiguration); @Before public void setUp() throws IOException { - wsClient = mock(ScannerWsClient.class, Mockito.RETURNS_DEEP_STUBS); root = new DefaultInputModule(ProjectDefinition.create().setKey("org.sonarsource.sonarqube:sonarqube").setBaseDir(temp.newFolder()).setWorkDir(temp.getRoot())); when(moduleHierarchy.root()).thenReturn(root); when(server.getPublicRootUrl()).thenReturn("https://localhost"); when(server.getVersion()).thenReturn("6.4"); + when(properties.metadataFilePath()).thenReturn(temp.newFolder().toPath() + .resolve("folder") + .resolve("report-task.txt")); } @Test public void log_and_dump_information_about_report_uploading() throws IOException { - ReportPublisher underTest = new ReportPublisher(settings.asConfig(), wsClient, server, contextPublisher, moduleHierarchy, mode, - mock(TempFolder.class), new ReportPublisherStep[0], branchConfiguration); - settings.setProperty(ScannerProperties.ORGANIZATION, "MyOrg"); - + when(properties.organizationKey()).thenReturn(Optional.of("MyOrg")); underTest.logSuccess("TASK-123"); assertThat(logTester.logs(LoggerLevel.INFO)) @@ -105,8 +103,7 @@ public class ReportPublisherTest { .contains("Note that you will be able to access the updated dashboard once the server has processed the submitted analysis report") .contains("More about the report processing at https://localhost/api/ce/task?id=TASK-123"); - File detailsFile = new File(temp.getRoot(), "report-task.txt"); - assertThat(readFileToString(detailsFile)).isEqualTo( + assertThat(readFileToString(properties.metadataFilePath().toFile(), StandardCharsets.UTF_8)).isEqualTo( "organization=MyOrg\n" + "projectKey=org.sonarsource.sonarqube:sonarqube\n" + "serverUrl=https://localhost\n" + @@ -118,8 +115,6 @@ public class ReportPublisherTest { @Test public void parse_upload_error_message() throws IOException { - ReportPublisher underTest = new ReportPublisher(settings.asConfig(), wsClient, server, contextPublisher, moduleHierarchy, mode, - mock(TempFolder.class), new ReportPublisherStep[0], branchConfiguration); HttpException ex = new HttpException("url", 404, "{\"errors\":[{\"msg\":\"Organization with key 'MyOrg' does not exist\"}]}"); WsResponse response = mock(WsResponse.class); when(response.failIfNotSuccessful()).thenThrow(ex); @@ -133,8 +128,6 @@ public class ReportPublisherTest { @Test public void log_public_url_if_defined_for_main_branch() throws IOException { when(server.getPublicRootUrl()).thenReturn("https://publicserver/sonarqube"); - ReportPublisher underTest = new ReportPublisher(settings.asConfig(), wsClient, server, contextPublisher, moduleHierarchy, mode, mock(TempFolder.class), - new ReportPublisherStep[0], branchConfiguration); underTest.logSuccess("TASK-123"); @@ -142,8 +135,7 @@ public class ReportPublisherTest { .contains("ANALYSIS SUCCESSFUL, you can browse https://publicserver/sonarqube/dashboard?id=org.sonarsource.sonarqube%3Asonarqube") .contains("More about the report processing at https://publicserver/sonarqube/api/ce/task?id=TASK-123"); - File detailsFile = new File(temp.getRoot(), "report-task.txt"); - assertThat(readFileToString(detailsFile)).isEqualTo( + assertThat(readFileToString(properties.metadataFilePath().toFile(), StandardCharsets.UTF_8)).isEqualTo( "projectKey=org.sonarsource.sonarqube:sonarqube\n" + "serverUrl=https://publicserver/sonarqube\n" + "serverVersion=6.4\n" + @@ -157,7 +149,7 @@ public class ReportPublisherTest { when(server.getPublicRootUrl()).thenReturn("https://publicserver/sonarqube"); when(branchConfiguration.branchType()).thenReturn(LONG); when(branchConfiguration.branchName()).thenReturn("branch-6.7"); - ReportPublisher underTest = new ReportPublisher(settings.asConfig(), wsClient, server, contextPublisher, moduleHierarchy, mode, mock(TempFolder.class), + ReportPublisher underTest = new ReportPublisher(properties, wsClient, server, contextPublisher, moduleHierarchy, mode, mock(TempFolder.class), new ReportPublisherStep[0], branchConfiguration); underTest.logSuccess("TASK-123"); @@ -165,8 +157,7 @@ public class ReportPublisherTest { .contains("ANALYSIS SUCCESSFUL, you can browse https://publicserver/sonarqube/dashboard?id=org.sonarsource.sonarqube%3Asonarqube&branch=branch-6.7") .contains("More about the report processing at https://publicserver/sonarqube/api/ce/task?id=TASK-123"); - File detailsFile = new File(temp.getRoot(), "report-task.txt"); - assertThat(readFileToString(detailsFile)).isEqualTo( + assertThat(readFileToString(properties.metadataFilePath().toFile(), StandardCharsets.UTF_8)).isEqualTo( "projectKey=org.sonarsource.sonarqube:sonarqube\n" + "serverUrl=https://publicserver/sonarqube\n" + "serverVersion=6.4\n" + @@ -180,7 +171,7 @@ public class ReportPublisherTest { when(server.getPublicRootUrl()).thenReturn("https://publicserver/sonarqube"); when(branchConfiguration.branchType()).thenReturn(SHORT); when(branchConfiguration.branchName()).thenReturn("branch-6.7"); - ReportPublisher underTest = new ReportPublisher(settings.asConfig(), wsClient, server, contextPublisher, moduleHierarchy, mode, mock(TempFolder.class), + ReportPublisher underTest = new ReportPublisher(properties, wsClient, server, contextPublisher, moduleHierarchy, mode, mock(TempFolder.class), new ReportPublisherStep[0], branchConfiguration); underTest.logSuccess("TASK-123"); @@ -188,8 +179,7 @@ public class ReportPublisherTest { .contains("ANALYSIS SUCCESSFUL, you can browse https://publicserver/sonarqube/dashboard?id=org.sonarsource.sonarqube%3Asonarqube&branch=branch-6.7&resolved=false") .contains("More about the report processing at https://publicserver/sonarqube/api/ce/task?id=TASK-123"); - File detailsFile = new File(temp.getRoot(), "report-task.txt"); - assertThat(readFileToString(detailsFile)).isEqualTo( + assertThat(readFileToString(properties.metadataFilePath().toFile(), StandardCharsets.UTF_8)).isEqualTo( "projectKey=org.sonarsource.sonarqube:sonarqube\n" + "serverUrl=https://publicserver/sonarqube\n" + "serverVersion=6.4\n" + @@ -205,7 +195,7 @@ public class ReportPublisherTest { when(branchConfiguration.branchType()).thenReturn(PULL_REQUEST); when(branchConfiguration.pullRequestKey()).thenReturn("105"); - ReportPublisher underTest = new ReportPublisher(settings.asConfig(), wsClient, server, contextPublisher, moduleHierarchy, mode, mock(TempFolder.class), + ReportPublisher underTest = new ReportPublisher(properties, wsClient, server, contextPublisher, moduleHierarchy, mode, mock(TempFolder.class), new ReportPublisherStep[0], branchConfiguration); underTest.logSuccess("TASK-123"); @@ -214,8 +204,7 @@ public class ReportPublisherTest { .contains("ANALYSIS SUCCESSFUL, you can browse https://publicserver/sonarqube/project/issues?id=org.sonarsource.sonarqube%3Asonarqube&pullRequest=105&resolved=false") .contains("More about the report processing at https://publicserver/sonarqube/api/ce/task?id=TASK-123"); - File detailsFile = new File(temp.getRoot(), "report-task.txt"); - assertThat(readFileToString(detailsFile)).isEqualTo( + assertThat(readFileToString(properties.metadataFilePath().toFile(), StandardCharsets.UTF_8)).isEqualTo( "projectKey=org.sonarsource.sonarqube:sonarqube\n" + "serverUrl=https://publicserver/sonarqube\n" + "serverVersion=6.4\n" + @@ -227,8 +216,6 @@ public class ReportPublisherTest { @Test public void fail_if_public_url_malformed() { when(server.getPublicRootUrl()).thenReturn("invalid"); - ReportPublisher underTest = new ReportPublisher(settings.asConfig(), wsClient, server, contextPublisher, moduleHierarchy, mode, mock(TempFolder.class), - new ReportPublisherStep[0], branchConfiguration); exception.expect(MessageException.class); exception.expectMessage("Failed to parse public URL set in SonarQube server: invalid"); @@ -236,27 +223,29 @@ public class ReportPublisherTest { } @Test - public void log_but_not_dump_information_when_report_is_not_uploaded() { - ReportPublisher underTest = new ReportPublisher(settings.asConfig(), wsClient, server, contextPublisher, moduleHierarchy, mode, mock(TempFolder.class), - new ReportPublisherStep[0], branchConfiguration); - + public void log_but_not_dump_information_when_report_is_not_uploaded() throws IOException { underTest.logSuccess(/* report not uploaded, no server task */null); assertThat(logTester.logs(LoggerLevel.INFO)) .contains("ANALYSIS SUCCESSFUL") .doesNotContain("dashboard/index"); - File detailsFile = new File(temp.getRoot(), ReportPublisher.METADATA_DUMP_FILENAME); - assertThat(detailsFile).doesNotExist(); + assertThat(properties.metadataFilePath()).doesNotExist(); + } + + @Test + public void log_and_dump_information_to_custom_path() throws IOException { + underTest.logSuccess("TASK-123"); + + assertThat(properties.metadataFilePath()).exists(); + assertThat(logTester.logs(LoggerLevel.DEBUG)).contains("Report metadata written to " + properties.metadataFilePath()); } @Test public void should_not_delete_report_if_property_is_set() throws IOException { - settings.setProperty("sonar.scanner.keepReport", true); + when(properties.shouldKeepReport()).thenReturn(true); Path reportDir = temp.getRoot().toPath().resolve("scanner-report"); Files.createDirectory(reportDir); - ReportPublisher underTest = new ReportPublisher(settings.asConfig(), wsClient, server, contextPublisher, moduleHierarchy, mode, mock(TempFolder.class), - new ReportPublisherStep[0], branchConfiguration); underTest.start(); underTest.stop(); @@ -267,21 +256,15 @@ public class ReportPublisherTest { public void should_delete_report_by_default() throws IOException { Path reportDir = temp.getRoot().toPath().resolve("scanner-report"); Files.createDirectory(reportDir); - ReportPublisher job = new ReportPublisher(settings.asConfig(), wsClient, server, contextPublisher, moduleHierarchy, mode, mock(TempFolder.class), - new ReportPublisherStep[0], - branchConfiguration); - job.start(); - job.stop(); + underTest.start(); + underTest.stop(); assertThat(reportDir).doesNotExist(); } @Test public void test_ws_parameters() throws Exception { - ReportPublisher underTest = new ReportPublisher(settings.asConfig(), wsClient, server, contextPublisher, moduleHierarchy, mode, mock(TempFolder.class), - new ReportPublisherStep[0], branchConfiguration); - - settings.setProperty(ScannerProperties.ORGANIZATION, "MyOrg"); + when(properties.organizationKey()).thenReturn(Optional.of("MyOrg")); WsResponse response = mock(WsResponse.class); @@ -300,18 +283,15 @@ public class ReportPublisherTest { verify(wsClient).call(capture.capture()); WsRequest wsRequest = capture.getValue(); - assertThat(wsRequest.getParams()).containsOnly( - entry("organization", "MyOrg"), - entry("projectKey", "org.sonarsource.sonarqube:sonarqube")); + assertThat(wsRequest.getParameters().getKeys()).containsOnly("organization", "projectKey"); + assertThat(wsRequest.getParameters().getValue("organization")).isEqualTo("MyOrg"); + assertThat(wsRequest.getParameters().getValue("projectKey")).isEqualTo("org.sonarsource.sonarqube:sonarqube"); } @Test public void test_send_branches_characteristics() throws Exception { - ReportPublisher underTest = new ReportPublisher(settings.asConfig(), wsClient, server, contextPublisher, moduleHierarchy, mode, mock(TempFolder.class), - new ReportPublisherStep[0], branchConfiguration); - String orgName = "MyOrg"; - settings.setProperty(ScannerProperties.ORGANIZATION, orgName); + when(properties.organizationKey()).thenReturn(Optional.of(orgName)); String branchName = "feature"; when(branchConfiguration.branchName()).thenReturn(branchName); @@ -343,11 +323,8 @@ public class ReportPublisherTest { @Test public void send_pull_request_characteristic() throws Exception { - ReportPublisher underTest = new ReportPublisher(settings.asConfig(), wsClient, server, contextPublisher, moduleHierarchy, mode, mock(TempFolder.class), - new ReportPublisherStep[0], branchConfiguration); - String orgName = "MyOrg"; - settings.setProperty(ScannerProperties.ORGANIZATION, orgName); + when(properties.organizationKey()).thenReturn(Optional.of(orgName)); String branchName = "feature"; String pullRequestId = "pr-123"; 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 c37dd15b173..b1786ef3ad9 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 @@ -23,26 +23,28 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; +import java.util.Optional; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; -import org.sonar.api.config.internal.MapSettings; import org.sonar.api.utils.MessageException; import org.sonar.scanner.WsTestUtil; import org.sonar.scanner.bootstrap.ScannerWsClient; +import org.sonar.scanner.scan.ScanProperties; import org.sonarqube.ws.Qualityprofiles; import org.sonarqube.ws.Qualityprofiles.SearchWsResponse.QualityProfile; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; public class DefaultQualityProfileLoaderTest { @Rule public ExpectedException exception = ExpectedException.none(); private ScannerWsClient wsClient = mock(ScannerWsClient.class); - private MapSettings settings = new MapSettings(); - private DefaultQualityProfileLoader underTest = new DefaultQualityProfileLoader(settings.asConfig(), wsClient); + private ScanProperties properties = mock(ScanProperties.class); + private DefaultQualityProfileLoader underTest = new DefaultQualityProfileLoader(properties, wsClient); @Test public void load_gets_profiles_for_specified_project_and_profile_name() throws IOException { @@ -71,7 +73,7 @@ public class DefaultQualityProfileLoaderTest { @Test public void load_sets_organization_parameter_if_defined_in_settings() throws IOException { - settings.setProperty("sonar.organization", "my-org"); + when(properties.organizationKey()).thenReturn(Optional.of("my-org")); prepareCallWithResults(); underTest.load("foo", null); verifyCalledPath("/api/qualityprofiles/search.protobuf?projectKey=foo&organization=my-org"); @@ -95,7 +97,7 @@ public class DefaultQualityProfileLoaderTest { @Test public void loadDefault_sets_organization_parameter_if_defined_in_settings() throws IOException { - settings.setProperty("sonar.organization", "my-org"); + when(properties.organizationKey()).thenReturn(Optional.of("my-org")); WsTestUtil.mockStream(wsClient, "/api/qualityprofiles/search.protobuf?defaults=true&organization=my-org", createStreamOfProfiles("qp")); WsTestUtil.mockStream(wsClient, "/api/qualityprofiles/search.protobuf?profileName=foo&organization=my-org", createStreamOfProfiles("qp")); underTest.loadDefault("foo"); 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 new file mode 100644 index 00000000000..01fe698652b --- /dev/null +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ScanPropertiesTest.java @@ -0,0 +1,108 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 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; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.Optional; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.rules.TemporaryFolder; +import org.sonar.api.batch.fs.internal.DefaultInputModule; +import org.sonar.api.batch.fs.internal.InputModuleHierarchy; +import org.sonar.api.config.internal.MapSettings; +import org.sonar.api.utils.MessageException; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class ScanPropertiesTest { + private MapSettings settings = new MapSettings(); + private InputModuleHierarchy inputModuleHierarchy = mock(InputModuleHierarchy.class); + private ScanProperties underTest = new ScanProperties(settings.asConfig(), inputModuleHierarchy); + + @Rule + public TemporaryFolder temp = new TemporaryFolder(); + + @Rule + public ExpectedException exception = ExpectedException.none(); + + @Before + public void setUp() throws IOException { + DefaultInputModule root = mock(DefaultInputModule.class); + when(root.getBaseDir()).thenReturn(temp.newFolder().toPath()); + when(root.getWorkDir()).thenReturn(temp.newFolder().toPath()); + when(inputModuleHierarchy.root()).thenReturn(root); + } + + @Test + public void defaults_if_no_setting_defined() { + assertThat(underTest.branch()).isEmpty(); + assertThat(underTest.organizationKey()).isEmpty(); + assertThat(underTest.preloadFileMetadata()).isFalse(); + assertThat(underTest.shouldKeepReport()).isFalse(); + assertThat(underTest.metadataFilePath()).isEqualTo(inputModuleHierarchy.root().getWorkDir().resolve("report-task.txt")); + underTest.validate(); + } + + @Test + public void should_define_organization_key() { + settings.setProperty("sonar.organization", "org"); + assertThat(underTest.organizationKey()).isEqualTo(Optional.of("org")); + } + + @Test + public void should_define_branch_name() { + settings.setProperty("sonar.branch.name", "name"); + assertThat(underTest.branch()).isEqualTo(Optional.of("name")); + } + + @Test + public void should_define_preload_file_metadata() { + settings.setProperty("sonar.preloadFileMetadata", "true"); + assertThat(underTest.preloadFileMetadata()).isTrue(); + } + + @Test + public void should_define_keep_report() { + settings.setProperty("sonar.scanner.keepReport", "true"); + assertThat(underTest.shouldKeepReport()).isTrue(); + } + + @Test + public void should_define_metadata_file_path() throws IOException { + Path path = temp.newFolder().toPath().resolve("report"); + settings.setProperty("sonar.scanner.metadataFilePath", path.toString()); + assertThat(underTest.metadataFilePath()).isEqualTo(path); + } + + @Test + public void validate_fails_if_metadata_file_location_is_not_absolute() { + settings.setProperty("sonar.scanner.metadataFilePath", "relative"); + + exception.expect(MessageException.class); + exception.expectMessage("Property 'sonar.scanner.metadataFilePath' must point to an absolute path: relative"); + underTest.validate(); + + } +} diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputFileBuilderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputFileBuilderTest.java index 38315790c36..580a0ac6d7b 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputFileBuilderTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputFileBuilderTest.java @@ -34,6 +34,7 @@ import org.sonar.api.batch.fs.internal.DefaultInputModule; import org.sonar.api.batch.fs.internal.SensorStrategy; import org.sonar.api.config.internal.MapSettings; import org.sonar.scanner.scan.DefaultInputModuleHierarchy; +import org.sonar.scanner.scan.ScanProperties; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; @@ -66,11 +67,11 @@ public class InputFileBuilderTest { MetadataGenerator metadataGenerator = mock(MetadataGenerator.class); BatchIdGenerator idGenerator = new BatchIdGenerator(); - MapSettings settings = new MapSettings(); + ScanProperties properties = mock(ScanProperties.class); ModuleFileSystemInitializer moduleFileSystemInitializer = mock(ModuleFileSystemInitializer.class); when(moduleFileSystemInitializer.defaultEncoding()).thenReturn(StandardCharsets.UTF_8); sensorStrategy = new SensorStrategy(); - builder = new InputFileBuilder(module, metadataGenerator, idGenerator, settings.asConfig(), moduleFileSystemInitializer, new DefaultInputModuleHierarchy(root), + builder = new InputFileBuilder(module, metadataGenerator, idGenerator, properties, moduleFileSystemInitializer, new DefaultInputModuleHierarchy(root), sensorStrategy); } -- 2.39.5