package org.jboss.aerogear.unifiedpush.message.serviceHolder; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.mockito.Mockito.mock; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicInteger; import org.jboss.aerogear.unifiedpush.message.serviceHolder.DisposableReference; import org.jboss.aerogear.unifiedpush.message.serviceHolder.ServiceDestroyer; import org.jboss.aerogear.unifiedpush.message.serviceHolder.ServiceDisposalScheduler; import org.junit.After; import org.junit.Before; import org.junit.Test; public class TestAbstractServiceHolder { private ServiceDisposalScheduler scheduler = new ServiceDisposalScheduler(); private ServiceDestroyer<Object> mockDestroyer; private Object instance = new Object(); @Before public void setUp() { scheduler.initialize(); mockDestroyer = mock(ServiceDestroyer.class); } @After public void tearDown() { scheduler.terminate(); } @Test public void test_that_get_nulls_the_reference() throws InterruptedException { DisposableReference<Object> disposableReference = new DisposableReference<>(instance, mockDestroyer); assertEquals(instance, disposableReference.get()); assertNull(disposableReference.get());; } @Test public void test_that_disposal_nulls_the_reference() throws InterruptedException { DisposableReference<Object> disposableReference = new DisposableReference<>(instance, mockDestroyer); disposableReference.dispose(); assertNull(disposableReference.get());; } @Test(timeout = 2000L) public void test_that_instance_is_disposed_after_delay() throws InterruptedException { final CountDownLatch latch = new CountDownLatch(1); ServiceDestroyer<Object> serviceDestroyer = new ServiceDestroyer<Object>() { public void destroy(Object instance) { latch.countDown(); }; }; DisposableReference<Object> disposableReference = new DisposableReference<>(instance, serviceDestroyer); scheduler.scheduleForDisposal(disposableReference, 1000); latch.await(); assertNull(disposableReference.get()); } @Test(timeout = 2000) public void test_disposing_multiple_instances() throws InterruptedException { final int numberOfInstances = 100; final CountDownLatch latch = new CountDownLatch(numberOfInstances); ServiceDestroyer<Object> serviceDestroyer = new ServiceDestroyer<Object>() { public void destroy(Object instance) { latch.countDown(); }; }; for (int i = 0; i < numberOfInstances; i++) { scheduler.scheduleForDisposal(new DisposableReference<>(instance, serviceDestroyer), 1000); } latch.await(); } @Test(timeout = 2000) public void test_disposing_gracefully_when_terminated() { final int numberOfInstances = 100; final AtomicInteger numberOfInstancesTerminatedGracefully = new AtomicInteger(); ServiceDestroyer<Object> serviceDestroyer = new ServiceDestroyer<Object>() { public void destroy(Object instance) { numberOfInstancesTerminatedGracefully.incrementAndGet(); }; }; for (int i = 0; i < numberOfInstances; i++) { scheduler.scheduleForDisposal(new DisposableReference<>(instance, serviceDestroyer), 100); // delay is lesser than termination timeout } scheduler.terminate(); assertEquals("all instances should be terminated gracefully", numberOfInstances, numberOfInstancesTerminatedGracefully.get()); } }