Skip to content

Commit

Permalink
refactored one IT
Browse files Browse the repository at this point in the history
  • Loading branch information
wind57 committed Oct 22, 2023
1 parent 913143c commit 4d1ad87
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,13 @@

package org.springframework.cloud.kubernetes.configuration.watcher;

import java.net.SocketException;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import com.github.tomakehurst.wiremock.client.WireMock;
import io.kubernetes.client.openapi.models.V1ConfigMap;
import io.kubernetes.client.openapi.models.V1ConfigMapBuilder;
import io.kubernetes.client.openapi.models.V1Deployment;
import io.kubernetes.client.openapi.models.V1EnvVar;
import io.kubernetes.client.openapi.models.V1Service;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
Expand Down Expand Up @@ -57,6 +54,9 @@ class ActuatorRefreshIT {

private static final String NAMESPACE = "default";

private static final String DOCKER_IMAGE = "docker.io/springcloud/" + SPRING_CLOUD_K8S_CONFIG_WATCHER_APP_NAME + ":"
+ Commons.pomVersion();

private static final K3sContainer K3S = Commons.container();

private static Util util;
Expand All @@ -68,10 +68,13 @@ static void beforeAll() throws Exception {
Commons.loadSpringCloudKubernetesImage(SPRING_CLOUD_K8S_CONFIG_WATCHER_APP_NAME, K3S);
util = new Util(K3S);
util.setUp(NAMESPACE);

configWatcher(Phase.CREATE);
}

@AfterAll
static void afterAll() throws Exception {
configWatcher(Phase.DELETE);
Commons.cleanUp(SPRING_CLOUD_K8S_CONFIG_WATCHER_APP_NAME, K3S);
Commons.systemPrune();
}
Expand All @@ -96,36 +99,34 @@ void after() {
// curl <WIREMOCK_POD_IP>:8080/__admin/mappings
@Test
void testActuatorRefresh() {
configWatcher(Phase.CREATE, false);

WireMock.configureFor(WIREMOCK_HOST, WIREMOCK_PORT, WIREMOCK_PATH);
await().timeout(Duration.ofSeconds(60))
await().timeout(Duration.ofSeconds(60)).ignoreException(SocketException.class)
.until(() -> WireMock
.stubFor(WireMock.post(WireMock.urlEqualTo("/actuator/refresh"))
.willReturn(WireMock.aResponse().withBody("{}").withStatus(200)))
.getResponse().wasConfigured());

// Create new configmap to trigger controller to signal app to refresh
V1ConfigMap configMap = new V1ConfigMapBuilder().editOrNewMetadata().withName("service-wiremock")
.addToLabels("spring.cloud.kubernetes.config", "true").endMetadata().addToData("foo", "bar").build();
util.createAndWait(NAMESPACE, configMap, null);
createConfigMap();

// Wait a bit before we verify
await().atMost(Duration.ofSeconds(30)).until(
() -> !WireMock.findAll(WireMock.postRequestedFor(WireMock.urlEqualTo("/actuator/refresh"))).isEmpty());

WireMock.verify(WireMock.postRequestedFor(WireMock.urlEqualTo("/actuator/refresh")));
util.deleteAndWait(NAMESPACE, configMap, null);

configWatcher(Phase.DELETE, false);
deleteConfigMap();

// the other test
testActuatorRefreshReloadDisabled();

}

/*
* same test as above, but reload is disabled.
*/
@Test
void testActuatorRefreshReloadDisabled() {
configWatcher(Phase.CREATE, true);

TestUtil.patchForDisabledReload(SPRING_CLOUD_K8S_CONFIG_WATCHER_APP_NAME, NAMESPACE, DOCKER_IMAGE);

WireMock.configureFor(WIREMOCK_HOST, WIREMOCK_PORT, WIREMOCK_PATH);
await().timeout(Duration.ofSeconds(60))
Expand All @@ -134,50 +135,29 @@ void testActuatorRefreshReloadDisabled() {
.willReturn(WireMock.aResponse().withBody("{}").withStatus(200)))
.getResponse().wasConfigured());

// Create new configmap to trigger controller to signal app to refresh
V1ConfigMap configMap = new V1ConfigMapBuilder().editOrNewMetadata().withName("service-wiremock")
.addToLabels("spring.cloud.kubernetes.config", "true").endMetadata().addToData("foo", "bar").build();
util.createAndWait(NAMESPACE, configMap, null);
createConfigMap();

// Wait a bit before we verify
await().atMost(Duration.ofSeconds(30)).until(
() -> !WireMock.findAll(WireMock.postRequestedFor(WireMock.urlEqualTo("/actuator/refresh"))).isEmpty());

Assertions.assertTrue(logs().contains("creating NOOP strategy because reload is disabled"));
Commons.waitForLogStatement("creating NOOP strategy because reload is disabled", K3S,
SPRING_CLOUD_K8S_CONFIG_WATCHER_APP_NAME);

// nothing related to 'ConfigReloadUtil' is present in logs
// this proves that once we disable reload everything still works
Assertions.assertFalse(logs().contains("ConfigReloadUtil"));

WireMock.verify(WireMock.postRequestedFor(WireMock.urlEqualTo("/actuator/refresh")));
util.deleteAndWait(NAMESPACE, configMap, null);

configWatcher(Phase.DELETE, true);
deleteConfigMap();

}

private void configWatcher(Phase phase, boolean disableReload) {
private static void configWatcher(Phase phase) {
V1ConfigMap configMap = (V1ConfigMap) util
.yaml("config-watcher/spring-cloud-kubernetes-configuration-watcher-configmap.yaml");
V1Deployment deployment = (V1Deployment) util
.yaml("config-watcher/spring-cloud-kubernetes-configuration-watcher-http-deployment.yaml");

List<V1EnvVar> envVars = new ArrayList<>(
Optional.ofNullable(deployment.getSpec().getTemplate().getSpec().getContainers().get(0).getEnv())
.orElse(new ArrayList<>()));

V1EnvVar commonsDebug = new V1EnvVar()
.name("LOGGING_LEVEL_ORG_SPRINGFRAMEWORK_CLOUD_KUBERNETES_COMMONS_CONFIG_RELOAD").value("DEBUG");
V1EnvVar watcherDebug = new V1EnvVar()
.name("LOGGING_LEVEL_ORG_SPRINGFRAMEWORK_CLOUD_KUBERNETES_CONFIGURATION_WATCHER").value("DEBUG");

envVars.add(commonsDebug);
envVars.add(watcherDebug);

if (disableReload) {
V1EnvVar disableReloadEnvVar = new V1EnvVar().name("SPRING_CLOUD_KUBERNETES_RELOAD_ENABLED").value("FALSE");
envVars.add(disableReloadEnvVar);
deployment.getSpec().getTemplate().getSpec().getContainers().get(0).setEnv(envVars);
}

.yaml("config-watcher/spring-cloud-kubernetes-configuration-watcher-deployment.yaml");
V1Service service = (V1Service) util
.yaml("config-watcher/spring-cloud-kubernetes-configuration-watcher-service.yaml");

Expand All @@ -192,6 +172,19 @@ private void configWatcher(Phase phase, boolean disableReload) {

}

// Create new configmap to trigger controller to signal app to refresh
private void createConfigMap() {
V1ConfigMap configMap = new V1ConfigMapBuilder().editOrNewMetadata().withName("service-wiremock")
.addToLabels("spring.cloud.kubernetes.config", "true").endMetadata().addToData("foo", "bar").build();
util.createAndWait(NAMESPACE, configMap, null);
}

private void deleteConfigMap() {
V1ConfigMap configMap = new V1ConfigMapBuilder().editOrNewMetadata().withName("service-wiremock")
.addToLabels("spring.cloud.kubernetes.config", "true").endMetadata().addToData("foo", "bar").build();
util.deleteAndWait(NAMESPACE, configMap, null);
}

private String logs() {
try {
String appPodName = K3S.execInContainer("sh", "-c", "kubectl get pods -l app="
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package org.springframework.cloud.kubernetes.configuration.watcher;

import java.net.SocketException;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.Base64;
Expand Down Expand Up @@ -156,7 +157,7 @@ void testConfigMapActuatorRefreshMultipleNamespaces() {
@Test
void testSecretActuatorRefreshMultipleNamespaces() {
WireMock.configureFor(WIREMOCK_HOST, WIREMOCK_PORT, WIREMOCK_PATH);
await().timeout(Duration.ofSeconds(60))
await().timeout(Duration.ofSeconds(60)).ignoreException(SocketException.class)
.until(() -> WireMock
.stubFor(WireMock.post(WireMock.urlEqualTo("/actuator/refresh"))
.willReturn(WireMock.aResponse().withBody("{}").withStatus(200)))
Expand Down Expand Up @@ -197,7 +198,7 @@ private void configWatcher(Phase phase) {
V1ConfigMap configMap = (V1ConfigMap) util
.yaml("config-watcher/spring-cloud-kubernetes-configuration-watcher-configmap.yaml");
V1Deployment deployment = (V1Deployment) util
.yaml("config-watcher/spring-cloud-kubernetes-configuration-watcher-http-deployment.yaml");
.yaml("config-watcher/spring-cloud-kubernetes-configuration-watcher-deployment.yaml");

List<V1EnvVar> envVars = List.of(
new V1EnvVar().name("SPRING_CLOUD_KUBERNETES_RELOAD_NAMESPACES_0").value(LEFT_NAMESPACE),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* Copyright 2013-2023 the original author or authors.
*
* 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
*
* https://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.springframework.cloud.kubernetes.configuration.watcher;

import java.util.Map;

import static org.springframework.cloud.kubernetes.integration.tests.commons.native_client.Util.patchWithReplace;

/**
* @author wind57
*/
final class TestUtil {

private TestUtil() {

}

private static final Map<String, String> POD_LABELS = Map.of("app",
"spring-cloud-kubernetes-configuration-watcher");

private static final String BODY_ONE = """
{
"spec": {
"template": {
"spec": {
"containers": [{
"name": "spring-cloud-kubernetes-configuration-watcher",
"image": "image_name_here",
"env": [
{
"name": "LOGGING_LEVEL_ORG_SPRINGFRAMEWORK_CLOUD_KUBERNETES_COMMONS_CONFIG_RELOAD",
"value": "DEBUG"
},
{
"name": "LOGGING_LEVEL_ORG_SPRINGFRAMEWORK_CLOUD_KUBERNETES_CONFIGURATION_WATCHER",
"value": "DEBUG"
},
{
"name": "SPRING_CLOUD_KUBERNETES_RELOAD_ENABLED",
"value": "FALSE"
}
]
}]
}
}
}
}
""";

static void patchForDisabledReload(String deploymentName, String namespace, String imageName) {
patchWithReplace(imageName, deploymentName, namespace, BODY_ONE, POD_LABELS);
}

}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-cloud-kubernetes-configuration-watcher-deployment
name: spring-cloud-kubernetes-configuration-watcher
spec:
selector:
matchLabels:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -240,13 +240,13 @@ public static String pomVersion() {
/**
* the assumption is that there is only a single pod that is 'Running'.
*/
public static void waitForLogStatement(String message, K3sContainer k3sContainer, String imageName) {
public static void waitForLogStatement(String message, K3sContainer k3sContainer, String appLabelValue) {
try {

await().atMost(Duration.ofMinutes(2)).pollInterval(Duration.ofSeconds(4)).until(() -> {

String appPodName = k3sContainer.execInContainer("sh", "-c",
"kubectl get pods -l app=" + imageName
"kubectl get pods -l app=" + appLabelValue
+ " -o custom-columns=POD:metadata.name,STATUS:status.phase"
+ " | grep -i 'running' | awk '{print $1}' | tr -d '\n' ")
.getStdout();
Expand Down

0 comments on commit 4d1ad87

Please sign in to comment.