/** * {@inheritDoc} */ @Override public void put(MergedContextConfiguration key, ApplicationContext context) { Assert.notNull(key, "Key must not be null"); Assert.notNull(context, "ApplicationContext must not be null"); this.contextMap.put(key, context); MergedContextConfiguration child = key; MergedContextConfiguration parent = child.getParent(); while (parent != null) { Set<MergedContextConfiguration> list = this.hierarchyMap.computeIfAbsent(parent, k -> new HashSet<>()); list.add(child); child = parent; parent = child.getParent(); } }
/** * Return the {@link ApplicationContextInitializer initializers} that will be applied * to the context. By default this method will adapt {@link ContextCustomizer context * customizers}, add {@link SpringApplication#getInitializers() application * initializers} and add * {@link MergedContextConfiguration#getContextInitializerClasses() initializers * specified on the test}. * @param config the source context configuration * @param application the application instance * @return the initializers to apply * @since 2.0.0 */ protected List<ApplicationContextInitializer<?>> getInitializers( MergedContextConfiguration config, SpringApplication application) { List<ApplicationContextInitializer<?>> initializers = new ArrayList<>(); for (ContextCustomizer contextCustomizer : config.getContextCustomizers()) { initializers.add(new ContextCustomizerAdapter(contextCustomizer, config)); } initializers.addAll(application.getInitializers()); for (Class<? extends ApplicationContextInitializer<?>> initializerClass : config .getContextInitializerClasses()) { initializers.add(BeanUtils.instantiateClass(initializerClass)); } if (config.getParent() != null) { initializers.add(new ParentContextApplicationContextInitializer( config.getParentApplicationContext())); } return initializers; }
@Test public void removeContextHierarchyCacheLevel1() { // Load Level 3-A TestContext testContext3a = TestContextTestUtils.buildTestContext( ClassHierarchyContextHierarchyLevel3aTestCase.class, contextCache); testContext3a.getApplicationContext(); assertContextCacheStatistics(contextCache, "level 3, A", 3, 0, 3); assertParentContextCount(2); // Load Level 3-B TestContext testContext3b = TestContextTestUtils.buildTestContext( ClassHierarchyContextHierarchyLevel3bTestCase.class, contextCache); testContext3b.getApplicationContext(); assertContextCacheStatistics(contextCache, "level 3, A and B", 4, 1, 4); assertParentContextCount(2); // Remove Level 1 // Should also remove Levels 2, 3-A, and 3-B, leaving nothing. contextCache.remove(getMergedContextConfiguration(testContext3a).getParent().getParent(), HierarchyMode.CURRENT_LEVEL); assertContextCacheStatistics(contextCache, "removed level 1", 0, 1, 4); assertParentContextCount(0); }
@Test public void removeContextHierarchyCacheLevel1WithExhaustiveMode() { // Load Level 3-A TestContext testContext3a = TestContextTestUtils.buildTestContext( ClassHierarchyContextHierarchyLevel3aTestCase.class, contextCache); testContext3a.getApplicationContext(); assertContextCacheStatistics(contextCache, "level 3, A", 3, 0, 3); assertParentContextCount(2); // Load Level 3-B TestContext testContext3b = TestContextTestUtils.buildTestContext( ClassHierarchyContextHierarchyLevel3bTestCase.class, contextCache); testContext3b.getApplicationContext(); assertContextCacheStatistics(contextCache, "level 3, A and B", 4, 1, 4); assertParentContextCount(2); // Remove Level 1 // Should also remove Levels 2, 3-A, and 3-B, leaving nothing. contextCache.remove(getMergedContextConfiguration(testContext3a).getParent().getParent(), HierarchyMode.EXHAUSTIVE); assertContextCacheStatistics(contextCache, "removed level 1", 0, 1, 4); assertParentContextCount(0); }
@Test public void removeContextHierarchyCacheLevel2WithExhaustiveMode() { // Load Level 3-A TestContext testContext3a = TestContextTestUtils.buildTestContext( ClassHierarchyContextHierarchyLevel3aTestCase.class, contextCache); testContext3a.getApplicationContext(); assertContextCacheStatistics(contextCache, "level 3, A", 3, 0, 3); assertParentContextCount(2); // Load Level 3-B TestContext testContext3b = TestContextTestUtils.buildTestContext( ClassHierarchyContextHierarchyLevel3bTestCase.class, contextCache); testContext3b.getApplicationContext(); assertContextCacheStatistics(contextCache, "level 3, A and B", 4, 1, 4); assertParentContextCount(2); // Remove Level 2 // Should wipe the cache contextCache.remove(getMergedContextConfiguration(testContext3a).getParent(), HierarchyMode.EXHAUSTIVE); assertContextCacheStatistics(contextCache, "removed level 2", 0, 1, 4); assertParentContextCount(0); }
@Test public void removeContextHierarchyCacheLevel2() { // Load Level 3-A TestContext testContext3a = TestContextTestUtils.buildTestContext( ClassHierarchyContextHierarchyLevel3aTestCase.class, contextCache); testContext3a.getApplicationContext(); assertContextCacheStatistics(contextCache, "level 3, A", 3, 0, 3); assertParentContextCount(2); // Load Level 3-B TestContext testContext3b = TestContextTestUtils.buildTestContext( ClassHierarchyContextHierarchyLevel3bTestCase.class, contextCache); testContext3b.getApplicationContext(); assertContextCacheStatistics(contextCache, "level 3, A and B", 4, 1, 4); assertParentContextCount(2); // Remove Level 2 // Should also remove Levels 3-A and 3-B, leaving only Level 1 as a context in the // cache but also removing the Level 1 hierarchy since all children have been // removed. contextCache.remove(getMergedContextConfiguration(testContext3a).getParent(), HierarchyMode.CURRENT_LEVEL); assertContextCacheStatistics(contextCache, "removed level 2", 1, 1, 4); assertParentContextCount(0); }
@Test public void removeContextHierarchyCacheLevel3Then2WithExhaustiveMode() { // Load Level 3-A TestContext testContext3a = TestContextTestUtils.buildTestContext( ClassHierarchyContextHierarchyLevel3aTestCase.class, contextCache); testContext3a.getApplicationContext(); assertContextCacheStatistics(contextCache, "level 3, A", 3, 0, 3); assertParentContextCount(2); // Load Level 3-B TestContext testContext3b = TestContextTestUtils.buildTestContext( ClassHierarchyContextHierarchyLevel3bTestCase.class, contextCache); testContext3b.getApplicationContext(); assertContextCacheStatistics(contextCache, "level 3, A and B", 4, 1, 4); assertParentContextCount(2); // Remove Level 3-A // Should wipe the cache. contextCache.remove(getMergedContextConfiguration(testContext3a), HierarchyMode.EXHAUSTIVE); assertContextCacheStatistics(contextCache, "removed level 3-A", 0, 1, 4); assertParentContextCount(0); // Remove Level 2 // Should not actually do anything since the cache was cleared in the // previous step. So the stats should remain the same. contextCache.remove(getMergedContextConfiguration(testContext3b).getParent(), HierarchyMode.EXHAUSTIVE); assertContextCacheStatistics(contextCache, "removed level 2", 0, 1, 4); assertParentContextCount(0); }
@Test public void removeContextHierarchyCacheLevel3Then2() { // Load Level 3-A TestContext testContext3a = TestContextTestUtils.buildTestContext( ClassHierarchyContextHierarchyLevel3aTestCase.class, contextCache); testContext3a.getApplicationContext(); assertContextCacheStatistics(contextCache, "level 3, A", 3, 0, 3); assertParentContextCount(2); // Load Level 3-B TestContext testContext3b = TestContextTestUtils.buildTestContext( ClassHierarchyContextHierarchyLevel3bTestCase.class, contextCache); testContext3b.getApplicationContext(); assertContextCacheStatistics(contextCache, "level 3, A and B", 4, 1, 4); assertParentContextCount(2); // Remove Level 3-A contextCache.remove(getMergedContextConfiguration(testContext3a), HierarchyMode.CURRENT_LEVEL); assertContextCacheStatistics(contextCache, "removed level 3-A", 3, 1, 4); assertParentContextCount(2); // Remove Level 2 // Should also remove Level 3-B, leaving only Level 1. contextCache.remove(getMergedContextConfiguration(testContext3b).getParent(), HierarchyMode.CURRENT_LEVEL); assertContextCacheStatistics(contextCache, "removed level 2", 1, 1, 4); assertParentContextCount(0); }
/** * {@inheritDoc} */ @Override public void put(MergedContextConfiguration key, ApplicationContext context) { Assert.notNull(key, "Key must not be null"); Assert.notNull(context, "ApplicationContext must not be null"); this.contextMap.put(key, context); MergedContextConfiguration child = key; MergedContextConfiguration parent = child.getParent(); while (parent != null) { Set<MergedContextConfiguration> list = this.hierarchyMap.computeIfAbsent(parent, k -> new HashSet<>()); list.add(child); child = parent; parent = child.getParent(); } }
/** * {@inheritDoc} */ @Override public void put(MergedContextConfiguration key, ApplicationContext context) { Assert.notNull(key, "Key must not be null"); Assert.notNull(context, "ApplicationContext must not be null"); this.contextMap.put(key, context); MergedContextConfiguration child = key; MergedContextConfiguration parent = child.getParent(); while (parent != null) { Set<MergedContextConfiguration> list = this.hierarchyMap.get(parent); if (list == null) { list = new HashSet<MergedContextConfiguration>(); this.hierarchyMap.put(parent, list); } list.add(child); child = parent; parent = child.getParent(); } }
/** * {@inheritDoc} */ @Override public void remove(MergedContextConfiguration key, HierarchyMode hierarchyMode) { Assert.notNull(key, "Key must not be null"); // startKey is the level at which to begin clearing the cache, depending // on the configured hierarchy mode. MergedContextConfiguration startKey = key; if (hierarchyMode == HierarchyMode.EXHAUSTIVE) { while (startKey.getParent() != null) { startKey = startKey.getParent(); } } List<MergedContextConfiguration> removedContexts = new ArrayList<MergedContextConfiguration>(); remove(removedContexts, startKey); // Remove all remaining references to any removed contexts from the // hierarchy map. for (MergedContextConfiguration currentKey : removedContexts) { for (Set<MergedContextConfiguration> children : this.hierarchyMap.values()) { children.remove(currentKey); } } // Remove empty entries from the hierarchy map. for (MergedContextConfiguration currentKey : this.hierarchyMap.keySet()) { if (this.hierarchyMap.get(currentKey).isEmpty()) { this.hierarchyMap.remove(currentKey); } } }
public ApplicationContext getParentApplicationContext() { MergedContextConfiguration parent = mergedContextConfiguration .getParent(); Assert.state( this.contextLoaderDelegate != null, "Cannot retrieve a parent application context without access to the CacheAwareContextLoaderDelegate"); if (parent == null) { return this.contextLoaderDelegate.loadContext(parentConfiguration); } ApplicationContext applicationContext = this.contextLoaderDelegate .loadContext(parent); if (applicationContext == null) { applicationContext = this.contextLoaderDelegate .loadContext(parentConfiguration); } return applicationContext; }
/** * Create a new {@link MergedContextConfiguration} with different classes and * properties. * @param mergedConfig the source config * @param classes the replacement classes * @param propertySourceProperties the replacement properties * @return a new {@link MergedContextConfiguration} */ protected final MergedContextConfiguration createModifiedConfig( MergedContextConfiguration mergedConfig, Class<?>[] classes, String[] propertySourceProperties) { return new MergedContextConfiguration(mergedConfig.getTestClass(), mergedConfig.getLocations(), classes, mergedConfig.getContextInitializerClasses(), mergedConfig.getActiveProfiles(), mergedConfig.getPropertySourceLocations(), propertySourceProperties, mergedConfig.getContextCustomizers(), mergedConfig.getContextLoader(), getCacheAwareContextLoaderDelegate(), mergedConfig.getParent()); }