/** * Copyright (C) 2013 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.util.test; import java.util.ArrayList; import java.util.List; import org.springframework.context.Lifecycle; /** * Helper class for managing {@link Lifecycle} implementing objects during a test session. Objects may be created by test infrastructure that must be shutdown but are embedded or wrapped in other * object instances which don't expose life cycle methods so may not be directly available for the caller to explicitly shut them down. * <p> * Typically a test method may written along the lines of: * * <pre> * public void testFoo() { * TestLifecycle.begin(); * try { * // ... test stuff * } finally { * TestLifecycle.end(); * } * } * </pre> * * Any test infrastructure that creates things that must be shutdown at the end of the test can register them, after they've been started, by a call to {@link #register}. */ public final class TestLifecycle { private static final ThreadLocal<TestLifecycle> s_instances = new ThreadLocal<TestLifecycle>(); private final List<Lifecycle> _toStop = new ArrayList<Lifecycle>(); private TestLifecycle() { } private static TestLifecycle instance() { final TestLifecycle instance = s_instances.get(); if (instance != null) { return instance; } else { throw new IllegalStateException("Current thread not associated with a test instance"); } } /** * Call at the start of a test. */ public static void begin() { if (s_instances.get() != null) { throw new IllegalStateException("Current thread already associated with a test instance"); } s_instances.set(new TestLifecycle()); } /** * Call at the end of a test. */ public static void end() { final List<Lifecycle> toStop = instance()._toStop; s_instances.set(null); for (Lifecycle instance : toStop) { if (instance.isRunning()) { instance.stop(); } } } /** * Associate a {@link Lifecycle} instance with this test session. When the session ends the {@link Lifecycle#stop} method will be called. * <p> * The object will only be registered if it is already started. * * @param instance the instance to register, not null * @throws IllegalStateException if {@link #begin} has not been called for this session */ public static void register(final Lifecycle instance) { if (instance.isRunning()) { instance()._toStop.add(instance); } } }