Trying to make sure there is no active tasks and introduce a timeout

Closes #34432

Signed-off-by: Pedro Igor <pigor.craveiro@gmail.com>
This commit is contained in:
Pedro Igor 2024-10-30 09:51:31 -03:00 committed by Alexander Schwartz
parent 9c50813bf4
commit db780ed6c7
3 changed files with 24 additions and 24 deletions

View file

@ -29,13 +29,16 @@ import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.WebDriverWait; import org.openqa.selenium.support.ui.WebDriverWait;
import java.time.Duration; import java.time.Duration;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import static org.jboss.arquillian.graphene.Graphene.waitGui; import static org.jboss.arquillian.graphene.Graphene.waitGui;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import static org.keycloak.testsuite.util.DroneUtils.getCurrentDriver; import static org.keycloak.testsuite.util.DroneUtils.getCurrentDriver;
import static org.openqa.selenium.support.ui.ExpectedConditions.javaScriptThrowsNoExceptions; import static org.openqa.selenium.support.ui.ExpectedConditions.javaScriptThrowsNoExceptions;
import static org.openqa.selenium.support.ui.ExpectedConditions.not; import static org.openqa.selenium.support.ui.ExpectedConditions.not;
@ -162,28 +165,28 @@ public final class WaitUtils {
waitUntilElementIsNotPresent(By.className("modal-backdrop")); waitUntilElementIsNotPresent(By.className("modal-backdrop"));
} }
public static long getNumExecutors(KeycloakTestingClient testingClient) { public static void waitForBruteForceExecutors(KeycloakTestingClient testingClient) {
String numExecutors = testingClient.server().fetchString(session -> {
ExecutorsProvider provider = session.getProvider(ExecutorsProvider.class);
ExecutorService executor = provider.getExecutor("bruteforce");
ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) executor;
return threadPoolExecutor.getCompletedTaskCount();
});
return Long.valueOf(numExecutors);
}
public static void waitForExecutors(KeycloakTestingClient testingClient, long numExecutors) {
testingClient.server().run(session -> { testingClient.server().run(session -> {
ExecutorsProvider provider = session.getProvider(ExecutorsProvider.class); ExecutorsProvider provider = session.getProvider(ExecutorsProvider.class);
ExecutorService executor = provider.getExecutor("bruteforce"); ExecutorService executor = provider.getExecutor("bruteforce");
ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) executor; ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) executor;
do { try {
try { CompletableFuture.runAsync(() -> {
Thread.sleep(1000); do {
} catch (Exception e) { try {
} Thread.sleep(1000);
} while (!threadPoolExecutor.getQueue().isEmpty()); } catch (InterruptedException e) {
assertEquals(numExecutors, threadPoolExecutor.getCompletedTaskCount()); throw new RuntimeException(e);
}
} while (!threadPoolExecutor.getQueue().isEmpty() || threadPoolExecutor.getActiveCount() > 0);
}).get(30, TimeUnit.SECONDS);
} catch (java.util.concurrent.TimeoutException te) {
fail("Timeout while waiting for brute force executors!");
} catch (Exception e) {
e.printStackTrace();
fail("Unexpected error while waiting for brute force executors!");
}
assertEquals(0, threadPoolExecutor.getActiveCount());
}); });
} }
} }

View file

@ -567,14 +567,13 @@ public abstract class AbstractAdvancedBrokerTest extends AbstractBrokerTest {
Map<String, Object> bruteForceStatus = realm.attackDetection().bruteForceUserStatus(user.getId()); Map<String, Object> bruteForceStatus = realm.attackDetection().bruteForceUserStatus(user.getId());
assertFalse("User should not be disabled by brute force.", (boolean) bruteForceStatus.get("disabled")); assertFalse("User should not be disabled by brute force.", (boolean) bruteForceStatus.get("disabled"));
long numExecutors = WaitUtils.getNumExecutors(testingClient);
// Login for 2 times with incorrect TOTP. This should temporarily disable the user // Login for 2 times with incorrect TOTP. This should temporarily disable the user
loginTotpPage.login("bad-totp"); loginTotpPage.login("bad-totp");
Assert.assertEquals("Invalid authenticator code.", loginTotpPage.getInputError()); Assert.assertEquals("Invalid authenticator code.", loginTotpPage.getInputError());
loginTotpPage.login("bad-totp"); loginTotpPage.login("bad-totp");
Assert.assertEquals("Invalid authenticator code.", loginTotpPage.getInputError()); Assert.assertEquals("Invalid authenticator code.", loginTotpPage.getInputError());
WaitUtils.waitForExecutors(testingClient, numExecutors+2); WaitUtils.waitForBruteForceExecutors(testingClient);
bruteForceStatus = realm.attackDetection().bruteForceUserStatus(user.getId()); bruteForceStatus = realm.attackDetection().bruteForceUserStatus(user.getId());
assertTrue("User should be disabled by brute force.", (boolean) bruteForceStatus.get("disabled")); assertTrue("User should be disabled by brute force.", (boolean) bruteForceStatus.get("disabled"));

View file

@ -416,11 +416,10 @@ public class BruteForceTest extends AbstractTestRealmKeycloakTest {
try { try {
realm.setMaxDeltaTimeSeconds(5); realm.setMaxDeltaTimeSeconds(5);
testRealm().update(realm); testRealm().update(realm);
long numExecutors = WaitUtils.getNumExecutors(testingClient);
loginInvalidPassword(); loginInvalidPassword();
//Wait for brute force executor to process the login and then wait for delta time //Wait for brute force executor to process the login and then wait for delta time
WaitUtils.waitForExecutors(testingClient, numExecutors + 1); WaitUtils.waitForBruteForceExecutors(testingClient);
testingClient.testing().setTimeOffset(Collections.singletonMap("offset", String.valueOf(5))); testingClient.testing().setTimeOffset(Collections.singletonMap("offset", String.valueOf(5)));
loginInvalidPassword(); loginInvalidPassword();
@ -438,11 +437,10 @@ public class BruteForceTest extends AbstractTestRealmKeycloakTest {
realm.setMaxDeltaTimeSeconds(5); realm.setMaxDeltaTimeSeconds(5);
realm.setPermanentLockout(true); realm.setPermanentLockout(true);
testRealm().update(realm); testRealm().update(realm);
long numExecutors = WaitUtils.getNumExecutors(testingClient);
loginInvalidPassword(); loginInvalidPassword();
//Wait for brute force executor to process the login and then wait for delta time //Wait for brute force executor to process the login and then wait for delta time
WaitUtils.waitForExecutors(testingClient, numExecutors + 1); WaitUtils.waitForBruteForceExecutors(testingClient);
testingClient.testing().setTimeOffset(Collections.singletonMap("offset", String.valueOf(5))); testingClient.testing().setTimeOffset(Collections.singletonMap("offset", String.valueOf(5)));
loginInvalidPassword(); loginInvalidPassword();