Browse Source
Prior to this commit, as a result of commit 6cdb34410b, the
DynamicValuesPropertySource was eagerly registered in the Environment
even if the DynamicPropertyRegistry was never used to register dynamic
properties.
This commit ensures that the DynamicValuesPropertySource is only
registered if we know that the DynamicPropertyRegistry is actually used
-- either by a @DynamicPropertySource method in a test class or via a
bean in the ApplicationContext that invokes add() on the
DynamicPropertyRegistry bean.
See gh-32271
Closes gh-32871
pull/32874/head
5 changed files with 218 additions and 46 deletions
@ -0,0 +1,79 @@
@@ -0,0 +1,79 @@
|
||||
/* |
||||
* Copyright 2002-2024 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.test.context.support; |
||||
|
||||
import java.util.Collections; |
||||
import java.util.LinkedHashMap; |
||||
import java.util.Map; |
||||
import java.util.concurrent.locks.Lock; |
||||
import java.util.concurrent.locks.ReentrantLock; |
||||
import java.util.function.Supplier; |
||||
|
||||
import org.springframework.core.env.ConfigurableEnvironment; |
||||
import org.springframework.core.env.MutablePropertySources; |
||||
import org.springframework.core.env.PropertySource; |
||||
import org.springframework.test.context.DynamicPropertyRegistry; |
||||
import org.springframework.util.Assert; |
||||
|
||||
/** |
||||
* Default {@link DynamicPropertyRegistry} implementation. |
||||
* |
||||
* @author Sam Brannen |
||||
* @since 6.2 |
||||
*/ |
||||
final class DefaultDynamicPropertyRegistry implements DynamicPropertyRegistry { |
||||
|
||||
final Map<String, Supplier<Object>> valueSuppliers = Collections.synchronizedMap(new LinkedHashMap<>()); |
||||
|
||||
private final ConfigurableEnvironment environment; |
||||
|
||||
private final boolean lazilyRegisterPropertySource; |
||||
|
||||
private final Lock propertySourcesLock = new ReentrantLock(); |
||||
|
||||
|
||||
DefaultDynamicPropertyRegistry(ConfigurableEnvironment environment, boolean lazilyRegisterPropertySource) { |
||||
this.environment = environment; |
||||
this.lazilyRegisterPropertySource = lazilyRegisterPropertySource; |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public void add(String name, Supplier<Object> valueSupplier) { |
||||
Assert.hasText(name, "'name' must not be null or blank"); |
||||
Assert.notNull(valueSupplier, "'valueSupplier' must not be null"); |
||||
if (this.lazilyRegisterPropertySource) { |
||||
ensurePropertySourceIsRegistered(); |
||||
} |
||||
this.valueSuppliers.put(name, valueSupplier); |
||||
} |
||||
|
||||
private void ensurePropertySourceIsRegistered() { |
||||
MutablePropertySources propertySources = this.environment.getPropertySources(); |
||||
this.propertySourcesLock.lock(); |
||||
try { |
||||
PropertySource<?> ps = propertySources.get(DynamicValuesPropertySource.PROPERTY_SOURCE_NAME); |
||||
if (ps == null) { |
||||
propertySources.addFirst(new DynamicValuesPropertySource(this.valueSuppliers)); |
||||
} |
||||
} |
||||
finally { |
||||
this.propertySourcesLock.unlock(); |
||||
} |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,55 @@
@@ -0,0 +1,55 @@
|
||||
/* |
||||
* Copyright 2002-2024 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.test.context; |
||||
|
||||
import org.junit.platform.suite.api.SelectClasses; |
||||
import org.junit.platform.suite.api.Suite; |
||||
|
||||
/** |
||||
* JUnit Platform based test suite for tests that involve the Spring TestContext |
||||
* Framework and dynamic properties. |
||||
* |
||||
* <p><strong>This suite is only intended to be used manually within an IDE.</strong> |
||||
* |
||||
* <h3>Logging Configuration</h3> |
||||
* |
||||
* <p>In order for our log4j2 configuration to be used in an IDE, you must |
||||
* set the following system property before running any tests — for |
||||
* example, in <em>Run Configurations</em> in Eclipse. |
||||
* |
||||
* <pre style="code"> |
||||
* -Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager |
||||
* </pre> |
||||
* |
||||
* @author Sam Brannen |
||||
* @since 6.2 |
||||
*/ |
||||
@Suite |
||||
@SelectClasses( |
||||
value = { |
||||
DynamicPropertyRegistryIntegrationTests.class, |
||||
DynamicPropertySourceIntegrationTests.class |
||||
}, |
||||
names = { |
||||
"org.springframework.test.context.junit.jupiter.nested.DynamicPropertySourceNestedTests", |
||||
"org.springframework.test.context.support.DefaultTestPropertySourcesIntegrationTests", |
||||
"org.springframework.test.context.support.DynamicPropertiesContextCustomizerFactoryTests", |
||||
"org.springframework.test.context.support.DynamicValuesPropertySourceTests" |
||||
} |
||||
) |
||||
class DynamicPropertiesTestSuite { |
||||
} |
||||
@ -0,0 +1,63 @@
@@ -0,0 +1,63 @@
|
||||
/* |
||||
* Copyright 2002-2024 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.test.context.support; |
||||
|
||||
import org.junit.jupiter.api.Test; |
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import org.springframework.core.env.ConfigurableEnvironment; |
||||
import org.springframework.core.env.MutablePropertySources; |
||||
import org.springframework.test.annotation.DirtiesContext; |
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
|
||||
/** |
||||
* Integration tests which ensure that test-related property sources are not |
||||
* registered by default. |
||||
* |
||||
* @author Sam Brannen |
||||
* @since 6.2 |
||||
*/ |
||||
@SpringJUnitConfig |
||||
@DirtiesContext |
||||
class DefaultTestPropertySourcesIntegrationTests { |
||||
|
||||
@Autowired |
||||
ConfigurableEnvironment env; |
||||
|
||||
|
||||
@Test |
||||
void ensureTestRelatedPropertySourcesAreNotRegisteredByDefault() { |
||||
assertPropertySourceIsNotRegistered(TestPropertySourceUtils.INLINED_PROPERTIES_PROPERTY_SOURCE_NAME); |
||||
assertPropertySourceIsNotRegistered(DynamicValuesPropertySource.PROPERTY_SOURCE_NAME); |
||||
} |
||||
|
||||
private void assertPropertySourceIsNotRegistered(String name) { |
||||
MutablePropertySources propertySources = this.env.getPropertySources(); |
||||
assertThat(propertySources.contains(name)) |
||||
.as("PropertySource \"%s\" should not be registered by default", name) |
||||
.isFalse(); |
||||
} |
||||
|
||||
|
||||
@Configuration |
||||
static class Config { |
||||
} |
||||
|
||||
} |
||||
Loading…
Reference in new issue