diff --git a/testsuite/integration-arquillian/tests/other/jpa-performance/README.md b/testsuite/integration-arquillian/tests/other/jpa-performance/README.md
index d389616..238bd4c 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 4916393..914f748 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);
-
- // 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");
- }
+ 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);
+ // 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();