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 org.limewire.gnutella.tests.LimeTestCase; import org.limewire.gnutella.tests.LimeTestUtils; import org.limewire.util.PrivilegedAccessor; import com.google.inject.Injector; import com.limegroup.gnutella.messages.QueryRequest; import com.limegroup.gnutella.messages.QueryRequestFactory; import com.limegroup.gnutella.util.NewConnection; import com.limegroup.gnutella.util.TestConnection; import com.limegroup.gnutella.util.TestConnectionFactory; import com.limegroup.gnutella.util.TestResultCounter; /** * Tests the functionality of the <tt>QueryHandlerTest</tt> class. */ public final class ProbeQueryTest extends LimeTestCase { /** * Cached method for creating the probe lists. */ private static Method CREATE_PROBE_LISTS; private TestConnectionFactory testConnectionFactory; private QueryHandlerFactory queryHandlerFactory; private QueryRequestFactory queryRequestFactory; 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); } @Override protected void setUp() throws Exception { Injector injector = LimeTestUtils.createInjectorNonEagerly(); testConnectionFactory = injector.getInstance(TestConnectionFactory.class); queryHandlerFactory = injector.getInstance(QueryHandlerFactory.class); queryRequestFactory = injector.getInstance(QueryRequestFactory.class); } /** * 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 { Method m = PrivilegedAccessor.getMethod(ProbeQuery.class, "sendProbe", new Class[]{}); List<NewConnection> connections = new LinkedList<NewConnection>(); for(int i=0; i<15; i++) { connections.add(testConnectionFactory.createNewConnection(10)); } QueryHandler handler = queryHandlerFactory.createHandler(queryRequestFactory.createQuery("test"), testConnectionFactory.createNewConnection(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. */ @SuppressWarnings("unchecked") public void testCreateProbeListsForSomewhatPopular() throws Exception { List<TestConnection> connections = new LinkedList<TestConnection>(); connections.clear(); for(int i=0; i<20; i++) { connections.add(testConnectionFactory.createNewHitConnection()); } for(int i=0; i<5; i++) { connections.add(testConnectionFactory.createNewConnection()); } for(int i=0; i<5; i++) { connections.add(testConnectionFactory.createOldConnection(5)); } QueryRequest query = queryRequestFactory.createQuery("test"); List<List> queryLists = (List<List>)CREATE_PROBE_LISTS.invoke(null, new Object[]{connections, query}); assertTrue("should not be any ttl=2 queries", queryLists.get(1).isEmpty()); assertTrue("should not be too many ttl=1", queryLists.get(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. */ @SuppressWarnings("unchecked") public void testCreateProbeListsForPopularContent() throws Exception { List<TestConnection> connections = new LinkedList(); for(int i=0; i<15; i++) { connections.add(testConnectionFactory.createNewHitConnection()); } for(int i=0; i<15; i++) { connections.add(testConnectionFactory.createOldConnection(5)); } QueryRequest query = queryRequestFactory.createQuery("test"); List<List> queryLists = (List<List>)CREATE_PROBE_LISTS.invoke(null, new Object[]{connections, query}); assertTrue("should not be any ttl=2 queries", queryLists.get(1).isEmpty()); assertEquals("should not be only 1 ttl=1 query", queryLists.get(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<Integer> list1 = new LinkedList<Integer>(); List<Integer> list2 = new LinkedList<Integer>(); 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); List<Integer> testList = new LinkedList<Integer>(); 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); } }