Add support to intercept server and realm config to test framework (#35184)

Closes #35173

Signed-off-by: stianst <stianst@gmail.com>
This commit is contained in:
Stian Thorgersen
2024-11-21 15:13:58 +01:00
committed by GitHub
parent 0ea77e6480
commit ad313e0109
46 changed files with 588 additions and 342 deletions
@@ -12,11 +12,11 @@ import org.keycloak.test.framework.injection.Supplier;
import org.keycloak.test.framework.realm.ClientSupplier;
import org.keycloak.test.framework.realm.RealmSupplier;
import org.keycloak.test.framework.realm.UserSupplier;
import org.keycloak.test.framework.server.DistributionKeycloakTestServerSupplier;
import org.keycloak.test.framework.server.EmbeddedKeycloakTestServerSupplier;
import org.keycloak.test.framework.server.KeycloakTestServer;
import org.keycloak.test.framework.server.DistributionKeycloakServerSupplier;
import org.keycloak.test.framework.server.EmbeddedKeycloakServerSupplier;
import org.keycloak.test.framework.server.KeycloakServer;
import org.keycloak.test.framework.server.KeycloakUrlsSupplier;
import org.keycloak.test.framework.server.RemoteKeycloakTestServerSupplier;
import org.keycloak.test.framework.server.RemoteKeycloakServerSupplier;
import java.util.List;
import java.util.Map;
@@ -30,9 +30,9 @@ public class CoreTestFrameworkExtension implements TestFrameworkExtension {
new ClientSupplier(),
new RealmSupplier(),
new UserSupplier(),
new DistributionKeycloakTestServerSupplier(),
new EmbeddedKeycloakTestServerSupplier(),
new RemoteKeycloakTestServerSupplier(),
new DistributionKeycloakServerSupplier(),
new EmbeddedKeycloakServerSupplier(),
new RemoteKeycloakServerSupplier(),
new KeycloakUrlsSupplier(),
new DevMemDatabaseSupplier(),
new DevFileDatabaseSupplier(),
@@ -46,7 +46,7 @@ public class CoreTestFrameworkExtension implements TestFrameworkExtension {
@Override
public Map<Class<?>, String> valueTypeAliases() {
return Map.of(
KeycloakTestServer.class, "server",
KeycloakServer.class, "server",
TestDatabase.class, "database"
);
}
@@ -9,7 +9,7 @@ import org.keycloak.test.framework.injection.InstanceContext;
import org.keycloak.test.framework.injection.LifeCycle;
import org.keycloak.test.framework.injection.RequestedInstance;
import org.keycloak.test.framework.injection.Supplier;
import org.keycloak.test.framework.server.KeycloakTestServer;
import org.keycloak.test.framework.server.KeycloakServer;
public class KeycloakAdminClientSupplier implements Supplier<Keycloak, InjectAdminClient> {
@@ -25,9 +25,9 @@ public class KeycloakAdminClientSupplier implements Supplier<Keycloak, InjectAdm
@Override
public Keycloak getValue(InstanceContext<Keycloak, InjectAdminClient> instanceContext) {
KeycloakTestServer testServer = instanceContext.getDependency(KeycloakTestServer.class);
KeycloakServer server = instanceContext.getDependency(KeycloakServer.class);
return KeycloakBuilder.builder()
.serverUrl(testServer.getBaseUrl())
.serverUrl(server.getBaseUrl())
.realm("master")
.grantType(OAuth2Constants.CLIENT_CREDENTIALS)
.clientId(Config.getAdminClientId())
@@ -1,7 +1,7 @@
package org.keycloak.test.framework.annotations;
import org.keycloak.test.framework.server.DefaultKeycloakTestServerConfig;
import org.keycloak.test.framework.server.KeycloakTestServerConfig;
import org.keycloak.test.framework.server.DefaultKeycloakServerConfig;
import org.keycloak.test.framework.server.KeycloakServerConfig;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
@@ -12,6 +12,6 @@ import java.lang.annotation.Target;
@Target(ElementType.TYPE)
public @interface KeycloakIntegrationTest {
Class<? extends KeycloakTestServerConfig> config() default DefaultKeycloakTestServerConfig.class;
Class<? extends KeycloakServerConfig> config() default DefaultKeycloakServerConfig.class;
}
@@ -5,8 +5,11 @@ import org.keycloak.test.framework.injection.InstanceContext;
import org.keycloak.test.framework.injection.LifeCycle;
import org.keycloak.test.framework.injection.RequestedInstance;
import org.keycloak.test.framework.injection.Supplier;
import org.keycloak.test.framework.injection.SupplierOrder;
import org.keycloak.test.framework.server.KeycloakServerConfigBuilder;
import org.keycloak.test.framework.server.KeycloakServerConfigInterceptor;
public abstract class AbstractDatabaseSupplier implements Supplier<TestDatabase, InjectTestDatabase> {
public abstract class AbstractDatabaseSupplier implements Supplier<TestDatabase, InjectTestDatabase>, KeycloakServerConfigInterceptor<TestDatabase, InjectTestDatabase> {
@Override
public Class<InjectTestDatabase> getAnnotationClass() {
@@ -41,4 +44,14 @@ public abstract class AbstractDatabaseSupplier implements Supplier<TestDatabase,
public void close(InstanceContext<TestDatabase, InjectTestDatabase> instanceContext) {
instanceContext.getValue().stop();
}
@Override
public KeycloakServerConfigBuilder intercept(KeycloakServerConfigBuilder serverConfig, InstanceContext<TestDatabase, InjectTestDatabase> instanceContext) {
return serverConfig.options(instanceContext.getValue().serverConfig());
}
@Override
public int order() {
return SupplierOrder.BEFORE_KEYCLOAK_SERVER;
}
}
@@ -1,7 +1,5 @@
package org.keycloak.test.framework.database;
import io.quarkus.maven.dependency.Dependency;
import java.util.Map;
public interface TestDatabase {
@@ -12,8 +10,4 @@ public interface TestDatabase {
Map<String, String> serverConfig();
default Dependency jdbcDriver() {
return null;
}
}
@@ -5,8 +5,10 @@ import org.keycloak.test.framework.injection.InstanceContext;
import org.keycloak.test.framework.injection.LifeCycle;
import org.keycloak.test.framework.injection.RequestedInstance;
import org.keycloak.test.framework.injection.Supplier;
import org.keycloak.test.framework.injection.SupplierOrder;
public class AdminEventsSupplier implements Supplier<AdminEvents, InjectAdminEvents> {
@Override
public Class<InjectAdminEvents> getAnnotationClass() {
return InjectAdminEvents.class;
@@ -44,4 +46,9 @@ public class AdminEventsSupplier implements Supplier<AdminEvents, InjectAdminEve
public boolean compatible(InstanceContext<AdminEvents, InjectAdminEvents> a, RequestedInstance<AdminEvents, InjectAdminEvents> b) {
return true;
}
@Override
public int order() {
return SupplierOrder.BEFORE_KEYCLOAK_SERVER;
}
}
@@ -5,8 +5,10 @@ import org.keycloak.test.framework.injection.InstanceContext;
import org.keycloak.test.framework.injection.LifeCycle;
import org.keycloak.test.framework.injection.RequestedInstance;
import org.keycloak.test.framework.injection.Supplier;
import org.keycloak.test.framework.injection.SupplierOrder;
public class EventsSupplier implements Supplier<Events, InjectEvents> {
@Override
public Class<InjectEvents> getAnnotationClass() {
return InjectEvents.class;
@@ -44,4 +46,9 @@ public class EventsSupplier implements Supplier<Events, InjectEvents> {
public boolean compatible(InstanceContext<Events, InjectEvents> a, RequestedInstance<Events, InjectEvents> b) {
return true;
}
@Override
public int order() {
return SupplierOrder.BEFORE_KEYCLOAK_SERVER;
}
}
@@ -17,12 +17,12 @@ public class SysLogServer {
private static final Logger LOGGER = Logger.getLogger(SysLogServer.class);
private static final int MAX_THREADS = 5;
private ServerSocket serverSocket;
private final ServerSocket serverSocket;
private final List<Thread> threads = Collections.synchronizedList(new LinkedList<>());
private final Set<SysLogListener> listeners = new HashSet<>();
private boolean running = true;
public void start() throws IOException {
public SysLogServer() throws IOException {
serverSocket = new ServerSocket(0);
startThread();
}
@@ -5,10 +5,14 @@ import org.keycloak.test.framework.injection.InstanceContext;
import org.keycloak.test.framework.injection.LifeCycle;
import org.keycloak.test.framework.injection.RequestedInstance;
import org.keycloak.test.framework.injection.Supplier;
import org.keycloak.test.framework.injection.SupplierOrder;
import org.keycloak.test.framework.server.KeycloakServerConfigBuilder;
import org.keycloak.test.framework.server.KeycloakServerConfigInterceptor;
import java.io.IOException;
public class SysLogServerSupplier implements Supplier<SysLogServer, InjectSysLogServer> {
public class SysLogServerSupplier implements Supplier<SysLogServer, InjectSysLogServer>, KeycloakServerConfigInterceptor<SysLogServer, InjectSysLogServer> {
@Override
public Class<InjectSysLogServer> getAnnotationClass() {
return InjectSysLogServer.class;
@@ -22,9 +26,7 @@ public class SysLogServerSupplier implements Supplier<SysLogServer, InjectSysLog
@Override
public SysLogServer getValue(InstanceContext<SysLogServer, InjectSysLogServer> instanceContext) {
try {
SysLogServer server = new SysLogServer();
server.start();
return server;
return new SysLogServer();
} catch (IOException e) {
throw new RuntimeException(e);
}
@@ -49,4 +51,22 @@ public class SysLogServerSupplier implements Supplier<SysLogServer, InjectSysLog
public boolean compatible(InstanceContext<SysLogServer, InjectSysLogServer> a, RequestedInstance<SysLogServer, InjectSysLogServer> b) {
return true;
}
@Override
public KeycloakServerConfigBuilder intercept(KeycloakServerConfigBuilder serverConfig, InstanceContext<SysLogServer, InjectSysLogServer> instanceContext) {
serverConfig.log()
.handlers(KeycloakServerConfigBuilder.LogHandlers.SYSLOG)
.syslogEndpoint(instanceContext.getValue().getEndpoint())
.handlerLevel(KeycloakServerConfigBuilder.LogHandlers.SYSLOG, "INFO");
serverConfig.option("spi-events-listener-jboss-logging-success-level", "INFO")
.log().categoryLevel("org.keycloak.events", "INFO");
return serverConfig;
}
@Override
public int order() {
return SupplierOrder.BEFORE_KEYCLOAK_SERVER;
}
}
@@ -8,6 +8,7 @@ import java.util.Set;
public class InstanceContext<T, A extends Annotation> {
private final int instanceId;
private final Registry registry;
private final Supplier<T, A> supplier;
private final A annotation;
@@ -18,7 +19,8 @@ public class InstanceContext<T, A extends Annotation> {
private final String ref;
private final Map<String, Object> notes = new HashMap<>();
public InstanceContext(Registry registry, Supplier<T, A> supplier, A annotation, Class<? extends T> requestedValueType) {
public InstanceContext(int instanceId, Registry registry, Supplier<T, A> supplier, A annotation, Class<? extends T> requestedValueType) {
this.instanceId = instanceId != -1 ? instanceId : hashCode();
this.registry = registry;
this.supplier = supplier;
this.annotation = annotation;
@@ -27,6 +29,10 @@ public class InstanceContext<T, A extends Annotation> {
this.ref = StringUtil.convertEmptyToNull(supplier.getRef(annotation));
}
public int getInstanceId() {
return instanceId;
}
public <D> D getDependency(Class<D> typeClazz) {
return getDependency(typeClazz, null);
}
@@ -8,6 +8,7 @@ import org.keycloak.test.framework.config.Config;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
@@ -61,6 +62,14 @@ public class Registry implements ExtensionContext.Store.CloseableResource {
throw new RuntimeException("Dependency not found: " + typeClass);
}
public List<InstanceContext<?, ?>> getDeployedInstances() {
return deployedInstances;
}
public List<RequestedInstance<?, ?>> getRequestedInstances() {
return requestedInstances;
}
private <T> T getDeployedDependency(Class<T> typeClass, String ref, InstanceContext dependent) {
InstanceContext dependency = getDeployedInstance(typeClass, ref);
if (dependency != null) {
@@ -80,7 +89,7 @@ public class Registry implements ExtensionContext.Store.CloseableResource {
private <T> T getRequestedDependency(Class<T> typeClass, String ref, InstanceContext dependent) {
RequestedInstance requestedDependency = getRequestedInstance(typeClass, ref);
if (requestedDependency != null) {
InstanceContext dependency = new InstanceContext<Object, Annotation>(this, requestedDependency.getSupplier(), requestedDependency.getAnnotation(), requestedDependency.getValueType());
InstanceContext dependency = new InstanceContext<Object, Annotation>(requestedDependency.getInstanceId(), this, requestedDependency.getSupplier(), requestedDependency.getAnnotation(), requestedDependency.getValueType());
dependency.setValue(requestedDependency.getSupplier().getValue(dependency));
dependency.registerDependency(dependent);
deployedInstances.add(dependency);
@@ -104,7 +113,7 @@ public class Registry implements ExtensionContext.Store.CloseableResource {
if (supplied.isPresent()) {
Supplier<T, ?> supplier = (Supplier<T, ?>) supplied.get();
Annotation defaultAnnotation = DefaultAnnotationProxy.proxy(supplier.getAnnotationClass());
dependency = new InstanceContext(this, supplier, defaultAnnotation, typeClass);
dependency = new InstanceContext(-1, this, supplier, defaultAnnotation, typeClass);
dependency.registerDependency(dependent);
dependency.setValue(supplier.getValue(dependency));
@@ -176,11 +185,12 @@ public class Registry implements ExtensionContext.Store.CloseableResource {
}
private void deployRequestedInstances() {
requestedInstances.sort(RequestedInstanceComparator.INSTANCE);
while (!requestedInstances.isEmpty()) {
RequestedInstance requestedInstance = requestedInstances.remove(0);
if (getDeployedInstance(requestedInstance) == null) {
InstanceContext instance = new InstanceContext(this, requestedInstance.getSupplier(), requestedInstance.getAnnotation(), requestedInstance.getValueType());
InstanceContext instance = new InstanceContext(requestedInstance.getInstanceId(), this, requestedInstance.getSupplier(), requestedInstance.getAnnotation(), requestedInstance.getValueType());
instance.setValue(requestedInstance.getSupplier().getValue(instance));
deployedInstances.add(instance);
@@ -233,7 +243,7 @@ public class Registry implements ExtensionContext.Store.CloseableResource {
public void close() {
LOGGER.debug("Closing all instances");
List<InstanceContext<?, ?>> destroy = deployedInstances.stream().toList();
List<InstanceContext<?, ?>> destroy = deployedInstances.stream().sorted(InstanceContextComparator.INSTANCE.reversed()).toList();
destroy.forEach(this::destroy);
}
@@ -382,4 +392,24 @@ public class Registry implements ExtensionContext.Store.CloseableResource {
return fields;
}
private static class RequestedInstanceComparator implements Comparator<RequestedInstance> {
static final RequestedInstanceComparator INSTANCE = new RequestedInstanceComparator();
@Override
public int compare(RequestedInstance o1, RequestedInstance o2) {
return Integer.compare(o1.getSupplier().order(), o2.getSupplier().order());
}
}
private static class InstanceContextComparator implements Comparator<InstanceContext> {
static final InstanceContextComparator INSTANCE = new InstanceContextComparator();
@Override
public int compare(InstanceContext o1, InstanceContext o2) {
return Integer.compare(o1.getSupplier().order(), o2.getSupplier().order());
}
}
}
@@ -4,6 +4,7 @@ import java.lang.annotation.Annotation;
public class RequestedInstance<T, A extends Annotation> {
private final int instanceId;
private final Supplier<T, A> supplier;
private final A annotation;
private final Class<? extends T> valueType;
@@ -11,6 +12,7 @@ public class RequestedInstance<T, A extends Annotation> {
private final String ref;
public RequestedInstance(Supplier<T, A> supplier, A annotation, Class<? extends T> valueType) {
this.instanceId = this.hashCode();
this.supplier = supplier;
this.annotation = annotation;
this.valueType = valueType;
@@ -18,6 +20,10 @@ public class RequestedInstance<T, A extends Annotation> {
this.ref = StringUtil.convertEmptyToNull(supplier.getRef(annotation));
}
public int getInstanceId() {
return instanceId;
}
public Supplier<T, A> getSupplier() {
return supplier;
}
@@ -34,4 +34,7 @@ public interface Supplier<T, S extends Annotation> {
default void onBeforeEach(InstanceContext<T, S> instanceContext) {
}
default int order() {
return SupplierOrder.DEFAULT;
}
}
@@ -0,0 +1,11 @@
package org.keycloak.test.framework.injection;
public interface SupplierOrder {
int BEFORE_KEYCLOAK_SERVER = 100;
int KEYCLOAK_SERVER = 250;
int BEFORE_REALM = 500;
int REALM = 750;
int DEFAULT = 1000;
}
@@ -4,9 +4,10 @@ import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.RolesRepresentation;
import java.util.Arrays;
import java.util.EventListener;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
public class RealmConfigBuilder {
@@ -67,6 +68,15 @@ public class RealmConfigBuilder {
return this;
}
public RealmConfigBuilder smtp(String host, int port, String from) {
Map<String, String> config = new HashMap<>();
config.put("host", host);
config.put("port", Integer.toString(port));
config.put("from", from);
rep.setSmtpServer(config);
return this;
}
public RealmRepresentation build() {
return rep;
}
@@ -0,0 +1,11 @@
package org.keycloak.test.framework.realm;
import org.keycloak.test.framework.injection.InstanceContext;
import java.lang.annotation.Annotation;
public interface RealmConfigInterceptor<T, S extends Annotation> {
RealmConfigBuilder intercept(RealmConfigBuilder realm, InstanceContext<T, S> instanceContext);
}
@@ -5,10 +5,13 @@ import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.test.framework.annotations.InjectRealm;
import org.keycloak.test.framework.injection.InstanceContext;
import org.keycloak.test.framework.injection.Registry;
import org.keycloak.test.framework.injection.RequestedInstance;
import org.keycloak.test.framework.injection.Supplier;
import org.keycloak.test.framework.injection.SupplierHelpers;
import org.keycloak.test.framework.server.KeycloakTestServer;
import org.keycloak.test.framework.injection.SupplierOrder;
import org.keycloak.test.framework.server.AbstractInterceptorHelper;
import org.keycloak.test.framework.server.KeycloakServer;
public class RealmSupplier implements Supplier<ManagedRealm, InjectRealm> {
@@ -26,11 +29,17 @@ public class RealmSupplier implements Supplier<ManagedRealm, InjectRealm> {
@Override
public ManagedRealm getValue(InstanceContext<ManagedRealm, InjectRealm> instanceContext) {
KeycloakTestServer server = instanceContext.getDependency(KeycloakTestServer.class);
KeycloakServer server = instanceContext.getDependency(KeycloakServer.class);
Keycloak adminClient = instanceContext.getDependency(Keycloak.class);
RealmConfig config = SupplierHelpers.getInstance(instanceContext.getAnnotation().config());
RealmRepresentation realmRepresentation = config.configure(RealmConfigBuilder.create()).build();
RealmConfigBuilder realmConfigBuilder = config.configure(RealmConfigBuilder.create());
RealmConfigInterceptorHelper interceptor = new RealmConfigInterceptorHelper(instanceContext.getRegistry());
realmConfigBuilder = interceptor.intercept(realmConfigBuilder, instanceContext);
RealmRepresentation realmRepresentation = realmConfigBuilder.build();
if (realmRepresentation.getRealm() == null) {
String realmName = SupplierHelpers.createName(instanceContext);
@@ -57,7 +66,12 @@ public class RealmSupplier implements Supplier<ManagedRealm, InjectRealm> {
@Override
public boolean compatible(InstanceContext<ManagedRealm, InjectRealm> a, RequestedInstance<ManagedRealm, InjectRealm> b) {
return a.getAnnotation().config().equals(b.getAnnotation().config());
if (!a.getAnnotation().config().equals(b.getAnnotation().config())) {
return false;
}
RealmConfigInterceptorHelper interceptor = new RealmConfigInterceptorHelper(a.getRegistry());
return interceptor.sameInterceptors(a);
}
@Override
@@ -67,4 +81,25 @@ public class RealmSupplier implements Supplier<ManagedRealm, InjectRealm> {
}
}
@Override
public int order() {
return SupplierOrder.REALM;
}
private static class RealmConfigInterceptorHelper extends AbstractInterceptorHelper<RealmConfigInterceptor, RealmConfigBuilder> {
private RealmConfigInterceptorHelper(Registry registry) {
super(registry, RealmConfigInterceptor.class);
}
@Override
public RealmConfigBuilder intercept(RealmConfigBuilder value, Supplier<?, ?> supplier, InstanceContext<?, ?> existingInstance) {
if (supplier instanceof RealmConfigInterceptor interceptor) {
value = interceptor.intercept(value, existingInstance);
}
return value;
}
}
}
@@ -0,0 +1,70 @@
package org.keycloak.test.framework.server;
import org.keycloak.test.framework.injection.InstanceContext;
import org.keycloak.test.framework.injection.Registry;
import org.keycloak.test.framework.injection.RequestedInstance;
import org.keycloak.test.framework.injection.Supplier;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
public abstract class AbstractInterceptorHelper<I, V> {
private final Class<?> interceptorClass;
private final List<Interception> interceptions = new LinkedList<>();
private final InterceptedBy interceptedBy = new InterceptedBy();
public AbstractInterceptorHelper(Registry registry, Class<I> interceptorClass) {
this.interceptorClass = interceptorClass;
registry.getDeployedInstances().stream().filter(i -> isInterceptor(i.getSupplier())).forEach(i -> interceptions.add(new Interception(i)));
registry.getRequestedInstances().stream().filter(r -> isInterceptor(r.getSupplier())).forEach(r -> interceptions.add(new Interception(r)));
interceptions.forEach(i -> interceptedBy.put(i.supplier, i.instanceId));
}
public boolean sameInterceptors(InstanceContext<?, ?> instanceContext) {
InterceptedBy previousInterceptedBy = instanceContext.getNote("InterceptedBy", InterceptedBy.class);
return interceptedBy.equals(previousInterceptedBy);
}
public V intercept(V value, InstanceContext<?, ?> instanceContext) {
for (Interception interception : interceptions) {
value = intercept(value, interception.supplier, interception.existingInstance);
}
instanceContext.addNote("InterceptedBy", interceptedBy);
return value;
}
public abstract V intercept(V value, Supplier<?, ?> supplier, InstanceContext<?, ?> existingInstance);
private boolean isInterceptor(Supplier<?, ?> supplier) {
return interceptorClass.isAssignableFrom(supplier.getClass());
}
public static class InterceptedBy extends HashMap<Supplier<?, ?>, Integer> {
}
private static class Interception {
private final int instanceId;
private final Supplier<?, ?> supplier;
private final InstanceContext<?, ?> existingInstance;
public Interception(InstanceContext<?, ?> existingInstance) {
this.supplier = existingInstance.getSupplier();
this.instanceId = existingInstance.getInstanceId();
this.existingInstance = existingInstance;
}
public Interception(RequestedInstance<?, ?> requestedInstance) {
this.supplier = requestedInstance.getSupplier();
this.instanceId = requestedInstance.getInstanceId();
this.existingInstance = null;
}
}
}
@@ -0,0 +1,110 @@
package org.keycloak.test.framework.server;
import org.jboss.logging.Logger;
import org.keycloak.test.framework.annotations.KeycloakIntegrationTest;
import org.keycloak.test.framework.config.Config;
import org.keycloak.test.framework.database.TestDatabase;
import org.keycloak.test.framework.injection.InstanceContext;
import org.keycloak.test.framework.injection.LifeCycle;
import org.keycloak.test.framework.injection.Registry;
import org.keycloak.test.framework.injection.RequestedInstance;
import org.keycloak.test.framework.injection.Supplier;
import org.keycloak.test.framework.injection.SupplierHelpers;
import org.keycloak.test.framework.injection.SupplierOrder;
public abstract class AbstractKeycloakServerSupplier implements Supplier<KeycloakServer, KeycloakIntegrationTest> {
@Override
public Class<KeycloakServer> getValueType() {
return KeycloakServer.class;
}
@Override
public Class<KeycloakIntegrationTest> getAnnotationClass() {
return KeycloakIntegrationTest.class;
}
@Override
public KeycloakServer getValue(InstanceContext<KeycloakServer, KeycloakIntegrationTest> instanceContext) {
KeycloakIntegrationTest annotation = instanceContext.getAnnotation();
KeycloakServerConfig serverConfig = SupplierHelpers.getInstance(annotation.config());
KeycloakServerConfigBuilder command = KeycloakServerConfigBuilder.startDev()
.cache("local")
.bootstrapAdminClient(Config.getAdminClientId(), Config.getAdminClientSecret());
command.log().handlers(KeycloakServerConfigBuilder.LogHandlers.CONSOLE);
command = serverConfig.configure(command);
if (requiresDatabase()) {
instanceContext.getDependency(TestDatabase.class);
}
ServerConfigInterceptorHelper interceptor = new ServerConfigInterceptorHelper(instanceContext.getRegistry());
command = interceptor.intercept(command, instanceContext);
command.log().fromConfig(Config.getConfig());
getLogger().info("Starting Keycloak test server");
if (getLogger().isDebugEnabled()) {
getLogger().debugv("Startup command and options: \n\t{0}", String.join("\n\t", command.toArgs()));
}
long start = System.currentTimeMillis();
KeycloakServer server = getServer();
server.start(command);
getLogger().infov("Keycloak test server started in {0} ms", System.currentTimeMillis() - start);
return server;
}
@Override
public LifeCycle getDefaultLifecycle() {
return LifeCycle.GLOBAL;
}
@Override
public boolean compatible(InstanceContext<KeycloakServer, KeycloakIntegrationTest> a, RequestedInstance<KeycloakServer, KeycloakIntegrationTest> b) {
if (!a.getAnnotation().config().equals(b.getAnnotation().config())) {
return false;
}
ServerConfigInterceptorHelper interceptor = new ServerConfigInterceptorHelper(a.getRegistry());
return interceptor.sameInterceptors(a);
}
@Override
public void close(InstanceContext<KeycloakServer, KeycloakIntegrationTest> instanceContext) {
instanceContext.getValue().stop();
}
public abstract KeycloakServer getServer();
public abstract boolean requiresDatabase();
public abstract Logger getLogger();
@Override
public int order() {
return SupplierOrder.KEYCLOAK_SERVER;
}
private static class ServerConfigInterceptorHelper extends AbstractInterceptorHelper<KeycloakServerConfigInterceptor, KeycloakServerConfigBuilder> {
private ServerConfigInterceptorHelper(Registry registry) {
super(registry, KeycloakServerConfigInterceptor.class);
}
@Override
public KeycloakServerConfigBuilder intercept(KeycloakServerConfigBuilder value, Supplier<?, ?> supplier, InstanceContext<?, ?> existingInstance) {
if (supplier instanceof KeycloakServerConfigInterceptor keycloakServerConfigInterceptor) {
value = keycloakServerConfigInterceptor.intercept(value, existingInstance);
}
return value;
}
}
}
@@ -1,104 +0,0 @@
package org.keycloak.test.framework.server;
import io.quarkus.maven.dependency.Dependency;
import org.jboss.logging.Logger;
import org.keycloak.test.framework.annotations.KeycloakIntegrationTest;
import org.keycloak.test.framework.config.Config;
import org.keycloak.test.framework.database.TestDatabase;
import org.keycloak.test.framework.events.SysLogServer;
import org.keycloak.test.framework.injection.InstanceContext;
import org.keycloak.test.framework.injection.LifeCycle;
import org.keycloak.test.framework.injection.RequestedInstance;
import org.keycloak.test.framework.injection.Supplier;
import org.keycloak.test.framework.injection.SupplierHelpers;
import java.util.HashSet;
import java.util.Set;
public abstract class AbstractKeycloakTestServerSupplier implements Supplier<KeycloakTestServer, KeycloakIntegrationTest> {
@Override
public Class<KeycloakTestServer> getValueType() {
return KeycloakTestServer.class;
}
@Override
public Class<KeycloakIntegrationTest> getAnnotationClass() {
return KeycloakIntegrationTest.class;
}
@Override
public KeycloakTestServer getValue(InstanceContext<KeycloakTestServer, KeycloakIntegrationTest> instanceContext) {
KeycloakIntegrationTest annotation = instanceContext.getAnnotation();
KeycloakTestServerConfig serverConfig = SupplierHelpers.getInstance(annotation.config());
CommandBuilder command = CommandBuilder.startDev()
.cache("local")
.bootstrapAdminClient(Config.getAdminClientId(), Config.getAdminClientSecret());
if (serverConfig.enableSysLog()) {
SysLogServer sysLogServer = instanceContext.getDependency(SysLogServer.class);
command.log().enableSyslog(sysLogServer.getEndpoint());
}
command.log().fromConfig(Config.getConfig());
if (!serverConfig.features().isEmpty()) {
command.features(serverConfig.features());
}
if (!serverConfig.featuresDisabled().isEmpty()) {
command.featuresDisabled(serverConfig.featuresDisabled());
}
command.options(serverConfig.options());
Set<Dependency> dependencies = new HashSet<>(serverConfig.dependencies());
if (requiresDatabase()) {
TestDatabase testDatabase = instanceContext.getDependency(TestDatabase.class);
command.databaseConfig(testDatabase.serverConfig());
Dependency jdbcDriver = testDatabase.jdbcDriver();
if (jdbcDriver != null) {
dependencies.add(jdbcDriver);
}
}
getLogger().info("Starting Keycloak test server");
if (getLogger().isDebugEnabled()) {
getLogger().debugv("Startup command and options: \n\t{0}", String.join("\n\t", command.toArgs()));
}
long start = System.currentTimeMillis();
KeycloakTestServer server = getServer();
server.start(command, dependencies);
getLogger().infov("Keycloak test server started in {0} ms", System.currentTimeMillis() - start);
return server;
}
@Override
public LifeCycle getDefaultLifecycle() {
return LifeCycle.GLOBAL;
}
@Override
public boolean compatible(InstanceContext<KeycloakTestServer, KeycloakIntegrationTest> a, RequestedInstance<KeycloakTestServer, KeycloakIntegrationTest> b) {
return a.getAnnotation().config().equals(b.getAnnotation().config());
}
@Override
public void close(InstanceContext<KeycloakTestServer, KeycloakIntegrationTest> instanceContext) {
instanceContext.getValue().stop();
}
public abstract KeycloakTestServer getServer();
public abstract boolean requiresDatabase();
public abstract Logger getLogger();
}
@@ -0,0 +1,10 @@
package org.keycloak.test.framework.server;
public class DefaultKeycloakServerConfig implements KeycloakServerConfig {
@Override
public KeycloakServerConfigBuilder configure(KeycloakServerConfigBuilder config) {
return config;
}
}
@@ -1,5 +0,0 @@
package org.keycloak.test.framework.server;
public class DefaultKeycloakTestServerConfig implements KeycloakTestServerConfig {
}
@@ -7,11 +7,10 @@ import org.keycloak.it.utils.RawKeycloakDistribution;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class DistributionKeycloakTestServer implements KeycloakTestServer {
public class DistributionKeycloakServer implements KeycloakServer {
private static final boolean DEBUG = false;
private static final boolean MANUAL_STOP = true;
@@ -23,14 +22,14 @@ public class DistributionKeycloakTestServer implements KeycloakTestServer {
private RawKeycloakDistribution keycloak;
@Override
public void start(CommandBuilder commandBuilder, Set<Dependency> dependencies) {
public void start(KeycloakServerConfigBuilder keycloakServerConfigBuilder) {
keycloak = new RawKeycloakDistribution(DEBUG, MANUAL_STOP, ENABLE_TLS, RE_CREATE, REMOVE_BUILD_OPTIONS_AFTER_BUILD, REQUEST_PORT, new LoggingOutputConsumer());
for (Dependency dependency : dependencies) {
for (Dependency dependency : keycloakServerConfigBuilder.toDependencies()) {
keycloak.copyProvider(dependency.getGroupId(), dependency.getArtifactId());
}
keycloak.run(commandBuilder.toArgs());
keycloak.run(keycloakServerConfigBuilder.toArgs());
}
@Override
@@ -2,13 +2,13 @@ package org.keycloak.test.framework.server;
import org.jboss.logging.Logger;
public class DistributionKeycloakTestServerSupplier extends AbstractKeycloakTestServerSupplier {
public class DistributionKeycloakServerSupplier extends AbstractKeycloakServerSupplier {
private static final Logger LOGGER = Logger.getLogger(DistributionKeycloakTestServerSupplier.class);
private static final Logger LOGGER = Logger.getLogger(DistributionKeycloakServerSupplier.class);
@Override
public KeycloakTestServer getServer() {
return new DistributionKeycloakTestServer();
public KeycloakServer getServer() {
return new DistributionKeycloakServer();
}
@Override
@@ -4,23 +4,21 @@ import io.quarkus.maven.dependency.Dependency;
import org.keycloak.Keycloak;
import org.keycloak.common.Version;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeoutException;
public class EmbeddedKeycloakTestServer implements KeycloakTestServer {
public class EmbeddedKeycloakServer implements KeycloakServer {
private Keycloak keycloak;
@Override
public void start(CommandBuilder commandBuilder, Set<Dependency> dependencies) {
public void start(KeycloakServerConfigBuilder keycloakServerConfigBuilder) {
Keycloak.Builder builder = Keycloak.builder().setVersion(Version.VERSION);
for(Dependency dependency : dependencies) {
for(Dependency dependency : keycloakServerConfigBuilder.toDependencies()) {
builder.addDependency(dependency.getGroupId(), dependency.getArtifactId(), "");
}
keycloak = builder.start(commandBuilder.toArgs());
keycloak = builder.start(keycloakServerConfigBuilder.toArgs());
}
@Override
@@ -2,13 +2,13 @@ package org.keycloak.test.framework.server;
import org.jboss.logging.Logger;
public class EmbeddedKeycloakTestServerSupplier extends AbstractKeycloakTestServerSupplier {
public class EmbeddedKeycloakServerSupplier extends AbstractKeycloakServerSupplier {
private static final Logger LOGGER = Logger.getLogger(EmbeddedKeycloakTestServerSupplier.class);
private static final Logger LOGGER = Logger.getLogger(EmbeddedKeycloakServerSupplier.class);
@Override
public KeycloakTestServer getServer() {
return new EmbeddedKeycloakTestServer();
public KeycloakServer getServer() {
return new EmbeddedKeycloakServer();
}
@Override
@@ -0,0 +1,11 @@
package org.keycloak.test.framework.server;
public interface KeycloakServer {
void start(KeycloakServerConfigBuilder keycloakServerConfigBuilder);
void stop();
String getBaseUrl();
}
@@ -0,0 +1,7 @@
package org.keycloak.test.framework.server;
public interface KeycloakServerConfig {
KeycloakServerConfigBuilder configure(KeycloakServerConfigBuilder config);
}
@@ -1,37 +1,43 @@
package org.keycloak.test.framework.server;
import io.quarkus.maven.dependency.Dependency;
import io.quarkus.maven.dependency.DependencyBuilder;
import io.smallrye.config.SmallRyeConfig;
import org.eclipse.microprofile.config.spi.ConfigSource;
import org.keycloak.common.Profile;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
public class CommandBuilder {
public class KeycloakServerConfigBuilder {
private final String command;
private final Map<String, String> options = new HashMap<>();
private final Set<String> features = new HashSet<>();
private final Set<String> featuresDisabled = new HashSet<>();
private final LogBuilder log = new LogBuilder();
private final Set<Dependency> dependencies = new HashSet<>();
private CommandBuilder(String command) {
private KeycloakServerConfigBuilder(String command) {
this.command = command;
}
public static CommandBuilder startDev() {
return new CommandBuilder("start-dev");
public static KeycloakServerConfigBuilder startDev() {
return new KeycloakServerConfigBuilder("start-dev");
}
public CommandBuilder bootstrapAdminClient(String clientId, String clientSecret) {
public KeycloakServerConfigBuilder bootstrapAdminClient(String clientId, String clientSecret) {
return option("bootstrap-admin-client-id", clientId)
.option("bootstrap-admin-client-secret", clientSecret);
}
public CommandBuilder cache(String cache) {
public KeycloakServerConfigBuilder cache(String cache) {
return option("cache", cache);
}
@@ -39,44 +45,57 @@ public class CommandBuilder {
return log;
}
public CommandBuilder features(Set<String> features) {
this.features.addAll(features);
public KeycloakServerConfigBuilder features(Profile.Feature... features) {
this.features.addAll(toFeatureStrings(features));
return this;
}
public CommandBuilder featuresDisabled(Set<String> featuresDisabled) {
this.featuresDisabled.addAll(featuresDisabled);
public KeycloakServerConfigBuilder featuresDisabled(Profile.Feature... features) {
this.featuresDisabled.addAll(toFeatureStrings(features));
return this;
}
public CommandBuilder databaseConfig(Map<String, String> databaseConfig) {
for (String k : databaseConfig.keySet()) {
if (!k.startsWith("db")) {
throw new IllegalArgumentException("Database config supplied non-database configuration: " + k);
}
}
return options(databaseConfig);
}
public CommandBuilder options(Map<String, String> options) {
public KeycloakServerConfigBuilder options(Map<String, String> options) {
this.options.putAll(options);
return this;
}
public CommandBuilder option(String key, String value) {
public KeycloakServerConfigBuilder option(String key, String value) {
options.put(key, value);
return this;
}
public KeycloakServerConfigBuilder dependency(String groupId, String artifactId) {
dependencies.add(new DependencyBuilder().setGroupId(groupId).setArtifactId(artifactId).build());
return this;
}
public class LogBuilder {
private Boolean color;
private String format;
private String rootLevel;
private Map<String, String> categoryLevels = new HashMap<>();
private final Map<String, String> categoryLevels = new HashMap<>();
private final Map<String, String> handlerLevels = new HashMap<>();
private final Set<String> handlers = new HashSet<>();
private String syslogEndpoint;
public LogBuilder enableSyslog(String syslogEndpoint) {
public LogBuilder handlers(LogHandlers... handlers) {
this.handlers.addAll(Arrays.stream(handlers).map(l -> l.name().toLowerCase()).collect(Collectors.toSet()));
return this;
}
public LogBuilder handlerLevel(LogHandlers handler, String logLevel) {
handlerLevels.put(handler.name().toLowerCase(), logLevel);
return this;
}
public LogBuilder categoryLevel(String category, String logLevel) {
categoryLevels.put(category, logLevel);
return this;
}
public LogBuilder syslogEndpoint(String syslogEndpoint) {
this.syslogEndpoint = syslogEndpoint;
return this;
}
@@ -112,12 +131,16 @@ public class CommandBuilder {
}
private void build() {
if (!handlers.isEmpty()) {
option("log", String.join(",", handlers));
}
if (!handlerLevels.isEmpty()) {
handlerLevels.forEach((key, value) -> option("log-" + key + "-level", value));
}
if (syslogEndpoint != null) {
option("log", "console,syslog");
option("log-syslog-level", "info");
option("log-syslog-endpoint", syslogEndpoint);
option("spi-events-listener-jboss-logging-success-level", "INFO");
categoryLevels.put("org.keycloak.events", "INFO");
}
if (format != null) {
@@ -166,4 +189,18 @@ public class CommandBuilder {
return args;
}
public Set<Dependency> toDependencies() {
return dependencies;
}
private Set<String> toFeatureStrings(Profile.Feature... features) {
return Arrays.stream(features).map(f -> f.name().toLowerCase().replace('_', '-')).collect(Collectors.toSet());
}
public enum LogHandlers {
CONSOLE,
FILE,
SYSLOG
}
}
@@ -0,0 +1,11 @@
package org.keycloak.test.framework.server;
import org.keycloak.test.framework.injection.InstanceContext;
import java.lang.annotation.Annotation;
public interface KeycloakServerConfigInterceptor<T, S extends Annotation> {
KeycloakServerConfigBuilder intercept(KeycloakServerConfigBuilder serverConfig, InstanceContext<T, S> instanceContext);
}
@@ -1,16 +0,0 @@
package org.keycloak.test.framework.server;
import io.quarkus.maven.dependency.Dependency;
import java.util.List;
import java.util.Set;
public interface KeycloakTestServer {
void start(CommandBuilder commandBuilder, Set<Dependency> dependencies);
void stop();
String getBaseUrl();
}
@@ -1,29 +0,0 @@
package org.keycloak.test.framework.server;
import io.quarkus.maven.dependency.Dependency;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
public interface KeycloakTestServerConfig {
default Map<String, String> options() {
return Collections.emptyMap();
}
default Set<String> features() {
return Collections.emptySet();
}
default Set<String> featuresDisabled() {
return Collections.emptySet();
}
default boolean enableSysLog() { return false; }
default Set<Dependency> dependencies() {
return Collections.emptySet();
}
}
@@ -19,8 +19,8 @@ public class KeycloakUrlsSupplier implements Supplier<KeycloakUrls, InjectKeyclo
@Override
public KeycloakUrls getValue(InstanceContext<KeycloakUrls, InjectKeycloakUrls> instanceContext) {
KeycloakTestServer testServer = instanceContext.getDependency(KeycloakTestServer.class);
return new KeycloakUrls(testServer.getBaseUrl());
KeycloakServer server = instanceContext.getDependency(KeycloakServer.class);
return new KeycloakUrls(server.getBaseUrl());
}
@Override
@@ -7,12 +7,12 @@ import java.net.URL;
import java.util.Set;
import java.util.concurrent.TimeUnit;
public class RemoteKeycloakTestServer implements KeycloakTestServer {
public class RemoteKeycloakServer implements KeycloakServer {
@Override
public void start(CommandBuilder commandBuilder, Set<Dependency> dependencies) {
public void start(KeycloakServerConfigBuilder keycloakServerConfigBuilder) {
if (!verifyRunningKeycloak()) {
printStartupInstructions(commandBuilder, dependencies);
printStartupInstructions(keycloakServerConfigBuilder);
waitForStartup();
}
}
@@ -26,13 +26,17 @@ public class RemoteKeycloakTestServer implements KeycloakTestServer {
return "http://localhost:8080";
}
private void printStartupInstructions(CommandBuilder commandBuilder, Set<Dependency> dependencies) {
private void printStartupInstructions(KeycloakServerConfigBuilder keycloakServerConfigBuilder) {
StringBuilder sb = new StringBuilder();
sb.append("Remote Keycloak server is not running on " + getBaseUrl() + ", please start Keycloak with:\n\n");
sb.append("Remote Keycloak server is not running on ")
.append(getBaseUrl())
.append(", please start Keycloak with:\n\n");
sb.append(String.join(" \\\n", commandBuilder.toArgs()));
sb.append(String.join(" \\\n", keycloakServerConfigBuilder.toArgs()));
sb.append("\n\n");
Set<Dependency> dependencies = keycloakServerConfigBuilder.toDependencies();
if (!dependencies.isEmpty()) {
sb.append("Requested providers:\n");
for (Dependency d : dependencies) {
@@ -2,13 +2,13 @@ package org.keycloak.test.framework.server;
import org.jboss.logging.Logger;
public class RemoteKeycloakTestServerSupplier extends AbstractKeycloakTestServerSupplier {
public class RemoteKeycloakServerSupplier extends AbstractKeycloakServerSupplier {
private static final Logger LOGGER = Logger.getLogger(RemoteKeycloakTestServerSupplier.class);
private static final Logger LOGGER = Logger.getLogger(RemoteKeycloakServerSupplier.class);
@Override
public KeycloakTestServer getServer() {
return new RemoteKeycloakTestServer();
public KeycloakServer getServer() {
return new RemoteKeycloakServer();
}
@Override
@@ -3,7 +3,7 @@ package org.keycloak.test.framework.injection;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.keycloak.admin.client.Keycloak;
import org.keycloak.test.framework.server.KeycloakTestServer;
import org.keycloak.test.framework.server.KeycloakServer;
import java.util.Map;
@@ -12,8 +12,8 @@ public class ValueTypeAliasTest {
@Test
public void withAlias() {
ValueTypeAlias valueTypeAlias = new ValueTypeAlias();
valueTypeAlias.addAll(Map.of(KeycloakTestServer.class, "server"));
Assertions.assertEquals("server", valueTypeAlias.getAlias(KeycloakTestServer.class));
valueTypeAlias.addAll(Map.of(KeycloakServer.class, "server"));
Assertions.assertEquals("server", valueTypeAlias.getAlias(KeycloakServer.class));
}
@Test
@@ -1,5 +1,9 @@
package org.keycloak.test.framework.database;
import org.keycloak.test.framework.annotations.InjectTestDatabase;
import org.keycloak.test.framework.injection.InstanceContext;
import org.keycloak.test.framework.server.KeycloakServerConfigBuilder;
public class OracleDatabaseSupplier extends AbstractDatabaseSupplier {
@Override
@@ -12,4 +16,9 @@ public class OracleDatabaseSupplier extends AbstractDatabaseSupplier {
return new OracleTestDatabase();
}
@Override
public KeycloakServerConfigBuilder intercept(KeycloakServerConfigBuilder serverConfig, InstanceContext<TestDatabase, InjectTestDatabase> instanceContext) {
return super.intercept(serverConfig, instanceContext)
.dependency("com.oracle.database.jdbc", "ojdbc11");
}
}
@@ -1,6 +1,5 @@
package org.keycloak.test.framework.database;
import io.quarkus.maven.dependency.Dependency;
import org.jboss.logging.Logger;
import org.testcontainers.containers.JdbcDatabaseContainer;
import org.testcontainers.oracle.OracleContainer;
@@ -21,11 +20,6 @@ class OracleTestDatabase extends AbstractContainerTestDatabase {
return NAME;
}
@Override
public Dependency jdbcDriver() {
return Dependency.of("com.oracle.database.jdbc", "ojdbc11");
}
@Override
public Logger getLogger() {
return LOGGER;
@@ -1,16 +1,18 @@
package org.keycloak.test.framework.mail;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.test.framework.mail.annotations.InjectMailServer;
import org.keycloak.test.framework.injection.InstanceContext;
import org.keycloak.test.framework.injection.RequestedInstance;
import org.keycloak.test.framework.injection.Supplier;
import org.keycloak.test.framework.realm.ManagedRealm;
import org.keycloak.test.framework.injection.SupplierOrder;
import org.keycloak.test.framework.mail.annotations.InjectMailServer;
import org.keycloak.test.framework.realm.RealmConfigBuilder;
import org.keycloak.test.framework.realm.RealmConfigInterceptor;
import java.util.HashMap;
import java.util.Map;
public class GreenMailSupplier implements Supplier<MailServer, InjectMailServer>, RealmConfigInterceptor<MailServer, InjectMailServer> {
public class GreenMailSupplier implements Supplier<MailServer, InjectMailServer> {
private final String HOSTNAME = "localhost";
private final int PORT = 3025;
private final String FROM = "auto@keycloak.org";
@Override
public Class<InjectMailServer> getAnnotationClass() {
@@ -24,20 +26,7 @@ public class GreenMailSupplier implements Supplier<MailServer, InjectMailServer>
@Override
public MailServer getValue(InstanceContext<MailServer, InjectMailServer> instanceContext) {
ManagedRealm realm = instanceContext.getDependency(ManagedRealm.class);
RealmRepresentation representation = realm.admin().toRepresentation();
Map<String, String> config = new HashMap<>();
config.put("from", "auto@keycloak.org");
config.put("host", "localhost");
config.put("port", "3025");
representation.setSmtpServer(config);
realm.admin().update(representation);
MailServer mailServer = new MailServer();
mailServer.start();
return mailServer;
return new MailServer(HOSTNAME, PORT);
}
@Override
@@ -49,4 +38,14 @@ public class GreenMailSupplier implements Supplier<MailServer, InjectMailServer>
public boolean compatible(InstanceContext<MailServer, InjectMailServer> a, RequestedInstance<MailServer, InjectMailServer> b) {
return true;
}
@Override
public RealmConfigBuilder intercept(RealmConfigBuilder realm, InstanceContext<MailServer, InjectMailServer> instanceContext) {
return realm.smtp(HOSTNAME, PORT, FROM);
}
@Override
public int order() {
return SupplierOrder.BEFORE_REALM;
}
}
@@ -8,13 +8,10 @@ import org.keycloak.test.framework.injection.ManagedTestResource;
public class MailServer extends ManagedTestResource {
private static final int PORT = 3025;
private static final String HOST = "localhost";
private final GreenMail greenMail;
private GreenMail greenMail;
public void start() {
ServerSetup setup = new ServerSetup(PORT, HOST, "smtp");
public MailServer(String host, int port) {
ServerSetup setup = new ServerSetup(port, host, "smtp");
greenMail = new GreenMail(setup);
greenMail.start();
@@ -12,9 +12,8 @@ import org.keycloak.test.framework.annotations.InjectRealm;
import org.keycloak.test.framework.annotations.KeycloakIntegrationTest;
import org.keycloak.test.framework.events.AdminEvents;
import org.keycloak.test.framework.realm.ManagedRealm;
import org.keycloak.test.framework.server.KeycloakTestServerConfig;
@KeycloakIntegrationTest(config = AdminEventsTest.ServerConfig.class)
@KeycloakIntegrationTest
public class AdminEventsTest {
@InjectAdminEvents
@@ -67,11 +66,4 @@ public class AdminEventsTest {
Assertions.assertEquals(OperationType.UPDATE, adminEvents.poll().getOperationType());
}
public static class ServerConfig implements KeycloakTestServerConfig {
@Override
public boolean enableSysLog() {
return true;
}
}
}
@@ -7,10 +7,10 @@ import org.keycloak.common.Profile;
import org.keycloak.representations.info.FeatureRepresentation;
import org.keycloak.test.framework.annotations.InjectAdminClient;
import org.keycloak.test.framework.annotations.KeycloakIntegrationTest;
import org.keycloak.test.framework.server.KeycloakTestServerConfig;
import org.keycloak.test.framework.server.KeycloakServerConfigBuilder;
import org.keycloak.test.framework.server.KeycloakServerConfig;
import java.util.Optional;
import java.util.Set;
@KeycloakIntegrationTest(config = CustomConfigTest.CustomServerConfig.class)
public class CustomConfigTest {
@@ -25,11 +25,11 @@ public class CustomConfigTest {
Assertions.assertTrue(updateEmailFeature.get().isEnabled());
}
public static class CustomServerConfig implements KeycloakTestServerConfig {
public static class CustomServerConfig implements KeycloakServerConfig {
@Override
public Set<String> features() {
return Set.of("update-email");
public KeycloakServerConfigBuilder configure(KeycloakServerConfigBuilder config) {
return config.features(Profile.Feature.UPDATE_EMAIL);
}
}
@@ -5,20 +5,19 @@ import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.keycloak.events.EventType;
import org.keycloak.test.framework.annotations.InjectEvents;
import org.keycloak.test.framework.oauth.nimbus.annotations.InjectOAuthClient;
import org.keycloak.test.framework.ui.annotations.InjectPage;
import org.keycloak.test.framework.ui.annotations.InjectWebDriver;
import org.keycloak.test.framework.annotations.KeycloakIntegrationTest;
import org.keycloak.test.framework.events.Events;
import org.keycloak.test.framework.oauth.nimbus.OAuthClient;
import org.keycloak.test.framework.oauth.nimbus.annotations.InjectOAuthClient;
import org.keycloak.test.framework.ui.annotations.InjectPage;
import org.keycloak.test.framework.ui.annotations.InjectWebDriver;
import org.keycloak.test.framework.ui.page.LoginPage;
import org.keycloak.test.framework.server.KeycloakTestServerConfig;
import org.openqa.selenium.WebDriver;
import java.io.IOException;
import java.net.URL;
@KeycloakIntegrationTest(config = EventsTest.ServerConfig.class)
@KeycloakIntegrationTest
public class EventsTest {
@InjectEvents
@@ -50,11 +49,4 @@ public class EventsTest {
Assertions.assertEquals(EventType.CLIENT_LOGIN, events.poll().getType());
}
public static class ServerConfig implements KeycloakTestServerConfig {
@Override
public boolean enableSysLog() {
return true;
}
}
}
@@ -1,7 +1,5 @@
package org.keycloak.test.examples;
import io.quarkus.maven.dependency.Dependency;
import io.quarkus.maven.dependency.DependencyBuilder;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
@@ -12,11 +10,11 @@ import org.junit.jupiter.api.Test;
import org.keycloak.test.framework.annotations.InjectRealm;
import org.keycloak.test.framework.annotations.KeycloakIntegrationTest;
import org.keycloak.test.framework.realm.ManagedRealm;
import org.keycloak.test.framework.server.KeycloakTestServerConfig;
import org.keycloak.test.framework.server.KeycloakServerConfigBuilder;
import org.keycloak.test.framework.server.KeycloakServerConfig;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Set;
/**
@@ -43,10 +41,12 @@ public class MyCustomProviderTest {
} catch (IOException ignored) {}
}
public static class ServerConfig implements KeycloakTestServerConfig {
public static class ServerConfig implements KeycloakServerConfig {
public Set<Dependency> dependencies() {
return Set.of(new DependencyBuilder().setGroupId("org.keycloak.test").setArtifactId("keycloak-test-framework-example-providers").build());
@Override
public KeycloakServerConfigBuilder configure(KeycloakServerConfigBuilder config) {
return config.dependency("org.keycloak.test", "keycloak-test-framework-example-providers");
}
}
}