package com.limegroup.gnutella; import java.util.Map; import junit.framework.Test; import com.limegroup.gnutella.stubs.ReplyHandlerStub; import com.limegroup.gnutella.util.BaseTestCase; import com.limegroup.gnutella.util.PrivilegedAccessor; /** * Test the public methods of the <tt>FileDesc</tt> class. */ public final class RouteTableTest extends BaseTestCase { public RouteTableTest(String name) { super(name); } public static Test suite() { return buildTestSuite(RouteTableTest.class); } public static void main(String[] args) { junit.textui.TestRunner.run(suite()); } public void testLegacy() throws Exception { RouteTable rt=null; byte[] g1=new byte[16]; g1[0]=(byte)1; byte[] g2=new byte[16]; g2[0]=(byte)2; byte[] g3=new byte[16]; g3[0]=(byte)3; byte[] g4=new byte[16]; g4[0]=(byte)4; ReplyHandler c1=new ReplyHandlerStub(); ReplyHandler c2=new ReplyHandlerStub(); ReplyHandler c3=new ReplyHandlerStub(); ReplyHandler c4=new ReplyHandlerStub(); //1. Test time replacement policy (glass box). int MSECS=1250; rt=new RouteTable(MSECS/1000, Integer.MAX_VALUE); rt.routeReply(g1, c1); rt.routeReply(g2, c2); //old, new: rt.routeReply(g3, c3); //{}, {g1, g2, g3} assertSame(c1, rt.getReplyHandler(g1)); assertSame(c2, rt.getReplyHandler(g2)); assertSame(c3, rt.getReplyHandler(g3, 0, (short) 0).getReplyHandler()); assertNull(rt.getReplyHandler(g4, 0, (short) 0)); try { Thread.sleep(MSECS); } catch (InterruptedException e) { } assertNotNull(rt.tryToRouteReply(g4, c4)); //{g1, g2, g3}, {g4} assertSame(c1, rt.getReplyHandler(g1)); rt.routeReply(g1, c1); //{g2, g3}, {g1, g4} assertSame(c1, rt.getReplyHandler(g1)); assertSame(c2, rt.getReplyHandler(g2, 0, (short) 0).getReplyHandler()); assertSame(c3, rt.getReplyHandler(g3)); assertSame(c4, rt.getReplyHandler(g4)); try { Thread.sleep(MSECS); } catch (InterruptedException e) { } rt.routeReply(g2, c3); //{g1, g4}, {g2} debug(rt.toString()); assertSame(c1, rt.getReplyHandler(g1)); assertSame(c3, rt.getReplyHandler(g2)); assertNull(rt.getReplyHandler(g3)); assertSame(c4, rt.getReplyHandler(g4)); try { Thread.sleep(MSECS); } catch (InterruptedException e) { } assertNull(rt.tryToRouteReply(g2, c2)); //{g2}, {}} assertNull(rt.getReplyHandler(g1)); assertSame(c3, rt.getReplyHandler(g2)); assertNull(rt.getReplyHandler(g3)); assertNull(rt.getReplyHandler(g4)); rt.routeReply(g2, c2); //{}, {g2} assertNull(rt.getReplyHandler(g1)); assertSame(c2, rt.getReplyHandler(g2)); assertNull(rt.getReplyHandler(g3)); assertNull(rt.getReplyHandler(g4)); //1.5 Test space replacment (hard upper bounds) rt=new RouteTable(Integer.MAX_VALUE, 1); rt.routeReply(g1, c1); rt.routeReply(g2, c2); //{g1}, {g2} assertSame(c1, rt.getReplyHandler(g1)); assertSame(c2, rt.getReplyHandler(g2)); rt.routeReply(g3, c3); //{g3}, {g2} assertNull(rt.getReplyHandler(g1)); assertSame(c2, rt.getReplyHandler(g2)); assertSame(c3, rt.getReplyHandler(g3)); rt.routeReply(g4, c4); assertNull(rt.getReplyHandler(g1)); assertNull(rt.getReplyHandler(g2)); assertSame(c3, rt.getReplyHandler(g3)); assertSame(c4, rt.getReplyHandler(g4)); //2. Test routing/re-routing abilities...with glass box tests. rt=new RouteTable(1000, Integer.MAX_VALUE); //test wrap-around PrivilegedAccessor.setValue(rt, "_nextID", new Integer(Integer.MAX_VALUE)); assertNotNull(rt.tryToRouteReply(g1, c1)); //g1->c1 assertNull(rt.tryToRouteReply(g1, c2)); assertSame(c1, rt.getReplyHandler(g1)); assertNotNull(rt.tryToRouteReply(g2, c2)); //g2->c2 assertSame(c2, rt.getReplyHandler(g2)); rt.routeReply(g2, c3); //g2->c3 assertSame(c1, rt.getReplyHandler(g1)); assertSame(c3, rt.getReplyHandler(g2)); rt.removeReplyHandler(c1); //g1->null rt.removeReplyHandler(c3); //g2->null assertNull(rt.getReplyHandler(g1, 0, (short) 0)); assertNull(rt.getReplyHandler(g2)); assertNull(rt.tryToRouteReply(g1, c1)); assertNull(rt.tryToRouteReply(g2, c3)); assertNull(rt.getReplyHandler(g1)); assertNull(rt.getReplyHandler(g2)); assertEquals(1, (getMap(rt, "_handlerMap")).size()); //g2 only assertEquals(1, (getMap(rt, "_idMap")).size()); //Test that _idMap/_handlerMap don't grow without bound. rt=new RouteTable(1000, Integer.MAX_VALUE); assertNotNull(rt.tryToRouteReply(g1, c1)); assertNotNull(rt.tryToRouteReply(g2, c1)); assertNotNull(rt.tryToRouteReply(g3, c1)); assertNotNull(rt.tryToRouteReply(g4, c1)); assertNull(rt.tryToRouteReply(g4, c1)); assertSame(c1, rt.getReplyHandler(g1)); assertSame(c1, rt.getReplyHandler(g2)); assertSame(c1, rt.getReplyHandler(g3)); assertSame(c1, rt.getReplyHandler(g4)); assertEquals(1, (getMap(rt, "_handlerMap")).size()); assertEquals(1, (getMap(rt, "_idMap")).size()); //3. Test reply counting logic. RouteTable.ReplyRoutePair rrp=null; rt=new RouteTable(MSECS/1000, Integer.MAX_VALUE); assertNotNull(rt.tryToRouteReply(g1, c1)); //g1 -> <c1, 0> rrp=rt.getReplyHandler(g1, 5, (short) 0); //g1 -> <c1, 0+5> assertSame(c1, rrp.getReplyHandler()); assertEquals(0, rrp.getBytesRouted()); rrp=rt.getReplyHandler(g1, 1, (short) 0); //g1 -> <c1, 5+1> assertSame(c1, rrp.getReplyHandler()); assertEquals(5, rrp.getBytesRouted()); rt.routeReply(g1, c2); //g1 -> <c2, 6> rrp=rt.getReplyHandler(g1, 2, (short) 0); //g1 -> <c2, 6+2> assertSame(c2, rrp.getReplyHandler()); assertEquals("Reply bytes", 6, rrp.getBytesRouted()); assertEquals(1, (getMap(rt, "_newMap")).size()); assertEquals(0, (getMap(rt, "_oldMap")).size()); try { Thread.sleep(MSECS); } catch (InterruptedException e) { } PrivilegedAccessor.invokeMethod(rt, "purge", null); assertEquals(0, (getMap(rt, "_newMap")).size()); assertEquals(1, (getMap(rt, "_oldMap")).size()); rrp=rt.getReplyHandler(g1, 3, (short) 0); //g1 -> <c2, 8+3> assertSame(c2, rrp.getReplyHandler()); assertEquals(8, rrp.getBytesRouted()); rt.routeReply(g1, c3); //g1 -> <c3, 11> assertEquals(1, (getMap(rt, "_newMap")).size()); assertEquals(0, (getMap(rt, "_oldMap")).size()); rrp=rt.getReplyHandler(g1, 10, (short) 0); //g1 -> <c3, 11+10> assertSame(c3, rrp.getReplyHandler()); assertEquals(11, rrp.getBytesRouted()); rt.removeReplyHandler(c3); assertNull(rt.getReplyHandler(g1,0, (short) 0)); } public void testTTLAdditions() { RouteTable rt=null; int MSECS=1000; rt=new RouteTable(MSECS/1000, Integer.MAX_VALUE); byte[] g1=new byte[16]; g1[0]=(byte)1; byte[] g2=new byte[16]; g2[0]=(byte)2; byte[] g3=new byte[16]; g3[0]=(byte)3; byte[] g4=new byte[16]; g4[0]=(byte)4; ReplyHandler c1=new ReplyHandlerStub(); ReplyHandler c2=new ReplyHandlerStub(); ReplyHandler c3=new ReplyHandlerStub(); ReplyHandler c4=new ReplyHandlerStub(); // test setTTL and getAndSetTTL rt.setTTL(rt.tryToRouteReply(g2, c2), (byte)2); rt.setTTL(rt.tryToRouteReply(g1, c1), (byte)3); try { rt.setTTL(null, (byte) 1); assertTrue(false); } catch (IllegalArgumentException expected) {} try { rt.setTTL(rt.tryToRouteReply(g3, c3), (byte) 0); assertTrue(false); } catch (IllegalArgumentException expected) {} try { rt.setTTL(new ResultCounterImpl(), (byte) 1); assertTrue(false); } catch (IllegalArgumentException expected) {} try { rt.getAndSetTTL(g3, (byte)0, (byte)2); assertTrue(false); } catch (IllegalArgumentException expected) {} try { rt.getAndSetTTL(g2, (byte)2, (byte)2); assertTrue(false); } catch (IllegalArgumentException expected) {} try { assertTrue(rt.getAndSetTTL(g1, (byte)3, (byte)4)); } catch (IllegalArgumentException expected) { assertTrue(false); } try { assertTrue(rt.getAndSetTTL(g1, (byte)4, (byte)5)); } catch (IllegalArgumentException expected) { assertTrue(false); } try { assertTrue(!rt.getAndSetTTL(g2, (byte)3, (byte)5)); } catch (IllegalArgumentException expected) { assertTrue(false); } } private Map getMap(RouteTable rt, String mapName) throws IllegalAccessException, NoSuchFieldException { return (Map) PrivilegedAccessor.getValue(rt, mapName); } private static final boolean debugOn = false; private static final void debug(Exception e) { if (debugOn) e.printStackTrace(); } private static final void debug(String out) { if (debugOn) System.out.println(out); } private static class ResultCounterImpl implements com.limegroup.gnutella.search.ResultCounter { public int getNumResults() { return 0; } } }