diff options
author | Bjørn Christian Seime <bjorn.christian@seime.no> | 2017-06-12 16:24:44 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-06-12 16:24:44 +0200 |
commit | 7a6c75c4fab8ceecd9271bb33d46ebe9ecd36b44 (patch) | |
tree | 415f72e93a637cc60db13c3a478309aeba483746 /jdisc_core/src/test | |
parent | 9a6d1fc6f5635fe917d1a563149764be12822ffc (diff) |
Reintroduce enforced destruction of ActiveContainer (#2712)
Reintroduce enforced destruction of ActiveContainer - without using finalizer
Diffstat (limited to 'jdisc_core/src/test')
-rw-r--r-- | jdisc_core/src/test/java/com/yahoo/jdisc/core/ActiveContainerDeactivationWatchdogTest.java | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/jdisc_core/src/test/java/com/yahoo/jdisc/core/ActiveContainerDeactivationWatchdogTest.java b/jdisc_core/src/test/java/com/yahoo/jdisc/core/ActiveContainerDeactivationWatchdogTest.java index 1a776f59e29..09ca2f93ff1 100644 --- a/jdisc_core/src/test/java/com/yahoo/jdisc/core/ActiveContainerDeactivationWatchdogTest.java +++ b/jdisc_core/src/test/java/com/yahoo/jdisc/core/ActiveContainerDeactivationWatchdogTest.java @@ -7,12 +7,20 @@ import com.yahoo.jdisc.test.TestDriver; import com.yahoo.test.ManualClock; import org.junit.Test; +import java.lang.ref.WeakReference; +import java.time.Clock; import java.time.Duration; import java.time.Instant; import java.util.Map; import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; /** * @author bjorncs @@ -59,6 +67,31 @@ public class ActiveContainerDeactivationWatchdogTest { } + @Test + public void deactivated_container_destructed_if_its_reference_counter_is_nonzero() { + ExecutorMock executor = new ExecutorMock(); + ActiveContainerDeactivationWatchdog watchdog = + new ActiveContainerDeactivationWatchdog(Clock.systemUTC(), executor); + ActiveContainer container = + new ActiveContainer(TestDriver.newSimpleApplicationInstanceWithoutOsgi().newContainerBuilder()); + AtomicBoolean destructed = new AtomicBoolean(false); + container.shutdown().notifyTermination(() -> destructed.set(true)); + + container.refer(); // increase reference counter to simluate a leaking resource + watchdog.onContainerActivation(container); + container.release(); // release resource + watchdog.onContainerActivation(null); // deactive container + + WeakReference<ActiveContainer> containerWeakReference = new WeakReference<>(container); + container = null; // make container instance collectable by GC + System.gc(); + + assertNull("Container is not GCed - probably because the watchdog has a concrete reference to it", + containerWeakReference.get()); + executor.containerDestructorCommand.run(); + assertTrue("Destructor is not called on deactivated container", destructed.get()); + } + private static class MockMetric implements Metric { public int totalCount; public int withRetainedReferencesCount; @@ -88,4 +121,25 @@ public class ActiveContainerDeactivationWatchdogTest { } } + private static class ExecutorMock extends ScheduledThreadPoolExecutor { + + public Runnable containerDestructorCommand; + private int registrationCounter = 0; + + public ExecutorMock() { + super(1); + } + + @Override + public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) { + if (registrationCounter == 2) { + containerDestructorCommand = command; + } else if (registrationCounter > 2){ + throw new IllegalStateException("Unexpected registration"); + } + ++registrationCounter; + return null; + } + } + } |