DeletePreconditions: Limit child listing to 1 project
Limit "parent:<project>" predicate in ListChildProjects to 1 project
to avoid consuming too much resources on big gerrit sites.
Bug: Issue 10401
Change-Id: Ibb54d2f4a6b3caff9939a6f7953ad8bc083ec688
diff --git a/src/main/java/com/googlesource/gerrit/plugins/deleteproject/DeletePreconditions.java b/src/main/java/com/googlesource/gerrit/plugins/deleteproject/DeletePreconditions.java
index 9a105f3..9c92ec6 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/deleteproject/DeletePreconditions.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/deleteproject/DeletePreconditions.java
@@ -18,14 +18,15 @@
import static com.google.gerrit.reviewdb.client.RefNames.REFS_TAGS;
import static com.googlesource.gerrit.plugins.deleteproject.DeleteOwnProjectCapability.DELETE_OWN_PROJECT;
import static com.googlesource.gerrit.plugins.deleteproject.DeleteProjectCapability.DELETE_PROJECT;
-import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toSet;
+import com.google.common.collect.Iterables;
import com.google.gerrit.extensions.annotations.PluginName;
import com.google.gerrit.extensions.api.access.PluginPermission;
import com.google.gerrit.extensions.common.ProjectInfo;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
+import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.reviewdb.client.Branch;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.CurrentUser;
@@ -136,13 +137,13 @@
private void assertHasNoChildProjects(ProjectResource rsrc) throws CannotDeleteProjectException {
try {
- List<ProjectInfo> children = listChildProjectsProvider.get().apply(rsrc);
+ List<ProjectInfo> children = listChildProjectsProvider.get().withLimit(1).apply(rsrc);
if (!children.isEmpty()) {
throw new CannotDeleteProjectException(
- "Cannot delete project because it has children: "
- + children.stream().map(info -> info.name).collect(joining(",")));
+ "Cannot delete project because it has at least one child: "
+ + Iterables.getOnlyElement(children).name);
}
- } catch (PermissionBackendException | ResourceConflictException e) {
+ } catch (OrmException | PermissionBackendException | RestApiException e) {
throw new CannotDeleteProjectException(
String.format("Unable to verify if '%s' has children projects.", rsrc.getName()));
}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/deleteproject/DeletePreconditionsTest.java b/src/test/java/com/googlesource/gerrit/plugins/deleteproject/DeletePreconditionsTest.java
index 168a17c..6658478 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/deleteproject/DeletePreconditionsTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/deleteproject/DeletePreconditionsTest.java
@@ -138,9 +138,10 @@
doNothing().when(protectedProjects).assertIsNotProtected(rsrc);
ListChildProjects childProjects = mock(ListChildProjects.class);
when(listChildProjectsProvider.get()).thenReturn(childProjects);
+ when(childProjects.withLimit(1)).thenReturn(childProjects);
when(childProjects.apply(rsrc)).thenReturn(ImmutableList.of(new ProjectInfo()));
expectedException.expect(ResourceConflictException.class);
- expectedException.expectMessage("Cannot delete project because it has children:");
+ expectedException.expectMessage("Cannot delete project because it has at least one child:");
preConditions.assertCanBeDeleted(rsrc, new DeleteProject.Input());
}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/deleteproject/DeleteProjectIT.java b/src/test/java/com/googlesource/gerrit/plugins/deleteproject/DeleteProjectIT.java
index 8a56fb7..206f231 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/deleteproject/DeleteProjectIT.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/deleteproject/DeleteProjectIT.java
@@ -191,7 +191,9 @@
adminSshSession.exec(cmd);
assertThat(adminSshSession.getError())
.isEqualTo(
- "fatal: Cannot delete project because it has children: " + childrenString + "\n");
+ "fatal: Cannot delete project because it has at least one child: "
+ + childrenString
+ + "\n");
assertThat(projectDir.exists()).isTrue();
}