package com.limegroup.gnutella.connection; import java.io.IOException; import java.io.InputStream; import java.net.ServerSocket; import java.net.Socket; import junit.framework.Test; import org.limewire.concurrent.ThreadExecutor; import org.limewire.core.settings.ConnectionSettings; import org.limewire.gnutella.tests.LimeTestCase; import org.limewire.gnutella.tests.LimeTestUtils; import org.limewire.io.IOUtils; import org.limewire.net.SocketsManager.ConnectType; import org.limewire.nio.NIOServerSocket; import org.limewire.nio.observer.AcceptObserver; import org.limewire.util.StringUtils; import com.google.inject.Injector; import com.limegroup.gnutella.StubGnetConnectObserver; import com.limegroup.gnutella.connection.RoutedConnection; import com.limegroup.gnutella.connection.RoutedConnectionFactory; import com.limegroup.gnutella.handshaking.HandshakeResponderFactory; public class ConnectionTest extends LimeTestCase { private static int LISTEN_PORT = 9999; private ConnectionAcceptor ACCEPTOR; private RoutedConnectionFactory routedConnectionFactory; public ConnectionTest(String name) { super(name); } public static Test suite() { return buildTestSuite(ConnectionTest.class); } public static void main(String argv[]) { junit.textui.TestRunner.run(suite()); } @Override public void setUp() throws Exception { routedConnectionFactory = LimeTestUtils.createInjectorNonEagerly().getInstance(RoutedConnectionFactory.class); ACCEPTOR = new ConnectionAcceptor(); ACCEPTOR.start(); ConnectionSettings.ALLOW_WHILE_DISCONNECTED.setValue(true); ConnectionSettings.PREFERENCING_ACTIVE.setValue(false); } @Override public void tearDown() throws Exception { ACCEPTOR.shutdown(); Thread.sleep(1000); } public void testNonBlockingConnectFailing() throws Exception { RoutedConnection rc = routedConnectionFactory.createRoutedConnection("127.0.0.1", LISTEN_PORT+1); StubGnetConnectObserver observer = new StubGnetConnectObserver(); rc.initialize(observer); observer.waitForResponse(3000); assertTrue(observer.isShutdown()); assertFalse(observer.isBadHandshake()); assertFalse(observer.isConnect()); assertFalse(observer.isNoGOK()); } public void testNonBlockingConnectSucceeds() throws Exception { RoutedConnection rc = routedConnectionFactory.createRoutedConnection("127.0.0.1", LISTEN_PORT); StubGnetConnectObserver observer = new StubGnetConnectObserver(); rc.initialize(observer); observer.waitForResponse(3000); assertFalse(observer.isShutdown()); assertFalse(observer.isBadHandshake()); assertFalse(observer.isNoGOK()); assertTrue(observer.isConnect()); } public void testNonBlockingNoGOK() throws Exception { ACCEPTOR.getObserver().setNoGOK(true); RoutedConnection rc = routedConnectionFactory.createRoutedConnection("127.0.0.1", LISTEN_PORT, ConnectType.PLAIN); StubGnetConnectObserver observer = new StubGnetConnectObserver(); rc.initialize(observer); observer.waitForResponse(10000); assertFalse(observer.isShutdown()); assertFalse(observer.isBadHandshake()); assertFalse(observer.isConnect()); assertTrue(observer.isNoGOK()); assertEquals(401, observer.getCode()); } public void testNonBlockingBadHandshake() throws Exception { ACCEPTOR.getObserver().setBadHandshake(true); RoutedConnection rc = routedConnectionFactory.createRoutedConnection("127.0.0.1", LISTEN_PORT, ConnectType.PLAIN); StubGnetConnectObserver observer = new StubGnetConnectObserver(); rc.initialize(observer); observer.waitForResponse(10000); assertFalse(observer.isShutdown()); assertTrue(observer.isBadHandshake()); assertFalse(observer.isConnect()); assertFalse(observer.isNoGOK()); } private static class ConnectionAcceptor { private ServerSocket socket; private SimpleAcceptObserver observer; public void start() throws Exception { observer = new SimpleAcceptObserver(); socket = new NIOServerSocket(LISTEN_PORT, observer); } public void shutdown() throws Exception { socket.close(); } public SimpleAcceptObserver getObserver() { return observer; } } private static class SimpleAcceptObserver implements AcceptObserver { private volatile boolean noGOK = false; private volatile boolean badHandshake = false; public void handleIOException(IOException iox) {} public void handleAccept(final Socket socket) throws IOException { ThreadExecutor.startThread(new Runnable() { public void run() { try { if(badHandshake) { socket.close(); return; } socket.setSoTimeout(3000); InputStream in = socket.getInputStream(); String word = IOUtils.readWord(in, 9); if (!word.equals("GNUTELLA")) throw new IOException("Bad word: " + word); if(noGOK) { socket.getOutputStream().write(StringUtils.toAsciiBytes("GNUTELLA/0.6 401 Failed\r\n\r\n")); socket.getOutputStream().flush(); return; } Injector injector = LimeTestUtils.createInjectorNonEagerly(); BlockingConnectionFactory connectionFactory = injector.getInstance(BlockingConnectionFactory.class); HandshakeResponderFactory handshakeResponderFactory = injector.getInstance(HandshakeResponderFactory.class); final BlockingConnection con = connectionFactory.createConnection(socket); con.initialize(null, handshakeResponderFactory.createUltrapeerHandshakeResponder("127.0.0.1"), 1000); } catch (IOException e) { throw new RuntimeException(e); } } }, "conninit"); } public void shutdown() { } public void setBadHandshake(boolean badHandshake) { this.badHandshake = badHandshake; } public void setNoGOK(boolean noGOK) { this.noGOK = noGOK; } } }