diff --git a/spring-context-support/src/test/java/org/springframework/scheduling/quartz/QuartzSupportTests.java b/spring-context-support/src/test/java/org/springframework/scheduling/quartz/QuartzSupportTests.java index 87adeaed3e5..7ab4a8bd948 100644 --- a/spring-context-support/src/test/java/org/springframework/scheduling/quartz/QuartzSupportTests.java +++ b/spring-context-support/src/test/java/org/springframework/scheduling/quartz/QuartzSupportTests.java @@ -391,7 +391,6 @@ class QuartzSupportTests { try (ClassPathXmlApplicationContext ctx = context("databasePersistence.xml")) { JdbcTemplate jdbcTemplate = new JdbcTemplate(ctx.getBean(DataSource.class)); assertThat(jdbcTemplate.queryForList("SELECT * FROM qrtz_triggers").isEmpty()).as("No triggers were persisted").isFalse(); - ctx.stop(); ctx.restart(); } } diff --git a/spring-context/src/main/java/org/springframework/context/ConfigurableApplicationContext.java b/spring-context/src/main/java/org/springframework/context/ConfigurableApplicationContext.java index 6f56d8a6e51..8dffb08bd69 100644 --- a/spring-context/src/main/java/org/springframework/context/ConfigurableApplicationContext.java +++ b/spring-context/src/main/java/org/springframework/context/ConfigurableApplicationContext.java @@ -221,16 +221,27 @@ public interface ConfigurableApplicationContext extends ApplicationContext, Life void refresh() throws BeansException, IllegalStateException; /** - * Stop all beans in this application context if necessary, and subsequently + * Pause all beans in this application context if necessary, and subsequently * restart all auto-startup beans, effectively restoring the lifecycle state * after {@link #refresh()} (typically after a preceding {@link #stop()} call * when a full {@link #start()} of even lazy-starting beans is to be avoided). * @since 7.0 - * @see #stop() + * @see #pause() + * @see #start() * @see SmartLifecycle#isAutoStartup() */ void restart(); + /** + * Stop all beans in this application context unless they explicitly opt out of + * pausing through {@link SmartLifecycle#isPauseable()} returning {@code false}. + * @since 7.0 + * @see #restart() + * @see #stop() + * @see SmartLifecycle#isPauseable() + */ + void pause(); + /** * Register a shutdown hook with the JVM runtime, closing this context * on JVM shutdown unless it has already been closed at that time. diff --git a/spring-context/src/main/java/org/springframework/context/LifecycleProcessor.java b/spring-context/src/main/java/org/springframework/context/LifecycleProcessor.java index d9d4ea446fb..c2e39a84d3d 100644 --- a/spring-context/src/main/java/org/springframework/context/LifecycleProcessor.java +++ b/spring-context/src/main/java/org/springframework/context/LifecycleProcessor.java @@ -44,6 +44,15 @@ public interface LifecycleProcessor extends Lifecycle { start(); } + /** + * Notification of context pause for auto-stopping components. + * @since 7.0 + * @see ConfigurableApplicationContext#pause() + */ + default void onPause() { + stop(); + } + /** * Notification of context close phase for auto-stopping components * before destruction. diff --git a/spring-context/src/main/java/org/springframework/context/SmartLifecycle.java b/spring-context/src/main/java/org/springframework/context/SmartLifecycle.java index ac2039cae68..cf4c43bd264 100644 --- a/spring-context/src/main/java/org/springframework/context/SmartLifecycle.java +++ b/spring-context/src/main/java/org/springframework/context/SmartLifecycle.java @@ -85,7 +85,7 @@ public interface SmartLifecycle extends Lifecycle, Phased { /** * Returns {@code true} if this {@code Lifecycle} component should get * started automatically by the container at the time that the containing - * {@link ApplicationContext} gets refreshed. + * {@link ApplicationContext} gets refreshed or restarted. *

A value of {@code false} indicates that the component is intended to * be started through an explicit {@link #start()} call instead, analogous * to a plain {@link Lifecycle} implementation. @@ -93,12 +93,35 @@ public interface SmartLifecycle extends Lifecycle, Phased { * @see #start() * @see #getPhase() * @see LifecycleProcessor#onRefresh() + * @see LifecycleProcessor#onRestart() * @see ConfigurableApplicationContext#refresh() + * @see ConfigurableApplicationContext#restart() */ default boolean isAutoStartup() { return true; } + /** + * Returns {@code true} if this {@code Lifecycle} component is able to + * participate in a restart sequence, receiving corresponding {@link #stop()} + * and {@link #start()} calls with a potential pause in-between. + *

A value of {@code false} indicates that the component prefers to + * be skipped in a pause scenario, neither receiving a {@link #stop()} + * call nor a subsequent {@link #start()} call, analogous to a plain + * {@link Lifecycle} implementation. It will only receive a {@link #stop()} + * call on close and on explicit context-wide stopping but not on pause. + *

The default implementation returns {@code true}. + * @since 7.0 + * @see #stop() + * @see LifecycleProcessor#onPause() + * @see LifecycleProcessor#onClose() + * @see ConfigurableApplicationContext#pause() + * @see ConfigurableApplicationContext#close() + */ + default boolean isPauseable() { + return true; + } + /** * Indicates that a Lifecycle component must stop if it is currently running. *

The provided callback is used by the {@link LifecycleProcessor} to support diff --git a/spring-context/src/main/java/org/springframework/context/event/ContextPausedEvent.java b/spring-context/src/main/java/org/springframework/context/event/ContextPausedEvent.java new file mode 100644 index 00000000000..759783bc0b2 --- /dev/null +++ b/spring-context/src/main/java/org/springframework/context/event/ContextPausedEvent.java @@ -0,0 +1,46 @@ +/* + * Copyright 2002-present 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.context.event; + +import org.springframework.context.ApplicationContext; +import org.springframework.context.ConfigurableApplicationContext; + +/** + * Event raised when an {@code ApplicationContext} gets paused. + * + *

Note that {@code ContextPausedEvent} is a specialization of + * {@link ContextStoppedEvent}. + * + * @author Juergen Hoeller + * @since 7.0 + * @see ConfigurableApplicationContext#pause() + * @see ContextRestartedEvent + * @see ContextStoppedEvent + */ +@SuppressWarnings("serial") +public class ContextPausedEvent extends ContextStoppedEvent { + + /** + * Create a new {@code ContextRestartedEvent}. + * @param source the {@code ContextPausedEvent} that has been restarted + * (must not be {@code null}) + */ + public ContextPausedEvent(ApplicationContext source) { + super(source); + } + +} diff --git a/spring-context/src/main/java/org/springframework/context/event/ContextRestartedEvent.java b/spring-context/src/main/java/org/springframework/context/event/ContextRestartedEvent.java index e8165be8d08..8ac44108917 100644 --- a/spring-context/src/main/java/org/springframework/context/event/ContextRestartedEvent.java +++ b/spring-context/src/main/java/org/springframework/context/event/ContextRestartedEvent.java @@ -17,6 +17,7 @@ package org.springframework.context.event; import org.springframework.context.ApplicationContext; +import org.springframework.context.ConfigurableApplicationContext; /** * Event raised when an {@code ApplicationContext} gets restarted. @@ -26,8 +27,9 @@ import org.springframework.context.ApplicationContext; * * @author Sam Brannen * @since 7.0 + * @see ConfigurableApplicationContext#restart() + * @see ContextPausedEvent * @see ContextStartedEvent - * @see ContextStoppedEvent */ @SuppressWarnings("serial") public class ContextRestartedEvent extends ContextStartedEvent { diff --git a/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java b/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java index cc846e3e5f3..d741a1f25c2 100644 --- a/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java +++ b/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java @@ -66,6 +66,7 @@ import org.springframework.context.PayloadApplicationEvent; import org.springframework.context.ResourceLoaderAware; import org.springframework.context.event.ApplicationEventMulticaster; import org.springframework.context.event.ContextClosedEvent; +import org.springframework.context.event.ContextPausedEvent; import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.context.event.ContextRestartedEvent; import org.springframework.context.event.ContextStartedEvent; @@ -1555,6 +1556,12 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader publishEvent(new ContextRestartedEvent(this)); } + @Override + public void pause() { + getLifecycleProcessor().onPause(); + publishEvent(new ContextPausedEvent(this)); + } + @Override public boolean isRunning() { return (this.lifecycleProcessor != null && this.lifecycleProcessor.isRunning()); diff --git a/spring-context/src/main/java/org/springframework/context/support/DefaultLifecycleProcessor.java b/spring-context/src/main/java/org/springframework/context/support/DefaultLifecycleProcessor.java index f5760107f59..02bf8c08ab5 100644 --- a/spring-context/src/main/java/org/springframework/context/support/DefaultLifecycleProcessor.java +++ b/spring-context/src/main/java/org/springframework/context/support/DefaultLifecycleProcessor.java @@ -287,7 +287,7 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor */ @Override public void stop() { - stopBeans(); + stopBeans(false); this.running = false; } @@ -308,7 +308,7 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor catch (ApplicationContextException ex) { // Some bean failed to auto-start within context refresh: // stop already started beans on context refresh failure. - stopBeans(); + stopBeans(false); throw ex; } this.running = true; @@ -318,15 +318,23 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor public void onRestart() { this.stoppedBeans = null; if (this.running) { - stopBeans(); + stopBeans(true); } startBeans(true); this.running = true; } + @Override + public void onPause() { + if (this.running) { + stopBeans(true); + this.running = false; + } + } + @Override public void onClose() { - stopBeans(); + stopBeans(false); this.running = false; } @@ -341,7 +349,7 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor void stopForRestart() { if (this.running) { this.stoppedBeans = ConcurrentHashMap.newKeySet(); - stopBeans(); + stopBeans(false); this.running = false; } } @@ -361,7 +369,8 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor lifecycleBeans.forEach((beanName, bean) -> { if (!autoStartupOnly || isAutoStartupCandidate(beanName, bean)) { int startupPhase = getPhase(bean); - phases.computeIfAbsent(startupPhase, phase -> new LifecycleGroup(phase, lifecycleBeans, autoStartupOnly)) + phases.computeIfAbsent( + startupPhase, phase -> new LifecycleGroup(phase, lifecycleBeans, autoStartupOnly, false)) .add(beanName, bean); } }); @@ -424,13 +433,14 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor (!(bean instanceof SmartLifecycle smartLifecycle) || smartLifecycle.isAutoStartup())); } - private void stopBeans() { + private void stopBeans(boolean pauseableOnly) { Map lifecycleBeans = getLifecycleBeans(); Map phases = new TreeMap<>(Comparator.reverseOrder()); lifecycleBeans.forEach((beanName, bean) -> { int shutdownPhase = getPhase(bean); - phases.computeIfAbsent(shutdownPhase, phase -> new LifecycleGroup(phase, lifecycleBeans, false)) + phases.computeIfAbsent( + shutdownPhase, phase -> new LifecycleGroup(phase, lifecycleBeans, false, pauseableOnly)) .add(beanName, bean); }); @@ -446,13 +456,13 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor * @param beanName the name of the bean to stop */ private void doStop(Map lifecycleBeans, final String beanName, - final CountDownLatch latch, final Set countDownBeanNames) { + boolean pauseableOnly, final CountDownLatch latch, final Set countDownBeanNames) { Lifecycle bean = lifecycleBeans.remove(beanName); if (bean != null) { String[] dependentBeans = getBeanFactory().getDependentBeans(beanName); for (String dependentBean : dependentBeans) { - doStop(lifecycleBeans, dependentBean, latch, countDownBeanNames); + doStop(lifecycleBeans, dependentBean, pauseableOnly, latch, countDownBeanNames); } try { if (bean.isRunning()) { @@ -461,20 +471,22 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor stoppedBeans.add(beanName); } if (bean instanceof SmartLifecycle smartLifecycle) { - if (logger.isTraceEnabled()) { - logger.trace("Asking bean '" + beanName + "' of type [" + - bean.getClass().getName() + "] to stop"); - } - countDownBeanNames.add(beanName); - smartLifecycle.stop(() -> { - latch.countDown(); - countDownBeanNames.remove(beanName); - if (logger.isDebugEnabled()) { - logger.debug("Bean '" + beanName + "' completed its stop procedure"); + if (!pauseableOnly || smartLifecycle.isPauseable()) { + if (logger.isTraceEnabled()) { + logger.trace("Asking bean '" + beanName + "' of type [" + + bean.getClass().getName() + "] to stop"); } - }); + countDownBeanNames.add(beanName); + smartLifecycle.stop(() -> { + latch.countDown(); + countDownBeanNames.remove(beanName); + if (logger.isDebugEnabled()) { + logger.debug("Bean '" + beanName + "' completed its stop procedure"); + } + }); + } } - else { + else if (!pauseableOnly) { if (logger.isTraceEnabled()) { logger.trace("Stopping bean '" + beanName + "' of type [" + bean.getClass().getName() + "]"); @@ -562,14 +574,19 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor private final boolean autoStartupOnly; + private final boolean pauseableOnly; + private final List members = new ArrayList<>(); private int smartMemberCount; - public LifecycleGroup(int phase, Map lifecycleBeans, boolean autoStartupOnly) { + public LifecycleGroup(int phase, Map lifecycleBeans, + boolean autoStartupOnly, boolean pauseableOnly) { + this.phase = phase; this.lifecycleBeans = lifecycleBeans; this.autoStartupOnly = autoStartupOnly; + this.pauseableOnly = pauseableOnly; } public void add(String name, Lifecycle bean) { @@ -621,7 +638,7 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor Set lifecycleBeanNames = new HashSet<>(this.lifecycleBeans.keySet()); for (LifecycleGroupMember member : this.members) { if (lifecycleBeanNames.contains(member.name)) { - doStop(this.lifecycleBeans, member.name, latch, countDownBeanNames); + doStop(this.lifecycleBeans, member.name, this.pauseableOnly, latch, countDownBeanNames); } else if (member.bean instanceof SmartLifecycle) { // Already removed: must have been a dependent bean from another phase diff --git a/spring-context/src/test/java/org/springframework/context/support/DefaultLifecycleProcessorTests.java b/spring-context/src/test/java/org/springframework/context/support/DefaultLifecycleProcessorTests.java index cb968cf9c12..7904d88138b 100644 --- a/spring-context/src/test/java/org/springframework/context/support/DefaultLifecycleProcessorTests.java +++ b/spring-context/src/test/java/org/springframework/context/support/DefaultLifecycleProcessorTests.java @@ -355,6 +355,7 @@ class DefaultLifecycleProcessorTests { TestSmartLifecycleBean smartBean1 = TestSmartLifecycleBean.forShutdownTests(5, 0, stoppedBeans); TestSmartLifecycleBean smartBean2 = TestSmartLifecycleBean.forShutdownTests(-3, 0, stoppedBeans); smartBean2.setAutoStartup(false); + smartBean2.setPauseable(false); context.getBeanFactory().registerSingleton("smartBean1", smartBean1); context.getBeanFactory().registerSingleton("smartBean2", smartBean2); @@ -375,11 +376,23 @@ class DefaultLifecycleProcessorTests { assertThat(stoppedBeans).containsExactly(smartBean1, smartBean1); assertThat(smartBean1.isRunning()).isTrue(); assertThat(smartBean2.isRunning()).isFalse(); + context.pause(); + assertThat(stoppedBeans).containsExactly(smartBean1, smartBean1, smartBean1); + assertThat(smartBean1.isRunning()).isFalse(); + assertThat(smartBean2.isRunning()).isFalse(); + context.restart(); + assertThat(stoppedBeans).containsExactly(smartBean1, smartBean1, smartBean1); + assertThat(smartBean1.isRunning()).isTrue(); + assertThat(smartBean2.isRunning()).isFalse(); context.start(); assertThat(smartBean1.isRunning()).isTrue(); assertThat(smartBean2.isRunning()).isTrue(); + context.pause(); + assertThat(stoppedBeans).containsExactly(smartBean1, smartBean1, smartBean1, smartBean1); + assertThat(smartBean1.isRunning()).isFalse(); + assertThat(smartBean2.isRunning()).isTrue(); context.close(); - assertThat(stoppedBeans).containsExactly(smartBean1, smartBean1, smartBean1, smartBean2); + assertThat(stoppedBeans).containsExactly(smartBean1, smartBean1, smartBean1, smartBean1, smartBean2); } @Test @@ -740,6 +753,8 @@ class DefaultLifecycleProcessorTests { private volatile boolean autoStartup = true; + private volatile boolean pauseable = true; + static TestSmartLifecycleBean forStartupTests(int phase, CopyOnWriteArrayList startedBeans) { return new TestSmartLifecycleBean(phase, 0, startedBeans, null); } @@ -769,6 +784,15 @@ class DefaultLifecycleProcessorTests { this.autoStartup = autoStartup; } + @Override + public boolean isPauseable() { + return this.pauseable; + } + + public void setPauseable(boolean pauseable) { + this.pauseable = pauseable; + } + @Override public void stop(final Runnable callback) { // calling stop() before the delay to preserve diff --git a/spring-test/src/main/java/org/springframework/test/context/cache/ContextCache.java b/spring-test/src/main/java/org/springframework/test/context/cache/ContextCache.java index 8840a4655a6..2a319d78b75 100644 --- a/spring-test/src/main/java/org/springframework/test/context/cache/ContextCache.java +++ b/spring-test/src/main/java/org/springframework/test/context/cache/ContextCache.java @@ -93,8 +93,8 @@ public interface ContextCache { /** * Obtain a cached {@link ApplicationContext} for the given key. *

If the cached application context was previously - * {@linkplain org.springframework.context.Lifecycle#stop() stopped}, it - * must be + * {@linkplain org.springframework.context.ConfigurableApplicationContext#pause() paused}, + * it must be * {@linkplain org.springframework.context.support.AbstractApplicationContext#restart() * restarted}. This applies to parent contexts as well. *

In addition, the {@linkplain #getHitCount() hit} and @@ -187,7 +187,7 @@ public interface ContextCache { * {@link MergedContextConfiguration} and any of its parents. *

If no other test classes are actively using the same application * context(s), the application context(s) should be - * {@linkplain org.springframework.context.Lifecycle#stop() stopped}. + * {@linkplain org.springframework.context.ConfigurableApplicationContext#pause() paused}. *

The default implementation of this method does nothing. Concrete * implementations are therefore highly encouraged to override this * method, {@link #registerContextUsage(MergedContextConfiguration, Class)}, diff --git a/spring-test/src/main/java/org/springframework/test/context/cache/DefaultContextCache.java b/spring-test/src/main/java/org/springframework/test/context/cache/DefaultContextCache.java index ad52643bd59..5451fb5854a 100644 --- a/spring-test/src/main/java/org/springframework/test/context/cache/DefaultContextCache.java +++ b/spring-test/src/main/java/org/springframework/test/context/cache/DefaultContextCache.java @@ -187,7 +187,7 @@ public class DefaultContextCache implements ContextCache { activeTestClasses.remove(testClass); if (activeTestClasses.isEmpty()) { if (context instanceof ConfigurableApplicationContext cac && cac.isRunning()) { - cac.stop(); + cac.pause(); } this.contextUsageMap.remove(mergedConfig); } diff --git a/spring-test/src/test/java/org/springframework/test/context/cache/UnusedContextsIntegrationTests.java b/spring-test/src/test/java/org/springframework/test/context/cache/UnusedContextsIntegrationTests.java index 9e861a1aee0..49dac4c34a1 100644 --- a/spring-test/src/test/java/org/springframework/test/context/cache/UnusedContextsIntegrationTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/cache/UnusedContextsIntegrationTests.java @@ -69,13 +69,13 @@ class UnusedContextsIntegrationTests { // No BeforeTestClass, since EventPublishingTestExecutionListener // only publishes events for a context that has already been loaded. "AfterTestClass:TestCase1", - "ContextStopped:TestCase1", + "ContextPaused:TestCase1", // --- TestCase2 ----------------------------------------------- "ContextRestarted:TestCase1", "BeforeTestClass:TestCase2", "AfterTestClass:TestCase2", - "ContextStopped:TestCase1", + "ContextPaused:TestCase1", // --- TestCase3 ----------------------------------------------- "ContextRestarted:TestCase1", @@ -90,13 +90,13 @@ class UnusedContextsIntegrationTests { // No BeforeTestClass, since EventPublishingTestExecutionListener // only publishes events for a context that has already been loaded. "AfterTestClass:TestCase4", - "ContextStopped:TestCase4", + "ContextPaused:TestCase4", // --- TestCase5 ----------------------------------------------- "ContextRestarted:TestCase4", "BeforeTestClass:TestCase5", "AfterTestClass:TestCase5", - "ContextStopped:TestCase4" + "ContextPaused:TestCase4" ); } @@ -130,19 +130,19 @@ class UnusedContextsIntegrationTests { // using the context "AfterTestClass:OverridingNestedTestCase1", - "ContextStopped:OverridingNestedTestCase1", + "ContextPaused:OverridingNestedTestCase1", // --- OverridingNestedTestCase2 --------------------------- "ContextRestarted:OverridingNestedTestCase1", "BeforeTestClass:OverridingNestedTestCase2", "AfterTestClass:OverridingNestedTestCase2", - "ContextStopped:OverridingNestedTestCase1", + "ContextPaused:OverridingNestedTestCase1", "AfterTestClass:NestedTestCase", // No Stopped event, since EnclosingTestCase is still using the context "AfterTestClass:EnclosingTestCase", - "ContextStopped:EnclosingTestCase" + "ContextPaused:EnclosingTestCase" ); } @@ -161,23 +161,23 @@ class UnusedContextsIntegrationTests { // --- ContextHierarchyLevel1TestCase ------------------------------ "ContextRefreshed:ContextHierarchyLevel1TestCase", "AfterTestClass:ContextHierarchyLevel1TestCase", - "ContextStopped:ContextHierarchyLevel1TestCase", + "ContextPaused:ContextHierarchyLevel1TestCase", // --- ContextHierarchyLevel2TestCase ------------------------------ "ContextRestarted:ContextHierarchyLevel1TestCase", "ContextRefreshed:ContextHierarchyLevel2TestCase", "AfterTestClass:ContextHierarchyLevel2TestCase", - "ContextStopped:ContextHierarchyLevel2TestCase", - "ContextStopped:ContextHierarchyLevel1TestCase", + "ContextPaused:ContextHierarchyLevel2TestCase", + "ContextPaused:ContextHierarchyLevel1TestCase", // --- ContextHierarchyLevel3a1TestCase ----------------------------- "ContextRestarted:ContextHierarchyLevel1TestCase", "ContextRestarted:ContextHierarchyLevel2TestCase", "ContextRefreshed:ContextHierarchyLevel3a1TestCase", "AfterTestClass:ContextHierarchyLevel3a1TestCase", - "ContextStopped:ContextHierarchyLevel3a1TestCase", - "ContextStopped:ContextHierarchyLevel2TestCase", - "ContextStopped:ContextHierarchyLevel1TestCase", + "ContextPaused:ContextHierarchyLevel3a1TestCase", + "ContextPaused:ContextHierarchyLevel2TestCase", + "ContextPaused:ContextHierarchyLevel1TestCase", // --- ContextHierarchyLevel3a2TestCase ----------------------------- "ContextRestarted:ContextHierarchyLevel1TestCase", @@ -185,18 +185,18 @@ class UnusedContextsIntegrationTests { "ContextRestarted:ContextHierarchyLevel3a1TestCase", "BeforeTestClass:ContextHierarchyLevel3a2TestCase", "AfterTestClass:ContextHierarchyLevel3a2TestCase", - "ContextStopped:ContextHierarchyLevel3a1TestCase", - "ContextStopped:ContextHierarchyLevel2TestCase", - "ContextStopped:ContextHierarchyLevel1TestCase", + "ContextPaused:ContextHierarchyLevel3a1TestCase", + "ContextPaused:ContextHierarchyLevel2TestCase", + "ContextPaused:ContextHierarchyLevel1TestCase", // --- ContextHierarchyLevel3bTestCase ----------------------------- "ContextRestarted:ContextHierarchyLevel1TestCase", "ContextRestarted:ContextHierarchyLevel2TestCase", "ContextRefreshed:ContextHierarchyLevel3bTestCase", "AfterTestClass:ContextHierarchyLevel3bTestCase", - "ContextStopped:ContextHierarchyLevel3bTestCase", - "ContextStopped:ContextHierarchyLevel2TestCase", - "ContextStopped:ContextHierarchyLevel1TestCase" + "ContextPaused:ContextHierarchyLevel3bTestCase", + "ContextPaused:ContextHierarchyLevel2TestCase", + "ContextPaused:ContextHierarchyLevel1TestCase" ); }