Test suites config for the new test framework (#41318)

Closes #41316

Signed-off-by: stianst <stianst@gmail.com>
This commit is contained in:
Stian Thorgersen
2025-07-23 09:23:16 +02:00
committed by GitHub
parent 50a5d9afe6
commit bd676ea845
8 changed files with 219 additions and 3 deletions

View File

@@ -30,6 +30,18 @@ public class Config {
return config.getOptionalValue("kc.test." + valueTypeAlias.getAlias(valueType), String.class).orElse(null);
}
public static String getIncludedSuppliers(Class<?> valueType) {
return config.getOptionalValue("kc.test." + valueTypeAlias.getAlias(valueType) + ".suppliers.included", String.class).orElse(null);
}
public static String getExcludedSuppliers(Class<?> valueType) {
return config.getOptionalValue("kc.test." + valueTypeAlias.getAlias(valueType) + ".suppliers.excluded", String.class).orElse(null);
}
public static String getSupplierConfig(Class<?> valueType) {
return config.getOptionalValue("kc.test." + valueTypeAlias.getAlias(valueType) + ".config", String.class).orElse(null);
}
public static <T> T getValueTypeConfig(Class<?> valueType, String name, String defaultValue, Class<T> type) {
name = getValueTypeFQN(valueType, name);
Optional<T> optionalValue = config.getOptionalValue(name, type);
@@ -80,7 +92,8 @@ public class Config {
.addDefaultSources()
.addDefaultInterceptors()
.withConverters(new Converter[]{ new CharsetConverter(), new MemorySizeConverter(), new InetSocketAddressConverter() })
.withInterceptors(new LogConfigInterceptor());
.withInterceptors(new LogConfigInterceptor())
.withSources(new SuiteConfigSource());
ConfigSource testEnvConfigSource = initTestEnvConfigSource();
if (testEnvConfigSource != null) {

View File

@@ -0,0 +1,40 @@
package org.keycloak.testframework.config;
import org.eclipse.microprofile.config.spi.ConfigSource;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class SuiteConfigSource implements ConfigSource {
private static final Map<String, String> SUITE_CONFIG = new HashMap<>();
public static void set(String key, String value) {
SUITE_CONFIG.put(key, value);
}
public static void clear() {
SUITE_CONFIG.clear();
}
@Override
public Set<String> getPropertyNames() {
return SUITE_CONFIG.keySet();
}
@Override
public String getValue(String s) {
return SUITE_CONFIG.get(s);
}
@Override
public String getName() {
return "SuiteConfigSource";
}
@Override
public int getOrdinal() {
return 270;
}
}

View File

@@ -6,6 +6,7 @@ import org.keycloak.testframework.config.Config;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
@@ -71,7 +72,7 @@ public class Extensions {
for (var supplier : extension.suppliers()) {
Class<?> valueType = supplier.getValueType();
String requestedSupplier = Config.getSelectedSupplier(valueType);
if (supplier.getAlias().equals(requestedSupplier) || (requestedSupplier == null && !loadedValueTypes.contains(valueType))) {
if (isSupplierIncluded(supplier) && (supplier.getAlias().equals(requestedSupplier) || (requestedSupplier == null && !loadedValueTypes.contains(valueType)))) {
configureSupplier(supplier);
suppliers.add(supplier);
loadedValueTypes.add(valueType);
@@ -86,6 +87,22 @@ public class Extensions {
return suppliers;
}
private boolean isSupplierIncluded(Supplier<?, ?> supplier) {
String includedSuppliers = Config.getIncludedSuppliers(supplier.getValueType());
if (includedSuppliers != null) {
if (Arrays.stream(includedSuppliers.split(",")).noneMatch(s -> s.equals(supplier.getAlias()))) {
return false;
}
}
String excludedSuppliers = Config.getExcludedSuppliers(supplier.getValueType());
if (excludedSuppliers != null) {
return Arrays.stream(excludedSuppliers.split(",")).noneMatch(s -> s.equals(supplier.getAlias()));
}
return true;
}
private List<Class<?>> loadAlwaysEnabledValueTypes(List<TestFrameworkExtension> extensions) {
return extensions.stream().flatMap(s -> s.alwaysEnabledValueTypes().stream()).toList();
}

View File

@@ -0,0 +1,45 @@
package org.keycloak.testframework.injection;
import org.keycloak.testframework.config.Config;
import org.keycloak.testframework.config.SuiteConfigSource;
import org.keycloak.testframework.server.KeycloakServerConfig;
public class SuiteSupport {
private static SuiteConfig suiteConfig = new SuiteConfig();
public static SuiteConfig startSuite() {
return suiteConfig;
}
public static void stopSuite() {
SuiteConfigSource.clear();
Config.initConfig();
suiteConfig = null;
}
public static class SuiteConfig {
public SuiteConfig registerServerConfig(Class<? extends KeycloakServerConfig> serverConfig) {
SuiteConfigSource.set("kc.test.server.config", serverConfig.getName());
return this;
}
public SuiteConfig supplier(String name, String supplier) {
SuiteConfigSource.set("kc.test." + name, supplier);
return this;
}
public SuiteConfig includedSuppliers(String name, String... suppliers) {
SuiteConfigSource.set("kc.test." + name + ".suppliers.included", String.join(",", suppliers));
return this;
}
public SuiteConfig excludedSuppliers(String name, String... suppliers) {
SuiteConfigSource.set("kc.test." + name + ".suppliers.excluded", String.join(",", suppliers));
return this;
}
}
}

View File

@@ -16,6 +16,18 @@ public class SupplierHelpers {
}
}
@SuppressWarnings("unchecked")
public static <T> T getInstance(String clazzName) {
try {
Class<T> clazz = (Class<T>) SupplierHelpers.class.getClassLoader().loadClass(clazzName);
Constructor<T> declaredConstructor = clazz.getDeclaredConstructor();
declaredConstructor.setAccessible(true);
return declaredConstructor.newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static <T> T getAnnotationField(Annotation annotation, String name, T defaultValue) {
T value = getAnnotationField(annotation, name);
return value != null ? value : defaultValue;

View File

@@ -1,10 +1,10 @@
package org.keycloak.testframework.server;
import org.jboss.logging.Logger;
import org.keycloak.testframework.injection.AbstractInterceptorHelper;
import org.keycloak.testframework.annotations.KeycloakIntegrationTest;
import org.keycloak.testframework.config.Config;
import org.keycloak.testframework.database.TestDatabase;
import org.keycloak.testframework.injection.AbstractInterceptorHelper;
import org.keycloak.testframework.injection.InstanceContext;
import org.keycloak.testframework.injection.LifeCycle;
import org.keycloak.testframework.injection.Registry;
@@ -27,6 +27,12 @@ public abstract class AbstractKeycloakServerSupplier implements Supplier<Keycloa
command.log().handlers(KeycloakServerConfigBuilder.LogHandlers.CONSOLE);
String supplierConfig = Config.getSupplierConfig(KeycloakServer.class);
if (supplierConfig != null) {
KeycloakServerConfig serverConfigOverride = SupplierHelpers.getInstance(supplierConfig);
serverConfigOverride.configure(command);
}
command = serverConfig.configure(command);
if (requiresDatabase()) {