diff --git a/pom.xml b/pom.xml
index a9c74b39289..a760e4aa023 100644
--- a/pom.xml
+++ b/pom.xml
@@ -172,6 +172,9 @@
23.6.0.24.10
+
+ quay.io/infinispan/server:${infinispan.version}
+
2.1.3
2.10
diff --git a/quarkus/tests/integration/pom.xml b/quarkus/tests/integration/pom.xml
index 96396249310..10b6d0fb330 100644
--- a/quarkus/tests/integration/pom.xml
+++ b/quarkus/tests/integration/pom.xml
@@ -188,7 +188,7 @@
${postgresql.container}
${mariadb.container}
${mysql.container}
- quay.io/infinispan/server:${infinispan.version}
+ ${infinispan.container}
${mssql.container}
${tidb.container}
diff --git a/test-framework/LOGGING.md b/test-framework/LOGGING.md
index 3390ceb75fe..1bc2ee60efb 100644
--- a/test-framework/LOGGING.md
+++ b/test-framework/LOGGING.md
@@ -42,7 +42,8 @@ Some useful categories include:
* `org.keycloak.testframework` - Logging from the test framework itself. Setting this to `DEBUG` can be helpful to debug any issues with the test framework itself, or custom suppliers.
* `org.keycloak` - Logging from the Keycloak server. If you set this to `DEBUG` for example, but don't want debug from the test framework, also explicitly set `org.keycloak.testframework` to for example `INFO`
* `managed.keycloak` - Log output from the managed Keycloak server if you are running the server in `distribution` mode (which is the default)
-* `managed.db` - Output from database containers are included in this category. Standard out is logged with `DEBUG` level, while standard error is logged with `WARN` level
+* `managed.db` - Output from database containers are included in this category. Standard out is logged with `DEBUG` level, while standard error is logged with `WARN` level
+* `managed.infinispan` - Output from the external Infinispan container is included in this category. Standard out is logged with `DEBUG` level, while standard error is logged with `WARN` level
### Enable log filtering
@@ -70,6 +71,7 @@ kc.test.log.category."org.keycloak.testframework".level=INFO
kc.test.log.category."org.keycloak".level=WARN
kc.test.log.category."managed.keycloak".level=WARN
kc.test.log.category."managed.db".level=WARN
+kc.test.log.category."managed.infinispan".level=WARN
```
This should serve as a good starting point balancing the need of log information with not producing too much noise.
@@ -89,6 +91,7 @@ KC_TEST_LOG_CATEGORY__ORG_KEYCLOAK___LEVEL=DEBUG
KC_TEST_LOG_CATEGORY__ORG_KEYCLOAK_TEST__LEVEL=DEBUG
KC_TEST_LOG_CATEGORY__MANAGED_KEYCLOAK__LEVEL=DEBUG
KC_TEST_LOG_CATEGORY__MANAGED_DB__LEVEL=DEBUG
+KC_TEST_LOG_CATEGORY__MANAGED_INFINISPAN__LEVEL=DEBUG
```
### Examples using environment variables
diff --git a/test-framework/clustering/src/main/java/org/keycloak/testframework/server/ClusteredKeycloakServer.java b/test-framework/clustering/src/main/java/org/keycloak/testframework/server/ClusteredKeycloakServer.java
index 2cd50ad63b0..c3af53d1f14 100644
--- a/test-framework/clustering/src/main/java/org/keycloak/testframework/server/ClusteredKeycloakServer.java
+++ b/test-framework/clustering/src/main/java/org/keycloak/testframework/server/ClusteredKeycloakServer.java
@@ -26,6 +26,7 @@ import org.infinispan.server.test.core.CountdownLatchLoggingConsumer;
import org.jboss.logging.Logger;
import org.keycloak.it.utils.DockerKeycloakDistribution;
import org.keycloak.testframework.clustering.LoadBalancer;
+import org.keycloak.testframework.infinispan.CacheType;
import org.keycloak.testframework.logging.JBossLogConsumer;
import org.testcontainers.images.RemoteDockerImage;
import org.testcontainers.utility.DockerImageName;
@@ -56,6 +57,10 @@ public class ClusteredKeycloakServer implements KeycloakServer {
int numServers = containers.length;
CountdownLatchLoggingConsumer clusterLatch = new CountdownLatchLoggingConsumer(numServers, String.format(CLUSTER_VIEW_REGEX, numServers));
String[] imagePeServer = null;
+
+ // Infinispan clustered cache
+ configBuilder.cache(CacheType.ISPN);
+
if (images == null || images.isEmpty() || (imagePeServer = images.split(",")).length == 1) {
startContainersWithSameImage(configBuilder, imagePeServer == null ? SNAPSHOT_IMAGE : imagePeServer[0], clusterLatch);
} else {
diff --git a/test-framework/clustering/src/main/java/org/keycloak/testframework/server/ClusteredKeycloakServerSupplier.java b/test-framework/clustering/src/main/java/org/keycloak/testframework/server/ClusteredKeycloakServerSupplier.java
index 34f558ef7ee..6401cac049b 100644
--- a/test-framework/clustering/src/main/java/org/keycloak/testframework/server/ClusteredKeycloakServerSupplier.java
+++ b/test-framework/clustering/src/main/java/org/keycloak/testframework/server/ClusteredKeycloakServerSupplier.java
@@ -32,9 +32,4 @@ public class ClusteredKeycloakServerSupplier extends AbstractKeycloakServerSuppl
public Logger getLogger() {
return LOGGER;
}
-
- @Override
- protected String cache() {
- return "ispn";
- }
}
diff --git a/test-framework/core/src/main/java/org/keycloak/testframework/CoreTestFrameworkExtension.java b/test-framework/core/src/main/java/org/keycloak/testframework/CoreTestFrameworkExtension.java
index 553e0ed0137..b1d40b5e1e5 100644
--- a/test-framework/core/src/main/java/org/keycloak/testframework/CoreTestFrameworkExtension.java
+++ b/test-framework/core/src/main/java/org/keycloak/testframework/CoreTestFrameworkExtension.java
@@ -2,6 +2,7 @@ package org.keycloak.testframework;
import org.keycloak.testframework.admin.AdminClientFactorySupplier;
import org.keycloak.testframework.admin.AdminClientSupplier;
+import org.keycloak.testframework.infinispan.InfinispanExternalServerSupplier;
import org.keycloak.testframework.database.DevFileDatabaseSupplier;
import org.keycloak.testframework.database.DevMemDatabaseSupplier;
import org.keycloak.testframework.database.TestDatabase;
@@ -43,7 +44,8 @@ public class CoreTestFrameworkExtension implements TestFrameworkExtension {
new EventsSupplier(),
new AdminEventsSupplier(),
new HttpClientSupplier(),
- new HttpServerSupplier()
+ new HttpServerSupplier(),
+ new InfinispanExternalServerSupplier()
);
}
diff --git a/test-framework/core/src/main/java/org/keycloak/testframework/annotations/InjectInfinispanServer.java b/test-framework/core/src/main/java/org/keycloak/testframework/annotations/InjectInfinispanServer.java
new file mode 100644
index 00000000000..e1cc029173c
--- /dev/null
+++ b/test-framework/core/src/main/java/org/keycloak/testframework/annotations/InjectInfinispanServer.java
@@ -0,0 +1,15 @@
+package org.keycloak.testframework.annotations;
+
+import org.keycloak.testframework.injection.LifeCycle;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface InjectInfinispanServer {
+
+ LifeCycle lifecycle() default LifeCycle.GLOBAL;
+}
diff --git a/test-framework/core/src/main/java/org/keycloak/testframework/database/DatabaseProperties.java b/test-framework/core/src/main/java/org/keycloak/testframework/database/DatabaseProperties.java
deleted file mode 100644
index 1e431bada6a..00000000000
--- a/test-framework/core/src/main/java/org/keycloak/testframework/database/DatabaseProperties.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package org.keycloak.testframework.database;
-
-import java.io.IOException;
-import java.util.Properties;
-
-public class DatabaseProperties {
-
- private static final Properties PROPERTIES = loadProperties();
-
- public static String getContainerImageName(String database) {
- return PROPERTIES.getProperty(database + ".container");
- }
-
- private static Properties loadProperties() {
- Properties properties = new Properties();
- try {
- properties.load(DatabaseProperties.class.getResourceAsStream("database.properties"));
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- return properties;
- }
-
-}
diff --git a/test-framework/core/src/main/java/org/keycloak/testframework/infinispan/CacheType.java b/test-framework/core/src/main/java/org/keycloak/testframework/infinispan/CacheType.java
new file mode 100644
index 00000000000..e9de8ea4419
--- /dev/null
+++ b/test-framework/core/src/main/java/org/keycloak/testframework/infinispan/CacheType.java
@@ -0,0 +1,10 @@
+package org.keycloak.testframework.infinispan;
+
+public enum CacheType {
+
+ // Local Infinispan Cache for Embedded Deployment only
+ LOCAL,
+
+ // Clustered Infinispan Cache can be set for Embedded or External Deployment
+ ISPN;
+}
diff --git a/test-framework/core/src/main/java/org/keycloak/testframework/infinispan/InfinispanExternalServer.java b/test-framework/core/src/main/java/org/keycloak/testframework/infinispan/InfinispanExternalServer.java
new file mode 100644
index 00000000000..a581e08f4bf
--- /dev/null
+++ b/test-framework/core/src/main/java/org/keycloak/testframework/infinispan/InfinispanExternalServer.java
@@ -0,0 +1,42 @@
+package org.keycloak.testframework.infinispan;
+
+import java.util.Map;
+
+import org.infinispan.server.test.core.InfinispanContainer;
+import org.jboss.logging.Logger;
+import org.keycloak.testframework.logging.JBossLogConsumer;
+import org.keycloak.testframework.util.ContainerImages;
+
+public class InfinispanExternalServer extends InfinispanContainer implements InfinispanServer {
+
+ private static final String USER = "keycloak";
+ private static final String PASSWORD = "Password1!";
+ private static final String HOST = "127.0.0.1";
+
+ public static InfinispanExternalServer create() {
+ return new InfinispanExternalServer(ContainerImages.getContainerImageName("infinispan"));
+ }
+
+ @SuppressWarnings("resource")
+ private InfinispanExternalServer(String dockerImageName) {
+ super(dockerImageName);
+ withUser(USER);
+ withPassword(PASSWORD);
+ withLogConsumer(new JBossLogConsumer(Logger.getLogger("managed.infinispan")));
+ addFixedExposedPort(11222, 11222);
+ }
+
+ @Override
+ public Map serverConfig() {
+ return Map.of(
+ "cache-remote-host", HOST,
+ "cache-remote-username", USER,
+ "cache-remote-password", PASSWORD,
+ "cache-remote-tls-enabled", "false",
+ "spi-cache-embedded-default-site-name", "ispn",
+ "spi-load-balancer-check-remote-poll-interval", "500",
+ "spi-cache-remote-default-client-intelligence", "BASIC",
+ "-Dkc.cache-remote-create-caches", "true"
+ );
+ }
+}
diff --git a/test-framework/core/src/main/java/org/keycloak/testframework/infinispan/InfinispanExternalServerSupplier.java b/test-framework/core/src/main/java/org/keycloak/testframework/infinispan/InfinispanExternalServerSupplier.java
new file mode 100644
index 00000000000..b3b3cf27c29
--- /dev/null
+++ b/test-framework/core/src/main/java/org/keycloak/testframework/infinispan/InfinispanExternalServerSupplier.java
@@ -0,0 +1,54 @@
+package org.keycloak.testframework.infinispan;
+
+import org.jboss.logging.Logger;
+import org.keycloak.testframework.annotations.InjectInfinispanServer;
+import org.keycloak.testframework.injection.InstanceContext;
+import org.keycloak.testframework.injection.RequestedInstance;
+import org.keycloak.testframework.injection.Supplier;
+import org.keycloak.testframework.injection.SupplierOrder;
+import org.keycloak.testframework.server.KeycloakServerConfigBuilder;
+import org.keycloak.testframework.server.KeycloakServerConfigInterceptor;
+
+public class InfinispanExternalServerSupplier implements Supplier, KeycloakServerConfigInterceptor {
+
+ private static final Logger LOGGER = Logger.getLogger(InfinispanExternalServerSupplier.class);
+
+ @Override
+ public InfinispanServer getValue(InstanceContext instanceContext) {
+ InfinispanServer server = InfinispanExternalServer.create();
+ getLogger().info("Starting Infinispan Server");
+
+ long start = System.currentTimeMillis();
+
+ server.start();
+
+ getLogger().infov("Infinispan server started in {0} ms", System.currentTimeMillis() - start);
+ return server;
+ }
+
+ @Override
+ public void close(InstanceContext instanceContext) {
+ instanceContext.getValue().stop();
+ }
+
+ @Override
+ public boolean compatible(InstanceContext a, RequestedInstance b) {
+ return a.getSupplier().getRef(a.getAnnotation()).equals(b.getSupplier().getRef(a.getAnnotation()));
+ }
+
+ @Override
+ public int order() {
+ return SupplierOrder.BEFORE_KEYCLOAK_SERVER;
+ }
+
+ @Override
+ public KeycloakServerConfigBuilder intercept(KeycloakServerConfigBuilder config, InstanceContext instanceContext) {
+ InfinispanServer ispnServer = instanceContext.getValue();
+
+ return config.options(ispnServer.serverConfig());
+ }
+
+ public Logger getLogger() {
+ return LOGGER;
+ }
+}
diff --git a/test-framework/core/src/main/java/org/keycloak/testframework/infinispan/InfinispanServer.java b/test-framework/core/src/main/java/org/keycloak/testframework/infinispan/InfinispanServer.java
new file mode 100644
index 00000000000..d951867735f
--- /dev/null
+++ b/test-framework/core/src/main/java/org/keycloak/testframework/infinispan/InfinispanServer.java
@@ -0,0 +1,12 @@
+package org.keycloak.testframework.infinispan;
+
+import java.util.Map;
+
+public interface InfinispanServer {
+
+ void start();
+
+ void stop();
+
+ Map serverConfig();
+}
diff --git a/test-framework/core/src/main/java/org/keycloak/testframework/server/AbstractKeycloakServerSupplier.java b/test-framework/core/src/main/java/org/keycloak/testframework/server/AbstractKeycloakServerSupplier.java
index af52c60ed52..1371508a769 100644
--- a/test-framework/core/src/main/java/org/keycloak/testframework/server/AbstractKeycloakServerSupplier.java
+++ b/test-framework/core/src/main/java/org/keycloak/testframework/server/AbstractKeycloakServerSupplier.java
@@ -2,6 +2,7 @@ package org.keycloak.testframework.server;
import org.jboss.logging.Logger;
import org.keycloak.testframework.annotations.KeycloakIntegrationTest;
+import org.keycloak.testframework.infinispan.InfinispanServer;
import org.keycloak.testframework.config.Config;
import org.keycloak.testframework.database.TestDatabase;
import org.keycloak.testframework.injection.AbstractInterceptorHelper;
@@ -21,7 +22,6 @@ public abstract class AbstractKeycloakServerSupplier implements Supplier dependencies = new HashSet<>();
private final Set configFiles = new HashSet<>();
+ private CacheType cacheType = CacheType.LOCAL;
+ private boolean externalInfinispan = false;
private KeycloakServerConfigBuilder(String command) {
this.command = command;
@@ -48,8 +50,24 @@ public class KeycloakServerConfigBuilder {
.option("bootstrap-admin-password", password);
}
- public KeycloakServerConfigBuilder cache(String cache) {
- return option("cache", cache);
+ public KeycloakServerConfigBuilder cache(CacheType cacheType) {
+ this.cacheType = cacheType;
+ return this;
+ }
+
+ public KeycloakServerConfigBuilder externalInfinispanEnabled(boolean enabled) {
+ if (enabled) {
+ this.externalInfinispan = true;
+ cache(CacheType.ISPN);
+ } else {
+ this.externalInfinispan = false;
+ cache(CacheType.LOCAL);
+ }
+ return this;
+ }
+
+ public boolean isExternalInfinispanEnabled() {
+ return this.externalInfinispan;
}
public LogBuilder log() {
@@ -185,12 +203,19 @@ public class KeycloakServerConfigBuilder {
}
List toArgs() {
+ // Cache setup -> supported values: local or ispn
+ option("cache", cacheType.name().toLowerCase());
+
log.build();
List args = new LinkedList<>();
args.add(command);
for (Map.Entry e : options.entrySet()) {
- args.add("--" + e.getKey() + "=" + e.getValue());
+ if (e.getKey().startsWith("-D")) {
+ args.add(e.getKey() + "=" + e.getValue());
+ } else {
+ args.add("--" + e.getKey() + "=" + e.getValue());
+ }
}
if (!features.isEmpty()) {
args.add("--features=" + String.join(",", features));
diff --git a/test-framework/core/src/main/java/org/keycloak/testframework/util/ContainerImages.java b/test-framework/core/src/main/java/org/keycloak/testframework/util/ContainerImages.java
new file mode 100644
index 00000000000..8eef83c97a0
--- /dev/null
+++ b/test-framework/core/src/main/java/org/keycloak/testframework/util/ContainerImages.java
@@ -0,0 +1,21 @@
+package org.keycloak.testframework.util;
+
+import java.io.IOException;
+import java.util.Properties;
+
+public class ContainerImages {
+
+ public static String getContainerImageName(String containerName) {
+ return loadProperties().getProperty(containerName + ".container");
+ }
+
+ private static Properties loadProperties() {
+ Properties properties = new Properties();
+ try {
+ properties.load(ContainerImages.class.getResourceAsStream("containers.properties"));
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ return properties;
+ }
+}
diff --git a/test-framework/core/src/main/resources/org/keycloak/testframework/database/database.properties b/test-framework/core/src/main/resources/org/keycloak/testframework/util/containers.properties
similarity index 59%
rename from test-framework/core/src/main/resources/org/keycloak/testframework/database/database.properties
rename to test-framework/core/src/main/resources/org/keycloak/testframework/util/containers.properties
index 5f4c7864e8e..3a4fe08d4f0 100644
--- a/test-framework/core/src/main/resources/org/keycloak/testframework/database/database.properties
+++ b/test-framework/core/src/main/resources/org/keycloak/testframework/util/containers.properties
@@ -1,6 +1,10 @@
+## Database containers ##
mysql.container=${mysql.container}
postgres.container=${postgresql.container}
mariadb.container=${mariadb.container}
mssql.container=${mssql.container}
oracle.container=${oracledb.container}
-tidb.container=${tidb.container}
\ No newline at end of file
+tidb.container=${tidb.container}
+
+## Infinispan container ##
+infinispan.container=${infinispan.container}
\ No newline at end of file
diff --git a/test-framework/db-mariadb/src/main/java/org/keycloak/testframework/database/MariaDBTestDatabase.java b/test-framework/db-mariadb/src/main/java/org/keycloak/testframework/database/MariaDBTestDatabase.java
index 481131d4a64..3e547e7c973 100644
--- a/test-framework/db-mariadb/src/main/java/org/keycloak/testframework/database/MariaDBTestDatabase.java
+++ b/test-framework/db-mariadb/src/main/java/org/keycloak/testframework/database/MariaDBTestDatabase.java
@@ -1,6 +1,7 @@
package org.keycloak.testframework.database;
import org.jboss.logging.Logger;
+import org.keycloak.testframework.util.ContainerImages;
import org.testcontainers.containers.JdbcDatabaseContainer;
import org.testcontainers.containers.MariaDBContainer;
import org.testcontainers.utility.DockerImageName;
@@ -13,7 +14,7 @@ class MariaDBTestDatabase extends AbstractContainerTestDatabase {
@Override
public JdbcDatabaseContainer> createContainer() {
- return new MariaDBContainer<>(DockerImageName.parse(DatabaseProperties.getContainerImageName(NAME)).asCompatibleSubstituteFor(NAME)).withCommand("--character-set-server=utf8 --collation-server=utf8_unicode_ci");
+ return new MariaDBContainer<>(DockerImageName.parse(ContainerImages.getContainerImageName(NAME)).asCompatibleSubstituteFor(NAME)).withCommand("--character-set-server=utf8 --collation-server=utf8_unicode_ci");
}
@Override
diff --git a/test-framework/db-mssql/src/main/java/org/keycloak/testframework/database/MSSQLServerTestDatabase.java b/test-framework/db-mssql/src/main/java/org/keycloak/testframework/database/MSSQLServerTestDatabase.java
index 97e86679ad1..466432bcd4a 100644
--- a/test-framework/db-mssql/src/main/java/org/keycloak/testframework/database/MSSQLServerTestDatabase.java
+++ b/test-framework/db-mssql/src/main/java/org/keycloak/testframework/database/MSSQLServerTestDatabase.java
@@ -1,8 +1,10 @@
package org.keycloak.testframework.database;
import org.jboss.logging.Logger;
+import org.keycloak.testframework.util.ContainerImages;
import org.testcontainers.containers.JdbcDatabaseContainer;
import org.testcontainers.containers.MSSQLServerContainer;
+import org.testcontainers.utility.DockerImageName;
import java.util.List;
@@ -15,7 +17,7 @@ class MSSQLServerTestDatabase extends AbstractContainerTestDatabase {
@SuppressWarnings("resource")
@Override
public JdbcDatabaseContainer> createContainer() {
- return new MSSQLServerContainer<>(DatabaseProperties.getContainerImageName(NAME)).withPassword(getPassword()).withEnv("MSSQL_PID", "Express").acceptLicense();
+ return new MSSQLServerContainer<>(DockerImageName.parse(ContainerImages.getContainerImageName(NAME))).withPassword(getPassword()).withEnv("MSSQL_PID", "Express").acceptLicense();
}
@Override
diff --git a/test-framework/db-mysql/src/main/java/org/keycloak/testframework/database/MySQLTestDatabase.java b/test-framework/db-mysql/src/main/java/org/keycloak/testframework/database/MySQLTestDatabase.java
index 2402d8f4c8e..69fe65de382 100644
--- a/test-framework/db-mysql/src/main/java/org/keycloak/testframework/database/MySQLTestDatabase.java
+++ b/test-framework/db-mysql/src/main/java/org/keycloak/testframework/database/MySQLTestDatabase.java
@@ -1,6 +1,7 @@
package org.keycloak.testframework.database;
import org.jboss.logging.Logger;
+import org.keycloak.testframework.util.ContainerImages;
import org.testcontainers.containers.JdbcDatabaseContainer;
import org.testcontainers.containers.MySQLContainer;
import org.testcontainers.utility.DockerImageName;
@@ -13,7 +14,7 @@ class MySQLTestDatabase extends AbstractContainerTestDatabase {
@Override
public JdbcDatabaseContainer> createContainer() {
- return new MySQLContainer<>(DockerImageName.parse(DatabaseProperties.getContainerImageName(NAME)).asCompatibleSubstituteFor(NAME));
+ return new MySQLContainer<>(DockerImageName.parse(ContainerImages.getContainerImageName(NAME)).asCompatibleSubstituteFor(NAME));
}
@Override
diff --git a/test-framework/db-oracle/src/main/java/org/keycloak/testframework/database/OracleTestDatabase.java b/test-framework/db-oracle/src/main/java/org/keycloak/testframework/database/OracleTestDatabase.java
index 53a2b91a3ea..2e379b4009d 100644
--- a/test-framework/db-oracle/src/main/java/org/keycloak/testframework/database/OracleTestDatabase.java
+++ b/test-framework/db-oracle/src/main/java/org/keycloak/testframework/database/OracleTestDatabase.java
@@ -1,6 +1,7 @@
package org.keycloak.testframework.database;
import org.jboss.logging.Logger;
+import org.keycloak.testframework.util.ContainerImages;
import org.testcontainers.containers.JdbcDatabaseContainer;
import org.testcontainers.oracle.OracleContainer;
import org.testcontainers.utility.DockerImageName;
@@ -13,7 +14,7 @@ class OracleTestDatabase extends AbstractContainerTestDatabase {
@Override
public JdbcDatabaseContainer> createContainer() {
- return new OracleContainer(DockerImageName.parse(DatabaseProperties.getContainerImageName(NAME)).asCompatibleSubstituteFor("gvenzl/oracle-free"));
+ return new OracleContainer(DockerImageName.parse(ContainerImages.getContainerImageName(NAME)).asCompatibleSubstituteFor("gvenzl/oracle-free"));
}
@Override
diff --git a/test-framework/db-postgres/src/main/java/org/keycloak/testframework/database/PostgresTestDatabase.java b/test-framework/db-postgres/src/main/java/org/keycloak/testframework/database/PostgresTestDatabase.java
index 6368f00e68a..bf7eeb259c0 100644
--- a/test-framework/db-postgres/src/main/java/org/keycloak/testframework/database/PostgresTestDatabase.java
+++ b/test-framework/db-postgres/src/main/java/org/keycloak/testframework/database/PostgresTestDatabase.java
@@ -1,6 +1,7 @@
package org.keycloak.testframework.database;
import org.jboss.logging.Logger;
+import org.keycloak.testframework.util.ContainerImages;
import org.testcontainers.containers.JdbcDatabaseContainer;
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.utility.DockerImageName;
@@ -15,7 +16,7 @@ public class PostgresTestDatabase extends AbstractContainerTestDatabase {
@Override
public JdbcDatabaseContainer> createContainer() {
- return new PostgreSQLContainer<>(DockerImageName.parse(DatabaseProperties.getContainerImageName(NAME)).asCompatibleSubstituteFor(NAME));
+ return new PostgreSQLContainer<>(DockerImageName.parse(ContainerImages.getContainerImageName(NAME)).asCompatibleSubstituteFor(NAME));
}
@Override
diff --git a/test-framework/db-tidb/src/main/java/org/keycloak/testframework/database/TiDBTestDatabase.java b/test-framework/db-tidb/src/main/java/org/keycloak/testframework/database/TiDBTestDatabase.java
index 4a760276d8c..537a316e6ab 100644
--- a/test-framework/db-tidb/src/main/java/org/keycloak/testframework/database/TiDBTestDatabase.java
+++ b/test-framework/db-tidb/src/main/java/org/keycloak/testframework/database/TiDBTestDatabase.java
@@ -2,6 +2,7 @@ package org.keycloak.testframework.database;
import org.apache.commons.lang3.StringUtils;
import org.jboss.logging.Logger;
+import org.keycloak.testframework.util.ContainerImages;
import org.testcontainers.containers.JdbcDatabaseContainer;
import org.testcontainers.tidb.TiDBContainer;
import org.testcontainers.utility.DockerImageName;
@@ -14,7 +15,7 @@ class TiDBTestDatabase extends AbstractContainerTestDatabase {
@Override
public JdbcDatabaseContainer> createContainer() {
- return new TiDBContainer(DockerImageName.parse(DatabaseProperties.getContainerImageName(NAME)).asCompatibleSubstituteFor("pingcap/tidb")){
+ return new TiDBContainer(DockerImageName.parse(ContainerImages.getContainerImageName(NAME)).asCompatibleSubstituteFor("pingcap/tidb")){
@Override
public TiDBContainer withDatabaseName(String databaseName) {
if(StringUtils.equals(this.getDatabaseName(), databaseName)) {
diff --git a/tests/base/src/test/java/org/keycloak/tests/suites/ClusterlessTestSuite.java b/tests/base/src/test/java/org/keycloak/tests/suites/ClusterlessTestSuite.java
new file mode 100644
index 00000000000..62c20a3f921
--- /dev/null
+++ b/tests/base/src/test/java/org/keycloak/tests/suites/ClusterlessTestSuite.java
@@ -0,0 +1,37 @@
+package org.keycloak.tests.suites;
+
+import org.junit.platform.suite.api.AfterSuite;
+import org.junit.platform.suite.api.BeforeSuite;
+import org.junit.platform.suite.api.SelectClasses;
+import org.junit.platform.suite.api.Suite;
+import org.keycloak.common.Profile;
+import org.keycloak.testframework.injection.SuiteSupport;
+import org.keycloak.testframework.server.KeycloakServerConfig;
+import org.keycloak.testframework.server.KeycloakServerConfigBuilder;
+import org.keycloak.tests.admin.ClientTest;
+
+@Suite
+@SelectClasses({ClientTest.class})
+public class ClusterlessTestSuite {
+
+ @BeforeSuite
+ public static void beforeSuite() {
+ SuiteSupport.startSuite()
+ .registerServerConfig(ClusterlessServerConfig.class);
+ }
+
+ @AfterSuite
+ public static void afterSuite() {
+ SuiteSupport.stopSuite();
+ }
+
+ public static class ClusterlessServerConfig implements KeycloakServerConfig {
+
+ @Override
+ public KeycloakServerConfigBuilder configure(KeycloakServerConfigBuilder config) {
+ return config.features(Profile.Feature.CLUSTERLESS)
+ .featuresDisabled(Profile.Feature.PERSISTENT_USER_SESSIONS)
+ .externalInfinispanEnabled(true);
+ }
+ }
+}
diff --git a/tests/base/src/test/java/org/keycloak/tests/suites/MultisiteTestSuite.java b/tests/base/src/test/java/org/keycloak/tests/suites/MultisiteTestSuite.java
new file mode 100644
index 00000000000..208f6eee25a
--- /dev/null
+++ b/tests/base/src/test/java/org/keycloak/tests/suites/MultisiteTestSuite.java
@@ -0,0 +1,37 @@
+package org.keycloak.tests.suites;
+
+import org.junit.platform.suite.api.AfterSuite;
+import org.junit.platform.suite.api.BeforeSuite;
+import org.junit.platform.suite.api.SelectClasses;
+import org.junit.platform.suite.api.Suite;
+import org.keycloak.common.Profile;
+import org.keycloak.testframework.injection.SuiteSupport;
+import org.keycloak.testframework.server.KeycloakServerConfig;
+import org.keycloak.testframework.server.KeycloakServerConfigBuilder;
+import org.keycloak.tests.admin.ClientTest;
+
+@Suite
+@SelectClasses({ClientTest.class})
+public class MultisiteTestSuite {
+
+ @BeforeSuite
+ public static void beforeSuite() {
+ SuiteSupport.startSuite()
+ .registerServerConfig(MultisiteServerConfig.class);
+ }
+
+ @AfterSuite
+ public static void afterSuite() {
+ SuiteSupport.stopSuite();
+ }
+
+ public static class MultisiteServerConfig implements KeycloakServerConfig {
+
+ @Override
+ public KeycloakServerConfigBuilder configure(KeycloakServerConfigBuilder config) {
+ return config.features(Profile.Feature.MULTI_SITE)
+ .featuresDisabled(Profile.Feature.PERSISTENT_USER_SESSIONS)
+ .externalInfinispanEnabled(true);
+ }
+ }
+}
diff --git a/tests/base/src/test/resources/keycloak-test.properties b/tests/base/src/test/resources/keycloak-test.properties
index c2212af8fa9..507a939ea2f 100644
--- a/tests/base/src/test/resources/keycloak-test.properties
+++ b/tests/base/src/test/resources/keycloak-test.properties
@@ -7,4 +7,5 @@ kc.test.log.category."org.keycloak.tests".level=INFO
kc.test.log.category."testinfo".level=INFO
kc.test.log.category."org.keycloak".level=WARN
kc.test.log.category."managed.keycloak".level=WARN
-kc.test.log.category."managed.db".level=WARN
\ No newline at end of file
+kc.test.log.category."managed.db".level=WARN
+kc.test.log.category."managed.infinispan".level=WARN
diff --git a/tests/clustering/src/test/resources/keycloak-test.properties b/tests/clustering/src/test/resources/keycloak-test.properties
index db43aed9d3b..98ccdf3ac01 100644
--- a/tests/clustering/src/test/resources/keycloak-test.properties
+++ b/tests/clustering/src/test/resources/keycloak-test.properties
@@ -13,4 +13,5 @@ kc.test.log.category."org.keycloak.it".level=INFO
kc.test.log.category."org.keycloak".level=WARN
kc.test.log.category."managed.keycloak".level=WARN
kc.test.log.category."managed.db".level=WARN
+kc.test.log.category."managed.infinispan".level=WARN
kc.test.log.category."org.keycloak.testframework.clustering".level=WARN
\ No newline at end of file
diff --git a/testsuite/integration-arquillian/tests/base/pom.xml b/testsuite/integration-arquillian/tests/base/pom.xml
index 90324985ca1..8b5055c4c22 100644
--- a/testsuite/integration-arquillian/tests/base/pom.xml
+++ b/testsuite/integration-arquillian/tests/base/pom.xml
@@ -780,7 +780,7 @@
infinispan
- quay.io/infinispan/server:${infinispan.version}
+ ${infinispan.container}
11222:11222