Fix DB tests for Quarkus

Fixes #13642
This commit is contained in:
Martin Bartoš 2022-08-08 17:32:36 +02:00 committed by Pedro Igor
parent 15b258bf26
commit 5a2852530f
6 changed files with 164 additions and 43 deletions

View file

@ -442,11 +442,17 @@
<profile>
<id>db-mysql</id>
<properties>
<keycloak.storage.connections.vendor>mysql</keycloak.storage.connections.vendor>
<keycloak.connectionsJpa.driver>com.mysql.jdbc.Driver</keycloak.connectionsJpa.driver>
<keycloak.connectionsJpa.database>keycloak</keycloak.connectionsJpa.database>
<keycloak.connectionsJpa.user>keycloak</keycloak.connectionsJpa.user>
<keycloak.connectionsJpa.password>keycloak</keycloak.connectionsJpa.password>
<keycloak.connectionsJpa.url>jdbc:mysql://${auth.server.db.host}/${keycloak.connectionsJpa.database}?allowPublicKeyRetrieval=true</keycloak.connectionsJpa.url>
<!-- Map Store JPA -->
<keycloak.map.storage.connectionsJpa.url>${keycloak.connectionsJpa.url}</keycloak.map.storage.connectionsJpa.url>
<keycloak.map.storage.connectionsJpa.user>${keycloak.connectionsJpa.user}</keycloak.map.storage.connectionsJpa.user>
<keycloak.map.storage.connectionsJpa.password>${keycloak.connectionsJpa.password}</keycloak.map.storage.connectionsJpa.password>
<!-- JDBC properties point to "default" JDBC driver for the particular DB -->
<!-- For EAP testing, it is recommended to override those with system properties pointing to GAV of more appropriate JDBC driver -->
<!-- for the particular EAP version -->
@ -470,11 +476,16 @@
<profile>
<id>db-postgres</id>
<properties>
<keycloak.storage.connections.vendor>postgres</keycloak.storage.connections.vendor>
<keycloak.connectionsJpa.driver>org.postgresql.Driver</keycloak.connectionsJpa.driver>
<keycloak.connectionsJpa.database>keycloak</keycloak.connectionsJpa.database>
<keycloak.connectionsJpa.user>keycloak</keycloak.connectionsJpa.user>
<keycloak.connectionsJpa.password>keycloak</keycloak.connectionsJpa.password>
<keycloak.connectionsJpa.url>jdbc:postgresql://${auth.server.db.host}/${keycloak.connectionsJpa.database}</keycloak.connectionsJpa.url>
<!-- Map Store JPA -->
<keycloak.map.storage.connectionsJpa.url>${keycloak.connectionsJpa.url}</keycloak.map.storage.connectionsJpa.url>
<keycloak.map.storage.connectionsJpa.user>${keycloak.connectionsJpa.user}</keycloak.map.storage.connectionsJpa.user>
<keycloak.map.storage.connectionsJpa.password>${keycloak.connectionsJpa.password}</keycloak.map.storage.connectionsJpa.password>
<!-- JDBC properties point to "default" JDBC driver for the particular DB -->
<!-- For EAP testing, it is recommended to override those with system properties pointing to GAV of more appropriate JDBC driver -->
<!-- for the particular EAP version -->
@ -505,11 +516,16 @@
<profile>
<id>db-mariadb</id>
<properties>
<keycloak.storage.connections.vendor>mariadb</keycloak.storage.connections.vendor>
<keycloak.connectionsJpa.driver>org.mariadb.jdbc.Driver</keycloak.connectionsJpa.driver>
<keycloak.connectionsJpa.database>keycloak</keycloak.connectionsJpa.database>
<keycloak.connectionsJpa.user>keycloak</keycloak.connectionsJpa.user>
<keycloak.connectionsJpa.password>keycloak</keycloak.connectionsJpa.password>
<keycloak.connectionsJpa.url>jdbc:mariadb://${auth.server.db.host}/${keycloak.connectionsJpa.database}</keycloak.connectionsJpa.url>
<!-- Map Store JPA -->
<keycloak.map.storage.connectionsJpa.url>${keycloak.connectionsJpa.url}</keycloak.map.storage.connectionsJpa.url>
<keycloak.map.storage.connectionsJpa.user>${keycloak.connectionsJpa.user}</keycloak.map.storage.connectionsJpa.user>
<keycloak.map.storage.connectionsJpa.password>${keycloak.connectionsJpa.password}</keycloak.map.storage.connectionsJpa.password>
<!-- JDBC properties point to "default" JDBC driver for the particular DB -->
<!-- For EAP testing, it is recommended to override those with system properties pointing to GAV of more appropriate JDBC driver -->
<!-- for the particular EAP version -->
@ -540,11 +556,16 @@
<docker.database.postStart>/opt/mssql-tools/bin/sqlcmd -e -U sa -P vEry5tron9Pwd -d master -Q CREATE\ DATABASE\ ${keycloak.connectionsJpa.database}</docker.database.postStart>
<docker.database.cmd>/bin/sh -c /opt/mssql/bin/sqlservr</docker.database.cmd>
<docker.database.wait-for-log-regex>(?si)SQL Server is now ready for client connections.*Service Broker manager has started</docker.database.wait-for-log-regex>
<keycloak.storage.connections.vendor>mssql</keycloak.storage.connections.vendor>
<keycloak.connectionsJpa.driver>com.microsoft.sqlserver.jdbc.SQLServerDriver</keycloak.connectionsJpa.driver>
<keycloak.connectionsJpa.database>keycloak</keycloak.connectionsJpa.database>
<keycloak.connectionsJpa.user>sa</keycloak.connectionsJpa.user>
<keycloak.connectionsJpa.password>vEry5tron9Pwd</keycloak.connectionsJpa.password>
<keycloak.connectionsJpa.url>jdbc:sqlserver://${auth.server.db.host}:${docker.database.port};databaseName=${keycloak.connectionsJpa.database}</keycloak.connectionsJpa.url>
<!-- Map Store JPA -->
<keycloak.map.storage.connectionsJpa.url>${keycloak.connectionsJpa.url}</keycloak.map.storage.connectionsJpa.url>
<keycloak.map.storage.connectionsJpa.user>${keycloak.connectionsJpa.user}</keycloak.map.storage.connectionsJpa.user>
<keycloak.map.storage.connectionsJpa.password>${keycloak.connectionsJpa.password}</keycloak.map.storage.connectionsJpa.password>
<!-- JDBC properties point to "default" JDBC driver for the particular DB -->
<!-- For EAP testing, it is recommended to override those with system properties pointing to GAV of more appropriate JDBC driver -->
<!-- for the particular EAP version -->
@ -569,11 +590,17 @@
<docker.database.skip>false</docker.database.skip>
<docker.database.cmd>/bin/sh -c exec\ $ORACLE_BASE/$RUN_FILE</docker.database.cmd>
<docker.database.wait-for-log-regex>(?si)DATABASE IS READY TO USE</docker.database.wait-for-log-regex>
<keycloak.storage.connections.vendor>oracle</keycloak.storage.connections.vendor>
<keycloak.connectionsJpa.driver>oracle.jdbc.OracleDriver</keycloak.connectionsJpa.driver>
<keycloak.connectionsJpa.database>XE</keycloak.connectionsJpa.database>
<keycloak.connectionsJpa.user>keycloak</keycloak.connectionsJpa.user>
<keycloak.connectionsJpa.password>keycloak</keycloak.connectionsJpa.password>
<keycloak.connectionsJpa.url>jdbc:oracle:thin:@${auth.server.db.host}:${docker.database.port}:${keycloak.connectionsJpa.database}</keycloak.connectionsJpa.url>
<!-- Map Store JPA -->
<keycloak.map.storage.connectionsJpa.url>${keycloak.connectionsJpa.url}</keycloak.map.storage.connectionsJpa.url>
<keycloak.map.storage.connectionsJpa.user>${keycloak.connectionsJpa.user}</keycloak.map.storage.connectionsJpa.user>
<keycloak.map.storage.connectionsJpa.password>${keycloak.connectionsJpa.password}</keycloak.map.storage.connectionsJpa.password>
<docker.database.postStart>bash -c while\ !\ sqlplus\ -L\ SYS/sa@localhost/XE\ AS\ SYSDBA\ &lt;&lt;&lt;\ $'CREATE\ USER\ ${keycloak.connectionsJpa.user}\ IDENTIFIED\ BY\ ${keycloak.connectionsJpa.password};\n\ GRANT\ CONNECT,\ RESOURCE,\ DBA,\ GRANT\ ANY\ PRIVILEGE,\ UNLIMITED\ TABLESPACE\ TO\ ${keycloak.connectionsJpa.user};\n';\ do\ sleep\ 5;\ done</docker.database.postStart>
<!-- JDBC properties point to "default" JDBC driver for the particular DB -->
<!-- For EAP testing, it is recommended to override those with system properties pointing to GAV of more appropriate JDBC driver -->

