Fix username matching pattern Make it possible to have hyphens, underscores and capital letters. Include test which is a combination of user name extraction and soft max quota. Change-Id: I69d2b4a1dfc4bb39940525bb27b6efd437867e68
diff --git a/src/main/java/com/googlesource/gerrit/plugins/quota/TaskParser.java b/src/main/java/com/googlesource/gerrit/plugins/quota/TaskParser.java index 732b082..5944308 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/quota/TaskParser.java +++ b/src/main/java/com/googlesource/gerrit/plugins/quota/TaskParser.java
@@ -20,7 +20,7 @@ import java.util.regex.Pattern; public class TaskParser { - public static final Pattern USER_EXTRACT_PATTERN = Pattern.compile("\\(([a-z0-9]+)\\)$"); + public static final Pattern USER_EXTRACT_PATTERN = Pattern.compile("\\(([\\-_A-Za-z0-9]+)\\)$"); public static Optional<String> user(WorkQueue.Task<?> task) { Matcher matcher = USER_EXTRACT_PATTERN.matcher(task.toString());
diff --git a/src/test/java/com/googlesource/gerrit/plugins/quota/TaskQuotasTest.java b/src/test/java/com/googlesource/gerrit/plugins/quota/TaskQuotasTest.java index c8870d0..61614c8 100644 --- a/src/test/java/com/googlesource/gerrit/plugins/quota/TaskQuotasTest.java +++ b/src/test/java/com/googlesource/gerrit/plugins/quota/TaskQuotasTest.java
@@ -34,6 +34,7 @@ public class TaskQuotasTest { private static final String PROJECT_X = "project-x"; private static final String USER_A = "USER_A"; + private static final String USER_B = "USER_B"; @Test public void testMaxStartForTaskForQueue() throws ConfigInvalidException { @@ -76,6 +77,61 @@ startAndCompleteTask(taskQuotas, u_x_3); } + @Test + public void testSoftMaxPerUserForQueue() throws ConfigInvalidException { + TaskQuotas taskQuotas = + taskQuotas( + 5, + 5, + """ +[quota "%s"] + softMaxStartPerUserForQueue = 2 %s +""" + .formatted(PROJECT_X, INTERACTIVE.getName())); + + // running: user_a: 1 user_b: 0 + Task<?> u_x_a_1 = task(INTERACTIVE.getName(), uploadPackTask(PROJECT_X, USER_A)); + assertTrue(taskQuotas.isReadyToStart(u_x_a_1)); + taskQuotas.onStart(u_x_a_1); + + // running: user_a: 2 user_b: 0 (user_a is at the softMax) + Task<?> u_x_a_2 = task(INTERACTIVE.getName(), uploadPackTask(PROJECT_X, USER_A)); + assertTrue(taskQuotas.isReadyToStart(u_x_a_2)); + taskQuotas.onStart(u_x_a_2); + + // running: user_a: 3 user_b: 0 (user_a able to start new task exceeding soft max) + Task<?> u_x_a_3 = task(INTERACTIVE.getName(), receivePackTask(PROJECT_X, USER_A)); + assertTrue(taskQuotas.isReadyToStart(u_x_a_3)); + taskQuotas.onStart(u_x_a_3); + + // running: user_a: 3 user_b: 1 + Task<?> u_x_b_1 = task(INTERACTIVE.getName(), uploadPackTask(PROJECT_X, USER_B)); + assertTrue(taskQuotas.isReadyToStart(u_x_b_1)); + taskQuotas.onStart(u_x_b_1); + + // running: user_a: 3 user_b: 2 + Task<?> u_x_b_2 = task(INTERACTIVE.getName(), receivePackTask(PROJECT_X, USER_B)); + assertTrue(taskQuotas.isReadyToStart(u_x_b_2)); + taskQuotas.onStart(u_x_b_2); + + // running: user_a: 2 user_b: 2 + taskQuotas.onStop(u_x_a_1); + Task<?> u_x_a_4 = task(INTERACTIVE.getName(), uploadPackTask(PROJECT_X, USER_A)); + assertFalse(taskQuotas.isReadyToStart(u_x_a_4)); + + // running: user_a: 2 user_b: 1 + taskQuotas.onStop(u_x_b_1); + + // running: user_a: 3 user_b: 1 + assertTrue(taskQuotas.isReadyToStart(u_x_a_4)); + taskQuotas.onStart(u_x_a_4); + + taskQuotas.onStop(u_x_a_2); + taskQuotas.onStop(u_x_a_3); + taskQuotas.onStop(u_x_a_4); + taskQuotas.onStop(u_x_b_2); + } + private Task<?> task(String queueName, String taskString) { Task<?> task = Mockito.mock(Task.class); when(task.getTaskId()).thenReturn(new Random().nextInt());