mirror of
https://github.com/spring-projects/spring-framework.git
synced 2026-09-17 08:24:13 +00:00
Revise "Close contexts when clearing test context cache"
This commit picks up where 97067f9c9c left off by removing the four
trailing collection-clearing calls in clear(), which are now redundant
since the removal loop already empties contextMap, hierarchyMap,
contextUsageMap, and unusedContexts as an invariant. This commit also
adds regression tests in LruContextCacheTests for closing a context
hierarchy via clear() and reset(), asserting bottom-up close order with
Mockito.inOrder(), and confirming that getParentContextCount() and
getContextUsageCount() return to zero.
See gh-36825
This commit is contained in:
-4
@@ -429,10 +429,6 @@ public class DefaultContextCache implements ContextCache {
|
||||
for (MergedContextConfiguration key : new ArrayList<>(this.contextMap.keySet())) {
|
||||
remove(key, HierarchyMode.CURRENT_LEVEL);
|
||||
}
|
||||
this.contextMap.clear();
|
||||
this.hierarchyMap.clear();
|
||||
this.contextUsageMap.clear();
|
||||
this.unusedContexts.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+70
-4
@@ -27,6 +27,7 @@ import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.InOrder;
|
||||
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
@@ -44,6 +45,7 @@ import static org.assertj.core.api.Assertions.as;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
import static org.assertj.core.api.InstanceOfAssertFactories.map;
|
||||
import static org.mockito.Mockito.inOrder;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
@@ -81,17 +83,23 @@ class LruContextCacheTests {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new DefaultContextCache(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // gh-36825
|
||||
void clearClosesContexts() {
|
||||
DefaultContextCache cache = new DefaultContextCache(4);
|
||||
|
||||
cache.put(fooConfig, key -> fooContext);
|
||||
cache.put(barConfig, key -> barContext);
|
||||
cache.put(bazConfig, key -> bazContext);
|
||||
cache.registerContextUsage(fooConfig, getClass());
|
||||
cache.registerContextUsage(barConfig, getClass());
|
||||
cache.registerContextUsage(bazConfig, getClass());
|
||||
assertCacheContents(cache, "Foo", "Bar", "Baz");
|
||||
assertThat(cache.getContextUsageCount()).isEqualTo(3);
|
||||
|
||||
cache.clear();
|
||||
assertCacheContents(cache);
|
||||
assertThat(cache.size()).isZero();
|
||||
assertThat(cache.getParentContextCount()).isZero();
|
||||
assertThat(cache.getContextUsageCount()).isZero();
|
||||
|
||||
verify(fooContext, times(1)).close();
|
||||
verify(barContext, times(1)).close();
|
||||
@@ -99,24 +107,78 @@ class LruContextCacheTests {
|
||||
verify(abcContext, never()).close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // gh-36825
|
||||
void resetClosesContexts() {
|
||||
DefaultContextCache cache = new DefaultContextCache(4);
|
||||
|
||||
cache.put(fooConfig, key -> fooContext);
|
||||
cache.put(barConfig, key -> barContext);
|
||||
cache.get(fooConfig);
|
||||
cache.get(abcConfig);
|
||||
assertThat(cache.getHitCount()).isEqualTo(1);
|
||||
assertThat(cache.getMissCount()).isEqualTo(1);
|
||||
assertCacheContents(cache, "Bar", "Foo");
|
||||
|
||||
cache.reset();
|
||||
assertCacheContents(cache);
|
||||
assertThat(cache.size()).isZero();
|
||||
assertThat(cache.getHitCount()).isZero();
|
||||
assertThat(cache.getMissCount()).isZero();
|
||||
assertThat(cache.getParentContextCount()).isZero();
|
||||
assertThat(cache.getContextUsageCount()).isZero();
|
||||
|
||||
verify(fooContext, times(1)).close();
|
||||
verify(barContext, times(1)).close();
|
||||
}
|
||||
|
||||
@Test // gh-36825
|
||||
void clearClosesContextHierarchyBottomUp() {
|
||||
DefaultContextCache cache = new DefaultContextCache(4);
|
||||
|
||||
// Foo (parent) <- Bar (child) <- Baz (grandchild)
|
||||
MergedContextConfiguration parentConfig = config(Foo.class);
|
||||
MergedContextConfiguration childConfig = config(Bar.class, parentConfig);
|
||||
MergedContextConfiguration grandchildConfig = config(Baz.class, childConfig);
|
||||
|
||||
cache.put(parentConfig, key -> fooContext);
|
||||
cache.put(childConfig, key -> barContext);
|
||||
cache.put(grandchildConfig, key -> bazContext);
|
||||
assertCacheContents(cache, "Foo", "Bar", "Baz");
|
||||
assertThat(cache.getParentContextCount()).isEqualTo(2);
|
||||
|
||||
cache.clear();
|
||||
assertThat(cache.size()).isZero();
|
||||
assertThat(cache.getParentContextCount()).isZero();
|
||||
|
||||
// Child contexts must be closed before their parents.
|
||||
InOrder inOrder = inOrder(bazContext, barContext, fooContext);
|
||||
inOrder.verify(bazContext).close();
|
||||
inOrder.verify(barContext).close();
|
||||
inOrder.verify(fooContext).close();
|
||||
}
|
||||
|
||||
@Test // gh-36825
|
||||
void resetClosesContextHierarchyBottomUp() {
|
||||
DefaultContextCache cache = new DefaultContextCache(4);
|
||||
|
||||
// Foo (parent) <- Bar (child)
|
||||
MergedContextConfiguration parentConfig = config(Foo.class);
|
||||
MergedContextConfiguration childConfig = config(Bar.class, parentConfig);
|
||||
|
||||
cache.put(parentConfig, key -> fooContext);
|
||||
cache.put(childConfig, key -> barContext);
|
||||
assertCacheContents(cache, "Foo", "Bar");
|
||||
assertThat(cache.getParentContextCount()).isEqualTo(1);
|
||||
|
||||
cache.reset();
|
||||
assertThat(cache.size()).isZero();
|
||||
assertThat(cache.getParentContextCount()).isZero();
|
||||
|
||||
// Child contexts must be closed before their parents.
|
||||
InOrder inOrder = inOrder(barContext, fooContext);
|
||||
inOrder.verify(barContext).close();
|
||||
inOrder.verify(fooContext).close();
|
||||
}
|
||||
|
||||
|
||||
@Nested
|
||||
@SuppressWarnings("deprecation")
|
||||
@@ -522,6 +584,10 @@ class LruContextCacheTests {
|
||||
return new MergedContextConfiguration(null, null, new Class<?>[] { clazz }, null, null);
|
||||
}
|
||||
|
||||
private static MergedContextConfiguration config(Class<?> clazz, MergedContextConfiguration parent) {
|
||||
return new MergedContextConfiguration(null, null, new Class<?>[] { clazz }, null, null, null, null, parent);
|
||||
}
|
||||
|
||||
private static void assertCacheContents(DefaultContextCache cache, String... expectedNames) {
|
||||
assertThat(cache).extracting("contextMap", as(map(MergedContextConfiguration.class, ApplicationContext.class)))
|
||||
.satisfies(contextMap -> {
|
||||
|
||||
Reference in New Issue
Block a user