package lsr.common;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;
import lsr.common.Dispatcher.Priority;
import org.junit.Before;
import org.junit.Test;
import org.mockito.InOrder;
public class DispatcherImplTest {
private DispatcherImpl dispatcher;
@Before
public void setUp() {
dispatcher = new DispatcherImpl("test");
dispatcher.start();
}
public void tearDown() throws InterruptedException {
dispatcher.interrupt();
dispatcher.join();
}
@Test
public void shouldDispatchTask() throws InterruptedException {
Runnable task = mock(Runnable.class);
dispatcher.dispatch(task);
Thread.sleep(100);
verify(task, times(1)).run();
}
@Test
public void shouldRunHighPriorityTaskFirst() throws InterruptedException {
Runnable lowPriorityTask = mock(Runnable.class);
Runnable highPriorityTask = mock(Runnable.class);
dispatcher.dispatch(new SlowTask(100));
dispatcher.dispatch(lowPriorityTask, Priority.Low);
dispatcher.dispatch(highPriorityTask, Priority.High);
Thread.sleep(150);
InOrder inOrder = inOrder(lowPriorityTask, highPriorityTask);
inOrder.verify(highPriorityTask).run();
inOrder.verify(lowPriorityTask).run();
}
@Test
public void shouldNotBeInDispatcherThread() {
assertFalse(dispatcher.amIInDispatcher());
}
@Test
public void shouldShowContentInToStringMethod() throws InterruptedException {
Runnable task = mock(Runnable.class);
dispatcher.dispatch(new SlowTask(100), Priority.High);
dispatcher.dispatch(task, Priority.High);
dispatcher.dispatch(task, Priority.High);
dispatcher.dispatch(task, Priority.High);
dispatcher.dispatch(task, Priority.Normal);
dispatcher.dispatch(task, Priority.Normal);
dispatcher.dispatch(task, Priority.Low);
String state = dispatcher.toString();
assertEquals("High:3,Normal:2,Low:1", state);
Thread.sleep(150);
}
@Test
public void shouldScheduleTask() throws InterruptedException {
Runnable firstTask = mock(Runnable.class);
Runnable secondTask = mock(Runnable.class);
dispatcher.schedule(secondTask, Priority.Normal, 100);
dispatcher.schedule(firstTask, Priority.Normal, 50);
Thread.sleep(150);
InOrder inOrder = inOrder(firstTask, secondTask);
inOrder.verify(firstTask).run();
inOrder.verify(secondTask).run();
}
@Test
public void shouldAllowToCancelScheduledTask() throws InterruptedException {
Runnable task = mock(Runnable.class);
PriorityTask priorityTask = dispatcher.schedule(task, Priority.Normal, 100);
assertTrue(100 - priorityTask.getDelay() < 5);
priorityTask.cancel();
Thread.sleep(150);
verifyZeroInteractions(task);
}
@Test
public void shouldAllowToCancelNormalTask() throws InterruptedException {
Runnable task = mock(Runnable.class);
dispatcher.dispatch(new SlowTask(100));
PriorityTask priorityTask = dispatcher.dispatch(task);
assertEquals(0, priorityTask.getDelay());
priorityTask.cancel();
Thread.sleep(150);
}
@Test
public void shouldScheduleAtFixedRate() throws InterruptedException {
Runnable firstTask = mock(Runnable.class);
Runnable secondTask = mock(Runnable.class);
dispatcher.scheduleAtFixedRate(secondTask, Priority.Normal, 5, 75);
dispatcher.scheduleAtFixedRate(firstTask, Priority.Normal, 0, 50);
Thread.sleep(125);
InOrder inOrder = inOrder(firstTask, secondTask);
inOrder.verify(firstTask).run();
inOrder.verify(secondTask).run();
inOrder.verify(firstTask).run();
inOrder.verify(secondTask).run();
inOrder.verify(firstTask).run();
verifyNoMoreInteractions(firstTask);
verifyNoMoreInteractions(secondTask);
}
@Test
public void shouldScheduleWithFixedDelay() throws InterruptedException {
Runnable firstTask = mock(Runnable.class);
Runnable secondTask = mock(Runnable.class);
dispatcher.scheduleWithFixedDelay(secondTask, Priority.Normal, 5, 75);
dispatcher.scheduleWithFixedDelay(firstTask, Priority.Normal, 0, 50);
Thread.sleep(125);
InOrder inOrder = inOrder(firstTask, secondTask);
inOrder.verify(firstTask).run();
inOrder.verify(secondTask).run();
inOrder.verify(firstTask).run();
inOrder.verify(secondTask).run();
inOrder.verify(firstTask).run();
verifyNoMoreInteractions(firstTask);
verifyNoMoreInteractions(secondTask);
}
private static class SlowTask implements Runnable {
private final int sleep;
public SlowTask(int sleep) {
this.sleep = sleep;
}
public void run() {
try {
Thread.sleep(sleep);
} catch (InterruptedException e) {
fail();
}
}
}
}