Polish tests

pull/18689/head
Stephane Nicoll 5 years ago
parent 6e6f4f763c
commit d254c62712

@ -19,12 +19,12 @@ package org.springframework.boot.actuate.context.properties;
import java.net.URI;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.Optional;
import java.util.function.Consumer;
import org.junit.jupiter.api.Test;
@ -32,12 +32,12 @@ import org.springframework.boot.actuate.context.properties.ConfigurationProperti
import org.springframework.boot.actuate.context.properties.ConfigurationPropertiesReportEndpoint.ContextConfigurationProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.context.ApplicationContext;
import org.springframework.boot.test.context.runner.ContextConsumer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.core.env.Environment;
import static org.assertj.core.api.Assertions.assertThat;
@ -51,207 +51,177 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
class ConfigurationPropertiesReportEndpointTests {
@Test
void configurationPropertiesAreReturned() {
load((context, properties) -> {
assertThat(properties.getBeans().size()).isGreaterThan(0);
ConfigurationPropertiesBeanDescriptor nestedProperties = properties.getBeans().get("testProperties");
assertThat(nestedProperties).isNotNull();
assertThat(nestedProperties.getPrefix()).isEqualTo("test");
assertThat(nestedProperties.getProperties()).isNotEmpty();
});
}
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withUserConfiguration(EndpointConfig.class);
@Test
void entriesWithNullValuesAreNotIncluded() {
load((context, properties) -> {
Map<String, Object> nestedProperties = properties.getBeans().get("testProperties").getProperties();
assertThat(nestedProperties).doesNotContainKey("nullValue");
});
void descriptorDetectsRelevantProperties() {
this.contextRunner.withUserConfiguration(TestPropertiesConfiguration.class).run(assertProperties("test",
(properties) -> assertThat(properties).containsOnlyKeys("dbPassword", "myTestProperty", "duration")));
}
@Test
void defaultKeySanitization() {
load((context, properties) -> {
Map<String, Object> nestedProperties = properties.getBeans().get("testProperties").getProperties();
assertThat(nestedProperties).isNotNull();
assertThat(nestedProperties.get("dbPassword")).isEqualTo("******");
assertThat(nestedProperties.get("myTestProperty")).isEqualTo("654321");
});
void descriptorDoesNotIncludePropertyWithNullValue() {
this.contextRunner.withUserConfiguration(TestPropertiesConfiguration.class)
.run(assertProperties("test", (properties) -> assertThat(properties).doesNotContainKey("nullValue")));
}
@Test
void customKeySanitization() {
load("property", (context, properties) -> {
Map<String, Object> nestedProperties = properties.getBeans().get("testProperties").getProperties();
assertThat(nestedProperties).isNotNull();
assertThat(nestedProperties.get("dbPassword")).isEqualTo("123456");
assertThat(nestedProperties.get("myTestProperty")).isEqualTo("******");
});
void descriptorWithDurationProperty() {
this.contextRunner.withUserConfiguration(TestPropertiesConfiguration.class).run(assertProperties("test",
(properties) -> assertThat(properties.get("duration")).isEqualTo(Duration.ofSeconds(10).toString())));
}
@Test
void customPatternKeySanitization() {
load(".*pass.*", (context, properties) -> {
Map<String, Object> nestedProperties = properties.getBeans().get("testProperties").getProperties();
assertThat(nestedProperties).isNotNull();
assertThat(nestedProperties.get("dbPassword")).isEqualTo("******");
assertThat(nestedProperties.get("myTestProperty")).isEqualTo("654321");
});
void descriptorWithNonCamelCaseProperty() {
this.contextRunner.withUserConfiguration(MixedCasePropertiesConfiguration.class).run(assertProperties(
"mixedcase", (properties) -> assertThat(properties.get("myURL")).isEqualTo("https://example.com")));
}
@Test
@SuppressWarnings("unchecked")
void keySanitizationWithCustomPatternUsingCompositeKeys() {
// gh-4415
load(Arrays.asList(".*\\.secrets\\..*", ".*\\.hidden\\..*"), (context, properties) -> {
Map<String, Object> nestedProperties = properties.getBeans().get("testProperties").getProperties();
assertThat(nestedProperties).isNotNull();
Map<String, Object> secrets = (Map<String, Object>) nestedProperties.get("secrets");
Map<String, Object> hidden = (Map<String, Object>) nestedProperties.get("hidden");
assertThat(secrets.get("mine")).isEqualTo("******");
assertThat(secrets.get("yours")).isEqualTo("******");
assertThat(hidden.get("mine")).isEqualTo("******");
});
void descriptorWithMixedCaseProperty() {
this.contextRunner.withUserConfiguration(MixedCasePropertiesConfiguration.class).run(assertProperties(
"mixedcase", (properties) -> assertThat(properties.get("mIxedCase")).isEqualTo("mixed")));
}
@Test
void nonCamelCaseProperty() {
load((context, properties) -> {
Map<String, Object> nestedProperties = properties.getBeans().get("testProperties").getProperties();
assertThat(nestedProperties.get("myURL")).isEqualTo("https://example.com");
});
void descriptorWithSingleLetterProperty() {
this.contextRunner.withUserConfiguration(MixedCasePropertiesConfiguration.class)
.run(assertProperties("mixedcase", (properties) -> assertThat(properties.get("z")).isEqualTo("zzz")));
}
@Test
void simpleBoolean() {
load((context, properties) -> {
Map<String, Object> nestedProperties = properties.getBeans().get("testProperties").getProperties();
assertThat(nestedProperties.get("simpleBoolean")).isEqualTo(true);
});
void descriptorWithSimpleBooleanProperty() {
this.contextRunner.withUserConfiguration(BooleanPropertiesConfiguration.class).run(assertProperties("boolean",
(properties) -> assertThat(properties.get("simpleBoolean")).isEqualTo(true)));
}
@Test
void mixedBoolean() {
load((context, properties) -> {
Map<String, Object> nestedProperties = properties.getBeans().get("testProperties").getProperties();
assertThat(nestedProperties.get("mixedBoolean")).isEqualTo(true);
});
void descriptorWithMixedBooleanProperty() {
this.contextRunner.withUserConfiguration(BooleanPropertiesConfiguration.class).run(assertProperties("boolean",
(properties) -> assertThat(properties.get("mixedBoolean")).isEqualTo(true)));
}
@Test
void mixedCase() {
load((context, properties) -> {
Map<String, Object> nestedProperties = properties.getBeans().get("testProperties").getProperties();
assertThat(nestedProperties.get("mIxedCase")).isEqualTo("mixed");
});
void sanitizeWithDefaultSettings() {
this.contextRunner.withUserConfiguration(TestPropertiesConfiguration.class)
.run(assertProperties("test", (properties) -> {
assertThat(properties.get("dbPassword")).isEqualTo("******");
assertThat(properties.get("myTestProperty")).isEqualTo("654321");
}));
}
@Test
void duration() {
load((context, properties) -> {
Map<String, Object> nestedProperties = properties.getBeans().get("testProperties").getProperties();
assertThat(nestedProperties.get("duration")).isEqualTo(Duration.ofSeconds(10).toString());
});
void sanitizeWithCustomKey() {
this.contextRunner.withUserConfiguration(TestPropertiesConfiguration.class)
.withPropertyValues("test.keys-to-sanitize=property").run(assertProperties("test", (properties) -> {
assertThat(properties.get("dbPassword")).isEqualTo("123456");
assertThat(properties.get("myTestProperty")).isEqualTo("******");
}));
}
@Test
void singleLetterProperty() {
load((context, properties) -> {
Map<String, Object> nestedProperties = properties.getBeans().get("testProperties").getProperties();
assertThat(nestedProperties.get("z")).isEqualTo("zzz");
});
void sanitizeWithCustomKeyPattern() {
this.contextRunner.withUserConfiguration(TestPropertiesConfiguration.class)
.withPropertyValues("test.keys-to-sanitize=.*pass.*").run(assertProperties("test", (properties) -> {
assertThat(properties.get("dbPassword")).isEqualTo("******");
assertThat(properties.get("myTestProperty")).isEqualTo("654321");
}));
}
@Test
@SuppressWarnings("unchecked")
void listsAreSanitized() {
load((context, properties) -> {
Map<String, Object> nestedProperties = properties.getBeans().get("testProperties").getProperties();
assertThat(nestedProperties.get("listItems")).isInstanceOf(List.class);
List<Object> list = (List<Object>) nestedProperties.get("listItems");
assertThat(list).hasSize(1);
Map<String, Object> item = (Map<String, Object>) list.get(0);
assertThat(item.get("somePassword")).isEqualTo("******");
});
void sanitizeWithCustomPatternUsingCompositeKeys() {
this.contextRunner.withUserConfiguration(Gh4415PropertiesConfiguration.class)
.withPropertyValues("test.keys-to-sanitize=.*\\.secrets\\..*,.*\\.hidden\\..*")
.run(assertProperties("gh4415", (properties) -> {
Map<String, Object> secrets = (Map<String, Object>) properties.get("secrets");
Map<String, Object> hidden = (Map<String, Object>) properties.get("hidden");
assertThat(secrets.get("mine")).isEqualTo("******");
assertThat(secrets.get("yours")).isEqualTo("******");
assertThat(hidden.get("mine")).isEqualTo("******");
}));
}
@Test
void sanitizedUriWithSensitiveInfo() {
load((context, properties) -> {
Map<String, Object> nestedProperties = properties.getBeans().get("testProperties").getProperties();
assertThat(nestedProperties.get("sensitiveUri")).isEqualTo("http://user:******@localhost:8080");
});
this.contextRunner.withUserConfiguration(SensiblePropertiesConfiguration.class)
.run(assertProperties("sensible", (properties) -> assertThat(properties.get("sensitiveUri"))
.isEqualTo("http://user:******@localhost:8080")));
}
@Test
void sanitizedUriWithNoPassword() {
load((context, properties) -> {
Map<String, Object> nestedProperties = properties.getBeans().get("testProperties").getProperties();
assertThat(nestedProperties.get("noPasswordUri")).isEqualTo("http://user:******@localhost:8080");
});
this.contextRunner.withUserConfiguration(SensiblePropertiesConfiguration.class)
.run(assertProperties("sensible", (properties) -> assertThat(properties.get("noPasswordUri"))
.isEqualTo("http://user:******@localhost:8080")));
}
@Test
@SuppressWarnings("unchecked")
void listsOfListsAreSanitized() {
load((context, properties) -> {
Map<String, Object> nestedProperties = properties.getBeans().get("testProperties").getProperties();
assertThat(nestedProperties.get("listOfListItems")).isInstanceOf(List.class);
List<List<Object>> listOfLists = (List<List<Object>>) nestedProperties.get("listOfListItems");
assertThat(listOfLists).hasSize(1);
List<Object> list = listOfLists.get(0);
assertThat(list).hasSize(1);
Map<String, Object> item = (Map<String, Object>) list.get(0);
assertThat(item.get("somePassword")).isEqualTo("******");
});
void sanitizeLists() {
this.contextRunner.withUserConfiguration(SensiblePropertiesConfiguration.class)
.run(assertProperties("sensible", (properties) -> {
assertThat(properties.get("listItems")).isInstanceOf(List.class);
List<Object> list = (List<Object>) properties.get("listItems");
assertThat(list).hasSize(1);
Map<String, Object> item = (Map<String, Object>) list.get(0);
assertThat(item.get("somePassword")).isEqualTo("******");
}));
}
private void load(BiConsumer<ApplicationContext, ContextConfigurationProperties> properties) {
load(Collections.emptyList(), properties);
}
private void load(String keyToSanitize, BiConsumer<ApplicationContext, ContextConfigurationProperties> properties) {
load(Collections.singletonList(keyToSanitize), properties);
@Test
void listsOfListsAreSanitized() {
this.contextRunner.withUserConfiguration(SensiblePropertiesConfiguration.class)
.run(assertProperties("sensible", (properties) -> {
assertThat(properties.get("listOfListItems")).isInstanceOf(List.class);
List<List<Object>> listOfLists = (List<List<Object>>) properties.get("listOfListItems");
assertThat(listOfLists).hasSize(1);
List<Object> list = listOfLists.get(0);
assertThat(list).hasSize(1);
Map<String, Object> item = (Map<String, Object>) list.get(0);
assertThat(item.get("somePassword")).isEqualTo("******");
}));
}
private void load(List<String> keysToSanitize,
BiConsumer<ApplicationContext, ContextConfigurationProperties> properties) {
ApplicationContextRunner contextRunner = new ApplicationContextRunner().withUserConfiguration(Config.class);
contextRunner.run((context) -> {
private ContextConsumer<AssertableApplicationContext> assertProperties(String prefix,
Consumer<Map<String, Object>> properties) {
return (context) -> {
ConfigurationPropertiesReportEndpoint endpoint = context
.getBean(ConfigurationPropertiesReportEndpoint.class);
if (!CollectionUtils.isEmpty(keysToSanitize)) {
endpoint.setKeysToSanitize(StringUtils.toStringArray(keysToSanitize));
}
properties.accept(context, endpoint.configurationProperties().getContexts().get(context.getId()));
});
ContextConfigurationProperties allProperties = endpoint.configurationProperties().getContexts()
.get(context.getId());
Optional<String> key = allProperties.getBeans().keySet().stream()
.filter((id) -> findIdFromPrefix(prefix, id)).findAny();
assertThat(key).describedAs("No configuration properties with prefix '%s' found", prefix).isPresent();
ConfigurationPropertiesBeanDescriptor descriptor = allProperties.getBeans().get(key.get());
assertThat(descriptor.getPrefix()).isEqualTo(prefix);
properties.accept(descriptor.getProperties());
};
}
private boolean findIdFromPrefix(String prefix, String id) {
int separator = id.indexOf("-");
String candidate = (separator != -1) ? id.substring(0, separator) : id;
return prefix.equals(candidate);
}
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties
static class Parent {
static class EndpointConfig {
@Bean
TestProperties testProperties() {
return new TestProperties();
ConfigurationPropertiesReportEndpoint endpoint(Environment environment) {
ConfigurationPropertiesReportEndpoint endpoint = new ConfigurationPropertiesReportEndpoint();
String[] keys = environment.getProperty("test.keys-to-sanitize", String[].class);
if (keys != null) {
endpoint.setKeysToSanitize(keys);
}
return endpoint;
}
}
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties
static class Config {
@Bean
ConfigurationPropertiesReportEndpoint endpoint() {
return new ConfigurationPropertiesReportEndpoint();
}
@Bean
TestProperties testProperties() {
return new TestProperties();
}
@EnableConfigurationProperties(TestProperties.class)
static class TestPropertiesConfiguration {
}
@ -262,39 +232,10 @@ class ConfigurationPropertiesReportEndpointTests {
private String myTestProperty = "654321";
private String myURL = "https://example.com";
private boolean simpleBoolean = true;
private Boolean mixedBoolean = true;
private String mIxedCase = "mixed";
private String z = "zzz";
private Map<String, Object> secrets = new HashMap<>();
private Hidden hidden = new Hidden();
private List<ListItem> listItems = new ArrayList<>();
private List<List<ListItem>> listOfListItems = new ArrayList<>();
private String nullValue = null;
private Duration duration = Duration.ofSeconds(10);
private URI sensitiveUri = URI.create("http://user:password@localhost:8080");
private URI noPasswordUri = URI.create("http://user:@localhost:8080");
TestProperties() {
this.secrets.put("mine", "myPrivateThing");
this.secrets.put("yours", "yourPrivateThing");
this.listItems.add(new ListItem());
this.listOfListItems.add(Arrays.asList(new ListItem()));
}
public String getDbPassword() {
return this.dbPassword;
}
@ -311,28 +252,45 @@ class ConfigurationPropertiesReportEndpointTests {
this.myTestProperty = myTestProperty;
}
public String getMyURL() {
return this.myURL;
public String getNullValue() {
return this.nullValue;
}
public void setMyURL(String myURL) {
this.myURL = myURL;
public void setNullValue(String nullValue) {
this.nullValue = nullValue;
}
public boolean isSimpleBoolean() {
return this.simpleBoolean;
public Duration getDuration() {
return this.duration;
}
public void setSimpleBoolean(boolean simpleBoolean) {
this.simpleBoolean = simpleBoolean;
public void setDuration(Duration duration) {
this.duration = duration;
}
public boolean isMixedBoolean() {
return (this.mixedBoolean != null) ? this.mixedBoolean : false;
}
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(MixedCaseProperties.class)
static class MixedCasePropertiesConfiguration {
}
@ConfigurationProperties("mixedcase")
public static class MixedCaseProperties {
private String myURL = "https://example.com";
private String mIxedCase = "mixed";
private String z = "zzz";
public String getMyURL() {
return this.myURL;
}
public void setMixedBoolean(Boolean mixedBoolean) {
this.mixedBoolean = mixedBoolean;
public void setMyURL(String myURL) {
this.myURL = myURL;
}
public String getmIxedCase() {
@ -351,12 +309,55 @@ class ConfigurationPropertiesReportEndpointTests {
this.z = z;
}
public Map<String, Object> getSecrets() {
return this.secrets;
}
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(BooleanProperties.class)
static class BooleanPropertiesConfiguration {
}
@ConfigurationProperties("boolean")
public static class BooleanProperties {
private boolean simpleBoolean = true;
private Boolean mixedBoolean = true;
public boolean isSimpleBoolean() {
return this.simpleBoolean;
}
public void setSecrets(Map<String, Object> secrets) {
this.secrets = secrets;
public void setSimpleBoolean(boolean simpleBoolean) {
this.simpleBoolean = simpleBoolean;
}
public boolean isMixedBoolean() {
return (this.mixedBoolean != null) ? this.mixedBoolean : false;
}
public void setMixedBoolean(Boolean mixedBoolean) {
this.mixedBoolean = mixedBoolean;
}
}
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(Gh4415Properties.class)
static class Gh4415PropertiesConfiguration {
}
@ConfigurationProperties("gh4415")
public static class Gh4415Properties {
private Hidden hidden = new Hidden();
private Map<String, Object> secrets = new HashMap<>();
Gh4415Properties() {
this.secrets.put("mine", "myPrivateThing");
this.secrets.put("yours", "yourPrivateThing");
}
public Hidden getHidden() {
@ -367,36 +368,50 @@ class ConfigurationPropertiesReportEndpointTests {
this.hidden = hidden;
}
public List<ListItem> getListItems() {
return this.listItems;
public Map<String, Object> getSecrets() {
return this.secrets;
}
public void setListItems(List<ListItem> listItems) {
this.listItems = listItems;
public void setSecrets(Map<String, Object> secrets) {
this.secrets = secrets;
}
public List<List<ListItem>> getListOfListItems() {
return this.listOfListItems;
}
public static class Hidden {
public void setListOfListItems(List<List<ListItem>> listOfListItems) {
this.listOfListItems = listOfListItems;
}
private String mine = "mySecret";
public String getNullValue() {
return this.nullValue;
}
public String getMine() {
return this.mine;
}
public void setNullValue(String nullValue) {
this.nullValue = nullValue;
}
public void setMine(String mine) {
this.mine = mine;
}
public Duration getDuration() {
return this.duration;
}
public void setDuration(Duration duration) {
this.duration = duration;
}
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(SensibleProperties.class)
static class SensiblePropertiesConfiguration {
}
@ConfigurationProperties("sensible")
public static class SensibleProperties {
private URI sensitiveUri = URI.create("http://user:password@localhost:8080");
private URI noPasswordUri = URI.create("http://user:@localhost:8080");
private List<ListItem> listItems = new ArrayList<>();
private List<List<ListItem>> listOfListItems = new ArrayList<>();
SensibleProperties() {
this.listItems.add(new ListItem());
this.listOfListItems.add(Collections.singletonList(new ListItem()));
}
public void setSensitiveUri(URI sensitiveUri) {
@ -415,18 +430,20 @@ class ConfigurationPropertiesReportEndpointTests {
return this.noPasswordUri;
}
public static class Hidden {
private String mine = "mySecret";
public List<ListItem> getListItems() {
return this.listItems;
}
public String getMine() {
return this.mine;
}
public void setListItems(List<ListItem> listItems) {
this.listItems = listItems;
}
public void setMine(String mine) {
this.mine = mine;
}
public List<List<ListItem>> getListOfListItems() {
return this.listOfListItems;
}
public void setListOfListItems(List<List<ListItem>> listOfListItems) {
this.listOfListItems = listOfListItems;
}
public static class ListItem {

Loading…
Cancel
Save