summaryrefslogtreecommitdiffstats
path: root/jdisc_core/src/test
diff options
context:
space:
mode:
authorBjørn Christian Seime <bjorn.christian@seime.no>2017-06-12 16:24:44 +0200
committerGitHub <noreply@github.com>2017-06-12 16:24:44 +0200
commit7a6c75c4fab8ceecd9271bb33d46ebe9ecd36b44 (patch)
tree415f72e93a637cc60db13c3a478309aeba483746 /jdisc_core/src/test
parent9a6d1fc6f5635fe917d1a563149764be12822ffc (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.java54
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;
+ }
+ }
+
}