Merge "Add checker description and checker message to the checks table"
diff --git a/java/com/google/gerrit/plugins/checks/api/ApiModule.java b/java/com/google/gerrit/plugins/checks/api/ApiModule.java
index ad1e7e3..88fb5cf 100644
--- a/java/com/google/gerrit/plugins/checks/api/ApiModule.java
+++ b/java/com/google/gerrit/plugins/checks/api/ApiModule.java
@@ -50,7 +50,7 @@
postOnCollection(CHECK_KIND).to(PostCheck.class);
get(CHECK_KIND).to(GetCheck.class);
post(CHECK_KIND).to(UpdateCheck.class);
-
+ post(CHECK_KIND, "rerun").to(RerunCheck.class);
DynamicMap.mapOf(binder(), PENDING_CHECK_KIND);
}
});
diff --git a/java/com/google/gerrit/plugins/checks/api/CheckApi.java b/java/com/google/gerrit/plugins/checks/api/CheckApi.java
index d137645..14acb41 100644
--- a/java/com/google/gerrit/plugins/checks/api/CheckApi.java
+++ b/java/com/google/gerrit/plugins/checks/api/CheckApi.java
@@ -26,6 +26,8 @@
/** Updates a check and returns the {@link CheckInfo} for the updated resource. */
CheckInfo update(CheckInput input) throws RestApiException;
+ /** Reruns the check and returns the {@link CheckInfo} for the updated check. */
+ CheckInfo rerun() throws RestApiException;
/**
* A default implementation which allows source compatibility when adding new methods to the
* interface.
@@ -40,5 +42,10 @@
public CheckInfo update(CheckInput input) throws RestApiException {
throw new NotImplementedException();
}
+
+ @Override
+ public CheckInfo rerun() throws RestApiException {
+ throw new NotImplementedException();
+ }
}
}
diff --git a/java/com/google/gerrit/plugins/checks/api/CheckApiImpl.java b/java/com/google/gerrit/plugins/checks/api/CheckApiImpl.java
index 5cd20f6..3be0a74 100644
--- a/java/com/google/gerrit/plugins/checks/api/CheckApiImpl.java
+++ b/java/com/google/gerrit/plugins/checks/api/CheckApiImpl.java
@@ -30,12 +30,18 @@
private final GetCheck getCheck;
private final UpdateCheck updateCheck;
private final CheckResource checkResource;
+ private final RerunCheck rerunCheck;
@Inject
- CheckApiImpl(GetCheck getCheck, UpdateCheck updateCheck, @Assisted CheckResource checkResource) {
+ CheckApiImpl(
+ GetCheck getCheck,
+ UpdateCheck updateCheck,
+ @Assisted CheckResource checkResource,
+ RerunCheck rerunCheck) {
this.getCheck = getCheck;
this.updateCheck = updateCheck;
this.checkResource = checkResource;
+ this.rerunCheck = rerunCheck;
}
@Override
@@ -56,4 +62,13 @@
throw asRestApiException("Cannot update check", e);
}
}
+
+ @Override
+ public CheckInfo rerun() throws RestApiException {
+ try {
+ return rerunCheck.apply(checkResource, null).value();
+ } catch (Exception e) {
+ throw asRestApiException("Cannot rerun check", e);
+ }
+ }
}
diff --git a/java/com/google/gerrit/plugins/checks/api/RerunCheck.java b/java/com/google/gerrit/plugins/checks/api/RerunCheck.java
new file mode 100644
index 0000000..4c6b0a4
--- /dev/null
+++ b/java/com/google/gerrit/plugins/checks/api/RerunCheck.java
@@ -0,0 +1,119 @@
+// 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.google.gerrit.plugins.checks.api;
+
+import com.google.gerrit.extensions.common.Input;
+import com.google.gerrit.extensions.restapi.AuthException;
+import com.google.gerrit.extensions.restapi.ResourceConflictException;
+import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
+import com.google.gerrit.extensions.restapi.Response;
+import com.google.gerrit.extensions.restapi.RestApiException;
+import com.google.gerrit.extensions.restapi.RestModifyView;
+import com.google.gerrit.plugins.checks.AdministrateCheckersPermission;
+import com.google.gerrit.plugins.checks.Check;
+import com.google.gerrit.plugins.checks.CheckJson;
+import com.google.gerrit.plugins.checks.CheckKey;
+import com.google.gerrit.plugins.checks.CheckUpdate;
+import com.google.gerrit.plugins.checks.Checker;
+import com.google.gerrit.plugins.checks.CheckerUuid;
+import com.google.gerrit.plugins.checks.Checkers;
+import com.google.gerrit.plugins.checks.Checks;
+import com.google.gerrit.plugins.checks.Checks.GetCheckOptions;
+import com.google.gerrit.plugins.checks.ChecksUpdate;
+import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.UserInitiated;
+import com.google.gerrit.server.permissions.PermissionBackend;
+import com.google.gerrit.server.permissions.PermissionBackendException;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import java.io.IOException;
+import java.util.Optional;
+import javax.inject.Provider;
+import org.eclipse.jgit.errors.ConfigInvalidException;
+
+@Singleton
+public class RerunCheck implements RestModifyView<CheckResource, Input> {
+ private final Provider<CurrentUser> self;
+ private final PermissionBackend permissionBackend;
+ private final AdministrateCheckersPermission permission;
+ private final Checks checks;
+ private final Provider<ChecksUpdate> checksUpdate;
+ private final CheckJson.Factory checkJsonFactory;
+ private final Checkers checkers;
+
+ @Inject
+ RerunCheck(
+ Provider<CurrentUser> self,
+ PermissionBackend permissionBackend,
+ AdministrateCheckersPermission permission,
+ Checks checks,
+ @UserInitiated Provider<ChecksUpdate> checksUpdate,
+ CheckJson.Factory checkJsonFactory,
+ Checkers checkers) {
+ this.self = self;
+ this.permissionBackend = permissionBackend;
+ this.permission = permission;
+ this.checks = checks;
+ this.checksUpdate = checksUpdate;
+ this.checkJsonFactory = checkJsonFactory;
+ this.checkers = checkers;
+ }
+
+ @Override
+ public Response<CheckInfo> apply(CheckResource checkResource, Input input)
+ throws RestApiException, IOException, PermissionBackendException, ConfigInvalidException {
+ if (!self.get().isIdentifiedUser()) {
+ throw new AuthException("Authentication required");
+ }
+ permissionBackend.currentUser().check(permission);
+ if (checkResource.getRevisionResource().getEdit().isPresent()) {
+ throw new ResourceConflictException("checks are not supported on a change edit");
+ }
+ CheckKey key =
+ CheckKey.create(
+ checkResource.getRevisionResource().getProject(),
+ checkResource.getRevisionResource().getPatchSet().id(),
+ checkResource.getCheckerUuid());
+ Optional<Check> check = checks.getCheck(key, GetCheckOptions.defaults());
+ CheckerUuid checkerUuid = checkResource.getCheckerUuid();
+ Check updatedCheck;
+ if (!check.isPresent()) {
+ Checker checker =
+ checkers
+ .getChecker(checkerUuid)
+ .orElseThrow(
+ () ->
+ new ResourceNotFoundException(
+ String.format("checker %s not found", checkerUuid)));
+ // This error should not be thrown since this case is filtered before reaching this code.
+ // Also return a backfilled check for checkers that do not apply to the change.
+ updatedCheck =
+ Check.newBackfilledCheck(
+ checkResource.getRevisionResource().getProject(),
+ checkResource.getRevisionResource().getPatchSet(),
+ checker);
+ } else {
+ CheckUpdate.Builder builder = CheckUpdate.builder();
+ builder
+ .setState(CheckState.NOT_STARTED)
+ .unsetFinished()
+ .unsetStarted()
+ .setMessage("")
+ .setUrl("");
+ updatedCheck = checksUpdate.get().updateCheck(key, builder.build());
+ }
+ return Response.ok(checkJsonFactory.noOptions().format(updatedCheck));
+ }
+}
diff --git a/java/com/google/gerrit/plugins/checks/rules/ChecksSubmitRule.java b/java/com/google/gerrit/plugins/checks/rules/ChecksSubmitRule.java
index 4850ef4..a1df4f5 100644
--- a/java/com/google/gerrit/plugins/checks/rules/ChecksSubmitRule.java
+++ b/java/com/google/gerrit/plugins/checks/rules/ChecksSubmitRule.java
@@ -15,7 +15,6 @@
package com.google.gerrit.plugins.checks.rules;
import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.common.data.SubmitRecord;
import com.google.gerrit.common.data.SubmitRecord.Status;
@@ -31,7 +30,7 @@
import com.google.inject.Inject;
import com.google.inject.Singleton;
import java.io.IOException;
-import java.util.Collection;
+import java.util.Optional;
@Singleton
public class ChecksSubmitRule implements SubmitRule {
@@ -60,7 +59,7 @@
}
@Override
- public Collection<SubmitRecord> evaluate(ChangeData changeData) {
+ public Optional<SubmitRecord> evaluate(ChangeData changeData) {
Project.NameKey project = changeData.project();
Change.Id changeId = changeData.getId();
@@ -71,7 +70,7 @@
String errorMessage =
String.format("failed to load the current patch set of change %s", changeId);
logger.atSevere().withCause(e).log(errorMessage);
- return singletonRecordForRuleError(errorMessage);
+ return recordForRuleError(errorMessage);
}
boolean areAllRequiredCheckersPassing;
@@ -82,24 +81,24 @@
String errorMessage =
String.format("failed to evaluate check states for change %s", changeId);
logger.atSevere().withCause(e).log(errorMessage);
- return singletonRecordForRuleError(errorMessage);
+ return recordForRuleError(errorMessage);
}
SubmitRecord submitRecord = new SubmitRecord();
if (areAllRequiredCheckersPassing) {
submitRecord.status = Status.OK;
- return ImmutableList.of(submitRecord);
+ return Optional.of(submitRecord);
}
submitRecord.status = Status.NOT_READY;
submitRecord.requirements = ImmutableList.of(DEFAULT_SUBMIT_REQUIREMENT_FOR_CHECKS);
- return ImmutableSet.of(submitRecord);
+ return Optional.of(submitRecord);
}
- private static Collection<SubmitRecord> singletonRecordForRuleError(String reason) {
+ private static Optional<SubmitRecord> recordForRuleError(String reason) {
SubmitRecord submitRecord = new SubmitRecord();
submitRecord.errorMessage = reason;
submitRecord.status = SubmitRecord.Status.RULE_ERROR;
- return ImmutableList.of(submitRecord);
+ return Optional.of(submitRecord);
}
}
diff --git a/javatests/com/google/gerrit/plugins/checks/acceptance/ChecksRestApiBindingsIT.java b/javatests/com/google/gerrit/plugins/checks/acceptance/ChecksRestApiBindingsIT.java
index 557aab0..03a9e7d 100644
--- a/javatests/com/google/gerrit/plugins/checks/acceptance/ChecksRestApiBindingsIT.java
+++ b/javatests/com/google/gerrit/plugins/checks/acceptance/ChecksRestApiBindingsIT.java
@@ -47,7 +47,8 @@
private static final ImmutableList<RestCall> SCOPED_CHECK_ENDPOINTS =
ImmutableList.of(
RestCall.get("/changes/%s/revisions/%s/checks~checks/%s"),
- RestCall.post("/changes/%s/revisions/%s/checks~checks/%s"));
+ RestCall.post("/changes/%s/revisions/%s/checks~checks/%s"),
+ RestCall.post("/changes/%s/revisions/%s/checks~checks/%s/rerun"));
@Test
public void rootEndpoints() throws Exception {
diff --git a/javatests/com/google/gerrit/plugins/checks/acceptance/api/RerunCheckIT.java b/javatests/com/google/gerrit/plugins/checks/acceptance/api/RerunCheckIT.java
new file mode 100644
index 0000000..9cc539f
--- /dev/null
+++ b/javatests/com/google/gerrit/plugins/checks/acceptance/api/RerunCheckIT.java
@@ -0,0 +1,150 @@
+// 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.google.gerrit.plugins.checks.acceptance.api;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
+
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
+import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
+import com.google.gerrit.extensions.restapi.AuthException;
+import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
+import com.google.gerrit.plugins.checks.CheckKey;
+import com.google.gerrit.plugins.checks.CheckerUuid;
+import com.google.gerrit.plugins.checks.acceptance.AbstractCheckersTest;
+import com.google.gerrit.plugins.checks.api.CheckInfo;
+import com.google.gerrit.plugins.checks.api.CheckState;
+import com.google.gerrit.reviewdb.client.PatchSet;
+import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.server.util.time.TimeUtil;
+import com.google.gerrit.testing.TestTimeUtil;
+import com.google.inject.Inject;
+import java.sql.Timestamp;
+import java.time.Instant;
+import java.util.concurrent.TimeUnit;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class RerunCheckIT extends AbstractCheckersTest {
+ @Inject private RequestScopeOperations requestScopeOperations;
+ @Inject private ProjectOperations projectOperations;
+
+ private PatchSet.Id patchSetId;
+ private CheckKey checkKey;
+
+ @Before
+ public void setUp() throws Exception {
+ TestTimeUtil.resetWithClockStep(1, TimeUnit.SECONDS);
+ TestTimeUtil.setClock(Timestamp.from(Instant.EPOCH));
+
+ patchSetId = createChange().getPatchSetId();
+
+ CheckerUuid checkerUuid = checkerOperations.newChecker().repository(project).create();
+ checkKey = CheckKey.create(project, patchSetId, checkerUuid);
+ }
+
+ @After
+ public void resetTime() {
+ TestTimeUtil.useSystemTime();
+ }
+
+ @Test
+ public void rerunResetsCheckInfo() throws Exception {
+ checkOperations
+ .newCheck(checkKey)
+ .state(CheckState.FAILED)
+ .started(TimeUtil.nowTs())
+ .finished(TimeUtil.nowTs())
+ .message("message")
+ .url("url.com")
+ .upsert();
+ Timestamp created = checkOperations.check(checkKey).get().created();
+ Timestamp updated = checkOperations.check(checkKey).get().updated();
+ CheckInfo info = checksApiFactory.revision(patchSetId).id(checkKey.checkerUuid()).rerun();
+ assertThat(info.state).isEqualTo(CheckState.NOT_STARTED);
+ assertThat(info.message).isEqualTo(null);
+ assertThat(info.url).isEqualTo(null);
+ assertThat(info.started).isEqualTo(null);
+ assertThat(info.finished).isEqualTo(null);
+ assertThat(info.created).isEqualTo(created);
+ assertThat(info.updated).isGreaterThan(updated);
+ }
+
+ @Test
+ public void rerunNotStartedCheck() throws Exception {
+ checkOperations.newCheck(checkKey).state(CheckState.NOT_STARTED).upsert();
+ CheckInfo info = checksApiFactory.revision(patchSetId).id(checkKey.checkerUuid()).rerun();
+ assertThat(info.state).isEqualTo(CheckState.NOT_STARTED);
+ }
+
+ @Test
+ public void rerunFinishedCheck() throws Exception {
+ checkOperations.newCheck(checkKey).state(CheckState.SUCCESSFUL).upsert();
+ CheckInfo info = checksApiFactory.revision(patchSetId).id(checkKey.checkerUuid()).rerun();
+ assertThat(info.state).isEqualTo(CheckState.NOT_STARTED);
+ assertThat(info.updated).isGreaterThan(info.created);
+ }
+
+ @Test
+ public void rerunCheckNotExistingButBackfilled() throws Exception {
+ CheckInfo info = checksApiFactory.revision(patchSetId).id(checkKey.checkerUuid()).rerun();
+ assertThat(info.state).isEqualTo(CheckState.NOT_STARTED);
+ assertThat(checkOperations.check(checkKey).exists()).isFalse();
+ }
+
+ @Test
+ public void rerunExistingCheckWithCheckerNotAppliedToChange() throws Exception {
+ Project.NameKey otherProject = projectOperations.newProject().create();
+ checkerOperations.checker(checkKey.checkerUuid()).forUpdate().repository(otherProject).update();
+ checkOperations.newCheck(checkKey).upsert();
+ CheckInfo info = checksApiFactory.revision(patchSetId).id(checkKey.checkerUuid()).rerun();
+ assertThat(info.state).isEqualTo(CheckState.NOT_STARTED);
+ }
+
+ @Test
+ public void rerunNonExistingCheckWithCheckerNotAppliedToChange() throws Exception {
+ Project.NameKey otherProject = projectOperations.newProject().create();
+ checkerOperations.checker(checkKey.checkerUuid()).forUpdate().repository(otherProject).update();
+ assertThrows(
+ ResourceNotFoundException.class,
+ () -> checksApiFactory.revision(patchSetId).id(checkKey.checkerUuid()).rerun());
+ assertThat(checkOperations.check(checkKey).exists()).isFalse();
+ }
+
+ @Test
+ public void cannotUpdateCheckWithoutAdministrateCheckers() throws Exception {
+ requestScopeOperations.setApiUser(user.id());
+ checkOperations.newCheck(checkKey).state(CheckState.SUCCESSFUL).upsert();
+
+ AuthException thrown =
+ assertThrows(
+ AuthException.class,
+ () -> checksApiFactory.revision(patchSetId).id(checkKey.checkerUuid()).rerun());
+ assertThat(thrown).hasMessageThat().contains("not permitted");
+ }
+
+ @Test
+ public void cannotUpdateCheckAnonymously() throws Exception {
+ requestScopeOperations.setApiUserAnonymous();
+ checkOperations.newCheck(checkKey).state(CheckState.SUCCESSFUL).upsert();
+
+ AuthException thrown =
+ assertThrows(
+ AuthException.class,
+ () -> checksApiFactory.revision(patchSetId).id(checkKey.checkerUuid()).rerun());
+ assertThat(thrown).hasMessageThat().contains("Authentication required");
+ }
+}
diff --git a/javatests/com/google/gerrit/plugins/checks/acceptance/api/UpdateCheckIT.java b/javatests/com/google/gerrit/plugins/checks/acceptance/api/UpdateCheckIT.java
index c6aa0c1..7cc2ce8 100644
--- a/javatests/com/google/gerrit/plugins/checks/acceptance/api/UpdateCheckIT.java
+++ b/javatests/com/google/gerrit/plugins/checks/acceptance/api/UpdateCheckIT.java
@@ -17,9 +17,11 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.testing.GerritJUnit.assertThrows;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.BadRequestException;
+import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.gerrit.plugins.checks.CheckKey;
import com.google.gerrit.plugins.checks.CheckerUuid;
import com.google.gerrit.plugins.checks.acceptance.AbstractCheckersTest;
@@ -42,6 +44,7 @@
public class UpdateCheckIT extends AbstractCheckersTest {
@Inject private RequestScopeOperations requestScopeOperations;
+ @Inject private ProjectOperations projectOperations;
private PatchSet.Id patchSetId;
private CheckKey checkKey;
@@ -227,8 +230,9 @@
}
@Test
- public void canUpdateCheckForCheckerThatDoesNotApplyToTheProject() throws Exception {
- Project.NameKey otherProject = createProjectOverAPI("other", null, true, null);
+ public void canUpdateCheckForCheckerThatDoesNotApplyToTheProjectAndCheckExists()
+ throws Exception {
+ Project.NameKey otherProject = projectOperations.newProject().create();
checkerOperations.checker(checkKey.checkerUuid()).forUpdate().repository(otherProject).update();
CheckInput input = new CheckInput();
@@ -239,6 +243,22 @@
}
@Test
+ public void
+ throwExceptionForUpdateCheckForCheckerThatDoesNotApplyToTheProjectAndCheckDoesNotExist()
+ throws Exception {
+ Project.NameKey otherProject = projectOperations.newProject().create();
+ CheckerUuid checkerUuid = checkerOperations.newChecker().repository(otherProject).create();
+ CheckKey checkKey = CheckKey.create(otherProject, patchSetId, checkerUuid);
+ assertThrows(
+ ResourceNotFoundException.class,
+ () ->
+ checksApiFactory
+ .revision(patchSetId)
+ .id(checkKey.checkerUuid())
+ .update(new CheckInput()));
+ }
+
+ @Test
public void canUpdateCheckForCheckerWithUnsupportedOperatorInQuery() throws Exception {
checkerOperations
.checker(checkKey.checkerUuid())
diff --git a/javatests/com/google/gerrit/plugins/checks/rules/BUILD b/javatests/com/google/gerrit/plugins/checks/rules/BUILD
index 17fdb2a..2e76709 100644
--- a/javatests/com/google/gerrit/plugins/checks/rules/BUILD
+++ b/javatests/com/google/gerrit/plugins/checks/rules/BUILD
@@ -14,6 +14,7 @@
"//lib:guava",
"//lib/jgit/org.eclipse.jgit:jgit",
"//lib/truth",
+ "//lib/truth:truth-java8-extension",
"//plugins/checks:checks__plugin",
],
)
diff --git a/javatests/com/google/gerrit/plugins/checks/rules/ChecksSubmitRuleTest.java b/javatests/com/google/gerrit/plugins/checks/rules/ChecksSubmitRuleTest.java
index cdb533d..2d75e6b 100644
--- a/javatests/com/google/gerrit/plugins/checks/rules/ChecksSubmitRuleTest.java
+++ b/javatests/com/google/gerrit/plugins/checks/rules/ChecksSubmitRuleTest.java
@@ -15,11 +15,11 @@
package com.google.gerrit.plugins.checks.rules;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth8.assertThat;
import static org.easymock.EasyMock.anyObject;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
-import com.google.common.collect.Iterables;
import com.google.gerrit.common.data.SubmitRecord;
import com.google.gerrit.plugins.checks.Checks;
import com.google.gerrit.reviewdb.client.Account;
@@ -29,7 +29,7 @@
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.util.time.TimeUtil;
import java.io.IOException;
-import java.util.Collection;
+import java.util.Optional;
import org.easymock.EasyMock;
import org.eclipse.jgit.lib.ObjectId;
import org.junit.Test;
@@ -46,7 +46,7 @@
expect(cd.currentPatchSet()).andThrow(new IllegalStateException("Fail for test"));
replay(cd);
- Collection<SubmitRecord> submitRecords = checksSubmitRule.evaluate(cd);
+ Optional<SubmitRecord> submitRecords = checksSubmitRule.evaluate(cd);
assertErrorRecord(submitRecords, "failed to load the current patch set of change 1");
}
@@ -73,16 +73,15 @@
.build());
replay(cd);
- Collection<SubmitRecord> submitRecords = checksSubmitRule.evaluate(cd);
+ Optional<SubmitRecord> submitRecords = checksSubmitRule.evaluate(cd);
assertErrorRecord(submitRecords, "failed to evaluate check states for change 1");
}
private static void assertErrorRecord(
- Collection<SubmitRecord> submitRecords, String expectedErrorMessage) {
- assertThat(submitRecords).hasSize(1);
+ Optional<SubmitRecord> submitRecord, String expectedErrorMessage) {
+ assertThat(submitRecord).isPresent();
- SubmitRecord submitRecord = Iterables.getOnlyElement(submitRecords);
- assertThat(submitRecord.status).isEqualTo(SubmitRecord.Status.RULE_ERROR);
- assertThat(submitRecord.errorMessage).isEqualTo(expectedErrorMessage);
+ assertThat(submitRecord.get().status).isEqualTo(SubmitRecord.Status.RULE_ERROR);
+ assertThat(submitRecord.get().errorMessage).isEqualTo(expectedErrorMessage);
}
}
diff --git a/resources/Documentation/rest-api-checks.md b/resources/Documentation/rest-api-checks.md
index 4bcd1a1..4395644 100644
--- a/resources/Documentation/rest-api-checks.md
+++ b/resources/Documentation/rest-api-checks.md
@@ -1,4 +1,4 @@
-# /changes/<id>/revisions/<id>/checks/ REST API
+# /changes/`id`/revisions/`id`/checks/ REST API
This page describes the check-related REST endpoints that are added by the
@PLUGIN@ plugin.
@@ -143,6 +143,7 @@
### <a id="update-check"> Update Check
_'POST /changes/1/revisions/1/checks/'_
+
_'POST /changes/1/revisions/1/checks/test:my-checker'_
Updates a check. The semantics are the same as for [CreateCheck](#create-check).
@@ -156,6 +157,17 @@
the URL, it must either match the value provided in the request body via
[CheckInput](#check-input) or the value in the request body is omitted.
+### <a id="rerun-check"> Rerun Check
+
+_'POST /changes/1/revisions/1/checks/test:my-checker/rerun'_
+
+Reruns a check. As response the [CheckInfo](#check-info) entity is returned that
+describes the created check.
+
+
+This REST endpoint supports rerunning a check. It also resets all relevant check
+fields such as `message`, `url`, `started` and `finished`.
+
## <a id="json-entities"> JSON Entities
### <a id="check-info"> CheckInfo