*/
package org.sonar.api.impl.utils;
+import java.io.File;
+import java.io.IOException;
+import javax.annotation.Nullable;
import org.apache.commons.lang.StringUtils;
import org.junit.rules.ExternalResource;
import org.junit.rules.TemporaryFolder;
import org.junit.runners.model.Statement;
import org.sonar.api.utils.TempFolder;
-import javax.annotation.Nullable;
-
-import java.io.File;
-import java.io.IOException;
-
/**
* Implementation of {@link org.sonar.api.utils.TempFolder} to be used
* only in JUnit tests. It wraps {@link org.junit.rules.TemporaryFolder}.
throw new IllegalStateException("Fail to create temp file", e);
}
}
+
+ public File getRoot() {
+ return junit.getRoot();
+ }
}
--- /dev/null
+/*
+ * 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());
+ }
+ }
+}
*/
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;
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
}
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);
} 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)
--- /dev/null
+/*
+ * 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;
+ }
+}
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;
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;
this.publishers = publishers;
this.branchConfiguration = branchConfiguration;
this.properties = properties;
+ this.ceTaskReportDataHolder = ceTaskReportDataHolder;
}
@Override
}
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() {
}
}
- 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) {
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;
TestExecutionPublisher.class,
SourcePublisher.class,
ChangedLinesPublisher.class,
+ AnalysisResultReporter.class,
//QualityGate check
QualityGateCheck.class,
getComponentByType(QualityGateCheck.class).await();
}
+ getComponentByType(AnalysisResultReporter.class).report();
+
getComponentByType(PostJobsExecutor.class).execute();
if (analysisMode.isMediumTest()) {
--- /dev/null
+/*
+ * 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);
+ }
+}
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;
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 {
tester.globalSettingsLoader,
tester.projectSettingsLoader,
tester.sonarRuntime,
+ tester.reportMetadataHolder,
result)
.setLogOutput(tester.logOutput)
.build().execute();
--- /dev/null
+/*
+ * 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();
+ }
+}
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;
public LogTester logTester = new LogTester();
@Rule
- public TemporaryFolder temp = new TemporaryFolder();
+ public JUnitTempFolder reportTempFolder = new JUnitTempFolder();
@Rule
public ExpectedException exception = ExpectedException.none();
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" +
}
@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);
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" +
}
@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" +
}
@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" +
}
@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" +
}
@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());
@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();
@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();
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());
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());
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());