Merge pull request #1916 from wind57/clean_up_in_a_test

Clean up integration tests
This commit is contained in:
Ryan Baxter
2025-05-02 08:55:05 -04:00
committed by GitHub
14 changed files with 410 additions and 318 deletions

View File

@@ -20,6 +20,7 @@ import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.configserver.configurations.MockConfig;
import org.springframework.context.ConfigurableApplicationContext;
import static org.assertj.core.api.Assertions.assertThat;
@@ -28,7 +29,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Ryan Baxter
*/
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
properties = { "spring.profiles.include=kubernetes,kubernetesdisabled" },
properties = { "spring.profiles.include=kubernetes,kubernetesdisabled", "test.first.config.enabled=true" },
classes = { KubernetesConfigServerApplication.class, MockConfig.class })
class ConfigServerAutoConfigurationKubernetesDisabledTests {

View File

@@ -20,6 +20,7 @@ import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.configserver.configurations.MockConfig;
import org.springframework.context.ConfigurableApplicationContext;
import static org.assertj.core.api.Assertions.assertThat;

View File

@@ -18,21 +18,17 @@ package org.springframework.cloud.kubernetes.configserver;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.cloud.config.server.environment.EnvironmentRepository;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import org.springframework.cloud.kubernetes.configserver.configurations.ThirdConfig;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
@SpringJUnitConfig
@SpringBootTest
@SpringBootTest(classes = ThirdConfig.class, properties = "test.third.config.enabled=true")
class KubernetesEnvironmentRepositoryFactoryTests {
@MockBean
@Autowired
private KubernetesEnvironmentRepository mockRepository;
@Test
@@ -47,20 +43,4 @@ class KubernetesEnvironmentRepositoryFactoryTests {
assertThat(repository).isSameAs(mockRepository);
}
@Configuration
static class TestConfig {
@Bean
public KubernetesEnvironmentRepository kubernetesEnvironmentRepository() {
return mock(KubernetesEnvironmentRepository.class);
}
@Bean
public KubernetesEnvironmentRepositoryFactory kubernetesEnvironmentRepositoryFactory(
KubernetesEnvironmentRepository kubernetesEnvironmentRepository) {
return new KubernetesEnvironmentRepositoryFactory(kubernetesEnvironmentRepository);
}
}
}

View File

@@ -36,6 +36,7 @@ import org.springframework.cloud.config.environment.Environment;
import org.springframework.cloud.kubernetes.client.config.KubernetesClientConfigContext;
import org.springframework.cloud.kubernetes.client.config.KubernetesClientConfigMapPropertySource;
import org.springframework.cloud.kubernetes.client.config.KubernetesClientConfigMapsCache;
import org.springframework.cloud.kubernetes.client.config.KubernetesClientSecretsCache;
import org.springframework.cloud.kubernetes.client.config.KubernetesClientSecretsPropertySource;
import org.springframework.cloud.kubernetes.commons.config.ConfigUtils;
import org.springframework.cloud.kubernetes.commons.config.Constants;
@@ -89,39 +90,33 @@ class KubernetesEnvironmentRepositoryTests {
private static final V1ConfigMapList CONFIGMAP_DEV_LIST = new V1ConfigMapList()
.addItemsItem(new V1ConfigMapBuilder()
.withMetadata(
new V1ObjectMetaBuilder().withName("stores").withNamespace("dev").withResourceVersion("1").build())
.withMetadata(new V1ObjectMetaBuilder().withName("stores").withNamespace("dev").build())
.addToData(Constants.APPLICATION_YAML,
"dummy:\n property:\n string2: \"dev\"\n int2: 1\n bool2: true\n")
.build());
private static final V1SecretList SECRET_LIST = new V1SecretListBuilder()
.addToItems(
new V1SecretBuilder()
.withMetadata(new V1ObjectMetaBuilder().withName("application")
.withResourceVersion("0")
.withNamespace("default")
.build())
.addToData("password", "p455w0rd".getBytes())
.addToData("username", "user".getBytes())
.build())
.addToItems(new V1SecretBuilder().withMetadata(
new V1ObjectMetaBuilder().withName("stores").withResourceVersion("0").withNamespace("default").build())
.addToItems(new V1SecretBuilder()
.withMetadata(new V1ObjectMetaBuilder().withName("application").withNamespace("default").build())
.addToData("password", "p455w0rd".getBytes())
.addToData("username", "user".getBytes())
.build())
.addToItems(new V1SecretBuilder()
.withMetadata(new V1ObjectMetaBuilder().withName("stores").withNamespace("default").build())
.addToData("password", "password-from-stores".getBytes())
.addToData("username", "stores".getBytes())
.build())
.addToItems(new V1SecretBuilder()
.withMetadata(new V1ObjectMetaBuilder().withName("stores-dev")
.withResourceVersion("0")
.withNamespace("default")
.build())
.withMetadata(new V1ObjectMetaBuilder().withName("stores-dev").withNamespace("default").build())
.addToData("password", "password-from-stores-dev".getBytes())
.addToData("username", "stores-dev".getBytes())
.build())
.build();
private static final KubernetesConfigServerProperties PROPERTIES = properties();
@BeforeAll
public static void before() {
static void before() {
KUBERNETES_PROPERTY_SOURCE_SUPPLIER.add((coreApi, applicationName, namespace, springEnv) -> {
List<MapPropertySource> propertySources = new ArrayList<>();
@@ -152,8 +147,9 @@ class KubernetesEnvironmentRepositoryTests {
}
@AfterEach
public void after() {
void after() {
new KubernetesClientConfigMapsCache().discardAll();
new KubernetesClientSecretsCache().discardAll();
}
@Test
@@ -169,7 +165,7 @@ class KubernetesEnvironmentRepositoryTests {
eq(null), eq(null), eq(null), eq(null), eq(null)))
.thenReturn(CONFIGMAP_DEV_LIST);
KubernetesEnvironmentRepository environmentRepository = new KubernetesEnvironmentRepository(coreApi,
KUBERNETES_PROPERTY_SOURCE_SUPPLIER, "default");
KUBERNETES_PROPERTY_SOURCE_SUPPLIER, "default", PROPERTIES);
Environment environment = environmentRepository.findOne("application", "", "");
assertThat(environment.getPropertySources().size()).isEqualTo(2);
environment.getPropertySources().forEach(propertySource -> {
@@ -245,7 +241,7 @@ class KubernetesEnvironmentRepositoryTests {
eq(null), eq(null), eq(null), eq(null), eq(null)))
.thenReturn(SECRET_LIST);
KubernetesEnvironmentRepository environmentRepository = new KubernetesEnvironmentRepository(coreApi,
KUBERNETES_PROPERTY_SOURCE_SUPPLIER, "default");
KUBERNETES_PROPERTY_SOURCE_SUPPLIER, "default", PROPERTIES);
Environment environment = environmentRepository.findOne("stores", "", "");
assertThat(environment.getPropertySources().size()).isEqualTo(4);
environment.getPropertySources().forEach(propertySource -> {
@@ -292,7 +288,7 @@ class KubernetesEnvironmentRepositoryTests {
eq(null), eq(null), eq(null), eq(null), eq(null)))
.thenReturn(CONFIGMAP_DEV_LIST);
KubernetesEnvironmentRepository environmentRepository = new KubernetesEnvironmentRepository(coreApi,
KUBERNETES_PROPERTY_SOURCE_SUPPLIER, "default");
KUBERNETES_PROPERTY_SOURCE_SUPPLIER, "default", PROPERTIES);
Environment environment = environmentRepository.findOne("stores", "dev", "");
assertThat(environment.getPropertySources().size()).isEqualTo(6);
environment.getPropertySources().forEach(propertySource -> {
@@ -356,7 +352,7 @@ class KubernetesEnvironmentRepositoryTests {
eq(null), eq(null), eq(null), eq(null), eq(null)))
.thenReturn(CONFIGMAP_DEV_LIST);
KubernetesEnvironmentRepository environmentRepository = new KubernetesEnvironmentRepository(coreApi,
KUBERNETES_PROPERTY_SOURCE_SUPPLIER, "default");
KUBERNETES_PROPERTY_SOURCE_SUPPLIER, "default", PROPERTIES);
Environment environment = environmentRepository.findOne("stores-dev", "", "");
environment.getPropertySources()
.stream()
@@ -404,7 +400,7 @@ class KubernetesEnvironmentRepositoryTests {
return propertySources;
});
KubernetesEnvironmentRepository environmentRepository = new KubernetesEnvironmentRepository(coreApi, suppliers,
"default");
"default", PROPERTIES);
Environment environment = environmentRepository.findOne("storessingle", "", "");
assertThat(environment.getPropertySources().size()).isEqualTo(1);
assertThat(environment.getPropertySources().get(0).getName())
@@ -434,4 +430,10 @@ class KubernetesEnvironmentRepositoryTests {
}
private static KubernetesConfigServerProperties properties() {
KubernetesConfigServerProperties properties = new KubernetesConfigServerProperties();
properties.setOrder(1);
return properties;
}
}

View File

@@ -27,15 +27,18 @@ import io.kubernetes.client.openapi.models.V1ObjectMetaBuilder;
import io.kubernetes.client.openapi.models.V1Secret;
import io.kubernetes.client.openapi.models.V1SecretBuilder;
import io.kubernetes.client.openapi.models.V1SecretList;
import io.kubernetes.client.openapi.models.V1SecretListBuilder;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import org.springframework.cloud.config.environment.Environment;
import org.springframework.cloud.kubernetes.client.config.KubernetesClientConfigMapsCache;
import org.springframework.cloud.kubernetes.client.config.KubernetesClientSecretsCache;
import org.springframework.cloud.kubernetes.commons.config.Constants;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -47,7 +50,7 @@ import static org.mockito.Mockito.when;
*/
class KubernetesPropertySourceSupplierTests {
private static final CoreV1Api coreApi = mock(CoreV1Api.class);
private static final CoreV1Api CORE_V1_API = mock(CoreV1Api.class);
private static final V1ConfigMapList CONFIGMAP_DEFAULT_LIST = new V1ConfigMapList()
.addItemsItem(buildConfigMap("gateway", "default"));
@@ -58,41 +61,51 @@ class KubernetesPropertySourceSupplierTests {
private static final V1ConfigMapList CONFIGMAP_TEAM_B_LIST = new V1ConfigMapList()
.addItemsItem(buildConfigMap("orders", "team-b"));
private static final V1SecretList SECRET_DEFAULT_LIST = new V1SecretListBuilder()
.addToItems(buildSecret("gateway", "default"))
.build();
private static final V1SecretList SECRET_DEFAULT_LIST = new V1SecretList()
.addItemsItem(buildSecret("gateway", "default"));
private static final V1SecretList SECRET_TEAM_A_LIST = new V1SecretListBuilder()
.addToItems(buildSecret("stores", "team-a"))
.build();
private static final V1SecretList SECRET_TEAM_A_LIST = new V1SecretList()
.addItemsItem(buildSecret("stores", "team-a"));
private static final V1SecretList SECRET_TEAM_B_LIST = new V1SecretListBuilder()
.addToItems(buildSecret("orders", "team-b"))
.build();
private static final V1SecretList SECRET_TEAM_B_LIST = new V1SecretList()
.addItemsItem(buildSecret("orders", "team-b"));
private static final KubernetesConfigServerProperties PROPERTIES = properties();
@BeforeAll
public static void before() throws ApiException {
when(coreApi.listNamespacedConfigMap(eq("default"), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null),
eq(null), eq(null), eq(null), eq(null), eq(null)))
static void beforeAll() throws ApiException {
when(CORE_V1_API.listNamespacedConfigMap("default", null, null, null, null, null, null, null, null, null, null,
null))
.thenReturn(CONFIGMAP_DEFAULT_LIST);
when(coreApi.listNamespacedConfigMap(eq("team-a"), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null),
eq(null), eq(null), eq(null), eq(null), eq(null)))
when(CORE_V1_API.listNamespacedConfigMap("team-a", null, null, null, null, null, null, null, null, null, null,
null))
.thenReturn(CONFIGMAP_TEAM_A_LIST);
when(coreApi.listNamespacedConfigMap(eq("team-b"), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null),
eq(null), eq(null), eq(null), eq(null), eq(null)))
when(CORE_V1_API.listNamespacedConfigMap("team-b", null, null, null, null, null, null, null, null, null, null,
null))
.thenReturn(CONFIGMAP_TEAM_B_LIST);
when(coreApi.listNamespacedSecret(eq("default"), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null),
eq(null), eq(null), eq(null), eq(null), eq(null)))
when(CORE_V1_API.listNamespacedSecret("default", null, null, null, null, null, null, null, null, null, null,
null))
.thenReturn(SECRET_DEFAULT_LIST);
when(coreApi.listNamespacedSecret(eq("team-a"), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null),
eq(null), eq(null), eq(null), eq(null), eq(null)))
when(CORE_V1_API.listNamespacedSecret("team-a", null, null, null, null, null, null, null, null, null, null,
null))
.thenReturn(SECRET_TEAM_A_LIST);
when(coreApi.listNamespacedSecret(eq("team-b"), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null),
eq(null), eq(null), eq(null), eq(null), eq(null)))
when(CORE_V1_API.listNamespacedSecret("team-b", null, null, null, null, null, null, null, null, null, null,
null))
.thenReturn(SECRET_TEAM_B_LIST);
}
@AfterAll
static void afterAll() {
Mockito.reset(CORE_V1_API);
}
@AfterEach
void afterEach() {
new KubernetesClientConfigMapsCache().discardAll();
new KubernetesClientSecretsCache().discardAll();
}
@Test
void whenCurrentAndExtraNamespacesAddedThenAllConfigMapsAreIncluded() {
KubernetesConfigServerProperties kubernetesConfigServerProperties = new KubernetesConfigServerProperties();
@@ -101,8 +114,8 @@ class KubernetesPropertySourceSupplierTests {
KubernetesPropertySourceSupplier kubernetesPropertySourceSupplier = new KubernetesConfigServerAutoConfiguration()
.configMapPropertySourceSupplier(kubernetesConfigServerProperties);
KubernetesEnvironmentRepository environmentRepository = new KubernetesEnvironmentRepository(coreApi,
Collections.singletonList(kubernetesPropertySourceSupplier), "default");
KubernetesEnvironmentRepository environmentRepository = new KubernetesEnvironmentRepository(CORE_V1_API,
Collections.singletonList(kubernetesPropertySourceSupplier), "default", PROPERTIES);
Environment environmentGateway = environmentRepository.findOne("gateway", "", "");
assertThat(environmentGateway.getPropertySources().size()).isEqualTo(1);
@@ -122,8 +135,8 @@ class KubernetesPropertySourceSupplierTests {
KubernetesPropertySourceSupplier kubernetesPropertySourceSupplier = new KubernetesConfigServerAutoConfiguration()
.configMapPropertySourceSupplier(kubernetesConfigServerProperties);
KubernetesEnvironmentRepository environmentRepository = new KubernetesEnvironmentRepository(coreApi,
Collections.singletonList(kubernetesPropertySourceSupplier), "default");
KubernetesEnvironmentRepository environmentRepository = new KubernetesEnvironmentRepository(CORE_V1_API,
Collections.singletonList(kubernetesPropertySourceSupplier), "default", PROPERTIES);
Environment environmentGateway = environmentRepository.findOne("gateway", "", "");
assertThat(environmentGateway.getPropertySources().size()).isEqualTo(0);
@@ -143,8 +156,8 @@ class KubernetesPropertySourceSupplierTests {
KubernetesPropertySourceSupplier kubernetesPropertySourceSupplier = new KubernetesConfigServerAutoConfiguration()
.secretsPropertySourceSupplier(kubernetesConfigServerProperties);
KubernetesEnvironmentRepository environmentRepository = new KubernetesEnvironmentRepository(coreApi,
Collections.singletonList(kubernetesPropertySourceSupplier), "default");
KubernetesEnvironmentRepository environmentRepository = new KubernetesEnvironmentRepository(CORE_V1_API,
Collections.singletonList(kubernetesPropertySourceSupplier), "default", PROPERTIES);
Environment environmentGateway = environmentRepository.findOne("gateway", "", "");
assertThat(environmentGateway.getPropertySources().size()).isEqualTo(1);
@@ -164,8 +177,8 @@ class KubernetesPropertySourceSupplierTests {
KubernetesPropertySourceSupplier kubernetesPropertySourceSupplier = new KubernetesConfigServerAutoConfiguration()
.secretsPropertySourceSupplier(kubernetesConfigServerProperties);
KubernetesEnvironmentRepository environmentRepository = new KubernetesEnvironmentRepository(coreApi,
Collections.singletonList(kubernetesPropertySourceSupplier), "default");
KubernetesEnvironmentRepository environmentRepository = new KubernetesEnvironmentRepository(CORE_V1_API,
Collections.singletonList(kubernetesPropertySourceSupplier), "default", PROPERTIES);
Environment environmentGateway = environmentRepository.findOne("gateway", "", "");
assertThat(environmentGateway.getPropertySources().size()).isEqualTo(0);
@@ -179,19 +192,25 @@ class KubernetesPropertySourceSupplierTests {
private static V1ConfigMap buildConfigMap(String name, String namespace) {
return new V1ConfigMapBuilder()
.withMetadata(
new V1ObjectMetaBuilder().withName(name).withNamespace(namespace).withResourceVersion("1").build())
.addToData(Constants.APPLICATION_YAML, "dummy:\n property:\n string: \"" + name + "\"\n")
.withMetadata(new V1ObjectMetaBuilder().withName(name).withNamespace(namespace).build())
.addToData(Constants.APPLICATION_PROPERTIES, """
dummy.property.string=%s
""".formatted(name))
.build();
}
private static V1Secret buildSecret(String name, String namespace) {
return new V1SecretBuilder()
.withMetadata(
new V1ObjectMetaBuilder().withName(name).withResourceVersion("0").withNamespace(namespace).build())
.withMetadata(new V1ObjectMetaBuilder().withName(name).withNamespace(namespace).build())
.addToData("password", "p455w0rd".getBytes())
.addToData("username", "user".getBytes())
.build();
}
private static KubernetesConfigServerProperties properties() {
KubernetesConfigServerProperties properties = new KubernetesConfigServerProperties();
properties.setOrder(1);
return properties;
}
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.cloud.kubernetes.configserver;
package org.springframework.cloud.kubernetes.configserver.configurations;
import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.client.WireMock;
@@ -22,14 +22,18 @@ import io.kubernetes.client.openapi.ApiClient;
import io.kubernetes.client.openapi.apis.CoreV1Api;
import io.kubernetes.client.util.ClientBuilder;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
/**
* @author Ryan Baxter
*/
public class TestBootstrapConfig {
@Configuration
@ConditionalOnProperty(value = "test.first.config.enabled", havingValue = "true", matchIfMissing = false)
public class FirstConfig {
@Bean
WireMockServer wireMockServer() {
@@ -41,9 +45,7 @@ public class TestBootstrapConfig {
@Bean
ApiClient apiClient(WireMockServer wireMockServer) {
ApiClient apiClient = new ClientBuilder().setBasePath(wireMockServer.baseUrl()).build();
apiClient.setDebugging(true);
return apiClient;
return new ClientBuilder().setBasePath(wireMockServer.baseUrl()).build();
}
@Bean

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.cloud.kubernetes.configserver;
package org.springframework.cloud.kubernetes.configserver.configurations;
import org.springframework.cloud.config.server.environment.EnvironmentRepository;
import org.springframework.context.annotation.Bean;
@@ -24,7 +24,7 @@ import org.springframework.context.annotation.Profile;
import static org.mockito.Mockito.mock;
@Configuration
class MockConfig {
public class MockConfig {
@Bean
@Profile("kubernetesdisabled")

View File

@@ -0,0 +1,94 @@
/*
* Copyright 2013-2025 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.configserver.configurations;
import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.client.WireMock;
import io.kubernetes.client.openapi.ApiClient;
import io.kubernetes.client.openapi.JSON;
import io.kubernetes.client.openapi.apis.CoreV1Api;
import io.kubernetes.client.openapi.models.V1ConfigMap;
import io.kubernetes.client.openapi.models.V1ConfigMapBuilder;
import io.kubernetes.client.openapi.models.V1ConfigMapList;
import io.kubernetes.client.openapi.models.V1ObjectMetaBuilder;
import io.kubernetes.client.openapi.models.V1Secret;
import io.kubernetes.client.openapi.models.V1SecretBuilder;
import io.kubernetes.client.openapi.models.V1SecretList;
import io.kubernetes.client.util.ClientBuilder;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.kubernetes.commons.config.Constants;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.get;
import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching;
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
/**
* @author wind57
*/
@Configuration
@ConditionalOnProperty(value = "test.second.config.enabled", havingValue = "true", matchIfMissing = false)
public class SecondConfig {
private static V1ConfigMap buildConfigMap() {
return new V1ConfigMapBuilder()
.withMetadata(new V1ObjectMetaBuilder().withName("gateway").withNamespace("default").build())
.addToData(Constants.APPLICATION_PROPERTIES, "dummy.property.string=gateway")
.build();
}
private static V1Secret buildSecret() {
return new V1SecretBuilder()
.withMetadata(new V1ObjectMetaBuilder().withName("gateway").withNamespace("default").build())
.addToData("password", "p455w0rd".getBytes())
.addToData("username", "user".getBytes())
.build();
}
private static final V1ConfigMapList CONFIGMAP_DEFAULT_LIST = new V1ConfigMapList().addItemsItem(buildConfigMap());
private static final V1SecretList SECRET_DEFAULT_LIST = new V1SecretList().addItemsItem(buildSecret());
@Bean
WireMockServer wireMockServer() {
WireMockServer wireMockServer = new WireMockServer(options().dynamicPort());
wireMockServer.start();
WireMock.configureFor(wireMockServer.port());
WireMock.stubFor(get(urlMatching("^/api/v1/namespaces/default/configmaps.*"))
.willReturn(aResponse().withStatus(200).withBody(new JSON().serialize(CONFIGMAP_DEFAULT_LIST))));
WireMock.stubFor(get(urlMatching("^/api/v1/namespaces/default/secrets.*"))
.willReturn(aResponse().withStatus(200).withBody(new JSON().serialize(SECRET_DEFAULT_LIST))));
return wireMockServer;
}
@Bean
ApiClient apiClient(WireMockServer wireMockServer) {
return new ClientBuilder().setBasePath(wireMockServer.baseUrl()).build();
}
@Bean
CoreV1Api coreApi(ApiClient apiClient) {
return new CoreV1Api(apiClient);
}
}

View File

@@ -0,0 +1,42 @@
/*
* Copyright 2013-2025 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.configserver.configurations;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.kubernetes.configserver.KubernetesEnvironmentRepository;
import org.springframework.cloud.kubernetes.configserver.KubernetesEnvironmentRepositoryFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import static org.mockito.Mockito.mock;
@Configuration
@ConditionalOnProperty(value = "test.third.config.enabled", havingValue = "true", matchIfMissing = false)
public class ThirdConfig {
@Bean
public KubernetesEnvironmentRepository kubernetesEnvironmentRepository() {
return mock(KubernetesEnvironmentRepository.class);
}
@Bean
public KubernetesEnvironmentRepositoryFactory kubernetesEnvironmentRepositoryFactory(
KubernetesEnvironmentRepository kubernetesEnvironmentRepository) {
return new KubernetesEnvironmentRepositoryFactory(kubernetesEnvironmentRepository);
}
}

View File

@@ -25,7 +25,7 @@ import org.springframework.cloud.kubernetes.configserver.KubernetesConfigServerA
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
properties = { "spring.main.cloud-platform=KUBERNETES", "spring.cloud.kubernetes.client.namespace=default",
"spring.profiles.include=kubernetes", "spring.cloud.kubernetes.secrets.enableApi=true",
"spring.cloud.bootstrap.enabled=true" },
"spring.cloud.bootstrap.enabled=true", "test.first.config.enabled=true" },
classes = { KubernetesConfigServerApplication.class })
class BootstrapConfigServerIntegrationTests extends ConfigServerIntegration {

View File

@@ -16,41 +16,20 @@
package org.springframework.cloud.kubernetes.configserver.it;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import io.kubernetes.client.openapi.ApiException;
import io.kubernetes.client.openapi.apis.CoreV1Api;
import io.kubernetes.client.openapi.models.V1ConfigMap;
import io.kubernetes.client.openapi.models.V1ConfigMapBuilder;
import io.kubernetes.client.openapi.models.V1ConfigMapList;
import io.kubernetes.client.openapi.models.V1ObjectMetaBuilder;
import io.kubernetes.client.openapi.models.V1Secret;
import io.kubernetes.client.openapi.models.V1SecretBuilder;
import io.kubernetes.client.openapi.models.V1SecretList;
import io.kubernetes.client.openapi.models.V1SecretListBuilder;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.cloud.config.environment.Environment;
import org.springframework.cloud.config.environment.PropertySource;
import org.springframework.cloud.config.server.environment.NativeEnvironmentRepository;
import org.springframework.cloud.kubernetes.client.config.KubernetesClientConfigContext;
import org.springframework.cloud.kubernetes.client.config.KubernetesClientConfigMapPropertySource;
import org.springframework.cloud.kubernetes.client.config.KubernetesClientConfigMapsCache;
import org.springframework.cloud.kubernetes.commons.config.Constants;
import org.springframework.cloud.kubernetes.commons.config.NamedConfigMapNormalizedSource;
import org.springframework.cloud.kubernetes.commons.config.NormalizedSource;
import org.springframework.cloud.kubernetes.configserver.KubernetesConfigServerApplication;
import org.springframework.cloud.kubernetes.configserver.KubernetesPropertySourceSupplier;
import org.springframework.core.env.MapPropertySource;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.ActiveProfiles;
@@ -65,59 +44,18 @@ import static org.mockito.Mockito.when;
/**
* @author Arjav Dongaonkar
*/
public class CompositeKubernetesIntegrationTests {
private static final List<KubernetesPropertySourceSupplier> KUBERNETES_PROPERTY_SOURCE_SUPPLIER = new ArrayList<>();
private static V1ConfigMap buildConfigMap(String name, String namespace) {
return new V1ConfigMapBuilder()
.withMetadata(
new V1ObjectMetaBuilder().withName(name).withNamespace(namespace).withResourceVersion("1").build())
.addToData(Constants.APPLICATION_YAML, "dummy:\n property:\n string: \"" + name + "\"\n")
.build();
}
private static V1Secret buildSecret(String name, String namespace) {
return new V1SecretBuilder()
.withMetadata(
new V1ObjectMetaBuilder().withName(name).withResourceVersion("0").withNamespace(namespace).build())
.addToData("password", "p455w0rd".getBytes())
.addToData("username", "user".getBytes())
.build();
}
private static final V1ConfigMapList CONFIGMAP_DEFAULT_LIST = new V1ConfigMapList()
.addItemsItem(buildConfigMap("gateway", "default"));
private static final V1SecretList SECRET_DEFAULT_LIST = new V1SecretListBuilder()
.addToItems(buildSecret("gateway", "default"))
.build();
@BeforeAll
public static void before() {
KUBERNETES_PROPERTY_SOURCE_SUPPLIER.add((coreApi, applicationName, namespace, springEnv) -> {
List<MapPropertySource> propertySources = new ArrayList<>();
NormalizedSource defaultSource = new NamedConfigMapNormalizedSource(applicationName, "default", false,
true);
KubernetesClientConfigContext defaultContext = new KubernetesClientConfigContext(coreApi, defaultSource,
"default", springEnv);
propertySources.add(new KubernetesClientConfigMapPropertySource(defaultContext));
return propertySources;
});
}
class CompositeKubernetesIntegrationTests {
@AfterEach
public void after() {
void after() {
new KubernetesClientConfigMapsCache().discardAll();
}
@Nested
@SpringBootTest(classes = { KubernetesConfigServerApplication.class },
properties = { "spring.main.cloud-platform=KUBERNETES", "spring.cloud.kubernetes.client.namespace=default",
"spring.config.name=compositeconfigserver",
"spring.cloud.config.server.composite[0].type=kubernetes",
"spring.cloud.kubernetes.secrets.enableApi=true" },
"spring.cloud.kubernetes.secrets.enableApi=true", "test.second.config.enabled=true" },
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ActiveProfiles({ "test", "composite", "kubernetes" })
class KubernetesCompositeConfigServerTest {
@@ -125,27 +63,18 @@ public class CompositeKubernetesIntegrationTests {
@LocalServerPort
private int port;
@MockBean
private CoreV1Api coreV1Api;
@Test
public void contextLoads() throws ApiException {
when(coreV1Api.listNamespacedConfigMap(eq("default"), eq(null), eq(null), eq(null), eq(null), eq(null),
eq(null), eq(null), eq(null), eq(null), eq(null), eq(null)))
.thenReturn(CONFIGMAP_DEFAULT_LIST);
when(coreV1Api.listNamespacedSecret(eq("default"), eq(null), eq(null), eq(null), eq(null), eq(null),
eq(null), eq(null), eq(null), eq(null), eq(null), eq(null)))
.thenReturn(SECRET_DEFAULT_LIST);
void contextLoads() {
ResponseEntity<Environment> response = new RestTemplate().exchange(
"http://localhost:" + this.port + "/gateway/default", HttpMethod.GET, null, Environment.class);
Environment environment = response.getBody();
assertThat(environment).isNotNull();
assertThat(environment.getPropertySources()).hasSize(4);
assertThat(environment.getPropertySources().size()).isEqualTo(4);
assertThat(environment.getPropertySources().get(0).getName())
.isEqualTo("configmap.gateway.default.default");
assertThat(environment.getPropertySources().get(1).getName()).contains("secret.gateway.default.default");
assertThat(environment.getPropertySources().get(1).getName()).isEqualTo("secret.gateway.default.default");
}
}
@@ -155,29 +84,19 @@ public class CompositeKubernetesIntegrationTests {
properties = { "spring.main.cloud-platform=KUBERNETES", "spring.cloud.kubernetes.client.namespace=default",
"spring.cloud.config.server.composite[0].type=kubernetes",
"spring.cloud.config.server.composite[1].type=native",
"spring.cloud.config.server.composite[1].location=file:./native-config",
"spring.cloud.kubernetes.secrets.enableApi=true" },
"spring.cloud.kubernetes.secrets.enableApi=true",
"spring.profiles.active=test, composite, kubernetes, native", "test.second.config.enabled=true" },
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ActiveProfiles({ "test", "composite", "kubernetes", "native" })
class KubernetesSecretsEnabledCompositeConfigServerTest {
@LocalServerPort
private int port;
@MockBean
private CoreV1Api coreV1Api;
@SpyBean
private NativeEnvironmentRepository nativeEnvironmentRepository;
@Test
public void contextLoads() throws Exception {
when(coreV1Api.listNamespacedConfigMap(eq("default"), eq(null), eq(null), eq(null), eq(null), eq(null),
eq(null), eq(null), eq(null), eq(null), eq(null), eq(null)))
.thenReturn(CONFIGMAP_DEFAULT_LIST);
when(coreV1Api.listNamespacedSecret(eq("default"), eq(null), eq(null), eq(null), eq(null), eq(null),
eq(null), eq(null), eq(null), eq(null), eq(null), eq(null)))
.thenReturn(SECRET_DEFAULT_LIST);
void contextLoads() {
Environment mockNativeEnvironment = new Environment("gateway", "default");
mockNativeEnvironment.add(new PropertySource("nativeProperties", Map.of("key1", "value1")));
@@ -190,13 +109,12 @@ public class CompositeKubernetesIntegrationTests {
Environment environment = response.getBody();
assertThat(environment).isNotNull();
assertThat(environment.getPropertySources()).hasSizeGreaterThanOrEqualTo(5);
assertThat(environment.getPropertySources().size()).isEqualTo(5);
assertThat(environment.getPropertySources().get(0).getName())
.isEqualTo("configmap.gateway.default.default");
assertThat(environment.getPropertySources().get(1).getName()).contains("secret.gateway.default.default");
assertThat(environment.getPropertySources()).anyMatch(ps -> ps.getName().contains("native"));
}
}
@@ -206,30 +124,19 @@ public class CompositeKubernetesIntegrationTests {
properties = { "spring.main.cloud-platform=KUBERNETES", "spring.cloud.kubernetes.client.namespace=default",
"spring.cloud.config.server.composite[0].type=kubernetes",
"spring.cloud.config.server.composite[1].type=native",
"spring.cloud.config.server.composite[1].location=file:./native-config",
"spring.cloud.kubernetes.config.enableApi=false",
"spring.cloud.kubernetes.secrets.enableApi=true" },
"spring.cloud.kubernetes.config.enableApi=false", "spring.cloud.kubernetes.secrets.enableApi=true",
"spring.profiles.active=test ,composite, kubernetes, native", "test.second.config.enabled=true" },
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ActiveProfiles({ "test", "composite", "kubernetes", "native" })
class KubernetesConfigMapDisabledCompositeConfigServerTest {
@LocalServerPort
private int port;
@MockBean
private CoreV1Api coreV1Api;
@SpyBean
private NativeEnvironmentRepository nativeEnvironmentRepository;
@Test
public void contextLoads() throws Exception {
when(coreV1Api.listNamespacedConfigMap(eq("default"), eq(null), eq(null), eq(null), eq(null), eq(null),
eq(null), eq(null), eq(null), eq(null), eq(null), eq(null)))
.thenReturn(CONFIGMAP_DEFAULT_LIST);
when(coreV1Api.listNamespacedSecret(eq("default"), eq(null), eq(null), eq(null), eq(null), eq(null),
eq(null), eq(null), eq(null), eq(null), eq(null), eq(null)))
.thenReturn(SECRET_DEFAULT_LIST);
void contextLoads() {
Environment mockNativeEnvironment = new Environment("gateway", "default");
mockNativeEnvironment.add(new PropertySource("nativeProperties", Map.of("key1", "value1")));
@@ -242,12 +149,11 @@ public class CompositeKubernetesIntegrationTests {
Environment environment = response.getBody();
assertThat(environment).isNotNull();
assertThat(environment.getPropertySources()).hasSizeGreaterThanOrEqualTo(3);
assertThat(environment.getPropertySources().size()).isEqualTo(3);
assertThat(environment.getPropertySources().get(0).getName()).isEqualTo("secret.gateway.default.default");
assertThat(environment.getPropertySources().get(1).getName()).contains("nativeProperties");
assertThat(environment.getPropertySources().get(1).getName()).isEqualTo("nativeProperties");
assertThat(environment.getPropertySources()).anyMatch(ps -> ps.getName().contains("native"));
}
}
@@ -257,28 +163,18 @@ public class CompositeKubernetesIntegrationTests {
properties = { "spring.main.cloud-platform=KUBERNETES", "spring.cloud.kubernetes.client.namespace=default",
"spring.cloud.config.server.composite[0].type=kubernetes",
"spring.cloud.config.server.composite[1].type=native",
"spring.cloud.config.server.composite[1].location=file:./native-config" },
"spring.profiles.active=test, composite, kubernetes, native", "test.second.config.enabled=true" },
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ActiveProfiles({ "test", "composite", "kubernetes", "native" })
class KubernetesSecretsDisabledCompositeConfigServerTest {
@LocalServerPort
private int port;
@MockBean
private CoreV1Api coreV1Api;
@SpyBean
private NativeEnvironmentRepository nativeEnvironmentRepository;
@Test
public void contextLoads() throws Exception {
when(coreV1Api.listNamespacedConfigMap(eq("default"), eq(null), eq(null), eq(null), eq(null), eq(null),
eq(null), eq(null), eq(null), eq(null), eq(null), eq(null)))
.thenReturn(CONFIGMAP_DEFAULT_LIST);
when(coreV1Api.listNamespacedSecret(eq("default"), eq(null), eq(null), eq(null), eq(null), eq(null),
eq(null), eq(null), eq(null), eq(null), eq(null), eq(null)))
.thenReturn(SECRET_DEFAULT_LIST);
void contextLoads() {
Environment mockNativeEnvironment = new Environment("gateway", "default");
mockNativeEnvironment.add(new PropertySource("nativeProperties", Map.of("key1", "value1")));
@@ -291,64 +187,51 @@ public class CompositeKubernetesIntegrationTests {
Environment environment = response.getBody();
assertThat(environment).isNotNull();
assertThat(environment.getPropertySources()).hasSizeGreaterThanOrEqualTo(3);
assertThat(environment.getPropertySources().size()).isEqualTo(3);
assertThat(environment.getPropertySources().get(0).getName())
.isEqualTo("configmap.gateway.default.default");
assertThat(environment.getPropertySources().get(1).getName()).contains("nativeProperties");
assertThat(environment.getPropertySources().get(1).getName()).isEqualTo("nativeProperties");
assertThat(environment.getPropertySources()).anyMatch(ps -> ps.getName().contains("native"));
}
}
@Nested
@SpringBootTest(classes = { KubernetesConfigServerApplication.class },
properties = { "spring.config.name:compositeconfigserver", "spring.main.cloud-platform=KUBERNETES",
"spring.cloud.kubernetes.client.namespace=default",
"spring.cloud.config.server.native.search-locations=file:./native-config",
properties = { "spring.main.cloud-platform=KUBERNETES", "spring.cloud.kubernetes.client.namespace=default",
"spring.cloud.config.server.native.order=1", "spring.cloud.kubernetes.configserver.order=2",
"spring.cloud.kubernetes.secrets.enableApi=true" },
"spring.cloud.kubernetes.secrets.enableApi=true", "test.second.config.enabled=true",
"spring.profiles.active=test, native, kubernetes" },
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ActiveProfiles({ "test", "native", "kubernetes" })
class NativeAndKubernetesConfigServerTest {
@LocalServerPort
private int port;
@MockBean
private CoreV1Api coreV1Api;
@SpyBean
private NativeEnvironmentRepository nativeEnvironmentRepository;
@Test
public void contextLoads() throws Exception {
when(coreV1Api.listNamespacedConfigMap(eq("default"), eq(null), eq(null), eq(null), eq(null), eq(null),
eq(null), eq(null), eq(null), eq(null), eq(null), eq(null)))
.thenReturn(CONFIGMAP_DEFAULT_LIST);
when(coreV1Api.listNamespacedSecret(eq("default"), eq(null), eq(null), eq(null), eq(null), eq(null),
eq(null), eq(null), eq(null), eq(null), eq(null), eq(null)))
.thenReturn(SECRET_DEFAULT_LIST);
void contextLoads() {
Environment mockNativeEnvironment = new Environment("gateway", "default");
mockNativeEnvironment.add(new PropertySource("nativeProperties", Map.of("key1", "value1")));
Environment nativeEnvironment = new Environment("gateway", "default");
nativeEnvironment.add(new PropertySource("nativeProperties", Map.of("key1", "value1")));
when(nativeEnvironmentRepository.findOne(anyString(), anyString(), eq(null), anyBoolean()))
.thenReturn(mockNativeEnvironment);
.thenReturn(nativeEnvironment);
ResponseEntity<Environment> response = new RestTemplate().exchange(
"http://localhost:" + this.port + "/gateway/default", HttpMethod.GET, null, Environment.class);
Environment environment = response.getBody();
assert environment != null;
assertThat(3).isEqualTo(environment.getPropertySources().size());
assertThat("nativeProperties").isEqualTo(environment.getPropertySources().get(0).getName());
assertThat(environment.getPropertySources().get(1).getName().contains("configmap.gateway.default.default")
&& !environment.getPropertySources().get(1).getName().contains("nativeProperties"))
.isTrue();
assertThat(environment.getPropertySources().get(2).getName()).contains("secret.gateway.default.default");
assertThat(environment.getPropertySources().size()).isEqualTo(3);
assertThat(environment.getPropertySources().get(0).getName()).isEqualTo("nativeProperties");
assertThat(environment.getPropertySources().get(1).getName())
.isEqualTo("configmap.gateway.default.default");
assertThat(environment.getPropertySources().get(2).getName()).isEqualTo("secret.gateway.default.default");
}
}

View File

@@ -16,45 +16,18 @@
package org.springframework.cloud.kubernetes.configserver.it;
import com.github.tomakehurst.wiremock.client.WireMock;
import io.kubernetes.client.util.ClientBuilder;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.mockito.MockedStatic;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.client.KubernetesClientUtils;
import org.springframework.cloud.kubernetes.configserver.KubernetesConfigServerApplication;
import org.springframework.cloud.kubernetes.configserver.TestBootstrapConfig;
import static org.mockito.Mockito.mockStatic;
import org.springframework.cloud.kubernetes.configserver.configurations.FirstConfig;
/**
* @author Ryan Baxter
*/
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
properties = { "spring.main.cloud-platform=KUBERNETES", "spring.cloud.kubernetes.client.namespace=default",
"spring.profiles.include=kubernetes", "spring.cloud.kubernetes.secrets.enableApi=true" },
classes = { KubernetesConfigServerApplication.class, TestBootstrapConfig.class })
"spring.profiles.include=kubernetes", "spring.cloud.kubernetes.secrets.enableApi=true",
"test.first.config.enabled=true" },
classes = { KubernetesConfigServerApplication.class, FirstConfig.class })
class ConfigDataConfigServerIntegrationTests extends ConfigServerIntegration {
private MockedStatic<KubernetesClientUtils> clientUtilsMock;
@BeforeEach
void setup() {
clientUtilsMock = mockStatic(KubernetesClientUtils.class);
clientUtilsMock.when(KubernetesClientUtils::kubernetesApiClient)
.thenReturn(new ClientBuilder().setBasePath(wireMockServer.baseUrl()).build());
}
@AfterEach
void teardown() {
clientUtilsMock.close();
}
@AfterEach
void afterEach() {
WireMock.reset();
}
}

View File

@@ -16,6 +16,8 @@
package org.springframework.cloud.kubernetes.configserver.it;
import java.util.Map;
import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.client.WireMock;
import io.kubernetes.client.openapi.JSON;
@@ -26,12 +28,16 @@ import io.kubernetes.client.openapi.models.V1ObjectMetaBuilder;
import io.kubernetes.client.openapi.models.V1SecretBuilder;
import io.kubernetes.client.openapi.models.V1SecretList;
import io.kubernetes.client.openapi.models.V1SecretListBuilder;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.cloud.config.environment.Environment;
import org.springframework.cloud.config.environment.PropertySource;
import org.springframework.cloud.kubernetes.client.config.KubernetesClientConfigMapsCache;
import org.springframework.cloud.kubernetes.client.config.KubernetesClientSecretsCache;
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.get;
@@ -43,6 +49,50 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
abstract class ConfigServerIntegration {
private static final String SOURCE_NAME = "test-cm";
private static final String NAMESPACE = "default";
private static final String TEST_CONFIG_MAP_DEV_PROPERTIES = "test-cm-dev.properties";
private static final String TEST_CONFIG_MAP_DEV_NAME = "configmap.test-cm.default.dev";
private static final String TEST_CONFIG_MAP_DEV_DATA = """
dummy.property.profile=dev
dummy.property.value=1
dummy.property.enabled=false
""";
private static final String TEST_CONFIG_MAP_QA_PROPERTIES = "test-cm-qa.properties";
private static final String TEST_CONFIG_MAP_QA_DATA = """
dummy.property.profile=qa
dummy.property.value=2
dummy.property.enabled=true
""";
private static final String TEST_CONFIG_MAP_PROD_PROPERTIES = "test-cm-prod.properties";
private static final String TEST_CONFIG_MAP_PROD_NAME = "configmap.test-cm.default.prod";
private static final String TEST_CONFIG_MAP_PROD_DATA = """
dummy.property.profile=prod
dummy.property.value=3
dummy.property.enabled=true
""";
private static final String TEST_CONFIG_MAP_PROPERTIES = "test-cm.properties";
private static final String TEST_CONFIG_MAP_NAME = "configmap.test-cm.default.default";
private static final String TEST_CONFIG_MAP_DATA = """
dummy.property.profile=default
dummy.property.value=4
dummy.property.enabled=true
""";
private static final String TEST_SECRET_NAME = "secret.test-cm.default.default";
@Autowired
private TestRestTemplate testRestTemplate;
@@ -51,23 +101,18 @@ abstract class ConfigServerIntegration {
@BeforeEach
void beforeEach() {
V1ConfigMapList TEST_CONFIGMAP = new V1ConfigMapList().addItemsItem(new V1ConfigMapBuilder().withMetadata(
new V1ObjectMetaBuilder().withName("test-cm").withNamespace("default").withResourceVersion("1").build())
.addToData("test-cm-dev.yaml", "dummy:\n property:\n string2: \"dev\"\n int2: 1\n bool2: false\n")
.addToData("test-cm-qa.yaml", "dummy:\n property:\n string2: \"qa\"\n int2: 2\n bool2: true\n")
.addToData("test-cm-prod.yaml",
"dummy:\n property:\n string2: \"prod\"\n int2: 3\n bool2: true\n")
.addToData("test-cm.yaml", "dummy:\n property:\n string2: \"default\"\n int2: 4\n bool2: true\n")
V1ConfigMapList TEST_CONFIGMAP = new V1ConfigMapList().addItemsItem(new V1ConfigMapBuilder()
.withMetadata(new V1ObjectMetaBuilder().withName(SOURCE_NAME).withNamespace(NAMESPACE).build())
.addToData(TEST_CONFIG_MAP_DEV_PROPERTIES, TEST_CONFIG_MAP_DEV_DATA)
.addToData(TEST_CONFIG_MAP_QA_PROPERTIES, TEST_CONFIG_MAP_QA_DATA)
.addToData(TEST_CONFIG_MAP_PROD_PROPERTIES, TEST_CONFIG_MAP_PROD_DATA)
.addToData(TEST_CONFIG_MAP_PROPERTIES, TEST_CONFIG_MAP_DATA)
.addToData("app.name", "test")
.build());
V1SecretList TEST_SECRET = new V1SecretListBuilder()
.withMetadata(new V1ListMetaBuilder().withResourceVersion("1").build())
V1SecretList TEST_SECRET = new V1SecretListBuilder().withMetadata(new V1ListMetaBuilder().build())
.addToItems(new V1SecretBuilder()
.withMetadata(new V1ObjectMetaBuilder().withName("test-cm")
.withResourceVersion("0")
.withNamespace("default")
.build())
.withMetadata(new V1ObjectMetaBuilder().withName(SOURCE_NAME).withNamespace(NAMESPACE).build())
.addToData("password", "p455w0rd".getBytes())
.addToData("username", "user".getBytes())
.build())
@@ -80,38 +125,87 @@ abstract class ConfigServerIntegration {
.willReturn(aResponse().withStatus(200).withBody(new JSON().serialize(TEST_SECRET))));
}
@AfterEach
void afterEach() {
WireMock.reset();
WireMock.shutdownServer();
wireMockServer.stop();
wireMockServer.shutdownServer();
new KubernetesClientConfigMapsCache().discardAll();
new KubernetesClientSecretsCache().discardAll();
}
@Test
void enabled() {
Environment env = testRestTemplate.getForObject("/test-cm/default", Environment.class);
assertThat(env.getPropertySources().size()).isEqualTo(2);
assertThat(env.getPropertySources().get(0).getName().equals("configmap.test-cm.default.default")).isTrue();
assertThat(env.getPropertySources().get(0).getSource().get("app.name")).isEqualTo("test");
assertThat(env.getPropertySources().get(1).getName().equals("secret.test-cm.default.default")).isTrue();
assertThat(env.getPropertySources().get(1).getSource().get("password")).isEqualTo("p455w0rd");
assertThat(env.getPropertySources().get(1).getSource().get("username")).isEqualTo("user");
Environment defaultEnv = testRestTemplate.getForObject("/test-cm/default", Environment.class);
assertDefaultProfile(defaultEnv);
Environment devprod = testRestTemplate.getForObject("/test-cm/dev,prod", Environment.class);
assertThat(devprod.getPropertySources().size()).isEqualTo(4);
assertThat(devprod.getPropertySources().get(0).getName().equals("configmap.test-cm.default.prod")).isTrue();
assertThat(devprod.getPropertySources().get(0).getSource().size()).isEqualTo(3);
assertThat(devprod.getPropertySources().get(0).getSource().get("dummy.property.int2")).isEqualTo(3);
assertThat(devprod.getPropertySources().get(0).getSource().get("dummy.property.bool2")).isEqualTo(true);
assertThat(devprod.getPropertySources().get(0).getSource().get("dummy.property.string2")).isEqualTo("prod");
assertThat(devprod.getPropertySources().get(1).getName().equals("configmap.test-cm.default.dev")).isTrue();
assertThat(devprod.getPropertySources().get(1).getSource().size()).isEqualTo(3);
assertThat(devprod.getPropertySources().get(1).getSource().get("dummy.property.int2")).isEqualTo(1);
assertThat(devprod.getPropertySources().get(1).getSource().get("dummy.property.bool2")).isEqualTo(false);
assertThat(devprod.getPropertySources().get(1).getSource().get("dummy.property.string2")).isEqualTo("dev");
assertThat(devprod.getPropertySources().get(2).getName().equals("configmap.test-cm.default.default")).isTrue();
assertThat(devprod.getPropertySources().get(2).getSource().size()).isEqualTo(4);
assertThat(devprod.getPropertySources().get(2).getSource().get("app.name")).isEqualTo("test");
assertThat(devprod.getPropertySources().get(2).getSource().get("dummy.property.int2")).isEqualTo(4);
assertThat(devprod.getPropertySources().get(2).getSource().get("dummy.property.bool2")).isEqualTo(true);
assertThat(devprod.getPropertySources().get(2).getSource().get("dummy.property.string2")).isEqualTo("default");
assertThat(devprod.getPropertySources().get(3).getName().equals("secret.test-cm.default.default")).isTrue();
assertThat(devprod.getPropertySources().get(3).getSource().size()).isEqualTo(2);
assertThat(devprod.getPropertySources().get(3).getSource().get("password")).isEqualTo("p455w0rd");
assertThat(devprod.getPropertySources().get(3).getSource().get("username")).isEqualTo("user");
Environment devAndProd = testRestTemplate.getForObject("/test-cm/dev,prod", Environment.class);
assertThat(devAndProd.getPropertySources().size()).isEqualTo(4);
assertTestConfigMapProd(devAndProd);
assertTestConfigMapDev(devAndProd);
assertTestConfigMapDefault(devAndProd);
assertTestSecretDefault(devAndProd);
}
private void assertTestConfigMapDev(Environment devAndProd) {
PropertySource testConfigMapDev = devAndProd.getPropertySources().get(1);
assertThat(testConfigMapDev.getName()).isEqualTo(TEST_CONFIG_MAP_DEV_NAME);
@SuppressWarnings("unchecked")
Map<String, Object> data = (Map<String, Object>) testConfigMapDev.getSource();
assertThat(data).containsExactlyInAnyOrderEntriesOf(Map.of("dummy.property.value", "1",
"dummy.property.enabled", "false", "dummy.property.profile", "dev"));
}
private void assertTestConfigMapProd(Environment devAndProd) {
PropertySource testConfigMapProd = devAndProd.getPropertySources().get(0);
assertThat(testConfigMapProd.getName()).isEqualTo(TEST_CONFIG_MAP_PROD_NAME);
@SuppressWarnings("unchecked")
Map<String, Object> data = (Map<String, Object>) testConfigMapProd.getSource();
assertThat(data).containsExactlyInAnyOrderEntriesOf(Map.of("dummy.property.value", "3",
"dummy.property.enabled", "true", "dummy.property.profile", "prod"));
}
private void assertTestConfigMapDefault(Environment devAndProd) {
PropertySource testConfigMap = devAndProd.getPropertySources().get(2);
assertThat(testConfigMap.getName()).isEqualTo(TEST_CONFIG_MAP_NAME);
@SuppressWarnings("unchecked")
Map<String, Object> data = (Map<String, Object>) testConfigMap.getSource();
assertThat(data).containsExactlyInAnyOrderEntriesOf(Map.of("dummy.property.value", "4",
"dummy.property.enabled", "true", "dummy.property.profile", "default", "app.name", "test"));
}
private void assertTestSecretDefault(Environment devAndProd) {
PropertySource testSecret = devAndProd.getPropertySources().get(3);
assertThat(testSecret.getName()).isEqualTo(TEST_SECRET_NAME);
@SuppressWarnings("unchecked")
Map<String, Object> data = (Map<String, Object>) testSecret.getSource();
assertThat(data).containsExactlyInAnyOrderEntriesOf(Map.of("password", "p455w0rd", "username", "user"));
}
private void assertDefaultProfile(Environment defaultEnv) {
assertThat(defaultEnv.getPropertySources().size()).isEqualTo(2);
PropertySource configMapSource = defaultEnv.getPropertySources().get(0);
assertThat(configMapSource.getName()).isEqualTo(TEST_CONFIG_MAP_NAME);
@SuppressWarnings("unchecked")
Map<String, Object> configmapData = (Map<String, Object>) configMapSource.getSource();
assertThat(configmapData).containsExactlyInAnyOrderEntriesOf(Map.of("dummy.property.value", "4",
"dummy.property.enabled", "true", "dummy.property.profile", "default", "app.name", "test"));
PropertySource secretSource = defaultEnv.getPropertySources().get(1);
assertThat(secretSource.getName()).isEqualTo(TEST_SECRET_NAME);
@SuppressWarnings("unchecked")
Map<String, Object> secretData = (Map<String, Object>) secretSource.getSource();
assertThat(secretData).containsExactlyInAnyOrderEntriesOf(Map.of("password", "p455w0rd", "username", "user"));
}
}

View File

@@ -1,2 +1,3 @@
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
org.springframework.cloud.kubernetes.configserver.TestBootstrapConfig
org.springframework.cloud.kubernetes.configserver.configurations.FirstConfig,\
org.springframework.cloud.kubernetes.configserver.configurations.SecondConfig