Fix Operator tests on OpenShift

Closes #22140
Closes #22142
Closes #22143
This commit is contained in:
Václav Muzikář 2023-08-01 12:14:40 +02:00 committed by Alexander Schwartz
parent cce0778886
commit b78b498a26
4 changed files with 50 additions and 33 deletions

View file

@ -41,7 +41,6 @@ import io.quarkus.test.junit.callback.QuarkusTestMethodContext;
import org.awaitility.Awaitility;
import org.eclipse.microprofile.config.ConfigProvider;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.TestInfo;
@ -179,7 +178,11 @@ public class BaseOperatorTest implements QuarkusTestAfterEachCallback {
}
private static void calculateNamespace() {
namespace = "keycloak-test-" + UUID.randomUUID();
namespace = getNewRandomNamespaceName();
}
public static String getNewRandomNamespaceName() {
return "keycloak-test-" + UUID.randomUUID();
}
protected static void deployDB() {

View file

@ -32,6 +32,7 @@ import org.keycloak.operator.crds.v2alpha1.deployment.Keycloak;
import org.keycloak.operator.crds.v2alpha1.deployment.spec.IngressSpec;
import org.keycloak.operator.crds.v2alpha1.deployment.spec.IngressSpecBuilder;
import org.keycloak.operator.crds.v2alpha1.deployment.spec.HostnameSpecBuilder;
import org.keycloak.operator.crds.v2alpha1.deployment.spec.UnsupportedSpecBuilder;
import org.keycloak.operator.testsuite.utils.K8sUtils;
import org.keycloak.operator.controllers.KeycloakIngress;
@ -76,6 +77,19 @@ public class KeycloakIngressTest extends BaseOperatorTest {
// on OpenShift, when Keycloak is configured for HTTP only, we use edge TLS termination, i.e. Route still uses TLS
baseUrl = "https://" + testHostname + ":443";
hostnameSpecBuilder.withHostname(testHostname);
// see https://github.com/keycloak/keycloak/issues/14400#issuecomment-1659900081
kc.getSpec().setUnsupported(new UnsupportedSpecBuilder()
.withNewPodTemplate()
.withNewSpec()
.addNewContainer()
.addNewEnv()
.withName("KC_PROXY")
.withValue("edge")
.endEnv()
.endContainer()
.endSpec()
.endPodTemplate()
.build());
}
else {
baseUrl = "http://" + kubernetesIp + ":80";

View file

@ -19,6 +19,7 @@ package org.keycloak.operator.testsuite.integration;
import io.fabric8.kubernetes.api.model.LocalObjectReference;
import io.fabric8.kubernetes.api.model.LocalObjectReferenceBuilder;
import io.fabric8.kubernetes.api.model.NamespaceBuilder;
import io.fabric8.kubernetes.api.model.PodTemplateSpecBuilder;
import io.fabric8.kubernetes.api.model.Secret;
import io.fabric8.kubernetes.client.dsl.Resource;
@ -110,26 +111,35 @@ public class PodTemplateTest extends BaseOperatorTest {
@Test
public void testPodTemplateIncorrectNamespace() {
// Arrange
var plainKc = getEmptyPodTemplateKeycloak();
var podTemplate = new PodTemplateSpecBuilder()
.withNewMetadata()
.withNamespace("bar")
.endMetadata()
.build();
plainKc.getSpec().getUnsupported().setPodTeplate(podTemplate);
final String wrongNamespace = getNewRandomNamespaceName();
try {
// Arrange
Log.info("Using incorrect namespace: " + wrongNamespace);
k8sclient.resource(new NamespaceBuilder().withNewMetadata().withName(wrongNamespace).endMetadata().build()).create(); // OpenShift actually checks existence of the NS
var plainKc = getEmptyPodTemplateKeycloak();
var podTemplate = new PodTemplateSpecBuilder()
.withNewMetadata()
.withNamespace(wrongNamespace)
.endMetadata()
.build();
plainKc.getSpec().getUnsupported().setPodTeplate(podTemplate);
// Act
K8sUtils.set(k8sclient, plainKc);
// Act
K8sUtils.set(k8sclient, plainKc);
// Assert
Log.info("Getting status of Keycloak");
Awaitility
.await()
.ignoreExceptions()
.atMost(3, MINUTES).untilAsserted(() -> {
CRAssert.assertKeycloakStatusCondition(getCrSelector().get(), HAS_ERRORS, false, "cannot be modified");
});
// Assert
Log.info("Getting status of Keycloak");
Awaitility
.await()
.ignoreExceptions()
.atMost(3, MINUTES).untilAsserted(() -> {
CRAssert.assertKeycloakStatusCondition(getCrSelector().get(), HAS_ERRORS, false, "cannot be modified");
});
}
finally {
Log.info("Deleting incorrect namespace: " + wrongNamespace);
k8sclient.namespaces().withName(wrongNamespace).delete();
}
}
@Test

View file

@ -17,13 +17,11 @@
package org.keycloak.operator.testsuite.integration;
import io.fabric8.kubernetes.api.model.Pod;
import io.fabric8.kubernetes.api.model.Secret;
import io.fabric8.kubernetes.api.model.SecretBuilder;
import io.fabric8.kubernetes.api.model.apps.StatefulSet;
import io.quarkus.logging.Log;
import io.quarkus.test.junit.QuarkusTest;
import org.awaitility.Awaitility;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
@ -34,8 +32,6 @@ import org.keycloak.operator.crds.v2alpha1.deployment.KeycloakStatusCondition;
import org.keycloak.operator.crds.v2alpha1.deployment.ValueOrSecret;
import org.keycloak.operator.crds.v2alpha1.deployment.spec.HostnameSpecBuilder;
import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.HashSet;
import java.util.Set;
@ -98,15 +94,9 @@ public class WatchedSecretsTest extends BaseOperatorTest {
Base64.getEncoder().encodeToString(username.getBytes()));
k8sclient.resource(dbSecret).update();
Pod pod = k8sclient.pods().withName(kc.getMetadata().getName() + "-0").waitUntilCondition(
p -> p != null && !prevRevision.equals(p.getMetadata().getLabels().get("controller-revision-hash")),
30, TimeUnit.SECONDS);
ByteArrayOutputStream logBytes = new ByteArrayOutputStream();
try (var ignored = k8sclient.pods().resource(pod).watchLog(logBytes)) {
Awaitility.await().atMost(1, TimeUnit.MINUTES).until(() -> logBytes.toString(StandardCharsets.UTF_8)
.contains("password authentication failed for user \"" + username + "\""));
}
// dynamically check pod 0 to avoid race conditions
Awaitility.await().atMost(1, TimeUnit.MINUTES).ignoreExceptions().until(() ->
k8sclient.pods().withName(kc.getMetadata().getName() + "-0").getLog().contains("password authentication failed for user \"" + username + "\""));
}
private StatefulSet getStatefulSet(Keycloak kc) {