package org.limewire.net; import java.io.IOException; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; import junit.framework.Test; import org.limewire.io.SimpleNetworkInstanceUtils; import org.limewire.net.ProxySettings.ProxyType; import org.limewire.nio.NBSocketFactory; import org.limewire.nio.NIOSocketFactory; import org.limewire.util.BaseTestCase; public class LimitedSocketControllerTest extends BaseTestCase { private final int TIMEOUT = 30000; private final NBSocketFactory FACTORY = new NIOSocketFactory(); private final int BAD_PORT = 9998; private final InetSocketAddress BAD_ADDR = new InetSocketAddress("127.0.0.1", BAD_PORT); private final int LISTEN_PORT = 9999; private final InetSocketAddress LISTEN_ADDR = new InetSocketAddress("127.0.0.1", LISTEN_PORT); private final int BAD_GOOGLE_PORT = 6666; private final InetSocketAddress BAD_GOOGLE_ADDR = new InetSocketAddress("www.google.com", BAD_GOOGLE_PORT); private ServerSocket listenSocket; private LimitedSocketController controller; private ProxyManager proxyManager; private ProxySettingsStub proxySettings; public LimitedSocketControllerTest(String name) { super(name); } public static Test suite() { return buildTestSuite(LimitedSocketControllerTest.class); } public static void main(String[] args) { junit.textui.TestRunner.run(suite()); } @Override public void setUp() throws Exception { listenSocket = new ServerSocket(LISTEN_PORT); listenSocket.setReuseAddress(true); proxySettings = new ProxySettingsStub(); proxyManager = new ProxyManagerImpl(proxySettings, new SimpleNetworkInstanceUtils()); controller = new LimitedSocketController(proxyManager, new EmptySocketBindingSettings(), 2); } @Override public void tearDown() throws Exception { listenSocket.close(); } public void testSimpleConnect() throws Exception { connect(false, true); } public void testSimpleConnectNB() throws Exception { connect(true, true); } public void testFailureConnect() throws Exception { connect(false, false); } public void testFailureConnectNB() throws Exception { connect(true, false); } public void testMaxConcurrent() throws Exception { assertEquals(2, controller.getNumAllowedSockets()); } public void testWaitsForTurn() throws Exception { ConnectObserverStub o1 = new ConnectObserverStub(); ConnectObserverStub o2 = new ConnectObserverStub(); controller.connect(FACTORY, BAD_GOOGLE_ADDR, null, TIMEOUT, o1); controller.connect(FACTORY, BAD_GOOGLE_ADDR, null, TIMEOUT, o2); // the above two will stall for awhile while trying to connect... long then = System.currentTimeMillis(); connect(false, true); long now = System.currentTimeMillis(); assertGreaterThan(10000, now - then); // make sure it took awhile } public void testWaitsForTurnNB() throws Exception { ConnectObserverStub o1 = new ConnectObserverStub(); ConnectObserverStub o2 = new ConnectObserverStub(); controller.connect(FACTORY, BAD_GOOGLE_ADDR, null, TIMEOUT, o1); controller.connect(FACTORY, BAD_GOOGLE_ADDR, null, TIMEOUT, o2); // the above two will stall for awhile while trying to connect... long then = System.currentTimeMillis(); connect(true, true); long now = System.currentTimeMillis(); assertGreaterThan(10000, now - then); // make sure it took awhile } public void testRemoveObserver() throws Exception { ConnectObserverStub o1 = new ConnectObserverStub(); controller.connect(FACTORY, LISTEN_ADDR, null, 0, o1); assertFalse(controller.removeConnectObserver(o1)); ConnectObserverStub o2 = new ConnectObserverStub(); ConnectObserverStub o3 = new ConnectObserverStub(); controller.connect(FACTORY, BAD_GOOGLE_ADDR, null, TIMEOUT, o2); controller.connect(FACTORY, BAD_GOOGLE_ADDR, null, TIMEOUT, o3); ConnectObserverStub o4 = new ConnectObserverStub(); controller.connect(FACTORY, LISTEN_ADDR, null, 0, o4); assertTrue(controller.removeConnectObserver(o4)); o3.waitForResponse(60000); // wait until o2 & o3 finish, make sure 4 didn't try Thread.sleep(1000); assertFalse(o4.isShutdown()); assertNull(o4.getSocket()); assertNull(o4.getIoException()); } public void testRemoveObserverWithProxies() throws Exception { proxySettings.setProxyHost("www.google.com"); proxySettings.setProxyPort(LISTEN_PORT); proxySettings.setProxyType(ProxyType.SOCKS5); ConnectObserverStub o1 = new ConnectObserverStub(); controller.connect(FACTORY, LISTEN_ADDR, null, 0, o1); assertFalse(controller.removeConnectObserver(o1)); ConnectObserverStub o2 = new ConnectObserverStub(); ConnectObserverStub o3 = new ConnectObserverStub(); controller.connect(FACTORY, BAD_GOOGLE_ADDR, null, TIMEOUT, o2); controller.connect(FACTORY, BAD_GOOGLE_ADDR, null, TIMEOUT, o3); ConnectObserverStub o4 = new ConnectObserverStub(); controller.connect(FACTORY, LISTEN_ADDR, null, 0, o4); assertTrue(controller.removeConnectObserver(o4)); o3.waitForResponse(60000); // wait until o2 & o3 finish, make sure 4 didn't try Thread.sleep(1000); assertFalse(o4.isShutdown()); assertNull(o4.getSocket()); assertNull(o4.getIoException()); } private void connect(boolean nb, boolean success) throws Exception { if (success) { Socket s; if (!nb) { s = controller.connect(FACTORY, LISTEN_ADDR, null, 0, null); } else { ConnectObserverStub o = new ConnectObserverStub(); s = controller.connect(FACTORY, LISTEN_ADDR, null, 0, o); o.waitForResponse(60000); assertEquals(s, o.getSocket()); assertNull(o.getIoException()); assertFalse(o.isShutdown()); } // Must connect somewhere, NPE is an error s.close(); } else { if (!nb) { try { controller.connect(FACTORY, BAD_ADDR, null, 0, null); fail("acceptedConnection from a bad proxy server"); } catch (IOException iox) { // Good -- expected behaviour } } else { ConnectObserverStub o = new ConnectObserverStub(); controller.connect(FACTORY, BAD_ADDR, null, 0, o); o.waitForResponse(60000); assertNull(o.getSocket()); assertNull(o.getIoException()); assertTrue(o.isShutdown()); } } } }