package com.limegroup.gnutella;
import java.io.BufferedWriter;
import java.io.File;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.Iterator;
import java.util.concurrent.TimeUnit;
import org.limewire.core.settings.FilterSettings;
import org.limewire.io.ByteReader;
import org.limewire.io.GUID;
import org.limewire.util.FileUtils;
import junit.framework.Test;
import com.google.inject.Injector;
import com.google.inject.Stage;
import com.limegroup.gnutella.library.FileManager;
import com.limegroup.gnutella.library.FileManagerTestUtils;
import com.limegroup.gnutella.messages.Message;
import com.limegroup.gnutella.messages.MessageFactory;
import com.limegroup.gnutella.messages.QueryReply;
import com.limegroup.gnutella.messages.QueryRequest;
import com.limegroup.gnutella.messages.QueryRequestFactory;
import com.limegroup.gnutella.messages.Message.Network;
import com.limegroup.gnutella.routing.QueryRouteTable;
import com.limegroup.gnutella.routing.RouteTableMessage;
/**
* Tests that an Ultrapeer correctly handles all aspects of PushProxy. For
* example:
* 1) handles the VendorMessage exchange as expected
* 2) handles HTTP requests as expected, forwarding on a PushRequest
*
* This class tests a lot of different pieces of code.
*
* ULTRAPEER_1 ---- CENTRAL TEST ULTRAPEER ---- ULTRAPEER_2
* |
* |
* |
* LEAF
*
* The leaf must be connected in the first test.
*/
public final class ServerSideBrowseHostTest extends ServerSideTestCase {
protected static int TIMEOUT = 2000;
private FileManager fileManager;
private QueryRequestFactory queryRequestFactory;
private MessageFactory messageFactory;
public ServerSideBrowseHostTest(String name) {
super(name);
}
public static Test suite() {
return buildTestSuite(ServerSideBrowseHostTest.class);
}
public static void main(String[] args) {
junit.textui.TestRunner.run(suite());
}
@Override
public int getNumberOfUltrapeers() {
return 1;
}
@Override
public int getNumberOfLeafpeers() {
return 1;
}
@Override
public void setUpQRPTables() throws Exception {
// for Ultrapeer 1
QueryRouteTable qrt = new QueryRouteTable();
qrt.add("leehsus");
qrt.add("berkeley");
for (Iterator iter=qrt.encode(null).iterator(); iter.hasNext(); ) {
ULTRAPEER[0].send((RouteTableMessage)iter.next());
assertTrue(ULTRAPEER[0].isOpen());
ULTRAPEER[0].flush();
}
}
@Override
protected void setUp() throws Exception {
Injector injector = LimeTestUtils.createInjector(Stage.PRODUCTION);
super.setUp(injector);
fileManager = injector.getInstance(FileManager.class);
queryRequestFactory = injector.getInstance(QueryRequestFactory.class);
messageFactory = injector.getInstance(MessageFactory.class);
}
// BEGIN TESTS
// ------------------------------------------------------
public void testResultsIndicateBrowseHostSupport() throws Exception {
drainAll();
// make sure leaf is sharing
assertEquals(2, fileManager.getGnutellaFileList().size());
// send a query that should be answered
QueryRequest query = queryRequestFactory.createQueryRequest(GUID.makeGuid(), (byte) 1,
"berkeley", null, null, null, false, Network.UNKNOWN, false, 0);
ULTRAPEER[0].send(query);
ULTRAPEER[0].flush();
// await a response
Message m = null;
do {
m = ULTRAPEER[0].receive(TIMEOUT);
} while (!(m instanceof QueryReply)) ;
// confirm it supports browse host
QueryReply reply = (QueryReply) m;
assertTrue(reply.getSupportsBrowseHost());
}
public void testHTTPRequest() throws Exception {
FilterSettings.MAX_RESPONSES_PER_REPLY.setValue(10);
FileManager fm = injector.getInstance(FileManager.class);
FileManagerTestUtils.waitForLoad(fm,2000);
// make sure more than FilterSettings.MAX_RESPONSES_PER_REPLY files
// are shared
for (int i = 0; i < FilterSettings.MAX_RESPONSES_PER_REPLY.getValue() * 2; i++) {
File f = new File(_scratchDir, "sharedFile"+i+".txt");
f.deleteOnExit();
FileUtils.writeObject(f, new Integer(i));
assertNotNull(fm.getGnutellaFileList().add(f).get(1, TimeUnit.SECONDS));
}
assertEquals(2 * FilterSettings.MAX_RESPONSES_PER_REPLY.getValue() + 2, fm.getGnutellaFileList().size());
String result = null;
Socket s = new Socket("localhost", PORT);
ByteReader in = new ByteReader(s.getInputStream());
BufferedWriter out =
new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
// first test a GET
out.write("GET / HTTP/1.1\r\n");
out.write("Accept: application/x-gnutella-packets\r\n");
out.write("\r\n");
out.flush();
// check opcode
result = in.readLine();
assertGreaterThan(result, -1, result.indexOf("200"));
// get to the replies....
String currLine = null;
do {
currLine = in.readLine();
} while ((currLine != null) && !currLine.equals(""));
// 10 in the first
QueryReply qr = (QueryReply) messageFactory.read(s.getInputStream(), Network.TCP);
assertEquals(10, qr.getResultCount());
// 10 in the second
qr = (QueryReply) messageFactory.read(s.getInputStream(), Network.TCP);
assertEquals(10, qr.getResultCount());
// 2 in the 3rd.
qr = (QueryReply) messageFactory.read(s.getInputStream(), Network.TCP);
assertEquals(2, qr.getResultCount());
assertNull(in.readLine());
s.close();
in.close();
}
public void testBadHTTPRequest1() throws Exception {
String result = null;
Socket s = new Socket("localhost", PORT);
ByteReader in = new ByteReader(s.getInputStream());
BufferedWriter out =
new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
// first test a GET
out.write("GET / HTTP/1.1\r\n");
out.write("\r\n");
out.flush();
// check opcode
result = in.readLine();
assertGreaterThan(result, -1, result.indexOf("406"));
s.close();
in.close();
}
}