package com.limegroup.gnutella.search; import java.lang.reflect.Method; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import junit.framework.Test; import com.limegroup.gnutella.RouterService; import com.limegroup.gnutella.messages.QueryRequest; import com.limegroup.gnutella.stubs.ActivityCallbackStub; import com.limegroup.gnutella.util.BaseTestCase; import com.limegroup.gnutella.util.NewConnection; import com.limegroup.gnutella.util.OldConnection; import com.limegroup.gnutella.util.PrivilegedAccessor; import com.limegroup.gnutella.util.TestConnection; import com.limegroup.gnutella.util.TestResultCounter; /** * Tests the functionality of the <tt>QueryHandlerTest</tt> class. */ public final class ProbeQueryTest extends BaseTestCase { /** * Cached method for creating the probe lists. */ private static Method CREATE_PROBE_LISTS; public ProbeQueryTest(String name) { super(name); } public static Test suite() { return buildTestSuite(ProbeQueryTest.class); } public static void main(String[] args) { junit.textui.TestRunner.run(suite()); } public static void globalSetUp() throws Exception { Class[] params = new Class[]{List.class, QueryRequest.class}; CREATE_PROBE_LISTS = PrivilegedAccessor.getMethod(ProbeQuery.class, "createProbeLists", params); } /** * Tests the method for sending a probe query to make sure it is sent to * the number of nodes we think it's sent to and to make sure it's sent * with the proper TTL. */ public void testSendProbe() throws Exception { RouterService rs = new RouterService(new ActivityCallbackStub()); assertNotNull("should have a message router", rs.getMessageRouter()); Method m = PrivilegedAccessor.getMethod(ProbeQuery.class, "sendProbe", new Class[]{}); List connections = new LinkedList(); for(int i=0; i<15; i++) { connections.add(NewConnection.createConnection(10)); } QueryHandler handler = QueryHandler.createHandler(QueryRequest.createQuery("test"), NewConnection.createConnection(8), new TestResultCounter(0)); ProbeQuery probe = new ProbeQuery(connections, handler); m.invoke(probe, new Object[]{}); int queriesSent = 0; int totalTTL = 0; Iterator iter = connections.iterator(); while(iter.hasNext()) { TestConnection tc = (TestConnection)iter.next(); queriesSent += tc.getNumQueries(); totalTTL += tc.getTotalTTL(); } assertEquals("should have only sent two queries", 3, queriesSent); assertEquals("should have sent 2 queries with TTL=2", 6, totalTTL); } /** * Test to make sure that the utility method for creating * our probe query lists is working as we expect it to. */ public void testCreateProbeListsForSomewhatPopular() throws Exception { List connections = new LinkedList(); connections.clear(); for(int i=0; i<20; i++) { connections.add(NewConnection.createHitConnection()); } for(int i=0; i<5; i++) { connections.add(NewConnection.createConnection()); } for(int i=0; i<5; i++) { connections.add(new OldConnection(5)); } QueryRequest query = QueryRequest.createQuery("test"); List[] queryLists = (List[])CREATE_PROBE_LISTS.invoke(null, new Object[]{connections, query}); System.out.println("TTL=1: "+queryLists[0].size()); System.out.println("TTL=2: "+queryLists[1].size()); assertTrue("should not be any ttl=2 queries", queryLists[1].isEmpty()); assertTrue("should not be too many ttl=1", queryLists[0].size() < 15); } /** * Test to make sure that the utility method for creating * our probe query lists is working as we expect it to when * the content we're searching for is very popular. */ public void testCreateProbeListsForPopularContent() throws Exception { List connections = new LinkedList(); for(int i=0; i<15; i++) { connections.add(NewConnection.createHitConnection()); } for(int i=0; i<15; i++) { connections.add(new OldConnection(5)); } QueryRequest query = QueryRequest.createQuery("test"); List[] queryLists = (List[])CREATE_PROBE_LISTS.invoke(null, new Object[]{connections, query}); assertTrue("should not be any ttl=2 queries", queryLists[1].isEmpty()); assertEquals("should not be only 1 ttl=1 query", queryLists[0].size(), 1); } /** * Tests the <tt>QueryHandler</tt> utility method that takes * two lists and puts the desired number of elements in a * third list, prioritizing elements from one list over the * other. */ public void testAddToList() throws Exception { Class[] paramTypes = new Class[]{List.class, List.class, List.class, Integer.TYPE}; Method m = PrivilegedAccessor.getMethod(ProbeQuery.class, "addToList", paramTypes); List listToAddTo = new LinkedList(); List list1 = new LinkedList(); List list2 = new LinkedList(); Integer numElements = new Integer(3); Object[] params = new Object[] {listToAddTo, list1, list2, numElements}; Integer one = new Integer(1); Integer two = new Integer(2); Integer three = new Integer(3); Integer four = new Integer(4); Integer five = new Integer(5); Integer six = new Integer(6); Integer seven = new Integer(7); List testList = new LinkedList(); testList.add(one); testList.add(two); testList.add(three); list1.add(one); list1.add(two); list1.add(three); m.invoke(null, params); assertEquals("lists should be equal", testList, listToAddTo); list1.clear(); list2.clear(); listToAddTo.clear(); list2.add(one); list2.add(two); list2.add(three); m.invoke(null, params); assertEquals("lists should be equal", testList, listToAddTo); list1.clear(); list2.clear(); listToAddTo.clear(); list1.add(one); list2.add(two); list2.add(three); m.invoke(null, params); assertEquals("lists should be equal", testList, listToAddTo); list1.clear(); list2.clear(); listToAddTo.clear(); list1.add(one); list1.add(two); list2.add(three); list2.add(four); m.invoke(null, params); assertEquals("lists should be equal", testList, listToAddTo); } }