aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-scanner-engine/src
diff options
context:
space:
mode:
authorJacek <jacek.poreda@sonarsource.com>2019-10-31 10:36:24 +0100
committerSonarTech <sonartech@sonarsource.com>2019-11-08 20:21:13 +0100
commit27d2f9f67e536f4186d3b763aa8c88e147a31eb0 (patch)
treecbec1d5c01c86ac537580869ac935d9aaf9e7783 /sonar-scanner-engine/src
parent535bc2b8da7e3f5f19c9bea4ab0a3722da10ffa2 (diff)
downloadsonarqube-27d2f9f67e536f4186d3b763aa8c88e147a31eb0.tar.gz
sonarqube-27d2f9f67e536f4186d3b763aa8c88e147a31eb0.zip
SONAR-12630 reorganize log results
Diffstat (limited to 'sonar-scanner-engine/src')
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/analysis/AnalysisResultReporter.java54
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/qualitygate/QualityGateCheck.java35
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/report/CeTaskReportDataHolder.java62
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ReportPublisher.java56
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java4
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/analysis/AnalysisResultReporterTest.java85
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/ScannerMediumTester.java3
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/report/CeTaskReportDataHolderTest.java63
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ReportPublisherTest.java105
9 files changed, 359 insertions, 108 deletions
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/analysis/AnalysisResultReporter.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/analysis/AnalysisResultReporter.java
new file mode 100644
index 00000000000..20c32d0b7c6
--- /dev/null
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/analysis/AnalysisResultReporter.java
@@ -0,0 +1,54 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 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.analysis;
+
+import org.sonar.api.utils.log.Logger;
+import org.sonar.api.utils.log.Loggers;
+import org.sonar.scanner.bootstrap.GlobalAnalysisMode;
+import org.sonar.scanner.report.CeTaskReportDataHolder;
+import org.sonar.scanner.scan.ScanProperties;
+
+public class AnalysisResultReporter {
+
+ private static final Logger LOG = Loggers.get(AnalysisResultReporter.class);
+
+ private final CeTaskReportDataHolder ceTaskReportDataHolder;
+ private final GlobalAnalysisMode analysisMode;
+ private final ScanProperties scanProperties;
+
+ public AnalysisResultReporter(GlobalAnalysisMode analysisMode, CeTaskReportDataHolder ceTaskReportDataHolder,
+ ScanProperties scanProperties) {
+ this.analysisMode = analysisMode;
+ this.ceTaskReportDataHolder = ceTaskReportDataHolder;
+ this.scanProperties = scanProperties;
+ }
+
+ public void report() {
+ if (analysisMode.isMediumTest()) {
+ LOG.info("ANALYSIS SUCCESSFUL");
+ } else {
+ LOG.info("ANALYSIS SUCCESSFUL, you can browse {}", ceTaskReportDataHolder.getDashboardUrl());
+ if (!scanProperties.shouldWaitForQualityGate()) {
+ LOG.info("Note that you will be able to access the updated dashboard once the server has processed the submitted analysis report");
+ }
+ LOG.info("More about the report processing at {}", ceTaskReportDataHolder.getCeTaskUrl());
+ }
+ }
+}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/qualitygate/QualityGateCheck.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/qualitygate/QualityGateCheck.java
index bae3d39b634..871ba195b74 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/qualitygate/QualityGateCheck.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/qualitygate/QualityGateCheck.java
@@ -19,21 +19,17 @@
*/
package org.sonar.scanner.qualitygate;
-import java.io.IOException;
import java.io.InputStream;
-import java.io.Reader;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Path;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.util.EnumSet;
-import java.util.Properties;
import org.picocontainer.Startable;
import org.sonar.api.utils.MessageException;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
import org.sonar.scanner.bootstrap.DefaultScannerWsClient;
+import org.sonar.scanner.bootstrap.GlobalAnalysisMode;
+import org.sonar.scanner.report.CeTaskReportDataHolder;
import org.sonar.scanner.scan.ScanProperties;
import org.sonarqube.ws.Ce;
import org.sonarqube.ws.Ce.TaskStatus;
@@ -51,14 +47,19 @@ public class QualityGateCheck implements Startable {
private static final int POLLING_INTERVAL_IN_MS = 5000;
private final DefaultScannerWsClient wsClient;
+ private final GlobalAnalysisMode analysisMode;
+ private final CeTaskReportDataHolder reportMetadataHolder;
private final ScanProperties properties;
private long qualityGateTimeoutInMs;
private boolean enabled;
- public QualityGateCheck(ScanProperties properties, DefaultScannerWsClient wsClient) {
+ public QualityGateCheck(DefaultScannerWsClient wsClient, GlobalAnalysisMode analysisMode, CeTaskReportDataHolder reportMetadataHolder,
+ ScanProperties properties) {
this.wsClient = wsClient;
this.properties = properties;
+ this.reportMetadataHolder = reportMetadataHolder;
+ this.analysisMode = analysisMode;
}
@Override
@@ -73,12 +74,16 @@ public class QualityGateCheck implements Startable {
}
public void await() {
+ if (!analysisMode.isMediumTest()) {
+ throw new IllegalStateException("Quality Gate check not available in medium test mode");
+ }
+
if (!enabled) {
- LOG.debug("Quality Gate Check disabled - skipping");
+ LOG.debug("Quality Gate check disabled - skipping");
return;
}
- String taskId = readTaskIdFromMetaDataFile();
+ String taskId = reportMetadataHolder.getCeTaskId();
Ce.Task task = waitForCeTaskToFinish(taskId);
@@ -93,22 +98,10 @@ public class QualityGateCheck implements Startable {
} else if (Status.NONE.equals(qualityGateStatus)) {
LOG.info("No Quality Gate is associated with the analysis - skipping");
} else {
- LOG.info("Quality Gate - FAILED");
throw MessageException.of("Quality Gate - FAILED");
}
}
- private String readTaskIdFromMetaDataFile() {
- Path file = properties.metadataFilePath();
- try (Reader reader = Files.newBufferedReader(file, StandardCharsets.UTF_8)) {
- Properties metadata = new Properties();
- metadata.load(reader);
- return metadata.getProperty("ceTaskId");
- } catch (IOException e) {
- throw new IllegalStateException("Unable to read metadata file: " + file, e);
- }
- }
-
private Ce.Task waitForCeTaskToFinish(String taskId) {
GetRequest getTaskResultReq = new GetRequest("api/ce/task")
.setMediaType(MediaTypes.PROTOBUF)
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/CeTaskReportDataHolder.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/CeTaskReportDataHolder.java
new file mode 100644
index 00000000000..a64bf79a855
--- /dev/null
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/CeTaskReportDataHolder.java
@@ -0,0 +1,62 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 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.report;
+
+import static java.util.Objects.requireNonNull;
+
+public class CeTaskReportDataHolder {
+ private boolean initialized = false;
+ private String ceTaskId;
+ private String ceTaskUrl;
+ private String dashboardUrl;
+
+ public void init(String ceTaskId, String ceTaskUrl, String dashboardUrl) {
+ requireNonNull(ceTaskId, "CE task id must not be null");
+ requireNonNull(ceTaskUrl, "CE task url must not be null");
+ requireNonNull(dashboardUrl, "Dashboard url map must not be null");
+
+ this.ceTaskId = ceTaskId;
+ this.ceTaskUrl = ceTaskUrl;
+ this.dashboardUrl = dashboardUrl;
+
+ this.initialized = true;
+ }
+
+ private void verifyInitialized() {
+ if (!initialized) {
+ throw new IllegalStateException("Scan report hasn't been published yet");
+ }
+ }
+
+ public String getCeTaskId() {
+ verifyInitialized();
+ return ceTaskId;
+ }
+
+ public String getDashboardUrl() {
+ verifyInitialized();
+ return dashboardUrl;
+ }
+
+ public String getCeTaskUrl() {
+ verifyInitialized();
+ return ceTaskUrl;
+ }
+}
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 ca0c8f5c1cf..1c6ce3987b1 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
@@ -40,8 +40,8 @@ import org.sonar.api.utils.TempFolder;
import org.sonar.api.utils.ZipUtils;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
-import org.sonar.scanner.bootstrap.GlobalAnalysisMode;
import org.sonar.scanner.bootstrap.DefaultScannerWsClient;
+import org.sonar.scanner.bootstrap.GlobalAnalysisMode;
import org.sonar.scanner.fs.InputModuleHierarchy;
import org.sonar.scanner.protocol.output.ScannerReportReader;
import org.sonar.scanner.protocol.output.ScannerReportWriter;
@@ -79,13 +79,15 @@ public class ReportPublisher implements Startable {
private final Server server;
private final BranchConfiguration branchConfiguration;
private final ScanProperties properties;
+ private final CeTaskReportDataHolder ceTaskReportDataHolder;
private Path reportDir;
private ScannerReportWriter writer;
private ScannerReportReader reader;
public ReportPublisher(ScanProperties properties, DefaultScannerWsClient wsClient, Server server, AnalysisContextReportPublisher contextPublisher,
- InputModuleHierarchy moduleHierarchy, GlobalAnalysisMode analysisMode, TempFolder temp, ReportPublisherStep[] publishers, BranchConfiguration branchConfiguration) {
+ InputModuleHierarchy moduleHierarchy, GlobalAnalysisMode analysisMode, TempFolder temp, ReportPublisherStep[] publishers, BranchConfiguration branchConfiguration,
+ CeTaskReportDataHolder ceTaskReportDataHolder) {
this.wsClient = wsClient;
this.server = server;
this.contextPublisher = contextPublisher;
@@ -95,6 +97,7 @@ public class ReportPublisher implements Startable {
this.publishers = publishers;
this.branchConfiguration = branchConfiguration;
this.properties = properties;
+ this.ceTaskReportDataHolder = ceTaskReportDataHolder;
}
@Override
@@ -132,15 +135,14 @@ public class ReportPublisher implements Startable {
}
public void execute() {
- String taskId = null;
File report = generateReportFile();
if (properties.shouldKeepReport()) {
LOG.info("Analysis report generated in " + reportDir);
}
if (!analysisMode.isMediumTest()) {
- taskId = upload(report);
+ String taskId = upload(report);
+ prepareAndDumpMetadata(taskId);
}
- logSuccess(taskId);
}
private File generateReportFile() {
@@ -204,36 +206,28 @@ public class ReportPublisher implements Startable {
}
}
- void logSuccess(@Nullable String taskId) {
- if (taskId == null) {
- LOG.info("ANALYSIS SUCCESSFUL");
- } else {
+ void prepareAndDumpMetadata(String taskId) {
+ Map<String, String> metadata = new LinkedHashMap<>();
- Map<String, String> metadata = new LinkedHashMap<>();
+ properties.organizationKey().ifPresent(org -> metadata.put("organization", org));
+ metadata.put("projectKey", moduleHierarchy.root().key());
+ metadata.put("serverUrl", server.getPublicRootUrl());
+ metadata.put("serverVersion", server.getVersion());
+ properties.branch().ifPresent(branch -> metadata.put("branch", branch));
- properties.organizationKey().ifPresent(org -> metadata.put("organization", org));
- metadata.put("projectKey", moduleHierarchy.root().key());
- metadata.put("serverUrl", server.getPublicRootUrl());
- metadata.put("serverVersion", server.getVersion());
- properties.branch().ifPresent(branch -> metadata.put("branch", branch));
+ URL dashboardUrl = buildDashboardUrl(server.getPublicRootUrl(), moduleHierarchy.root().key());
+ metadata.put("dashboardUrl", dashboardUrl.toExternalForm());
- URL dashboardUrl = buildDashboardUrl(server.getPublicRootUrl(), moduleHierarchy.root().key());
- metadata.put("dashboardUrl", dashboardUrl.toExternalForm());
+ URL taskUrl = HttpUrl.parse(server.getPublicRootUrl()).newBuilder()
+ .addPathSegment("api").addPathSegment("ce").addPathSegment("task")
+ .addQueryParameter(ID, taskId)
+ .build()
+ .url();
+ metadata.put("ceTaskId", taskId);
+ metadata.put("ceTaskUrl", taskUrl.toExternalForm());
- URL taskUrl = HttpUrl.parse(server.getPublicRootUrl()).newBuilder()
- .addPathSegment("api").addPathSegment("ce").addPathSegment("task")
- .addQueryParameter(ID, taskId)
- .build()
- .url();
- metadata.put("ceTaskId", taskId);
- metadata.put("ceTaskUrl", taskUrl.toExternalForm());
-
- LOG.info("ANALYSIS SUCCESSFUL, you can browse {}", dashboardUrl);
- LOG.info("Note that you will be able to access the updated dashboard once the server has processed the submitted analysis report");
- LOG.info("More about the report processing at {}", taskUrl);
-
- dumpMetadata(metadata);
- }
+ ceTaskReportDataHolder.init(taskId, taskUrl.toExternalForm(), dashboardUrl.toExternalForm());
+ dumpMetadata(metadata);
}
private URL buildDashboardUrl(String publicUrl, String effectiveKey) {
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 5ab47b36755..45b63ec6cc1 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
@@ -37,6 +37,7 @@ import org.sonar.core.metric.ScannerMetrics;
import org.sonar.core.platform.ComponentContainer;
import org.sonar.scanner.DefaultFileLinesContextFactory;
import org.sonar.scanner.ProjectInfo;
+import org.sonar.scanner.analysis.AnalysisResultReporter;
import org.sonar.scanner.analysis.AnalysisTempFolderProvider;
import org.sonar.scanner.analysis.DefaultAnalysisMode;
import org.sonar.scanner.bootstrap.ExtensionInstaller;
@@ -248,6 +249,7 @@ public class ProjectScanContainer extends ComponentContainer {
TestExecutionPublisher.class,
SourcePublisher.class,
ChangedLinesPublisher.class,
+ AnalysisResultReporter.class,
//QualityGate check
QualityGateCheck.class,
@@ -360,6 +362,8 @@ public class ProjectScanContainer extends ComponentContainer {
getComponentByType(QualityGateCheck.class).await();
}
+ getComponentByType(AnalysisResultReporter.class).report();
+
getComponentByType(PostJobsExecutor.class).execute();
if (analysisMode.isMediumTest()) {
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/analysis/AnalysisResultReporterTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/analysis/AnalysisResultReporterTest.java
new file mode 100644
index 00000000000..f5c9d89b60e
--- /dev/null
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/analysis/AnalysisResultReporterTest.java
@@ -0,0 +1,85 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 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.analysis;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.utils.log.LogTester;
+import org.sonar.api.utils.log.LoggerLevel;
+import org.sonar.scanner.bootstrap.GlobalAnalysisMode;
+import org.sonar.scanner.report.CeTaskReportDataHolder;
+import org.sonar.scanner.scan.ScanProperties;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class AnalysisResultReporterTest {
+ @Rule
+ public LogTester logTester = new LogTester();
+
+ private CeTaskReportDataHolder ceTaskReportDataHolder = mock(CeTaskReportDataHolder.class);
+ private GlobalAnalysisMode analysisMode = mock(GlobalAnalysisMode.class);
+ private ScanProperties scanProperties = mock(ScanProperties.class);
+
+ private AnalysisResultReporter underTest = new AnalysisResultReporter(analysisMode, ceTaskReportDataHolder, scanProperties);
+
+ @Test
+ public void should_log_simple_success_message() {
+ when(analysisMode.isMediumTest()).thenReturn(true);
+ underTest.report();
+
+ assertThat(logTester.logs(LoggerLevel.INFO))
+ .containsOnly("ANALYSIS SUCCESSFUL");
+ }
+
+ @Test
+ public void should_log_success_message_with_urls() {
+ String ceTaskUrl = "http://sonarqube/taskurl";
+ String dashboardUrl = "http://sonarqube/dashboardurl";
+ when(ceTaskReportDataHolder.getCeTaskUrl()).thenReturn(ceTaskUrl);
+ when(ceTaskReportDataHolder.getDashboardUrl()).thenReturn(dashboardUrl);
+
+ underTest.report();
+
+ assertThat(logTester.logs(LoggerLevel.INFO))
+ .containsExactly(
+ "ANALYSIS SUCCESSFUL, you can browse " + dashboardUrl,
+ "Note that you will be able to access the updated dashboard once the server has processed the submitted analysis report",
+ "More about the report processing at " + ceTaskUrl);
+ }
+
+ @Test
+ public void should_log_short_success_message_with_urls_if_quality_gate_wait_enabled() {
+ String ceTaskUrl = "http://sonarqube/taskurl";
+ String dashboardUrl = "http://sonarqube/dashboardurl";
+ when(ceTaskReportDataHolder.getCeTaskUrl()).thenReturn(ceTaskUrl);
+ when(ceTaskReportDataHolder.getDashboardUrl()).thenReturn(dashboardUrl);
+
+ when(scanProperties.shouldWaitForQualityGate()).thenReturn(true);
+
+ underTest.report();
+
+ assertThat(logTester.logs(LoggerLevel.INFO))
+ .containsExactly(
+ "ANALYSIS SUCCESSFUL, you can browse " + dashboardUrl,
+ "More about the report processing at " + ceTaskUrl);
+ }
+}
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 a8769acd7a5..be6be13b727 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
@@ -57,6 +57,7 @@ import org.sonar.batch.bootstrapper.Batch;
import org.sonar.batch.bootstrapper.EnvironmentInformation;
import org.sonar.batch.bootstrapper.LogOutput;
import org.sonar.scanner.bootstrap.GlobalAnalysisMode;
+import org.sonar.scanner.report.CeTaskReportDataHolder;
import org.sonar.scanner.repository.FileData;
import org.sonar.scanner.repository.MetricsRepository;
import org.sonar.scanner.repository.MetricsRepositoryLoader;
@@ -95,6 +96,7 @@ public class ScannerMediumTester extends ExternalResource {
private final FakeQualityProfileLoader qualityProfiles = new FakeQualityProfileLoader();
private final FakeActiveRulesLoader activeRules = new FakeActiveRulesLoader();
private final FakeSonarRuntime sonarRuntime = new FakeSonarRuntime();
+ private final CeTaskReportDataHolder reportMetadataHolder = new CeTaskReportDataHolder();
private LogOutput logOutput = null;
private static void createWorkingDirs() throws IOException {
@@ -294,6 +296,7 @@ public class ScannerMediumTester extends ExternalResource {
tester.globalSettingsLoader,
tester.projectSettingsLoader,
tester.sonarRuntime,
+ tester.reportMetadataHolder,
result)
.setLogOutput(tester.logOutput)
.build().execute();
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
new file mode 100644
index 00000000000..4d184299729
--- /dev/null
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/CeTaskReportDataHolderTest.java
@@ -0,0 +1,63 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 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.report;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class CeTaskReportDataHolderTest {
+
+ @Rule
+ public ExpectedException exception = ExpectedException.none();
+
+ CeTaskReportDataHolder underTest = new CeTaskReportDataHolder();
+
+ @Test
+ public void should_initialize_field() {
+ String ceTaskId = "ceTaskId";
+ String ceTaskUrl = "ceTaskUrl";
+ String dashboardUrl = "dashboardUrl";
+ underTest.init(ceTaskId, ceTaskUrl, dashboardUrl);
+ assertThat(underTest.getCeTaskId()).isEqualTo(ceTaskId);
+ assertThat(underTest.getCeTaskUrl()).isEqualTo(ceTaskUrl);
+ assertThat(underTest.getDashboardUrl()).isEqualTo(dashboardUrl);
+ }
+
+ @Test
+ public void getCeTaskId_should_fail_if_not_initialized() {
+ exception.expect(IllegalStateException.class);
+ underTest.getCeTaskId();
+ }
+
+ @Test
+ public void getCeTaskUrl_should_fail_if_not_initialized() {
+ exception.expect(IllegalStateException.class);
+ underTest.getCeTaskUrl();
+ }
+
+ @Test
+ public void getDashboardUrl_should_fail_if_not_initialized() {
+ exception.expect(IllegalStateException.class);
+ underTest.getDashboardUrl();
+ }
+}
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 11781cc6b25..3fc00a31110 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
@@ -30,23 +30,24 @@ import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
-import org.junit.rules.TemporaryFolder;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
import org.sonar.api.batch.bootstrap.ProjectDefinition;
+import org.sonar.api.batch.fs.internal.DefaultInputModule;
+import org.sonar.api.impl.utils.JUnitTempFolder;
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.scanner.bootstrap.GlobalAnalysisMode;
import org.sonar.scanner.bootstrap.DefaultScannerWsClient;
-import org.sonar.api.batch.fs.internal.DefaultInputModule;
+import org.sonar.scanner.bootstrap.GlobalAnalysisMode;
import org.sonar.scanner.fs.InputModuleHierarchy;
import org.sonar.scanner.scan.ScanProperties;
import org.sonar.scanner.scan.branch.BranchConfiguration;
import org.sonarqube.ws.Ce;
import org.sonarqube.ws.client.HttpException;
+import org.sonarqube.ws.client.MockWsResponse;
import org.sonarqube.ws.client.WsRequest;
import org.sonarqube.ws.client.WsResponse;
@@ -66,7 +67,7 @@ public class ReportPublisherTest {
public LogTester logTester = new LogTester();
@Rule
- public TemporaryFolder temp = new TemporaryFolder();
+ public JUnitTempFolder reportTempFolder = new JUnitTempFolder();
@Rule
public ExpectedException exception = ExpectedException.none();
@@ -79,29 +80,26 @@ public class ReportPublisherTest {
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);
+ CeTaskReportDataHolder reportMetadataHolder = mock(CeTaskReportDataHolder.class);
+ ReportPublisher underTest = new ReportPublisher(properties, wsClient, server, contextPublisher, moduleHierarchy, mode, reportTempFolder,
+ new ReportPublisherStep[0], branchConfiguration, reportMetadataHolder);
@Before
- public void setUp() throws IOException {
- root = new DefaultInputModule(ProjectDefinition.create().setKey("org.sonarsource.sonarqube:sonarqube").setBaseDir(temp.newFolder()).setWorkDir(temp.getRoot()));
+ public void setUp() {
+ root = new DefaultInputModule(
+ ProjectDefinition.create().setKey("org.sonarsource.sonarqube:sonarqube").setBaseDir(reportTempFolder.newDir()).setWorkDir(reportTempFolder.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()
+ when(properties.metadataFilePath()).thenReturn(reportTempFolder.newDir().toPath()
.resolve("folder")
.resolve("report-task.txt"));
}
@Test
- public void log_and_dump_information_about_report_uploading() throws IOException {
+ public void dump_information_about_report_uploading() throws IOException {
when(properties.organizationKey()).thenReturn(Optional.of("MyOrg"));
- underTest.logSuccess("TASK-123");
-
- assertThat(logTester.logs(LoggerLevel.INFO))
- .contains("ANALYSIS SUCCESSFUL, you can browse https://localhost/dashboard?id=org.sonarsource.sonarqube%3Asonarqube")
- .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");
+ underTest.prepareAndDumpMetadata("TASK-123");
assertThat(readFileToString(properties.metadataFilePath().toFile(), StandardCharsets.UTF_8)).isEqualTo(
"organization=MyOrg\n" +
@@ -114,7 +112,7 @@ public class ReportPublisherTest {
}
@Test
- public void parse_upload_error_message() throws IOException {
+ public void parse_upload_error_message() {
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);
@@ -122,18 +120,14 @@ public class ReportPublisherTest {
exception.expect(MessageException.class);
exception.expectMessage("Failed to upload report - Organization with key 'MyOrg' does not exist");
- underTest.upload(temp.newFile());
+ underTest.upload(reportTempFolder.newFile());
}
@Test
- public void log_public_url_if_defined_for_main_branch() throws IOException {
+ public void dump_public_url_if_defined_for_main_branch() throws IOException {
when(server.getPublicRootUrl()).thenReturn("https://publicserver/sonarqube");
- underTest.logSuccess("TASK-123");
-
- assertThat(logTester.logs(LoggerLevel.INFO))
- .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");
+ underTest.prepareAndDumpMetadata("TASK-123");
assertThat(readFileToString(properties.metadataFilePath().toFile(), StandardCharsets.UTF_8)).isEqualTo(
"projectKey=org.sonarsource.sonarqube:sonarqube\n" +
@@ -145,17 +139,14 @@ public class ReportPublisherTest {
}
@Test
- public void log_public_url_if_defined_for_long_living_branches() throws IOException {
+ public void dump_public_url_if_defined_for_long_living_branches() throws IOException {
when(server.getPublicRootUrl()).thenReturn("https://publicserver/sonarqube");
when(branchConfiguration.branchType()).thenReturn(LONG);
when(branchConfiguration.branchName()).thenReturn("branch-6.7");
ReportPublisher underTest = new ReportPublisher(properties, wsClient, server, contextPublisher, moduleHierarchy, mode, mock(TempFolder.class),
- new ReportPublisherStep[0], branchConfiguration);
+ new ReportPublisherStep[0], branchConfiguration, reportMetadataHolder);
- underTest.logSuccess("TASK-123");
- assertThat(logTester.logs(LoggerLevel.INFO))
- .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");
+ underTest.prepareAndDumpMetadata("TASK-123");
assertThat(readFileToString(properties.metadataFilePath().toFile(), StandardCharsets.UTF_8)).isEqualTo(
"projectKey=org.sonarsource.sonarqube:sonarqube\n" +
@@ -167,17 +158,14 @@ public class ReportPublisherTest {
}
@Test
- public void log_public_url_if_defined_for_short_living_branches() throws IOException {
+ public void dump_public_url_if_defined_for_short_living_branches() throws IOException {
when(server.getPublicRootUrl()).thenReturn("https://publicserver/sonarqube");
when(branchConfiguration.branchType()).thenReturn(SHORT);
when(branchConfiguration.branchName()).thenReturn("branch-6.7");
ReportPublisher underTest = new ReportPublisher(properties, wsClient, server, contextPublisher, moduleHierarchy, mode, mock(TempFolder.class),
- new ReportPublisherStep[0], branchConfiguration);
+ new ReportPublisherStep[0], branchConfiguration, reportMetadataHolder);
- underTest.logSuccess("TASK-123");
- assertThat(logTester.logs(LoggerLevel.INFO))
- .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");
+ underTest.prepareAndDumpMetadata("TASK-123");
assertThat(readFileToString(properties.metadataFilePath().toFile(), StandardCharsets.UTF_8)).isEqualTo(
"projectKey=org.sonarsource.sonarqube:sonarqube\n" +
@@ -189,20 +177,16 @@ public class ReportPublisherTest {
}
@Test
- public void log_public_url_if_defined_for_pull_request() throws IOException {
+ public void dump_public_url_if_defined_for_pull_request() throws IOException {
when(server.getPublicRootUrl()).thenReturn("https://publicserver/sonarqube");
when(branchConfiguration.branchName()).thenReturn("Bitbucket cloud Widget");
when(branchConfiguration.branchType()).thenReturn(PULL_REQUEST);
when(branchConfiguration.pullRequestKey()).thenReturn("105");
ReportPublisher underTest = new ReportPublisher(properties, wsClient, server, contextPublisher, moduleHierarchy, mode, mock(TempFolder.class),
- new ReportPublisherStep[0], branchConfiguration);
+ new ReportPublisherStep[0], branchConfiguration, reportMetadataHolder);
- underTest.logSuccess("TASK-123");
-
- assertThat(logTester.logs(LoggerLevel.INFO))
- .contains("ANALYSIS SUCCESSFUL, you can browse https://publicserver/sonarqube/dashboard?id=org.sonarsource.sonarqube%3Asonarqube&pullRequest=105")
- .contains("More about the report processing at https://publicserver/sonarqube/api/ce/task?id=TASK-123");
+ underTest.prepareAndDumpMetadata("TASK-123");
assertThat(readFileToString(properties.metadataFilePath().toFile(), StandardCharsets.UTF_8)).isEqualTo(
"projectKey=org.sonarsource.sonarqube:sonarqube\n" +
@@ -223,19 +207,28 @@ public class ReportPublisherTest {
}
@Test
- public void log_but_not_dump_information_when_report_is_not_uploaded() throws IOException {
- underTest.logSuccess(/* report not uploaded, no server task */null);
+ public void should_not_dump_information_when_medium_test_enabled() {
+ when(mode.isMediumTest()).thenReturn(true);
+ underTest.start();
+ underTest.execute();
+ assertThat(properties.metadataFilePath()).doesNotExist();
+ }
- assertThat(logTester.logs(LoggerLevel.INFO))
- .contains("ANALYSIS SUCCESSFUL")
- .doesNotContain("dashboard/index");
+ @Test
+ public void should_upload_and_dump_information() {
+ MockWsResponse submitMockResponse = new MockWsResponse();
+ submitMockResponse.setContent(Ce.SubmitResponse.newBuilder().setTaskId("task-1234").build().toByteArray());
+ when(wsClient.call(any())).thenReturn(submitMockResponse);
+ underTest.start();
+ underTest.execute();
- assertThat(properties.metadataFilePath()).doesNotExist();
+ assertThat(properties.metadataFilePath()).exists();
+ assertThat(logTester.logs(LoggerLevel.DEBUG)).contains("Report metadata written to " + properties.metadataFilePath());
}
@Test
- public void log_and_dump_information_to_custom_path() throws IOException {
- underTest.logSuccess("TASK-123");
+ public void dump_information_to_custom_path() {
+ underTest.prepareAndDumpMetadata("TASK-123");
assertThat(properties.metadataFilePath()).exists();
assertThat(logTester.logs(LoggerLevel.DEBUG)).contains("Report metadata written to " + properties.metadataFilePath());
@@ -244,7 +237,7 @@ public class ReportPublisherTest {
@Test
public void should_not_delete_report_if_property_is_set() throws IOException {
when(properties.shouldKeepReport()).thenReturn(true);
- Path reportDir = temp.getRoot().toPath().resolve("scanner-report");
+ Path reportDir = reportTempFolder.getRoot().toPath().resolve("scanner-report");
Files.createDirectory(reportDir);
underTest.start();
@@ -254,7 +247,7 @@ public class ReportPublisherTest {
@Test
public void should_delete_report_by_default() throws IOException {
- Path reportDir = temp.getRoot().toPath().resolve("scanner-report");
+ Path reportDir = reportTempFolder.getRoot().toPath().resolve("scanner-report");
Files.createDirectory(reportDir);
underTest.start();
@@ -277,7 +270,7 @@ public class ReportPublisherTest {
when(response.contentStream()).thenReturn(in);
when(wsClient.call(any(WsRequest.class))).thenReturn(response);
- underTest.upload(temp.newFile());
+ underTest.upload(reportTempFolder.newFile());
ArgumentCaptor<WsRequest> capture = ArgumentCaptor.forClass(WsRequest.class);
verify(wsClient).call(capture.capture());
@@ -308,7 +301,7 @@ public class ReportPublisherTest {
when(response.contentStream()).thenReturn(in);
when(wsClient.call(any(WsRequest.class))).thenReturn(response);
- underTest.upload(temp.newFile());
+ underTest.upload(reportTempFolder.newFile());
ArgumentCaptor<WsRequest> capture = ArgumentCaptor.forClass(WsRequest.class);
verify(wsClient).call(capture.capture());
@@ -343,7 +336,7 @@ public class ReportPublisherTest {
when(response.contentStream()).thenReturn(in);
when(wsClient.call(any(WsRequest.class))).thenReturn(response);
- underTest.upload(temp.newFile());
+ underTest.upload(reportTempFolder.newFile());
ArgumentCaptor<WsRequest> capture = ArgumentCaptor.forClass(WsRequest.class);
verify(wsClient).call(capture.capture());