Do not execute test methods before HTTPS listener is not ready (#15984)

Closes #15904
This commit is contained in:
Pedro Igor 2022-12-13 22:47:43 -08:00 committed by GitHub
parent 0f2ca3bfdd
commit d27a5d5b42
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 29 additions and 41 deletions

View file

@ -31,6 +31,7 @@ public @interface DistributionTest {
boolean debug() default false; boolean debug() default false;
boolean keepAlive() default false; boolean keepAlive() default false;
boolean createAdminUser() default false; boolean createAdminUser() default false;
boolean enableTls() default false;
enum ReInstall { enum ReInstall {

View file

@ -40,6 +40,7 @@ public enum DistributionType {
return new RawKeycloakDistribution( return new RawKeycloakDistribution(
config.debug(), config.debug(),
config.keepAlive(), config.keepAlive(),
config.enableTls(),
!DistributionTest.ReInstall.NEVER.equals(config.reInstall()), !DistributionTest.ReInstall.NEVER.equals(config.reInstall()),
config.removeBuildOptionsAfterBuild(), config.removeBuildOptionsAfterBuild(),
config.createAdminUser()); config.createAdminUser());

View file

@ -81,7 +81,9 @@ public final class RawKeycloakDistribution implements KeycloakDistribution {
private boolean manualStop; private boolean manualStop;
private String relativePath; private String relativePath;
private int httpPort; private int httpPort;
private int httpsPort;
private boolean debug; private boolean debug;
private boolean enableTls;
private boolean reCreate; private boolean reCreate;
private boolean removeBuildOptionsAfterBuild; private boolean removeBuildOptionsAfterBuild;
private boolean createAdminUser; private boolean createAdminUser;
@ -89,10 +91,11 @@ public final class RawKeycloakDistribution implements KeycloakDistribution {
private boolean inited = false; private boolean inited = false;
private Map<String, String> envVars = new HashMap<>(); private Map<String, String> envVars = new HashMap<>();
public RawKeycloakDistribution(boolean debug, boolean manualStop, boolean reCreate, boolean removeBuildOptionsAfterBuild, public RawKeycloakDistribution(boolean debug, boolean manualStop, boolean enableTls, boolean reCreate, boolean removeBuildOptionsAfterBuild,
boolean createAdminUser) { boolean createAdminUser) {
this.debug = debug; this.debug = debug;
this.manualStop = manualStop; this.manualStop = manualStop;
this.enableTls = enableTls;
this.reCreate = reCreate; this.reCreate = reCreate;
this.removeBuildOptionsAfterBuild = removeBuildOptionsAfterBuild; this.removeBuildOptionsAfterBuild = removeBuildOptionsAfterBuild;
this.createAdminUser = createAdminUser; this.createAdminUser = createAdminUser;
@ -107,6 +110,7 @@ public final class RawKeycloakDistribution implements KeycloakDistribution {
} }
stop(); stop();
try { try {
configureServer();
startServer(arguments); startServer(arguments);
if (manualStop) { if (manualStop) {
asyncReadOutput(); asyncReadOutput();
@ -134,6 +138,12 @@ public final class RawKeycloakDistribution implements KeycloakDistribution {
return CLIResult.create(getOutputStream(), getErrorStream(), getExitCode()); return CLIResult.create(getOutputStream(), getErrorStream(), getExitCode());
} }
private void configureServer() {
if (enableTls) {
copyOrReplaceFileFromClasspath("/server.keystore", Path.of("conf", "server.keystore"));
}
}
@Override @Override
public void stop() { public void stop() {
if (isRunning()) { if (isRunning()) {
@ -230,6 +240,7 @@ public final class RawKeycloakDistribution implements KeycloakDistribution {
this.relativePath = arguments.stream().filter(arg -> arg.startsWith("--http-relative-path")).map(arg -> arg.substring(arg.indexOf('=') + 1)).findAny().orElse("/"); this.relativePath = arguments.stream().filter(arg -> arg.startsWith("--http-relative-path")).map(arg -> arg.substring(arg.indexOf('=') + 1)).findAny().orElse("/");
this.httpPort = Integer.parseInt(arguments.stream().filter(arg -> arg.startsWith("--http-port")).map(arg -> arg.substring(arg.indexOf('=') + 1)).findAny().orElse("8080")); this.httpPort = Integer.parseInt(arguments.stream().filter(arg -> arg.startsWith("--http-port")).map(arg -> arg.substring(arg.indexOf('=') + 1)).findAny().orElse("8080"));
this.httpsPort = Integer.parseInt(arguments.stream().filter(arg -> arg.startsWith("--https-port")).map(arg -> arg.substring(arg.indexOf('=') + 1)).findAny().orElse("8443"));
allArgs.add("-Dkc.home.dir=" + distPath + File.separator); allArgs.add("-Dkc.home.dir=" + distPath + File.separator);
allArgs.addAll(arguments); allArgs.addAll(arguments);
@ -238,7 +249,15 @@ public final class RawKeycloakDistribution implements KeycloakDistribution {
} }
private void waitForReadiness() throws MalformedURLException { private void waitForReadiness() throws MalformedURLException {
URL contextRoot = new URL("http://localhost:" + httpPort + ("/" + relativePath + "/realms/master/").replace("//", "/")); waitForReadiness("http", httpPort);
if (enableTls) {
waitForReadiness("https", httpsPort);
}
}
private void waitForReadiness(String scheme, int port) throws MalformedURLException {
URL contextRoot = new URL(scheme + "://localhost:" + port + ("/" + relativePath + "/realms/master/").replace("//", "/"));
HttpURLConnection connection = null; HttpURLConnection connection = null;
long startTime = System.currentTimeMillis(); long startTime = System.currentTimeMillis();
@ -250,7 +269,6 @@ public final class RawKeycloakDistribution implements KeycloakDistribution {
try { try {
// wait before checking for opening a new connection // wait before checking for opening a new connection
Thread.sleep(1000);
if ("https".equals(contextRoot.getProtocol())) { if ("https".equals(contextRoot.getProtocol())) {
HttpsURLConnection httpsConnection = (HttpsURLConnection) (connection = (HttpURLConnection) contextRoot.openConnection()); HttpsURLConnection httpsConnection = (HttpsURLConnection) (connection = (HttpURLConnection) contextRoot.openConnection());
httpsConnection.setSSLSocketFactory(createInsecureSslSocketFactory()); httpsConnection.setSSLSocketFactory(createInsecureSslSocketFactory());
@ -271,6 +289,10 @@ public final class RawKeycloakDistribution implements KeycloakDistribution {
if (connection != null) { if (connection != null) {
connection.disconnect(); connection.disconnect();
} }
try {
Thread.sleep(1000);
} catch (Exception ignore) {
}
} }
} }
} }

View file

@ -22,8 +22,6 @@ import static io.restassured.RestAssured.when;
import org.junit.Assert; import org.junit.Assert;
import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.keycloak.it.cli.dist.util.CopyTLSKeystore;
import org.keycloak.it.junit5.extension.BeforeStartDistribution;
import org.keycloak.it.junit5.extension.DistributionTest; import org.keycloak.it.junit5.extension.DistributionTest;
import org.keycloak.it.junit5.extension.RawDistOnly; import org.keycloak.it.junit5.extension.RawDistOnly;
import org.keycloak.protocol.oidc.representations.OIDCConfigurationRepresentation; import org.keycloak.protocol.oidc.representations.OIDCConfigurationRepresentation;
@ -31,8 +29,7 @@ import org.keycloak.protocol.oidc.representations.OIDCConfigurationRepresentatio
import io.quarkus.test.junit.main.Launch; import io.quarkus.test.junit.main.Launch;
import io.restassured.RestAssured; import io.restassured.RestAssured;
@DistributionTest(keepAlive = true, defaultOptions = { "--http-enabled=true" }) @DistributionTest(keepAlive = true, enableTls = true, defaultOptions = { "--http-enabled=true" })
@BeforeStartDistribution(CopyTLSKeystore.class)
@RawDistOnly(reason = "Containers are immutable") @RawDistOnly(reason = "Containers are immutable")
public class HostnameDistTest { public class HostnameDistTest {

View file

@ -24,8 +24,6 @@ import static org.hamcrest.Matchers.containsString;
import org.junit.Assert; import org.junit.Assert;
import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.keycloak.it.cli.dist.util.CopyTLSKeystore;
import org.keycloak.it.junit5.extension.BeforeStartDistribution;
import org.keycloak.it.junit5.extension.DistributionTest; import org.keycloak.it.junit5.extension.DistributionTest;
import org.keycloak.it.junit5.extension.RawDistOnly; import org.keycloak.it.junit5.extension.RawDistOnly;
import org.keycloak.protocol.oidc.representations.OIDCConfigurationRepresentation; import org.keycloak.protocol.oidc.representations.OIDCConfigurationRepresentation;
@ -33,8 +31,7 @@ import org.keycloak.protocol.oidc.representations.OIDCConfigurationRepresentatio
import io.quarkus.test.junit.main.Launch; import io.quarkus.test.junit.main.Launch;
import io.restassured.RestAssured; import io.restassured.RestAssured;
@DistributionTest(keepAlive = true) @DistributionTest(keepAlive = true, enableTls = true)
@BeforeStartDistribution(CopyTLSKeystore.class)
@RawDistOnly(reason = "Containers are immutable") @RawDistOnly(reason = "Containers are immutable")
public class ProxyDistTest { public class ProxyDistTest {

View file

@ -1,30 +0,0 @@
/*
* 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.cli.dist.util;
import java.nio.file.Path;
import java.util.function.Consumer;
import org.keycloak.it.utils.KeycloakDistribution;
public class CopyTLSKeystore implements Consumer<KeycloakDistribution> {
@Override
public void accept(KeycloakDistribution distribution) {
distribution.copyOrReplaceFileFromClasspath("/server.keystore", Path.of("conf", "server.keystore"));
}
}