Browse Source

Introduce ConfigurableApplicationContext.pause() and SmartLifecycle.isPauseable()

Closes gh-35269
pull/34146/merge
Juergen Hoeller 5 months ago
parent
commit
149d468ce4
  1. 1
      spring-context-support/src/test/java/org/springframework/scheduling/quartz/QuartzSupportTests.java
  2. 15
      spring-context/src/main/java/org/springframework/context/ConfigurableApplicationContext.java
  3. 9
      spring-context/src/main/java/org/springframework/context/LifecycleProcessor.java
  4. 25
      spring-context/src/main/java/org/springframework/context/SmartLifecycle.java
  5. 46
      spring-context/src/main/java/org/springframework/context/event/ContextPausedEvent.java
  6. 4
      spring-context/src/main/java/org/springframework/context/event/ContextRestartedEvent.java
  7. 7
      spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java
  8. 43
      spring-context/src/main/java/org/springframework/context/support/DefaultLifecycleProcessor.java
  9. 26
      spring-context/src/test/java/org/springframework/context/support/DefaultLifecycleProcessorTests.java
  10. 6
      spring-test/src/main/java/org/springframework/test/context/cache/ContextCache.java
  11. 2
      spring-test/src/main/java/org/springframework/test/context/cache/DefaultContextCache.java
  12. 38
      spring-test/src/test/java/org/springframework/test/context/cache/UnusedContextsIntegrationTests.java

1
spring-context-support/src/test/java/org/springframework/scheduling/quartz/QuartzSupportTests.java

@ -391,7 +391,6 @@ class QuartzSupportTests { @@ -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();
}
}

15
spring-context/src/main/java/org/springframework/context/ConfigurableApplicationContext.java

@ -221,16 +221,27 @@ public interface ConfigurableApplicationContext extends ApplicationContext, Life @@ -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.

9
spring-context/src/main/java/org/springframework/context/LifecycleProcessor.java

@ -44,6 +44,15 @@ public interface LifecycleProcessor extends Lifecycle { @@ -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.

25
spring-context/src/main/java/org/springframework/context/SmartLifecycle.java

@ -85,7 +85,7 @@ public interface SmartLifecycle extends Lifecycle, Phased { @@ -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.
* <p>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 { @@ -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.
* <p>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.
* <p>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.
* <p>The provided callback is used by the {@link LifecycleProcessor} to support

46
spring-context/src/main/java/org/springframework/context/event/ContextPausedEvent.java

@ -0,0 +1,46 @@ @@ -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.
*
* <p>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);
}
}

4
spring-context/src/main/java/org/springframework/context/event/ContextRestartedEvent.java

@ -17,6 +17,7 @@ @@ -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; @@ -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 {

7
spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java

@ -66,6 +66,7 @@ import org.springframework.context.PayloadApplicationEvent; @@ -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 @@ -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());

43
spring-context/src/main/java/org/springframework/context/support/DefaultLifecycleProcessor.java

@ -287,7 +287,7 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
Map<Integer, LifecycleGroup> 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 @@ -446,13 +456,13 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor
* @param beanName the name of the bean to stop
*/
private void doStop(Map<String, ? extends Lifecycle> lifecycleBeans, final String beanName,
final CountDownLatch latch, final Set<String> countDownBeanNames) {
boolean pauseableOnly, final CountDownLatch latch, final Set<String> 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,6 +471,7 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor @@ -461,6 +471,7 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor
stoppedBeans.add(beanName);
}
if (bean instanceof SmartLifecycle smartLifecycle) {
if (!pauseableOnly || smartLifecycle.isPauseable()) {
if (logger.isTraceEnabled()) {
logger.trace("Asking bean '" + beanName + "' of type [" +
bean.getClass().getName() + "] to stop");
@ -474,7 +485,8 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor @@ -474,7 +485,8 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor
}
});
}
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 @@ -562,14 +574,19 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor
private final boolean autoStartupOnly;
private final boolean pauseableOnly;
private final List<LifecycleGroupMember> members = new ArrayList<>();
private int smartMemberCount;
public LifecycleGroup(int phase, Map<String, ? extends Lifecycle> lifecycleBeans, boolean autoStartupOnly) {
public LifecycleGroup(int phase, Map<String, ? extends Lifecycle> 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 @@ -621,7 +638,7 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor
Set<String> 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

26
spring-context/src/test/java/org/springframework/context/support/DefaultLifecycleProcessorTests.java

@ -355,6 +355,7 @@ class DefaultLifecycleProcessorTests { @@ -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 { @@ -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 { @@ -740,6 +753,8 @@ class DefaultLifecycleProcessorTests {
private volatile boolean autoStartup = true;
private volatile boolean pauseable = true;
static TestSmartLifecycleBean forStartupTests(int phase, CopyOnWriteArrayList<Lifecycle> startedBeans) {
return new TestSmartLifecycleBean(phase, 0, startedBeans, null);
}
@ -769,6 +784,15 @@ class DefaultLifecycleProcessorTests { @@ -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

6
spring-test/src/main/java/org/springframework/test/context/cache/ContextCache.java vendored

@ -93,8 +93,8 @@ public interface ContextCache { @@ -93,8 +93,8 @@ public interface ContextCache {
/**
* Obtain a cached {@link ApplicationContext} for the given key.
* <p>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.
* <p>In addition, the {@linkplain #getHitCount() hit} and
@ -187,7 +187,7 @@ public interface ContextCache { @@ -187,7 +187,7 @@ public interface ContextCache {
* {@link MergedContextConfiguration} and any of its parents.
* <p>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}.
* <p>The default implementation of this method does nothing. Concrete
* implementations are therefore highly encouraged to override this
* method, {@link #registerContextUsage(MergedContextConfiguration, Class)},

2
spring-test/src/main/java/org/springframework/test/context/cache/DefaultContextCache.java vendored

@ -187,7 +187,7 @@ public class DefaultContextCache implements ContextCache { @@ -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);
}

38
spring-test/src/test/java/org/springframework/test/context/cache/UnusedContextsIntegrationTests.java vendored

@ -69,13 +69,13 @@ class UnusedContextsIntegrationTests { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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"
);
}

Loading…
Cancel
Save