View file

@ -22,7 +22,7 @@ public class KeycloakQuarkusConfiguration implements ContainerConfiguration {
private int bindHttpPortOffset = 100;
private int bindHttpPort = 8080;
private int bindHttpsPortOffset = 0;
private int bindHttpsPort = Integer.valueOf(System.getProperty("auth.server.https.port", "8543"));
private int bindHttpsPort = Integer.getInteger("auth.server.https.port", 8543);
private int debugPort = -1;
private Path providersPath = Paths.get(System.getProperty("auth.server.home"));
private int startupTimeoutInSeconds = 300;
@ -163,6 +163,4 @@ public class KeycloakQuarkusConfiguration implements ContainerConfiguration {
public void setImportFile(String importFile) {
this.importFile = importFile;
}
}

View file

@ -31,6 +31,7 @@ import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import org.apache.commons.exec.StreamPumper;
@ -47,6 +48,7 @@ import org.jboss.shrinkwrap.api.Archive;
import org.jboss.shrinkwrap.api.exporter.ZipExporter;
import org.jboss.shrinkwrap.descriptor.api.Descriptor;
import org.keycloak.testsuite.arquillian.SuiteContext;
import org.keycloak.testsuite.model.StoreProvider;
/**
* @author mhajas
@ -54,7 +56,6 @@ import org.keycloak.testsuite.arquillian.SuiteContext;
public class KeycloakQuarkusServerDeployableContainer implements DeployableContainer<KeycloakQuarkusConfiguration> {
private static final int DEFAULT_SHUTDOWN_TIMEOUT_SECONDS = 10;
private static final String AUTH_SERVER_QUARKUS_MAP_STORAGE_PROFILE = "auth.server.quarkus.mapStorage.profile.config";
private static final Logger log = Logger.getLogger(KeycloakQuarkusServerDeployableContainer.class);
@ -182,9 +183,6 @@ public class KeycloakQuarkusServerDeployableContainer implements DeployableConta
builder.environment().put("JAVA_OPTS", javaOpts);
}
builder.environment().put("KEYCLOAK_ADMIN", "admin");
builder.environment().put("KEYCLOAK_ADMIN_PASSWORD", "admin");
if (restart.compareAndSet(false, true)) {
deleteDirectory(configuration.getProvidersPath().resolve("data"));
}
@ -216,15 +214,18 @@ public class KeycloakQuarkusServerDeployableContainer implements DeployableConta
commands.add("-Djboss.node.name=" + configuration.getRoute());
}
String mapStorageProfile = System.getProperty(AUTH_SERVER_QUARKUS_MAP_STORAGE_PROFILE);
// only run build during restarts or when running cluster tests
final StoreProvider storeProvider = StoreProvider.getCurrentProvider();
if (restart.get() || "ha".equals(System.getProperty("auth.server.quarkus.cluster.config"))) {
final Supplier<Boolean> shouldSetUpDb = () -> !restart.get() && !storeProvider.equals(StoreProvider.DEFAULT);
final Supplier<String> getClusterConfig = () -> System.getProperty("auth.server.quarkus.cluster.config", "local");
// only run build during first execution of the server (if the DB is specified), restarts or when running cluster tests
if (restart.get() || shouldSetUpDb.get() || "ha".equals(getClusterConfig.get())) {
commands.removeIf("--optimized"::equals);
commands.add("--http-relative-path=/auth");
if (mapStorageProfile == null) {
String cacheMode = System.getProperty("auth.server.quarkus.cluster.config", "local");
if (!storeProvider.isMapStore()) {
String cacheMode = getClusterConfig.get();
if ("local".equals(cacheMode)) {
commands.add("--cache=local");
@ -234,7 +235,7 @@ public class KeycloakQuarkusServerDeployableContainer implements DeployableConta
}
}
addStorageOptions(commands);
addStorageOptions(storeProvider, commands);
commands.addAll(getAdditionalBuildArgs());
@ -243,34 +244,9 @@ public class KeycloakQuarkusServerDeployableContainer implements DeployableConta
return commands.toArray(new String[0]);
}
private void addStorageOptions(List<String> commands) {
String mapStorageProfile = System.getProperty(AUTH_SERVER_QUARKUS_MAP_STORAGE_PROFILE);
if (mapStorageProfile != null) {
// We need to drop optimized flag because --storage is build option therefore startup requires re-augmentation
commands.removeIf("--optimized"::equals);
// As config is re-augmented on startup we need to also add --http-relative-path as ant build from
// integration-arquillian/servers/auth-server/quarkus/ant/configure.xml is replaced by build invoked on
// startup when we add new build option below
commands.add("--http-relative-path=/auth");
switch (mapStorageProfile) {
case "chm":
commands.add("--storage=" + mapStorageProfile);
break;
case "jpa":
commands.add("--storage=" + mapStorageProfile);
commands.add("--db-username=" + System.getProperty("keycloak.map.storage.connectionsJpa.url"));
commands.add("--db-password=" + System.getProperty("keycloak.map.storage.connectionsJpa.user"));
commands.add("--db-url=" + System.getProperty("keycloak.map.storage.connectionsJpa.password"));
break;
case "hotrod":
commands.add("--storage=" + mapStorageProfile);
// TODO: URL / username / password
break;
}
}
private void addStorageOptions(StoreProvider storeProvider, List<String> commands) {
log.debugf("Store '%s' is used.", storeProvider.name());
storeProvider.addStoreOptions(commands);
}
private void waitForReadiness() throws MalformedURLException, LifecycleException {

View file

@ -0,0 +1,114 @@
/*
* Copyright 2022 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.
*/
package org.keycloak.testsuite.model;
import org.keycloak.utils.StringUtil;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
/**
* @author <a href="mailto:mabartos@redhat.com">Martin Bartos</a>
*/
public enum StoreProvider {
CHM("chm") {
@Override
public void addStoreOptions(List<String> commands) {
commands.add("--storage=" + getAlias());
}
},
JPA("jpa") {
@Override
public void addStoreOptions(List<String> commands) {
commands.add("--storage=" + getAlias());
getDbVendor().ifPresent(vendor -> commands.add("--db=" + vendor));
commands.add("--db-url='" + System.getProperty("keycloak.map.storage.connectionsJpa.url") + "'");
commands.add("--db-username=" + System.getProperty("keycloak.map.storage.connectionsJpa.user"));
commands.add("--db-password=" + System.getProperty("keycloak.map.storage.connectionsJpa.password"));
}
},
HOTROD("hotrod") {
@Override
public void addStoreOptions(List<String> commands) {
commands.add("--storage=" + getAlias());
commands.add("--storage-hotrod-host='" + System.getProperty("keycloak.connectionsHotRod.host") + "'");
commands.add("--storage-hotrod-username" + System.getProperty("keycloak.connectionsHotRod.username"));
commands.add("--storage-hotrod-password" + System.getProperty("keycloak.connectionsHotRod.password"));
}
},
LEGACY("legacy") {
@Override
public void addStoreOptions(List<String> commands) {
getDbVendor().ifPresent(vendor -> commands.add("--db=" + vendor));
commands.add("--db-url='" + System.getProperty("keycloak.connectionsJpa.url") + "'");
commands.add("--db-username=" + System.getProperty("keycloak.connectionsJpa.user"));
commands.add("--db-password=" + System.getProperty("keycloak.connectionsJpa.password"));
}
},
DEFAULT("default") {
@Override
public void addStoreOptions(List<String> commands) {
//nop
}
};
public static final String AUTH_SERVER_QUARKUS_MAP_STORAGE_PROFILE = "auth.server.quarkus.mapStorage.profile.config";
public static final String DB_VENDOR_PROPERTY = "keycloak.storage.connections.vendor";
private final String alias;
public abstract void addStoreOptions(List<String> commands);
StoreProvider(String alias) {
this.alias = alias;
}
public String getAlias() {
return alias;
}
public boolean isLegacyStore() {
return this.equals(LEGACY);
}
public boolean isMapStore() {
return !isLegacyStore() && !this.equals(DEFAULT);
}
public static Optional<String> getDbVendor() {
return Optional.ofNullable(System.getProperty(DB_VENDOR_PROPERTY)).filter(StringUtil::isNotBlank);
}
public static StoreProvider getCurrentProvider() {
return getProviderByAlias(System.getProperty(AUTH_SERVER_QUARKUS_MAP_STORAGE_PROFILE, ""));
}
/**
* Get Store Provider by alias
*
* @param alias alias
* @return store provider, LEGACY when vendor is specified, otherwise DEFAULT
*/
public static StoreProvider getProviderByAlias(String alias) {
return Arrays.stream(StoreProvider.values())
.filter(f -> f.getAlias().equals(alias))
.findFirst()
.orElseGet(() -> getDbVendor().isEmpty() ? DEFAULT : LEGACY);
}
}

View file

@ -656,9 +656,13 @@
<container qualifier="auth-server-quarkus" mode="manual" >
<configuration>
<property name="enabled">${auth.server.quarkus}</property>
<property name="adapterImplClass">org.keycloak.testsuite.arquillian.containers.KeycloakQuarkusServerDeployableContainer</property>
<property name="adapterImplClass">
org.keycloak.testsuite.arquillian.containers.KeycloakQuarkusServerDeployableContainer
</property>
<property name="bindHttpPortOffset">${auth.server.port.offset}</property>
<property name="javaOpts">-Xms512m -Xmx512m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=512m -Djava.net.preferIPv4Stack=true</property>
<property name="javaOpts">-Xms512m -Xmx512m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=512m
-Djava.net.preferIPv4Stack=true -Dauth.server.db.host=some
</property>
</configuration>
</container>

View file

@ -57,6 +57,7 @@
<auth.server.home>${containers.home}/${auth.server.container}</auth.server.home>
<auth.server.config.dir>${auth.server.home}</auth.server.config.dir>
<auth.server.db.host>${docker.container.testdb.ip}</auth.server.db.host>
<auth.server.host>localhost</auth.server.host>
<auth.server.management.host>${auth.server.host}</auth.server.management.host>
<auth.server.browserHost/> <!-- if set, this host will be used by the browser instead of auth.server.host -->
@ -688,6 +689,7 @@
<!-- used by PasswordPolicyTest.testBlacklistPasswordPolicyWithTestBlacklist, see KEYCLOAK-5244 -->
<keycloak.password.blacklists.path>${project.build.directory}/dependency/password-blacklists</keycloak.password.blacklists.path>
<keycloak.storage.connections.vendor>${keycloak.storage.connections.vendor}</keycloak.storage.connections.vendor>
<keycloak.connectionsJpa.driver>${keycloak.connectionsJpa.driver}</keycloak.connectionsJpa.driver>
<keycloak.connectionsJpa.url>${keycloak.connectionsJpa.url}</keycloak.connectionsJpa.url>
<keycloak.connectionsJpa.database>${keycloak.connectionsJpa.database}</keycloak.connectionsJpa.database>