From 443efb46f0374f7ed48e3bcc28174474a46f0902 Mon Sep 17 00:00:00 2001 From: Stian Thorgersen Date: Mon, 22 Jul 2024 15:02:59 +0200 Subject: [PATCH] Testsuite PoC - Add more unit tests for the registry (#31468) Signed-off-by: stianst --- .../test/framework/config/Config.java | 2 +- .../test/framework/injection/Registry.java | 16 ++-- .../framework/injection/ValueTypeAlias.java | 2 +- .../framework/injection/RegistryTest.java | 93 +++++++++++++++++++ .../injection/ValueTypeAliasTest.java | 20 ++++ .../injection/mocks/MockParent2Supplier.java | 45 +++++++++ .../injection/mocks/MockParentSupplier.java | 4 +- ...keycloak.test.framework.injection.Supplier | 1 + 8 files changed, 173 insertions(+), 10 deletions(-) create mode 100644 test-poc/framework/src/test/java/org/keycloak/test/framework/injection/ValueTypeAliasTest.java create mode 100644 test-poc/framework/src/test/java/org/keycloak/test/framework/injection/mocks/MockParent2Supplier.java diff --git a/test-poc/framework/src/main/java/org/keycloak/test/framework/config/Config.java b/test-poc/framework/src/main/java/org/keycloak/test/framework/config/Config.java index db71242bf4..8148fcf14e 100644 --- a/test-poc/framework/src/main/java/org/keycloak/test/framework/config/Config.java +++ b/test-poc/framework/src/main/java/org/keycloak/test/framework/config/Config.java @@ -17,7 +17,7 @@ public class Config { return config.getOptionalValue("kc.test." + ValueTypeAlias.getAlias(valueType), String.class).orElse(null); } - private static SmallRyeConfig initConfig() { + public static SmallRyeConfig initConfig() { SmallRyeConfigBuilder configBuilder = new SmallRyeConfigBuilder() .addDefaultSources() .addDefaultInterceptors() diff --git a/test-poc/framework/src/main/java/org/keycloak/test/framework/injection/Registry.java b/test-poc/framework/src/main/java/org/keycloak/test/framework/injection/Registry.java index b4f35eaef8..02484b8dc4 100644 --- a/test-poc/framework/src/main/java/org/keycloak/test/framework/injection/Registry.java +++ b/test-poc/framework/src/main/java/org/keycloak/test/framework/injection/Registry.java @@ -58,6 +58,8 @@ public class Registry { dependency.registerDependency(dependent); deployedInstances.add(dependency); + requestedInstances.remove(requestedDependency); + if (LOGGER.isTraceEnabled()) { LOGGER.tracev("Injecting requested dependency {0} into {1}", dependency.getSupplier().getClass().getSimpleName(), @@ -141,21 +143,17 @@ public class Registry { } private void deployRequestedInstances() { - Iterator> itr = requestedInstances.iterator(); - while (itr.hasNext()) { - RequestedInstance requestedInstance = itr.next(); + while (!requestedInstances.isEmpty()) { + RequestedInstance requestedInstance = requestedInstances.remove(0); InstanceContext instance = new InstanceContext(this, requestedInstance.getSupplier(), requestedInstance.getAnnotation(), requestedInstance.getValueType()); instance.setValue(requestedInstance.getSupplier().getValue(instance)); + deployedInstances.add(instance); if (LOGGER.isTraceEnabled()) { LOGGER.tracev("Created instance: {0}", requestedInstance.getSupplier().getClass().getSimpleName()); } - - deployedInstances.add(instance); - - itr.remove(); } } @@ -189,6 +187,10 @@ public class Registry { destroy.forEach(this::destroy); } + List> getSuppliers() { + return suppliers; + } + private RequestedInstance createRequestedInstance(Annotation[] annotations, Class valueType) { for (Annotation a : annotations) { for (Supplier s : suppliers) { diff --git a/test-poc/framework/src/main/java/org/keycloak/test/framework/injection/ValueTypeAlias.java b/test-poc/framework/src/main/java/org/keycloak/test/framework/injection/ValueTypeAlias.java index 01e2713338..166d8ec56c 100644 --- a/test-poc/framework/src/main/java/org/keycloak/test/framework/injection/ValueTypeAlias.java +++ b/test-poc/framework/src/main/java/org/keycloak/test/framework/injection/ValueTypeAlias.java @@ -14,7 +14,7 @@ public class ValueTypeAlias { TestDatabase.class, "database" ); - public static String getAlias(Class clazz) { + public static String getAlias(Class clazz) { String alias = aliases.get(clazz); if (alias == null) { alias = clazz.getSimpleName(); diff --git a/test-poc/framework/src/test/java/org/keycloak/test/framework/injection/RegistryTest.java b/test-poc/framework/src/test/java/org/keycloak/test/framework/injection/RegistryTest.java index 0279084f6e..30ce31334b 100644 --- a/test-poc/framework/src/test/java/org/keycloak/test/framework/injection/RegistryTest.java +++ b/test-poc/framework/src/test/java/org/keycloak/test/framework/injection/RegistryTest.java @@ -5,14 +5,18 @@ import org.hamcrest.Matchers; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.keycloak.test.framework.config.Config; import org.keycloak.test.framework.injection.mocks.MockChildAnnotation; import org.keycloak.test.framework.injection.mocks.MockChildSupplier; import org.keycloak.test.framework.injection.mocks.MockChildValue; import org.keycloak.test.framework.injection.mocks.MockInstances; +import org.keycloak.test.framework.injection.mocks.MockParent2Supplier; import org.keycloak.test.framework.injection.mocks.MockParentAnnotation; import org.keycloak.test.framework.injection.mocks.MockParentSupplier; import org.keycloak.test.framework.injection.mocks.MockParentValue; +import java.util.List; + public class RegistryTest { private Registry registry; @@ -114,6 +118,72 @@ public class RegistryTest { Assertions.assertNotSame(child1, parentAndChildTest.child); } + @Test + public void testRecreateIfDifferentLifeCycleRequested() { + MockParentSupplier.DEFAULT_LIFECYCLE = LifeCycle.GLOBAL; + + ParentTest parentTest = new ParentTest(); + + registry.beforeEach(parentTest); + registry.afterEach(); + registry.afterAll(); + assertRunning(parentTest.parent); + + MockParentSupplier.DEFAULT_LIFECYCLE = LifeCycle.CLASS; + + ParentTest parentTest2 = new ParentTest(); + registry.beforeEach(parentTest2); + + assertRunning(parentTest2.parent); + assertClosed(parentTest.parent); + Assertions.assertNotSame(parentTest2.parent, parentTest.parent); + } + + @Test + public void testRecreateIfNotCompatible() { + ParentTest parentTest = new ParentTest(); + + registry.beforeEach(parentTest); + MockParentValue parent1 = parentTest.parent; + registry.afterEach(); + + MockParentSupplier.COMPATIBLE = false; + + registry.beforeEach(parentTest); + registry.afterEach(); + + MockParentValue parent2 = parentTest.parent; + + assertRunning(parent2); + assertClosed(parent1); + Assertions.assertNotSame(parent2, parent1); + } + + @Test + public void testSelectedSupplierDefault() { + List> suppliers = registry.getSuppliers(); + Assertions.assertEquals(1, suppliers.stream().filter(s -> s.getValueType().equals(MockParentValue.class)).count()); + Assertions.assertTrue(suppliers.stream().anyMatch(s -> s.getClass().equals(MockParentSupplier.class))); + Assertions.assertFalse(suppliers.stream().anyMatch(s -> s.getClass().equals(MockParent2Supplier.class))); + } + + @Test + public void testSelectedSupplierConfigOverride() { + System.setProperty("kc.test.MockParentValue", MockParent2Supplier.class.getSimpleName()); + try { + Config.initConfig(); + + registry = new Registry(); + List> suppliers = registry.getSuppliers(); + Assertions.assertEquals(1, suppliers.stream().filter(s -> s.getValueType().equals(MockParentValue.class)).count()); + Assertions.assertFalse(suppliers.stream().anyMatch(s -> s.getClass().equals(MockParentSupplier.class))); + Assertions.assertTrue(suppliers.stream().anyMatch(s -> s.getClass().equals(MockParent2Supplier.class))); + } finally { + System.getProperties().remove("kc.test.MockParentValue"); + Config.initConfig(); + } + } + @Test public void testDependencyCreatedOnDemand() { ChildTest childTest = new ChildTest(); @@ -122,6 +192,22 @@ public class RegistryTest { assertRunning(childTest.child, childTest.child.getParent()); } + @Test + public void testDependencyRequestedBefore() { + ParentAndChildTest test = new ParentAndChildTest(); + + registry.beforeEach(test); + assertRunning(test.child, test.child.getParent()); + } + + @Test + public void testDependencyRequestedAfter() { + ChildAndParentTest test = new ChildAndParentTest(); + + registry.beforeEach(test); + assertRunning(test.child, test.child.getParent()); + } + public static void assertRunning(Object... values) { MatcherAssert.assertThat(MockInstances.INSTANCES, Matchers.hasItems(values)); MatcherAssert.assertThat(MockInstances.INSTANCES, Matchers.hasSize(values.length)); @@ -150,4 +236,11 @@ public class RegistryTest { MockChildValue child; } + public static final class ChildAndParentTest { + @MockChildAnnotation + MockChildValue child; + + @MockParentAnnotation + MockParentValue parent; + } } diff --git a/test-poc/framework/src/test/java/org/keycloak/test/framework/injection/ValueTypeAliasTest.java b/test-poc/framework/src/test/java/org/keycloak/test/framework/injection/ValueTypeAliasTest.java new file mode 100644 index 0000000000..55a8c585ef --- /dev/null +++ b/test-poc/framework/src/test/java/org/keycloak/test/framework/injection/ValueTypeAliasTest.java @@ -0,0 +1,20 @@ +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.openqa.selenium.WebDriver; + +public class ValueTypeAliasTest { + + @Test + public void withAlias() { + Assertions.assertEquals("browser", ValueTypeAlias.getAlias(WebDriver.class)); + } + + @Test + public void withoutAlias() { + Assertions.assertEquals("Keycloak", ValueTypeAlias.getAlias(Keycloak.class)); + } + +} diff --git a/test-poc/framework/src/test/java/org/keycloak/test/framework/injection/mocks/MockParent2Supplier.java b/test-poc/framework/src/test/java/org/keycloak/test/framework/injection/mocks/MockParent2Supplier.java new file mode 100644 index 0000000000..bac68361e9 --- /dev/null +++ b/test-poc/framework/src/test/java/org/keycloak/test/framework/injection/mocks/MockParent2Supplier.java @@ -0,0 +1,45 @@ +package org.keycloak.test.framework.injection.mocks; + +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; + +public class MockParent2Supplier implements Supplier { + + public static LifeCycle DEFAULT_LIFECYCLE = LifeCycle.CLASS; + + public static void reset() { + DEFAULT_LIFECYCLE = LifeCycle.CLASS; + } + + @Override + public Class getAnnotationClass() { + return MockParentAnnotation.class; + } + + @Override + public Class getValueType() { + return MockParentValue.class; + } + + @Override + public MockParentValue getValue(InstanceContext instanceContext) { + return new MockParentValue(); + } + + @Override + public boolean compatible(InstanceContext a, RequestedInstance b) { + return true; + } + + @Override + public void close(InstanceContext instanceContext) { + instanceContext.getValue().close(); + } + + @Override + public LifeCycle getDefaultLifecycle() { + return DEFAULT_LIFECYCLE; + } +} diff --git a/test-poc/framework/src/test/java/org/keycloak/test/framework/injection/mocks/MockParentSupplier.java b/test-poc/framework/src/test/java/org/keycloak/test/framework/injection/mocks/MockParentSupplier.java index 4c356a9f00..4054c07708 100644 --- a/test-poc/framework/src/test/java/org/keycloak/test/framework/injection/mocks/MockParentSupplier.java +++ b/test-poc/framework/src/test/java/org/keycloak/test/framework/injection/mocks/MockParentSupplier.java @@ -8,9 +8,11 @@ import org.keycloak.test.framework.injection.Supplier; public class MockParentSupplier implements Supplier { public static LifeCycle DEFAULT_LIFECYCLE = LifeCycle.CLASS; + public static boolean COMPATIBLE = true; public static void reset() { DEFAULT_LIFECYCLE = LifeCycle.CLASS; + COMPATIBLE = true; } @Override @@ -30,7 +32,7 @@ public class MockParentSupplier implements Supplier a, RequestedInstance b) { - return true; + return COMPATIBLE; } @Override diff --git a/test-poc/framework/src/test/resources/META-INF/services/org.keycloak.test.framework.injection.Supplier b/test-poc/framework/src/test/resources/META-INF/services/org.keycloak.test.framework.injection.Supplier index c67a594ea4..ff17ebaa5f 100644 --- a/test-poc/framework/src/test/resources/META-INF/services/org.keycloak.test.framework.injection.Supplier +++ b/test-poc/framework/src/test/resources/META-INF/services/org.keycloak.test.framework.injection.Supplier @@ -1,2 +1,3 @@ org.keycloak.test.framework.injection.mocks.MockParentSupplier +org.keycloak.test.framework.injection.mocks.MockParent2Supplier org.keycloak.test.framework.injection.mocks.MockChildSupplier \ No newline at end of file