Add conditional workflow for test-poc (#31406)
Signed-off-by: stianst <stianst@gmail.com>
This commit is contained in:
parent
64c6dc00c0
commit
7216967465
22 changed files with 274 additions and 226 deletions
3
.github/actions/conditional/action.yml
vendored
3
.github/actions/conditional/action.yml
vendored
|
@ -22,6 +22,9 @@ outputs:
|
||||||
ci-webauthn:
|
ci-webauthn:
|
||||||
description: Should "ci.yml" execute (WebAuthn)
|
description: Should "ci.yml" execute (WebAuthn)
|
||||||
value: ${{ steps.changes.outputs.ci-webauthn }}
|
value: ${{ steps.changes.outputs.ci-webauthn }}
|
||||||
|
ci-test-poc:
|
||||||
|
description: Should "ci.yml" execute (Test PoC)
|
||||||
|
value: ${{ steps.changes.outputs.ci-test-poc }}
|
||||||
operator:
|
operator:
|
||||||
description: Should "operator-ci.yml" execute
|
description: Should "operator-ci.yml" execute
|
||||||
value: ${{ steps.changes.outputs.operator }}
|
value: ${{ steps.changes.outputs.operator }}
|
||||||
|
|
2
.github/actions/conditional/conditions
vendored
2
.github/actions/conditional/conditions
vendored
|
@ -48,3 +48,5 @@ js/libs/ui-shared/ ci ci-webauthn
|
||||||
themes/ codeql-themes
|
themes/ codeql-themes
|
||||||
|
|
||||||
testsuite::database-suite ci-store
|
testsuite::database-suite ci-store
|
||||||
|
|
||||||
|
test-poc/ ci ci-test-poc
|
22
.github/workflows/ci.yml
vendored
22
.github/workflows/ci.yml
vendored
|
@ -34,6 +34,7 @@ jobs:
|
||||||
ci-sssd: ${{ steps.conditional.outputs.ci-sssd }}
|
ci-sssd: ${{ steps.conditional.outputs.ci-sssd }}
|
||||||
ci-webauthn: ${{ steps.conditional.outputs.ci-webauthn }}
|
ci-webauthn: ${{ steps.conditional.outputs.ci-webauthn }}
|
||||||
ci-store-matrix: ${{ steps.conditional-stores.outputs.matrix }}
|
ci-store-matrix: ${{ steps.conditional-stores.outputs.matrix }}
|
||||||
|
ci-test-poc: ${{ steps.conditional.outputs.ci-test-poc }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
@ -863,6 +864,26 @@ jobs:
|
||||||
with:
|
with:
|
||||||
job-id: migration-tests-${{ matrix.old-version }}-${{ matrix.database }}
|
job-id: migration-tests-${{ matrix.old-version }}-${{ matrix.database }}
|
||||||
|
|
||||||
|
test-poc:
|
||||||
|
name: Test PoC
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: needs.conditional.outputs.ci-test-poc == 'true'
|
||||||
|
needs:
|
||||||
|
- conditional
|
||||||
|
- build
|
||||||
|
timeout-minutes: 30
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- id: integration-test-setup
|
||||||
|
name: Integration test setup
|
||||||
|
uses: ./.github/actions/integration-test-setup
|
||||||
|
|
||||||
|
- name: Run tests
|
||||||
|
run: |
|
||||||
|
cd test-poc
|
||||||
|
mvn clean install
|
||||||
|
|
||||||
check:
|
check:
|
||||||
name: Status Check - Keycloak CI
|
name: Status Check - Keycloak CI
|
||||||
if: always()
|
if: always()
|
||||||
|
@ -886,6 +907,7 @@ jobs:
|
||||||
- sssd-unit-tests
|
- sssd-unit-tests
|
||||||
- migration-tests
|
- migration-tests
|
||||||
- external-infinispan-tests
|
- external-infinispan-tests
|
||||||
|
- test-poc
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
|
@ -7,13 +7,13 @@ import java.util.Optional;
|
||||||
public class NoAdminUserKeycloakTestServerConfig implements KeycloakTestServerConfig {
|
public class NoAdminUserKeycloakTestServerConfig implements KeycloakTestServerConfig {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<String> adminUserName() {
|
public String adminUserName() {
|
||||||
return Optional.empty();
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<String> adminUserPassword() {
|
public String adminUserPassword() {
|
||||||
return Optional.empty();
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,18 +18,8 @@ public class PagesTest {
|
||||||
@Test
|
@Test
|
||||||
public void testLoginFromWelcome() {
|
public void testLoginFromWelcome() {
|
||||||
welcomePage.navigateTo();
|
welcomePage.navigateTo();
|
||||||
try {
|
|
||||||
Thread.sleep(1000);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
loginPage.fillLogin("admin", "admin");
|
loginPage.fillLogin("admin", "admin");
|
||||||
loginPage.submit();
|
loginPage.submit();
|
||||||
try {
|
|
||||||
Thread.sleep(1000);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,8 @@ package org.keycloak.test.framework.admin;
|
||||||
|
|
||||||
import org.keycloak.admin.client.Keycloak;
|
import org.keycloak.admin.client.Keycloak;
|
||||||
import org.keycloak.test.framework.TestAdminClient;
|
import org.keycloak.test.framework.TestAdminClient;
|
||||||
import org.keycloak.test.framework.injection.InstanceWrapper;
|
import org.keycloak.test.framework.injection.InstanceContext;
|
||||||
import org.keycloak.test.framework.injection.LifeCycle;
|
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.RequestedInstance;
|
||||||
import org.keycloak.test.framework.injection.Supplier;
|
import org.keycloak.test.framework.injection.Supplier;
|
||||||
import org.keycloak.test.framework.server.KeycloakTestServer;
|
import org.keycloak.test.framework.server.KeycloakTestServer;
|
||||||
|
@ -22,25 +21,24 @@ public class KeycloakAdminClientSupplier implements Supplier<Keycloak, TestAdmin
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InstanceWrapper<Keycloak, TestAdminClient> getValue(Registry registry, TestAdminClient annotation) {
|
public Keycloak getValue(InstanceContext<Keycloak, TestAdminClient> instanceContext) {
|
||||||
InstanceWrapper<Keycloak, TestAdminClient> wrapper = new InstanceWrapper<>(this, annotation);
|
KeycloakTestServer testServer = instanceContext.getDependency(KeycloakTestServer.class);
|
||||||
|
return Keycloak.getInstance(testServer.getBaseUrl(), "master", "admin", "admin", "admin-cli");
|
||||||
KeycloakTestServer testServer = registry.getDependency(KeycloakTestServer.class, wrapper);
|
|
||||||
|
|
||||||
Keycloak keycloak = Keycloak.getInstance(testServer.getBaseUrl(), "master", "admin", "admin", "admin-cli");
|
|
||||||
wrapper.setValue(keycloak, LifeCycle.GLOBAL);
|
|
||||||
|
|
||||||
return wrapper;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean compatible(InstanceWrapper<Keycloak, TestAdminClient> a, RequestedInstance<Keycloak, TestAdminClient> b) {
|
public LifeCycle getDefaultLifecycle() {
|
||||||
|
return LifeCycle.GLOBAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean compatible(InstanceContext<Keycloak, TestAdminClient> a, RequestedInstance<Keycloak, TestAdminClient> b) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close(Keycloak keycloak) {
|
public void close(InstanceContext<Keycloak, TestAdminClient> instanceContext) {
|
||||||
keycloak.close();
|
instanceContext.getValue().close();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
package org.keycloak.test.framework.database;
|
package org.keycloak.test.framework.database;
|
||||||
|
|
||||||
import org.keycloak.test.framework.KeycloakTestDatabase;
|
import org.keycloak.test.framework.KeycloakTestDatabase;
|
||||||
import org.keycloak.test.framework.injection.InstanceWrapper;
|
import org.keycloak.test.framework.injection.InstanceContext;
|
||||||
import org.keycloak.test.framework.injection.LifeCycle;
|
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.RequestedInstance;
|
||||||
import org.keycloak.test.framework.injection.Supplier;
|
import org.keycloak.test.framework.injection.Supplier;
|
||||||
|
|
||||||
|
@ -23,17 +22,26 @@ public abstract class AbstractDatabaseSupplier implements Supplier<TestDatabase,
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InstanceWrapper<TestDatabase, KeycloakTestDatabase> getValue(Registry registry, KeycloakTestDatabase annotation) {
|
public TestDatabase getValue(InstanceContext<TestDatabase, KeycloakTestDatabase> instanceContext) {
|
||||||
TestDatabase testDatabase = getTestDatabase();
|
TestDatabase testDatabase = getTestDatabase();
|
||||||
testDatabase.start();
|
testDatabase.start();
|
||||||
return new InstanceWrapper<>(this, annotation, testDatabase, LifeCycle.GLOBAL);
|
return testDatabase;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean compatible(InstanceWrapper<TestDatabase, KeycloakTestDatabase> a, RequestedInstance<TestDatabase, KeycloakTestDatabase> b) {
|
public boolean compatible(InstanceContext<TestDatabase, KeycloakTestDatabase> a, RequestedInstance<TestDatabase, KeycloakTestDatabase> b) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LifeCycle getDefaultLifecycle() {
|
||||||
|
return LifeCycle.GLOBAL;
|
||||||
|
}
|
||||||
|
|
||||||
abstract TestDatabase getTestDatabase();
|
abstract TestDatabase getTestDatabase();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close(InstanceContext<TestDatabase, KeycloakTestDatabase> instanceContext) {
|
||||||
|
instanceContext.getValue().stop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,30 +6,35 @@ import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public class InstanceWrapper<T, A extends Annotation> {
|
public class InstanceContext<T, A extends Annotation> {
|
||||||
|
|
||||||
|
private final Registry registry;
|
||||||
private final Supplier<T, A> supplier;
|
private final Supplier<T, A> supplier;
|
||||||
private final A annotation;
|
private final A annotation;
|
||||||
private final Set<InstanceWrapper<T, A>> dependencies = new HashSet<>();
|
private final Set<InstanceContext<T, A>> dependencies = new HashSet<>();
|
||||||
private T value;
|
private T value;
|
||||||
|
private Class<? extends T> requestedValueType;
|
||||||
private LifeCycle lifeCycle;
|
private LifeCycle lifeCycle;
|
||||||
private final Map<String, Object> notes = new HashMap<>();
|
private final Map<String, Object> notes = new HashMap<>();
|
||||||
|
|
||||||
public InstanceWrapper(Supplier<T, A> supplier, A annotation) {
|
public InstanceContext(Registry registry, Supplier<T, A> supplier, A annotation, Class<? extends T> requestedValueType) {
|
||||||
|
this.registry = registry;
|
||||||
this.supplier = supplier;
|
this.supplier = supplier;
|
||||||
this.annotation = annotation;
|
this.annotation = annotation;
|
||||||
|
this.requestedValueType = requestedValueType;
|
||||||
|
this.lifeCycle = supplier.getLifeCycle(annotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
public InstanceWrapper(Supplier<T, A> supplier, A annotation, T value, LifeCycle lifeCycle) {
|
public <D> D getDependency(Class<D> typeClazz) {
|
||||||
this.supplier = supplier;
|
return registry.getDependency(typeClazz, this);
|
||||||
this.annotation = annotation;
|
|
||||||
this.value = value;
|
|
||||||
this.lifeCycle = lifeCycle;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setValue(T value, LifeCycle lifeCycle) {
|
public Registry getRegistry() {
|
||||||
|
return registry;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setValue(T value) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
this.lifeCycle = lifeCycle;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Supplier<T, A> getSupplier() {
|
public Supplier<T, A> getSupplier() {
|
||||||
|
@ -40,6 +45,10 @@ public class InstanceWrapper<T, A extends Annotation> {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Class<? extends T> getRequestedValueType() {
|
||||||
|
return requestedValueType;
|
||||||
|
}
|
||||||
|
|
||||||
public LifeCycle getLifeCycle() {
|
public LifeCycle getLifeCycle() {
|
||||||
return lifeCycle;
|
return lifeCycle;
|
||||||
}
|
}
|
||||||
|
@ -48,12 +57,12 @@ public class InstanceWrapper<T, A extends Annotation> {
|
||||||
return annotation;
|
return annotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<InstanceWrapper<T, A>> getDependencies() {
|
public Set<InstanceContext<T, A>> getDependencies() {
|
||||||
return dependencies;
|
return dependencies;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerDependency(InstanceWrapper<T, A> instanceWrapper) {
|
public void registerDependency(InstanceContext<T, A> instanceContext) {
|
||||||
dependencies.add(instanceWrapper);
|
dependencies.add(instanceContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addNote(String key, Object value) {
|
public void addNote(String key, Object value) {
|
|
@ -22,7 +22,7 @@ public class Registry {
|
||||||
|
|
||||||
private ExtensionContext currentContext;
|
private ExtensionContext currentContext;
|
||||||
private final List<Supplier<?, ?>> suppliers = new LinkedList<>();
|
private final List<Supplier<?, ?>> suppliers = new LinkedList<>();
|
||||||
private final List<InstanceWrapper<?, ?>> deployedInstances = new LinkedList<>();
|
private final List<InstanceContext<?, ?>> deployedInstances = new LinkedList<>();
|
||||||
private final List<RequestedInstance<?, ?>> requestedInstances = new LinkedList<>();
|
private final List<RequestedInstance<?, ?>> requestedInstances = new LinkedList<>();
|
||||||
|
|
||||||
public Registry() {
|
public Registry() {
|
||||||
|
@ -38,8 +38,8 @@ public class Registry {
|
||||||
this.currentContext = currentContext;
|
this.currentContext = currentContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> T getDependency(Class<T> typeClass, InstanceWrapper dependent) {
|
public <T> T getDependency(Class<T> typeClass, InstanceContext dependent) {
|
||||||
InstanceWrapper dependency = getDeployedInstance(typeClass);
|
InstanceContext dependency = getDeployedInstance(typeClass);
|
||||||
if (dependency != null) {
|
if (dependency != null) {
|
||||||
dependency.registerDependency(dependent);
|
dependency.registerDependency(dependent);
|
||||||
|
|
||||||
|
@ -54,7 +54,8 @@ public class Registry {
|
||||||
|
|
||||||
RequestedInstance requestedDependency = getRequestedInstance(typeClass);
|
RequestedInstance requestedDependency = getRequestedInstance(typeClass);
|
||||||
if (requestedDependency != null) {
|
if (requestedDependency != null) {
|
||||||
dependency = requestedDependency.getSupplier().getValue(this, requestedDependency.getAnnotation(), typeClass);
|
dependency = new InstanceContext<Object, Annotation>(this, requestedDependency.getSupplier(), requestedDependency.getAnnotation(), requestedDependency.getValueType());
|
||||||
|
dependency.setValue(requestedDependency.getSupplier().getValue(dependency));
|
||||||
dependency.registerDependency(dependent);
|
dependency.registerDependency(dependent);
|
||||||
deployedInstances.add(dependency);
|
deployedInstances.add(dependency);
|
||||||
|
|
||||||
|
@ -70,7 +71,10 @@ public class Registry {
|
||||||
Optional<Supplier<?, ?>> supplied = suppliers.stream().filter(s -> s.getValueType().equals(typeClass)).findFirst();
|
Optional<Supplier<?, ?>> supplied = suppliers.stream().filter(s -> s.getValueType().equals(typeClass)).findFirst();
|
||||||
if (supplied.isPresent()) {
|
if (supplied.isPresent()) {
|
||||||
Supplier<T, ?> supplier = (Supplier<T, ?>) supplied.get();
|
Supplier<T, ?> supplier = (Supplier<T, ?>) supplied.get();
|
||||||
dependency = supplier.getValue(this, null, typeClass);
|
dependency = new InstanceContext(this, supplier, null, typeClass);
|
||||||
|
dependency.registerDependency(dependent);
|
||||||
|
dependency.setValue(supplier.getValue(dependency));
|
||||||
|
|
||||||
deployedInstances.add(dependency);
|
deployedInstances.add(dependency);
|
||||||
|
|
||||||
if (LOGGER.isTraceEnabled()) {
|
if (LOGGER.isTraceEnabled()) {
|
||||||
|
@ -114,9 +118,9 @@ public class Registry {
|
||||||
Iterator<RequestedInstance<?, ?>> itr = requestedInstances.iterator();
|
Iterator<RequestedInstance<?, ?>> itr = requestedInstances.iterator();
|
||||||
while (itr.hasNext()) {
|
while (itr.hasNext()) {
|
||||||
RequestedInstance<?, ?> requestedInstance = itr.next();
|
RequestedInstance<?, ?> requestedInstance = itr.next();
|
||||||
InstanceWrapper deployedInstance = getDeployedInstance(requestedInstance);
|
InstanceContext deployedInstance = getDeployedInstance(requestedInstance);
|
||||||
if (deployedInstance != null) {
|
if (deployedInstance != null) {
|
||||||
if (deployedInstance.getSupplier().compatible(deployedInstance, requestedInstance)) {
|
if (requestedInstance.getLifeCycle().equals(deployedInstance.getLifeCycle()) && deployedInstance.getSupplier().compatible(deployedInstance, requestedInstance)) {
|
||||||
if (LOGGER.isTraceEnabled()) {
|
if (LOGGER.isTraceEnabled()) {
|
||||||
LOGGER.tracev("Reusing compatible: {0}",
|
LOGGER.tracev("Reusing compatible: {0}",
|
||||||
deployedInstance.getSupplier().getClass().getSimpleName());
|
deployedInstance.getSupplier().getClass().getSimpleName());
|
||||||
|
@ -140,7 +144,8 @@ public class Registry {
|
||||||
while (itr.hasNext()) {
|
while (itr.hasNext()) {
|
||||||
RequestedInstance requestedInstance = itr.next();
|
RequestedInstance requestedInstance = itr.next();
|
||||||
|
|
||||||
InstanceWrapper instance = requestedInstance.getSupplier().getValue(this, requestedInstance.getAnnotation(), requestedInstance.getValueType());
|
InstanceContext instance = new InstanceContext(this, requestedInstance.getSupplier(), requestedInstance.getAnnotation(), requestedInstance.getValueType());
|
||||||
|
instance.setValue(requestedInstance.getSupplier().getValue(instance));
|
||||||
|
|
||||||
if (LOGGER.isTraceEnabled()) {
|
if (LOGGER.isTraceEnabled()) {
|
||||||
LOGGER.tracev("Created instance: {0}",
|
LOGGER.tracev("Created instance: {0}",
|
||||||
|
@ -155,7 +160,7 @@ public class Registry {
|
||||||
|
|
||||||
private void injectFields(Object testInstance) {
|
private void injectFields(Object testInstance) {
|
||||||
for (Field f : testInstance.getClass().getDeclaredFields()) {
|
for (Field f : testInstance.getClass().getDeclaredFields()) {
|
||||||
InstanceWrapper<?, ?> instance = getDeployedInstance(f.getType(), f.getAnnotations());
|
InstanceContext<?, ?> instance = getDeployedInstance(f.getType(), f.getAnnotations());
|
||||||
try {
|
try {
|
||||||
f.setAccessible(true);
|
f.setAccessible(true);
|
||||||
f.set(testInstance, instance.getValue());
|
f.set(testInstance, instance.getValue());
|
||||||
|
@ -167,19 +172,19 @@ public class Registry {
|
||||||
|
|
||||||
public void afterAll() {
|
public void afterAll() {
|
||||||
LOGGER.trace("Closing instances with class lifecycle");
|
LOGGER.trace("Closing instances with class lifecycle");
|
||||||
List<InstanceWrapper<?, ?>> destroy = deployedInstances.stream().filter(i -> i.getLifeCycle().equals(LifeCycle.CLASS)).toList();
|
List<InstanceContext<?, ?>> destroy = deployedInstances.stream().filter(i -> i.getLifeCycle().equals(LifeCycle.CLASS)).toList();
|
||||||
destroy.forEach(this::destroy);
|
destroy.forEach(this::destroy);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void afterEach() {
|
public void afterEach() {
|
||||||
LOGGER.trace("Closing instances with method lifecycle");
|
LOGGER.trace("Closing instances with method lifecycle");
|
||||||
List<InstanceWrapper<?, ?>> destroy = deployedInstances.stream().filter(i -> i.getLifeCycle().equals(LifeCycle.METHOD)).toList();
|
List<InstanceContext<?, ?>> destroy = deployedInstances.stream().filter(i -> i.getLifeCycle().equals(LifeCycle.METHOD)).toList();
|
||||||
destroy.forEach(this::destroy);
|
destroy.forEach(this::destroy);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onShutdown() {
|
public void onShutdown() {
|
||||||
LOGGER.trace("Closing instances with global lifecycle");
|
LOGGER.trace("Closing instances with global lifecycle");
|
||||||
List<InstanceWrapper<?, ?>> destroy = deployedInstances.stream().filter(i -> i.getLifeCycle().equals(LifeCycle.GLOBAL)).toList();
|
List<InstanceContext<?, ?>> destroy = deployedInstances.stream().filter(i -> i.getLifeCycle().equals(LifeCycle.GLOBAL)).toList();
|
||||||
destroy.forEach(this::destroy);
|
destroy.forEach(this::destroy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,9 +199,9 @@ public class Registry {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private InstanceWrapper<?, ?> getDeployedInstance(Class<?> valueType, Annotation[] annotations) {
|
private InstanceContext<?, ?> getDeployedInstance(Class<?> valueType, Annotation[] annotations) {
|
||||||
for (Annotation a : annotations) {
|
for (Annotation a : annotations) {
|
||||||
for (InstanceWrapper<?, ?> i : deployedInstances) {
|
for (InstanceContext<?, ?> i : deployedInstances) {
|
||||||
Supplier<?, ?> supplier = i.getSupplier();
|
Supplier<?, ?> supplier = i.getSupplier();
|
||||||
if (supplier.getAnnotationClass().equals(a.annotationType()) && valueType.isAssignableFrom(i.getValue().getClass())) {
|
if (supplier.getAnnotationClass().equals(a.annotationType()) && valueType.isAssignableFrom(i.getValue().getClass())) {
|
||||||
return i;
|
return i;
|
||||||
|
@ -206,23 +211,23 @@ public class Registry {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void destroy(InstanceWrapper instanceWrapper) {
|
private void destroy(InstanceContext instanceContext) {
|
||||||
boolean removed = deployedInstances.remove(instanceWrapper);
|
boolean removed = deployedInstances.remove(instanceContext);
|
||||||
if (removed) {
|
if (removed) {
|
||||||
Set<InstanceWrapper> dependencies = instanceWrapper.getDependencies();
|
Set<InstanceContext> dependencies = instanceContext.getDependencies();
|
||||||
dependencies.forEach(this::destroy);
|
dependencies.forEach(this::destroy);
|
||||||
instanceWrapper.getSupplier().close(instanceWrapper);
|
instanceContext.getSupplier().close(instanceContext);
|
||||||
|
|
||||||
if (LOGGER.isTraceEnabled()) {
|
if (LOGGER.isTraceEnabled()) {
|
||||||
LOGGER.tracev("Closed instance: {0}",
|
LOGGER.tracev("Closed instance: {0}",
|
||||||
instanceWrapper.getSupplier().getClass().getSimpleName());
|
instanceContext.getSupplier().getClass().getSimpleName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private InstanceWrapper getDeployedInstance(RequestedInstance requestedInstance) {
|
private InstanceContext getDeployedInstance(RequestedInstance requestedInstance) {
|
||||||
Class requestedValueType = requestedInstance.getValueType();
|
Class requestedValueType = requestedInstance.getValueType();
|
||||||
for (InstanceWrapper<?, ?> i : deployedInstances) {
|
for (InstanceContext<?, ?> i : deployedInstances) {
|
||||||
if (requestedValueType != null) {
|
if (requestedValueType != null) {
|
||||||
if (requestedValueType.isAssignableFrom(i.getValue().getClass())) {
|
if (requestedValueType.isAssignableFrom(i.getValue().getClass())) {
|
||||||
return i;
|
return i;
|
||||||
|
@ -280,7 +285,7 @@ public class Registry {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private InstanceWrapper getDeployedInstance(Class typeClass) {
|
private InstanceContext getDeployedInstance(Class typeClass) {
|
||||||
return deployedInstances.stream().filter(i -> i.getSupplier().getValueType().equals(typeClass)).findFirst().orElse(null);
|
return deployedInstances.stream().filter(i -> i.getSupplier().getValueType().equals(typeClass)).findFirst().orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,11 +7,13 @@ public class RequestedInstance<T, A extends Annotation> {
|
||||||
private final Supplier<T, A> supplier;
|
private final Supplier<T, A> supplier;
|
||||||
private final A annotation;
|
private final A annotation;
|
||||||
private final Class<? extends T> valueType;
|
private final Class<? extends T> valueType;
|
||||||
|
private final LifeCycle lifeCycle;
|
||||||
|
|
||||||
public RequestedInstance(Supplier<T, A> supplier, A annotation, Class<? extends T> valueType) {
|
public RequestedInstance(Supplier<T, A> supplier, A annotation, Class<? extends T> valueType) {
|
||||||
this.supplier = supplier;
|
this.supplier = supplier;
|
||||||
this.annotation = annotation;
|
this.annotation = annotation;
|
||||||
this.valueType = valueType;
|
this.valueType = valueType;
|
||||||
|
this.lifeCycle = supplier.getLifeCycle(annotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Supplier<T, A> getSupplier() {
|
public Supplier<T, A> getSupplier() {
|
||||||
|
@ -25,4 +27,8 @@ public class RequestedInstance<T, A extends Annotation> {
|
||||||
public Class<? extends T> getValueType() {
|
public Class<? extends T> getValueType() {
|
||||||
return valueType;
|
return valueType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LifeCycle getLifeCycle() {
|
||||||
|
return lifeCycle;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
package org.keycloak.test.framework.injection;
|
package org.keycloak.test.framework.injection;
|
||||||
|
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
public interface Supplier<T, S extends Annotation> {
|
public interface Supplier<T, S extends Annotation> {
|
||||||
|
|
||||||
|
@ -8,19 +11,29 @@ public interface Supplier<T, S extends Annotation> {
|
||||||
|
|
||||||
Class<T> getValueType();
|
Class<T> getValueType();
|
||||||
|
|
||||||
InstanceWrapper<T, S> getValue(Registry registry, S annotation);
|
T getValue(InstanceContext<T, S> instanceContext);
|
||||||
|
|
||||||
default InstanceWrapper<T, S> getValue(Registry registry, S annotation, Class<? extends T> valueType) {
|
default LifeCycle getLifeCycle(S annotation) {
|
||||||
return getValue(registry, annotation);
|
if (annotation != null) {
|
||||||
|
Optional<Method> lifecycle = Arrays.stream(annotation.annotationType().getMethods()).filter(m -> m.getName().equals("lifecycle")).findFirst();
|
||||||
|
if (lifecycle.isPresent()) {
|
||||||
|
try {
|
||||||
|
return (LifeCycle) lifecycle.get().invoke(annotation);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return getDefaultLifecycle();
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean compatible(InstanceWrapper<T, S> a, RequestedInstance<T, S> b);
|
default LifeCycle getDefaultLifecycle() {
|
||||||
|
return LifeCycle.CLASS;
|
||||||
default void close(T value) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
default void close(InstanceWrapper<T, S> instanceWrapper) {
|
boolean compatible(InstanceContext<T, S> a, RequestedInstance<T, S> b);
|
||||||
close(instanceWrapper.getValue());
|
|
||||||
|
default void close(InstanceContext<T, S> instanceContext) {
|
||||||
}
|
}
|
||||||
|
|
||||||
default String getAlias() {
|
default String getAlias() {
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
package org.keycloak.test.framework.page;
|
package org.keycloak.test.framework.page;
|
||||||
|
|
||||||
import org.keycloak.test.framework.injection.InstanceWrapper;
|
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.RequestedInstance;
|
||||||
import org.keycloak.test.framework.injection.Supplier;
|
import org.keycloak.test.framework.injection.Supplier;
|
||||||
import org.openqa.selenium.WebDriver;
|
import org.openqa.selenium.WebDriver;
|
||||||
|
@ -21,21 +19,14 @@ public class PageSupplier implements Supplier<AbstractPage, TestPage> {
|
||||||
return AbstractPage.class;
|
return AbstractPage.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
public InstanceWrapper<AbstractPage, TestPage> getValue(Registry registry, TestPage annotation) {
|
@Override
|
||||||
throw new UnsupportedOperationException();
|
public AbstractPage getValue(InstanceContext<AbstractPage, TestPage> instanceContext) {
|
||||||
|
WebDriver webDriver = instanceContext.getDependency(WebDriver.class);
|
||||||
|
return createPage(webDriver, instanceContext.getRequestedValueType());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InstanceWrapper<AbstractPage, TestPage> getValue(Registry registry, TestPage annotation, Class<? extends AbstractPage> valueType) {
|
public boolean compatible(InstanceContext<AbstractPage, TestPage> a, RequestedInstance<AbstractPage, TestPage> b) {
|
||||||
InstanceWrapper<AbstractPage, TestPage> instanceWrapper = new InstanceWrapper<>(this, annotation);
|
|
||||||
WebDriver webDriver = registry.getDependency(WebDriver.class, instanceWrapper);
|
|
||||||
AbstractPage page = createPage(webDriver, valueType);
|
|
||||||
instanceWrapper.setValue(page, LifeCycle.CLASS);
|
|
||||||
return instanceWrapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean compatible(InstanceWrapper<AbstractPage, TestPage> a, RequestedInstance<AbstractPage, TestPage> b) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,8 @@ import org.keycloak.admin.client.resource.ClientResource;
|
||||||
import org.keycloak.admin.client.resource.RealmResource;
|
import org.keycloak.admin.client.resource.RealmResource;
|
||||||
import org.keycloak.representations.idm.ClientRepresentation;
|
import org.keycloak.representations.idm.ClientRepresentation;
|
||||||
import org.keycloak.test.framework.TestClient;
|
import org.keycloak.test.framework.TestClient;
|
||||||
import org.keycloak.test.framework.injection.InstanceWrapper;
|
import org.keycloak.test.framework.injection.InstanceContext;
|
||||||
import org.keycloak.test.framework.injection.LifeCycle;
|
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.RequestedInstance;
|
||||||
import org.keycloak.test.framework.injection.Supplier;
|
import org.keycloak.test.framework.injection.Supplier;
|
||||||
import org.keycloak.test.framework.injection.SupplierHelpers;
|
import org.keycloak.test.framework.injection.SupplierHelpers;
|
||||||
|
@ -27,17 +26,14 @@ public class ClientSupplier implements Supplier<ClientResource, TestClient> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InstanceWrapper<ClientResource, TestClient> getValue(Registry registry, TestClient annotation) {
|
public ClientResource getValue(InstanceContext<ClientResource, TestClient> instanceContext) {
|
||||||
InstanceWrapper<ClientResource, TestClient> wrapper = new InstanceWrapper<>(this, annotation);
|
RealmResource realm = instanceContext.getDependency(RealmResource.class);
|
||||||
LifeCycle lifecycle = annotation.lifecycle();
|
|
||||||
|
|
||||||
RealmResource realm = registry.getDependency(RealmResource.class, wrapper);
|
ClientConfig config = SupplierHelpers.getInstance(instanceContext.getAnnotation().config());
|
||||||
|
|
||||||
ClientConfig config = SupplierHelpers.getInstance(annotation.config());
|
|
||||||
ClientRepresentation clientRepresentation = config.getRepresentation();
|
ClientRepresentation clientRepresentation = config.getRepresentation();
|
||||||
|
|
||||||
if (clientRepresentation.getClientId() == null) {
|
if (clientRepresentation.getClientId() == null) {
|
||||||
String clientId = lifecycle.equals(LifeCycle.GLOBAL) ? config.getClass().getSimpleName() : registry.getCurrentContext().getRequiredTestClass().getSimpleName();
|
String clientId = instanceContext.getLifeCycle().equals(LifeCycle.GLOBAL) ? config.getClass().getSimpleName() : instanceContext.getRegistry().getCurrentContext().getRequiredTestClass().getSimpleName();
|
||||||
clientRepresentation.setClientId(clientId);
|
clientRepresentation.setClientId(clientId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,22 +44,19 @@ public class ClientSupplier implements Supplier<ClientResource, TestClient> {
|
||||||
|
|
||||||
response.close();
|
response.close();
|
||||||
|
|
||||||
wrapper.addNote(CLIENT_UUID_KEY, clientId);
|
instanceContext.addNote(CLIENT_UUID_KEY, clientId);
|
||||||
|
|
||||||
ClientResource clientResource = realm.clients().get(clientId);
|
return realm.clients().get(clientId);
|
||||||
wrapper.setValue(clientResource, lifecycle);
|
|
||||||
|
|
||||||
return wrapper;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean compatible(InstanceWrapper<ClientResource, TestClient> a, RequestedInstance<ClientResource, TestClient> b) {
|
public boolean compatible(InstanceContext<ClientResource, TestClient> a, RequestedInstance<ClientResource, TestClient> b) {
|
||||||
return a.getAnnotation().config().equals(b.getAnnotation().config());
|
return a.getAnnotation().config().equals(b.getAnnotation().config());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close(ClientResource client) {
|
public void close(InstanceContext<ClientResource, TestClient> instanceContext) {
|
||||||
client.remove();
|
instanceContext.getValue().remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,8 @@ import org.keycloak.admin.client.Keycloak;
|
||||||
import org.keycloak.admin.client.resource.RealmResource;
|
import org.keycloak.admin.client.resource.RealmResource;
|
||||||
import org.keycloak.representations.idm.RealmRepresentation;
|
import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
import org.keycloak.test.framework.TestRealm;
|
import org.keycloak.test.framework.TestRealm;
|
||||||
import org.keycloak.test.framework.injection.InstanceWrapper;
|
import org.keycloak.test.framework.injection.InstanceContext;
|
||||||
import org.keycloak.test.framework.injection.LifeCycle;
|
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.RequestedInstance;
|
||||||
import org.keycloak.test.framework.injection.Supplier;
|
import org.keycloak.test.framework.injection.Supplier;
|
||||||
import org.keycloak.test.framework.injection.SupplierHelpers;
|
import org.keycloak.test.framework.injection.SupplierHelpers;
|
||||||
|
@ -26,39 +25,33 @@ public class RealmSupplier implements Supplier<RealmResource, TestRealm> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InstanceWrapper<RealmResource, TestRealm> getValue(Registry registry, TestRealm annotation) {
|
public RealmResource getValue(InstanceContext<RealmResource, TestRealm> instanceContext) {
|
||||||
InstanceWrapper<RealmResource, TestRealm> wrapper = new InstanceWrapper<>(this, annotation);
|
Keycloak adminClient = instanceContext.getDependency(Keycloak.class);
|
||||||
LifeCycle lifecycle = annotation.lifecycle();
|
|
||||||
|
|
||||||
Keycloak adminClient = registry.getDependency(Keycloak.class, wrapper);
|
RealmConfig config = SupplierHelpers.getInstance(instanceContext.getAnnotation().config());
|
||||||
|
|
||||||
RealmConfig config = SupplierHelpers.getInstance(annotation.config());
|
|
||||||
RealmRepresentation realmRepresentation = config.getRepresentation();
|
RealmRepresentation realmRepresentation = config.getRepresentation();
|
||||||
|
|
||||||
if (realmRepresentation.getRealm() == null) {
|
if (realmRepresentation.getRealm() == null) {
|
||||||
String realmName = lifecycle.equals(LifeCycle.GLOBAL) ? config.getClass().getSimpleName() : registry.getCurrentContext().getRequiredTestClass().getSimpleName();
|
String realmName = instanceContext.getLifeCycle().equals(LifeCycle.GLOBAL) ? config.getClass().getSimpleName() : instanceContext.getRegistry().getCurrentContext().getRequiredTestClass().getSimpleName();
|
||||||
realmRepresentation.setRealm(realmName);
|
realmRepresentation.setRealm(realmName);
|
||||||
}
|
}
|
||||||
|
|
||||||
String realmName = realmRepresentation.getRealm();
|
String realmName = realmRepresentation.getRealm();
|
||||||
wrapper.addNote(REALM_NAME_KEY, realmName);
|
instanceContext.addNote(REALM_NAME_KEY, realmName);
|
||||||
|
|
||||||
adminClient.realms().create(realmRepresentation);
|
adminClient.realms().create(realmRepresentation);
|
||||||
|
|
||||||
RealmResource realmResource = adminClient.realm(realmRepresentation.getRealm());
|
return adminClient.realm(realmRepresentation.getRealm());
|
||||||
wrapper.setValue(realmResource, lifecycle);
|
|
||||||
|
|
||||||
return wrapper;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean compatible(InstanceWrapper<RealmResource, TestRealm> a, RequestedInstance<RealmResource, TestRealm> b) {
|
public boolean compatible(InstanceContext<RealmResource, TestRealm> a, RequestedInstance<RealmResource, TestRealm> b) {
|
||||||
return a.getAnnotation().config().equals(b.getAnnotation().config());
|
return a.getAnnotation().config().equals(b.getAnnotation().config());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close(RealmResource realm) {
|
public void close(InstanceContext<RealmResource, TestRealm> instanceContext) {
|
||||||
realm.remove();
|
instanceContext.getValue().remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,8 @@ import org.keycloak.admin.client.resource.RealmResource;
|
||||||
import org.keycloak.admin.client.resource.UserResource;
|
import org.keycloak.admin.client.resource.UserResource;
|
||||||
import org.keycloak.representations.idm.UserRepresentation;
|
import org.keycloak.representations.idm.UserRepresentation;
|
||||||
import org.keycloak.test.framework.TestUser;
|
import org.keycloak.test.framework.TestUser;
|
||||||
import org.keycloak.test.framework.injection.InstanceWrapper;
|
import org.keycloak.test.framework.injection.InstanceContext;
|
||||||
import org.keycloak.test.framework.injection.LifeCycle;
|
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.RequestedInstance;
|
||||||
import org.keycloak.test.framework.injection.Supplier;
|
import org.keycloak.test.framework.injection.Supplier;
|
||||||
import org.keycloak.test.framework.injection.SupplierHelpers;
|
import org.keycloak.test.framework.injection.SupplierHelpers;
|
||||||
|
@ -27,17 +26,14 @@ public class UserSupplier implements Supplier<UserResource, TestUser> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InstanceWrapper<UserResource, TestUser> getValue(Registry registry, TestUser annotation) {
|
public UserResource getValue(InstanceContext<UserResource, TestUser> instanceContext) {
|
||||||
InstanceWrapper<UserResource, TestUser> wrapper = new InstanceWrapper<>(this, annotation);
|
RealmResource realm = instanceContext.getDependency(RealmResource.class);
|
||||||
LifeCycle lifecycle = annotation.lifecycle();
|
|
||||||
|
|
||||||
RealmResource realm = registry.getDependency(RealmResource.class, wrapper);
|
UserConfig config = SupplierHelpers.getInstance(instanceContext.getAnnotation().config());
|
||||||
|
|
||||||
UserConfig config = SupplierHelpers.getInstance(annotation.config());
|
|
||||||
UserRepresentation userRepresentation = config.getRepresentation();
|
UserRepresentation userRepresentation = config.getRepresentation();
|
||||||
|
|
||||||
if (userRepresentation.getUsername() == null) {
|
if (userRepresentation.getUsername() == null) {
|
||||||
String username = lifecycle.equals(LifeCycle.GLOBAL) ? config.getClass().getSimpleName() : registry.getCurrentContext().getRequiredTestClass().getSimpleName();
|
String username = instanceContext.getLifeCycle().equals(LifeCycle.GLOBAL) ? config.getClass().getSimpleName() : instanceContext.getRegistry().getCurrentContext().getRequiredTestClass().getSimpleName();
|
||||||
userRepresentation.setUsername(username);
|
userRepresentation.setUsername(username);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,22 +44,19 @@ public class UserSupplier implements Supplier<UserResource, TestUser> {
|
||||||
|
|
||||||
response.close();
|
response.close();
|
||||||
|
|
||||||
wrapper.addNote(USER_UUID_KEY, userId);
|
instanceContext.addNote(USER_UUID_KEY, userId);
|
||||||
|
|
||||||
UserResource userResource = realm.users().get(userId);
|
return realm.users().get(userId);
|
||||||
wrapper.setValue(userResource, lifecycle);
|
|
||||||
|
|
||||||
return wrapper;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean compatible(InstanceWrapper<UserResource, TestUser> a, RequestedInstance<UserResource, TestUser> b) {
|
public boolean compatible(InstanceContext<UserResource, TestUser> a, RequestedInstance<UserResource, TestUser> b) {
|
||||||
return a.getAnnotation().config().equals(b.getAnnotation().config());
|
return a.getAnnotation().config().equals(b.getAnnotation().config());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close(UserResource user) {
|
public void close(InstanceContext<UserResource, TestUser> instanceContext) {
|
||||||
user.remove();
|
instanceContext.getValue().remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,8 @@ package org.keycloak.test.framework.server;
|
||||||
|
|
||||||
import org.keycloak.test.framework.KeycloakIntegrationTest;
|
import org.keycloak.test.framework.KeycloakIntegrationTest;
|
||||||
import org.keycloak.test.framework.database.TestDatabase;
|
import org.keycloak.test.framework.database.TestDatabase;
|
||||||
import org.keycloak.test.framework.injection.InstanceWrapper;
|
import org.keycloak.test.framework.injection.InstanceContext;
|
||||||
import org.keycloak.test.framework.injection.LifeCycle;
|
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.RequestedInstance;
|
||||||
import org.keycloak.test.framework.injection.Supplier;
|
import org.keycloak.test.framework.injection.Supplier;
|
||||||
import org.keycloak.test.framework.injection.SupplierHelpers;
|
import org.keycloak.test.framework.injection.SupplierHelpers;
|
||||||
|
@ -25,13 +24,13 @@ public abstract class AbstractKeycloakTestServerSupplier implements Supplier<Key
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InstanceWrapper<KeycloakTestServer, KeycloakIntegrationTest> getValue(Registry registry, KeycloakIntegrationTest annotation) {
|
public KeycloakTestServer getValue(InstanceContext<KeycloakTestServer, KeycloakIntegrationTest> instanceContext) {
|
||||||
|
KeycloakIntegrationTest annotation = instanceContext.getAnnotation();
|
||||||
KeycloakTestServerConfig serverConfig = SupplierHelpers.getInstance(annotation.config());
|
KeycloakTestServerConfig serverConfig = SupplierHelpers.getInstance(annotation.config());
|
||||||
InstanceWrapper<KeycloakTestServer, KeycloakIntegrationTest> wrapper = new InstanceWrapper<>(this, annotation);
|
|
||||||
|
|
||||||
Map<String, String> databaseConfig;
|
Map<String, String> databaseConfig;
|
||||||
if (requiresDatabase()) {
|
if (requiresDatabase()) {
|
||||||
TestDatabase testDatabase = registry.getDependency(TestDatabase.class, wrapper);
|
TestDatabase testDatabase = instanceContext.getDependency(TestDatabase.class);
|
||||||
databaseConfig = testDatabase.getServerConfig();
|
databaseConfig = testDatabase.getServerConfig();
|
||||||
} else {
|
} else {
|
||||||
databaseConfig = Collections.emptyMap();
|
databaseConfig = Collections.emptyMap();
|
||||||
|
@ -39,20 +38,22 @@ public abstract class AbstractKeycloakTestServerSupplier implements Supplier<Key
|
||||||
|
|
||||||
KeycloakTestServer keycloakTestServer = getServer();
|
KeycloakTestServer keycloakTestServer = getServer();
|
||||||
keycloakTestServer.start(serverConfig, databaseConfig);
|
keycloakTestServer.start(serverConfig, databaseConfig);
|
||||||
|
return keycloakTestServer;
|
||||||
wrapper.setValue(keycloakTestServer, LifeCycle.GLOBAL);
|
|
||||||
|
|
||||||
return wrapper;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean compatible(InstanceWrapper<KeycloakTestServer, KeycloakIntegrationTest> a, RequestedInstance<KeycloakTestServer, KeycloakIntegrationTest> b) {
|
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());
|
return a.getAnnotation().config().equals(b.getAnnotation().config());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close(KeycloakTestServer keycloakTestServer) {
|
public void close(InstanceContext<KeycloakTestServer, KeycloakIntegrationTest> instanceContext) {
|
||||||
keycloakTestServer.stop();
|
instanceContext.getValue().stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract KeycloakTestServer getServer();
|
public abstract KeycloakTestServer getServer();
|
||||||
|
|
|
@ -21,8 +21,8 @@ public class DistributionKeycloakTestServer implements KeycloakTestServer {
|
||||||
keycloak = new RawKeycloakDistribution(debug, manualStop, enableTls, reCreate, removeBuildOptionsAfterBuild, requestPort);
|
keycloak = new RawKeycloakDistribution(debug, manualStop, enableTls, reCreate, removeBuildOptionsAfterBuild, requestPort);
|
||||||
|
|
||||||
// Set environment variables user and password for Keycloak Admin used by Keycloak instance.
|
// Set environment variables user and password for Keycloak Admin used by Keycloak instance.
|
||||||
keycloak.setEnvVar("KC_BOOTSTRAP_ADMIN_USERNAME", serverConfig.adminUserName().get());
|
keycloak.setEnvVar("KC_BOOTSTRAP_ADMIN_USERNAME", serverConfig.adminUserName());
|
||||||
keycloak.setEnvVar("KC_BOOTSTRAP_ADMIN_PASSWORD", serverConfig.adminUserPassword().get());
|
keycloak.setEnvVar("KC_BOOTSTRAP_ADMIN_PASSWORD", serverConfig.adminUserPassword());
|
||||||
|
|
||||||
List<String> rawOptions = new LinkedList<>();
|
List<String> rawOptions = new LinkedList<>();
|
||||||
rawOptions.add("start-dev");
|
rawOptions.add("start-dev");
|
||||||
|
|
|
@ -22,8 +22,16 @@ public class EmbeddedKeycloakTestServer implements KeycloakTestServer {
|
||||||
rawOptions.add("--features=" + String.join(",", serverConfig.features()));
|
rawOptions.add("--features=" + String.join(",", serverConfig.features()));
|
||||||
}
|
}
|
||||||
|
|
||||||
serverConfig.adminUserName().ifPresent(username -> System.setProperty("keycloakAdmin", username));
|
if (serverConfig.adminUserName() != null) {
|
||||||
serverConfig.adminUserPassword().ifPresent(password -> System.setProperty("keycloakAdminPassword", password));
|
System.setProperty("keycloakAdmin", serverConfig.adminUserName());
|
||||||
|
} else {
|
||||||
|
System.getProperties().remove("keycloakAdmin");
|
||||||
|
}
|
||||||
|
if (serverConfig.adminUserPassword() != null) {
|
||||||
|
System.setProperty("keycloakAdminPassword", serverConfig.adminUserPassword());
|
||||||
|
} else {
|
||||||
|
System.getProperties().remove("keycloakAdminPassword");
|
||||||
|
}
|
||||||
|
|
||||||
serverConfig.options().forEach((key, value) -> rawOptions.add("--" + key + "=" + value));
|
serverConfig.options().forEach((key, value) -> rawOptions.add("--" + key + "=" + value));
|
||||||
databaseConfig.forEach((key, value) -> rawOptions.add("--" + key + "=" + value));
|
databaseConfig.forEach((key, value) -> rawOptions.add("--" + key + "=" + value));
|
||||||
|
|
|
@ -15,12 +15,12 @@ public interface KeycloakTestServerConfig {
|
||||||
return Collections.emptySet();
|
return Collections.emptySet();
|
||||||
}
|
}
|
||||||
|
|
||||||
default Optional<String> adminUserName() {
|
default String adminUserName() {
|
||||||
return Optional.of("admin");
|
return "admin";
|
||||||
}
|
}
|
||||||
|
|
||||||
default Optional<String> adminUserPassword() {
|
default String adminUserPassword() {
|
||||||
return Optional.of("admin");
|
return "admin";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
package org.keycloak.test.framework.webdriver;
|
||||||
|
|
||||||
|
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.openqa.selenium.PageLoadStrategy;
|
||||||
|
import org.openqa.selenium.WebDriver;
|
||||||
|
import org.openqa.selenium.remote.AbstractDriverOptions;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
|
||||||
|
public abstract class AbstractWebDriverSupplier implements Supplier<WebDriver, TestWebDriver> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<TestWebDriver> getAnnotationClass() {
|
||||||
|
return TestWebDriver.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<WebDriver> getValueType() {
|
||||||
|
return WebDriver.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WebDriver getValue(InstanceContext<WebDriver, TestWebDriver> instanceContext) {
|
||||||
|
return getWebDriver();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean compatible(InstanceContext<WebDriver, TestWebDriver> a, RequestedInstance<WebDriver, TestWebDriver> b) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LifeCycle getLifeCycle(TestWebDriver annotation) {
|
||||||
|
return LifeCycle.GLOBAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close(InstanceContext<WebDriver, TestWebDriver> instanceContext) {
|
||||||
|
instanceContext.getValue().quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract WebDriver getWebDriver();
|
||||||
|
|
||||||
|
public void setGlobalOptions(AbstractDriverOptions<?> options) {
|
||||||
|
options.setImplicitWaitTimeout(Duration.ofSeconds(5));
|
||||||
|
options.setPageLoadStrategy(PageLoadStrategy.NORMAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,44 +1,27 @@
|
||||||
package org.keycloak.test.framework.webdriver;
|
package org.keycloak.test.framework.webdriver;
|
||||||
|
|
||||||
import org.keycloak.test.framework.injection.InstanceWrapper;
|
|
||||||
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.openqa.selenium.WebDriver;
|
import org.openqa.selenium.WebDriver;
|
||||||
import org.openqa.selenium.chrome.ChromeDriver;
|
import org.openqa.selenium.chrome.ChromeDriver;
|
||||||
|
import org.openqa.selenium.chrome.ChromeOptions;
|
||||||
|
|
||||||
public class ChromeWebDriverSupplier implements Supplier<WebDriver, TestWebDriver> {
|
public class ChromeWebDriverSupplier extends AbstractWebDriverSupplier {
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<TestWebDriver> getAnnotationClass() {
|
|
||||||
return TestWebDriver.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<WebDriver> getValueType() {
|
|
||||||
return WebDriver.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public InstanceWrapper<WebDriver, TestWebDriver> getValue(Registry registry, TestWebDriver annotation) {
|
|
||||||
final var driver = new ChromeDriver();
|
|
||||||
return new InstanceWrapper<>(this, annotation, driver, LifeCycle.GLOBAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean compatible(InstanceWrapper<WebDriver, TestWebDriver> a, RequestedInstance<WebDriver, TestWebDriver> b) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close(WebDriver instance) {
|
|
||||||
instance.quit();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getAlias() {
|
public String getAlias() {
|
||||||
return "chrome";
|
return "chrome";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WebDriver getWebDriver() {
|
||||||
|
ChromeOptions options = new ChromeOptions();
|
||||||
|
setGlobalOptions(options);
|
||||||
|
options.addArguments(
|
||||||
|
"--headless",
|
||||||
|
"--disable-gpu",
|
||||||
|
"--window-size=1920,1200",
|
||||||
|
"--ignore-certificate-errors",
|
||||||
|
"--disable-dev-shm-usage"
|
||||||
|
);
|
||||||
|
return new ChromeDriver(options);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,43 +1,21 @@
|
||||||
package org.keycloak.test.framework.webdriver;
|
package org.keycloak.test.framework.webdriver;
|
||||||
|
|
||||||
import org.keycloak.test.framework.injection.InstanceWrapper;
|
|
||||||
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.openqa.selenium.WebDriver;
|
import org.openqa.selenium.WebDriver;
|
||||||
import org.openqa.selenium.firefox.FirefoxDriver;
|
import org.openqa.selenium.firefox.FirefoxDriver;
|
||||||
|
import org.openqa.selenium.firefox.FirefoxOptions;
|
||||||
|
|
||||||
public class FirefoxWebDriverSupplier implements Supplier<WebDriver, TestWebDriver> {
|
public class FirefoxWebDriverSupplier extends AbstractWebDriverSupplier {
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<TestWebDriver> getAnnotationClass() {
|
|
||||||
return TestWebDriver.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<WebDriver> getValueType() {
|
|
||||||
return WebDriver.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public InstanceWrapper<WebDriver, TestWebDriver> getValue(Registry registry, TestWebDriver annotation) {
|
|
||||||
final var driver = new FirefoxDriver();
|
|
||||||
return new InstanceWrapper<>(this, annotation, driver, LifeCycle.GLOBAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean compatible(InstanceWrapper<WebDriver, TestWebDriver> a, RequestedInstance<WebDriver, TestWebDriver> b) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close(WebDriver instance) {
|
|
||||||
instance.quit();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getAlias() {
|
public String getAlias() {
|
||||||
return "firefox";
|
return "firefox";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WebDriver getWebDriver() {
|
||||||
|
FirefoxOptions options = new FirefoxOptions();
|
||||||
|
setGlobalOptions(options);
|
||||||
|
options.addArguments("-headless");
|
||||||
|
return new FirefoxDriver(options);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue