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(); }
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(); } }
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 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 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 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(); }
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(); } }
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(); }
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 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(); }
// 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 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(); }