public void testWritePartialMsg() throws Exception { assertEquals(0, SENT.size()); assertEquals(0, STATS.getSent()); Message m = q("reaalllllllllly long query"); SINK.resize(m.getTotalLength() - 20); WRITER.send(m); assertEquals(1, STATS.getSent()); assertTrue(WRITER.handleWrite()); // still stuff left to write. assertTrue(SINK.interested()); assertEquals( 1, SENT.size()); // it's sent, even though the other side didn't receive it fully yet. assertEquals(buffer(m), buffer(SENT.next())); ByteBuffer buffer = ByteBuffer.allocate(m.getTotalLength()); buffer.put(SINK.getBuffer()); SINK.resize(100000); assertFalse(WRITER.handleWrite()); assertFalse(SINK.interested()); buffer.put(SINK.getBuffer()); Message in = read((ByteBuffer) buffer.flip()); assertEquals(buffer(m), buffer(in)); }
private Message read(ByteBuffer buffer) throws Exception { ByteArrayInputStream in = new ByteArrayInputStream(buffer.array(), buffer.position(), buffer.limit()); Message m = read(in); buffer.position(buffer.position() + m.getTotalLength()); return m; }
@Override public void setUp() throws Exception { networkManagerStub = new NetworkManagerStub(); networkManagerStub.setPort(PORT); Injector injector = LimeTestUtils.createInjector(MyActivityCallback.class, new LimeTestUtils.NetworkManagerStubModule(networkManagerStub)); super.setUp(injector); DownloadManagerImpl downloadManager = (DownloadManagerImpl)injector.getInstance(DownloadManager.class); callback = (MyActivityCallback) injector.getInstance(ActivityCallback.class); downloadManager.clearAllDownloads(); // Turn off by default, explicitly test elsewhere. networkManagerStub.setIncomingTLSEnabled(false); networkManagerStub.setOutgoingTLSEnabled(false); // duplicate queries are sent out each time, so avoid the DuplicateFilter Thread.sleep(2000); // send a MessagesSupportedMessage testUP[0].send(injector.getInstance(MessagesSupportedVendorMessage.class)); testUP[0].flush(); // we expect to get a PushProxy request Message m; do { m = testUP[0].receive(TIMEOUT); } while (!(m instanceof PushProxyRequest)); // we should answer the push proxy request PushProxyAcknowledgement ack = new PushProxyAcknowledgement(InetAddress .getLocalHost(), 6355, new GUID(m.getGUID())); testUP[0].send(ack); testUP[0].flush(); }
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(); }
private void readNumConnectBacks(int num, BlockingConnection conn, int timeout) throws Exception { Message m; for (int i = 0; i < num; i++) { do { m = conn.receive(timeout); } while (!(m instanceof TCPConnectBackVendorMessage)); } try { do { m = conn.receive(timeout); } while (!(m instanceof TCPConnectBackVendorMessage)); fail("got extra message " + m.getClass() + " on " + conn); } catch (IOException expected) { } }
private void exchangeSupportedMessages() throws Exception { // send a MessagesSupportedMessage testUP[0].send(messagesSupportedVendorMessage); testUP[0].flush(); testUP[1].send(messagesSupportedVendorMessage); testUP[1].flush(); // we expect to get a TCPConnectBack request Message m = null; boolean gotTCP = false, gotUDP = false; do { m = testUP[0].receive(TIMEOUT); if (m instanceof TCPConnectBackVendorMessage) gotTCP = true; if (m instanceof UDPConnectBackVendorMessage) { cbGuid = m.getGUID(); gotUDP = true; } } while (!gotTCP || !gotUDP); // client side seems to follow the setup process A-OK }
public void testWritePartialAndMore() throws Exception { Message out1 = q("first long query"); Message out2 = q("second long query"); Message out3 = q("third long query"); assertEquals(0, STATS.getSent()); SINK.resize(out1.getTotalLength() + 20); WRITER.send(out1); WRITER.send(out2); assertEquals(2, STATS.getSent()); assertEquals(0, SENT.size()); assertTrue(WRITER.handleWrite()); assertTrue(SINK.interested()); assertEquals(2, SENT.size()); // two were sent, one was received. assertEquals(buffer(out1), buffer(SENT.next())); assertEquals(buffer(out2), buffer(SENT.next())); ByteBuffer buffer = ByteBuffer.allocate(1000); buffer.put(SINK.getBuffer()).flip(); SINK.resize(10000); Message in1 = read(buffer); assertTrue(buffer.hasRemaining()); assertEquals(20, buffer.remaining()); buffer.compact(); WRITER.send(out3); assertEquals(3, STATS.getSent()); assertFalse(WRITER.handleWrite()); assertEquals(1, SENT.size()); assertEquals(buffer(out3), buffer(SENT.next())); assertFalse(SINK.interested()); buffer.put(SINK.getBuffer()).flip(); Message in2 = read(buffer); Message in3 = read(buffer); assertTrue(!buffer.hasRemaining()); assertEquals(buffer(out2), buffer(in2)); assertEquals(buffer(out3), buffer(in3)); }
// This test checks that if _acceptedUnsolicitedIncoming is false, connect // back messages are NOT sent public void testUDPExpireRequestsNotSent() throws Exception { drainAll(); UDPService udpServ = udpService; for (int i = 0; i < 2; i++) { assertFalse(udpServ.canReceiveUnsolicited()); try { testUP[0].receive(TIMEOUT); } catch (InterruptedIOException expected) { } Thread.sleep(MY_EXPIRE_TIME + MY_VALIDATE_TIME); assertFalse(udpServ.canReceiveUnsolicited()); Thread.sleep(100); // now we should get the connect backs cuz it has been a while Message m = null; do { m = testUP[0].receive(TIMEOUT); } while (!(m instanceof UDPConnectBackVendorMessage)); cbGuid = m.getGUID(); } }
public void testSimpleWrite() throws Exception { Message one, two, three; one = q("query one"); two = g(7123); three = s(8134); assertEquals(0, STATS.getSent()); assertFalse(SINK.interested()); WRITER.send(one); WRITER.send(two); WRITER.send(three); assertEquals(3, STATS.getSent()); assertTrue(SINK.interested()); assertEquals(0, SENT.size()); assertFalse(WRITER.handleWrite()); // nothing left to write. assertEquals(3, SENT.size()); ByteBuffer buffer = SINK.getBuffer(); assertEquals( one.getTotalLength() + two.getTotalLength() + three.getTotalLength(), buffer.limit()); ByteArrayInputStream in = new ByteArrayInputStream(buffer.array(), 0, buffer.limit()); Message in1, in2, in3; in1 = read(in); in2 = read(in); in3 = read(in); assertEquals(-1, in.read()); assertEquals(buffer(one), buffer(in1)); assertEquals(buffer(two), buffer(in2)); assertEquals(buffer(three), buffer(in3)); assertEquals(buffer(one), buffer(SENT.next())); assertEquals(buffer(two), buffer(SENT.next())); assertEquals(buffer(three), buffer(SENT.next())); assertFalse(SINK.interested()); assertEquals(3, STATS.getSent()); }
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 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 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 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 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(); } }
// test buffer doesn't get re-ordered. public void testBuffer() throws Exception { Message m = null; QUEUE.add(q("first")); QUEUE.add(q("second")); QUEUE.add(g(7000)); QUEUE.add(q("third")); QUEUE.add(p(4)); QUEUE.add(p(3)); QUEUE.add(q("fourth")); QUEUE.add(s(6340)); QUEUE.add(s(6341)); QUEUE.add(r(6342)); QUEUE.add(t()); QUEUE.add(c(1)); QUEUE.add(q("fifth")); QUEUE.add(c(2)); m = QUEUE.removeNext(); assertInstanceof(QueryRequest.class, m); assertEquals("first", ((QueryRequest) m).getQuery()); m = QUEUE.removeNext(); assertInstanceof(QueryRequest.class, m); assertEquals("second", ((QueryRequest) m).getQuery()); m = QUEUE.removeNext(); assertInstanceof(PingReply.class, m); assertEquals(7000, ((PingReply) m).getPort()); m = QUEUE.removeNext(); assertInstanceof(QueryRequest.class, m); assertEquals("third", ((QueryRequest) m).getQuery()); m = QUEUE.removeNext(); assertInstanceof(PingRequest.class, m); assertEquals(4, m.getTTL()); m = QUEUE.removeNext(); assertInstanceof(PingRequest.class, m); assertEquals(3, m.getTTL()); m = QUEUE.removeNext(); assertInstanceof(QueryRequest.class, m); assertEquals("fourth", ((QueryRequest) m).getQuery()); m = QUEUE.removeNext(); assertInstanceof(PushRequest.class, m); assertEquals(6340, ((PushRequest) m).getPort()); m = QUEUE.removeNext(); assertInstanceof(PushRequest.class, m); assertEquals(6341, ((PushRequest) m).getPort()); m = QUEUE.removeNext(); assertInstanceof(QueryReply.class, m); assertEquals(6342, ((QueryReply) m).getPort()); m = QUEUE.removeNext(); assertInstanceof(ResetTableMessage.class, m); m = QUEUE.removeNext(); assertInstanceof(PatchTableMessage.class, m); assertEquals(1, ((PatchTableMessage) m).getSequenceNumber()); m = QUEUE.removeNext(); assertInstanceof(QueryRequest.class, m); assertEquals("fifth", ((QueryRequest) m).getQuery()); m = QUEUE.removeNext(); assertInstanceof(PatchTableMessage.class, m); assertEquals(2, ((PatchTableMessage) m).getSequenceNumber()); assertNull(QUEUE.removeNext()); context.assertIsSatisfied(); }
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(); }
// 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); } }
private ByteBuffer buffer(Message m) throws Exception { ByteArrayOutputStream out = new ByteArrayOutputStream(); m.write(out); out.flush(); return ByteBuffer.wrap(out.toByteArray()); }
private Message read(InputStream in) throws Exception { return Message.read(in, (byte) 100); }