Improve Quarkus configuration tests execution (#31668)

Signed-off-by: Martin Bartoš <mabartos@redhat.com>
This commit is contained in:
Martin Bartoš 2024-07-26 16:47:51 +02:00 committed by GitHub
parent c9f5a0aa32
commit 4d60c91cb8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 174 additions and 143 deletions

View file

@ -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<String, String> ENVIRONMENT_VARIABLES = new HashMap<>(System.getenv());
@SuppressWarnings("unchecked")
public static void putEnvVar(String name, String value) {
Map<String, String> env = System.getenv();
Field field = null;
try {
field = env.getClass().getDeclaredField("m");
field.setAccessible(true);
((Map<String, String>) 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<String, String> map) {
map.forEach(ConfigurationTest::putEnvVar);
}
@SuppressWarnings("unchecked")
public static void removeEnvVar(String name) {
Map<String, String> env = System.getenv();
Field field = null;
try {
field = env.getClass().getDeclaredField("m");
field.setAccessible(true);
((Map<String, String>) 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<String, ConfigValue> 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<String, String> expectedValues) {
expectedValues.forEach(this::assertConfig);
}
protected void assertExternalConfig(String key, String expectedValue) {
assertConfig(key, expectedValue, true);
}
protected void assertExternalConfig(Map<String, String> expectedValues) {
expectedValues.forEach(this::assertExternalConfig);
}
}

View file

@ -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<String, String> ENVIRONMENT_VARIABLES = new HashMap<>(System.getenv());
@SuppressWarnings("unchecked")
public static void putEnvVar(String name, String value) {
Map<String, String> env = System.getenv();
Field field = null;
try {
field = env.getClass().getDeclaredField("m");
field.setAccessible(true);
((Map<String, String>) 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<String, String> map) {
map.forEach(ConfigurationTest::putEnvVar);
}
@SuppressWarnings("unchecked")
public static void removeEnvVar(String name) {
Map<String, String> env = System.getenv();
Field field = null;
try {
field = env.getClass().getDeclaredField("m");
field.setAccessible(true);
((Map<String, String>) 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<String, ConfigValue> 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<String, String> expectedValues) {
expectedValues.forEach(this::assertConfig);
}
protected void assertExternalConfig(String key, String expectedValue) {
assertConfig(key, expectedValue, true);
}
protected void assertExternalConfig(Map<String, String> expectedValues) {
expectedValues.forEach(this::assertExternalConfig);
}
}

View file

@ -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<String> artifactsSet, Option<Boolean> enabledOption) {
assertIgnoredArtifacts(artifactsSet, enabledOption, true);
}
private void assertIgnoredArtifacts(Set<String> artifactsSet, Option<Boolean> 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));
});
}
}

View file

@ -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));
}
}
}