KEYCLOAK-19547 Switch arquillian quarkus container to use autobuild to prevent timeo… (#8576)

* KEYCLOAK-19547 Switch arquillian quarkus container to use autobuild to prevent timeouts when reaugmentation is longer than 10s

Co-authored-by: Dominik Guhr <dguhr@redhat.com>
This commit is contained in:
Dominik Guhr 2021-10-18 13:53:12 +02:00 committed by GitHub
parent 8ee992e638
commit c45a6fde12
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 46 additions and 76 deletions

View file

@ -168,9 +168,11 @@ public final class PropertyMappers {
}
public static boolean isBuildTimeProperty(String name) {
if ("kc.features".equals(name)) {
if (isFeaturesBuildTimeProperty(name) || isSpiBuildTimeProperty(name)) {
return true;
}
return name.startsWith(MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX)
&& PropertyMapper.MAPPERS.entrySet().stream()
.anyMatch(entry -> entry.getValue().getFrom().equals(name) && entry.getValue().isBuildTime())
@ -184,6 +186,14 @@ public final class PropertyMappers {
&& !PropertyMappers.toCLIFormat("kc.config.file").equals(name);
}
private static boolean isSpiBuildTimeProperty(String name) {
return name.startsWith("kc.spi") && (name.endsWith("provider") || name.endsWith("enabled"));
}
private static boolean isFeaturesBuildTimeProperty(String name) {
return name.startsWith("kc.features");
}
public static String toCLIFormat(String name) {
if (name.indexOf('.') == -1) {
return name;

View file

@ -44,7 +44,7 @@ import org.keycloak.testsuite.arquillian.SuiteContext;
*/
public class KeycloakQuarkusServerDeployableContainer implements DeployableContainer<KeycloakQuarkusConfiguration> {
protected static final Logger log = Logger.getLogger(KeycloakQuarkusServerDeployableContainer.class);
private static final Logger log = Logger.getLogger(KeycloakQuarkusServerDeployableContainer.class);
private KeycloakQuarkusConfiguration configuration;
private Process container;
@ -53,9 +53,7 @@ public class KeycloakQuarkusServerDeployableContainer implements DeployableConta
@Inject
private Instance<SuiteContext> suiteContext;
private boolean forceReaugmentation;
private List<String> additionalArgs = Collections.emptyList();
private List<String> runtimeProperties = Collections.emptyList();
private List<String> additionalBuildArgs = Collections.emptyList();
@Override
public Class<KeycloakQuarkusConfiguration> getConfigurationClass() {
@ -98,7 +96,7 @@ public class KeycloakQuarkusServerDeployableContainer implements DeployableConta
try {
deployArchiveToServer(archive);
restartServer(true);
restartServer();
} catch (Exception e) {
throw new DeploymentException(e.getMessage(),e);
}
@ -111,7 +109,7 @@ public class KeycloakQuarkusServerDeployableContainer implements DeployableConta
File wrkDir = configuration.getProvidersPath().resolve("providers").toFile();
try {
Files.deleteIfExists(wrkDir.toPath().resolve(archive.getName()));
restartServer(true);
restartServer();
} catch (Exception e) {
throw new DeploymentException(e.getMessage(),e);
}
@ -145,33 +143,16 @@ public class KeycloakQuarkusServerDeployableContainer implements DeployableConta
FileUtils.deleteDirectory(configuration.getProvidersPath().resolve("data").toFile());
}
if (isReaugmentBeforeStart()) {
List<String> commands = new ArrayList<>(Arrays.asList("./kc.sh", "build", "-Dquarkus.http.root-path=/auth", "--http-enabled=true"));
addAdditionalCommands(commands);
ProcessBuilder reaugment = new ProcessBuilder(commands);
reaugment.directory(wrkDir).inheritIO();
try {
log.infof("Re-building the server with the new configuration");
reaugment.start().waitFor(10, TimeUnit.SECONDS);
} catch (InterruptedException e) {
throw new RuntimeException("Timeout while waiting for re-augmentation", e);
}
}
return builder.start();
}
private boolean isReaugmentBeforeStart() {
return configuration.isReaugmentBeforeStart() || forceReaugmentation;
}
private String[] getProcessCommands() {
List<String> commands = new ArrayList<>();
commands.add("./kc.sh");
commands.add("-Dquarkus.http.root-path=/auth");
commands.add("--auto-build");
commands.add("--http-enabled=true");
if (configuration.getDebugPort() > 0) {
commands.add("--debug");
@ -184,25 +165,16 @@ public class KeycloakQuarkusServerDeployableContainer implements DeployableConta
commands.add("--http-port=" + configuration.getBindHttpPort());
commands.add("--https-port=" + configuration.getBindHttpsPort());
//for setting the spi.login-protocol.saml.known-protocols values correctly in keycloak.properties
commands.add("-Dauth.server.http.port=" + configuration.getBindHttpPort());
commands.add("-Dauth.server.https.port=" + configuration.getBindHttpsPort());
if (configuration.getRoute() != null) {
commands.add("-Djboss.node.name=" + configuration.getRoute());
}
commands.add("--cluster=" + System.getProperty("auth.server.quarkus.cluster.config", "local"));
commands.addAll(getRuntimeProperties());
addAdditionalCommands(commands);
commands.addAll(getAdditionalBuildArgs());
return commands.toArray(new String[0]);
}
private void addAdditionalCommands(List<String> commands) {
commands.addAll(additionalArgs);
}
private void waitForReadiness() throws MalformedURLException, LifecycleException {
SuiteContext suiteContext = this.suiteContext.get();
//TODO: not sure if the best endpoint but it makes sure that everything is properly initialized. Once we have
@ -295,17 +267,8 @@ public class KeycloakQuarkusServerDeployableContainer implements DeployableConta
return TimeUnit.SECONDS.toMillis(configuration.getStartupTimeoutInSeconds());
}
public void forceReAugmentation(String... args) {
forceReaugmentation = true;
additionalArgs = Arrays.asList(args);
}
public void resetConfiguration(boolean isReAugmentationNeeded) {
additionalArgs = Collections.emptyList();
runtimeProperties = Collections.emptyList();
if (isReAugmentationNeeded) {
forceReAugmentation();
}
public void resetConfiguration() {
additionalBuildArgs = Collections.emptyList();
}
private void deployArchiveToServer(Archive<?> archive) throws IOException {
@ -314,19 +277,16 @@ public class KeycloakQuarkusServerDeployableContainer implements DeployableConta
Files.copy(zipStream, providersDir.toPath().resolve(archive.getName()), StandardCopyOption.REPLACE_EXISTING);
}
public void restartServer(boolean isReaugmentation) throws Exception {
if(isReaugmentation) {
forceReaugmentation = true;
}
public void restartServer() throws Exception {
stop();
start();
}
public List<String> getRuntimeProperties() {
return runtimeProperties;
public List<String> getAdditionalBuildArgs() {
return additionalBuildArgs;
}
public void setRuntimeProperties(List<String> runtimeProperties) {
this.runtimeProperties = runtimeProperties;
public void setAdditionalBuildArgs(List<String> newArgs) {
additionalBuildArgs = newArgs;
}
}

View file

@ -9,6 +9,7 @@ import org.wildfly.extras.creaper.core.online.CliException;
import org.wildfly.extras.creaper.core.online.OnlineManagementClient;
import java.io.IOException;
import java.util.Collections;
public class SpiProvidersSwitchingUtils {
@ -24,7 +25,7 @@ public class SpiProvidersSwitchingUtils {
System.setProperty("keycloak." + annotation.spi() + ".provider", annotation.providerId());
} else if (authServerInfo.isQuarkus()) {
KeycloakQuarkusServerDeployableContainer container = (KeycloakQuarkusServerDeployableContainer) authServerInfo.getArquillianContainer().getDeployableContainer();
container.forceReAugmentation(KEYCLOAKX_ARG_SPI_PREFIX + toDashCase(annotation.spi()) +"-provider="+annotation.providerId());
container.setAdditionalBuildArgs(Collections.singletonList(KEYCLOAKX_ARG_SPI_PREFIX + toDashCase(annotation.spi()) + "-provider=" + annotation.providerId()));
} else {
OnlineManagementClient client = AuthServerTestEnricher.getManagementClient();
@ -45,7 +46,8 @@ public class SpiProvidersSwitchingUtils {
System.clearProperty("keycloak." + annotation.spi() + ".provider");
} else if (authServerInfo.isQuarkus()) {
KeycloakQuarkusServerDeployableContainer container = (KeycloakQuarkusServerDeployableContainer) authServerInfo.getArquillianContainer().getDeployableContainer();
container.resetConfiguration(true);
container.resetConfiguration();
container.setAdditionalBuildArgs(Collections.singletonList(KEYCLOAKX_ARG_SPI_PREFIX + toDashCase(annotation.spi()) + "-provider=default"));
} else {
OnlineManagementClient client = AuthServerTestEnricher.getManagementClient();
if (annotation.onlyUpdateDefault()) {

View file

@ -160,7 +160,7 @@ public class ClientSearchTest extends AbstractClientTest {
String s = String.join(",",searchableAttributes);
controller.stop(suiteContext.getAuthServerInfo().getQualifier());
KeycloakQuarkusServerDeployableContainer container = (KeycloakQuarkusServerDeployableContainer)suiteContext.getAuthServerInfo().getArquillianContainer().getDeployableContainer();
container.setRuntimeProperties(Collections.singletonList("--spi-client-jpa-searchable-attributes=\""+ s + "\""));
container.setAdditionalBuildArgs(Collections.singletonList("--spi-client-jpa-searchable-attributes=\""+ s + "\""));
controller.start(suiteContext.getAuthServerInfo().getQualifier());
} else {
throw new RuntimeException("Don't know how to config");
@ -180,8 +180,8 @@ public class ClientSearchTest extends AbstractClientTest {
executeCli("/subsystem=keycloak-server/spi=client:remove");
} else if(suiteContext.getAuthServerInfo().isQuarkus()) {
KeycloakQuarkusServerDeployableContainer container = (KeycloakQuarkusServerDeployableContainer)suiteContext.getAuthServerInfo().getArquillianContainer().getDeployableContainer();
container.setRuntimeProperties(Collections.emptyList());
container.restartServer(false);
container.setAdditionalBuildArgs(Collections.emptyList());
container.restartServer();
} else {
throw new RuntimeException("Don't know how to config");
}

View file

@ -10,14 +10,13 @@ import org.wildfly.extras.creaper.core.online.OnlineManagementClient;
import org.wildfly.extras.creaper.core.online.operations.admin.Administration;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public abstract class AbstractHostnameTest extends AbstractKeycloakTest {
private static final Logger LOGGER = Logger.getLogger(AbstractHostnameTest.class);
private boolean isReaugmentationNeeded;
@ArquillianResource
protected ContainerController controller;
@ -42,7 +41,8 @@ public abstract class AbstractHostnameTest extends AbstractKeycloakTest {
} else if (suiteContext.getAuthServerInfo().isQuarkus()) {
controller.stop(suiteContext.getAuthServerInfo().getQualifier());
KeycloakQuarkusServerDeployableContainer container = (KeycloakQuarkusServerDeployableContainer)suiteContext.getAuthServerInfo().getArquillianContainer().getDeployableContainer();
container.resetConfiguration(isReaugmentationNeeded);
container.resetConfiguration();
container.setAdditionalBuildArgs(Collections.singletonList("--spi-hostname-provider=default"));
controller.start(suiteContext.getAuthServerInfo().getQualifier());
} else {
throw new RuntimeException("Don't know how to config");
@ -73,15 +73,14 @@ public abstract class AbstractHostnameTest extends AbstractKeycloakTest {
} else if (suiteContext.getAuthServerInfo().isQuarkus()) {
controller.stop(suiteContext.getAuthServerInfo().getQualifier());
KeycloakQuarkusServerDeployableContainer container = (KeycloakQuarkusServerDeployableContainer)suiteContext.getAuthServerInfo().getArquillianContainer().getDeployableContainer();
List<String> runtimeProperties = new ArrayList<>();
runtimeProperties.add("--spi-hostname-default-frontend-url="+frontendUrl);
runtimeProperties.add("--spi-hostname-default-force-backend-url-to-frontend-url="+ forceBackendUrlToFrontendUrl);
List<String> additionalArgs = new ArrayList<>();
additionalArgs.add("--spi-hostname-default-frontend-url="+frontendUrl);
additionalArgs.add("--spi-hostname-default-force-backend-url-to-frontend-url="+ forceBackendUrlToFrontendUrl);
if (adminUrl != null){
runtimeProperties.add("--spi-hostname-default-admin-url="+adminUrl);
additionalArgs.add("--spi-hostname-default-admin-url="+adminUrl);
}
container.setRuntimeProperties(runtimeProperties);
container.setAdditionalBuildArgs(additionalArgs);
controller.start(suiteContext.getAuthServerInfo().getQualifier());
isReaugmentationNeeded = false;
} else {
throw new RuntimeException("Don't know how to config");
}
@ -106,13 +105,12 @@ public abstract class AbstractHostnameTest extends AbstractKeycloakTest {
} else if (suiteContext.getAuthServerInfo().isQuarkus()) {
controller.stop(suiteContext.getAuthServerInfo().getQualifier());
KeycloakQuarkusServerDeployableContainer container = (KeycloakQuarkusServerDeployableContainer)suiteContext.getAuthServerInfo().getArquillianContainer().getDeployableContainer();
container.forceReAugmentation("--spi-hostname-provider=fixed" +
" --spi-hostname-fixed-hostname="+ hostname +
" --spi-hostname-fixed-http-port="+ httpPort +
" --spi-hostname-fixed-https-port="+ httpsPort +
" --spi-hostname-fixed-always-https="+ alwaysHttps);
container.setAdditionalBuildArgs(Collections.singletonList("--spi-hostname-provider=fixed" +
" --spi-hostname-fixed-hostname=" + hostname +
" --spi-hostname-fixed-http-port=" + httpPort +
" --spi-hostname-fixed-https-port=" + httpsPort +
" --spi-hostname-fixed-always-https=" + alwaysHttps));
controller.start(suiteContext.getAuthServerInfo().getQualifier());
isReaugmentationNeeded = true;
} else {
throw new RuntimeException("Don't know how to config");
}