package com.limegroup.gnutella; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; import junit.framework.Test; import com.limegroup.gnutella.messages.Message; import com.limegroup.gnutella.messages.PingReply; import com.limegroup.gnutella.messages.PingRequest; import com.limegroup.gnutella.search.HostData; import com.limegroup.gnutella.stubs.ActivityCallbackStub; import com.limegroup.gnutella.util.IpPort; import com.limegroup.gnutella.util.PrivilegedAccessor; /** * Tests that UDP host ranker works. */ public class UDPHostRankerTest extends ClientSideTestCase { protected static final int PORT=6669; protected static int TIMEOUT=1000; // should override super public UDPHostRankerTest(String name) { super(name); } public static Test suite() { return buildTestSuite(UDPHostRankerTest.class); } public static void main(String[] args) { junit.textui.TestRunner.run(suite()); } ///////////////////////// Actual Tests //////////////////////////// public void testRanker() throws Exception { DatagramSocket[] udps = new DatagramSocket[20]; for (int i = 0; i < udps.length; i++) udps[i] = new DatagramSocket(); final List list = new ArrayList(); for (int i = 0; i < udps.length; i++) list.add(new IpPortImpl(udps[i])); final MLImpl ml = new MLImpl(); PingRequest pr = new PingRequest(GUID.makeGuid(), (byte)1); UDPPinger pinger = new UniqueHostPinger(); pinger.rank(list, ml, null, pr); Thread.sleep(500); assertTrue(ml.registered); for (int i = 0; i < udps.length; i++) { DatagramPacket pack = new DatagramPacket(new byte[1000], 1000); udps[i].setSoTimeout(TIMEOUT); try { udps[i].receive(pack); } catch (IOException bad) { fail("Did not get expected message, i = " + i, bad); } InputStream in = new ByteArrayInputStream(pack.getData()); // as long as we don't get a ClassCastException we are good to go PingRequest ping = (PingRequest) Message.read(in); ByteArrayOutputStream baos = new ByteArrayOutputStream(); PingReply pong = PingReply.create(ping.getGUID(), (byte)1); pong.write(baos); pack = new DatagramPacket(baos.toByteArray(), baos.toByteArray().length, InetAddress.getLocalHost(), PORT); udps[i].send(pack); } Thread.sleep(2000); //processing assertEquals(udps.length, ml.count); // wait 20 seconds, make sure MessageRouter's map is clear Thread.sleep(20000); Map map = (Map) PrivilegedAccessor.getValue(RouterService.getMessageRouter(), "_messageListeners"); assertEquals(0, map.size()); assertTrue(ml.unregistered); } ////////////////////////////////////////////////////////////////// private class MLImpl implements MessageListener { public int count = 0; public boolean registered = false; public boolean unregistered = false; public void processMessage(Message m, ReplyHandler handler) { assertTrue(m instanceof PingReply); count++; } public void registered(byte[] guid) { registered = true; } public void unregistered(byte[] guid) { unregistered = true; } } private class IpPortImpl implements IpPort { DatagramSocket _ds; public IpPortImpl(DatagramSocket ds) { _ds = ds; } public InetAddress getInetAddress() { try { return InetAddress.getLocalHost(); } catch (Exception noway) {} return null; } public int getPort() { return _ds.getLocalPort(); } public String getAddress() { try { return InetAddress.getLocalHost().getHostAddress(); } catch (Exception noway) {} return null; } } public static Integer numUPs() { return new Integer(1); } public static ActivityCallback getActivityCallback() { return new MyActivityCallback(); } private static byte[] myIP() { return new byte[] { (byte)192, (byte)168, 0, 1 }; } public static class MyActivityCallback extends ActivityCallbackStub { private RemoteFileDesc rfd = null; public RemoteFileDesc getRFD() { return rfd; } public void handleQueryResult(RemoteFileDesc rfd, HostData data, Set locs) { this.rfd = rfd; } } }