diff --git a/testsuite/integration-arquillian/tests/other/jpa-performance/README.md b/testsuite/integration-arquillian/tests/other/jpa-performance/README.md index d38961620e..238bd4cfec 100644 --- a/testsuite/integration-arquillian/tests/other/jpa-performance/README.md +++ b/testsuite/integration-arquillian/tests/other/jpa-performance/README.md @@ -1,15 +1,26 @@ # Keycloak JPA Performance Tests +## Test Phases + +1. Create individual users +2. Delete realm **Optional** +3. Re-import realm **Optional** +4. Delete individual users + +Phases 2 and 3 are activated by property `many.users.reimport=true|false`. + + ## How to run 1. Build the Arquilian Base Testsuite module: `/testsuite/integration-arquillian/base` 2. Run the test from this module using `mvn test` or `mvn clean test`. Optional parameters: -``` --Dmany.users.count=10000 --Dmany.users.batch=1000 -``` +* `many.users.count` - Number of users to add/delete. Default: *10000*. +* `many.users.batch` - Measurement batch size. Default: *1000*. +* `many.users.reimport` - Switch for phases 2 and 3. Default: *false*. +* `many.users.minTokenValidity` - Minimum validity of admin-client's access token. Default: *10000*. (ms) + ### With MySQL diff --git a/testsuite/integration-arquillian/tests/other/jpa-performance/src/test/java/org/keycloak/testsuite/user/ManyUsersTest.java b/testsuite/integration-arquillian/tests/other/jpa-performance/src/test/java/org/keycloak/testsuite/user/ManyUsersTest.java index 4916393bff..914f748555 100644 --- a/testsuite/integration-arquillian/tests/other/jpa-performance/src/test/java/org/keycloak/testsuite/user/ManyUsersTest.java +++ b/testsuite/integration-arquillian/tests/other/jpa-performance/src/test/java/org/keycloak/testsuite/user/ManyUsersTest.java @@ -13,9 +13,9 @@ import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.testsuite.util.Timer; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.util.JsonSerialization; -import static org.junit.Assert.fail; import org.keycloak.admin.client.resource.RealmResource; import static org.keycloak.testsuite.util.IOUtil.PROJECT_BUILD_DIRECTORY; +import static org.junit.Assert.fail; /** * @@ -25,6 +25,7 @@ public class ManyUsersTest extends AbstractUserTest { private static final int COUNT = Integer.parseInt(System.getProperty("many.users.count", "10000")); private static final int BATCH = Integer.parseInt(System.getProperty("many.users.batch", "1000")); + private static final boolean REIMPORT = Boolean.parseBoolean(System.getProperty("many.users.reimport", "false")); private static final String REALM = "realm_with_many_users"; @@ -33,6 +34,26 @@ public class ManyUsersTest extends AbstractUserTest { private final Timer realmTimer = new Timer(); private final Timer usersTimer = new Timer(); + private static final long MIN_TOKEN_VALIDITY = Long.parseLong(System.getProperty("many.users.minTokenValidity", "10000")); + long tokenExpirationTime = 0; + + protected boolean tokenMinValidityExpired() { + return System.currentTimeMillis() >= tokenExpirationTime - MIN_TOKEN_VALIDITY; + } + + protected void refreshToken() { + long requestTime = System.currentTimeMillis(); + adminClient.tokenManager().refreshToken(); + tokenExpirationTime = requestTime + adminClient.tokenManager().getAccessToken().getExpiresIn() * 1000; + } + + protected void refreshTokenIfMinValidityExpired() { + if (tokenMinValidityExpired()) { + log.info(String.format("Minimum access token validity (%s ms) expired --> refreshing", MIN_TOKEN_VALIDITY)); + refreshToken(); + } + } + protected RealmResource realmResource() { return realmsResouce().realm(REALM); } @@ -48,6 +69,8 @@ public class ManyUsersTest extends AbstractUserTest { RealmRepresentation realm = new RealmRepresentation(); realm.setRealm(REALM); realmsResouce().create(realm); + + refreshToken(); } @After @@ -66,6 +89,7 @@ public class ManyUsersTest extends AbstractUserTest { usersTimer.reset("create " + BATCH + " users"); int i = 0; for (UserRepresentation user : users) { + refreshTokenIfMinValidityExpired(); createUser(realmResource().users(), user); if (++i % BATCH == 0) { usersTimer.reset(); @@ -77,32 +101,37 @@ public class ManyUsersTest extends AbstractUserTest { log.info("Created users: " + i + " / " + users.size()); } - // SAVE REALM - realmTimer.reset("save realm with " + users.size() + " users"); - File realmFile = new File(PROJECT_BUILD_DIRECTORY, REALM + ".json"); - JsonSerialization.writeValueToStream(new BufferedOutputStream(new FileOutputStream(realmFile)), realm); + if (REIMPORT) { + + // SAVE REALM + realmTimer.reset("save realm with " + users.size() + " users"); + File realmFile = new File(PROJECT_BUILD_DIRECTORY, REALM + ".json"); + JsonSerialization.writeValueToStream(new BufferedOutputStream(new FileOutputStream(realmFile)), realm); + + // DELETE REALM + realmTimer.reset("delete realm with " + users.size() + " users"); + realmResource().remove(); + try { + realmResource().toRepresentation(); + fail("realm not deleted"); + } catch (Exception ex) { + log.debug("realm deleted"); + } + + // RE-IMPORT SAVED REALM + realmTimer.reset("re-import realm with " + realm.getUsers().size() + " users"); + realmsResouce().create(realm); + realmTimer.reset("load " + realm.getUsers().size() + " users"); + users = realmResource().users().search("", 0, Integer.MAX_VALUE); - // DELETE REALM - realmTimer.reset("delete realm with " + users.size() + " users"); - realmResource().remove(); - try { - realmResource().toRepresentation(); - fail("realm not deleted"); - } catch (Exception ex) { - log.debug("realm deleted"); } - // RE-IMPORT SAVED REALM - realmTimer.reset("re-import realm with " + realm.getUsers().size() + " users"); - realmsResouce().create(realm); - realmTimer.reset("load " + realm.getUsers().size() + " users"); - users = realmResource().users().search("", 0, Integer.MAX_VALUE); - // DELETE INDIVIDUAL USERS realmTimer.reset("delete " + users.size() + " users"); usersTimer.reset("delete " + BATCH + " users", false); i = 0; for (UserRepresentation user : users) { + refreshTokenIfMinValidityExpired(); realmResource().users().get(user.getId()).remove(); if (++i % BATCH == 0) { usersTimer.reset();