package com.tryge.xocotl.util;
import com.tryge.xocotl.io.DuplexChannel;
import com.tryge.xocotl.io.MessageDecoder;
import com.tryge.xocotl.io.MessageListener;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import java.net.InetSocketAddress;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.isA;
import static org.mockito.Matchers.same;
import static org.mockito.Mockito.*;
/**
* @author michael.zehender@me.com
*/
public class ConnectManagerTest {
private ScheduledExecutorService scheduler;
private ScheduledFuture future;
private ConnectCallback callback;
private ConnectTaskFactory factory;
private ConnectTask task;
private ConnectConfig config;
private ConnectManager manager;
@Before
public void setUp() {
scheduler = mock(ScheduledExecutorService.class);
future = mock(ScheduledFuture.class);
callback = mock(ConnectCallback.class);
factory = mock(ConnectTaskFactory.class);
task = mock(ConnectTask.class);
config = new ConnectConfig();
config.setAddress(new InetSocketAddress(4000));
config.setDecoder(mock(MessageDecoder.class));
config.setListener(mock(MessageListener.class));
config.setConnectTimeout(500);
when(factory.newInstance(isA(ConnectCallback.class), same(config))).thenReturn(task);
manager = new ConnectManager(scheduler, callback, config, factory);
}
@Test
public void testStartAndStopConnectManager() {
when(scheduler.scheduleAtFixedRate(same(task), eq(0L), eq(5000L), same(TimeUnit.MILLISECONDS))).thenReturn(future);
manager.start(5000L);
verify(scheduler).scheduleAtFixedRate(same(task), eq(0L), eq(5000L), same(TimeUnit.MILLISECONDS));
manager.stop();
verify(future).cancel(true);
verifyNoMoreInteractions(scheduler, future, callback, task);
}
@Test
public void testOnConnectAndOnDisconnectCallbackDelegation() {
when(scheduler.scheduleAtFixedRate(same(task), eq(0L), eq(5000L), same(TimeUnit.MILLISECONDS))).thenReturn(future);
manager.start(5000L);
DuplexChannel channel = mock(DuplexChannel.class);
ArgumentCaptor<ConnectCallback> captor = ArgumentCaptor.forClass(ConnectCallback.class);
verify(factory).newInstance(captor.capture(), same(config));
ConnectCallback callback = captor.getValue();
when(this.callback.checkChannel(same(channel))).thenReturn(true);
boolean value = callback.checkChannel(channel);
assertTrue(value);
callback.onConnect(channel);
verify(this.callback).checkChannel(same(channel));
verify(future).cancel(false);
ArgumentCaptor<Runnable> connectRunnable = ArgumentCaptor.forClass(Runnable.class);
verify(scheduler).submit(connectRunnable.capture());
Runnable runnable = connectRunnable.getValue();
runnable.run();
verify(this.callback).onConnect(same(channel));
when(scheduler.scheduleAtFixedRate(same(task), eq(5000L), eq(5000L), same(TimeUnit.MILLISECONDS))).thenReturn(future);
callback.onDisconnect();
connectRunnable = ArgumentCaptor.forClass(Runnable.class);
verify(scheduler, times(2)).submit(connectRunnable.capture());
verify(scheduler).scheduleAtFixedRate(same(task), eq(5000L), eq(5000L), same(TimeUnit.MILLISECONDS));
runnable = connectRunnable.getAllValues().get(1);
runnable.run();
verify(this.callback).onDisconnect();
}
@Test
public void testIsConnectedDelegatesToConnectTask() {
when(task.isConnected()).thenReturn(true);
boolean value = manager.isConnected();
verify(task).isConnected();
assertTrue(value);
}
}