Merge branch 'stable-2.16' * stable-2.16: Model healthcheck latency as gauge rather than timer Introduce the changes query healthcheck Config: allow per-check timeout configuration Send metrics when running healthcheck Fix ListProjects constructor in IT Change-Id: I5efad5b0dda5af529b3c55af33128959222cde3b
diff --git a/README.md b/README.md index edb538d..fe38bc8 100644 --- a/README.md +++ b/README.md
@@ -39,7 +39,7 @@ - elapsed: elapsed time in millis to perform the check - reviewdb: check that Gerrit can connect and query ReviewDb - projectslist: check that Gerrit can list projects -- auth: check that Gerrit can authenticate users +- jgit: check that Gerrit can access repositories Each check returns a JSON payload with the following information: @@ -72,7 +72,7 @@ "elapsed": 100, "result": "passed" }, - "auth": { + "jgit": { "ts": 139402910202, "elapsed": 80, "result": "passed" @@ -101,7 +101,7 @@ "elapsed": 100, "result": "timeout" }, - "auth": { + "jgit": { "ts": 139402910202, "elapsed": 80, "result": "passed" @@ -109,3 +109,12 @@ } ``` +## Metrics + +As for all other endpoints in Gerrit, some metrics are automatically emitted when the `/config/server/healthcheck~status` +endpoint is hit (thanks to the [Dropwizard](https://metrics.dropwizard.io/3.1.0/manual/core/) library). + +Some additional metrics are also produced to give extra insights on their result about results and latency of healthcheck +sub component, such as jgit, reviewdb, etc. + +More information can be found in the [config.md](resources/Documentation/config.md) file. \ No newline at end of file
diff --git a/src/main/java/com/googlesource/gerrit/plugins/healthcheck/HealthCheckConfig.java b/src/main/java/com/googlesource/gerrit/plugins/healthcheck/HealthCheckConfig.java new file mode 100644 index 0000000..6c93e91 --- /dev/null +++ b/src/main/java/com/googlesource/gerrit/plugins/healthcheck/HealthCheckConfig.java
@@ -0,0 +1,75 @@ +// Copyright (C) 2019 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.googlesource.gerrit.plugins.healthcheck; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.MoreObjects; +import com.google.common.base.Strings; +import com.google.gerrit.extensions.annotations.PluginName; +import com.google.gerrit.server.config.PluginConfigFactory; +import com.google.inject.Inject; +import com.google.inject.Singleton; +import java.util.concurrent.TimeUnit; +import org.eclipse.jgit.errors.ConfigInvalidException; +import org.eclipse.jgit.lib.Config; + +@Singleton +public class HealthCheckConfig { + public static final String HEALTHCHECK = "healthcheck"; + public static final HealthCheckConfig DEFAULT_CONFIG = new HealthCheckConfig(null); + private static final long HEALTHCHECK_TIMEOUT_DEFAULT = 500L; + private static final String QUERY_DEFAULT = "status:open"; + private static final int LIMIT_DEFAULT = 10; + + private final Config config; + + @Inject + public HealthCheckConfig(PluginConfigFactory configFactory, @PluginName String pluginName) { + config = configFactory.getGlobalPluginConfig(pluginName); + } + + @VisibleForTesting + public HealthCheckConfig(String configText) { + config = new Config(); + if (!Strings.isNullOrEmpty(configText)) { + try { + config.fromText(configText); + } catch (ConfigInvalidException e) { + throw new IllegalArgumentException("Invalid configuration " + configText, e); + } + } + } + + public long getTimeout() { + return getTimeout(null); + } + + public long getTimeout(String healthCheckName) { + long defaultTimeout = healthCheckName == null ? HEALTHCHECK_TIMEOUT_DEFAULT : getTimeout(null); + return config.getTimeUnit( + HEALTHCHECK, healthCheckName, "timeout", defaultTimeout, TimeUnit.MILLISECONDS); + } + + public String getQuery(String healthCheckName) { + String defaultQuery = healthCheckName == null ? QUERY_DEFAULT : getQuery(null); + return MoreObjects.firstNonNull( + config.getString(HEALTHCHECK, healthCheckName, "query"), defaultQuery); + } + + public int getLimit(String healthCheckName) { + int defaultLimit = healthCheckName == null ? LIMIT_DEFAULT : getLimit(null); + return config.getInt(HEALTHCHECK, healthCheckName, "limit", defaultLimit); + } +}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/healthcheck/HealthCheckMetrics.java b/src/main/java/com/googlesource/gerrit/plugins/healthcheck/HealthCheckMetrics.java new file mode 100644 index 0000000..edc3223 --- /dev/null +++ b/src/main/java/com/googlesource/gerrit/plugins/healthcheck/HealthCheckMetrics.java
@@ -0,0 +1,96 @@ +// Copyright (C) 2019 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.googlesource.gerrit.plugins.healthcheck; + +import com.google.common.annotations.VisibleForTesting; +import com.google.gerrit.extensions.events.LifecycleListener; +import com.google.gerrit.extensions.registration.DynamicSet; +import com.google.gerrit.extensions.registration.RegistrationHandle; +import com.google.gerrit.metrics.CallbackMetric0; +import com.google.gerrit.metrics.Counter0; +import com.google.gerrit.metrics.Description; +import com.google.gerrit.metrics.MetricMaker; +import com.google.inject.Inject; +import com.google.inject.Singleton; +import com.googlesource.gerrit.plugins.healthcheck.check.HealthCheck; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +@Singleton +public class HealthCheckMetrics implements LifecycleListener { + + private final DynamicSet<HealthCheck> healthChecks; + private final MetricMaker metricMaker; + private final Set<RegistrationHandle> registeredMetrics; + private final Set<Runnable> triggers; + + @Inject + public HealthCheckMetrics(DynamicSet<HealthCheck> healthChecks, MetricMaker metricMaker) { + this.healthChecks = healthChecks; + this.metricMaker = metricMaker; + this.registeredMetrics = Collections.synchronizedSet(new HashSet<>()); + this.triggers = Collections.synchronizedSet(new HashSet<>()); + } + + @Override + public void start() { + + for (HealthCheck healthCheck : healthChecks) { + String name = healthCheck.name(); + + Counter0 failureMetric = + metricMaker.newCounter( + String.format("%s/failure", name), + new Description(String.format("%s healthcheck failures count", name)) + .setCumulative() + .setRate() + .setUnit("failures")); + + CallbackMetric0<Long> latencyMetric = + metricMaker.newCallbackMetric( + String.format("%s/latest_latency", name), + Long.class, + new Description(String.format("%s health check latency execution (ms)", name)) + .setGauge() + .setUnit(Description.Units.MILLISECONDS)); + + Runnable metricCallBack = + () -> { + HealthCheck.StatusSummary status = healthCheck.getLatestStatus(); + latencyMetric.set(healthCheck.getLatestStatus().elapsed); + if (status.isFailure()) { + failureMetric.increment(); + } + }; + + registeredMetrics.add(failureMetric); + registeredMetrics.add(metricMaker.newTrigger(latencyMetric, metricCallBack)); + triggers.add(metricCallBack); + } + } + + @Override + public void stop() { + for (RegistrationHandle handle : registeredMetrics) { + handle.remove(); + } + } + + @VisibleForTesting + public void triggerAll() { + triggers.forEach(Runnable::run); + } +}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/healthcheck/HealthCheckSubsystemsModule.java b/src/main/java/com/googlesource/gerrit/plugins/healthcheck/HealthCheckSubsystemsModule.java index d57a1f9..277c11f 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/healthcheck/HealthCheckSubsystemsModule.java +++ b/src/main/java/com/googlesource/gerrit/plugins/healthcheck/HealthCheckSubsystemsModule.java
@@ -14,11 +14,13 @@ package com.googlesource.gerrit.plugins.healthcheck; +import com.google.gerrit.extensions.events.LifecycleListener; import com.google.gerrit.extensions.registration.DynamicSet; import com.google.inject.AbstractModule; import com.googlesource.gerrit.plugins.healthcheck.check.HealthCheck; import com.googlesource.gerrit.plugins.healthcheck.check.JGitHealthCheck; import com.googlesource.gerrit.plugins.healthcheck.check.ProjectsListHealthCheck; +import com.googlesource.gerrit.plugins.healthcheck.check.QueryChangesHealthCheck; public class HealthCheckSubsystemsModule extends AbstractModule { @@ -26,6 +28,8 @@ protected void configure() { bindChecker(JGitHealthCheck.class); bindChecker(ProjectsListHealthCheck.class); + bindChecker(QueryChangesHealthCheck.class); + bind(LifecycleListener.class).to(HealthCheckMetrics.class); } private void bindChecker(Class<? extends HealthCheck> healthCheckClass) {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/healthcheck/api/HealthCheckStatusEndpoint.java b/src/main/java/com/googlesource/gerrit/plugins/healthcheck/api/HealthCheckStatusEndpoint.java index 87a1fc8..26a2042 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/healthcheck/api/HealthCheckStatusEndpoint.java +++ b/src/main/java/com/googlesource/gerrit/plugins/healthcheck/api/HealthCheckStatusEndpoint.java
@@ -50,8 +50,8 @@ .stream() .filter( res -> - res instanceof HealthCheck.Status - && ((HealthCheck.Status) res).result != HealthCheck.Result.PASSED) + res instanceof HealthCheck.StatusSummary + && ((HealthCheck.StatusSummary) res).result != HealthCheck.Result.PASSED) .findFirst() .isPresent()) { return HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/AbstractHealthCheck.java b/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/AbstractHealthCheck.java index 5c8d410..26ef1ee 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/AbstractHealthCheck.java +++ b/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/AbstractHealthCheck.java
@@ -16,6 +16,7 @@ import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListeningExecutorService; +import com.googlesource.gerrit.plugins.healthcheck.HealthCheckConfig; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; @@ -24,13 +25,17 @@ public abstract class AbstractHealthCheck implements HealthCheck { private static final Logger log = LoggerFactory.getLogger(AbstractHealthCheck.class); - public static final long CHECK_TIMEOUT = 500L; + private final long timeout; private final String name; private final ListeningExecutorService executor; + protected StatusSummary latestStatus; - protected AbstractHealthCheck(ListeningExecutorService executor, String name) { + protected AbstractHealthCheck( + ListeningExecutorService executor, HealthCheckConfig config, String name) { this.executor = executor; this.name = name; + this.timeout = config.getTimeout(name); + this.latestStatus = StatusSummary.INITIAL_STATUS; } @Override @@ -39,9 +44,9 @@ } @Override - public Status run() { + public StatusSummary run() { final long ts = System.currentTimeMillis(); - ListenableFuture<Status> resultFuture = + ListenableFuture<StatusSummary> resultFuture = executor.submit( () -> { Result healthy; @@ -51,19 +56,24 @@ log.warn("Check {} failed", name, e); healthy = Result.FAILED; } - return new Status(healthy, ts, System.currentTimeMillis() - ts); + return new StatusSummary(healthy, ts, System.currentTimeMillis() - ts); }); - try { - return resultFuture.get(CHECK_TIMEOUT, TimeUnit.MILLISECONDS); + latestStatus = resultFuture.get(timeout, TimeUnit.MILLISECONDS); } catch (TimeoutException e) { log.warn("Check {} timed out", name, e); - return new Status(Result.TIMEOUT, ts, System.currentTimeMillis() - ts); + latestStatus = new StatusSummary(Result.TIMEOUT, ts, System.currentTimeMillis() - ts); } catch (InterruptedException | ExecutionException e) { log.warn("Check {} failed while waiting for its future result", name, e); - return new Status(Result.FAILED, ts, System.currentTimeMillis() - ts); + latestStatus = new StatusSummary(Result.FAILED, ts, System.currentTimeMillis() - ts); } + return latestStatus; } protected abstract Result doCheck() throws Exception; + + @Override + public StatusSummary getLatestStatus() { + return latestStatus; + } }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/HealthCheck.java b/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/HealthCheck.java index 355b0cf..4f6a532 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/HealthCheck.java +++ b/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/HealthCheck.java
@@ -27,19 +27,27 @@ TIMEOUT; } - public class Status { + public class StatusSummary { + public static final StatusSummary INITIAL_STATUS = + new StatusSummary(Result.PASSED, System.currentTimeMillis(), 0L); public final Result result; public final long ts; public final long elapsed; - public Status(Result result, long ts, long elapsed) { + public StatusSummary(Result result, long ts, long elapsed) { this.result = result; this.ts = ts; this.elapsed = elapsed; } + + public Boolean isFailure() { + return this.result != Result.PASSED; + } } - Status run(); + StatusSummary run(); String name(); + + StatusSummary getLatestStatus(); }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/HealthCheckNames.java b/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/HealthCheckNames.java index 9a87490..670e1b4 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/HealthCheckNames.java +++ b/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/HealthCheckNames.java
@@ -17,4 +17,5 @@ public interface HealthCheckNames { String JGIT = "jgit"; String PROJECTSLIST = "projectslist"; + String QUERYCHANGES = "querychanges"; }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/JGitHealthCheck.java b/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/JGitHealthCheck.java index a23e0d1..73fa88d 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/JGitHealthCheck.java +++ b/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/JGitHealthCheck.java
@@ -20,9 +20,12 @@ import com.google.gerrit.server.config.AllProjectsName; import com.google.gerrit.server.git.GitRepositoryManager; import com.google.inject.Inject; +import com.google.inject.Singleton; +import com.googlesource.gerrit.plugins.healthcheck.HealthCheckConfig; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.Repository; +@Singleton public class JGitHealthCheck extends AbstractHealthCheck { private final GitRepositoryManager repositoryManager; private final AllProjectsName allProjectsName; @@ -30,9 +33,11 @@ @Inject public JGitHealthCheck( ListeningExecutorService executor, + HealthCheckConfig config, GitRepositoryManager repositoryManager, AllProjectsName allProjectsName) { - super(executor, JGIT); + super(executor, config, JGIT); + this.repositoryManager = repositoryManager; this.allProjectsName = allProjectsName; }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/ProjectsListHealthCheck.java b/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/ProjectsListHealthCheck.java index a7552f9..4da142d 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/ProjectsListHealthCheck.java +++ b/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/ProjectsListHealthCheck.java
@@ -20,18 +20,23 @@ import com.google.gerrit.extensions.common.ProjectInfo; import com.google.gerrit.server.restapi.project.ListProjects; import com.google.inject.Inject; +import com.google.inject.Singleton; +import com.googlesource.gerrit.plugins.healthcheck.HealthCheckConfig; import java.util.SortedMap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +@Singleton public class ProjectsListHealthCheck extends AbstractHealthCheck { private static final Logger log = LoggerFactory.getLogger(ProjectsListHealthCheck.class); private static final int PROJECTS_LIST_LIMIT = 100; private final ListProjects listProjects; @Inject - public ProjectsListHealthCheck(ListeningExecutorService executor, ListProjects listProjects) { - super(executor, PROJECTSLIST); + public ProjectsListHealthCheck( + ListeningExecutorService executor, HealthCheckConfig config, ListProjects listProjects) { + super(executor, config, PROJECTSLIST); + this.listProjects = listProjects; }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/QueryChangesHealthCheck.java b/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/QueryChangesHealthCheck.java new file mode 100644 index 0000000..2f5d115 --- /dev/null +++ b/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/QueryChangesHealthCheck.java
@@ -0,0 +1,72 @@ +// Copyright (C) 2019 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.googlesource.gerrit.plugins.healthcheck.check; + +import static com.googlesource.gerrit.plugins.healthcheck.check.HealthCheckNames.QUERYCHANGES; + +import com.google.common.util.concurrent.ListeningExecutorService; +import com.google.gerrit.server.restapi.change.QueryChanges; +import com.google.gerrit.server.util.ManualRequestContext; +import com.google.gerrit.server.util.OneOffRequestContext; +import com.google.inject.Inject; +import com.google.inject.Singleton; +import com.googlesource.gerrit.plugins.healthcheck.HealthCheckConfig; +import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Singleton +public class QueryChangesHealthCheck extends AbstractHealthCheck { + private static final Logger log = LoggerFactory.getLogger(QueryChangesHealthCheck.class); + private final QueryChanges queryChanges; + private final int limit; + private final OneOffRequestContext oneOffCtx; + + @Inject + public QueryChangesHealthCheck( + ListeningExecutorService executor, + HealthCheckConfig config, + QueryChanges queryChanges, + OneOffRequestContext oneOffCtx) { + super(executor, config, QUERYCHANGES); + this.queryChanges = queryChanges; + this.limit = config.getLimit(QUERYCHANGES); + queryChanges.setLimit(limit); + queryChanges.addQuery(config.getQuery(QUERYCHANGES)); + queryChanges.setStart(0); + this.oneOffCtx = oneOffCtx; + } + + @Override + protected Result doCheck() throws Exception { + try (ManualRequestContext ctx = oneOffCtx.open()) { + List<?> changes = queryChanges.apply(null); + if (changes == null) { + log.warn("Cannot query changes: received a null list of results"); + return Result.FAILED; + } + + if (changes.size() < limit) { + log.warn( + "Query changes did not return enough items: expected {} items but got only {}", + limit, + changes.size()); + return Result.FAILED; + } + + return Result.PASSED; + } + } +}
diff --git a/src/main/resources/Documentation/about.md b/src/main/resources/Documentation/about.md new file mode 100644 index 0000000..b2f798d --- /dev/null +++ b/src/main/resources/Documentation/about.md
@@ -0,0 +1,3 @@ +This plugin provides support for monitoring and alerting purposes. +A common use-case is the automatic detection and recovery of issues +for Gerrit Servers that need to be available on a 24x7 basis.
diff --git a/src/main/resources/Documentation/config.md b/src/main/resources/Documentation/config.md new file mode 100644 index 0000000..74ad62c --- /dev/null +++ b/src/main/resources/Documentation/config.md
@@ -0,0 +1,66 @@ +@PLUGIN@ configuration +====================== + +The @PLUGIN@ +------------ + +The plugin does not require any configuration at all and exposes an HTTP +endpoint for querying the service status. + +``` +GET /config/server/healthcheck~status + +)]}' +{ + "ts": 139402910202, + "elapsed": 100, + "reviewdb": { + "ts": 139402910202, + "elapsed": 50, + "result": "passed" + }, + "projectslist": { + "ts": 139402910202, + "elapsed": 100, + "result": "passed" + }, + "auth": { + "ts": 139402910202, + "elapsed": 80, + "result": "passed" + } +} +``` + +Settings +-------- + +The plugin allows to customize its behaviour through a specific +`healthcheck.config` file in the `$GERRIT_SITE/etc` directory. + +Each section of the form `[healthcheck "<checkName>"]` can tailor the +behaviour of an individual `<checkName>`. The section `[healthcheck]` +defines the global defaults valid for all checks. + +The following check names are available: + +- `reviewdb` : check connectivity and ability to query ReviewDb +- `jgit` : check connectivity to the filesystem and ability to open a JGit ref and object +- `projectslist` : check the ability to list projects with their descriptions + +The follwing parameters are available: + +- `healthcheck.<checkName>.timeout` : Specific timeout (msec) for the + healthcheck to complete. Zero means that there is no timeout. + + Default: 500 + +- `healthcheck.<checkName>.query` : Query to be executed for extracting + elements from the check. + + Default: status:open + +- `healthcheck.<checkName>.limit` : Maximum number of elements to retrieve from + the the check results. + + Default: 10 \ No newline at end of file
diff --git a/src/resources/Documentation/config.md b/src/resources/Documentation/config.md new file mode 100644 index 0000000..ea51c10 --- /dev/null +++ b/src/resources/Documentation/config.md
@@ -0,0 +1,68 @@ +## Metrics + +As for all other endpoints in Gerrit, some metrics are automatically emitted when the `/config/server/healthcheck~status` +endpoint is hit (thanks to the [Dropwizard](https://metrics.dropwizard.io/3.1.0/manual/core/) library). +For example, some of the metrics exposed will be: + +``` +# HELP http_server_rest_api_response_bytes_healthcheck_com_googlesource_gerrit_plugins_healthcheck_api_HealthCheckStatusEndpoint Generated from Dropwizard metric import (metric=http/server/rest_api/response_bytes/healthcheck-com.googlesource.gerrit.plugins.healthcheck.api.HealthCheckStatusEndpoint, type=com.codahale.metrics.Histogram) +# TYPE http_server_rest_api_response_bytes_healthcheck_com_googlesource_gerrit_plugins_healthcheck_api_HealthCheckStatusEndpoint summary +http_server_rest_api_response_bytes_healthcheck_com_googlesource_gerrit_plugins_healthcheck_api_HealthCheckStatusEndpoint{quantile="0.5",} 308.0 +http_server_rest_api_response_bytes_healthcheck_com_googlesource_gerrit_plugins_healthcheck_api_HealthCheckStatusEndpoint{quantile="0.75",} 308.0 +http_server_rest_api_response_bytes_healthcheck_com_googlesource_gerrit_plugins_healthcheck_api_HealthCheckStatusEndpoint{quantile="0.95",} 308.0 +http_server_rest_api_response_bytes_healthcheck_com_googlesource_gerrit_plugins_healthcheck_api_HealthCheckStatusEndpoint{quantile="0.98",} 310.0 +http_server_rest_api_response_bytes_healthcheck_com_googlesource_gerrit_plugins_healthcheck_api_HealthCheckStatusEndpoint{quantile="0.99",} 310.0 +http_server_rest_api_response_bytes_healthcheck_com_googlesource_gerrit_plugins_healthcheck_api_HealthCheckStatusEndpoint{quantile="0.999",} 310.0 +http_server_rest_api_response_bytes_healthcheck_com_googlesource_gerrit_plugins_healthcheck_api_HealthCheckStatusEndpoint_count 4.0 + +# HELP http_server_rest_api_server_latency_healthcheck_com_googlesource_gerrit_plugins_healthcheck_api_HealthCheckStatusEndpoint Generated from Dropwizard metric import (metric=http/server/rest_api/server_latency/healthcheck-com.googlesource.gerrit.plugins.healthcheck.api.HealthCheckStatusEndpoint, type=com.codahale.metrics.Timer) +# TYPE http_server_rest_api_server_latency_healthcheck_com_googlesource_gerrit_plugins_healthcheck_api_HealthCheckStatusEndpoint summary +http_server_rest_api_server_latency_healthcheck_com_googlesource_gerrit_plugins_healthcheck_api_HealthCheckStatusEndpoint{quantile="0.5",} 0.008638662 +http_server_rest_api_server_latency_healthcheck_com_googlesource_gerrit_plugins_healthcheck_api_HealthCheckStatusEndpoint{quantile="0.75",} 0.008638662 +http_server_rest_api_server_latency_healthcheck_com_googlesource_gerrit_plugins_healthcheck_api_HealthCheckStatusEndpoint{quantile="0.95",} 0.010553707 +http_server_rest_api_server_latency_healthcheck_com_googlesource_gerrit_plugins_healthcheck_api_HealthCheckStatusEndpoint{quantile="0.98",} 0.147902061 +http_server_rest_api_server_latency_healthcheck_com_googlesource_gerrit_plugins_healthcheck_api_HealthCheckStatusEndpoint{quantile="0.99",} 0.147902061 +http_server_rest_api_server_latency_healthcheck_com_googlesource_gerrit_plugins_healthcheck_api_HealthCheckStatusEndpoint{quantile="0.999",} 0.147902061 +http_server_rest_api_server_latency_healthcheck_com_googlesource_gerrit_plugins_healthcheck_api_HealthCheckStatusEndpoint_count 4.0 + +# HELP http_server_rest_api_count_healthcheck_com_googlesource_gerrit_plugins_healthcheck_api_HealthCheckStatusEndpoint_total Generated from Dropwizard metric import (metric=http/server/rest_api/count/healthcheck-com.googlesource.gerrit.plugins.healthcheck.api.HealthCheckStatusEndpoint, type=com.codahale.metrics.Meter) +# TYPE http_server_rest_api_count_healthcheck_com_googlesource_gerrit_plugins_healthcheck_api_HealthCheckStatusEndpoint_total counter +http_server_rest_api_count_healthcheck_com_googlesource_gerrit_plugins_healthcheck_api_HealthCheckStatusEndpoint_total 4.0 + +# HELP http_server_rest_api_error_count_healthcheck_com_googlesource_gerrit_plugins_healthcheck_api_HealthCheckStatusEndpoint_500_total Generated from Dropwizard metric import (metric=http/server/rest_api/error_count/healthcheck-com.googlesource.gerrit.plugins.healthcheck.api.HealthCheckStatusEndpoint/500, type=com.codahale.metrics.Meter) +# TYPE http_server_rest_api_error_count_healthcheck_com_googlesource_gerrit_plugins_healthcheck_api_HealthCheckStatusEndpoint_500_total counter +http_server_rest_api_error_count_healthcheck_com_googlesource_gerrit_plugins_healthcheck_api_HealthCheckStatusEndpoint_500_total 2.0 +``` + +However some extra metrics are also emitted to expose more details about the healthcheck result. +Specifically two metrics are emitted for each component contributing to the overall healthcheck result (JGIT, PROJECTLIST, REVIEWDB). +* plugins_healthcheck_<healthcheck_component>_latest_measured_latency: the latency of this component in the latest executed healthcheck run +* plugins_healthcheck_jgit_failure_total: the cumulative number of failures for this specific component + +``` +# HELP plugins_healthcheck_jgit_latest_measured_latency Generated from Dropwizard metric import (metric=plugins/healthcheck/jgit/latency, type=com.google.gerrit.metrics.dropwizard.CallbackMetricImpl0$1) +# TYPE plugins_healthcheck_jgit_latest_measured_latency gauge +plugins_healthcheck_jgit_latest_measured_latency 4.0 + +# HELP plugins_healthcheck_projectslist_latest_measured_latency Generated from Dropwizard metric import (metric=plugins/healthcheck/projectslist/latency, type=com.google.gerrit.metrics.dropwizard.CallbackMetricImpl0$1) +# TYPE plugins_healthcheck_projectslist_latest_measured_latency gauge +plugins_healthcheck_projectslist_latest_measured_latency 5.0 + +# HELP plugins_healthcheck_reviewdb_latest_measured_latency Generated from Dropwizard metric import (metric=plugins/healthcheck/reviewdb/latency, type=com.google.gerrit.metrics.dropwizard.CallbackMetricImpl0$1) +# TYPE plugins_healthcheck_reviewdb_latest_measured_latency gauge +plugins_healthcheck_reviewdb_latest_measured_latency 3.0 + +# HELP plugins_healthcheck_jgit_failure_total Generated from Dropwizard metric import (metric=plugins/healthcheck/jgit/failure, type=com.codahale.metrics.Meter) +# TYPE plugins_healthcheck_jgit_failure_total counter +plugins_healthcheck_jgit_failure_total 3.0 + +# HELP plugins_healthcheck_projectslist_failure_total Generated from Dropwizard metric import (metric=plugins/healthcheck/projectslist/failure, type=com.codahale.metrics.Meter) +# TYPE plugins_healthcheck_projectslist_failure_total counter +plugins_healthcheck_projectslist_failure_total 0.0 + +# HELP plugins_healthcheck_reviewdb_failure_total Generated from Dropwizard metric import (metric=plugins/healthcheck/reviewdb/failure, type=com.codahale.metrics.Meter) +# TYPE plugins_healthcheck_reviewdb_failure_total counter +plugins_healthcheck_reviewdb_failure_total 0.0 +``` + +Metrics will be exposed to prometheus by the [metrics-reporter-prometheus](https://gerrit.googlesource.com/plugins/metrics-reporter-prometheus/) plugin.
diff --git a/src/test/java/com/googlesource/gerrit/plugins/healthcheck/HealthCheckConfigTest.java b/src/test/java/com/googlesource/gerrit/plugins/healthcheck/HealthCheckConfigTest.java new file mode 100644 index 0000000..fc215ff --- /dev/null +++ b/src/test/java/com/googlesource/gerrit/plugins/healthcheck/HealthCheckConfigTest.java
@@ -0,0 +1,48 @@ +// Copyright (C) 2019 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.googlesource.gerrit.plugins.healthcheck; + +import static com.google.common.truth.Truth.assertThat; +import static com.googlesource.gerrit.plugins.healthcheck.HealthCheckConfig.DEFAULT_CONFIG; + +import org.junit.Test; + +public class HealthCheckConfigTest { + + @Test + public void shouldHaveDefaultTimeout() { + long defaultTimeout = DEFAULT_CONFIG.getTimeout(null); + assertThat(defaultTimeout).isGreaterThan(0L); + assertThat(DEFAULT_CONFIG.getTimeout("fooCheck")).isEqualTo(defaultTimeout); + } + + @Test + public void shouldHaveGlobalTimeout() { + HealthCheckConfig config = new HealthCheckConfig("[healthcheck]\n" + "timeout=1000"); + + assertThat(config.getTimeout(null)).isEqualTo(1000); + assertThat(config.getTimeout("barCheck")).isEqualTo(1000); + } + + @Test + public void shouldHaveCheckOverriddenTimeout() { + HealthCheckConfig config = + new HealthCheckConfig( + "[healthcheck]\n" + "timeout=2000\n" + "[healthcheck \"fooCheck\"]\n" + "timeout=1000"); + + assertThat(config.getTimeout("fooCheck")).isEqualTo(1000); + assertThat(config.getTimeout("barCheck")).isEqualTo(2000); + } +}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/healthcheck/HealthCheckIT.java b/src/test/java/com/googlesource/gerrit/plugins/healthcheck/HealthCheckIT.java index ec338b6..3f70903 100644 --- a/src/test/java/com/googlesource/gerrit/plugins/healthcheck/HealthCheckIT.java +++ b/src/test/java/com/googlesource/gerrit/plugins/healthcheck/HealthCheckIT.java
@@ -17,20 +17,48 @@ import static com.google.common.net.HttpHeaders.CONTENT_TYPE; import static com.google.common.truth.Truth.assertThat; import static com.googlesource.gerrit.plugins.healthcheck.check.HealthCheckNames.JGIT; +import static com.googlesource.gerrit.plugins.healthcheck.check.HealthCheckNames.QUERYCHANGES; import com.google.gerrit.acceptance.LightweightPluginDaemonTest; import com.google.gerrit.acceptance.RestResponse; import com.google.gerrit.acceptance.Sandboxed; import com.google.gerrit.acceptance.TestPlugin; +import com.google.gerrit.extensions.annotations.PluginName; import com.google.gson.Gson; import com.google.gson.JsonObject; +import com.google.inject.AbstractModule; +import com.googlesource.gerrit.plugins.healthcheck.check.HealthCheckNames; import java.io.IOException; +import org.junit.Before; import org.junit.Test; @TestPlugin(name = "healthcheck", sysModule = "com.googlesource.gerrit.plugins.healthcheck.Module") @Sandboxed public class HealthCheckIT extends LightweightPluginDaemonTest { Gson gson = new Gson(); + HealthCheckConfig config; + + @Override + @Before + public void setUpTestPlugin() throws Exception { + super.setUpTestPlugin(); + + config = + server + .getTestInjector() + .createChildInjector( + new AbstractModule() { + @Override + protected void configure() { + bind(String.class).annotatedWith(PluginName.class).toInstance("healthcheck"); + } + }) + .getInstance(HealthCheckConfig.class); + int numChanges = config.getLimit(HealthCheckNames.QUERYCHANGES); + for (int i = 0; i < numChanges; i++) { + createChange("refs/for/master"); + } + } @Test public void shouldReturnOkWhenHealthy() throws Exception { @@ -52,6 +80,17 @@ assertCheckResult(respPayload, JGIT, "passed"); } + @Test + public void shouldReturnQueryChangesCheck() throws Exception { + createChange("refs/for/master"); + RestResponse resp = getHealthCheckStatus(); + resp.assertOK(); + + JsonObject respPayload = gson.fromJson(resp.getReader(), JsonObject.class); + + assertCheckResult(respPayload, QUERYCHANGES, "passed"); + } + private RestResponse getHealthCheckStatus() throws IOException { return adminRestSession.get("/config/server/healthcheck~status"); }
diff --git a/src/test/java/com/googlesource/gerrit/plugins/healthcheck/HealthCheckMetricsTest.java b/src/test/java/com/googlesource/gerrit/plugins/healthcheck/HealthCheckMetricsTest.java new file mode 100644 index 0000000..9955a33 --- /dev/null +++ b/src/test/java/com/googlesource/gerrit/plugins/healthcheck/HealthCheckMetricsTest.java
@@ -0,0 +1,164 @@ +// Copyright (C) 2019 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.googlesource.gerrit.plugins.healthcheck; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.util.concurrent.ListeningExecutorService; +import com.google.gerrit.extensions.events.LifecycleListener; +import com.google.gerrit.extensions.registration.DynamicSet; +import com.google.gerrit.metrics.CallbackMetric0; +import com.google.gerrit.metrics.Counter0; +import com.google.gerrit.metrics.Description; +import com.google.gerrit.metrics.DisabledMetricMaker; +import com.google.gerrit.metrics.MetricMaker; +import com.google.inject.AbstractModule; +import com.google.inject.Guice; +import com.google.inject.Inject; +import com.google.inject.Injector; +import com.google.inject.Singleton; +import com.googlesource.gerrit.plugins.healthcheck.check.AbstractHealthCheck; +import com.googlesource.gerrit.plugins.healthcheck.check.HealthCheck; +import com.googlesource.gerrit.plugins.healthcheck.check.HealthCheck.Result; +import com.googlesource.gerrit.plugins.healthcheck.check.HealthCheck.StatusSummary; +import org.junit.Before; +import org.junit.Test; + +public class HealthCheckMetricsTest { + + @Inject private ListeningExecutorService executor; + private TestMetrics testMetrics = new TestMetrics(); + + @Before + public void setUp() throws Exception { + testMetrics.reset(); + } + + private void setWithStatusSummary(StatusSummary StatusSummary) { + TestHealthCheck testHealthCheck = new TestHealthCheck(executor, "test", StatusSummary); + + Injector injector = + testInjector( + new AbstractModule() { + @Override + protected void configure() { + DynamicSet.bind(binder(), HealthCheck.class).toInstance(testHealthCheck); + bind(MetricMaker.class).toInstance(testMetrics); + bind(LifecycleListener.class).to(HealthCheckMetrics.class); + } + }); + HealthCheckMetrics healthCheckMetrics = injector.getInstance(HealthCheckMetrics.class); + + healthCheckMetrics.start(); + testHealthCheck.run(); + healthCheckMetrics.triggerAll(); + } + + @Test + public void shouldSendCounterWhenStatusSummaryFailed() { + Long elapsed = 100L; + setWithStatusSummary(new StatusSummary(Result.FAILED, 1L, elapsed)); + + assertThat(testMetrics.getFailures()).isEqualTo(1); + assertThat(testMetrics.getLatency()).isEqualTo(elapsed); + } + + @Test + public void shouldSendCounterWhenStatusSummaryTimeout() { + Long elapsed = 100L; + setWithStatusSummary(new StatusSummary(Result.TIMEOUT, 1L, elapsed)); + + assertThat(testMetrics.getFailures()).isEqualTo(1); + assertThat(testMetrics.getLatency()).isEqualTo(elapsed); + } + + @Test + public void shouldNOTSendCounterWhenStatusSummarySuccess() { + Long elapsed = 100L; + setWithStatusSummary(new StatusSummary(Result.PASSED, 1L, elapsed)); + + assertThat(testMetrics.failures).isEqualTo(0L); + assertThat(testMetrics.getLatency()).isEqualTo(elapsed); + } + + private Injector testInjector(AbstractModule testModule) { + return Guice.createInjector(new HealthCheckModule(), testModule); + } + + @Singleton + private static class TestMetrics extends DisabledMetricMaker { + private Long failures = 0L; + private Long latency = 0L; + + public Long getFailures() { + return failures; + } + + public Long getLatency() { + return latency; + } + + public void reset() { + failures = 0L; + latency = 0L; + } + + @Override + public Counter0 newCounter(String name, Description desc) { + return new Counter0() { + @Override + public void incrementBy(long value) { + failures += value; + } + + @Override + public void remove() {} + }; + } + + @Override + public <V> CallbackMetric0<V> newCallbackMetric( + String name, Class<V> valueClass, Description desc) { + return new CallbackMetric0<V>() { + @Override + public void set(V value) { + latency = (Long) value; + } + + @Override + public void remove() {} + }; + } + } + + private static class TestHealthCheck extends AbstractHealthCheck { + + protected TestHealthCheck( + ListeningExecutorService executor, String name, StatusSummary returnStatusSummary) { + super(executor, HealthCheckConfig.DEFAULT_CONFIG, name); + this.latestStatus = returnStatusSummary; + } + + @Override + protected Result doCheck() { + return latestStatus.result; + } + + @Override + public StatusSummary run() { + return latestStatus; + } + } +}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/healthcheck/HealthCheckStatusEndpointTest.java b/src/test/java/com/googlesource/gerrit/plugins/healthcheck/HealthCheckStatusEndpointTest.java index 84ec773..78b89e4 100644 --- a/src/test/java/com/googlesource/gerrit/plugins/healthcheck/HealthCheckStatusEndpointTest.java +++ b/src/test/java/com/googlesource/gerrit/plugins/healthcheck/HealthCheckStatusEndpointTest.java
@@ -15,36 +15,48 @@ package com.googlesource.gerrit.plugins.healthcheck; import static com.google.common.truth.Truth.assertThat; +import static com.googlesource.gerrit.plugins.healthcheck.HealthCheckConfig.DEFAULT_CONFIG; +import com.google.common.util.concurrent.MoreExecutors; import com.google.gerrit.extensions.registration.DynamicSet; import com.google.gerrit.extensions.restapi.Response; +import com.google.gerrit.metrics.DisabledMetricMaker; +import com.google.gerrit.metrics.MetricMaker; import com.google.inject.AbstractModule; import com.google.inject.Guice; import com.google.inject.Injector; import com.googlesource.gerrit.plugins.healthcheck.api.HealthCheckStatusEndpoint; +import com.googlesource.gerrit.plugins.healthcheck.check.AbstractHealthCheck; import com.googlesource.gerrit.plugins.healthcheck.check.HealthCheck; +import java.util.concurrent.Executors; import javax.servlet.http.HttpServletResponse; import org.junit.Test; public class HealthCheckStatusEndpointTest { - public static class TestHealthCheck implements HealthCheck { - private final HealthCheck.Status checkResult; - private final String checkName; + public static class TestHealthCheck extends AbstractHealthCheck { + private final HealthCheck.Result checkResult; + private final long sleep; - public TestHealthCheck(String checkName, HealthCheck.Result result, long ts, long elapsed) { - this.checkName = checkName; - this.checkResult = new Status(result, ts, elapsed); + public TestHealthCheck( + HealthCheckConfig config, String checkName, HealthCheck.Result result, long sleep) { + super(MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10)), config, checkName); + this.checkResult = result; + this.sleep = sleep; } @Override - public Status run() { + public Result doCheck() { + try { + Thread.sleep(sleep); + } catch (InterruptedException e) { + } return checkResult; } @Override - public String name() { - return checkName; + public StatusSummary getLatestStatus() { + return this.latestStatus; } } @@ -56,7 +68,11 @@ @Override protected void configure() { DynamicSet.bind(binder(), HealthCheck.class) - .toInstance(new TestHealthCheck("checkOk", HealthCheck.Result.PASSED, 1, 2)); + .toInstance( + new TestHealthCheck( + DEFAULT_CONFIG, "checkOk", HealthCheck.Result.PASSED, 0)); + bind(HealthCheckConfig.class).toInstance(DEFAULT_CONFIG); + DynamicSet.bind(binder(), MetricMaker.class).toInstance(new DisabledMetricMaker()); } }); @@ -68,6 +84,29 @@ } @Test + public void shouldReturnServerErrorWhenOneChecksTimesOut() throws Exception { + Injector injector = + testInjector( + new AbstractModule() { + @Override + protected void configure() { + HealthCheckConfig config = + new HealthCheckConfig("[healthcheck]\n" + "timeout = 20"); + DynamicSet.bind(binder(), HealthCheck.class) + .toInstance( + new TestHealthCheck(config, "checkOk", HealthCheck.Result.PASSED, 30)); + bind(HealthCheckConfig.class).toInstance(config); + } + }); + + HealthCheckStatusEndpoint healthCheckApi = + injector.getInstance(HealthCheckStatusEndpoint.class); + Response<?> resp = (Response<?>) healthCheckApi.apply(null); + + assertThat(resp.statusCode()).isEqualTo(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + } + + @Test public void shouldReturnServerErrorWhenAtLeastOneCheckIsFailing() throws Exception { Injector injector = testInjector( @@ -75,9 +114,13 @@ @Override protected void configure() { DynamicSet.bind(binder(), HealthCheck.class) - .toInstance(new TestHealthCheck("checkOk", HealthCheck.Result.PASSED, 1, 2)); + .toInstance( + new TestHealthCheck( + DEFAULT_CONFIG, "checkOk", HealthCheck.Result.PASSED, 0)); DynamicSet.bind(binder(), HealthCheck.class) - .toInstance(new TestHealthCheck("checkKo", HealthCheck.Result.FAILED, 1, 2)); + .toInstance( + new TestHealthCheck( + DEFAULT_CONFIG, "checkKo", HealthCheck.Result.FAILED, 0)); } });
diff --git a/src/test/java/com/googlesource/gerrit/plugins/healthcheck/JGitHealthCheckTest.java b/src/test/java/com/googlesource/gerrit/plugins/healthcheck/JGitHealthCheckTest.java index 1991871..50a748f 100644 --- a/src/test/java/com/googlesource/gerrit/plugins/healthcheck/JGitHealthCheckTest.java +++ b/src/test/java/com/googlesource/gerrit/plugins/healthcheck/JGitHealthCheckTest.java
@@ -15,6 +15,7 @@ package com.googlesource.gerrit.plugins.healthcheck; import static com.google.common.truth.Truth.assertThat; +import static com.googlesource.gerrit.plugins.healthcheck.HealthCheckConfig.DEFAULT_CONFIG; import static org.eclipse.jgit.lib.RefUpdate.Result.NEW; import com.google.common.util.concurrent.ListeningExecutorService; @@ -60,14 +61,16 @@ @Test public void shouldBeHealthyWhenJGitIsWorking() { JGitHealthCheck reviewDbCheck = - new JGitHealthCheck(executor, getWorkingRepositoryManager(), allProjectsName); + new JGitHealthCheck( + executor, DEFAULT_CONFIG, getWorkingRepositoryManager(), allProjectsName); assertThat(reviewDbCheck.run().result).isEqualTo(Result.PASSED); } @Test public void shouldBeUnhealthyWhenJGitIsFailing() { JGitHealthCheck jGitHealthCheck = - new JGitHealthCheck(executor, getFailingGitRepositoryManager(), allProjectsName); + new JGitHealthCheck( + executor, DEFAULT_CONFIG, getFailingGitRepositoryManager(), allProjectsName); assertThat(jGitHealthCheck.run().result).isEqualTo(Result.FAILED); }
diff --git a/src/test/java/com/googlesource/gerrit/plugins/healthcheck/ProjectsListHealthCheckTest.java b/src/test/java/com/googlesource/gerrit/plugins/healthcheck/ProjectsListHealthCheckTest.java index 93d1350..eefce0a 100644 --- a/src/test/java/com/googlesource/gerrit/plugins/healthcheck/ProjectsListHealthCheckTest.java +++ b/src/test/java/com/googlesource/gerrit/plugins/healthcheck/ProjectsListHealthCheckTest.java
@@ -15,6 +15,7 @@ package com.googlesource.gerrit.plugins.healthcheck; import static com.google.common.truth.Truth.assertThat; +import static com.googlesource.gerrit.plugins.healthcheck.HealthCheckConfig.DEFAULT_CONFIG; import com.google.common.util.concurrent.ListeningExecutorService; import com.google.gerrit.extensions.common.ProjectInfo; @@ -22,7 +23,6 @@ import com.google.gerrit.server.restapi.project.ListProjects; import com.google.inject.Guice; import com.google.inject.Inject; -import com.googlesource.gerrit.plugins.healthcheck.check.AbstractHealthCheck; import com.googlesource.gerrit.plugins.healthcheck.check.HealthCheck.Result; import com.googlesource.gerrit.plugins.healthcheck.check.ProjectsListHealthCheck; import java.util.SortedMap; @@ -34,21 +34,21 @@ @Inject private ListeningExecutorService executor; @Before - public void setUp() { + public void setUp() throws Exception { Guice.createInjector(new HealthCheckModule()).injectMembers(this); } @Test public void shouldBeHealthyWhenListProjectsWorks() { ProjectsListHealthCheck jGitHealthCheck = - new ProjectsListHealthCheck(executor, getWorkingProjectList(0)); + new ProjectsListHealthCheck(executor, DEFAULT_CONFIG, getWorkingProjectList(0)); assertThat(jGitHealthCheck.run().result).isEqualTo(Result.PASSED); } @Test public void shouldBeUnhealthyWhenListProjectsIsFailing() { ProjectsListHealthCheck jGitHealthCheck = - new ProjectsListHealthCheck(executor, getFailingProjectList()); + new ProjectsListHealthCheck(executor, DEFAULT_CONFIG, getFailingProjectList()); assertThat(jGitHealthCheck.run().result).isEqualTo(Result.FAILED); } @@ -56,7 +56,7 @@ public void shouldBeUnhealthyWhenListProjectsIsTimingOut() { ProjectsListHealthCheck jGitHealthCheck = new ProjectsListHealthCheck( - executor, getWorkingProjectList(AbstractHealthCheck.CHECK_TIMEOUT * 2)); + executor, DEFAULT_CONFIG, getWorkingProjectList(DEFAULT_CONFIG.getTimeout() * 2)); assertThat(jGitHealthCheck.run().result).isEqualTo(Result.TIMEOUT); }