Implement JGit health-check
Check that JGit is able to open and read objects
from All-Projects repository.
Change-Id: Ibc7dc325b2f3529636b6ed8297bf3ca13269b444
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 9e6ebc5..55bf18b 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/healthcheck/HealthCheckSubsystemsModule.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/healthcheck/HealthCheckSubsystemsModule.java
@@ -17,12 +17,18 @@
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.ReviewDbHealthCheck;
public class HealthCheckSubsystemsModule extends AbstractModule {
@Override
protected void configure() {
- DynamicSet.bind(binder(), HealthCheck.class).to(ReviewDbHealthCheck.class);
+ bindChecker(ReviewDbHealthCheck.class);
+ bindChecker(JGitHealthCheck.class);
+ }
+
+ private void bindChecker(Class<? extends HealthCheck> healthCheckClass) {
+ DynamicSet.bind(binder(), HealthCheck.class).to(healthCheckClass);
}
}
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
new file mode 100644
index 0000000..f186092
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/AbstractHealthCheck.java
@@ -0,0 +1,47 @@
+// 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 org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class AbstractHealthCheck implements HealthCheck {
+ private static final Logger log = LoggerFactory.getLogger(AbstractHealthCheck.class);
+ private final String name;
+
+ protected AbstractHealthCheck(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String name() {
+ return name;
+ }
+
+ @Override
+ public Status run() {
+ Result healthy;
+ long ts = System.currentTimeMillis();
+ try {
+ healthy = doCheck();
+ } catch (Exception e) {
+ log.warn("Check {} failed", name, e);
+ healthy = Result.FAILED;
+ }
+ return new Status(healthy, ts, System.currentTimeMillis() - ts);
+ }
+
+ protected abstract Result doCheck() throws Exception;
+}
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 e33b755..1c88f0e 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 REVIEWDB = "reviewdb";
+ String JGIT = "jgit";
}
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
new file mode 100644
index 0000000..be0a373
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/JGitHealthCheck.java
@@ -0,0 +1,44 @@
+// 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.JGIT;
+
+import com.google.gerrit.server.config.AllProjectsName;
+import com.google.gerrit.server.git.GitRepositoryManager;
+import com.google.inject.Inject;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.Repository;
+
+public class JGitHealthCheck extends AbstractHealthCheck {
+ private final GitRepositoryManager repositoryManager;
+ private final AllProjectsName allProjectsName;
+
+ @Inject
+ public JGitHealthCheck(GitRepositoryManager repositoryManager, AllProjectsName allProjectsName) {
+ super(JGIT);
+ this.repositoryManager = repositoryManager;
+ this.allProjectsName = allProjectsName;
+ }
+
+ @Override
+ protected Result doCheck() throws Exception {
+ try (Repository allProjects = repositoryManager.openRepository(allProjectsName)) {
+ ObjectId headObj = allProjects.resolve("refs/meta/config");
+ allProjects.open(headObj).getType();
+ return Result.PASSED;
+ }
+ }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/ReviewDbHealthCheck.java b/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/ReviewDbHealthCheck.java
index ff9b74b..10aad07 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/ReviewDbHealthCheck.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/ReviewDbHealthCheck.java
@@ -23,38 +23,22 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class ReviewDbHealthCheck implements HealthCheck {
+public class ReviewDbHealthCheck extends AbstractHealthCheck {
private static final Logger log = LoggerFactory.getLogger(ReviewDbHealthCheck.class);
private final Provider<ReviewDb> reviewDb;
@Inject
public ReviewDbHealthCheck(Provider<ReviewDb> reviewDb) {
+ super(REVIEWDB);
this.reviewDb = reviewDb;
}
@Override
- public HealthCheck.Status run() {
- HealthCheck.Result healthy;
- long ts = System.currentTimeMillis();
- try {
- healthy = doCheck();
- } catch (Exception e) {
- log.warn("Check reviewdb has failed", e);
- healthy = HealthCheck.Result.FAILED;
- }
- return new HealthCheck.Status(healthy, ts, System.currentTimeMillis() - ts);
- }
-
- @Override
- public String name() {
- return REVIEWDB;
- }
-
- private HealthCheck.Result doCheck() throws Exception {
+ protected Result doCheck() throws Exception {
try (ReviewDb db = reviewDb.get()) {
db.schemaVersion().get(new CurrentSchemaVersion.Key());
- return HealthCheck.Result.PASSED;
+ return Result.PASSED;
}
}
}
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 4471372..f5c6036 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/healthcheck/HealthCheckIT.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/healthcheck/HealthCheckIT.java
@@ -16,17 +16,16 @@
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.REVIEWDB;
-import java.io.IOException;
-
-import org.junit.Test;
-
import com.google.gerrit.acceptance.LightweightPluginDaemonTest;
import com.google.gerrit.acceptance.RestResponse;
import com.google.gerrit.acceptance.TestPlugin;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
+import java.io.IOException;
+import org.junit.Test;
@TestPlugin(name = "healthcheck", sysModule = "com.googlesource.gerrit.plugins.healthcheck.Module")
public class HealthCheckIT extends LightweightPluginDaemonTest {
@@ -48,14 +47,28 @@
resp.assertOK();
JsonObject respPayload = gson.fromJson(resp.getReader(), JsonObject.class);
- assertThat(respPayload.has(REVIEWDB)).isTrue();
- JsonObject reviewDbStatus = respPayload.get(REVIEWDB).getAsJsonObject();
- assertThat(reviewDbStatus.has("result")).isTrue();
- assertThat(reviewDbStatus.get("result").getAsString()).isEqualTo("passed");
+ assertCheckResult(respPayload, REVIEWDB, "passed");
+ }
+
+ @Test
+ public void shouldReturnJGitCheck() throws Exception {
+ RestResponse resp = getHealthCheckStatus();
+ resp.assertOK();
+
+ JsonObject respPayload = gson.fromJson(resp.getReader(), JsonObject.class);
+
+ assertCheckResult(respPayload, JGIT, "passed");
}
private RestResponse getHealthCheckStatus() throws IOException {
return adminRestSession.get("/config/server/healthcheck~status");
}
+
+ private void assertCheckResult(JsonObject respPayload, String checkName, String result) {
+ assertThat(respPayload.has(checkName)).isTrue();
+ JsonObject reviewDbStatus = respPayload.get(checkName).getAsJsonObject();
+ assertThat(reviewDbStatus.has("result")).isTrue();
+ assertThat(reviewDbStatus.get("result").getAsString()).isEqualTo(result);
+ }
}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/healthcheck/JGitHealthCheckTest.java b/src/test/java/com/googlesource/gerrit/plugins/healthcheck/JGitHealthCheckTest.java
new file mode 100644
index 0000000..677d22a
--- /dev/null
+++ b/src/test/java/com/googlesource/gerrit/plugins/healthcheck/JGitHealthCheckTest.java
@@ -0,0 +1,107 @@
+// 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 org.eclipse.jgit.lib.RefUpdate.Result.NEW;
+
+import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.server.config.AllProjectsName;
+import com.google.gerrit.server.git.GitRepositoryManager;
+import com.google.gerrit.server.git.RepositoryCaseMismatchException;
+import com.google.gerrit.testutil.InMemoryRepositoryManager;
+import com.googlesource.gerrit.plugins.healthcheck.check.HealthCheck.Result;
+import com.googlesource.gerrit.plugins.healthcheck.check.JGitHealthCheck;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.SortedSet;
+import org.eclipse.jgit.errors.RepositoryNotFoundException;
+import org.eclipse.jgit.lib.CommitBuilder;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.ObjectInserter;
+import org.eclipse.jgit.lib.PersonIdent;
+import org.eclipse.jgit.lib.RefUpdate;
+import org.eclipse.jgit.lib.Repository;
+import org.junit.Before;
+import org.junit.Test;
+
+public class JGitHealthCheckTest {
+ private AllProjectsName allProjectsName = new AllProjectsName("All-Projects");
+ private InMemoryRepositoryManager inMemoryRepositoryManager = new InMemoryRepositoryManager();
+ PersonIdent personIdent = new PersonIdent("Gerrit Rietveld", "gerrit@rietveld.nl");
+
+ @Before
+ public void setupAllProjects() throws Exception {
+ InMemoryRepositoryManager.Repo repo =
+ inMemoryRepositoryManager.createRepository(allProjectsName);
+ createCommit(repo, "refs/meta/config");
+ }
+
+ @Test
+ public void shouldBeHealthyWhenJGitIsWorking() {
+ JGitHealthCheck reviewDbCheck =
+ new JGitHealthCheck(getWorkingRepositoryManager(), allProjectsName);
+ assertThat(reviewDbCheck.run().result).isEqualTo(Result.PASSED);
+ }
+
+ @Test
+ public void shouldBeUnhealthyWhenJGitIsFailing() {
+ JGitHealthCheck jGitHealthCheck =
+ new JGitHealthCheck(getFailingGitRepositoryManager(), allProjectsName);
+ assertThat(jGitHealthCheck.run().result).isEqualTo(Result.FAILED);
+ }
+
+ private GitRepositoryManager getFailingGitRepositoryManager() {
+ return new GitRepositoryManager() {
+
+ @Override
+ public Repository openRepository(Project.NameKey name)
+ throws RepositoryNotFoundException, IOException {
+ throw new RepositoryNotFoundException("Can't fine repository " + name);
+ }
+
+ @Override
+ public Repository createRepository(Project.NameKey name)
+ throws RepositoryCaseMismatchException, RepositoryNotFoundException, IOException {
+ throw new IOException("Can't create repositories");
+ }
+
+ @Override
+ public SortedSet<Project.NameKey> list() {
+ return Collections.emptySortedSet();
+ }
+ };
+ }
+
+ private GitRepositoryManager getWorkingRepositoryManager() {
+ return inMemoryRepositoryManager;
+ }
+
+ private void createCommit(InMemoryRepositoryManager.Repo repo, String ref) throws IOException {
+ try (ObjectInserter oi = repo.newObjectInserter()) {
+ CommitBuilder cb = new CommitBuilder();
+ cb.setTreeId(oi.insert(Constants.OBJ_TREE, new byte[] {}));
+ cb.setAuthor(personIdent);
+ cb.setCommitter(personIdent);
+ cb.setMessage("Test commit\n");
+ ObjectId id = oi.insert(cb);
+ oi.flush();
+ RefUpdate ru = repo.updateRef(ref);
+ ru.setNewObjectId(id);
+ assertThat(ru.update()).isEqualTo(NEW);
+ }
+ }
+}