diff --git a/testsuite/integration-arquillian/tests/other/jpa-performance/README.md b/testsuite/integration-arquillian/tests/other/jpa-performance/README.md deleted file mode 100644 index 9e05577052b..00000000000 --- a/testsuite/integration-arquillian/tests/other/jpa-performance/README.md +++ /dev/null @@ -1,63 +0,0 @@ -# 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: -* `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) -* `many.users.read.after.create` - If true, then additional request to read user is send always after the user is created. Default: *false* -* `many.users.create.objects` - If true, then some additional objects will be added to each user (2 attributes, password credential, 2 group mappings, 1 required action) Default: *false* -* `many.users.create.social.links` - If true, then one social (identityProvider) link will be added to each user and then later read. Default: *false* -* `keycloak.connectionsJpa.globalStatsInterval` - Interval in seconds to log Hibernate statistics into log. Default: *-1* (which means statistics are disabled) - - -### With MySQL - -Start dockerized MySQL: -``` -docker run --name mysql-keycloak -e MYSQL_ROOT_PASSWORD=keycloak -e MYSQL_DATABASE=keycloak -e MYSQL_USER=keycloak -e MYSQL_PASSWORD=keycloak -d -p 3306:3306 mysql -``` - -Additional test parameters: -``` --Pclean-jpa --Dkeycloak.connectionsJpa.url=jdbc:mysql://localhost/keycloak --Dkeycloak.connectionsJpa.driver=com.mysql.jdbc.Driver --Dkeycloak.connectionsJpa.user=keycloak --Dkeycloak.connectionsJpa.password=keycloak -``` - -### With PostgreSQL - -Start dockerized PostgreSQL: -``` -docker run --name postgres-keycloak -e POSTGRES_PASSWORD=keycloak -d -p 5432:5432 postgres -``` - -Additional test parameters: -``` --Pclean-jpa --Dkeycloak.connectionsJpa.url=jdbc:postgresql://localhost/postgres --Dkeycloak.connectionsJpa.driver=org.postgresql.Driver --Dkeycloak.connectionsJpa.user=postgres --Dkeycloak.connectionsJpa.password=keycloak -``` - -## Reports - -Test creates reports in `target/stats`. diff --git a/testsuite/integration-arquillian/tests/other/jpa-performance/pom.xml b/testsuite/integration-arquillian/tests/other/jpa-performance/pom.xml deleted file mode 100644 index a4715a5937b..00000000000 --- a/testsuite/integration-arquillian/tests/other/jpa-performance/pom.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - 4.0.0 - - - org.keycloak.testsuite - integration-arquillian-tests-other - 999.0.0-SNAPSHOT - - - integration-arquillian-tests-jpa-performance - - Keycloak JPA Performance Tests - - 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 deleted file mode 100644 index 04a4c39fd7d..00000000000 --- a/testsuite/integration-arquillian/tests/other/jpa-performance/src/test/java/org/keycloak/testsuite/user/ManyUsersTest.java +++ /dev/null @@ -1,253 +0,0 @@ -package org.keycloak.testsuite.user; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.keycloak.admin.client.resource.RealmResource; -import org.keycloak.admin.client.resource.UsersResource; -import org.keycloak.models.UserModel; -import org.keycloak.representations.idm.CredentialRepresentation; -import org.keycloak.representations.idm.FederatedIdentityRepresentation; -import org.keycloak.representations.idm.GroupRepresentation; -import org.keycloak.representations.idm.RealmRepresentation; -import org.keycloak.representations.idm.RequiredActionProviderRepresentation; -import org.keycloak.representations.idm.UserRepresentation; -import org.keycloak.testsuite.admin.ApiUtil; -import org.keycloak.testsuite.util.Timer; -import org.keycloak.util.JsonSerialization; - -import javax.ws.rs.core.Response; -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.Collections; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.UUID; - -import static org.junit.Assert.fail; -import static org.keycloak.testsuite.util.IOUtil.PROJECT_BUILD_DIRECTORY; - -/** - * - * @author tkyjovsk - */ -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")); - - // When true, then it will always send another request to GET user after he is created (this trigger some DB queries and cache user on Keycloak side) - private static final boolean READ_USER_AFTER_CREATE = Boolean.parseBoolean(System.getProperty("many.users.read.after.create", "false")); - - // When true, then each user will be updated with password, 2 additional attributes, 2 default groups and some required action - private static final boolean CREATE_OBJECTS = Boolean.parseBoolean(System.getProperty("many.users.create.objects", "false")); - - // When true, then each user will be updated with 2 federated identity links - private static final boolean CREATE_SOCIAL_LINKS = Boolean.parseBoolean(System.getProperty("many.users.create.social.links", "false")); - - private static final boolean REIMPORT = Boolean.parseBoolean(System.getProperty("many.users.reimport", "false")); - - private static final String REALM = "realm_with_many_users"; - - private List users; - - 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); - } - - @Before - public void before() { - log.infof("Reading users after create is %s", READ_USER_AFTER_CREATE ? "ENABLED" : "DISABLED"); - - users = new LinkedList<>(); - for (int i = 0; i < COUNT; i++) { - users.add(createUserRep("user" + i)); - } - - realmTimer.reset("create realm before test"); - createRealm(REALM); - - if (CREATE_OBJECTS) { - - // Assuming default groups and required action already created - if (realmResource().getDefaultGroups().isEmpty()) { - log.infof("Creating default groups 'group1' and 'group2'."); - setDefaultGroup("group1"); - setDefaultGroup("group2"); - - RequiredActionProviderRepresentation updatePassword = realmResource().flows().getRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD.toString()); - updatePassword.setDefaultAction(true); - realmResource().flows().updateRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD.toString(), updatePassword); - } - } - - refreshToken(); - } - - private void setDefaultGroup(String groupName) { - GroupRepresentation group = new GroupRepresentation(); - group.setName(groupName); - Response resp = realmResource().groups().add(group); - String groupId = ApiUtil.getCreatedId(resp); - resp.close(); - realmResource().addDefaultGroup(groupId); - } - - @After - public void after() { - realmTimer.clearStats(true, true, false); - usersTimer.clearStats(); - } - - @Override - public UserRepresentation createUser(UsersResource users, UserRepresentation user) { - // Add some additional attributes to user - if (CREATE_OBJECTS) { - Map> attrs = new HashMap<>(); - attrs.put("attr1", Collections.singletonList("val1")); - attrs.put("attr2", Collections.singletonList("val2")); - user.setAttributes(attrs); - } - - UserRepresentation userRep = super.createUser(users, user); - - // Add password - if (CREATE_OBJECTS) { - CredentialRepresentation password = new CredentialRepresentation(); - password.setType(CredentialRepresentation.PASSWORD); - password.setValue("password"); - password.setTemporary(false); - users.get(userRep.getId()).resetPassword(password); - } - - // Add social link - if (CREATE_SOCIAL_LINKS) { - createSocialLink("facebook", users, userRep.getId()); - } - - return userRep; - } - - private void createSocialLink(String provider, UsersResource users, String userId) { - String uuid = UUID.randomUUID().toString(); - - FederatedIdentityRepresentation link = new FederatedIdentityRepresentation(); - link.setIdentityProvider(provider); - link.setUserId(uuid); - link.setUserName(uuid); - users.get(userId).addFederatedIdentity(provider, link); - } - - @Test - public void manyUsers() throws IOException { - RealmRepresentation realm = realmResource().toRepresentation(); - realm.setUsers(users); - - // CREATE - realmTimer.reset("create " + users.size() + " users"); - usersTimer.reset("create " + BATCH + " users"); - int i = 0; - for (UserRepresentation user : users) { - refreshTokenIfMinValidityExpired(); - UserRepresentation createdUser = createUser(realmResource().users(), user); - - // Send additional request to read every user after he is created - if (READ_USER_AFTER_CREATE) { - UserRepresentation returned = realmResource().users().get(createdUser.getId()).toRepresentation(); - Assert.assertEquals(returned.getId(), createdUser.getId()); - } - - // Send additional request to read social links of user - if (CREATE_SOCIAL_LINKS) { - List fedIdentities = realmResource().users().get(createdUser.getId()).getFederatedIdentity(); - } - - if (++i % BATCH == 0) { - usersTimer.reset(); - log.info("Created users: " + i + " / " + users.size()); - } - } - if (i % BATCH != 0) { - usersTimer.reset(); - log.info("Created users: " + i + " / " + users.size()); - } - - 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, -1); - - } - - // 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(); - log.info("Deleted users: " + i + " / " + users.size()); - } - } - if (i % BATCH != 0) { - usersTimer.reset(); - log.info("Deleted users: " + i + " / " + users.size()); - } - realmTimer.reset(); - } - - private void createRealm(String REALM) { - RealmRepresentation rep = new RealmRepresentation(); - rep.setRealm(REALM); - adminClient.realms().create(rep); - } - -} diff --git a/testsuite/integration-arquillian/tests/other/jpa-performance/src/test/resources/log4j.properties b/testsuite/integration-arquillian/tests/other/jpa-performance/src/test/resources/log4j.properties deleted file mode 100644 index e6e934c76d8..00000000000 --- a/testsuite/integration-arquillian/tests/other/jpa-performance/src/test/resources/log4j.properties +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright 2016 Red Hat, Inc. and/or its affiliates -# and other contributors as indicated by the @author tags. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -log4j.rootLogger=info - -log4j.appender.keycloak=org.apache.log4j.ConsoleAppender -log4j.appender.keycloak.layout=org.apache.log4j.PatternLayout -log4j.appender.keycloak.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p [%c] %m%n - -log4j.appender.testsuite=org.apache.log4j.ConsoleAppender -log4j.appender.testsuite.layout=org.apache.log4j.PatternLayout -log4j.appender.testsuite.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p %m%n - -log4j.logger.org.keycloak=off, keycloak - -log4j.logger.org.keycloak.testsuite=debug, testsuite -log4j.additivity.org.keycloak.testsuite=false - -# Enable to view events -# log4j.logger.org.keycloak.events=debug - -# Enable to view loaded SPI and Providers -# log4j.logger.org.keycloak.services.DefaultKeycloakSessionFactory=debug -# log4j.logger.org.keycloak.provider.ProviderManager=debug -# log4j.logger.org.keycloak.provider.FileSystemProviderLoaderFactory=debug - -# Liquibase updates logged with "info" by default. Logging level can be changed by system property "keycloak.liquibase.logging.level" -keycloak.liquibase.logging.level=info -log4j.logger.org.keycloak.connections.jpa.updater.liquibase=${keycloak.liquibase.logging.level} -log4j.logger.org.keycloak.connections.jpa=debug - -# Enable to view database updates -# log4j.logger.org.keycloak.connections.jpa.DefaultJpaConnectionProviderFactory=debug -# log4j.logger.org.keycloak.migration.MigrationModelManager=debug - -# Enable to view kerberos/spnego logging -# log4j.logger.org.keycloak.broker.kerberos=trace - -# Enable to view detailed AS REQ and TGS REQ requests to embedded Kerberos server -# log4j.logger.org.apache.directory.server.kerberos=debug - -log4j.logger.org.xnio=off -log4j.logger.org.hibernate=off -log4j.logger.org.jboss.resteasy=warn -log4j.logger.org.apache.directory.api=warn -log4j.logger.org.apache.directory.server.core=warn \ No newline at end of file diff --git a/testsuite/integration-arquillian/tests/other/pom.xml b/testsuite/integration-arquillian/tests/other/pom.xml index 108447c25c7..d3f846d78b3 100644 --- a/testsuite/integration-arquillian/tests/other/pom.xml +++ b/testsuite/integration-arquillian/tests/other/pom.xml @@ -93,12 +93,6 @@ - - jpa-performance - - jpa-performance - - sssd