package com.limegroup.gnutella;
import java.util.List;
import java.util.Map;
import junit.framework.Test;
import org.limewire.gnutella.tests.LimeTestUtils;
import org.limewire.io.GUID;
import com.google.inject.Injector;
import com.limegroup.gnutella.messages.Message;
import com.limegroup.gnutella.messages.PingReply;
import com.limegroup.gnutella.messages.PingReplyFactory;
/**
* Tests Message Listener usage in MessageRouter.
*/
public class MessageListenerTest extends ClientSideTestCase {
final int PORT = 6669;
private PingReplyFactory pingReplyFactory;
private MessageRouterImpl messageRouter;
{
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());
}
@Override
protected void setUp() throws Exception {
Injector injector = LimeTestUtils.createInjector();
super.setUp(injector);
pingReplyFactory = injector.getInstance(PingReplyFactory.class);
messageRouter = (MessageRouterImpl) injector.getInstance(MessageRouter.class);
}
public void testMessageListener() throws Exception {
final GUID guid = new GUID(GUID.makeGuid());
final MLImpl ml = new MLImpl();
PingReply pong = pingReplyFactory.create(guid.bytes(), (byte) 2);
messageRouter.registerMessageListener(guid.bytes(), ml);
Map<byte[], List<MessageListener>> 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);
messageRouter.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 = pingReplyFactory.create(guid.bytes(), (byte) 2);
messageRouter.registerMessageListener(guid.bytes(), ml1);
messageRouter.registerMessageListener(guid.bytes(), ml2);
Map<byte[], List<MessageListener>> 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);
messageRouter.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);
messageRouter.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 = pingReplyFactory.create(guid1.bytes(), (byte) 2);
PingReply pong2 = pingReplyFactory.create(guid2.bytes(), (byte) 2);
messageRouter.registerMessageListener(guid1.bytes(), ml1);
messageRouter.registerMessageListener(guid2.bytes(), ml2);
Map<byte[], List<MessageListener>> 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);
messageRouter.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);
messageRouter.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 = pingReplyFactory.create(guid1.bytes(), (byte) 2);
PingReply pong2 = pingReplyFactory.create(guid2.bytes(), (byte) 2);
messageRouter.registerMessageListener(guid1.bytes(), ml1);
messageRouter.registerMessageListener(guid2.bytes(), ml2);
Map<byte[], List<MessageListener>> 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
messageRouter.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.
messageRouter.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.
messageRouter.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.
messageRouter.unregisterMessageListener(guid1.bytes(), ml1);
map = getMap();
assertEquals(1, map.size());
messageRouter.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<byte[], List<MessageListener>> getMap() throws Exception {
return messageRouter.getMessageListenerMap();
}
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;
}
}
@Override
public int getNumberOfPeers() {
return 1;
}
}