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());
}
}