package com.limegroup.gnutella.util;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import com.limegroup.gnutella.io.StubConnectObserver;
import com.limegroup.gnutella.settings.ConnectionSettings;
import junit.framework.Test;
public class LimitedSocketControllerTest extends BaseTestCase {
private static final int TIMEOUT = 30000;
private int BAD_PORT = 9998;
private InetSocketAddress BAD_ADDR = new InetSocketAddress("127.0.0.1", BAD_PORT);
private int LISTEN_PORT = 9999;
private InetSocketAddress LISTEN_ADDR = new InetSocketAddress("127.0.0.1", LISTEN_PORT);
private int BAD_GOOGLE_PORT = 6666;
private InetSocketAddress BAD_GOOGLE_ADDR = new InetSocketAddress("www.google.com", BAD_GOOGLE_PORT);
private ServerSocket LISTEN_SOCKET;
private LimitedSocketController CONTROLLER;
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());
}
public void setUp() throws Exception {
LISTEN_SOCKET = new ServerSocket(LISTEN_PORT);
LISTEN_SOCKET.setReuseAddress(true);
CONTROLLER = new LimitedSocketController(2);
}
public void tearDown() throws Exception {
LISTEN_SOCKET.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 {
StubConnectObserver o1 = new StubConnectObserver();
StubConnectObserver o2 = new StubConnectObserver();
CONTROLLER.connect(BAD_GOOGLE_ADDR, TIMEOUT, o1);
CONTROLLER.connect(BAD_GOOGLE_ADDR, 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 {
StubConnectObserver o1 = new StubConnectObserver();
StubConnectObserver o2 = new StubConnectObserver();
CONTROLLER.connect(BAD_GOOGLE_ADDR, TIMEOUT, o1);
CONTROLLER.connect(BAD_GOOGLE_ADDR, 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 {
StubConnectObserver o1 = new StubConnectObserver();
CONTROLLER.connect(LISTEN_ADDR, 0, o1);
assertFalse(CONTROLLER.removeConnectObserver(o1));
StubConnectObserver o2 = new StubConnectObserver();
StubConnectObserver o3 = new StubConnectObserver();
CONTROLLER.connect(BAD_GOOGLE_ADDR, TIMEOUT, o2);
CONTROLLER.connect(BAD_GOOGLE_ADDR, TIMEOUT, o3);
StubConnectObserver o4 = new StubConnectObserver();
CONTROLLER.connect(LISTEN_ADDR, 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 {
ConnectionSettings.PROXY_HOST.setValue("127.0.0.1");
ConnectionSettings.PROXY_PORT.setValue(LISTEN_PORT);
ConnectionSettings.CONNECTION_METHOD.setValue(ConnectionSettings.C_SOCKS5_PROXY);
StubConnectObserver o1 = new StubConnectObserver();
CONTROLLER.connect(LISTEN_ADDR, 0, o1);
assertFalse(CONTROLLER.removeConnectObserver(o1));
StubConnectObserver o2 = new StubConnectObserver();
StubConnectObserver o3 = new StubConnectObserver();
CONTROLLER.connect(BAD_GOOGLE_ADDR, TIMEOUT, o2);
CONTROLLER.connect(BAD_GOOGLE_ADDR, TIMEOUT, o3);
StubConnectObserver o4 = new StubConnectObserver();
CONTROLLER.connect(LISTEN_ADDR, 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(LISTEN_ADDR, 0, null);
} else {
StubConnectObserver o = new StubConnectObserver();
s = CONTROLLER.connect(LISTEN_ADDR, 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(BAD_ADDR, 0, null);
fail("acceptedConnection from a bad proxy server");
} catch (IOException iox) {
// Good -- expected behaviour
}
} else {
StubConnectObserver o = new StubConnectObserver();
CONTROLLER.connect(BAD_ADDR, 0, o);
o.waitForResponse(60000);
assertNull(o.getSocket());
assertNull(o.getIoException());
assertTrue(o.isShutdown());
}
}
}
}