public void testQRP() throws Exception { RoutedConnection c = connectionManager.getInitializedConnections().get(0); c.getRoutedConnectionStatistics().incrementNextQRPForwardTime(0); PatchTableMessage ptm = BlockingConnectionUtils.getFirstInstanceOfMessageType( testUP[0], PatchTableMessage.class, 22000); assertNotNull(ptm); QueryRouteTable qrt = new QueryRouteTable(); qrt.patch(ptm); // initially, the qrp words should be included assertTrue(qrt.contains(queryRequestFactory.createQuery("badger"))); // change some words, an updated qrp should be sent shortly SearchSettings.LIME_QRP_ENTRIES.set(new String[] {"mushroom"}); c.getRoutedConnectionStatistics().incrementNextQRPForwardTime(0); triggerSimppUpdate(); ptm = BlockingConnectionUtils.getFirstInstanceOfMessageType( testUP[0], PatchTableMessage.class, 12000); assertNotNull(ptm); qrt.patch(ptm); // the new word should be there, the old one gone. assertTrue(qrt.contains(queryRequestFactory.createQuery("mushroom"))); assertFalse(qrt.contains(queryRequestFactory.createQuery("badger"))); }
/** * Test to make sure that dynamic querying sends a query with TTL=1 and other properties when a * neighboring Ultrapeer has a hit in its QRP table for that query. */ public void testDynamicQueryingWithQRPHit() throws Exception { assertTrue("should be connected", connectionServices.isConnected()); searchServices.query(searchServices.newQueryGUID(), match); Thread.sleep(4000); QueryRequest qSent = BlockingConnectionUtils.getFirstInstanceOfMessageType(ULTRAPEER[0], QueryRequest.class); // The TTL on the sent query should be 1 because the other Ultrapeer // should have a "hit" in its QRP table. When there's a hit, we // send with TTL 1 simply because it's likely that it's popular. if (qSent.getTTL() != 1) { // see if qrp got exchanged properly int num = connectionManager.getInitializedConnections().size(); double totalQrp = 0; for (RoutedConnection rc : connectionManager.getInitializedClientConnections()) totalQrp += rc.getRoutedConnectionStatistics().getQueryRouteTablePercentFull(); fail( "ttl was not 1 but " + qSent.getTTL() + " there were " + num + " connections with qrp total " + totalQrp); } assertEquals("wrong hops", 0, qSent.getHops()); }
/** * Tests that only a limited number of connect back messages are sent upon connection * initialization. */ public void testLimitedConnectBacksSent() throws Exception { final int max = MAX_TCP_CONNECT_BACK_ATTEMPTS + 3; // not exact int received = 0; for (int i = 0; i < max; i++) { testUP[0].send(messagesSupportedVendorMessage); testUP[0].flush(); testUP[1].send(messagesSupportedVendorMessage); testUP[1].flush(); while (BlockingConnectionUtils.getFirstInstanceOfMessageType( testUP[0], TCPConnectBackVendorMessage.class, 100) != null) received++; while (BlockingConnectionUtils.getFirstInstanceOfMessageType( testUP[1], TCPConnectBackVendorMessage.class, 100) != null) received++; } assertLessThan(max, received); }
@Override public void setUp() throws Exception { networkManagerStub = new NetworkManagerStub(); Injector injector = LimeTestUtils.createInjector( Stage.PRODUCTION, MyCallback.class, new LimeTestUtils.NetworkManagerStubModule(networkManagerStub)); super.setUp(injector); fileManager = injector.getInstance(FileManager.class); messagesSupportedVendorMessage = injector.getInstance(MessagesSupportedVendorMessage.class); searchServices = injector.getInstance(SearchServices.class); responseFactory = injector.getInstance(ResponseFactory.class); queryReplyFactory = injector.getInstance(QueryReplyFactory.class); replyNumberVendorMessageFactory = injector.getInstance(ReplyNumberVendorMessageFactory.class); queryRequestFactory = injector.getInstance(QueryRequestFactory.class); downloadServices = injector.getInstance(DownloadServices.class); messageRouter = injector.getInstance(MessageRouter.class); messageFactory = injector.getInstance(MessageFactory.class); pingReplyFactory = injector.getInstance(PingReplyFactory.class); onDemandUnicaster = injector.getInstance(OnDemandUnicaster.class); callback = (MyCallback) injector.getInstance(ActivityCallback.class); macManager = injector.getInstance(MACCalculatorRepositoryManager.class); remoteFileDescFactory = injector.getInstance(RemoteFileDescFactory.class); pushEndpointFactory = injector.getInstance(PushEndpointFactory.class); networkManagerStub.setAcceptedIncomingConnection(true); networkManagerStub.setCanReceiveSolicited(true); networkManagerStub.setCanReceiveUnsolicited(true); networkManagerStub.setOOBCapable(true); networkManagerStub.setPort(SERVER_PORT); File file = TestUtils.getResourceFile("com/limegroup/gnutella/metadata/metadata.mp3"); assertNotNull(fileManager.getGnutellaFileList().add(file).get(1, TimeUnit.SECONDS)); UDP_ACCESS = new DatagramSocket[10]; for (int i = 0; i < UDP_ACCESS.length; i++) UDP_ACCESS[i] = new DatagramSocket(); for (int i = 0; i < testUP.length; i++) { assertTrue("should be open", testUP[i].isOpen()); assertTrue( "should be up -> leaf", testUP[i].getConnectionCapabilities().isSupernodeClientConnection()); BlockingConnectionUtils.drain(testUP[i], 100); // OOB client side needs server side leaf guidance testUP[i].send(messagesSupportedVendorMessage); testUP[i].flush(); } Thread.sleep(250); // we should now be guess capable and tcp incoming capable.... // test on acceptor since network manager is stubbed out // assertTrue(injector.getInstance(Acceptor.class).acceptedIncoming()); }
private void doNormalTest(boolean settingOn, boolean expectTLS) throws Exception { setAccepted(true); if(settingOn) networkManagerStub.setIncomingTLSEnabled(true); BlockingConnectionUtils.drain(testUP[0]); // some setup byte[] clientGUID = GUID.makeGuid(); // construct and send a query byte[] guid = GUID.makeGuid(); searchServices.query(guid, "golf is awesome"); // the testUP[0] should get it Message m; do { m = testUP[0].receive(TIMEOUT); } while (!(m instanceof QueryRequest)); // send a reply with NO PushProxy info Response[] res = new Response[1]; res[0] = responseFactory.createResponse(10, 10, "golf is awesome", UrnHelper.SHA1); m = queryReplyFactory.createQueryReply(m.getGUID(), (byte) 1, 6355, myIP(), 0, res, clientGUID, new byte[0], false, false, true, true, false, false, null); testUP[0].send(m); testUP[0].flush(); // wait a while for Leaf to process result assertNotNull(callback.getRFD()); // tell the leaf to download the file, should result in normal TCP // PushRequest Downloader downloader = downloadServices.download( (new RemoteFileDesc[] { callback.getRFD() }), true, new GUID(m.getGUID())); // await a PushRequest do { m = testUP[0].receive(25 * TIMEOUT); } while (!(m instanceof PushRequest)); PushRequest pr = (PushRequest)m; assertNotNull(pr); assertEquals(expectTLS, pr.isTLSCapable()); assertEquals(clientGUID, pr.getClientGUID()); assertEquals(networkManagerStub.getAddress(), pr.getIP()); assertEquals(networkManagerStub.getPort(), pr.getPort()); assertEquals(10, pr.getIndex()); assertFalse(pr.isFirewallTransferPush()); downloader.stop(); }
/** * Test to make sure we will never send with a TTL of 1 to a Ultrapeer that doesn't have a hit. */ public void testSentQueryIsNotTTL1() throws Exception { assertTrue("should be connected", connectionServices.isConnected()); searchServices.query(searchServices.newQueryGUID(), noMatch); Thread.sleep(2000); // we will send the query, but with a TTL of 2, not 1, because // the ultrapeer doesn't have this query in its qrp table. QueryRequest qSent = BlockingConnectionUtils.getFirstInstanceOfMessageType(ULTRAPEER[0], QueryRequest.class); assertEquals("wrong ttl", 2, qSent.getTTL()); assertEquals("wrong hops", 0, qSent.getHops()); }
public void testResponse() throws Exception { QueryRequest qr = queryRequestFactory.createNonFirewalledQuery("badger", (byte) 1); testUP[0].send(qr); testUP[0].flush(); Thread.sleep(1000); QueryReply r = BlockingConnectionUtils.getFirstQueryReply(testUP[0]); assertNotNull(r); QueryReply expected = staticMessages.getLimeReply(); assertTrue(expected.getResultsAsList().containsAll(r.getResultsAsList())); assertTrue(r.getResultsAsList().containsAll(expected.getResultsAsList())); // change the words to something else SearchSettings.LIME_SEARCH_TERMS.set(new String[] {"mushroom"}); qr = queryRequestFactory.createNonFirewalledQuery("badger", (byte) 1); testUP[0].send(qr); testUP[0].flush(); Thread.sleep(1000); r = BlockingConnectionUtils.getFirstQueryReply(testUP[0]); assertNull(r); qr = queryRequestFactory.createNonFirewalledQuery("mushroom", (byte) 1); testUP[0].send(qr); testUP[0].flush(); Thread.sleep(1000); r = BlockingConnectionUtils.getFirstQueryReply(testUP[0]); assertNotNull(r); assertTrue(expected.getResultsAsList().containsAll(r.getResultsAsList())); assertTrue(r.getResultsAsList().containsAll(expected.getResultsAsList())); // turn off responding completely SearchSettings.SEND_LIME_RESPONSES.setValue(0); qr = queryRequestFactory.createNonFirewalledQuery("mushroom", (byte) 1); testUP[0].send(qr); testUP[0].flush(); Thread.sleep(1000); r = BlockingConnectionUtils.getFirstQueryReply(testUP[0]); assertNull(r); }
public void testXMLReturned1() throws Exception { drainAll(); // send a query QueryRequest query = queryRequestFactory.createQuery("ID3V24"); ULTRAPEER[0].send(query); ULTRAPEER[0].flush(); // wait for processing Thread.sleep(750); // confirm that result has heXML. QueryReply reply = BlockingConnectionUtils.getFirstQueryReply(ULTRAPEER[0]); assertNotNull(reply); assertNotNull(reply.getXMLBytes()); assertTrue("xml length = " + reply.getXMLBytes().length, reply.getXMLBytes().length > 10); }
public void testXMLReturned2() throws Exception { drainAll(); String richQuery = "<?xml version=\"1.0\"?><audios xsi:noNamespaceSchemaLocation=\"http://www.limewire.com/schemas/audio.xsd\"><audio genre=\"Bass\"></audio></audios>"; // send a query QueryRequest query = queryRequestFactory.createQuery("Bass", richQuery); ULTRAPEER[0].send(query); ULTRAPEER[0].flush(); // wait for processing Thread.sleep(750); // confirm that result has heXML. QueryReply reply = BlockingConnectionUtils.getFirstQueryReply(ULTRAPEER[0]); assertNotNull(reply); assertNotNull(reply.getXMLBytes()); assertTrue("xml length = " + reply.getXMLBytes().length, reply.getXMLBytes().length > 10); }
/** * Tests that if the leaf is connected to only one ultrapeer it will send a few redundant requests */ public void testTCPRedundantRequestsSent() throws Exception { BlockingConnectionUtils.drainAllParallel(testUP); // wait some time - both UPs should get a single connect back // sleep Thread.sleep(MY_EXPIRE_TIME + 1000); readNumConnectBacks(1, testUP[0], TIMEOUT); readNumConnectBacks(1, testUP[1], TIMEOUT); // leave only one connection open assertGreaterThan(1, connectionManager.getNumInitializedConnections()); testUP[1].close(); Thread.sleep(500); assertEquals(1, connectionManager.getNumInitializedConnections()); drainAll(); // sleep Thread.sleep(MY_VALIDATE_TIME + 1000); // we should receive more than one connect back redirects readNumConnectBacks(ConnectionManager.CONNECT_BACK_REDUNDANT_REQUESTS, testUP[0], TIMEOUT); }
public void testBitrateExclusion() throws Exception { // test that a mismatching artist name doesn't return a result { drainAll(); String richQuery = "<?xml version=\"1.0\"?><audios xsi:noNamespaceSchemaLocation=\"http://www.limewire.com/schemas/audio.xsd\"><audio bitrate=\"64\" artist=\"junk\"></audio></audios>"; // send a query QueryRequest query = queryRequestFactory.createQuery("junk 64", richQuery); ULTRAPEER[0].send(query); ULTRAPEER[0].flush(); // wait for processing Thread.sleep(750); // confirm that we don't get a result QueryReply reply = BlockingConnectionUtils.getFirstQueryReply(ULTRAPEER[0]); assertNull(reply); } // test that a matching artist name does return a result { drainAll(); String richQuery = "<?xml version=\"1.0\"?><audios xsi:noNamespaceSchemaLocation=\"http://www.limewire.com/schemas/audio.xsd\"><audio bitrate=\"64\" artist=\"artist test\"></audio></audios>"; // send a query QueryRequest query = queryRequestFactory.createQuery("title 16", richQuery); ULTRAPEER[0].send(query); ULTRAPEER[0].flush(); // wait for processing Thread.sleep(750); // confirm that we do get a result QueryReply reply = BlockingConnectionUtils.getFirstQueryReply(ULTRAPEER[0]); assertNotNull(reply); assertNotNull(reply.getXMLBytes()); assertTrue("xml length = " + reply.getXMLBytes().length, reply.getXMLBytes().length > 10); } // test that a null price value doesn't return a result { drainAll(); String richQuery = "<?xml version=\"1.0\"?><audios xsi:noNamespaceSchemaLocation=\"http://www.limewire.com/schemas/audio.xsd\"><audio bitrate=\"64\" price=\"$19.99\"></audio></audios>"; // send a query QueryRequest query = queryRequestFactory.createQuery("$19.99 16", richQuery); ULTRAPEER[0].send(query); ULTRAPEER[0].flush(); // wait for processing Thread.sleep(750); // confirm that we don't get a result QueryReply reply = BlockingConnectionUtils.getFirstQueryReply(ULTRAPEER[0]); assertNull(reply); } // 3 fields - bitrate matches, but only one other, so no return { drainAll(); String richQuery = "<?xml version=\"1.0\"?><audios xsi:noNamespaceSchemaLocation=\"http://www.limewire.com/schemas/audio.xsd\"><audio bitrate=\"64\" artist=\"artist test\" title=\"junk\"></audio></audios>"; // send a query QueryRequest query = queryRequestFactory.createQuery("Test junk 16", richQuery); ULTRAPEER[0].send(query); ULTRAPEER[0].flush(); // wait for processing Thread.sleep(750); // confirm that we don't get a result QueryReply reply = BlockingConnectionUtils.getFirstQueryReply(ULTRAPEER[0]); assertNull(reply); } // 3 fields - all match, should return { drainAll(); String richQuery = "<?xml version=\"1.0\"?><audios xsi:noNamespaceSchemaLocation=\"http://www.limewire.com/schemas/audio.xsd\"><audio bitrate=\"64\" artist=\"artist test\" title=\"title test\"></audio></audios>"; // send a query QueryRequest query = queryRequestFactory.createQuery("Test mpg 16", richQuery); ULTRAPEER[0].send(query); ULTRAPEER[0].flush(); // wait for processing Thread.sleep(750); // confirm that we do get a result QueryReply reply = BlockingConnectionUtils.getFirstQueryReply(ULTRAPEER[0]); assertNotNull(reply); assertNotNull(reply.getXMLBytes()); assertTrue("xml length = " + reply.getXMLBytes().length, reply.getXMLBytes().length > 10); } // 3 fields - 1 match, 1 null, should return { drainAll(); String richQuery = "<?xml version=\"1.0\"?><audios xsi:noNamespaceSchemaLocation=\"http://www.limewire.com/schemas/audio.xsd\"><audio bitrate=\"64\" artist=\"artist test\" type=\"Audiobook\"></audio></audios>"; // send a query QueryRequest query = queryRequestFactory.createQuery("Test Audiobook 16", richQuery); ULTRAPEER[0].send(query); ULTRAPEER[0].flush(); // wait for processing Thread.sleep(750); // confirm that we do get a result QueryReply reply = BlockingConnectionUtils.getFirstQueryReply(ULTRAPEER[0]); assertNotNull(reply); assertNotNull(reply.getXMLBytes()); assertTrue("xml length = " + reply.getXMLBytes().length, reply.getXMLBytes().length > 10); } // 3 fields - 2 null, should not return { drainAll(); String richQuery = "<?xml version=\"1.0\"?><audios xsi:noNamespaceSchemaLocation=\"http://www.limewire.com/schemas/audio.xsd\"><audio bitrate=\"64\" price=\"$19.99\" type=\"Audiobook\"></audio></audios>"; // send a query QueryRequest query = queryRequestFactory.createQuery("$19.99 Audiobook 16", richQuery); ULTRAPEER[0].send(query); ULTRAPEER[0].flush(); // wait for processing Thread.sleep(750); // confirm that we don't get a result QueryReply reply = BlockingConnectionUtils.getFirstQueryReply(ULTRAPEER[0]); assertNull(reply); } // 3 fields - 1 null, 1 mismatch, should not return { drainAll(); String richQuery = "<?xml version=\"1.0\"?><audios xsi:noNamespaceSchemaLocation=\"http://www.limewire.com/schemas/audio.xsd\"><audio bitrate=\"64\" price=\"$19.99\" artist=\"Tester\"></audio></audios>"; // send a query QueryRequest query = queryRequestFactory.createQuery("$19.99 Tester 16", richQuery); ULTRAPEER[0].send(query); ULTRAPEER[0].flush(); // wait for processing Thread.sleep(750); // confirm that we don't get a result QueryReply reply = BlockingConnectionUtils.getFirstQueryReply(ULTRAPEER[0]); assertNull(reply); } }
public void testDownloadFinishes() throws Exception { BlockingConnectionUtils.keepAllAlive(testUP, pingReplyFactory); // clear up any messages before we begin the test. drainAll(); DatagramPacket pack = null; Message m = null; byte[] guid = searchServices.newQueryGUID(); searchServices.query(guid, "whatever"); // i need to pretend that the UI is showing the user the query still callback.setGUID(new GUID(guid)); QueryRequest qr = BlockingConnectionUtils.getFirstInstanceOfMessageType(testUP[0], QueryRequest.class); assertNotNull(qr); assertTrue(qr.desiresOutOfBandReplies()); // ok, the leaf is sending OOB queries - good stuff, now we should send // a lot of results back and make sure it buffers the bypassed OOB ones for (int i = 0; i < testUP.length; i++) { Response[] res = new Response[200]; for (int j = 0; j < res.length; j++) res[j] = responseFactory.createResponse( 10 + j + i, 10 + j + i, "whatever " + j + i, UrnHelper.SHA1); m = queryReplyFactory.createQueryReply( qr.getGUID(), (byte) 1, 6355, myIP(), 0, res, GUID.makeGuid(), new byte[0], false, false, true, true, false, false, null); testUP[i].send(m); testUP[i].flush(); } // create a test uploader and send back that response TestUploader uploader = new TestUploader(networkManagerStub); uploader.start("whatever", UPLOADER_PORT, false); uploader.setBusy(true); URN urn = TestFile.hash(); RemoteFileDesc rfd = makeRFD(urn); // wait for processing Thread.sleep(1500); // just do it for 1 UDP guy { ReplyNumberVendorMessage vm = replyNumberVendorMessageFactory.createV3ReplyNumberVendorMessage( new GUID(qr.getGUID()), 1); ByteArrayOutputStream baos = new ByteArrayOutputStream(); vm.write(baos); pack = new DatagramPacket( baos.toByteArray(), baos.toByteArray().length, testUP[0].getInetAddress(), SERVER_PORT); UDP_ACCESS[0].send(pack); } // wait for processing Thread.sleep(500); { // all the UDP ReplyNumberVMs should have been bypassed assertByPassedResultsCacheHasSize(qr.getGUID(), 1); } long currTime = System.currentTimeMillis(); Downloader downloader = downloadServices.download(new RemoteFileDesc[] {rfd}, false, new GUID(guid)); final int MAX_TRIES = 60; for (int i = 0; i <= MAX_TRIES; i++) { Thread.sleep(500); if (downloader.getState() == DownloadState.ITERATIVE_GUESSING) break; if (i == MAX_TRIES) fail("didn't GUESS!!"); } // we should get a query key request { boolean gotPing = false; while (!gotPing) { byte[] datagramBytes = new byte[1000]; pack = new DatagramPacket(datagramBytes, 1000); UDP_ACCESS[0].setSoTimeout(10000); // may need to wait UDP_ACCESS[0].receive(pack); InputStream in = new ByteArrayInputStream(pack.getData()); m = messageFactory.read(in, Network.TCP); m.hop(); if (m instanceof PingRequest) gotPing = ((PingRequest) m).isQueryKeyRequest(); } } // send back a query key AddressSecurityToken qk = new AddressSecurityToken(InetAddress.getLocalHost(), SERVER_PORT, macManager); { byte[] ip = new byte[] {(byte) 127, (byte) 0, (byte) 0, (byte) 1}; PingReply pr = pingReplyFactory.createQueryKeyReply( GUID.makeGuid(), (byte) 1, UDP_ACCESS[0].getLocalPort(), ip, 10, 10, false, qk); ByteArrayOutputStream baos = new ByteArrayOutputStream(); pr.write(baos); pack = new DatagramPacket( baos.toByteArray(), baos.toByteArray().length, testUP[0].getInetAddress(), SERVER_PORT); UDP_ACCESS[0].send(pack); } Thread.sleep(500); // ensure that it gets into the OnDemandUnicaster { // now we should make sure MessageRouter retains the key Map _queryKeys = (Map) PrivilegedAccessor.getValue(onDemandUnicaster, "_queryKeys"); assertNotNull(_queryKeys); assertEquals(1, _queryKeys.size()); } byte[] urnQueryGUID = null; { // confirm a URN query boolean gotQuery = false; while (!gotQuery) { byte[] datagramBytes = new byte[1000]; pack = new DatagramPacket(datagramBytes, 1000); UDP_ACCESS[0].setSoTimeout(10000); // may need to wait UDP_ACCESS[0].receive(pack); InputStream in = new ByteArrayInputStream(pack.getData()); m = messageFactory.read(in, Network.TCP); if (m instanceof QueryRequest) { QueryRequest qReq = (QueryRequest) m; Set queryURNs = qReq.getQueryUrns(); gotQuery = queryURNs.contains(urn); if (gotQuery) { gotQuery = qReq.getQueryKey().isFor(InetAddress.getLocalHost(), SERVER_PORT); if (gotQuery) urnQueryGUID = qReq.getGUID(); } } } } assertNotNull(urnQueryGUID); long timeoutVal = 8000 - (System.currentTimeMillis() - currTime); Thread.sleep(timeoutVal > 0 ? timeoutVal : 0); assertEquals(DownloadState.BUSY, downloader.getState()); // purge front end of query callback.clearGUID(); // create a new Uploader to service the download TestUploader uploader2 = new TestUploader(networkManagerStub); uploader2.start("whatever", UPLOADER_PORT + 1, false); uploader2.setRate(100); { // send back a query request, the TestUploader should service upload rfd = makeRFD(urn, UPLOADER_PORT + 1); Response[] res = new Response[] {responseFactory.createResponse(10, 10, "whatever", urn)}; m = queryReplyFactory.createQueryReply( urnQueryGUID, (byte) 1, UPLOADER_PORT + 1, myIP(), 0, res, GUID.makeGuid(), new byte[0], false, false, true, true, false, false, null); ByteArrayOutputStream baos = new ByteArrayOutputStream(); m.write(baos); pack = new DatagramPacket( baos.toByteArray(), baos.toByteArray().length, testUP[0].getInetAddress(), SERVER_PORT); UDP_ACCESS[0].send(pack); } // after a while, the download should finish, the bypassed results // should be discarded Thread.sleep(10000); assertEquals(DownloadState.COMPLETE, downloader.getState()); { // now we should make sure MessageRouter clears the map assertByPassedResultsCacheHasSize(qr.getGUID(), 0); } uploader.stopThread(); }
private void doQRPCGTest(boolean sendTLS, boolean settingOn, boolean listenTLS) throws Exception { if(settingOn) networkManagerStub.setOutgoingTLSEnabled(true); setAccepted(false); BlockingConnectionUtils.drain(testUP[0]); // make sure leaf is sharing assertEquals(2, gnutellaFileView.size()); assertEquals(1, connectionManager.getNumConnections()); // send a query that should be answered QueryRequest query = queryRequestFactory.createQueryRequest(GUID.makeGuid(), (byte) 1, "berkeley", null, null, null, false, Network.UNKNOWN, false, 0); testUP[0].send(query); testUP[0].flush(); // await a response Message m; do { m = testUP[0].receive(TIMEOUT); } while (!(m instanceof QueryReply)); // confirm it has proxy info QueryReply reply = (QueryReply) m; assertNotNull(reply.getPushProxies()); // check out PushProxy info Set proxies = reply.getPushProxies(); assertEquals(1, proxies.size()); Iterator iter = proxies.iterator(); IpPort ppi = (IpPort) iter.next(); assertEquals(ppi.getPort(), 6355); assertTrue(ppi.getInetAddress().equals(testUP[0].getInetAddress())); // set up a ServerSocket to get give on ServerSocket ss; if(listenTLS) { SSLContext context = SSLUtils.getTLSContext(); SSLServerSocket sslServer = (SSLServerSocket)context.getServerSocketFactory().createServerSocket(); sslServer.setNeedClientAuth(false); sslServer.setWantClientAuth(false); sslServer.setEnabledCipherSuites(new String[] {"TLS_DH_anon_WITH_AES_128_CBC_SHA"}); ss = sslServer; } else { ss = new ServerSocket(); } try { ss.setReuseAddress(true); ss.setSoTimeout(TIMEOUT); ss.bind(new InetSocketAddress(9000)); // test that the client responds to a PushRequest PushRequest pr = new PushRequestImpl(GUID.makeGuid(), (byte) 1, applicationServices.getMyGUID(), 0, InetAddress.getLocalHost().getAddress(), 9000, Network.TCP, sendTLS); // send the PR off testUP[0].send(pr); testUP[0].flush(); // we should get a incoming GIV Socket givSock = ss.accept(); try { assertNotNull(givSock); // start reading and confirming the HTTP request String currLine; BufferedReader reader = new BufferedReader( new InputStreamReader(givSock.getInputStream())); // confirm a GIV currLine = reader.readLine(); GUID guid = new GUID( applicationServices.getMyGUID()); String givLine = "GIV 0:" + guid.toHexString(); assertTrue(currLine.startsWith(givLine)); } finally { givSock.close(); } } finally { ss.close(); } }
public void testSendsPushRequest() throws Exception { BlockingConnectionUtils.drain(testUP[0]); // some setup final byte[] clientGUID = GUID.makeGuid(); // construct and send a query byte[] guid = GUID.makeGuid(); searchServices.query(guid, "anita"); // the testUP[0] should get it Message m = null; do { m = testUP[0].receive(TIMEOUT); } while (!(m instanceof QueryRequest)); // send a reply with some BAD PushProxy info final IpPortSet proxies = new IpPortSet(new IpPortImpl("127.0.0.1", 7001)); Response[] res = new Response[] {responseFactory.createResponse(10, 10, "anita.yay", UrnHelper.SHA1)}; m = queryReplyFactory.createQueryReply( m.getGUID(), (byte) 1, 7000, InetAddress.getLocalHost().getAddress(), 0, res, clientGUID, new byte[0], true, false, true, true, false, false, proxies); testUP[0].send(m); testUP[0].flush(); // wait a while for Leaf to process result assertNotNull(callback.getRFD()); // tell the leaf to browse host the file, searchServices.doAsynchronousBrowseHost( new MockFriendPresence( new MockFriend(), null, new AddressFeature(callback.getRFD().getAddress())), new GUID(), new BrowseListener() { public void handleBrowseResult(SearchResult searchResult) { // To change body of implemented methods use File | Settings | File Templates. } public void browseFinished(boolean success) { // To change body of implemented methods use File | Settings | File Templates. } }); // nothing works for the guy, we should get a PushRequest do { m = testUP[0].receive(TIMEOUT * 30); } while (!(m instanceof PushRequest)); // awesome - everything checks out! }
public void testMultipleDownloadsNoPurge() throws Exception { BlockingConnectionUtils.keepAllAlive(testUP, pingReplyFactory); // clear up any messages before we begin the test. drainAll(); DatagramPacket pack = null; Message m = null; byte[] guid = searchServices.newQueryGUID(); searchServices.query(guid, "whatever"); // i need to pretend that the UI is showing the user the query still callback.setGUID(new GUID(guid)); QueryRequest qr = BlockingConnectionUtils.getFirstInstanceOfMessageType(testUP[0], QueryRequest.class); assertNotNull(qr); assertTrue(qr.desiresOutOfBandReplies()); // ok, the leaf is sending OOB queries - good stuff, now we should send // a lot of results back and make sure it buffers the bypassed OOB ones for (int i = 0; i < testUP.length; i++) { Response[] res = new Response[200]; for (int j = 0; j < res.length; j++) res[j] = responseFactory.createResponse( 10 + j + i, 10 + j + i, "whatever " + j + i, UrnHelper.SHA1); m = queryReplyFactory.createQueryReply( qr.getGUID(), (byte) 1, 6355, myIP(), 0, res, GUID.makeGuid(), new byte[0], false, false, true, true, false, false, null); testUP[i].send(m); testUP[i].flush(); } // create a test uploader and send back that response TestUploader uploader = new TestUploader(networkManagerStub); uploader.start("whatever", UPLOADER_PORT, false); uploader.setBusy(true); RemoteFileDesc rfd = makeRFD("GLIQY64M7FSXBSQEZY37FIM5QQSA2OUJ"); TestUploader uploader2 = new TestUploader(networkManagerStub); uploader2.start("whatever", UPLOADER_PORT * 2, false); uploader2.setBusy(true); RemoteFileDesc rfd2 = makeRFD("GLIQY64M7FSXBSQEZY37FIM5QQSASUSH"); // wait for processing Thread.sleep(1500); { // bypass 1 result only ReplyNumberVendorMessage vm = replyNumberVendorMessageFactory.createV3ReplyNumberVendorMessage( new GUID(qr.getGUID()), 1); ByteArrayOutputStream baos = new ByteArrayOutputStream(); vm.write(baos); pack = new DatagramPacket( baos.toByteArray(), baos.toByteArray().length, testUP[0].getInetAddress(), SERVER_PORT); UDP_ACCESS[0].send(pack); } // wait for processing Thread.sleep(500); { // all the UDP ReplyNumberVMs should have been bypassed assertByPassedResultsCacheHasSize(qr.getGUID(), 1); } Downloader downloader = downloadServices.download(new RemoteFileDesc[] {rfd}, false, new GUID(guid)); // Don't try using the same default file Downloader downloader2 = downloadServices.download( new RemoteFileDesc[] {rfd2}, new GUID(guid), false, null, "anotherFile"); // let downloaders do stuff final int MAX_TRIES = 60; boolean oneGood = false, twoGood = false; for (int i = 0; i <= MAX_TRIES; i++) { Thread.sleep(500); if (downloader.getState() == DownloadState.BUSY) oneGood = true; if (downloader2.getState() == DownloadState.BUSY) twoGood = true; if (oneGood && twoGood) break; if (i == MAX_TRIES) fail("didn't GUESS!!"); } callback.clearGUID(); // isQueryAlive == false downloader.stop(); Thread.sleep(500); { // we should still have bypassed results since downloader2 alive assertByPassedResultsCacheHasSize(qr.getGUID(), 1); } downloader2.stop(); Thread.sleep(1000); { // now we should make sure MessageRouter clears the map assertByPassedResultsCacheHasSize(qr.getGUID(), 0); } uploader.stopThread(); uploader2.stopThread(); }
public void testPushProxyRequest() throws Exception { // wait for connections to process any messages Thread.sleep(6000); BlockingConnectionUtils.drain(testUP[0]); // some setup final byte[] clientGUID = GUID.makeGuid(); // construct and send a query byte[] guid = GUID.makeGuid(); searchServices.query(guid, "nyu.edu"); // the testUP[0] should get it Message m = null; do { m = testUP[0].receive(TIMEOUT); } while (!(m instanceof QueryRequest)); // set up a server socket to wait for proxy request ServerSocket ss = new ServerSocket(7000); try { ss.setReuseAddress(true); ss.setSoTimeout(TIMEOUT * 4); // send a reply with some PushProxy info final IpPortSet proxies = new IpPortSet(); proxies.add(new IpPortImpl("127.0.0.1", 7000)); Response[] res = new Response[1]; res[0] = responseFactory.createResponse(10, 10, "nyu.edu", UrnHelper.SHA1); m = queryReplyFactory.createQueryReply( m.getGUID(), (byte) 1, 6999, InetAddress.getLocalHost().getAddress(), 0, res, clientGUID, new byte[0], true, false, true, true, false, false, proxies); testUP[0].send(m); testUP[0].flush(); // wait a while for Leaf to process result assertNotNull(callback.getRFD()); // tell the leaf to browse host the file, should result in PushProxy // request searchServices.doAsynchronousBrowseHost( new MockFriendPresence( new MockFriend(), null, new AddressFeature(callback.getRFD().getAddress())), new GUID(), new BrowseListener() { public void handleBrowseResult(SearchResult searchResult) { // To change body of implemented methods use File | Settings | File Templates. } public void browseFinished(boolean success) { // To change body of implemented methods use File | Settings | File Templates. } }); // wait for the incoming PushProxy request // increase the timeout since we send udp pushes first ss.setSoTimeout(7000); Socket httpSock = ss.accept(); try { BufferedWriter sockWriter = new BufferedWriter( new OutputStreamWriter(httpSock.getOutputStream(), HTTP.DEFAULT_PROTOCOL_CHARSET)); sockWriter.write("HTTP/1.1 202 OK\r\n"); sockWriter.flush(); // start reading and confirming the HTTP request String currLine = null; BufferedReader reader = new BufferedReader( new InputStreamReader(httpSock.getInputStream(), HTTP.DEFAULT_PROTOCOL_CHARSET)); // confirm a GET/HEAD pushproxy request currLine = reader.readLine(); assertTrue( currLine.startsWith("GET /gnutella/push-proxy") || currLine.startsWith("HEAD /gnutella/push-proxy")); // make sure it sends the correct client GUID int beginIndex = currLine.indexOf("ID=") + 3; String guidString = currLine.substring(beginIndex, beginIndex + 26); GUID guidFromBackend = new GUID(clientGUID); GUID guidFromNetwork = new GUID(Base32.decode(guidString)); assertEquals(guidFromNetwork, guidFromBackend); // make sure the node sends the correct X-Node currLine = reader.readLine(); assertTrue(currLine.startsWith("X-Node:")); StringTokenizer st = new StringTokenizer(currLine, ":"); assertEquals(st.nextToken(), "X-Node"); InetAddress addr = InetAddress.getByName(st.nextToken().trim()); Arrays.equals(addr.getAddress(), networkManagerStub.getAddress()); assertEquals(SERVER_PORT, Integer.parseInt(st.nextToken())); // now we need to GIV Socket push = new Socket(InetAddress.getLocalHost(), SERVER_PORT); try { BufferedWriter writer = new BufferedWriter( new OutputStreamWriter(push.getOutputStream(), HTTP.DEFAULT_PROTOCOL_CHARSET)); writer.write("GIV 0:" + new GUID(clientGUID).toHexString() + "/\r\n"); writer.write("\r\n"); writer.flush(); assertIsBrowse(push, push.getLocalPort()); } finally { push.close(); } } finally { httpSock.close(); } try { do { m = testUP[0].receive(TIMEOUT); assertNotInstanceof(m.toString(), PushRequest.class, m); } while (true); } catch (InterruptedIOException expected) { } } finally { ss.close(); } }
// RUN THIS TEST LAST!! // TODO move this test case to OnDemandUnicasterTest, sounds like a pure unit test // proabably doesn't make sense anymore since it doesn't have any data from the // previous tests to clear public void testUnicasterClearingCode() throws Exception { BlockingConnectionUtils.keepAllAlive(testUP, pingReplyFactory); // clear up any messages before we begin the test. drainAll(); { // clear all the unicaster data structures Long[] longs = new Long[] {new Long(0), new Long(1)}; Class[] classTypes = new Class[] {Long.TYPE, Long.TYPE}; // now confirm that clearing code works Object ret = PrivilegedAccessor.invokeMethod( onDemandUnicaster, "clearDataStructures", longs, classTypes); assertTrue(ret instanceof Boolean); assertTrue(((Boolean) ret).booleanValue()); } DatagramPacket pack = null; Message m = null; byte[] guid = searchServices.newQueryGUID(); searchServices.query(guid, "whatever"); // i need to pretend that the UI is showing the user the query still callback.setGUID(new GUID(guid)); QueryRequest qr = BlockingConnectionUtils.getFirstInstanceOfMessageType(testUP[0], QueryRequest.class); assertNotNull(qr); assertTrue(qr.desiresOutOfBandReplies()); // ok, the leaf is sending OOB queries - good stuff, now we should send // a lot of results back and make sure it buffers the bypassed OOB ones for (int i = 0; i < testUP.length; i++) { Response[] res = new Response[200]; for (int j = 0; j < res.length; j++) res[j] = responseFactory.createResponse( 10 + j + i, 10 + j + i, "whatever " + j + i, UrnHelper.SHA1); m = queryReplyFactory.createQueryReply( qr.getGUID(), (byte) 1, 6355, myIP(), 0, res, GUID.makeGuid(), new byte[0], false, false, true, true, false, false, null); testUP[i].send(m); testUP[i].flush(); } // create a test uploader and send back that response TestUploader uploader = new TestUploader(networkManagerStub); uploader.start("whatever", UPLOADER_PORT, false); uploader.setBusy(true); RemoteFileDesc rfd = makeRFD("GLIQY64M7FSXBSQEZY37FIM5QQSA2OUJ"); // wait for processing Thread.sleep(1500); for (int i = 0; i < UDP_ACCESS.length; i++) { ReplyNumberVendorMessage vm = replyNumberVendorMessageFactory.createV3ReplyNumberVendorMessage( new GUID(qr.getGUID()), i + 1); ByteArrayOutputStream baos = new ByteArrayOutputStream(); vm.write(baos); pack = new DatagramPacket( baos.toByteArray(), baos.toByteArray().length, testUP[0].getInetAddress(), SERVER_PORT); UDP_ACCESS[i].send(pack); } // wait for processing Thread.sleep(500); { // all the UDP ReplyNumberVMs should have been bypassed assertByPassedResultsCacheHasSize(qr.getGUID(), UDP_ACCESS.length); } Downloader downloader = downloadServices.download(new RemoteFileDesc[] {rfd}, false, new GUID(guid)); final int MAX_TRIES = 60; for (int i = 0; i <= MAX_TRIES; i++) { Thread.sleep(500); if (downloader.getState() == DownloadState.ITERATIVE_GUESSING) break; if (i == MAX_TRIES) fail("didn't GUESS!!"); } // we should start getting guess queries on all UDP ports, actually // querykey requests for (int i = 0; i < UDP_ACCESS.length; i++) { boolean gotPing = false; while (!gotPing) { try { byte[] datagramBytes = new byte[1000]; pack = new DatagramPacket(datagramBytes, 1000); UDP_ACCESS[i].setSoTimeout(10000); // may need to wait UDP_ACCESS[i].receive(pack); InputStream in = new ByteArrayInputStream(pack.getData()); m = messageFactory.read(in, Network.TCP); m.hop(); if (m instanceof PingRequest) gotPing = ((PingRequest) m).isQueryKeyRequest(); } catch (InterruptedIOException iioe) { assertTrue("was successful for " + i, false); } } } // Prepopulate Query Keys AddressSecurityToken qk = new AddressSecurityToken(InetAddress.getLocalHost(), SERVER_PORT, macManager); for (int i = 0; i < (UDP_ACCESS.length / 2); i++) { byte[] ip = new byte[] {(byte) 127, (byte) 0, (byte) 0, (byte) 1}; PingReply pr = pingReplyFactory.createQueryKeyReply( GUID.makeGuid(), (byte) 1, UDP_ACCESS[i].getLocalPort(), ip, 10, 10, false, qk); pr.hop(); onDemandUnicaster.handleQueryKeyPong(pr); } // ensure that it gets into the OnDemandUnicaster { // now we should make sure MessageRouter retains the key Map _queryKeys = (Map) PrivilegedAccessor.getValue(onDemandUnicaster, "_queryKeys"); assertNotNull(_queryKeys); assertEquals((UDP_ACCESS.length / 2), _queryKeys.size()); // now make sure some URNs are still buffered Map _bufferedURNs = (Map) PrivilegedAccessor.getValue(onDemandUnicaster, "_bufferedURNs"); assertNotNull(_bufferedURNs); assertEquals((UDP_ACCESS.length / 2), _bufferedURNs.size()); } // now until those guys get expired Thread.sleep(60 * 1000); { Long[] longs = new Long[] {new Long(0), new Long(1)}; Class[] classTypes = new Class[] {Long.TYPE, Long.TYPE}; // now confirm that clearing code works Object ret = PrivilegedAccessor.invokeMethod( onDemandUnicaster, "clearDataStructures", longs, classTypes); assertTrue(ret instanceof Boolean); assertTrue(((Boolean) ret).booleanValue()); } // ensure that clearing worked { // now we should make sure MessageRouter retains the key Map _queryKeys = (Map) PrivilegedAccessor.getValue(onDemandUnicaster, "_queryKeys"); assertNotNull(_queryKeys); assertEquals(0, _queryKeys.size()); // now make sure some URNs are still buffered Map _bufferedURNs = (Map) PrivilegedAccessor.getValue(onDemandUnicaster, "_bufferedURNs"); assertNotNull(_bufferedURNs); assertEquals(0, _bufferedURNs.size()); } assertEquals(DownloadState.BUSY, downloader.getState()); callback.clearGUID(); downloader.stop(); Thread.sleep(1000); { // now we should make sure MessageRouter clears the map assertByPassedResultsCacheHasSize(qr.getGUID(), 0); } }
public void testHTTPRequest() throws Exception { BlockingConnectionUtils.drain(testUP[0]); // some setup final byte[] clientGUID = GUID.makeGuid(); // construct and send a query byte[] guid = GUID.makeGuid(); searchServices.query(guid, "boalt.org"); // the testUP[0] should get it Message m = null; do { m = testUP[0].receive(TIMEOUT); } while (!(m instanceof QueryRequest)); // set up a server socket ServerSocket ss = new ServerSocket(7000); try { ss.setReuseAddress(true); ss.setSoTimeout(TIMEOUT); // send a reply Response[] res = new Response[1]; res[0] = responseFactory.createResponse(10, 10, "boalt.org", UrnHelper.SHA1); m = queryReplyFactory.createQueryReply( m.getGUID(), (byte) 1, 7000, InetAddress.getLocalHost().getAddress(), 0, res, clientGUID, new byte[0], false, false, true, true, false, false, null); testUP[0].send(m); testUP[0].flush(); // wait a while for Leaf to process result assertNotNull(callback.getRFD()); // tell the leaf to browse host the file, should result in direct HTTP // request searchServices.doAsynchronousBrowseHost( new MockFriendPresence( new MockFriend(), null, new AddressFeature(callback.getRFD().getAddress())), new GUID(), new BrowseListener() { public void handleBrowseResult(SearchResult searchResult) { // To change body of implemented methods use File | Settings | File Templates. } public void browseFinished(boolean success) { // To change body of implemented methods use File | Settings | File Templates. } }); // wait for the incoming HTTP request Socket httpSock = ss.accept(); try { assertIsBrowse(httpSock, 7000); } finally { httpSock.close(); } try { do { m = testUP[0].receive(TIMEOUT); assertTrue(!(m instanceof PushRequest)); } while (true); } catch (InterruptedIOException expected) { } } finally { // awesome - everything checks out! ss.close(); } }
public void testNoDownloadQueryDonePurge() throws Exception { // set smaller clear times so we can test in a timely fashion BlockingConnectionUtils.keepAllAlive(testUP, pingReplyFactory); // clear up any messages before we begin the test. drainAll(); Message m = null; byte[] guid = searchServices.newQueryGUID(); searchServices.query(guid, "whatever"); // i need to pretend that the UI is showing the user the query still callback.setGUID(new GUID(guid)); QueryRequest qr = BlockingConnectionUtils.getFirstInstanceOfMessageType(testUP[0], QueryRequest.class); assertNotNull(qr); assertTrue(qr.desiresOutOfBandReplies()); // ok, the leaf is sending OOB queries - good stuff, now we should send // a lot of results back and make sure it buffers the bypassed OOB ones for (int i = 0; i < testUP.length; i++) { Response[] res = new Response[200]; for (int j = 0; j < res.length; j++) res[j] = responseFactory.createResponse( 10 + j + i, 10 + j + i, "whatever " + j + i, UrnHelper.SHA1); m = queryReplyFactory.createQueryReply( qr.getGUID(), (byte) 1, 6355, myIP(), 0, res, GUID.makeGuid(), new byte[0], false, false, true, true, false, false, null); testUP[i].send(m); testUP[i].flush(); } // wait for processing Thread.sleep(2000); for (int i = 0; i < UDP_ACCESS.length; i++) { ReplyNumberVendorMessage vm = replyNumberVendorMessageFactory.createV3ReplyNumberVendorMessage( new GUID(qr.getGUID()), i + 1); ByteArrayOutputStream baos = new ByteArrayOutputStream(); vm.write(baos); DatagramPacket pack = new DatagramPacket( baos.toByteArray(), baos.toByteArray().length, testUP[0].getInetAddress(), SERVER_PORT); UDP_ACCESS[i].send(pack); } // wait for processing Thread.sleep(1000); { // all the UDP ReplyNumberVMs should have been bypassed assertByPassedResultsCacheHasSize(qr.getGUID(), UDP_ACCESS.length); } { // now we should make sure MessageRouter clears the map searchServices.stopQuery(new GUID(qr.getGUID())); assertByPassedResultsCacheHasSize(qr.getGUID(), 0); } callback.clearGUID(); }
private void doHTTPRequestTest(boolean settingOn, boolean expectTLS) throws Exception { if(settingOn) networkManagerStub.setIncomingTLSEnabled(true); setAccepted(true); BlockingConnectionUtils.drain(testUP[0]); // some setup byte[] clientGUID = GUID.makeGuid(); // construct and send a query byte[] guid = GUID.makeGuid(); searchServices.query(guid, "boalt.org"); // the testUP[0] should get it Message m; do { m = testUP[0].receive(TIMEOUT); } while (!(m instanceof QueryRequest)); // set up a server socket ServerSocket ss = new ServerSocket(7000); try { ss.setReuseAddress(true); ss.setSoTimeout(25 * TIMEOUT); // send a reply with some PushProxy info Set<IpPort> proxies = new TreeSet<IpPort>(IpPort.COMPARATOR); proxies.add(new IpPortImpl("127.0.0.1", 7000)); Response[] res = new Response[1]; res[0] = responseFactory.createResponse(10, 10, "boalt.org", UrnHelper.SHA1); m = queryReplyFactory.createQueryReply(m.getGUID(), (byte) 1, 6355, myIP(), 0, res, clientGUID, new byte[0], true, false, true, true, false, false, proxies); testUP[0].send(m); testUP[0].flush(); // wait a while for Leaf to process result assertNotNull(callback.getRFD()); // tell the leaf to download the file, should result in push proxy // request Downloader download = downloadServices.download((new RemoteFileDesc[] { callback.getRFD() }), true, new GUID(m.getGUID())); // wait for the incoming HTTP request Socket httpSock = ss.accept(); try { assertNotNull(httpSock); // start reading and confirming the HTTP request String currLine; BufferedReader reader = new BufferedReader(new InputStreamReader(httpSock.getInputStream())); // confirm a GET/HEAD pushproxy request currLine = reader.readLine(); assertTrue(currLine.startsWith("GET /gnutella/push-proxy") || currLine.startsWith("HEAD /gnutella/push-proxy")); if(expectTLS) { assertTrue(currLine.contains("tls=true")); } else { assertFalse(currLine.contains("tls")); } // make sure it sends the correct client GUID int beginIndex = currLine.indexOf("ID=") + 3; String guidString = currLine.substring(beginIndex, beginIndex+26); GUID guidFromBackend = new GUID(clientGUID); GUID guidFromNetwork = new GUID(Base32.decode(guidString)); assertEquals(guidFromNetwork, guidFromBackend); // make sure the node sends the correct X-Node currLine = reader.readLine(); assertTrue(currLine.startsWith("X-Node:")); StringTokenizer st = new StringTokenizer(currLine, ":"); assertEquals(st.nextToken(), "X-Node"); InetAddress addr = InetAddress.getByName(st.nextToken().trim()); Arrays.equals(addr.getAddress(), networkManagerStub.getAddress()); assertEquals(PORT, Integer.parseInt(st.nextToken())); // send back a 202 and make sure no PushRequest is sent via the normal // way BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(httpSock.getOutputStream())); writer.write("HTTP/1.1 202 gobbledygook"); writer.flush(); } finally { httpSock.close(); } try { do { m = testUP[0].receive(TIMEOUT); assertTrue(!(m instanceof PushRequest)); } while (true) ; } catch (InterruptedIOException ignore) {} // now make a connection to the leaf to confirm that it will send a // correct download request Socket push = new Socket(InetAddress.getLocalHost(), PORT); try { BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(push.getOutputStream())); writer.write("GIV "); writer.flush(); NIOTestUtils.waitForNIO(); // the PUSH request is not matched in PushList.getBestHost() if // this is set to false: the RemoteFileDesc contains the IP // 192.168.0.1 but since we are connecting from a different IP // it is not matched but it'll accept it this is set to true and // both IPs are private ConnectionSettings.LOCAL_IS_PRIVATE.setValue(true); writer.write("0:" + new GUID(clientGUID).toHexString() + "/\r\n"); writer.write("\r\n"); writer.flush(); BufferedReader reader = new BufferedReader(new InputStreamReader(push.getInputStream())); String currLine = reader.readLine(); assertEquals(MessageFormat.format("GET /uri-res/N2R?{0} HTTP/1.1", UrnHelper.SHA1), currLine); } finally { push.close(); } download.stop(); } finally { ss.close(); } }
public void testDownloadProgressQueryDoneNoPurge() throws Exception { BlockingConnectionUtils.keepAllAlive(testUP, pingReplyFactory); // clear up any messages before we begin the test. drainAll(); // luckily there is hacky little way to go through the download paces - // download from yourself :) . Message m = null; byte[] guid = searchServices.newQueryGUID(); searchServices.query(guid, "metadata"); callback.setGUID(new GUID(guid)); QueryRequest qr = BlockingConnectionUtils.getFirstInstanceOfMessageType(testUP[0], QueryRequest.class); assertNotNull(qr); assertTrue(qr.desiresOutOfBandReplies()); // just return ONE real result and the rest junk Response resp = null; QueryReply reply = null; { // get a correct response object QueryRequest qrTemp = queryRequestFactory.createQuery("metadata"); testUP[0].send(qrTemp); testUP[0].flush(); reply = BlockingConnectionUtils.getFirstInstanceOfMessageType(testUP[0], QueryReply.class); assertNotNull(reply); resp = (reply.getResultsAsList()).get(0); } assertNotNull(reply); assertNotNull(resp); Response[] res = new Response[] {resp}; // this isn't really needed but just for completeness send it back to // the test Leaf m = queryReplyFactory.createQueryReply( guid, (byte) 1, SERVER_PORT, myIP(), 0, res, GUID.makeGuid(), new byte[0], false, false, true, true, false, false, null); testUP[0].send(m); testUP[0].flush(); // send back a lot of results via TCP so you konw the UDP one will be // bypassed for (int i = 0; i < testUP.length; i++) { res = new Response[75]; for (int j = 0; j < res.length; j++) res[j] = responseFactory.createResponse( 10 + j + i, 10 + j + i, "metadata " + j + i, UrnHelper.SHA1); m = queryReplyFactory.createQueryReply( guid, (byte) 1, testUP[0].getPort(), myIP(), 0, res, GUID.makeGuid(), new byte[0], false, false, true, true, false, false, null); testUP[i].send(m); testUP[i].flush(); } // allow for processing Thread.sleep(3000); { // now we should make sure MessageRouter has not bypassed anything // yet assertByPassedResultsCacheHasSize(qr.getGUID(), 0); } // send back a UDP response and make sure it was saved in bypassed... { ReplyNumberVendorMessage vm = replyNumberVendorMessageFactory.createV3ReplyNumberVendorMessage(new GUID(guid), 1); ByteArrayOutputStream baos = new ByteArrayOutputStream(); vm.write(baos); DatagramPacket pack = new DatagramPacket( baos.toByteArray(), baos.toByteArray().length, testUP[0].getInetAddress(), SERVER_PORT); UDP_ACCESS[0].send(pack); } // allow for processing Thread.sleep(500); { // all the UDP ReplyNumberVMs should have been bypassed assertByPassedResultsCacheHasSize(guid, 1); } // now do the download, wait for it to finish, and then bypassed results // should be empty again RemoteFileDesc rfd = resp.toRemoteFileDesc(reply, null, remoteFileDescFactory, pushEndpointFactory); assertFalse("file should not be saved yet", new File(_savedDir, "metadata.mp3").exists()); downloadServices.download(new RemoteFileDesc[] {rfd}, false, new GUID(guid)); UploadSettings.UPLOAD_SPEED.setValue(5); searchServices.stopQuery(new GUID(guid)); callback.clearGUID(); // download still in progress, don't purge assertByPassedResultsCacheHasSize(guid, 1); UploadSettings.UPLOAD_SPEED.setValue(100); // sleep to make sure the download starts Thread.sleep(20000); assertTrue("file should saved", new File(_savedDir, "metadata.mp3").exists()); // now we should make sure MessageRouter clears the cache assertByPassedResultsCacheHasSize(qr.getGUID(), 0); }
public void testCanReactToBadPushProxy() throws Exception { // assume client accepted connections from the outside successfully setAccepted(true); BlockingConnectionUtils.drain(testUP[0]); // some setup byte[] clientGUID = GUID.makeGuid(); // construct and send a query byte[] guid = GUID.makeGuid(); searchServices.query(guid, "berkeley.edu"); // the testUP[0] should get it Message m; do { m = testUP[0].receive(TIMEOUT); } while (!(m instanceof QueryRequest)); // set up a server socket ServerSocket ss = new ServerSocket(7000); try { ss.setReuseAddress(true); ss.setSoTimeout(25 * TIMEOUT); // send a reply with some BAD PushProxy info // PushProxyInterface[] proxies = new // QueryReply.PushProxyContainer[2]; Set<IpPort> proxies = new TreeSet<IpPort>(IpPort.COMPARATOR); proxies.add(new IpPortImpl("127.0.0.1", 7000)); proxies.add(new IpPortImpl("127.0.0.1", 8000)); Response[] res = new Response[1]; res[0] = responseFactory.createResponse(10, 10, "berkeley.edu", UrnHelper.SHA1); m = queryReplyFactory.createQueryReply(m.getGUID(), (byte) 1, 6355, myIP(), 0, res, clientGUID, new byte[0], true, false, true, true, false, false, proxies); testUP[0].send(m); testUP[0].flush(); // wait a while for Leaf to process result assertNotNull(callback.getRFD()); // tell the leaf to download the file, should result in push proxy // request downloadServices .download( (new RemoteFileDesc[] { callback.getRFD() }), true, new GUID((m.getGUID()))); // wait for the incoming HTTP request Socket httpSock = ss.accept(); try { // send back an error and make sure the PushRequest is sent via // the normal way BufferedWriter writer = new BufferedWriter( new OutputStreamWriter(httpSock.getOutputStream())); writer.write("HTTP/1.1 410 gobbledygook"); writer.flush(); } finally { httpSock.close(); } // await a PushRequest do { m = testUP[0].receive(TIMEOUT * 8); } while (!(m instanceof PushRequest)); } finally { ss.close(); } }
public void testBusyDownloadLocatesSources() throws Exception { BlockingConnectionUtils.keepAllAlive(testUP, pingReplyFactory); // clear up any messages before we begin the test. drainAll(); DatagramPacket pack = null; Message m = null; byte[] guid = searchServices.newQueryGUID(); searchServices.query(guid, "whatever"); // i need to pretend that the UI is showing the user the query still callback.setGUID(new GUID(guid)); QueryRequest qr = BlockingConnectionUtils.getFirstInstanceOfMessageType(testUP[0], QueryRequest.class); assertNotNull(qr); assertTrue(qr.desiresOutOfBandReplies()); // ok, the leaf is sending OOB queries - good stuff, now we should send // a lot of results back and make sure it buffers the bypassed OOB ones for (int i = 0; i < testUP.length; i++) { Response[] res = new Response[200]; for (int j = 0; j < res.length; j++) res[j] = responseFactory.createResponse( 10 + j + i, 10 + j + i, "whatever " + j + i, UrnHelper.SHA1); m = queryReplyFactory.createQueryReply( qr.getGUID(), (byte) 1, 6355, myIP(), 0, res, GUID.makeGuid(), new byte[0], false, false, true, true, false, false, null); testUP[i].send(m); testUP[i].flush(); } // create a test uploader and send back that response TestUploader uploader = new TestUploader(networkManagerStub); uploader.start("whatever", UPLOADER_PORT, false); uploader.setBusy(true); RemoteFileDesc rfd = makeRFD("GLIQY64M7FSXBSQEZY37FIM5QQSA2OUJ"); // wait for processing Thread.sleep(1500); for (int i = 0; i < UDP_ACCESS.length; i++) { ReplyNumberVendorMessage vm = replyNumberVendorMessageFactory.createV3ReplyNumberVendorMessage( new GUID(qr.getGUID()), i + 1); ByteArrayOutputStream baos = new ByteArrayOutputStream(); vm.write(baos); pack = new DatagramPacket( baos.toByteArray(), baos.toByteArray().length, testUP[0].getInetAddress(), SERVER_PORT); UDP_ACCESS[i].send(pack); } // wait for processing Thread.sleep(500); { // all the UDP ReplyNumberVMs should have been bypassed assertByPassedResultsCacheHasSize(qr.getGUID(), UDP_ACCESS.length); } Downloader downloader = downloadServices.download(new RemoteFileDesc[] {rfd}, false, new GUID(guid)); final int MAX_TRIES = 60; for (int i = 0; i <= MAX_TRIES; i++) { Thread.sleep(1000); if (downloader.getState() == DownloadState.ITERATIVE_GUESSING) break; if (i == MAX_TRIES) fail("didn't GUESS!!"); } // we should start getting guess queries on all UDP ports, actually // querykey requests for (int i = 0; i < UDP_ACCESS.length; i++) { boolean gotPing = false; while (!gotPing) { try { byte[] datagramBytes = new byte[1000]; pack = new DatagramPacket(datagramBytes, 1000); UDP_ACCESS[i].setSoTimeout(10000); // may need to wait UDP_ACCESS[i].receive(pack); InputStream in = new ByteArrayInputStream(pack.getData()); m = messageFactory.read(in, Network.TCP); m.hop(); if (m instanceof PingRequest) gotPing = ((PingRequest) m).isQueryKeyRequest(); } catch (InterruptedIOException iioe) { fail("was successful for " + i, iioe); } } } // Thread.sleep((UDP_ACCESS.length * 1000) - // (System.currentTimeMillis() - currTime)); int guessWaitTime = 5000; Thread.sleep(guessWaitTime + 2000); assertEquals(DownloadState.BUSY, downloader.getState()); callback.clearGUID(); downloader.stop(); Thread.sleep(1000); { // now we should make sure MessageRouter clears the map assertByPassedResultsCacheHasSize(qr.getGUID(), 0); } uploader.stopThread(); }