Add support to select supplier for a given type (#31292)

Closes #30609

Signed-off-by: stianst <stianst@gmail.com>
This commit is contained in:
Stian Thorgersen 2024-07-16 10:22:00 +02:00 committed by GitHub
parent 73247f585a
commit 479e2132fc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 173 additions and 5 deletions

2
.gitignore vendored
View file

@ -112,3 +112,5 @@ node_modules
# JENV # JENV
.java-version .java-version
.env

View file

@ -0,0 +1,57 @@
package org.keycloak.test.framework.config;
import org.keycloak.test.framework.injection.ValueTypeAlias;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
public class Config {
private final static Config instance = new Config();
private Properties localEnv = new Properties();
private Config() {
File envFile = new File(".env");
if (envFile.isFile()) {
try {
localEnv.load(new FileInputStream(envFile));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
public static Config getInstance() {
return instance;
}
public String getSelectedSupplier(Class valueType) {
return getString("kc-test-" + ValueTypeAlias.getAlias(valueType));
}
public String getString(String key) {
String propKey = key.replace('-', '.');
String envKey = key.replace('-', '_').toUpperCase();
String value = System.getProperty(propKey);
if (value != null) {
return value;
}
value = System.getenv(envKey);
if (value != null) {
return value;
}
value = localEnv.getProperty(envKey);
if (value != null) {
return value;
}
return null;
}
}

View file

@ -2,10 +2,16 @@ package org.keycloak.test.framework.database;
public class DevFileDatabaseSupplier extends AbstractDatabaseSupplier { public class DevFileDatabaseSupplier extends AbstractDatabaseSupplier {
public static final String VENDOR = "dev-file";
@Override @Override
TestDatabase getTestDatabase() { TestDatabase getTestDatabase() {
DatabaseConfig databaseConfig = new DatabaseConfig().vendor("dev-file"); DatabaseConfig databaseConfig = new DatabaseConfig().vendor(VENDOR);
return new TestDatabase(databaseConfig); return new TestDatabase(databaseConfig);
} }
@Override
public String getAlias() {
return VENDOR;
}
} }

View file

@ -2,10 +2,16 @@ package org.keycloak.test.framework.database;
public class DevMemDatabaseSupplier extends AbstractDatabaseSupplier { public class DevMemDatabaseSupplier extends AbstractDatabaseSupplier {
public static final String VENDOR = "dev-mem";
@Override @Override
TestDatabase getTestDatabase() { TestDatabase getTestDatabase() {
DatabaseConfig databaseConfig = new DatabaseConfig().vendor("dev-mem"); DatabaseConfig databaseConfig = new DatabaseConfig().vendor(VENDOR);
return new TestDatabase(databaseConfig); return new TestDatabase(databaseConfig);
} }
@Override
public String getAlias() {
return VENDOR;
}
} }

View file

@ -2,14 +2,20 @@ package org.keycloak.test.framework.database;
public class PostgresDatabaseSupplier extends AbstractDatabaseSupplier { public class PostgresDatabaseSupplier extends AbstractDatabaseSupplier {
public static final String VENDOR = "postgres";
@Override @Override
TestDatabase getTestDatabase() { TestDatabase getTestDatabase() {
DatabaseConfig databaseConfig = new DatabaseConfig() DatabaseConfig databaseConfig = new DatabaseConfig()
.vendor("postgres") .vendor(VENDOR)
.username("keycloak") .username("keycloak")
.password("keycloak") .password("keycloak")
.containerImage("the-postgres-container:the-version"); .containerImage("the-postgres-container:the-version");
return new TestDatabase(databaseConfig); return new TestDatabase(databaseConfig);
} }
@Override
public String getAlias() {
return VENDOR;
}
} }

View file

@ -2,9 +2,11 @@ package org.keycloak.test.framework.injection;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.api.extension.ExtensionContext;
import org.keycloak.test.framework.config.Config;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
@ -209,10 +211,48 @@ public class Registry {
} }
private void loadSuppliers() { private void loadSuppliers() {
ServiceLoader.load(Supplier.class).iterator().forEachRemaining(suppliers::add); Iterator<Supplier> supplierIterator = ServiceLoader.load(Supplier.class).iterator();
Set<Class> loadedValueTypes = new HashSet<>();
Set<Supplier> skippedSuppliers = new HashSet<>();
while (supplierIterator.hasNext()) {
Supplier supplier = supplierIterator.next();
boolean shouldAdd = false;
Class supplierValueType = supplier.getValueType();
if (!loadedValueTypes.contains(supplierValueType)) {
String requestedSupplier = Config.getInstance().getSelectedSupplier(supplierValueType);
if (requestedSupplier != null) {
if (requestedSupplier.equals(supplier.getAlias())) {
shouldAdd = true;
}
} else {
shouldAdd = true;
}
}
if (shouldAdd) {
suppliers.add(supplier);
loadedValueTypes.add(supplierValueType);
} else {
skippedSuppliers.add(supplier);
}
}
if (LOGGER.isTraceEnabled()) { if (LOGGER.isTraceEnabled()) {
LOGGER.tracev("Suppliers: {0}", suppliers.stream().map(s -> s.getClass().getSimpleName()).collect(Collectors.joining(", "))); StringBuilder loaded = new StringBuilder();
loaded.append("Loaded suppliers:");
for (Supplier s : suppliers) {
loaded.append("\n - " + ValueTypeAlias.getAlias(s.getValueType()) + " --> " + s.getAlias());
}
LOGGER.trace(loaded.toString());
StringBuilder skipped = new StringBuilder();
skipped.append("Skipped suppliers:");
for (Supplier s : skippedSuppliers) {
skipped.append("\n - " + ValueTypeAlias.getAlias(s.getValueType()) + " --> " + s.getAlias());
}
LOGGER.trace(skipped.toString());
} }
} }

View file

@ -14,4 +14,8 @@ public interface Supplier<T, S extends Annotation> {
default void close(T instance) {} default void close(T instance) {}
default String getAlias() {
return getClass().getSimpleName();
}
} }

View file

@ -0,0 +1,25 @@
package org.keycloak.test.framework.injection;
import org.keycloak.test.framework.database.TestDatabase;
import org.keycloak.test.framework.server.KeycloakTestServer;
import org.openqa.selenium.WebDriver;
import java.util.Map;
public class ValueTypeAlias {
private static final Map<Class, String> aliases = Map.of(
WebDriver.class, "browser",
KeycloakTestServer.class, "server",
TestDatabase.class, "database"
);
public static String getAlias(Class clazz) {
String alias = aliases.get(clazz);
if (alias == null) {
alias = clazz.getSimpleName();
}
return alias;
}
}

View file

@ -12,4 +12,8 @@ public class DistributionKeycloakTestServerSupplier extends AbstractKeycloakTest
return true; return true;
} }
@Override
public String getAlias() {
return "distribution";
}
} }

View file

@ -12,4 +12,8 @@ public class EmbeddedKeycloakTestServerSupplier extends AbstractKeycloakTestServ
return true; return true;
} }
@Override
public String getAlias() {
return "embedded";
}
} }

View file

@ -12,4 +12,8 @@ public class RemoteKeycloakTestServerSupplier extends AbstractKeycloakTestServer
return false; return false;
} }
@Override
public String getAlias() {
return "remote";
}
} }

View file

@ -34,4 +34,10 @@ public class ChromeWebDriverSupplier implements Supplier<WebDriver, TestWebDrive
public void close(WebDriver instance) { public void close(WebDriver instance) {
instance.quit(); instance.quit();
} }
@Override
public String getAlias() {
return "chrome";
}
} }

View file

@ -35,4 +35,8 @@ public class FirefoxWebDriverSupplier implements Supplier<WebDriver, TestWebDriv
instance.quit(); instance.quit();
} }
@Override
public String getAlias() {
return "firefox";
}
} }