aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLukasz Jarocki <lukasz.jarocki@sonarsource.com>2021-12-10 10:26:07 +0100
committerLukasz Jarocki <lukasz.jarocki@sonarsource.com>2021-12-13 15:22:58 +0100
commit0d0b7e4ff71957681e868404f87a526314f89181 (patch)
tree7a404c2e87183a90b3ee716c4874a21d798c6879
parent38d139582c17354e22e54ea03a73213cd87ca87d (diff)
downloadsonarqube-0d0b7e4ff71957681e868404f87a526314f89181.tar.gz
sonarqube-0d0b7e4ff71957681e868404f87a526314f89181.zip
SONAR-15770 added compute engine metrics
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeActivityDao.java4
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeActivityMapper.java2
-rw-r--r--server/sonar-db-dao/src/main/resources/org/sonar/db/ce/CeActivityMapper.xml9
-rw-r--r--server/sonar-db-dao/src/test/java/org/sonar/db/ce/CeActivityDaoTest.java10
-rw-r--r--server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/MainCollector.java60
-rw-r--r--server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/MonitoringTask.java27
-rw-r--r--server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/ServerMonitoringMetrics.java24
-rw-r--r--server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/ce/ComputeEngineMetricsTask.java52
-rw-r--r--server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/ce/NumberOfTasksInQueueTask.java42
-rw-r--r--server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/ce/RecentTasksDurationTask.java94
-rw-r--r--server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/devops/AzureMetricsTask.java65
-rw-r--r--server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/devops/BitbucketMetricsTask.java73
-rw-r--r--server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/devops/DevOpsMetricsTask.java52
-rw-r--r--server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/devops/DevOpsPlatformsMetricsCollector.java166
-rw-r--r--server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/devops/GithubMetricsTask.java65
-rw-r--r--server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/devops/GitlabMetricsTask.java65
-rw-r--r--server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/MainCollectorTest.java75
-rw-r--r--server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/ServerMonitoringMetricsTest.java23
-rw-r--r--server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/ce/ComputeEngineMetricsTaskTest.java108
-rw-r--r--server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/ce/NumberOfTasksInQueueTaskTest.java51
-rw-r--r--server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/ce/RecentTasksDurationTaskTest.java134
-rw-r--r--server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/devops/AbstractDevOpsMetricsTaskTest.java38
-rw-r--r--server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/devops/AzureMetricsTaskTest.java92
-rw-r--r--server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/devops/BitbucketMetricsTaskTest.java122
-rw-r--r--server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/devops/DevOpsMetricsTaskTest.java86
-rw-r--r--server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/devops/DevOpsPlatformsMetricsCollectorTest.java185
-rw-r--r--server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/devops/GithubMetricsTaskTest.java91
-rw-r--r--server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/devops/GitlabMetricsTaskTest.java90
-rw-r--r--server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java19
29 files changed, 1571 insertions, 353 deletions
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeActivityDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeActivityDao.java
index 613f000eb6d..0ebd518ff56 100644
--- a/server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeActivityDao.java
+++ b/server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeActivityDao.java
@@ -61,6 +61,10 @@ public class CeActivityDao implements Dao {
return mapper(dbSession).selectOlderThan(beforeDate);
}
+ public List<CeActivityDto> selectNewerThan(DbSession dbSession, long beforeDate) {
+ return mapper(dbSession).selectNewerThan(beforeDate);
+ }
+
public List<CeActivityDto> selectByTaskType(DbSession dbSession, String taskType) {
return mapper(dbSession).selectByTaskType(taskType);
}
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeActivityMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeActivityMapper.java
index b6a2a00c1cb..f4e95203874 100644
--- a/server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeActivityMapper.java
+++ b/server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeActivityMapper.java
@@ -34,6 +34,8 @@ public interface CeActivityMapper {
List<CeActivityDto> selectOlderThan(@Param("beforeDate") long beforeDate);
+ List<CeActivityDto> selectNewerThan(@Param("afterDate") long afterDate);
+
int countLastByStatusAndMainComponentUuid(@Param("status") CeActivityDto.Status status, @Nullable @Param("mainComponentUuid") String mainComponentUuid);
void insert(CeActivityDto dto);
diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/ce/CeActivityMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/ce/CeActivityMapper.xml
index 17c222152dd..f94c83b5ffc 100644
--- a/server/sonar-db-dao/src/main/resources/org/sonar/db/ce/CeActivityMapper.xml
+++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/ce/CeActivityMapper.xml
@@ -143,6 +143,15 @@
where
ca.created_at &lt; #{beforeDate,jdbcType=BIGINT}
</select>
+
+ <select id="selectNewerThan" parameterType="long" resultType="org.sonar.db.ce.CeActivityDto">
+ select
+ <include refid="columns"/>
+ from ce_activity ca
+ left outer join ce_scanner_context csc on csc.task_uuid = ca.uuid
+ where
+ ca.created_at &gt; #{afterDate,jdbcType=BIGINT}
+ </select>
<select id="countLastByStatusAndMainComponentUuid" resultType="int">
select
diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/ce/CeActivityDaoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/ce/CeActivityDaoTest.java
index cca5ec95293..6916d6ba297 100644
--- a/server/sonar-db-dao/src/test/java/org/sonar/db/ce/CeActivityDaoTest.java
+++ b/server/sonar-db-dao/src/test/java/org/sonar/db/ce/CeActivityDaoTest.java
@@ -647,6 +647,16 @@ public class CeActivityDaoTest {
}
@Test
+ public void selectNewerThan() {
+ insertWithCreationDate("TASK_1", 1_450_000_000_000L);
+ insertWithCreationDate("TASK_2", 1_460_000_000_000L);
+ insertWithCreationDate("TASK_3", 1_470_000_000_000L);
+
+ List<CeActivityDto> dtos = underTest.selectNewerThan(db.getSession(), 1_455_000_000_000L);
+ assertThat(dtos).extracting("uuid").containsOnly("TASK_2", "TASK_3");
+ }
+
+ @Test
public void selectOlder_populates_hasScannerContext_flag() {
insertWithCreationDate("TASK_1", 1_450_000_000_000L);
CeActivityDto dto2 = insertWithCreationDate("TASK_2", 1_450_000_000_000L);
diff --git a/server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/MainCollector.java b/server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/MainCollector.java
new file mode 100644
index 00000000000..389a1d7bc72
--- /dev/null
+++ b/server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/MainCollector.java
@@ -0,0 +1,60 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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.server.monitoring;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import org.picocontainer.Startable;
+
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+public class MainCollector implements Startable {
+
+ private final MonitoringTask[] monitoringTasks;
+ private ScheduledExecutorService scheduledExecutorService;
+
+ public MainCollector(MonitoringTask[] monitoringTasks) {
+ this.monitoringTasks = monitoringTasks;
+ }
+
+ @Override
+ public void start() {
+ this.scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(
+ new ThreadFactoryBuilder()
+ .setDaemon(true)
+ .setNameFormat(getClass().getCanonicalName() + "-thread-%d")
+ .build());
+ for (MonitoringTask task : monitoringTasks) {
+ scheduledExecutorService.scheduleWithFixedDelay(task, task.getDelay(), task.getPeriod(), MILLISECONDS);
+ }
+ }
+
+ @Override
+ public void stop() {
+ scheduledExecutorService.shutdown();
+ }
+
+ @VisibleForTesting
+ ScheduledExecutorService getScheduledExecutorService() {
+ return scheduledExecutorService;
+ }
+}
diff --git a/server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/MonitoringTask.java b/server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/MonitoringTask.java
new file mode 100644
index 00000000000..c445d8269a1
--- /dev/null
+++ b/server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/MonitoringTask.java
@@ -0,0 +1,27 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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.server.monitoring;
+
+public interface MonitoringTask extends Runnable {
+
+ long getDelay();
+
+ long getPeriod();
+}
diff --git a/server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/ServerMonitoringMetrics.java b/server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/ServerMonitoringMetrics.java
index 1fb4c46adaa..a58870a7905 100644
--- a/server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/ServerMonitoringMetrics.java
+++ b/server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/ServerMonitoringMetrics.java
@@ -20,6 +20,7 @@
package org.sonar.server.monitoring;
import io.prometheus.client.Gauge;
+import io.prometheus.client.Summary;
import org.sonar.api.server.ServerSide;
@ServerSide
@@ -30,6 +31,9 @@ public class ServerMonitoringMetrics {
private final Gauge bitbucketConfigOk;
private final Gauge azureConfigOk;
+ private final Gauge cePendingTasksTotal;
+ private final Summary ceTasksRunningDuration;
+
public ServerMonitoringMetrics() {
githubConfigOk = Gauge.build()
.name("github_config_ok")
@@ -50,6 +54,17 @@ public class ServerMonitoringMetrics {
.name("azure_config_ok")
.help("Tells whether SonarQube instance has configured Azure integration and its status is green. 0 for green, 1 otherwise .")
.register();
+
+ cePendingTasksTotal = Gauge.build()
+ .name("sonarqube_compute_engine_pending_tasks_total")
+ .help("Number of tasks at given point of time that were pending in the Compute Engine queue [SHARED, same value for every SonarQube instance]")
+ .register();
+
+ ceTasksRunningDuration = Summary.build()
+ .name("sonarqube_compute_engine_tasks_running_duration_seconds")
+ .help("Compute engine task running time in seconds")
+ .labelNames("task_type", "project_key")
+ .register();
}
public void setGithubStatusToGreen() {
@@ -83,4 +98,13 @@ public class ServerMonitoringMetrics {
public void setBitbucketStatusToRed() {
bitbucketConfigOk.set(1);
}
+
+ public void setNumberOfPendingTasks(int numberOfPendingTasks) {
+ cePendingTasksTotal.set(numberOfPendingTasks);
+ }
+
+ public void observeComputeEngineTaskDuration(long durationInSeconds, String taskType, String projectKey) {
+ ceTasksRunningDuration.labels(taskType, projectKey).observe(durationInSeconds);
+ }
+
}
diff --git a/server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/ce/ComputeEngineMetricsTask.java b/server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/ce/ComputeEngineMetricsTask.java
new file mode 100644
index 00000000000..f0394be4bfd
--- /dev/null
+++ b/server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/ce/ComputeEngineMetricsTask.java
@@ -0,0 +1,52 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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.server.monitoring.ce;
+
+import org.sonar.api.config.Configuration;
+import org.sonar.db.DbClient;
+import org.sonar.server.monitoring.MonitoringTask;
+import org.sonar.server.monitoring.ServerMonitoringMetrics;
+
+public abstract class ComputeEngineMetricsTask implements MonitoringTask {
+
+ private static final String DELAY_IN_MILISECONDS_PROPERTY = "sonar.server.monitoring.ce.initial.delay";
+ private static final String PERIOD_IN_MILISECONDS_PROPERTY = "sonar.server.monitoring.ce.period";
+
+ protected final DbClient dbClient;
+ protected final ServerMonitoringMetrics metrics;
+
+ private final Configuration config;
+
+ protected ComputeEngineMetricsTask(DbClient dbClient, ServerMonitoringMetrics metrics, Configuration config) {
+ this.dbClient = dbClient;
+ this.metrics = metrics;
+ this.config = config;
+ }
+
+ @Override
+ public long getDelay() {
+ return config.getLong(DELAY_IN_MILISECONDS_PROPERTY).orElse(10_000L);
+ }
+
+ @Override
+ public long getPeriod() {
+ return config.getLong(PERIOD_IN_MILISECONDS_PROPERTY).orElse(30_000L);
+ }
+}
diff --git a/server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/ce/NumberOfTasksInQueueTask.java b/server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/ce/NumberOfTasksInQueueTask.java
new file mode 100644
index 00000000000..0a48db31706
--- /dev/null
+++ b/server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/ce/NumberOfTasksInQueueTask.java
@@ -0,0 +1,42 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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.server.monitoring.ce;
+
+import org.sonar.api.config.Configuration;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.ce.CeQueueDto;
+import org.sonar.server.monitoring.ServerMonitoringMetrics;
+
+public class NumberOfTasksInQueueTask extends ComputeEngineMetricsTask {
+
+ public NumberOfTasksInQueueTask(DbClient dbClient, ServerMonitoringMetrics metrics, Configuration config) {
+ super(dbClient, metrics, config);
+ }
+
+ @Override
+ public void run() {
+ try (DbSession dbSession = dbClient.openSession(false)) {
+ int size = dbClient.ceQueueDao().countByStatus(dbSession, CeQueueDto.Status.PENDING);
+ metrics.setNumberOfPendingTasks(size);
+ }
+ }
+
+}
diff --git a/server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/ce/RecentTasksDurationTask.java b/server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/ce/RecentTasksDurationTask.java
new file mode 100644
index 00000000000..1aae8cc0fea
--- /dev/null
+++ b/server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/ce/RecentTasksDurationTask.java
@@ -0,0 +1,94 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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.server.monitoring.ce;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import org.sonar.api.config.Configuration;
+import org.sonar.api.utils.System2;
+import org.sonar.api.utils.log.Logger;
+import org.sonar.api.utils.log.Loggers;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.ce.CeActivityDto;
+import org.sonar.db.component.ComponentDto;
+import org.sonar.server.monitoring.ServerMonitoringMetrics;
+
+import static java.util.Objects.requireNonNull;
+
+public class RecentTasksDurationTask extends ComputeEngineMetricsTask {
+
+ private static final Logger LOGGER = Loggers.get(RecentTasksDurationTask.class);
+ private final System2 system;
+
+ private long lastUpdatedTimestamp;
+
+ public RecentTasksDurationTask(DbClient dbClient, ServerMonitoringMetrics metrics, Configuration config,
+ System2 system) {
+ super(dbClient, metrics, config);
+ this.system = system;
+ this.lastUpdatedTimestamp = system.now();
+ }
+
+ @Override
+ public void run() {
+ try (DbSession dbSession = dbClient.openSession(false)) {
+ List<CeActivityDto> recentSuccessfulTasks = getRecentSuccessfulTasks(dbSession);
+
+ Collection<String> componentUuids = recentSuccessfulTasks.stream()
+ .map(CeActivityDto::getMainComponentUuid)
+ .collect(Collectors.toList());
+ List<ComponentDto> componentDtos = dbClient.componentDao().selectByUuids(dbSession, componentUuids);
+ Map<String, String> componentUuidAndKeys = componentDtos.stream()
+ .collect(Collectors.toMap(ComponentDto::uuid, ComponentDto::getKey));
+
+ reportObservedDurationForTasks(recentSuccessfulTasks, componentUuidAndKeys);
+ }
+ lastUpdatedTimestamp = system.now();
+ }
+
+ private List<CeActivityDto> getRecentSuccessfulTasks(DbSession dbSession) {
+ List<CeActivityDto> recentTasks = dbClient.ceActivityDao().selectNewerThan(dbSession, lastUpdatedTimestamp);
+ return recentTasks.stream()
+ .filter(c -> c.getStatus() == CeActivityDto.Status.SUCCESS)
+ .collect(Collectors.toList());
+ }
+
+ private void reportObservedDurationForTasks(List<CeActivityDto> tasks, Map<String, String> componentUuidAndKeys) {
+ for (CeActivityDto task : tasks) {
+ String mainComponentUuid = task.getMainComponentUuid();
+ Long executionTimeMs = task.getExecutionTimeMs();
+ try {
+ requireNonNull(mainComponentUuid);
+ requireNonNull(executionTimeMs);
+
+ String mainComponentKey = componentUuidAndKeys.get(mainComponentUuid);
+ requireNonNull(mainComponentKey);
+
+ metrics.observeComputeEngineTaskDuration(executionTimeMs, task.getTaskType(), mainComponentUuid);
+ } catch (RuntimeException e) {
+ LOGGER.warn("Can't report metric data for a CE task with component uuid " + mainComponentUuid, e);
+ }
+ }
+
+ }
+}
diff --git a/server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/devops/AzureMetricsTask.java b/server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/devops/AzureMetricsTask.java
new file mode 100644
index 00000000000..34d6a3e9ebf
--- /dev/null
+++ b/server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/devops/AzureMetricsTask.java
@@ -0,0 +1,65 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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.server.monitoring.devops;
+
+import java.util.List;
+import org.sonar.alm.client.azure.AzureDevOpsValidator;
+import org.sonar.api.config.Configuration;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.alm.setting.ALM;
+import org.sonar.db.alm.setting.AlmSettingDto;
+import org.sonar.server.monitoring.ServerMonitoringMetrics;
+
+public class AzureMetricsTask extends DevOpsMetricsTask {
+
+ private final AzureDevOpsValidator azureDevOpsValidator;
+
+ public AzureMetricsTask(ServerMonitoringMetrics metrics, AzureDevOpsValidator azureDevOpsValidator,
+ DbClient dbClient, Configuration config) {
+ super(dbClient, metrics, config);
+ this.azureDevOpsValidator = azureDevOpsValidator;
+ }
+
+ @Override
+ public void run() {
+ try (DbSession dbSession = dbClient.openSession(false)) {
+ List<AlmSettingDto> azureSettingsDtos = dbClient.almSettingDao().selectByAlm(dbSession, ALM.AZURE_DEVOPS);
+
+ if (azureSettingsDtos.isEmpty()) {
+ metrics.setAzureStatusToRed();
+ return;
+ }
+
+ validate(azureSettingsDtos);
+ }
+ }
+
+ private void validate(List<AlmSettingDto> almSettingDtos) {
+ try {
+ for (AlmSettingDto dto : almSettingDtos) {
+ azureDevOpsValidator.validate(dto);
+ }
+ metrics.setAzureStatusToGreen();
+ } catch (Exception e) {
+ metrics.setAzureStatusToRed();
+ }
+ }
+}
diff --git a/server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/devops/BitbucketMetricsTask.java b/server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/devops/BitbucketMetricsTask.java
new file mode 100644
index 00000000000..2a9c7b11d4b
--- /dev/null
+++ b/server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/devops/BitbucketMetricsTask.java
@@ -0,0 +1,73 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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.server.monitoring.devops;
+
+import java.util.List;
+import org.sonar.alm.client.bitbucket.bitbucketcloud.BitbucketCloudValidator;
+import org.sonar.alm.client.bitbucketserver.BitbucketServerSettingsValidator;
+import org.sonar.api.config.Configuration;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.alm.setting.ALM;
+import org.sonar.db.alm.setting.AlmSettingDto;
+import org.sonar.server.monitoring.ServerMonitoringMetrics;
+
+public class BitbucketMetricsTask extends DevOpsMetricsTask {
+
+ private final BitbucketCloudValidator bitbucketCloudValidator;
+ private final BitbucketServerSettingsValidator bitbucketServerValidator;
+
+ public BitbucketMetricsTask(ServerMonitoringMetrics metrics, BitbucketCloudValidator bitbucketCloudValidator,
+ BitbucketServerSettingsValidator bitbucketServerSettingsValidator, DbClient dbClient, Configuration config) {
+ super(dbClient, metrics, config);
+ this.bitbucketCloudValidator = bitbucketCloudValidator;
+ this.bitbucketServerValidator = bitbucketServerSettingsValidator;
+ }
+
+ @Override
+ public void run() {
+ try (DbSession dbSession = dbClient.openSession(false)) {
+ List<AlmSettingDto> bitbucketServerDtos = dbClient.almSettingDao().selectByAlm(dbSession, ALM.BITBUCKET);
+ List<AlmSettingDto> bitbucketCloudDtos = dbClient.almSettingDao().selectByAlm(dbSession, ALM.BITBUCKET_CLOUD);
+
+ if (bitbucketServerDtos.isEmpty() && bitbucketCloudDtos.isEmpty()) {
+ metrics.setBitbucketStatusToRed();
+ return;
+ }
+
+ try {
+ validate(bitbucketServerDtos, bitbucketCloudDtos);
+ metrics.setBitbucketStatusToGreen();
+ } catch (RuntimeException e) {
+ metrics.setBitbucketStatusToRed();
+ }
+
+ }
+ }
+
+ private void validate(List<AlmSettingDto> bitbucketServerDtos, List<AlmSettingDto> bitbucketCloudDtos) {
+ for (AlmSettingDto dto : bitbucketServerDtos) {
+ bitbucketServerValidator.validate(dto);
+ }
+ for (AlmSettingDto dto : bitbucketCloudDtos) {
+ bitbucketCloudValidator.validate(dto);
+ }
+ }
+}
diff --git a/server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/devops/DevOpsMetricsTask.java b/server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/devops/DevOpsMetricsTask.java
new file mode 100644
index 00000000000..666d86d00ac
--- /dev/null
+++ b/server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/devops/DevOpsMetricsTask.java
@@ -0,0 +1,52 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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.server.monitoring.devops;
+
+import org.sonar.api.config.Configuration;
+import org.sonar.db.DbClient;
+import org.sonar.server.monitoring.MonitoringTask;
+import org.sonar.server.monitoring.ServerMonitoringMetrics;
+
+public abstract class DevOpsMetricsTask implements MonitoringTask {
+
+ private static final String DELAY_IN_MILISECONDS_PROPERTY = "sonar.server.monitoring.devops.initial.delay";
+ private static final String PERIOD_IN_MILISECONDS_PROPERTY = "sonar.server.monitoring.devops.period";
+
+ protected final DbClient dbClient;
+ protected final ServerMonitoringMetrics metrics;
+
+ private final Configuration config;
+
+ protected DevOpsMetricsTask(DbClient dbClient, ServerMonitoringMetrics metrics, Configuration config) {
+ this.dbClient = dbClient;
+ this.metrics = metrics;
+ this.config = config;
+ }
+
+ @Override
+ public long getDelay() {
+ return config.getLong(DELAY_IN_MILISECONDS_PROPERTY).orElse(10_000L);
+ }
+
+ @Override
+ public long getPeriod() {
+ return config.getLong(PERIOD_IN_MILISECONDS_PROPERTY).orElse(300_000L);
+ }
+}
diff --git a/server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/devops/DevOpsPlatformsMetricsCollector.java b/server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/devops/DevOpsPlatformsMetricsCollector.java
deleted file mode 100644
index fcee736a451..00000000000
--- a/server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/devops/DevOpsPlatformsMetricsCollector.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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.server.monitoring.devops;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.util.concurrent.ThreadFactoryBuilder;
-import java.util.List;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.stream.Collectors;
-import org.picocontainer.Startable;
-import org.sonar.alm.client.azure.AzureDevOpsValidator;
-import org.sonar.alm.client.bitbucket.bitbucketcloud.BitbucketCloudValidator;
-import org.sonar.alm.client.bitbucketserver.BitbucketServerSettingsValidator;
-import org.sonar.alm.client.github.GithubGlobalSettingsValidator;
-import org.sonar.alm.client.gitlab.GitlabGlobalSettingsValidator;
-import org.sonar.api.config.Configuration;
-import org.sonar.api.server.ServerSide;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
-import org.sonar.db.alm.setting.ALM;
-import org.sonar.db.alm.setting.AlmSettingDto;
-import org.sonar.server.monitoring.ServerMonitoringMetrics;
-
-import static java.util.concurrent.TimeUnit.MILLISECONDS;
-
-@ServerSide
-public class DevOpsPlatformsMetricsCollector implements Startable {
-
- private static final String DELAY_IN_MILISECONDS_PROPERTY = "sonar.server.monitoring.devops.initial.delay";
- private static final String PERIOD_IN_MILISECONDS_PROPERTY = "sonar.server.monitoring.devops.period";
-
- private final Configuration config;
-
- private final BitbucketServerSettingsValidator bitbucketServerValidator;
- private final GithubGlobalSettingsValidator githubValidator;
- private final GitlabGlobalSettingsValidator gitlabValidator;
- private final BitbucketCloudValidator bitbucketCloudValidator;
- private final AzureDevOpsValidator azureDevOpsValidator;
-
- private final DbClient dbClient;
- private final ServerMonitoringMetrics metrics;
-
- private ScheduledExecutorService scheduledExecutorService;
-
- public DevOpsPlatformsMetricsCollector(ServerMonitoringMetrics metrics, DbClient dbClient,
- BitbucketServerSettingsValidator bitbucketServerValidator, GithubGlobalSettingsValidator githubValidator,
- GitlabGlobalSettingsValidator gitlabValidator, BitbucketCloudValidator bitbucketCloudValidator,
- AzureDevOpsValidator azureDevOpsValidator, Configuration config) {
- this.bitbucketCloudValidator = bitbucketCloudValidator;
- this.bitbucketServerValidator = bitbucketServerValidator;
- this.githubValidator = githubValidator;
- this.azureDevOpsValidator = azureDevOpsValidator;
- this.gitlabValidator = gitlabValidator;
- this.metrics = metrics;
- this.dbClient = dbClient;
- this.config = config;
- }
-
- @Override
- public void start() {
- this.scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(
- new ThreadFactoryBuilder()
- .setDaemon(true)
- .setNameFormat(getClass().getCanonicalName() + "-thread-%d")
- .build());
- long delayInMilliseconds = config.getLong(DELAY_IN_MILISECONDS_PROPERTY).orElse(10_000L);
- long periodInMilliseconds = config.getLong(PERIOD_IN_MILISECONDS_PROPERTY).orElse(300_000L);
- scheduledExecutorService.scheduleWithFixedDelay(createTask(), delayInMilliseconds, periodInMilliseconds, MILLISECONDS);
- }
-
- @Override
- public void stop() {
- scheduledExecutorService.shutdown();
- }
-
- @VisibleForTesting
- Runnable createTask() {
- return () -> {
- try (DbSession dbSession = dbClient.openSession(false)) {
- List<AlmSettingDto> almSettingDtos = dbClient.almSettingDao().selectAll(dbSession);
- validateBitbucket(getALMsDTOs(almSettingDtos, ALM.BITBUCKET));
- validateBitbucketCloud(getALMsDTOs(almSettingDtos, ALM.BITBUCKET_CLOUD));
- validateGithub(getALMsDTOs(almSettingDtos, ALM.GITHUB));
- validateGitlab(getALMsDTOs(almSettingDtos, ALM.GITLAB));
- validateAzure(getALMsDTOs(almSettingDtos, ALM.AZURE_DEVOPS));
- }
- };
- }
-
- private static List<AlmSettingDto> getALMsDTOs(List<AlmSettingDto> almSettingDtos, ALM alm) {
- return almSettingDtos.stream().filter(dto -> dto.getAlm() == alm).collect(Collectors.toList());
- }
-
- private void validateGithub(List<AlmSettingDto> almSettingDtos) {
- try {
- for (AlmSettingDto dto : almSettingDtos) {
- githubValidator.validate(dto);
- }
- metrics.setGithubStatusToGreen();
- } catch (RuntimeException e) {
- metrics.setGithubStatusToRed();
- }
- }
-
- private void validateBitbucket(List<AlmSettingDto> almSettingDtos) {
- try {
- for (AlmSettingDto dto : almSettingDtos) {
- bitbucketServerValidator.validate(dto);
- }
- metrics.setBitbucketStatusToGreen();
- } catch (Exception e) {
- metrics.setBitbucketStatusToRed();
- }
- }
-
- private void validateBitbucketCloud(List<AlmSettingDto> almSettingDtos) {
- try {
- for (AlmSettingDto dto : almSettingDtos) {
- bitbucketCloudValidator.validate(dto);
- }
- metrics.setBitbucketStatusToGreen();
- } catch (Exception e) {
- metrics.setBitbucketStatusToRed();
- }
- }
-
- private void validateGitlab(List<AlmSettingDto> almSettingDtos) {
- try {
- for (AlmSettingDto dto : almSettingDtos) {
- gitlabValidator.validate(dto);
- }
- metrics.setGitlabStatusToGreen();
- } catch (Exception e) {
- metrics.setGitlabStatusToRed();
- }
- }
-
- private void validateAzure(List<AlmSettingDto> almSettingDtos) {
- try {
- for (AlmSettingDto dto : almSettingDtos) {
- azureDevOpsValidator.validate(dto);
- }
- metrics.setAzureStatusToGreen();
- } catch (Exception e) {
- metrics.setAzureStatusToRed();
- }
- }
-}
diff --git a/server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/devops/GithubMetricsTask.java b/server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/devops/GithubMetricsTask.java
new file mode 100644
index 00000000000..7e0d76ffcc6
--- /dev/null
+++ b/server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/devops/GithubMetricsTask.java
@@ -0,0 +1,65 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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.server.monitoring.devops;
+
+import java.util.List;
+import org.sonar.alm.client.github.GithubGlobalSettingsValidator;
+import org.sonar.api.config.Configuration;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.alm.setting.ALM;
+import org.sonar.db.alm.setting.AlmSettingDto;
+import org.sonar.server.monitoring.ServerMonitoringMetrics;
+
+public class GithubMetricsTask extends DevOpsMetricsTask {
+
+ private final GithubGlobalSettingsValidator githubValidator;
+
+ public GithubMetricsTask(ServerMonitoringMetrics metrics, GithubGlobalSettingsValidator githubValidator,
+ DbClient dbClient, Configuration config) {
+ super(dbClient, metrics, config);
+ this.githubValidator = githubValidator;
+ }
+
+ @Override
+ public void run() {
+ try (DbSession dbSession = dbClient.openSession(false)) {
+ List<AlmSettingDto> githubSettingsDtos = dbClient.almSettingDao().selectByAlm(dbSession, ALM.GITHUB);
+
+ if (githubSettingsDtos.isEmpty()) {
+ metrics.setGithubStatusToRed();
+ return;
+ }
+
+ validateGithub(githubSettingsDtos);
+ }
+ }
+
+ private void validateGithub(List<AlmSettingDto> almSettingDtos) {
+ try {
+ for (AlmSettingDto dto : almSettingDtos) {
+ githubValidator.validate(dto);
+ }
+ metrics.setGithubStatusToGreen();
+ } catch (RuntimeException e) {
+ metrics.setGithubStatusToRed();
+ }
+ }
+}
diff --git a/server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/devops/GitlabMetricsTask.java b/server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/devops/GitlabMetricsTask.java
new file mode 100644
index 00000000000..c0ef583939f
--- /dev/null
+++ b/server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/devops/GitlabMetricsTask.java
@@ -0,0 +1,65 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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.server.monitoring.devops;
+
+import java.util.List;
+import org.sonar.alm.client.gitlab.GitlabGlobalSettingsValidator;
+import org.sonar.api.config.Configuration;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.alm.setting.ALM;
+import org.sonar.db.alm.setting.AlmSettingDto;
+import org.sonar.server.monitoring.ServerMonitoringMetrics;
+
+public class GitlabMetricsTask extends DevOpsMetricsTask {
+
+ private final GitlabGlobalSettingsValidator gitlabValidator;
+
+ public GitlabMetricsTask(ServerMonitoringMetrics metrics, GitlabGlobalSettingsValidator gitlabValidator,
+ DbClient dbClient, Configuration config) {
+ super(dbClient, metrics, config);
+ this.gitlabValidator = gitlabValidator;
+ }
+
+ @Override
+ public void run() {
+ try (DbSession dbSession = dbClient.openSession(false)) {
+ List<AlmSettingDto> gitlabSettingsDtos = dbClient.almSettingDao().selectByAlm(dbSession, ALM.GITLAB);
+
+ if (gitlabSettingsDtos.isEmpty()) {
+ metrics.setGitlabStatusToRed();
+ return;
+ }
+
+ validateGitlab(gitlabSettingsDtos);
+ }
+ }
+
+ private void validateGitlab(List<AlmSettingDto> almSettingDtos) {
+ try {
+ for (AlmSettingDto dto : almSettingDtos) {
+ gitlabValidator.validate(dto);
+ }
+ metrics.setGitlabStatusToGreen();
+ } catch (RuntimeException e) {
+ metrics.setGitlabStatusToRed();
+ }
+ }
+}
diff --git a/server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/MainCollectorTest.java b/server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/MainCollectorTest.java
new file mode 100644
index 00000000000..eac306f0f77
--- /dev/null
+++ b/server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/MainCollectorTest.java
@@ -0,0 +1,75 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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.server.monitoring;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class MainCollectorTest {
+
+ private final MonitoringTask task1 = mock(MonitoringTask.class);
+ private final MonitoringTask task2 = mock(MonitoringTask.class);
+
+ private MainCollector underTest;
+
+ @Before
+ public void before() {
+ MonitoringTask[] tasks = {task1, task2};
+ for(MonitoringTask task : tasks) {
+ when(task.getDelay()).thenReturn(1L);
+ when(task.getPeriod()).thenReturn(1L);
+ }
+ underTest = new MainCollector(tasks);
+ }
+
+ @After
+ public void stop() {
+ underTest.stop();
+ }
+
+ @Test
+ public void startAndStop_executorServiceIsShutdown() {
+ underTest.start();
+
+ assertFalse(underTest.getScheduledExecutorService().isShutdown());
+
+ underTest.stop();
+
+ assertTrue(underTest.getScheduledExecutorService().isShutdown());
+ }
+
+ @Test
+ public void start_givenTwoTasks_callsGetsDelayAndPeriodFromTasks() {
+ underTest.start();
+
+ verify(task1, times(1)).getDelay();
+ verify(task1, times(1)).getPeriod();
+ verify(task2, times(1)).getDelay();
+ verify(task2, times(1)).getPeriod();
+ }
+}
diff --git a/server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/ServerMonitoringMetricsTest.java b/server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/ServerMonitoringMetricsTest.java
index 0849f04a3e3..4dafde05eaa 100644
--- a/server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/ServerMonitoringMetricsTest.java
+++ b/server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/ServerMonitoringMetricsTest.java
@@ -23,6 +23,7 @@ import io.prometheus.client.Collector;
import io.prometheus.client.CollectorRegistry;
import java.util.Collections;
import java.util.Enumeration;
+import java.util.Iterator;
import org.junit.Before;
import org.junit.Test;
@@ -75,6 +76,28 @@ public class ServerMonitoringMetricsTest {
assertThat(CollectorRegistry.defaultRegistry.getSampleValue("azure_config_ok")).isEqualTo(1);
}
+ @Test
+ public void setters_setNumberOfPendingTasks() {
+ ServerMonitoringMetrics metrics = new ServerMonitoringMetrics();
+
+ metrics.setNumberOfPendingTasks(10);
+
+ assertThat(CollectorRegistry.defaultRegistry.getSampleValue("sonarqube_compute_engine_pending_tasks_total"))
+ .isEqualTo(10);
+ }
+
+ @Test
+ public void observeComputeEngineTaskDurationTest() {
+ ServerMonitoringMetrics metrics = new ServerMonitoringMetrics();
+ String[] labelNames = {"task_type", "project_key"};
+ String[] labelValues = {"REPORT", "projectKey"};
+
+ metrics.observeComputeEngineTaskDuration(10, labelValues[0], labelValues[1]);
+
+ assertThat(CollectorRegistry.defaultRegistry.getSampleValue("sonarqube_compute_engine_tasks_running_duration_seconds_sum",
+ labelNames, labelValues)).isEqualTo(10);
+ }
+
private int sizeOfDefaultRegistry() {
Enumeration<Collector.MetricFamilySamples> metrics = CollectorRegistry.defaultRegistry.metricFamilySamples();
return Collections.list(metrics).size();
diff --git a/server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/ce/ComputeEngineMetricsTaskTest.java b/server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/ce/ComputeEngineMetricsTaskTest.java
new file mode 100644
index 00000000000..711fb4dfa6b
--- /dev/null
+++ b/server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/ce/ComputeEngineMetricsTaskTest.java
@@ -0,0 +1,108 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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.server.monitoring.ce;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.api.config.Configuration;
+import org.sonar.db.DbClient;
+import org.sonar.server.monitoring.ServerMonitoringMetrics;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+
+public class ComputeEngineMetricsTaskTest {
+
+ private final ServerMonitoringMetrics metrics = mock(ServerMonitoringMetrics.class);
+ private final DbClient dbClient = mock(DbClient.class);
+ private DumpMapConfiguration config;
+
+ private ComputeEngineMetricsTask underTest;
+
+ @Before
+ public void before() {
+ config = new DumpMapConfiguration();
+ underTest = new ComputeEngineMetricsTask(dbClient, metrics, config) {
+ @Override
+ public void run() {
+ //intentionally empty
+ }
+ };
+ }
+
+ @Test
+ public void getDelay_returnNumberIfConfigEmpty() {
+ long delay = underTest.getDelay();
+
+ assertThat(delay).isPositive();
+ }
+
+ @Test
+ public void getDelay_returnNumberFromConfig() {
+ config.put("sonar.server.monitoring.ce.initial.delay", "100000");
+
+ long delay = underTest.getDelay();
+
+ assertThat(delay).isEqualTo(100_000L);
+ }
+
+ @Test
+ public void getPeriod_returnNumberIfConfigEmpty() {
+ long delay = underTest.getPeriod();
+
+ assertThat(delay).isPositive();
+ }
+
+ @Test
+ public void getPeriod_returnNumberFromConfig() {
+ config.put("sonar.server.monitoring.ce.period", "100000");
+
+ long delay = underTest.getPeriod();
+
+ assertThat(delay).isEqualTo(100_000L);
+ }
+
+ private static class DumpMapConfiguration implements Configuration {
+ private final Map<String, String> keyValues = new HashMap<>();
+
+ public Configuration put(String key, String value) {
+ keyValues.put(key, value.trim());
+ return this;
+ }
+
+ @Override
+ public Optional<String> get(String key) {
+ return Optional.ofNullable(keyValues.get(key));
+ }
+
+ @Override
+ public boolean hasKey(String key) {
+ throw new UnsupportedOperationException("hasKey not implemented");
+ }
+
+ @Override
+ public String[] getStringArray(String key) {
+ throw new UnsupportedOperationException("getStringArray not implemented");
+ }
+ }
+}
diff --git a/server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/ce/NumberOfTasksInQueueTaskTest.java b/server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/ce/NumberOfTasksInQueueTaskTest.java
new file mode 100644
index 00000000000..dc56cb4e197
--- /dev/null
+++ b/server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/ce/NumberOfTasksInQueueTaskTest.java
@@ -0,0 +1,51 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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.server.monitoring.ce;
+
+import org.junit.Test;
+import org.sonar.api.config.Configuration;
+import org.sonar.db.DbClient;
+import org.sonar.db.ce.CeQueueDao;
+import org.sonar.server.monitoring.ServerMonitoringMetrics;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class NumberOfTasksInQueueTaskTest {
+
+ private final DbClient dbClient = mock(DbClient.class);
+ private final CeQueueDao ceQueueDao = mock(CeQueueDao.class);
+ private final ServerMonitoringMetrics metrics = mock(ServerMonitoringMetrics.class);
+ private final Configuration config = mock(Configuration.class);
+
+ @Test
+ public void run_setsValueInMetricsBasedOnValueReturnedFromDatabase() {
+ NumberOfTasksInQueueTask task = new NumberOfTasksInQueueTask(dbClient, metrics, config);
+ when(dbClient.ceQueueDao()).thenReturn(ceQueueDao);
+ when(ceQueueDao.countByStatus(any(), any())).thenReturn(10);
+
+ task.run();
+
+ verify(metrics, times(1)).setNumberOfPendingTasks(10);
+ }
+}
diff --git a/server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/ce/RecentTasksDurationTaskTest.java b/server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/ce/RecentTasksDurationTaskTest.java
new file mode 100644
index 00000000000..2d4eea9b745
--- /dev/null
+++ b/server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/ce/RecentTasksDurationTaskTest.java
@@ -0,0 +1,134 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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.server.monitoring.ce;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.api.config.Configuration;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbClient;
+import org.sonar.db.ce.CeActivityDao;
+import org.sonar.db.ce.CeActivityDto;
+import org.sonar.db.ce.CeQueueDto;
+import org.sonar.db.component.ComponentDao;
+import org.sonar.db.component.ComponentDto;
+import org.sonar.server.monitoring.ServerMonitoringMetrics;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class RecentTasksDurationTaskTest {
+
+ private final DbClient dbClient = mock(DbClient.class);
+ private final CeActivityDao ceActivityDao = mock(CeActivityDao.class);
+ private final ComponentDao componentDao = mock(ComponentDao.class);
+ private final ServerMonitoringMetrics metrics = mock(ServerMonitoringMetrics.class);
+ private final Configuration config = mock(Configuration.class);
+ private final System2 system = mock(System2.class);
+
+ @Before
+ public void before() {
+ when(dbClient.ceActivityDao()).thenReturn(ceActivityDao);
+ when(dbClient.componentDao()).thenReturn(componentDao);
+ ComponentDto componentDto = new ComponentDto();
+ componentDto.setDbKey("key");
+ }
+
+ @Test
+ public void run_given5SuccessfulTasks_observeDurationFor5Tasks() {
+ RecentTasksDurationTask task = new RecentTasksDurationTask(dbClient, metrics, config, system);
+ List<CeActivityDto> recentTasks = createTasks(5, 0);
+
+ when(componentDao.selectByUuids(any(), any())).thenReturn(createComponentDtos(5));
+ when(ceActivityDao.selectNewerThan(any(), anyLong())).thenReturn(recentTasks);
+
+ task.run();
+
+ verify(metrics, times(5)).observeComputeEngineTaskDuration(anyLong(), any(), any());
+ }
+
+ @Test
+ public void run_given1SuccessfulTasksAnd1Failing_observeDurationFor1Tasks() {
+ RecentTasksDurationTask task = new RecentTasksDurationTask(dbClient, metrics, config, system);
+ List<CeActivityDto> recentTasks = createTasks(1, 1);
+
+ when(componentDao.selectByUuids(any(), any())).thenReturn(createComponentDtos(1));
+ when(ceActivityDao.selectNewerThan(any(), anyLong())).thenReturn(recentTasks);
+
+ task.run();
+
+ verify(metrics, times(1)).observeComputeEngineTaskDuration(anyLong(), any(), any());
+ }
+
+ @Test
+ public void run_givenNullExecutionTime_dontReportMetricData() {
+ RecentTasksDurationTask task = new RecentTasksDurationTask(dbClient, metrics, config, system);
+ List<CeActivityDto> recentTasks = createTasks(1, 0);
+ recentTasks.get(0).setExecutionTimeMs(null);
+
+ when(componentDao.selectByUuids(any(), any())).thenReturn(createComponentDtos(1));
+ when(ceActivityDao.selectNewerThan(any(), anyLong())).thenReturn(recentTasks);
+
+ task.run();
+
+ verify(metrics, times(0)).observeComputeEngineTaskDuration(anyLong(), any(), any());
+ }
+
+ private List<CeActivityDto> createTasks(int numberOfSuccededTasks, int numberOfFailedTasks) {
+ List<CeActivityDto> dtos = new ArrayList<>();
+
+ for (int i=0; i<numberOfSuccededTasks; i++) {
+ dtos.add(newCeActivityTask(CeActivityDto.Status.SUCCESS));
+ }
+
+ for (int i=0; i<numberOfFailedTasks; i++) {
+ dtos.add(newCeActivityTask(CeActivityDto.Status.FAILED));
+ }
+
+ return dtos;
+ }
+
+ private List<ComponentDto> createComponentDtos(int number) {
+ List<ComponentDto> componentDtos = new ArrayList<>();
+ for(int i=0; i<5; i++) {
+ ComponentDto component = new ComponentDto();
+ component.setUuid(i + "");
+ component.setDbKey(i + "");
+ componentDtos.add(component);
+ }
+ return componentDtos;
+ }
+
+ private CeActivityDto newCeActivityTask(CeActivityDto.Status status) {
+ CeActivityDto dto = new CeActivityDto(new CeQueueDto());
+ dto.setStatus(status);
+ dto.setMainComponentUuid("0");
+ dto.setExecutionTimeMs(1000L);
+ return dto;
+ }
+}
+
+
diff --git a/server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/devops/AbstractDevOpsMetricsTaskTest.java b/server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/devops/AbstractDevOpsMetricsTaskTest.java
new file mode 100644
index 00000000000..876b008504e
--- /dev/null
+++ b/server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/devops/AbstractDevOpsMetricsTaskTest.java
@@ -0,0 +1,38 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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.server.monitoring.devops;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.sonar.db.alm.setting.ALM;
+import org.sonar.db.alm.setting.AlmSettingDto;
+
+public abstract class AbstractDevOpsMetricsTaskTest {
+
+ protected List<AlmSettingDto> generateDtos(int numberOfDtos, ALM alm) {
+ List<AlmSettingDto> settingDtos = new ArrayList<>();
+ for(int i=0; i<numberOfDtos; i++) {
+ AlmSettingDto dto = new AlmSettingDto();
+ dto.setAlm(alm);
+ settingDtos.add(dto);
+ }
+ return settingDtos;
+ }
+}
diff --git a/server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/devops/AzureMetricsTaskTest.java b/server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/devops/AzureMetricsTaskTest.java
new file mode 100644
index 00000000000..09081b3b8d9
--- /dev/null
+++ b/server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/devops/AzureMetricsTaskTest.java
@@ -0,0 +1,92 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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.server.monitoring.devops;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.IntStream;
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.alm.client.azure.AzureDevOpsValidator;
+import org.sonar.api.config.Configuration;
+import org.sonar.db.DbClient;
+import org.sonar.db.alm.setting.ALM;
+import org.sonar.db.alm.setting.AlmSettingDao;
+import org.sonar.db.alm.setting.AlmSettingDto;
+import org.sonar.server.monitoring.ServerMonitoringMetrics;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class AzureMetricsTaskTest extends AbstractDevOpsMetricsTaskTest {
+
+ private final ServerMonitoringMetrics metrics = mock(ServerMonitoringMetrics.class);
+ private final AzureDevOpsValidator azureDevOpsValidator = mock(AzureDevOpsValidator.class);
+ private final DbClient dbClient = mock(DbClient.class);
+ private final Configuration config = mock(Configuration.class);
+
+ private final AlmSettingDao almSettingsDao = mock(AlmSettingDao.class);
+
+ private final AzureMetricsTask underTest = new AzureMetricsTask(metrics, azureDevOpsValidator, dbClient, config);
+
+ @Before
+ public void before() {
+ when(dbClient.almSettingDao()).thenReturn(almSettingsDao);
+ }
+
+ @Test
+ public void run_azureDevOpsValidatorDoesntThrowException_setGreenStatusInMetricsOnce() {
+ List<AlmSettingDto> dtos = generateDtos(5, ALM.AZURE_DEVOPS);
+ when(almSettingsDao.selectByAlm(any(), any())).thenReturn(dtos);
+
+ underTest.run();
+
+ verify(metrics, times(1)).setAzureStatusToGreen();
+ verify(metrics, times(0)).setAzureStatusToRed();
+ }
+
+ @Test
+ public void run_azureDevOpsValidatorDoesntThrowException_setRedStatusInMetricsOnce() {
+ List<AlmSettingDto> dtos = generateDtos(5, ALM.AZURE_DEVOPS);
+ when(almSettingsDao.selectByAlm(any(), any())).thenReturn(dtos);
+
+ doThrow(new RuntimeException()).when(azureDevOpsValidator).validate(any());
+
+ underTest.run();
+
+ verify(metrics, times(0)).setAzureStatusToGreen();
+ verify(metrics, times(1)).setAzureStatusToRed();
+ }
+
+ @Test
+ public void run_azureIntegrationNotConfigured_setRedStatusInMetricsOnce() {
+ when(almSettingsDao.selectByAlm(any(), any())).thenReturn(Collections.emptyList());
+
+ underTest.run();
+
+ verify(metrics, times(0)).setAzureStatusToGreen();
+ verify(metrics, times(1)).setAzureStatusToRed();
+ }
+}
diff --git a/server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/devops/BitbucketMetricsTaskTest.java b/server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/devops/BitbucketMetricsTaskTest.java
new file mode 100644
index 00000000000..0ed22ed1388
--- /dev/null
+++ b/server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/devops/BitbucketMetricsTaskTest.java
@@ -0,0 +1,122 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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.server.monitoring.devops;
+
+import java.util.Collections;
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.alm.client.bitbucket.bitbucketcloud.BitbucketCloudValidator;
+import org.sonar.alm.client.bitbucketserver.BitbucketServerSettingsValidator;
+import org.sonar.api.config.Configuration;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.alm.setting.ALM;
+import org.sonar.db.alm.setting.AlmSettingDao;
+import org.sonar.server.monitoring.ServerMonitoringMetrics;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class BitbucketMetricsTaskTest extends AbstractDevOpsMetricsTaskTest {
+
+ private final ServerMonitoringMetrics metrics = mock(ServerMonitoringMetrics.class);
+ private final BitbucketCloudValidator bitbucketCloudValidator = mock(BitbucketCloudValidator.class);
+ private final BitbucketServerSettingsValidator bitbucketServerValidator = mock(BitbucketServerSettingsValidator.class);
+ private final DbClient dbClient = mock(DbClient.class);
+ private final Configuration config = mock(Configuration.class);
+
+ private final AlmSettingDao almSettingsDao = mock(AlmSettingDao.class);
+ private final DbSession dbSession = mock(DbSession.class);
+
+ private final BitbucketMetricsTask underTest = new BitbucketMetricsTask(metrics, bitbucketCloudValidator,
+ bitbucketServerValidator, dbClient, config);
+
+ @Before
+ public void before() {
+ when(dbClient.almSettingDao()).thenReturn(almSettingsDao);
+ when(dbClient.openSession(anyBoolean())).thenReturn(dbSession);
+ }
+
+ @Test
+ public void run_bitbucketValidatorsDontThrowException_setGreenStatusInMetricsOnce() {
+ when(almSettingsDao.selectByAlm(dbSession, ALM.BITBUCKET)).thenReturn(generateDtos(5, ALM.BITBUCKET));
+ when(almSettingsDao.selectByAlm(dbSession, ALM.BITBUCKET_CLOUD)).thenReturn(generateDtos(5, ALM.BITBUCKET_CLOUD));
+
+ underTest.run();
+
+ verify(metrics, times(1)).setBitbucketStatusToGreen();
+ verify(metrics, times(0)).setBitbucketStatusToRed();
+ }
+
+ @Test
+ public void run_bitbucketValidatorsDoThrowException_setRedStatusInMetricsOnce() {
+ when(almSettingsDao.selectByAlm(dbSession, ALM.BITBUCKET)).thenReturn(generateDtos(5, ALM.BITBUCKET));
+ when(almSettingsDao.selectByAlm(dbSession, ALM.BITBUCKET_CLOUD)).thenReturn(generateDtos(5, ALM.BITBUCKET_CLOUD));
+
+ doThrow(new RuntimeException()).when(bitbucketCloudValidator).validate(any());
+ doThrow(new RuntimeException()).when(bitbucketServerValidator).validate(any());
+
+ underTest.run();
+
+ verify(metrics, times(0)).setBitbucketStatusToGreen();
+ verify(metrics, times(1)).setBitbucketStatusToRed();
+ }
+
+
+ @Test
+ public void run_bitbucketServerValidatorThrowExceptionCloudDoesNot_setRedStatusInMetricsOnce() {
+ when(almSettingsDao.selectByAlm(dbSession, ALM.BITBUCKET)).thenReturn(generateDtos(5, ALM.BITBUCKET));
+ when(almSettingsDao.selectByAlm(dbSession, ALM.BITBUCKET_CLOUD)).thenReturn(generateDtos(5, ALM.BITBUCKET_CLOUD));
+
+ doThrow(new RuntimeException()).when(bitbucketServerValidator).validate(any());
+
+ underTest.run();
+
+ verify(metrics, times(0)).setBitbucketStatusToGreen();
+ verify(metrics, times(1)).setBitbucketStatusToRed();
+ }
+
+ @Test
+ public void run_bitbucketServerConfiguredBitbucketCloudNot_setGreenStatusInMetricsOnce() {
+ when(almSettingsDao.selectByAlm(dbSession, ALM.BITBUCKET)).thenReturn(generateDtos(1, ALM.BITBUCKET));
+
+ underTest.run();
+
+ verify(metrics, times(1)).setBitbucketStatusToGreen();
+ verify(metrics, times(0)).setBitbucketStatusToRed();
+ }
+
+ @Test
+ public void run_bitbucketIntegrationNotConfigured_setRedStatusInMetricsOnce() {
+ when(almSettingsDao.selectByAlm(dbSession, ALM.BITBUCKET)).thenReturn(Collections.emptyList());
+ when(almSettingsDao.selectByAlm(dbSession, ALM.BITBUCKET_CLOUD)).thenReturn(Collections.emptyList());
+
+ underTest.run();
+
+ verify(metrics, times(0)).setBitbucketStatusToGreen();
+ verify(metrics, times(1)).setBitbucketStatusToRed();
+ }
+
+}
diff --git a/server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/devops/DevOpsMetricsTaskTest.java b/server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/devops/DevOpsMetricsTaskTest.java
new file mode 100644
index 00000000000..904c250d6dc
--- /dev/null
+++ b/server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/devops/DevOpsMetricsTaskTest.java
@@ -0,0 +1,86 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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.server.monitoring.devops;
+
+import java.util.Optional;
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.api.config.Configuration;
+import org.sonar.db.DbClient;
+import org.sonar.server.monitoring.ServerMonitoringMetrics;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class DevOpsMetricsTaskTest {
+
+ private final ServerMonitoringMetrics metrics = mock(ServerMonitoringMetrics.class);
+ private final DbClient dbClient = mock(DbClient.class);
+ private final Configuration config = mock(Configuration.class);
+
+ private DevOpsMetricsTask underTest;
+
+ @Before
+ public void before() {
+ underTest = new DevOpsMetricsTask(dbClient, metrics, config) {
+ @Override
+ public void run() {
+ //intentionally empty
+ }
+ };
+ }
+
+ @Test
+ public void getDelay_returnNumberIfConfigEmpty() {
+ when(config.get("sonar.server.monitoring.devops.initial.delay")).thenReturn(Optional.empty());
+
+ long delay = underTest.getDelay();
+
+ assertThat(delay).isPositive();
+ }
+
+ @Test
+ public void getDelay_returnNumberFromConfig() {
+ when(config.getLong("sonar.server.monitoring.devops.initial.delay")).thenReturn(Optional.of(100_000L));
+
+ long delay = underTest.getDelay();
+
+ assertThat(delay).isEqualTo(100_000L);
+ }
+
+ @Test
+ public void getPeriod_returnNumberIfConfigEmpty() {
+ when(config.get("sonar.server.monitoring.devops.period")).thenReturn(Optional.empty());
+
+ long delay = underTest.getPeriod();
+
+ assertThat(delay).isPositive();
+ }
+
+ @Test
+ public void getPeriod_returnNumberFromConfig() {
+ when(config.getLong("sonar.server.monitoring.devops.period")).thenReturn(Optional.of(100_000L));
+
+ long delay = underTest.getPeriod();
+
+ assertThat(delay).isEqualTo(100_000L);
+ }
+}
diff --git a/server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/devops/DevOpsPlatformsMetricsCollectorTest.java b/server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/devops/DevOpsPlatformsMetricsCollectorTest.java
deleted file mode 100644
index d464825e9ee..00000000000
--- a/server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/devops/DevOpsPlatformsMetricsCollectorTest.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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.server.monitoring.devops;
-
-import org.sonar.api.config.Configuration;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
-import java.util.Set;
-import org.junit.Before;
-import org.junit.Test;
-import org.sonar.alm.client.azure.AzureDevOpsValidator;
-import org.sonar.alm.client.bitbucket.bitbucketcloud.BitbucketCloudValidator;
-import org.sonar.alm.client.bitbucketserver.BitbucketServerSettingsValidator;
-import org.sonar.alm.client.github.GithubGlobalSettingsValidator;
-import org.sonar.alm.client.gitlab.GitlabGlobalSettingsValidator;
-import org.sonar.db.DbClient;
-import org.sonar.db.alm.setting.ALM;
-import org.sonar.db.alm.setting.AlmSettingDao;
-import org.sonar.db.alm.setting.AlmSettingDto;
-import org.sonar.server.monitoring.ServerMonitoringMetrics;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoInteractions;
-import static org.mockito.Mockito.when;
-
-public class DevOpsPlatformsMetricsCollectorTest {
-
- private final ServerMonitoringMetrics serverMonitoringMetrics = mock(ServerMonitoringMetrics.class);
- private final DbClient dbClient = mock(DbClient.class);
- private final BitbucketServerSettingsValidator bitbucketServerValidator = mock(BitbucketServerSettingsValidator.class);
- private final GithubGlobalSettingsValidator githubValidator = mock(GithubGlobalSettingsValidator.class);
- private final GitlabGlobalSettingsValidator gitlabValidator = mock(GitlabGlobalSettingsValidator.class);
- private final BitbucketCloudValidator bitbucketCloudValidator = mock(BitbucketCloudValidator.class);
- private final AzureDevOpsValidator azureDevOpsValidator = mock(AzureDevOpsValidator.class);
- private final Configuration config = mock(Configuration.class);
-
- private DevOpsPlatformsMetricsCollector collector;
-
- @Before
- public void before() {
- collector = new DevOpsPlatformsMetricsCollector(serverMonitoringMetrics,
- dbClient, bitbucketServerValidator, githubValidator, gitlabValidator, bitbucketCloudValidator,
- azureDevOpsValidator, config);
- }
-
- @Test
- public void start_startsNewDeamonThread() {
- collector.start();
-
- Optional<Thread> newDeamonThread = findNewDeamonThread();
-
- assertThat(newDeamonThread).isPresent();
- assertThat(newDeamonThread.get().isDaemon()).isTrue();
- }
-
- @Test
- public void createTask_givenOneConfigForEachALM_allValidatorsAreCalled() {
- AlmSettingDao dao = mock(AlmSettingDao.class);
- List<AlmSettingDto> almSettingDtos = createAlmSettingDtos();
- when(dao.selectAll(any())).thenReturn(almSettingDtos);
- when(dbClient.almSettingDao()).thenReturn(dao);
-
- collector.createTask().run();
-
- verify(bitbucketCloudValidator, times(1)).validate(findDto(ALM.BITBUCKET_CLOUD, almSettingDtos));
- verify(bitbucketServerValidator, times(1)).validate(findDto(ALM.BITBUCKET, almSettingDtos));
- verify(azureDevOpsValidator, times(1)).validate(findDto(ALM.AZURE_DEVOPS, almSettingDtos));
- verify(gitlabValidator, times(1)).validate(findDto(ALM.GITLAB, almSettingDtos));
- verify(githubValidator, times(1)).validate(findDto(ALM.GITHUB, almSettingDtos));
- }
-
- @Test
- public void createTask_givenOnlyGitHubConfigured_validateOnlyGithub() {
- AlmSettingDao dao = mock(AlmSettingDao.class);
- AlmSettingDto githubDto = new AlmSettingDto();
- githubDto.setAlm(ALM.GITHUB);
- when(dao.selectAll(any())).thenReturn(List.of(githubDto));
- when(dbClient.almSettingDao()).thenReturn(dao);
-
- collector.createTask().run();
-
- verifyNoInteractions(bitbucketCloudValidator);
- verifyNoInteractions(bitbucketServerValidator);
- verifyNoInteractions(azureDevOpsValidator);
- verifyNoInteractions(gitlabValidator);
-
- verify(githubValidator, times(1)).validate(githubDto);
- }
-
- @Test
- public void createTask_givenAllValidationsFailing_setAllMetricsStatusesToFalse() {
- AlmSettingDao dao = mock(AlmSettingDao.class);
- List<AlmSettingDto> almSettingDtos = createAlmSettingDtos();
- when(dao.selectAll(any())).thenReturn(almSettingDtos);
- when(dbClient.almSettingDao()).thenReturn(dao);
-
- doThrow(new RuntimeException()).when(bitbucketCloudValidator).validate(any());
- doThrow(new RuntimeException()).when(bitbucketServerValidator).validate(any());
- doThrow(new RuntimeException()).when(azureDevOpsValidator).validate(any());
- doThrow(new RuntimeException()).when(gitlabValidator).validate(any());
- doThrow(new RuntimeException()).when(githubValidator).validate(any());
-
- collector.createTask().run();
-
- verify(serverMonitoringMetrics, times(2)).setBitbucketStatusToRed(); //2 validators for Bitbucket
- verify(serverMonitoringMetrics, times(1)).setAzureStatusToRed();
- verify(serverMonitoringMetrics, times(1)).setGitlabStatusToRed();
- verify(serverMonitoringMetrics, times(1)).setGithubStatusToRed();
- }
-
- @Test
- public void createTask_givenAllValidationsArePassing_setAllMetricsStatusesToTrue() {
- AlmSettingDao dao = mock(AlmSettingDao.class);
- List<AlmSettingDto> almSettingDtos = createAlmSettingDtos();
- when(dao.selectAll(any())).thenReturn(almSettingDtos);
- when(dbClient.almSettingDao()).thenReturn(dao);
-
- collector.createTask().run();
-
- verify(serverMonitoringMetrics, times(2)).setBitbucketStatusToGreen(); //2 validators for Bitbucket
- verify(serverMonitoringMetrics, times(1)).setAzureStatusToGreen();
- verify(serverMonitoringMetrics, times(1)).setGitlabStatusToGreen();
- verify(serverMonitoringMetrics, times(1)).setGithubStatusToGreen();
- }
-
- @Test
- public void createTask_givenFirstGithubValidationNotPassingAndSecondPassing_setGitHubValidationToTrue() {
- AlmSettingDao dao = mock(AlmSettingDao.class);
- List<AlmSettingDto> almSettingDtos = createAlmSettingDtos();
- when(dao.selectAll(any())).thenReturn(almSettingDtos);
- when(dbClient.almSettingDao()).thenReturn(dao);
-
- when(githubValidator.validate(any()))
- .thenThrow(new RuntimeException())
- .thenReturn(null);
-
- collector.createTask().run();
-
- verify(serverMonitoringMetrics, times(1)).setGithubStatusToRed();
- verify(serverMonitoringMetrics, times(0)).setGithubStatusToGreen();
- }
-
- private AlmSettingDto findDto(ALM alm, List<AlmSettingDto> almSettingDtos) {
- return almSettingDtos.stream().filter(d -> d.getAlm() == alm).findFirst().get();
- }
-
- private List<AlmSettingDto> createAlmSettingDtos() {
- List<AlmSettingDto> dtos = new ArrayList<>();
- for(ALM alm : ALM.values()) {
- AlmSettingDto almSettingDto = new AlmSettingDto();
- almSettingDto.setAlm(alm);
- dtos.add(almSettingDto);
- }
- return dtos;
- }
-
- private Optional<Thread> findNewDeamonThread() {
- Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
- String threadPartialName = DevOpsPlatformsMetricsCollector.class.getName();
- return threadSet.stream().filter(t -> t.getName().contains(threadPartialName)).findFirst();
- }
-}
diff --git a/server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/devops/GithubMetricsTaskTest.java b/server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/devops/GithubMetricsTaskTest.java
new file mode 100644
index 00000000000..fff40ad0a0f
--- /dev/null
+++ b/server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/devops/GithubMetricsTaskTest.java
@@ -0,0 +1,91 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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.server.monitoring.devops;
+
+import java.util.Collections;
+import java.util.List;
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.alm.client.github.GithubGlobalSettingsValidator;
+import org.sonar.alm.client.gitlab.GitlabGlobalSettingsValidator;
+import org.sonar.api.config.Configuration;
+import org.sonar.db.DbClient;
+import org.sonar.db.alm.setting.ALM;
+import org.sonar.db.alm.setting.AlmSettingDao;
+import org.sonar.db.alm.setting.AlmSettingDto;
+import org.sonar.server.monitoring.ServerMonitoringMetrics;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class GithubMetricsTaskTest extends AbstractDevOpsMetricsTaskTest {
+
+ private final ServerMonitoringMetrics metrics = mock(ServerMonitoringMetrics.class);
+ private final GithubGlobalSettingsValidator githubValidator = mock(GithubGlobalSettingsValidator.class);
+ private final DbClient dbClient = mock(DbClient.class);
+ private final Configuration config = mock(Configuration.class);
+
+ private final AlmSettingDao almSettingsDao = mock(AlmSettingDao.class);
+
+ private final GithubMetricsTask underTest = new GithubMetricsTask(metrics, githubValidator, dbClient, config);
+
+ @Before
+ public void before() {
+ when(dbClient.almSettingDao()).thenReturn(almSettingsDao);
+ }
+
+ @Test
+ public void run_githubValidatorDoesntThrowException_setGreenStatusInMetricsOnce() {
+ List<AlmSettingDto> dtos = generateDtos(5, ALM.GITHUB);
+ when(almSettingsDao.selectByAlm(any(), any())).thenReturn(dtos);
+
+ underTest.run();
+
+ verify(metrics, times(1)).setGithubStatusToGreen();
+ verify(metrics, times(0)).setGithubStatusToRed();
+ }
+
+ @Test
+ public void run_githubValidatorDoesntThrowException_setRedStatusInMetricsOnce() {
+ List<AlmSettingDto> dtos = generateDtos(5, ALM.GITHUB);
+ when(almSettingsDao.selectByAlm(any(), any())).thenReturn(dtos);
+
+ doThrow(new RuntimeException()).when(githubValidator).validate(any());
+
+ underTest.run();
+
+ verify(metrics, times(0)).setGithubStatusToGreen();
+ verify(metrics, times(1)).setGithubStatusToRed();
+ }
+
+ @Test
+ public void run_githubIntegrationNotConfigured_setRedStatusInMetricsOnce() {
+ when(almSettingsDao.selectByAlm(any(), any())).thenReturn(Collections.emptyList());
+
+ underTest.run();
+
+ verify(metrics, times(0)).setGithubStatusToGreen();
+ verify(metrics, times(1)).setGithubStatusToRed();
+ }
+}
diff --git a/server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/devops/GitlabMetricsTaskTest.java b/server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/devops/GitlabMetricsTaskTest.java
new file mode 100644
index 00000000000..18f7e98f05a
--- /dev/null
+++ b/server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/devops/GitlabMetricsTaskTest.java
@@ -0,0 +1,90 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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.server.monitoring.devops;
+
+import java.util.Collections;
+import java.util.List;
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.alm.client.gitlab.GitlabGlobalSettingsValidator;
+import org.sonar.api.config.Configuration;
+import org.sonar.db.DbClient;
+import org.sonar.db.alm.setting.ALM;
+import org.sonar.db.alm.setting.AlmSettingDao;
+import org.sonar.db.alm.setting.AlmSettingDto;
+import org.sonar.server.monitoring.ServerMonitoringMetrics;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class GitlabMetricsTaskTest extends AbstractDevOpsMetricsTaskTest {
+
+ private final ServerMonitoringMetrics metrics = mock(ServerMonitoringMetrics.class);
+ private final GitlabGlobalSettingsValidator gitlabValidator = mock(GitlabGlobalSettingsValidator.class);
+ private final DbClient dbClient = mock(DbClient.class);
+ private final Configuration config = mock(Configuration.class);
+
+ private final AlmSettingDao almSettingsDao = mock(AlmSettingDao.class);
+
+ private final GitlabMetricsTask underTest = new GitlabMetricsTask(metrics, gitlabValidator, dbClient, config);
+
+ @Before
+ public void before() {
+ when(dbClient.almSettingDao()).thenReturn(almSettingsDao);
+ }
+
+ @Test
+ public void run_gitlabValidatorDoesntThrowException_setGreenStatusInMetricsOnce() {
+ List<AlmSettingDto> dtos = generateDtos(5, ALM.GITLAB);
+ when(almSettingsDao.selectByAlm(any(), any())).thenReturn(dtos);
+
+ underTest.run();
+
+ verify(metrics, times(1)).setGitlabStatusToGreen();
+ verify(metrics, times(0)).setGitlabStatusToRed();
+ }
+
+ @Test
+ public void run_gitlabValidatorDoesntThrowException_setRedStatusInMetricsOnce() {
+ List<AlmSettingDto> dtos = generateDtos(5, ALM.GITLAB);
+ when(almSettingsDao.selectByAlm(any(), any())).thenReturn(dtos);
+
+ doThrow(new RuntimeException()).when(gitlabValidator).validate(any());
+
+ underTest.run();
+
+ verify(metrics, times(0)).setGitlabStatusToGreen();
+ verify(metrics, times(1)).setGitlabStatusToRed();
+ }
+
+ @Test
+ public void run_gitlabIntegrationNotConfigured_setRedStatusInMetricsOnce() {
+ when(almSettingsDao.selectByAlm(any(), any())).thenReturn(Collections.emptyList());
+
+ underTest.run();
+
+ verify(metrics, times(0)).setGitlabStatusToGreen();
+ verify(metrics, times(1)).setGitlabStatusToRed();
+ }
+}
diff --git a/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java b/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java
index fe0c229346c..af5d604e2bc 100644
--- a/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java
+++ b/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java
@@ -126,9 +126,15 @@ import org.sonar.server.measure.ws.MeasuresWsModule;
import org.sonar.server.metric.MetricFinder;
import org.sonar.server.metric.UnanalyzedLanguageMetrics;
import org.sonar.server.metric.ws.MetricsWsModule;
+import org.sonar.server.monitoring.MainCollector;
import org.sonar.server.monitoring.MonitoringWsModule;
-import org.sonar.server.monitoring.devops.DevOpsPlatformsMetricsCollector;
+import org.sonar.server.monitoring.ce.NumberOfTasksInQueueTask;
+import org.sonar.server.monitoring.ce.RecentTasksDurationTask;
+import org.sonar.server.monitoring.devops.AzureMetricsTask;
+import org.sonar.server.monitoring.devops.BitbucketMetricsTask;
import org.sonar.server.monitoring.ServerMonitoringMetrics;
+import org.sonar.server.monitoring.devops.GithubMetricsTask;
+import org.sonar.server.monitoring.devops.GitlabMetricsTask;
import org.sonar.server.newcodeperiod.ws.NewCodePeriodsWsModule;
import org.sonar.server.notification.NotificationModule;
import org.sonar.server.notification.ws.NotificationWsModule;
@@ -578,7 +584,16 @@ public class PlatformLevel4 extends PlatformLevel {
// monitoring
ServerMonitoringMetrics.class,
- DevOpsPlatformsMetricsCollector.class,
+
+ AzureMetricsTask.class,
+ BitbucketMetricsTask.class,
+ GithubMetricsTask.class,
+ GitlabMetricsTask.class,
+
+ NumberOfTasksInQueueTask.class,
+ RecentTasksDurationTask.class,
+
+ MainCollector.class,
PluginsRiskConsentFilter.class