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 Message Listener usage in MessageRouter. */ public class MessageListenerTest extends ClientSideTestCase { protected static final int PORT=6669; protected static int TIMEOUT=1000; // should override super public MessageListenerTest(String name) { super(name); } public static Test suite() { return buildTestSuite(MessageListenerTest.class); } public static void main(String[] args) { junit.textui.TestRunner.run(suite()); } public void testMessageListener() throws Exception { final GUID guid = new GUID(GUID.makeGuid()); final MLImpl ml = new MLImpl(); PingReply pong = PingReply.create(guid.bytes(), (byte) 2); rs.getMessageRouter().registerMessageListener(guid.bytes(), ml); Map map = getMap(); assertEquals(1, map.size()); assertEquals(0, ml.count); assertTrue(ml.registered); // send off the pong for processing testUP[0].send(pong); testUP[0].flush(); Thread.sleep(2000); rs.getMessageRouter().unregisterMessageListener(guid.bytes(), ml); map = getMap(); assertEquals(0, map.size()); assertEquals(1, ml.count); assertTrue(ml.unregistered); } public void testMultipleListenersWithOneGUID() throws Exception { final GUID guid = new GUID(GUID.makeGuid()); final MLImpl ml1 = new MLImpl(); final MLImpl ml2 = new MLImpl(); PingReply pong = PingReply.create(guid.bytes(), (byte) 2); rs.getMessageRouter().registerMessageListener(guid.bytes(), ml1); rs.getMessageRouter().registerMessageListener(guid.bytes(), ml2); Map map = getMap(); assertEquals(1, map.size()); assertEquals(0, ml1.count); assertEquals(0, ml2.count); assertTrue(ml1.registered); assertTrue(ml2.registered); // send off the pong for processing testUP[0].send(pong); testUP[0].flush(); Thread.sleep(2000); assertEquals(1, ml1.count); assertEquals(1, ml2.count); rs.getMessageRouter().unregisterMessageListener(guid.bytes(), ml1); assertTrue(ml1.unregistered); assertFalse(ml2.unregistered); map = getMap(); assertEquals(1, map.size()); // send off the pong for processing testUP[0].send(pong); testUP[0].flush(); Thread.sleep(2000); assertEquals(1, ml1.count); assertEquals(2, ml2.count); rs.getMessageRouter().unregisterMessageListener(guid.bytes(), ml2); assertTrue(ml2.unregistered); map = getMap(); assertEquals(0, map.size()); } public void testMultipleGUIDListeners() throws Exception { final GUID guid1 = new GUID(GUID.makeGuid()); final GUID guid2 = new GUID(GUID.makeGuid()); final MLImpl ml1 = new MLImpl(); final MLImpl ml2 = new MLImpl(); PingReply pong1 = PingReply.create(guid1.bytes(), (byte) 2); PingReply pong2 = PingReply.create(guid2.bytes(), (byte) 2); rs.getMessageRouter().registerMessageListener(guid1.bytes(), ml1); rs.getMessageRouter().registerMessageListener(guid2.bytes(), ml2); Map map = getMap(); assertEquals(2, map.size()); assertEquals(0, ml1.count); assertEquals(0, ml2.count); assertTrue(ml1.registered); assertTrue(ml2.registered); // send off the pong for processing testUP[0].send(pong1); testUP[0].flush(); Thread.sleep(2000); assertEquals(1, ml1.count); assertEquals(0, ml2.count); // send off the pong for processing testUP[0].send(pong2); testUP[0].flush(); Thread.sleep(2000); assertEquals(1, ml1.count); assertEquals(1, ml2.count); rs.getMessageRouter().unregisterMessageListener(guid1.bytes(), ml1); assertTrue(ml1.unregistered); assertFalse(ml2.unregistered); map = getMap(); assertEquals(1, map.size()); // send off the pong for processing -- nothing should get it. testUP[0].send(pong1); testUP[0].flush(); Thread.sleep(2000); assertEquals(1, ml1.count); assertEquals(1, ml2.count); rs.getMessageRouter().unregisterMessageListener(guid2.bytes(), ml2); assertTrue(ml2.unregistered); map = getMap(); assertEquals(0, map.size()); } public void testFunkyAddingAndRemoving() throws Exception { final GUID guid1 = new GUID(GUID.makeGuid()); final GUID guid2 = new GUID(GUID.makeGuid()); final MLImpl ml1 = new MLImpl(); final MLImpl ml2 = new MLImpl(); PingReply pong1 = PingReply.create(guid1.bytes(), (byte) 2); PingReply pong2 = PingReply.create(guid2.bytes(), (byte) 2); rs.getMessageRouter().registerMessageListener(guid1.bytes(), ml1); rs.getMessageRouter().registerMessageListener(guid2.bytes(), ml2); Map map = getMap(); assertEquals(2, map.size()); assertTrue(ml1.registered); assertTrue(ml2.registered); // send off the pong for processing testUP[0].send(pong1); testUP[0].flush(); Thread.sleep(2000); assertEquals(1, ml1.count); assertEquals(0, ml2.count); // add ml1 again to ml1 -- should be notified twice per message now rs.getMessageRouter().registerMessageListener(guid1.bytes(), ml1); map = getMap(); assertEquals(2, map.size()); assertTrue(ml1.registered); assertTrue(ml2.registered); // send off the pong for processing testUP[0].send(pong1); testUP[0].flush(); Thread.sleep(2000); assertEquals(3, ml1.count); assertEquals(0, ml2.count); // remove ml1 -- should be notified just once on the next send. rs.getMessageRouter().unregisterMessageListener(guid1.bytes(), ml1); map = getMap(); assertEquals(2, map.size()); assertTrue(ml1.registered); assertTrue(ml1.unregistered); assertTrue(ml2.registered); // send off the pong for processing testUP[0].send(pong1); testUP[0].flush(); Thread.sleep(2000); assertEquals(4, ml1.count); assertEquals(0, ml2.count); // try removing ml1 from guid2's bytes, nothing should happen. rs.getMessageRouter().unregisterMessageListener(guid2.bytes(), ml1); map = getMap(); assertEquals(2, map.size()); assertTrue(ml1.registered); assertTrue(ml1.unregistered); assertTrue(ml2.registered); // send off the pong for processing testUP[0].send(pong1); testUP[0].flush(); Thread.sleep(2000); assertEquals(5, ml1.count); assertEquals(0, ml2.count); // now send ml2's pong. testUP[0].send(pong2); testUP[0].flush(); Thread.sleep(2000); assertEquals(5, ml1.count); assertEquals(1, ml2.count); // and unregister the two of'm. rs.getMessageRouter().unregisterMessageListener(guid1.bytes(), ml1); map = getMap(); assertEquals(1, map.size()); rs.getMessageRouter().unregisterMessageListener(guid2.bytes(), ml2); map = getMap(); assertEquals(0, map.size()); assertTrue(ml2.unregistered); // send pongs again -- nothing should get'm. testUP[0].send(pong1); testUP[0].send(pong2); testUP[0].flush(); Thread.sleep(2000); assertEquals(5, ml1.count); assertEquals(1, ml2.count); } ////////////////////////////////////////////////////////////////// private final Map getMap() throws Exception { return (Map) PrivilegedAccessor.getValue(RouterService.getMessageRouter(), "_messageListeners"); } 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; } } public static Integer numUPs() { return new Integer(1); } public static ActivityCallback getActivityCallback() { return new ActivityCallbackStub(); } private static byte[] myIP() { return new byte[] { (byte)192, (byte)168, 0, 1 }; } }