From 4d60c91cb869b14c4836eac981a318acc88e399d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Barto=C5=A1?= Date: Fri, 26 Jul 2024 16:47:51 +0200 Subject: [PATCH] Improve Quarkus configuration tests execution (#31668) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Bartoš --- .../test/AbstractConfigurationTest.java | 152 ++++++++++++++++++ .../configuration/test/ConfigurationTest.java | 116 +------------ .../test/IgnoredArtifactsTest.java | 45 +++--- .../test/ManagementConfigurationTest.java | 4 +- 4 files changed, 174 insertions(+), 143 deletions(-) create mode 100644 quarkus/runtime/src/test/java/org/keycloak/quarkus/runtime/configuration/test/AbstractConfigurationTest.java diff --git a/quarkus/runtime/src/test/java/org/keycloak/quarkus/runtime/configuration/test/AbstractConfigurationTest.java b/quarkus/runtime/src/test/java/org/keycloak/quarkus/runtime/configuration/test/AbstractConfigurationTest.java new file mode 100644 index 0000000000..47cf4f527d --- /dev/null +++ b/quarkus/runtime/src/test/java/org/keycloak/quarkus/runtime/configuration/test/AbstractConfigurationTest.java @@ -0,0 +1,152 @@ +/* + * Copyright 2024 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.keycloak.quarkus.runtime.configuration.test; + +import io.quarkus.runtime.LaunchMode; +import io.quarkus.runtime.configuration.ConfigUtils; +import io.smallrye.config.ConfigValue; +import io.smallrye.config.SmallRyeConfig; +import io.smallrye.config.SmallRyeConfigProviderResolver; +import org.eclipse.microprofile.config.ConfigProvider; +import org.eclipse.microprofile.config.spi.ConfigProviderResolver; +import org.junit.After; +import org.keycloak.Config; +import org.keycloak.quarkus.runtime.configuration.Configuration; +import org.keycloak.quarkus.runtime.configuration.KeycloakConfigSourceProvider; +import org.keycloak.quarkus.runtime.configuration.MicroProfileConfigProvider; + +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import java.util.function.Function; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.hamcrest.MatcherAssert.assertThat; + +public abstract class AbstractConfigurationTest { + + private static final Properties SYSTEM_PROPERTIES = (Properties) System.getProperties().clone(); + private static final Map ENVIRONMENT_VARIABLES = new HashMap<>(System.getenv()); + + @SuppressWarnings("unchecked") + public static void putEnvVar(String name, String value) { + Map env = System.getenv(); + Field field = null; + try { + field = env.getClass().getDeclaredField("m"); + field.setAccessible(true); + ((Map) field.get(env)).put(name, value); + } catch (Exception cause) { + throw new RuntimeException("Failed to update environment variables", cause); + } finally { + if (field != null) { + field.setAccessible(false); + } + } + } + + public static void putEnvVars(Map map) { + map.forEach(ConfigurationTest::putEnvVar); + } + + @SuppressWarnings("unchecked") + public static void removeEnvVar(String name) { + Map env = System.getenv(); + Field field = null; + try { + field = env.getClass().getDeclaredField("m"); + field.setAccessible(true); + ((Map) field.get(env)).remove(name); + } catch (Exception cause) { + throw new RuntimeException("Failed to update environment variables", cause); + } finally { + if (field != null) { + field.setAccessible(false); + } + } + } + + public static void setSystemProperty(String key, String value, Runnable runnable) { + System.setProperty(key, value); + try { + runnable.run(); + } finally { + System.clearProperty(key); + } + } + + @After + public void onAfter() { + Properties current = System.getProperties(); + + for (String name : current.stringPropertyNames()) { + if (!SYSTEM_PROPERTIES.containsKey(name)) { + current.remove(name); + } + } + + for (String name : new HashMap<>(System.getenv()).keySet()) { + if (!ENVIRONMENT_VARIABLES.containsKey(name)) { + removeEnvVar(name); + } + } + + SmallRyeConfigProviderResolver.class.cast(ConfigProviderResolver.instance()).releaseConfig(ConfigProvider.getConfig()); + } + + protected Config.Scope initConfig(String... scope) { + Config.init(new MicroProfileConfigProvider(createConfig())); + return Config.scope(scope); + } + + protected SmallRyeConfig createConfig() { + KeycloakConfigSourceProvider.reload(); + // older versions of quarkus implicitly picked up this config, now we + // must set it manually + SmallRyeConfig config = ConfigUtils.configBuilder(true, LaunchMode.NORMAL).build(); + SmallRyeConfigProviderResolver resolver = new SmallRyeConfigProviderResolver(); + resolver.registerConfig(config, Thread.currentThread().getContextClassLoader()); + ConfigProviderResolver.setInstance(resolver); + return config; + } + + protected void assertConfig(String key, String expectedValue, boolean isExternal) { + Function getConfig = isExternal ? Configuration::getConfigValue : Configuration::getKcConfigValue; + var value = getConfig.apply(key).getValue(); + assertThat(String.format("Value is null for key '%s'", key), value, notNullValue()); + assertThat(String.format("Different value for key '%s'", key), value, is(expectedValue)); + } + + protected void assertConfig(String key, String expectedValue) { + assertConfig(key, expectedValue, false); + } + + protected void assertConfig(Map expectedValues) { + expectedValues.forEach(this::assertConfig); + } + + protected void assertExternalConfig(String key, String expectedValue) { + assertConfig(key, expectedValue, true); + } + + protected void assertExternalConfig(Map expectedValues) { + expectedValues.forEach(this::assertExternalConfig); + } +} diff --git a/quarkus/runtime/src/test/java/org/keycloak/quarkus/runtime/configuration/test/ConfigurationTest.java b/quarkus/runtime/src/test/java/org/keycloak/quarkus/runtime/configuration/test/ConfigurationTest.java index 904588073b..f6d03a692f 100644 --- a/quarkus/runtime/src/test/java/org/keycloak/quarkus/runtime/configuration/test/ConfigurationTest.java +++ b/quarkus/runtime/src/test/java/org/keycloak/quarkus/runtime/configuration/test/ConfigurationTest.java @@ -17,110 +17,35 @@ package org.keycloak.quarkus.runtime.configuration.test; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.notNullValue; -import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.keycloak.quarkus.runtime.Environment.isWindows; import static org.keycloak.quarkus.runtime.configuration.ConfigArgsConfigSource.CLI_ARGS; -import java.lang.reflect.Field; import java.nio.file.Path; import java.util.HashMap; import java.util.Map; -import java.util.Properties; -import java.util.function.Function; import io.smallrye.config.SmallRyeConfig; -import io.smallrye.config.SmallRyeConfigProviderResolver; import org.hibernate.dialect.H2Dialect; import org.hibernate.dialect.PostgreSQLDialect; -import io.quarkus.runtime.LaunchMode; import io.smallrye.config.ConfigValue; import io.smallrye.config.PropertiesConfigSource; import io.smallrye.config.SmallRyeConfigBuilder; -import org.eclipse.microprofile.config.ConfigProvider; -import org.eclipse.microprofile.config.spi.ConfigProviderResolver; import org.h2.Driver; import org.hibernate.dialect.MariaDBDialect; -import org.junit.After; import org.junit.Assert; import org.junit.Test; import org.keycloak.Config; import org.keycloak.quarkus.runtime.configuration.ConfigArgsConfigSource; -import org.keycloak.quarkus.runtime.configuration.Configuration; -import org.keycloak.quarkus.runtime.configuration.KeycloakConfigSourceProvider; -import org.keycloak.quarkus.runtime.configuration.MicroProfileConfigProvider; -import io.quarkus.runtime.configuration.ConfigUtils; import org.keycloak.quarkus.runtime.Environment; import org.keycloak.quarkus.runtime.vault.FilesKeystoreVaultProviderFactory; import org.keycloak.quarkus.runtime.vault.FilesPlainTextVaultProviderFactory; import org.mariadb.jdbc.MariaDbDataSource; import org.postgresql.xa.PGXADataSource; -public class ConfigurationTest { - - private static final Properties SYSTEM_PROPERTIES = (Properties) System.getProperties().clone(); - private static final Map ENVIRONMENT_VARIABLES = new HashMap<>(System.getenv()); - - @SuppressWarnings("unchecked") - public static void putEnvVar(String name, String value) { - Map env = System.getenv(); - Field field = null; - try { - field = env.getClass().getDeclaredField("m"); - field.setAccessible(true); - ((Map) field.get(env)).put(name, value); - } catch (Exception cause) { - throw new RuntimeException("Failed to update environment variables", cause); - } finally { - if (field != null) { - field.setAccessible(false); - } - } - } - - public static void putEnvVars(Map map) { - map.forEach(ConfigurationTest::putEnvVar); - } - - @SuppressWarnings("unchecked") - public static void removeEnvVar(String name) { - Map env = System.getenv(); - Field field = null; - try { - field = env.getClass().getDeclaredField("m"); - field.setAccessible(true); - ((Map) field.get(env)).remove(name); - } catch (Exception cause) { - throw new RuntimeException("Failed to update environment variables", cause); - } finally { - if (field != null) { - field.setAccessible(false); - } - } - } - - @After - public void onAfter() { - Properties current = System.getProperties(); - - for (String name : current.stringPropertyNames()) { - if (!SYSTEM_PROPERTIES.containsKey(name)) { - current.remove(name); - } - } - - for (String name : new HashMap<>(System.getenv()).keySet()) { - if (!ENVIRONMENT_VARIABLES.containsKey(name)) { - removeEnvVar(name); - } - } - - SmallRyeConfigProviderResolver.class.cast(ConfigProviderResolver.instance()).releaseConfig(ConfigProvider.getConfig()); - } +public class ConfigurationTest extends AbstractConfigurationTest { @Test public void testCamelCase() { @@ -631,43 +556,4 @@ public class ConfigurationTest { ConfigValue secret = config.getConfigValue("my.secret"); assertEquals("secret", secret.getValue()); } - - protected Config.Scope initConfig(String... scope) { - Config.init(new MicroProfileConfigProvider(createConfig())); - return Config.scope(scope); - } - - private SmallRyeConfig createConfig() { - KeycloakConfigSourceProvider.reload(); - // older versions of quarkus implicitly picked up this config, now we - // must set it manually - SmallRyeConfig config = ConfigUtils.configBuilder(true, LaunchMode.NORMAL).build(); - SmallRyeConfigProviderResolver resolver = new SmallRyeConfigProviderResolver(); - resolver.registerConfig(config, Thread.currentThread().getContextClassLoader()); - ConfigProviderResolver.setInstance(resolver); - return config; - } - - protected void assertConfig(String key, String expectedValue, boolean isExternal) { - Function getConfig = isExternal ? Configuration::getConfigValue : Configuration::getKcConfigValue; - var value = getConfig.apply(key).getValue(); - assertThat(String.format("Value is null for key '%s'", key), value, notNullValue()); - assertThat(String.format("Different value for key '%s'", key), value, is(expectedValue)); - } - - protected void assertConfig(String key, String expectedValue) { - assertConfig(key, expectedValue, false); - } - - protected void assertConfig(Map expectedValues) { - expectedValues.forEach(this::assertConfig); - } - - protected void assertExternalConfig(String key, String expectedValue) { - assertConfig(key, expectedValue, true); - } - - protected void assertExternalConfig(Map expectedValues) { - expectedValues.forEach(this::assertExternalConfig); - } } diff --git a/quarkus/runtime/src/test/java/org/keycloak/quarkus/runtime/configuration/test/IgnoredArtifactsTest.java b/quarkus/runtime/src/test/java/org/keycloak/quarkus/runtime/configuration/test/IgnoredArtifactsTest.java index 7b96597b5b..4009913418 100644 --- a/quarkus/runtime/src/test/java/org/keycloak/quarkus/runtime/configuration/test/IgnoredArtifactsTest.java +++ b/quarkus/runtime/src/test/java/org/keycloak/quarkus/runtime/configuration/test/IgnoredArtifactsTest.java @@ -24,9 +24,9 @@ import org.keycloak.common.profile.PropertiesProfileConfigResolver; import org.keycloak.config.DatabaseOptions; import org.keycloak.config.HealthOptions; import org.keycloak.config.MetricsOptions; +import org.keycloak.config.Option; import org.keycloak.quarkus.runtime.configuration.Configuration; import org.keycloak.quarkus.runtime.configuration.IgnoredArtifacts; -import org.keycloak.quarkus.runtime.configuration.MicroProfileConfigProvider; import java.util.Collection; import java.util.HashSet; @@ -44,6 +44,8 @@ import static org.keycloak.quarkus.runtime.configuration.IgnoredArtifacts.JDBC_M import static org.keycloak.quarkus.runtime.configuration.IgnoredArtifacts.JDBC_MYSQL; import static org.keycloak.quarkus.runtime.configuration.IgnoredArtifacts.JDBC_ORACLE; import static org.keycloak.quarkus.runtime.configuration.IgnoredArtifacts.JDBC_POSTGRES; +import static org.keycloak.quarkus.runtime.configuration.MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX; +import static org.keycloak.quarkus.runtime.configuration.test.ConfigurationTest.setSystemProperty; public class IgnoredArtifactsTest { @@ -124,8 +126,7 @@ public class IgnoredArtifactsTest { var notIgnoredWithDefaults = new HashSet<>(notIgnored); notIgnoredWithDefaults.addAll(IGNORED_JDBC_FROM_PROPS); - System.setProperty(MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX + DatabaseOptions.DB.getKey(), vendor); - try { + setSystemProperty(NS_KEYCLOAK_PREFIX + DatabaseOptions.DB.getKey(), vendor, () -> { final var resultArtifacts = IgnoredArtifacts.getDefaultIgnoredArtifacts(); assertThat(String.format("Ignored artifacts does not comply with the specified artifacts for '%s' JDBC driver", vendor), resultArtifacts, @@ -136,38 +137,30 @@ public class IgnoredArtifactsTest { assertThat("Ignored artifacts does not contain items for the other JDBC drivers", resultArtifacts, CoreMatchers.hasItems(includedArtifacts.toArray(new String[0]))); - } finally { - System.getProperties().remove(MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX + DatabaseOptions.DB.getKey()); - } + }); } @Test public void health() { - var ignoredArtifacts = IgnoredArtifacts.getDefaultIgnoredArtifacts(); - // Health disabled by default - assertThat(ignoredArtifacts.containsAll(IgnoredArtifacts.HEALTH), is(true)); - - System.setProperty(MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX + HealthOptions.HEALTH_ENABLED.getKey(), "true"); - try { - final var artifacts = IgnoredArtifacts.getDefaultIgnoredArtifacts(); - assertThat(artifacts.containsAll(IgnoredArtifacts.HEALTH), is(false)); - } finally { - System.setProperty(MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX + HealthOptions.HEALTH_ENABLED.getKey(), ""); - } + assertIgnoredArtifacts(IgnoredArtifacts.HEALTH, HealthOptions.HEALTH_ENABLED); } @Test public void metrics() { - var ignoredArtifacts = IgnoredArtifacts.getDefaultIgnoredArtifacts(); - // Metrics disabled by default - assertThat(ignoredArtifacts.containsAll(IgnoredArtifacts.METRICS), is(true)); + assertIgnoredArtifacts(IgnoredArtifacts.METRICS, MetricsOptions.METRICS_ENABLED); + } - System.setProperty(MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX + MetricsOptions.METRICS_ENABLED.getKey(), "true"); - try { + private void assertIgnoredArtifacts(Set artifactsSet, Option enabledOption) { + assertIgnoredArtifacts(artifactsSet, enabledOption, true); + } + + private void assertIgnoredArtifacts(Set artifactsSet, Option enabledOption, boolean disabledByDefault) { + var ignoredArtifacts = IgnoredArtifacts.getDefaultIgnoredArtifacts(); + assertThat(String.format("Expected: %s.\n Actual: %s.", artifactsSet, ignoredArtifacts), ignoredArtifacts.containsAll(artifactsSet), is(disabledByDefault)); + + setSystemProperty(NS_KEYCLOAK_PREFIX + enabledOption.getKey(), Boolean.valueOf(disabledByDefault).toString(), () -> { final var artifacts = IgnoredArtifacts.getDefaultIgnoredArtifacts(); - assertThat(artifacts.containsAll(IgnoredArtifacts.METRICS), is(false)); - } finally { - System.setProperty(MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX + HealthOptions.HEALTH_ENABLED.getKey(), ""); - } + assertThat(artifacts.containsAll(artifactsSet), is(!disabledByDefault)); + }); } } diff --git a/quarkus/runtime/src/test/java/org/keycloak/quarkus/runtime/configuration/test/ManagementConfigurationTest.java b/quarkus/runtime/src/test/java/org/keycloak/quarkus/runtime/configuration/test/ManagementConfigurationTest.java index 31f6e0d92c..8ec36f1dcb 100644 --- a/quarkus/runtime/src/test/java/org/keycloak/quarkus/runtime/configuration/test/ManagementConfigurationTest.java +++ b/quarkus/runtime/src/test/java/org/keycloak/quarkus/runtime/configuration/test/ManagementConfigurationTest.java @@ -24,7 +24,7 @@ import java.util.Map; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; -public class ManagementConfigurationTest extends ConfigurationTest { +public class ManagementConfigurationTest extends AbstractConfigurationTest { @Test public void managementDefaults() { @@ -262,4 +262,4 @@ public class ManagementConfigurationTest extends ConfigurationTest { private void assertManagementHttpsEnabled(boolean expected) { assertThat("Expected value for Management HTTPS is different", ManagementPropertyMappers.isManagementTlsEnabled(), is(expected)); } -} \ No newline at end of file +}