Persisted config source not loading properties at runtime (#12157)
Co-authored-by: Dominik Guhr <dguhr@redhat.com>
This commit is contained in:
parent
0cb3c95ed5
commit
6156272f39
20 changed files with 271 additions and 47 deletions
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
|
@ -489,7 +489,7 @@ jobs:
|
||||||
|
|
||||||
- name: Run Quarkus Storage Tests
|
- name: Run Quarkus Storage Tests
|
||||||
run: |
|
run: |
|
||||||
./mvnw clean install -nsu -B -f quarkus/tests/pom.xml -Ptest-database -Dtest=PostgreSQLStartDatabaseTest | misc/log/trimmer.sh
|
./mvnw clean install -nsu -B -f quarkus/tests/pom.xml -Ptest-database -Dtest=PostgreSQLDistTest | misc/log/trimmer.sh
|
||||||
TEST_RESULT=${PIPESTATUS[0]}
|
TEST_RESULT=${PIPESTATUS[0]}
|
||||||
find . -path '*/target/surefire-reports/*.xml' | zip -q reports-quarkus-tests.zip -@
|
find . -path '*/target/surefire-reports/*.xml' | zip -q reports-quarkus-tests.zip -@
|
||||||
exit $TEST_RESULT
|
exit $TEST_RESULT
|
||||||
|
|
|
@ -31,7 +31,6 @@ import java.util.Optional;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import io.quarkus.bootstrap.runner.RunnerClassLoader;
|
|
||||||
import io.quarkus.runtime.LaunchMode;
|
import io.quarkus.runtime.LaunchMode;
|
||||||
import io.quarkus.runtime.configuration.ProfileManager;
|
import io.quarkus.runtime.configuration.ProfileManager;
|
||||||
import org.apache.commons.lang3.SystemUtils;
|
import org.apache.commons.lang3.SystemUtils;
|
||||||
|
@ -49,11 +48,11 @@ public final class Environment {
|
||||||
private Environment() {}
|
private Environment() {}
|
||||||
|
|
||||||
public static Boolean isRebuild() {
|
public static Boolean isRebuild() {
|
||||||
return !isRuntimeMode();
|
return Boolean.getBoolean("quarkus.launch.rebuild");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Boolean isRuntimeMode() {
|
public static Boolean isRuntimeMode() {
|
||||||
return Thread.currentThread().getContextClassLoader() instanceof RunnerClassLoader;
|
return !isRebuild();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getHomeDir() {
|
public static String getHomeDir() {
|
||||||
|
|
|
@ -68,7 +68,7 @@ public final class PersistedConfigSource extends PropertiesConfigSource {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Map<String, String> readProperties() {
|
private static Map<String, String> readProperties() {
|
||||||
if (!Environment.isRebuild()) {
|
if (Environment.isRuntimeMode()) {
|
||||||
InputStream fileStream = loadPersistedConfig();
|
InputStream fileStream = loadPersistedConfig();
|
||||||
|
|
||||||
if (fileStream == null) {
|
if (fileStream == null) {
|
||||||
|
|
|
@ -21,7 +21,6 @@ metrics-enabled=false
|
||||||
%import_export.http-enabled=true
|
%import_export.http-enabled=true
|
||||||
%import_export.hostname-strict=false
|
%import_export.hostname-strict=false
|
||||||
%import_export.hostname-strict-https=false
|
%import_export.hostname-strict-https=false
|
||||||
%import_export.cluster=local
|
|
||||||
|
|
||||||
#logging defaults
|
#logging defaults
|
||||||
log-console-output=default
|
log-console-output=default
|
||||||
|
|
|
@ -79,6 +79,14 @@
|
||||||
<artifactId>approvaltests</artifactId>
|
<artifactId>approvaltests</artifactId>
|
||||||
<version>${approvaltests.version}</version>
|
<version>${approvaltests.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.testcontainers</groupId>
|
||||||
|
<artifactId>postgresql</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.testcontainers</groupId>
|
||||||
|
<artifactId>mariadb</artifactId>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
|
@ -54,6 +54,7 @@ public class CLITestExtension extends QuarkusMainTestExtension {
|
||||||
private static final String KEY_VALUE_SEPARATOR = "[= ]";
|
private static final String KEY_VALUE_SEPARATOR = "[= ]";
|
||||||
private KeycloakDistribution dist;
|
private KeycloakDistribution dist;
|
||||||
private final Set<String> testSysProps = new HashSet<>();
|
private final Set<String> testSysProps = new HashSet<>();
|
||||||
|
private DatabaseContainer databaseContainer;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void beforeEach(ExtensionContext context) throws Exception {
|
public void beforeEach(ExtensionContext context) throws Exception {
|
||||||
|
@ -81,6 +82,8 @@ public class CLITestExtension extends QuarkusMainTestExtension {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
configureDatabase(context);
|
||||||
|
|
||||||
if (distConfig != null) {
|
if (distConfig != null) {
|
||||||
onKeepServerAlive(context.getRequiredTestMethod().getAnnotation(KeepServerAlive.class));
|
onKeepServerAlive(context.getRequiredTestMethod().getAnnotation(KeepServerAlive.class));
|
||||||
|
|
||||||
|
@ -96,7 +99,6 @@ public class CLITestExtension extends QuarkusMainTestExtension {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
configureProfile(context);
|
configureProfile(context);
|
||||||
configureDatabase(context);
|
|
||||||
super.beforeEach(context);
|
super.beforeEach(context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -148,6 +150,10 @@ public class CLITestExtension extends QuarkusMainTestExtension {
|
||||||
for (String property : testSysProps) {
|
for (String property : testSysProps) {
|
||||||
System.getProperties().remove(property);
|
System.getProperties().remove(property);
|
||||||
}
|
}
|
||||||
|
if (databaseContainer != null && databaseContainer.isRunning()) {
|
||||||
|
databaseContainer.stop();
|
||||||
|
databaseContainer = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -237,10 +243,22 @@ public class CLITestExtension extends QuarkusMainTestExtension {
|
||||||
WithDatabase database = context.getTestClass().orElse(Object.class).getDeclaredAnnotation(WithDatabase.class);
|
WithDatabase database = context.getTestClass().orElse(Object.class).getDeclaredAnnotation(WithDatabase.class);
|
||||||
|
|
||||||
if (database != null) {
|
if (database != null) {
|
||||||
configureDevServices();
|
if (dist == null) {
|
||||||
setProperty("kc.db", database.alias());
|
configureDevServices();
|
||||||
// databases like mssql are very strict about password policy
|
setProperty("kc.db", database.alias());
|
||||||
setProperty("kc.db-password", "Password1!");
|
setProperty("kc.db-password", DatabaseContainer.DEFAULT_PASSWORD);
|
||||||
|
} else {
|
||||||
|
databaseContainer = new DatabaseContainer(database.alias());
|
||||||
|
|
||||||
|
databaseContainer.start();
|
||||||
|
|
||||||
|
dist.setProperty("db", database.alias());
|
||||||
|
dist.setProperty("db-username", databaseContainer.getUsername());
|
||||||
|
dist.setProperty("db-password", databaseContainer.getPassword());
|
||||||
|
dist.setProperty("db-url", databaseContainer.getJdbcUrl());
|
||||||
|
|
||||||
|
dist.start(List.of("build"));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// This is for re-creating the H2 database instead of using the default in home
|
// This is for re-creating the H2 database instead of using the default in home
|
||||||
setProperty("kc.db-url-path", new QuarkusPlatform().getTmpDirectory().getAbsolutePath());
|
setProperty("kc.db-url-path", new QuarkusPlatform().getTmpDirectory().getAbsolutePath());
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 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.it.junit5.extension;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
import org.testcontainers.containers.JdbcDatabaseContainer;
|
||||||
|
import org.testcontainers.containers.MariaDBContainer;
|
||||||
|
import org.testcontainers.containers.PostgreSQLContainer;
|
||||||
|
|
||||||
|
public class DatabaseContainer {
|
||||||
|
|
||||||
|
static final String DEFAULT_PASSWORD = "Password1!";
|
||||||
|
|
||||||
|
private final String alias;
|
||||||
|
private JdbcDatabaseContainer container;
|
||||||
|
|
||||||
|
DatabaseContainer(String alias) {
|
||||||
|
this.alias = alias;
|
||||||
|
}
|
||||||
|
|
||||||
|
void start() {
|
||||||
|
container = createContainer()
|
||||||
|
.withDatabaseName("keycloak")
|
||||||
|
.withUsername(getUsername())
|
||||||
|
.withPassword(getPassword());
|
||||||
|
|
||||||
|
container.withStartupTimeout(Duration.ofMinutes(5)).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isRunning() {
|
||||||
|
return container.isRunning();
|
||||||
|
}
|
||||||
|
|
||||||
|
String getJdbcUrl() {
|
||||||
|
return container.getJdbcUrl();
|
||||||
|
}
|
||||||
|
|
||||||
|
String getUsername() {
|
||||||
|
return "keycloak";
|
||||||
|
}
|
||||||
|
|
||||||
|
String getPassword() {
|
||||||
|
return DEFAULT_PASSWORD;
|
||||||
|
}
|
||||||
|
|
||||||
|
void stop() {
|
||||||
|
container.stop();
|
||||||
|
container = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private JdbcDatabaseContainer createContainer() {
|
||||||
|
switch (alias) {
|
||||||
|
case "postgres":
|
||||||
|
return new PostgreSQLContainer("postgres:alpine");
|
||||||
|
case "mariadb":
|
||||||
|
return new MariaDBContainer("mariadb:10.5.9");
|
||||||
|
default:
|
||||||
|
throw new RuntimeException("Unsupported database: " + alias);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -38,5 +38,10 @@ public @interface DistributionTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
ReInstall reInstall() default ReInstall.BEFORE_ALL;
|
ReInstall reInstall() default ReInstall.BEFORE_ALL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If any build option must be unset after the running the build command.
|
||||||
|
*/
|
||||||
|
boolean removeBuildOptionsAfterBuild() default false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,8 @@ public enum DistributionType {
|
||||||
return new RawKeycloakDistribution(
|
return new RawKeycloakDistribution(
|
||||||
config.debug(),
|
config.debug(),
|
||||||
config.keepAlive(),
|
config.keepAlive(),
|
||||||
!DistributionTest.ReInstall.NEVER.equals(config.reInstall()));
|
!DistributionTest.ReInstall.NEVER.equals(config.reInstall()),
|
||||||
|
config.removeBuildOptionsAfterBuild());
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Function<DistributionTest, KeycloakDistribution> factory;
|
private final Function<DistributionTest, KeycloakDistribution> factory;
|
||||||
|
|
|
@ -33,8 +33,6 @@ public @interface WithDatabase {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The database name as per database aliases.
|
* The database name as per database aliases.
|
||||||
*
|
|
||||||
* @return the database alias
|
|
||||||
*/
|
*/
|
||||||
String alias();
|
String alias();
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,4 +46,8 @@ public interface KeycloakDistribution {
|
||||||
default void copyOrReplaceFileFromClasspath(String file, Path distDir) {
|
default void copyOrReplaceFileFromClasspath(String file, Path distDir) {
|
||||||
throw new RuntimeException("Not implemented");
|
throw new RuntimeException("Not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default void removeProperty(String db) {
|
||||||
|
throw new RuntimeException("Not implemented");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,7 @@ import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
|
import java.util.function.Consumer;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import javax.net.ssl.HostnameVerifier;
|
import javax.net.ssl.HostnameVerifier;
|
||||||
|
@ -54,6 +55,9 @@ import org.apache.commons.io.FileUtils;
|
||||||
|
|
||||||
import org.keycloak.common.Version;
|
import org.keycloak.common.Version;
|
||||||
import org.keycloak.quarkus.runtime.Environment;
|
import org.keycloak.quarkus.runtime.Environment;
|
||||||
|
import org.keycloak.quarkus.runtime.cli.command.Build;
|
||||||
|
import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper;
|
||||||
|
import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMappers;
|
||||||
|
|
||||||
import static org.keycloak.quarkus.runtime.Environment.LAUNCH_MODE;
|
import static org.keycloak.quarkus.runtime.Environment.LAUNCH_MODE;
|
||||||
|
|
||||||
|
@ -69,13 +73,15 @@ public final class RawKeycloakDistribution implements KeycloakDistribution {
|
||||||
private int httpPort;
|
private int httpPort;
|
||||||
private boolean debug;
|
private boolean debug;
|
||||||
private boolean reCreate;
|
private boolean reCreate;
|
||||||
|
private boolean removeBuildOptionsAfterBuild;
|
||||||
private ExecutorService outputExecutor;
|
private ExecutorService outputExecutor;
|
||||||
private boolean inited = false;
|
private boolean inited = false;
|
||||||
|
|
||||||
public RawKeycloakDistribution(boolean debug, boolean manualStop, boolean reCreate) {
|
public RawKeycloakDistribution(boolean debug, boolean manualStop, boolean reCreate, boolean removeBuildOptionsAfterBuild) {
|
||||||
this.debug = debug;
|
this.debug = debug;
|
||||||
this.manualStop = manualStop;
|
this.manualStop = manualStop;
|
||||||
this.reCreate = reCreate;
|
this.reCreate = reCreate;
|
||||||
|
this.removeBuildOptionsAfterBuild = removeBuildOptionsAfterBuild;
|
||||||
this.distPath = prepareDistribution();
|
this.distPath = prepareDistribution();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,6 +104,11 @@ public final class RawKeycloakDistribution implements KeycloakDistribution {
|
||||||
stop();
|
stop();
|
||||||
throw new RuntimeException("Failed to start the server", cause);
|
throw new RuntimeException("Failed to start the server", cause);
|
||||||
} finally {
|
} finally {
|
||||||
|
if (arguments.contains(Build.NAME) && removeBuildOptionsAfterBuild) {
|
||||||
|
for (PropertyMapper mapper : PropertyMappers.getBuildTimeMappers()) {
|
||||||
|
removeProperty(mapper.getFrom().substring(3));
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!manualStop) {
|
if (!manualStop) {
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
|
@ -108,7 +119,6 @@ public final class RawKeycloakDistribution implements KeycloakDistribution {
|
||||||
public void stop() {
|
public void stop() {
|
||||||
if (isRunning()) {
|
if (isRunning()) {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
if (Environment.isWindows()) {
|
if (Environment.isWindows()) {
|
||||||
// On Windows, we're executing kc.bat in a runtime as "keycloak",
|
// On Windows, we're executing kc.bat in a runtime as "keycloak",
|
||||||
// so tha java process is an actual child process
|
// so tha java process is an actual child process
|
||||||
|
@ -409,12 +419,27 @@ public final class RawKeycloakDistribution implements KeycloakDistribution {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setProperty(String key, String value) {
|
public void setProperty(String key, String value) {
|
||||||
setProperty(key, value, distPath.resolve("conf").resolve("keycloak.conf").toFile());
|
updateProperties(properties -> properties.put(key, value), distPath.resolve("conf").resolve("keycloak.conf").toFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeProperty(String key) {
|
||||||
|
updateProperties(new Consumer<Properties>() {
|
||||||
|
@Override
|
||||||
|
public void accept(Properties properties) {
|
||||||
|
properties.remove(key);
|
||||||
|
}
|
||||||
|
}, distPath.resolve("conf").resolve("keycloak.conf").toFile());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setQuarkusProperty(String key, String value) {
|
public void setQuarkusProperty(String key, String value) {
|
||||||
setProperty(key, value, getQuarkusPropertiesFile());
|
updateProperties(new Consumer<Properties>() {
|
||||||
|
@Override
|
||||||
|
public void accept(Properties properties) {
|
||||||
|
properties.put(key, value);
|
||||||
|
}
|
||||||
|
}, getQuarkusPropertiesFile());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -439,27 +464,27 @@ public final class RawKeycloakDistribution implements KeycloakDistribution {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setProperty(String key, String value, File confFile) {
|
private void updateProperties(Consumer<Properties> propertiesConsumer, File propertiesFile) {
|
||||||
Properties properties = new Properties();
|
Properties properties = new Properties();
|
||||||
|
|
||||||
if (confFile.exists()) {
|
if (propertiesFile.exists()) {
|
||||||
try (
|
try (
|
||||||
FileInputStream in = new FileInputStream(confFile);
|
FileInputStream in = new FileInputStream(propertiesFile);
|
||||||
) {
|
) {
|
||||||
|
|
||||||
properties.load(in);
|
properties.load(in);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException("Failed to update " + confFile, e);
|
throw new RuntimeException("Failed to update " + propertiesFile, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try (
|
try (
|
||||||
FileOutputStream out = new FileOutputStream(confFile)
|
FileOutputStream out = new FileOutputStream(propertiesFile)
|
||||||
) {
|
) {
|
||||||
properties.put(key, value);
|
propertiesConsumer.accept(properties);
|
||||||
properties.store(out, "");
|
properties.store(out, "");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException("Failed to update " + confFile, e);
|
throw new RuntimeException("Failed to update " + propertiesFile, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,23 +17,27 @@
|
||||||
|
|
||||||
package org.keycloak.it.storage.database;
|
package org.keycloak.it.storage.database;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.MethodOrderer;
|
||||||
|
import org.junit.jupiter.api.Order;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.TestMethodOrder;
|
||||||
import org.keycloak.it.junit5.extension.CLIResult;
|
import org.keycloak.it.junit5.extension.CLIResult;
|
||||||
|
|
||||||
import io.quarkus.test.junit.main.Launch;
|
import io.quarkus.test.junit.main.Launch;
|
||||||
import io.quarkus.test.junit.main.LaunchResult;
|
import io.quarkus.test.junit.main.LaunchResult;
|
||||||
|
|
||||||
public abstract class AbstractStartDabataseTest {
|
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
||||||
|
public abstract class BasicDatabaseTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Launch({ "start-dev" })
|
@Launch({ "start", "--http-enabled=true", "--hostname-strict=false" })
|
||||||
void testSuccessful(LaunchResult result) {
|
void testSuccessful(LaunchResult result) {
|
||||||
CLIResult cliResult = (CLIResult) result;
|
CLIResult cliResult = (CLIResult) result;
|
||||||
cliResult.assertStartedDevMode();
|
cliResult.assertStarted();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Launch({ "start-dev", "--db-username=wrong" })
|
@Launch({ "start", "--http-enabled=true", "--hostname-strict=false", "--db-username=wrong" })
|
||||||
void testWrongUsername(LaunchResult result) {
|
void testWrongUsername(LaunchResult result) {
|
||||||
CLIResult cliResult = (CLIResult) result;
|
CLIResult cliResult = (CLIResult) result;
|
||||||
cliResult.assertMessage("ERROR: Failed to obtain JDBC connection");
|
cliResult.assertMessage("ERROR: Failed to obtain JDBC connection");
|
||||||
|
@ -43,7 +47,7 @@ public abstract class AbstractStartDabataseTest {
|
||||||
protected abstract void assertWrongUsername(CLIResult cliResult);
|
protected abstract void assertWrongUsername(CLIResult cliResult);
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Launch({ "start-dev", "--db-password=wrong" })
|
@Launch({ "start", "--http-enabled=true", "--hostname-strict=false", "--db-password=wrong" })
|
||||||
void testWrongPassword(LaunchResult result) {
|
void testWrongPassword(LaunchResult result) {
|
||||||
CLIResult cliResult = (CLIResult) result;
|
CLIResult cliResult = (CLIResult) result;
|
||||||
cliResult.assertMessage("ERROR: Failed to obtain JDBC connection");
|
cliResult.assertMessage("ERROR: Failed to obtain JDBC connection");
|
||||||
|
@ -51,4 +55,23 @@ public abstract class AbstractStartDabataseTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void assertWrongPassword(CLIResult cliResult);
|
protected abstract void assertWrongPassword(CLIResult cliResult);
|
||||||
|
|
||||||
|
@Order(1)
|
||||||
|
@Test
|
||||||
|
@Launch({ "export", "--dir=./target/export"})
|
||||||
|
public void testExportSucceeds(LaunchResult result) {
|
||||||
|
CLIResult cliResult = (CLIResult) result;
|
||||||
|
cliResult.assertMessage("Full model export requested");
|
||||||
|
cliResult.assertMessage("Export finished successfully");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Order(2)
|
||||||
|
@Test
|
||||||
|
@Launch({ "import", "--dir=./target/export" })
|
||||||
|
void testImportSucceeds(LaunchResult result) {
|
||||||
|
CLIResult cliResult = (CLIResult) result;
|
||||||
|
cliResult.assertMessage("target/export");
|
||||||
|
cliResult.assertMessage("Realm 'master' imported");
|
||||||
|
cliResult.assertMessage("Import finished successfully");
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -27,7 +27,7 @@ import io.quarkus.test.junit.main.LaunchResult;
|
||||||
|
|
||||||
@CLITest
|
@CLITest
|
||||||
@WithDatabase(alias = "mssql")
|
@WithDatabase(alias = "mssql")
|
||||||
public class MSSQLStartDatabaseTest extends AbstractStartDabataseTest {
|
public class MSSQLTest extends BasicDatabaseTest {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* It should be possible to enable XA but here we reproduce a managed environment where only nonXA transaction is supported
|
* It should be possible to enable XA but here we reproduce a managed environment where only nonXA transaction is supported
|
|
@ -23,7 +23,7 @@ import org.keycloak.it.junit5.extension.WithDatabase;
|
||||||
|
|
||||||
@CLITest
|
@CLITest
|
||||||
@WithDatabase(alias = "mariadb")
|
@WithDatabase(alias = "mariadb")
|
||||||
public class MariaDBStartDatabaseTest extends AbstractStartDabataseTest {
|
public class MariaDBTest extends BasicDatabaseTest {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void assertWrongPassword(CLIResult cliResult) {
|
protected void assertWrongPassword(CLIResult cliResult) {
|
|
@ -17,17 +17,13 @@
|
||||||
|
|
||||||
package org.keycloak.it.storage.database;
|
package org.keycloak.it.storage.database;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.keycloak.it.junit5.extension.CLIResult;
|
import org.keycloak.it.junit5.extension.CLIResult;
|
||||||
import org.keycloak.it.junit5.extension.CLITest;
|
import org.keycloak.it.junit5.extension.CLITest;
|
||||||
import org.keycloak.it.junit5.extension.WithDatabase;
|
import org.keycloak.it.junit5.extension.WithDatabase;
|
||||||
|
|
||||||
import io.quarkus.test.junit.main.Launch;
|
|
||||||
import io.quarkus.test.junit.main.LaunchResult;
|
|
||||||
|
|
||||||
@CLITest
|
@CLITest
|
||||||
@WithDatabase(alias = "mysql")
|
@WithDatabase(alias = "mysql")
|
||||||
public class MySQLStartDatabaseTest extends AbstractStartDabataseTest {
|
public class MySQLTest extends BasicDatabaseTest {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void assertWrongUsername(CLIResult cliResult) {
|
protected void assertWrongUsername(CLIResult cliResult) {
|
|
@ -17,17 +17,13 @@
|
||||||
|
|
||||||
package org.keycloak.it.storage.database;
|
package org.keycloak.it.storage.database;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.keycloak.it.junit5.extension.CLIResult;
|
import org.keycloak.it.junit5.extension.CLIResult;
|
||||||
import org.keycloak.it.junit5.extension.CLITest;
|
import org.keycloak.it.junit5.extension.CLITest;
|
||||||
import org.keycloak.it.junit5.extension.WithDatabase;
|
import org.keycloak.it.junit5.extension.WithDatabase;
|
||||||
|
|
||||||
import io.quarkus.test.junit.main.Launch;
|
|
||||||
import io.quarkus.test.junit.main.LaunchResult;
|
|
||||||
|
|
||||||
@CLITest
|
@CLITest
|
||||||
@WithDatabase(alias = "oracle")
|
@WithDatabase(alias = "oracle")
|
||||||
public class OracleStartDatabaseTest extends AbstractStartDabataseTest {
|
public class OracleTest extends BasicDatabaseTest {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void assertWrongUsername(CLIResult cliResult) {
|
protected void assertWrongUsername(CLIResult cliResult) {
|
|
@ -17,17 +17,13 @@
|
||||||
|
|
||||||
package org.keycloak.it.storage.database;
|
package org.keycloak.it.storage.database;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.keycloak.it.junit5.extension.CLIResult;
|
import org.keycloak.it.junit5.extension.CLIResult;
|
||||||
import org.keycloak.it.junit5.extension.CLITest;
|
import org.keycloak.it.junit5.extension.CLITest;
|
||||||
import org.keycloak.it.junit5.extension.WithDatabase;
|
import org.keycloak.it.junit5.extension.WithDatabase;
|
||||||
|
|
||||||
import io.quarkus.test.junit.main.Launch;
|
|
||||||
import io.quarkus.test.junit.main.LaunchResult;
|
|
||||||
|
|
||||||
@CLITest
|
@CLITest
|
||||||
@WithDatabase(alias = "postgres")
|
@WithDatabase(alias = "postgres")
|
||||||
public class PostgreSQLStartDatabaseTest extends AbstractStartDabataseTest {
|
public class PostgreSQLTest extends BasicDatabaseTest {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void assertWrongUsername(CLIResult cliResult) {
|
protected void assertWrongUsername(CLIResult cliResult) {
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 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.it.storage.database.dist;
|
||||||
|
|
||||||
|
import org.keycloak.it.junit5.extension.CLIResult;
|
||||||
|
import org.keycloak.it.junit5.extension.CLITest;
|
||||||
|
import org.keycloak.it.junit5.extension.WithDatabase;
|
||||||
|
import org.keycloak.it.storage.database.BasicDatabaseTest;
|
||||||
|
|
||||||
|
@CLITest
|
||||||
|
@WithDatabase(alias = "mariadb")
|
||||||
|
public class MariaDBDistTest extends BasicDatabaseTest {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void assertWrongPassword(CLIResult cliResult) {
|
||||||
|
cliResult.assertMessage("Access denied for user");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void assertWrongUsername(CLIResult cliResult) {
|
||||||
|
cliResult.assertMessage("Access denied for user 'wrong'");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 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.it.storage.database.dist;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.containsString;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.keycloak.it.junit5.extension.CLIResult;
|
||||||
|
import org.keycloak.it.junit5.extension.DistributionTest;
|
||||||
|
import org.keycloak.it.junit5.extension.WithDatabase;
|
||||||
|
import org.keycloak.it.storage.database.PostgreSQLTest;
|
||||||
|
|
||||||
|
import io.quarkus.test.junit.main.Launch;
|
||||||
|
import io.quarkus.test.junit.main.LaunchResult;
|
||||||
|
|
||||||
|
@DistributionTest(removeBuildOptionsAfterBuild = true)
|
||||||
|
@WithDatabase(alias = "postgres")
|
||||||
|
public class PostgreSQLDistTest extends PostgreSQLTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Launch("show-config")
|
||||||
|
public void testDbOptionFromPersistedConfigSource(LaunchResult result) {
|
||||||
|
CLIResult cliResult = (CLIResult) result;
|
||||||
|
assertThat(cliResult.getOutput(),containsString("postgres (PersistedConfigSource)"));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue