package com.tryge.xocotl.util;
import com.tryge.xocotl.io.DuplexChannel;
import com.tryge.xocotl.io.MessageDecoder;
import com.tryge.xocotl.io.MessageListener;
import com.tryge.xocotl.io.SocketChannels;
import org.junit.Test;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.isA;
import static org.mockito.Mockito.*;
/**
* @author michael.zehender@me.com
*/
public class DefaultConnectTaskTest {
private static final int PORT = 7880;
@Test
public void givenConnectionEstablishButInvalidThenCloseChannel() throws BrokenBarrierException, InterruptedException {
final CyclicBarrier barrier = new CyclicBarrier(2);
Thread server = new Thread() {
@Override
public void run() {
try {
ServerSocket serverSocket = new ServerSocket(PORT);
barrier.await();
// the port forwarding of adb accepts a connection but then immediately
// closes it when it detects that nothing listens to the remote port.
// therefore simulate the accept and close behaviour.
Socket socket = serverSocket.accept();
socket.close();
serverSocket.close();
} catch (Exception e) {
// ignore
}
}
};
server.start();
barrier.await();
ConnectCallback callback = mock(ConnectCallback.class);
MessageDecoder decoder = mock(MessageDecoder.class);
MessageListener listener = mock(MessageListener.class);
ConnectConfig config = new ConnectConfig();
config.setFactory(SocketChannels.getFactory());
config.setAddress(new InetSocketAddress(PORT));
config.setDecoder(decoder);
config.setListener(listener);
when(callback.checkChannel(isA(DuplexChannel.class))).thenReturn(false);
DefaultConnectTask task = new DefaultConnectTask(callback, config);
task.run();
verify(callback).checkChannel(isA(DuplexChannel.class));
verifyNoMoreInteractions(callback, decoder, listener);
server.join();
}
@Test
public void givenConnectionEstablishAndValid() throws BrokenBarrierException, InterruptedException {
final CyclicBarrier barrier = new CyclicBarrier(2);
final CyclicBarrier barrier2 = new CyclicBarrier(2);
Thread server = new Thread() {
@Override
public void run() {
try {
ServerSocket serverSocket = new ServerSocket(PORT);
barrier.await();
// the port forwarding of adb accepts a connection but then immediately
// closes it when it detects that nothing listens to the remote port.
// therefore simulate the accept and close behaviour.
Socket socket = serverSocket.accept();
barrier2.await();
socket.close();
serverSocket.close();
} catch (Exception e) {
// ignore
}
}
};
server.start();
barrier.await();
ConnectCallback callback = mock(ConnectCallback.class);
MessageDecoder decoder = mock(MessageDecoder.class);
MessageListener listener = mock(MessageListener.class);
ConnectConfig config = new ConnectConfig();
config.setAddress(new InetSocketAddress(PORT));
config.setDecoder(decoder);
config.setListener(listener);
when(callback.checkChannel(isA(DuplexChannel.class))).thenReturn(true);
DefaultConnectTask task = new DefaultConnectTask(callback, config);
task.run();
assertTrue(task.isConnected());
barrier2.await();
verify(callback).checkChannel(isA(DuplexChannel.class));
verify(callback).onConnect(isA(DuplexChannel.class));
verify(callback, timeout(100)).onDisconnect();
verifyNoMoreInteractions(callback, decoder, listener);
server.join();
}
}