ConfigDataEnvironmentTests Class — spring-boot Architecture
Architecture documentation for the ConfigDataEnvironmentTests class in ConfigDataEnvironmentTests.java from the spring-boot codebase.
Entity Profile
Relationship Graph
Source Code
core/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigDataEnvironmentTests.java lines 66–425
class ConfigDataEnvironmentTests {
private final DeferredLogFactory logFactory = Supplier::get;
private final DefaultBootstrapContext bootstrapContext = new DefaultBootstrapContext();
private final MockApplicationEnvironment environment = new MockApplicationEnvironment();
private final ResourceLoader resourceLoader = new DefaultResourceLoader();
private final Collection<String> additionalProfiles = Collections.emptyList();
private final ConversionService conversionService = DefaultConversionService.getSharedInstance();
@Test
void createExposesEnvironmentBinderToConfigDataLocationResolvers() {
this.environment.setProperty("spring", "boot");
TestConfigDataEnvironment configDataEnvironment = new TestConfigDataEnvironment(this.logFactory,
this.bootstrapContext, this.environment, this.resourceLoader, this.additionalProfiles, null);
Binder binder = configDataEnvironment.getConfigDataLocationResolversBinder();
assertThat(binder).isNotNull();
assertThat(binder.bind("spring", String.class).get()).isEqualTo("boot");
}
@Test
void createCreatesContributorsBasedOnExistingSources() {
MockPropertySource propertySource1 = new MockPropertySource("p1");
MockPropertySource propertySource2 = new MockPropertySource("p2");
MockPropertySource propertySource3 = new MockPropertySource("p3");
this.environment.getPropertySources().addLast(propertySource1);
this.environment.getPropertySources().addLast(propertySource2);
this.environment.getPropertySources().addLast(propertySource3);
ConfigDataEnvironment configDataEnvironment = new ConfigDataEnvironment(this.logFactory, this.bootstrapContext,
this.environment, this.resourceLoader, this.additionalProfiles, null);
List<ConfigDataEnvironmentContributor> children = configDataEnvironment.getContributors()
.getRoot()
.getChildren(ImportPhase.BEFORE_PROFILE_ACTIVATION);
Object[] wrapped = children.stream()
.filter((child) -> child.getKind() == Kind.EXISTING)
.map(ConfigDataEnvironmentContributor::getPropertySource)
.toArray();
assertThat(wrapped[1]).isEqualTo(propertySource1);
assertThat(wrapped[2]).isEqualTo(propertySource2);
assertThat(wrapped[3]).isEqualTo(propertySource3);
}
@Test
void createWhenHasDefaultPropertySourceMovesItToLastContributor() {
MockPropertySource defaultPropertySource = new MockPropertySource("defaultProperties");
MockPropertySource propertySource1 = new MockPropertySource("p2");
MockPropertySource propertySource2 = new MockPropertySource("p3");
this.environment.getPropertySources().addLast(defaultPropertySource);
this.environment.getPropertySources().addLast(propertySource1);
this.environment.getPropertySources().addLast(propertySource2);
ConfigDataEnvironment configDataEnvironment = new ConfigDataEnvironment(this.logFactory, this.bootstrapContext,
this.environment, this.resourceLoader, this.additionalProfiles, null);
List<ConfigDataEnvironmentContributor> children = configDataEnvironment.getContributors()
.getRoot()
.getChildren(ImportPhase.BEFORE_PROFILE_ACTIVATION);
Object[] wrapped = children.stream()
.filter((child) -> child.getKind() == Kind.EXISTING)
.map(ConfigDataEnvironmentContributor::getPropertySource)
.toArray();
assertThat(wrapped[1]).isEqualTo(propertySource1);
assertThat(wrapped[2]).isEqualTo(propertySource2);
assertThat(wrapped[3]).isEqualTo(defaultPropertySource);
}
@Test
void createCreatesInitialImportContributorsInCorrectOrder() {
this.environment.setProperty("spring.config.location", "l1,l2");
this.environment.setProperty("spring.config.additional-location", "a1,a2");
this.environment.setProperty("spring.config.import", "i1,i2");
ConfigDataEnvironment configDataEnvironment = new ConfigDataEnvironment(this.logFactory, this.bootstrapContext,
this.environment, this.resourceLoader, this.additionalProfiles, null);
List<ConfigDataEnvironmentContributor> children = configDataEnvironment.getContributors()
.getRoot()
.getChildren(ImportPhase.BEFORE_PROFILE_ACTIVATION);
Object[] imports = children.stream()
.filter((child) -> child.getKind() == Kind.INITIAL_IMPORT)
.map(ConfigDataEnvironmentContributor::getImports)
.map(Object::toString)
.toArray();
assertThat(imports).containsExactly("[i2]", "[i1]", "[a2]", "[a1]", "[l2]", "[l1]");
}
@Test
@WithResource(name = "application.properties", content = "spring=boot")
void processAndApplyAddsImportedSourceToEnvironment() {
ConfigDataEnvironment configDataEnvironment = new ConfigDataEnvironment(this.logFactory, this.bootstrapContext,
this.environment, this.resourceLoader, this.additionalProfiles, null);
configDataEnvironment.processAndApply();
assertThat(this.environment.getProperty("spring")).isEqualTo("boot");
}
@Test
@WithResource(name = "application.properties", content = """
spring=boot
#---
spring.config.activate.on-profile=missing
other=value
No newline at end of file
""")
void processAndApplyOnlyAddsActiveContributors() {
ConfigDataEnvironment configDataEnvironment = new ConfigDataEnvironment(this.logFactory, this.bootstrapContext,
this.environment, this.resourceLoader, this.additionalProfiles, null);
configDataEnvironment.processAndApply();
assertThat(this.environment.getProperty("spring")).isEqualTo("boot");
assertThat(this.environment.getProperty("other")).isNull();
}
@Test
void processAndApplyMovesDefaultPropertySourceToLast(TestInfo info) {
MockPropertySource defaultPropertySource = new MockPropertySource("defaultProperties");
this.environment.getPropertySources().addFirst(defaultPropertySource);
this.environment.setProperty("spring.config.location", getConfigLocation(info));
ConfigDataEnvironment configDataEnvironment = new ConfigDataEnvironment(this.logFactory, this.bootstrapContext,
this.environment, this.resourceLoader, this.additionalProfiles, null);
configDataEnvironment.processAndApply();
List<PropertySource<?>> sources = this.environment.getPropertySources().stream().toList();
assertThat(sources.get(sources.size() - 1)).isSameAs(defaultPropertySource);
}
@Test
@WithResource(name = "application.properties", content = "spring.profiles.default=one,two,three")
void processAndApplySetsDefaultProfiles(TestInfo info) {
ConfigDataEnvironment configDataEnvironment = new ConfigDataEnvironment(this.logFactory, this.bootstrapContext,
this.environment, this.resourceLoader, this.additionalProfiles, null);
configDataEnvironment.processAndApply();
assertThat(this.environment.getDefaultProfiles()).containsExactly("one", "two", "three");
}
@Test
@WithResource(name = "application.properties", content = "spring.profiles.active=one,two,three")
void processAndApplySetsActiveProfiles() {
ConfigDataEnvironment configDataEnvironment = new ConfigDataEnvironment(this.logFactory, this.bootstrapContext,
this.environment, this.resourceLoader, this.additionalProfiles, null);
configDataEnvironment.processAndApply();
assertThat(this.environment.getActiveProfiles()).containsExactly("one", "two", "three");
}
@Test
@WithResource(name = "application.properties", content = """
spring.profiles.active=one,two,three
spring.profiles.group.one=four,five
""")
void processAndApplySetsActiveProfilesAndProfileGroups() {
ConfigDataEnvironment configDataEnvironment = new ConfigDataEnvironment(this.logFactory, this.bootstrapContext,
this.environment, this.resourceLoader, this.additionalProfiles, null);
configDataEnvironment.processAndApply();
assertThat(this.environment.getActiveProfiles()).containsExactly("one", "four", "five", "two", "three");
}
@Test
@WithResource(name = "application.properties", content = "spring.profiles.active=test")
void processAndApplyDoesNotSetProfilesFromIgnoreProfilesContributors(TestInfo info) {
ConfigDataEnvironment configDataEnvironment = new ConfigDataEnvironment(this.logFactory, this.bootstrapContext,
this.environment, this.resourceLoader, this.additionalProfiles, null) {
@Override
protected ConfigDataEnvironmentContributors createContributors(
List<ConfigDataEnvironmentContributor> contributors) {
Map<String, Object> source = new LinkedHashMap<>();
source.put("spring.profiles.active", "ignore1");
source.put("spring.profiles.include", "ignore2");
ConfigData data = new ConfigData(Collections.singleton(new MapPropertySource("test", source)),
ConfigData.Option.IGNORE_PROFILES);
contributors.add(ConfigDataEnvironmentContributor.ofUnboundImport(ConfigDataLocation.of("test"),
mock(ConfigDataResource.class), false, data, 0,
ConfigDataEnvironmentTests.this.conversionService, ConfigDataEnvironmentUpdateListener.NONE));
return super.createContributors(contributors);
}
};
configDataEnvironment.processAndApply();
assertThat(this.environment.getActiveProfiles()).containsExactly("test");
}
@ParameterizedTest
@ValueSource(strings = { "include", "include[0]" })
void processAndApplyWhenHasProfileIncludeInProfileSpecificDocumentThrowsException(String property, TestInfo info) {
this.environment.setProperty("spring.config.location", getConfigLocation(info));
ConfigDataEnvironment configDataEnvironment = new ConfigDataEnvironment(this.logFactory, this.bootstrapContext,
this.environment, this.resourceLoader, this.additionalProfiles, null) {
@Override
protected ConfigDataEnvironmentContributors createContributors(
List<ConfigDataEnvironmentContributor> contributors) {
Map<String, Object> source = new LinkedHashMap<>();
source.put("spring.config.activate.on-profile", "activate");
source.put("spring.profiles." + property, "include");
ConfigData data = new ConfigData(Collections.singleton(new MapPropertySource("test", source)));
contributors.add(ConfigDataEnvironmentContributor.ofUnboundImport(ConfigDataLocation.of("test"),
mock(ConfigDataResource.class), false, data, 0,
ConfigDataEnvironmentTests.this.conversionService, ConfigDataEnvironmentUpdateListener.NONE));
return super.createContributors(contributors);
}
};
assertThatExceptionOfType(InactiveConfigDataAccessException.class)
.isThrownBy(configDataEnvironment::processAndApply);
}
@ParameterizedTest
@ValueSource(strings = { "spring.profiles.include", "spring.profiles.include[0]" })
void processAndApplyIncludesProfilesFromSpringProfilesInclude(String property, TestInfo info) {
this.environment.setProperty("spring.config.location", getConfigLocation(info));
ConfigDataEnvironment configDataEnvironment = new ConfigDataEnvironment(this.logFactory, this.bootstrapContext,
this.environment, this.resourceLoader, this.additionalProfiles, null) {
@Override
protected ConfigDataEnvironmentContributors createContributors(
List<ConfigDataEnvironmentContributor> contributors) {
Map<String, Object> source = new LinkedHashMap<>();
source.put(property, "included");
ConfigData data = new ConfigData(Collections.singleton(new MapPropertySource("test", source)));
contributors.add(ConfigDataEnvironmentContributor.ofUnboundImport(ConfigDataLocation.of("test"),
mock(ConfigDataResource.class), false, data, 0,
ConfigDataEnvironmentTests.this.conversionService, ConfigDataEnvironmentUpdateListener.NONE));
return super.createContributors(contributors);
}
};
configDataEnvironment.processAndApply();
assertThat(this.environment.getActiveProfiles()).containsExactly("included");
}
@Test
@WithResource(name = "application.properties", content = "spring=boot")
void processAndApplyDoesNotSetProfilesFromIgnoreProfilesContributorsWhenNoProfilesActive(TestInfo info) {
ConfigDataEnvironment configDataEnvironment = new ConfigDataEnvironment(this.logFactory, this.bootstrapContext,
this.environment, this.resourceLoader, this.additionalProfiles, null) {
@Override
protected ConfigDataEnvironmentContributors createContributors(
List<ConfigDataEnvironmentContributor> contributors) {
Map<String, Object> source = new LinkedHashMap<>();
source.put("spring.profiles.active", "ignore1");
source.put("spring.profiles.include", "ignore2");
ConfigData data = new ConfigData(Collections.singleton(new MapPropertySource("test", source)),
ConfigData.Option.IGNORE_PROFILES);
contributors.add(ConfigDataEnvironmentContributor.ofUnboundImport(ConfigDataLocation.of("test"),
mock(ConfigDataResource.class), false, data, 0,
ConfigDataEnvironmentTests.this.conversionService, ConfigDataEnvironmentUpdateListener.NONE));
return super.createContributors(contributors);
}
};
configDataEnvironment.processAndApply();
assertThat(this.environment.getActiveProfiles()).isEmpty();
assertThat(this.environment.getProperty("spring")).isEqualTo("boot");
}
@Test
void processAndApplyWhenHasInvalidPropertyThrowsException() {
this.environment.setProperty("spring.profiles", "a");
ConfigDataEnvironment configDataEnvironment = new ConfigDataEnvironment(this.logFactory, this.bootstrapContext,
this.environment, this.resourceLoader, this.additionalProfiles, null);
assertThatExceptionOfType(InvalidConfigDataPropertyException.class)
.isThrownBy(configDataEnvironment::processAndApply);
}
@Test
@WithResource(name = "custom/config.properties", content = "spring=boot")
void processAndApplyWhenHasListenerCallsOnPropertySourceAdded(TestInfo info) {
this.environment.setProperty("spring.config.location", "classpath:custom/config.properties");
TestConfigDataEnvironmentUpdateListener listener = new TestConfigDataEnvironmentUpdateListener();
ConfigDataEnvironment configDataEnvironment = new ConfigDataEnvironment(this.logFactory, this.bootstrapContext,
this.environment, this.resourceLoader, this.additionalProfiles, listener);
configDataEnvironment.processAndApply();
assertThat(listener.getAddedPropertySources()).hasSize(1);
AddedPropertySource addedPropertySource = listener.getAddedPropertySources().get(0);
assertThat(addedPropertySource.getPropertySource().getProperty("spring")).isEqualTo("boot");
assertThat(addedPropertySource.getLocation()).hasToString("classpath:custom/config.properties");
ConfigDataResource resource = addedPropertySource.getResource();
assertThat(resource).isNotNull();
assertThat(resource.toString()).contains("class path resource").contains("custom/config.properties");
}
@Test
@WithResource(name = "application.properties", content = "spring.profiles.active=one,two,three")
void processAndApplyWhenHasListenerCallsOnSetProfiles(TestInfo info) {
TestConfigDataEnvironmentUpdateListener listener = new TestConfigDataEnvironmentUpdateListener();
ConfigDataEnvironment configDataEnvironment = new ConfigDataEnvironment(this.logFactory, this.bootstrapContext,
this.environment, this.resourceLoader, this.additionalProfiles, listener);
configDataEnvironment.processAndApply();
Profiles profiles = listener.getProfiles();
assertThat(profiles).isNotNull();
assertThat(profiles.getActive()).containsExactly("one", "two", "three");
}
@Test
@SuppressWarnings("rawtypes")
@WithResource(name = "separate-class-loader-spring.factories", content = """
org.springframework.boot.context.config.ConfigDataLoader=\
org.springframework.boot.context.config.ConfigDataEnvironmentTests$SeparateClassLoaderConfigDataLoader
""")
void configDataLoadersAreLoadedUsingClassLoaderFromResourceLoader() {
ResourceLoader resourceLoader = mock(ResourceLoader.class);
ClassLoader classLoader = new ClassLoader(Thread.currentThread().getContextClassLoader()) {
@Override
public Enumeration<URL> getResources(String name) throws IOException {
if (SpringFactoriesLoader.FACTORIES_RESOURCE_LOCATION.equals(name)) {
return super.getResources("separate-class-loader-spring.factories");
}
return super.getResources(name);
}
};
given(resourceLoader.getClassLoader()).willReturn(classLoader);
TestConfigDataEnvironment configDataEnvironment = new TestConfigDataEnvironment(this.logFactory,
this.bootstrapContext, this.environment, resourceLoader, this.additionalProfiles, null);
assertThat(configDataEnvironment).extracting("loaders.loaders")
.asInstanceOf(InstanceOfAssertFactories.LIST)
.extracting((item) -> (Class) item.getClass())
.containsOnly(SeparateClassLoaderConfigDataLoader.class);
}
private String getConfigLocation(TestInfo info) {
return "optional:classpath:" + info.getTestClass().get().getName().replace('.', '/') + "-"
+ info.getTestMethod().get().getName() + ".properties";
}
static class TestConfigDataEnvironment extends ConfigDataEnvironment {
private @Nullable Binder configDataLocationResolversBinder;
TestConfigDataEnvironment(DeferredLogFactory logFactory, ConfigurableBootstrapContext bootstrapContext,
ConfigurableEnvironment environment, ResourceLoader resourceLoader,
Collection<String> additionalProfiles,
@Nullable ConfigDataEnvironmentUpdateListener environmentUpdateListener) {
super(logFactory, bootstrapContext, environment, resourceLoader, additionalProfiles,
environmentUpdateListener);
}
@Override
protected ConfigDataLocationResolvers createConfigDataLocationResolvers(DeferredLogFactory logFactory,
ConfigurableBootstrapContext bootstrapContext, Binder binder, ResourceLoader resourceLoader) {
this.configDataLocationResolversBinder = binder;
return super.createConfigDataLocationResolvers(logFactory, bootstrapContext, binder, resourceLoader);
}
@Nullable Binder getConfigDataLocationResolversBinder() {
return this.configDataLocationResolversBinder;
}
}
static class SeparateClassLoaderConfigDataLoader implements ConfigDataLoader<ConfigDataResource> {
@Override
public @Nullable ConfigData load(ConfigDataLoaderContext context, ConfigDataResource resource)
throws IOException, ConfigDataResourceNotFoundException {
return null;
}
}
}
Domain
Source
Analyze Your Own Codebase
Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.
Try Supermodel Free