package com.limegroup.gnutella.messages.vendor;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import junit.framework.Test;
import org.jmock.Expectations;
import org.jmock.Mockery;
import org.limewire.collection.IntervalSet;
import org.limewire.collection.Range;
import org.limewire.core.settings.SharingSettings;
import org.limewire.core.settings.UploadSettings;
import org.limewire.io.Connectable;
import org.limewire.io.ConnectableImpl;
import org.limewire.io.GUID;
import org.limewire.io.IpPort;
import org.limewire.io.IpPortImpl;
import org.limewire.io.IpPortSet;
import org.limewire.util.ByteUtils;
import org.limewire.util.PrivilegedAccessor;
import com.google.inject.AbstractModule;
import com.google.inject.Injector;
import com.limegroup.gnutella.ConnectionManager;
import com.limegroup.gnutella.DownloadManager;
import com.limegroup.gnutella.LimeTestUtils;
import com.limegroup.gnutella.MessageRouter;
import com.limegroup.gnutella.NetworkManager;
import com.limegroup.gnutella.PushEndpoint;
import com.limegroup.gnutella.PushEndpointCache;
import com.limegroup.gnutella.RemoteFileDesc;
import com.limegroup.gnutella.URN;
import com.limegroup.gnutella.UploadManager;
import com.limegroup.gnutella.altlocs.AltLocManager;
import com.limegroup.gnutella.altlocs.AlternateLocation;
import com.limegroup.gnutella.altlocs.AlternateLocationCollection;
import com.limegroup.gnutella.altlocs.AlternateLocationFactory;
import com.limegroup.gnutella.altlocs.PushAltLoc;
import com.limegroup.gnutella.downloader.PingRanker;
import com.limegroup.gnutella.downloader.RemoteFileDescContext;
import com.limegroup.gnutella.downloader.RemoteFileDescFactory;
import com.limegroup.gnutella.helpers.UrnHelper;
import com.limegroup.gnutella.library.FileDescStub;
import com.limegroup.gnutella.library.FileManager;
import com.limegroup.gnutella.library.FileManagerStub;
import com.limegroup.gnutella.library.GnutellaFileListStub;
import com.limegroup.gnutella.library.IncompleteFileDescStub;
import com.limegroup.gnutella.messages.MessageFactory;
import com.limegroup.gnutella.messages.Message.Network;
import com.limegroup.gnutella.stubs.ConnectionManagerStub;
import com.limegroup.gnutella.stubs.MessageRouterStub;
import com.limegroup.gnutella.stubs.NetworkManagerStub;
import com.limegroup.gnutella.stubs.UploadManagerStub;
import com.limegroup.gnutella.util.LimeTestCase;
/**
* this class tests the handling of udp head requests and responses.
*/
@SuppressWarnings({"unchecked", "null"})
public class HeadTest extends LimeTestCase {
/**
* URNs for the 3 files that will be requested
*/
private URN _haveFull,_notHave,_havePartial, _tlsURN, _largeURN;
/**
* file descs for the partial and complete files
*/
private IncompleteFileDescStub _partial, _partialLarge;
/**
* an interval that can fit in a packet, and one that can't
*/
private IntervalSet _ranges, _rangesMedium, _rangesJustFit, _rangesTooBig, _rangesLarge, _rangesOnlyLarge;
private PushEndpoint pushCollectionPE, tlsCollectionPE;
private RemoteFileDescContext blankRFD;
private HeadPongFactory headPongFactory;
private Injector injector;
private Mockery mockery;
private DownloadManager downloadManager;
private RemoteFileDescFactory remoteFileDescFactory;
public HeadTest(String name) {
super(name);
}
public static Test suite() {
return buildTestSuite(HeadTest.class);
}
@Override
public void setUp() throws Exception {
SharingSettings.ADD_ALTERNATE_FOR_SELF.setValue(false);
mockery = new Mockery();
downloadManager = mockery.mock(DownloadManager.class);
injector = LimeTestUtils.createInjector(new AbstractModule() {
@Override
protected void configure() {
bind(MessageRouter.class).to(MessageRouterStub.class);
bind(ConnectionManager.class).to(ConnectionManagerStub.class);
bind(NetworkManager.class).to(NetworkManagerStub.class);
bind(UploadManager.class).to(UploadManagerStub.class);
bind(FileManager.class).to(FileManagerStub.class);
bind(DownloadManager.class).toInstance(downloadManager);
}
});
headPongFactory = injector.getInstance(HeadPongFactory.class);
remoteFileDescFactory = injector.getInstance(RemoteFileDescFactory.class);
NetworkManagerStub networkManager = (NetworkManagerStub)injector.getInstance(NetworkManager.class);
networkManager.setAcceptedIncomingConnection(true);
networkManager.setIncomingTLSEnabled(true);
ConnectionManagerStub connectionManager = (ConnectionManagerStub)injector.getInstance(ConnectionManager.class);
connectionManager.setPushProxies(new HashSet<Connectable>(Collections.singletonList(new ConnectableImpl("1.2.3.4", 6346, false))));
int base=0;
_ranges = new IntervalSet();
for (int i=2;i<10;i++) {
int low = base;
_ranges.add(Range.createRange(low,low+i));
base+=2*i;
}
base=0;
_rangesMedium = new IntervalSet();
for (int i=2;i<70;i++) {
int low = base;
_rangesMedium.add(Range.createRange(low,low+i));
base+=2*i;
}
base=0;
_rangesJustFit = new IntervalSet();
for (int i=2;i<73;i++) {
int low = base;
_rangesJustFit.add(Range.createRange(low,low+i));
base+=2*i;
}
base=0;
_rangesTooBig = new IntervalSet();
for (int i=2;i<220;i++) {
int low = base;
_rangesTooBig.add(Range.createRange(low,low+i));
base+=2*i;
}
_rangesLarge = new IntervalSet();
_rangesLarge.add(Range.createRange(10, 20));
_rangesLarge.add(Range.createRange(0xFFFFFF00l, 0xFFFFFFFFFFl));
_rangesOnlyLarge = new IntervalSet();
_rangesOnlyLarge.add(Range.createRange(0xFFFFFF00l, 0xFFFFFFFFFFl));
_notHave = GnutellaFileListStub.DEFAULT_URN;
_haveFull = URN.createSHA1Urn("urn:sha1:PLSTHIPQGSSZTS5FJUPAKUZWUGYQYPFE");
_havePartial = URN.createSHA1Urn("urn:sha1:PLSTHIPQGSSZTS5FJUPAKUZWUGYQYPFD");
_tlsURN = URN.createSHA1Urn("urn:sha1:PLSTHIPQGSSZTS5FJUPAKUZWUGYQYTLS");
_largeURN = URN.createSHA1Urn("urn:sha1:PLSTHIPQGSSZTS5FJUPAKUZWUGYQYTLG");
_partial = new IncompleteFileDescStub("incomplete",_havePartial,3);
_partial.setRangesByte(_ranges.toBytes());
_partialLarge = new IncompleteFileDescStub("incompleteLArge", _largeURN, 4) {
@Override
public long getFileSize() {
return 0xFFFFFFFF00l;
}
};
_partialLarge.setRangesByte(_rangesLarge.toBytes());
FileDescStub complete = new FileDescStub("complete", _haveFull, 2);
FileManagerStub fileManager = (FileManagerStub)injector.getInstance(FileManager.class);
fileManager.getGnutellaFileList().add(complete);
fileManager.getGnutellaFileList().add(new FileDescStub("test", _tlsURN, 100));
fileManager.getIncompleteFileList().add(_partial);
fileManager.getIncompleteFileList().add(_partialLarge);
assertEquals(_partial,fileManager.getIncompleteFileList().getFileDesc(_havePartial));
assertEquals(_partialLarge,fileManager.getIncompleteFileList().getFileDesc(_largeURN));
assertEquals(complete,fileManager.getGnutellaFileList().getFileDesc(_haveFull));
blankRFD = new RemoteFileDescContext(remoteFileDescFactory.createRemoteFileDesc(new ConnectableImpl("1.1.1.1", 1, false), 1, "file", 1, new byte[16], 1, -1,
false, null, URN.NO_URN_SET, false, null, -1));
assertFalse(blankRFD.isBusy());
assertFalse(blankRFD.isPartialSource());
assertFalse(blankRFD.isReplyToMulticast());
assertEquals(Integer.MAX_VALUE, blankRFD.getQueueStatus());
createCollections();
PrivilegedAccessor.setValue(HeadPongFactoryImpl.class, "PACKET_SIZE", HeadPongFactoryImpl.DEFAULT_PACKET_SIZE);
}
@Override
protected void tearDown() throws Exception {
mockery.assertIsSatisfied();
}
private void clearStoredProxies() throws Exception {
PushEndpointCache pushEndpointCache = injector.getInstance(PushEndpointCache.class);
pushEndpointCache.clear();
}
/**
* tests the scenario where the file cannot be found.
*/
public void testFileNotFound() throws Exception {
HeadPing ping = new HeadPing(_notHave);
HeadPong pong = headPongFactory.create(ping);
clearStoredProxies();
pong = reparse(pong);
assertEquals(pong.getGUID(),ping.getGUID());
assertFalse(pong.hasFile());
assertFalse(pong.hasCompleteFile());
assertEmpty(pong.getAltLocs());
assertNull(pong.getRanges());
}
/** Tests that a binary headping gets a 404 for large files */
public void testBinaryLarge() throws Exception {
mockery.checking(new Expectations() {{
atLeast(1).of(downloadManager).isActivelyDownloading(with(same(_largeURN)));
will(returnValue(false));
}});
MockHeadPongRequestor ping = new MockHeadPongRequestor();
ping.setGuid(GUID.makeGuid());
ping.setUrn(_largeURN);
ping.setPongGGEPCapable(false);
HeadPong pong = headPongFactory.create(ping);
pong = reparse(pong);
assertFalse(pong.hasFile());
ping.setPongGGEPCapable(true);
pong = headPongFactory.create(ping);
pong = reparse(pong);
assertTrue(pong.hasFile());
}
/**
* tests the scenarios where an incomplete and complete files are
* behind firewall or open.
*/
public void testFirewalledNoAcceptedIncoming() throws Exception {
mockery.checking(new Expectations() {{
atLeast(1).of(downloadManager).isActivelyDownloading(with(same(_havePartial)));
will(returnValue(false));
}});
NetworkManagerStub networkManager = (NetworkManagerStub)injector.getInstance(NetworkManager.class);
networkManager.setAcceptedIncomingConnection(false);
HeadPing ping = new HeadPing(_haveFull);
HeadPing pingi = new HeadPing(_havePartial);
HeadPong pong = headPongFactory.create(ping);
HeadPong pongi = headPongFactory.create(pingi);
clearStoredProxies();
pong = reparse(pong);
pongi = reparse(pongi);
assertEquals(ping.getGUID(),pong.getGUID());
assertEquals(pingi.getGUID(),pongi.getGUID());
assertTrue(pong.hasFile());
assertTrue(pong.isFirewalled());
assertTrue(pong.hasCompleteFile());
assertEmpty(pong.getAltLocs());
assertNull(pong.getRanges());
assertTrue(pongi.hasFile());
assertTrue(pongi.isFirewalled());
assertFalse(pongi.hasCompleteFile());
assertEmpty(pongi.getAltLocs());
assertNull(pongi.getRanges());
}
public void testFirewalledAcceptedIncoming() throws Exception {
mockery.checking(new Expectations() {{
atLeast(1).of(downloadManager).isActivelyDownloading(with(same(_havePartial)));
will(returnValue(false));
}});
NetworkManagerStub networkManager = (NetworkManagerStub)injector.getInstance(NetworkManager.class);
networkManager.setAcceptedIncomingConnection(true);
HeadPing ping = new HeadPing(_haveFull);
HeadPing pingi = new HeadPing(_havePartial);
HeadPong pong = headPongFactory.create(ping);
HeadPong pongi = headPongFactory.create(pingi);
clearStoredProxies();
pong = reparse(pong);
pongi = reparse(pongi);
assertEquals(pong.getGUID(),ping.getGUID());
assertEquals(pingi.getGUID(),pongi.getGUID());
assertFalse(pong.isFirewalled());
assertTrue(pong.hasFile());
assertTrue(pong.hasCompleteFile());
assertEmpty(pong.getAltLocs());
assertNull(pong.getRanges());
assertTrue(pongi.hasFile());
assertFalse(pongi.isFirewalled());
assertFalse(pongi.hasCompleteFile());
assertEmpty(pongi.getAltLocs());
assertNull(pongi.getRanges());
}
/**
* tests whether the downloading flag is set properly.
*/
public void testActivelyDownloading() throws Exception {
mockery.checking(new Expectations() {{
atLeast(1).of(downloadManager).isActivelyDownloading(with(same(_partial.getSHA1Urn())));
will(returnValue(true));
}});
HeadPing ping = new HeadPing(_havePartial);
HeadPong pong = headPongFactory.create(ping);
clearStoredProxies();
pong = reparse(pong);
assertTrue(pong.isDownloading());
}
public void testNotActivelyDownloading() throws Exception {
mockery.checking(new Expectations() {{
atLeast(1).of(downloadManager).isActivelyDownloading(with(same(_havePartial)));
will(returnValue(false));
}});
HeadPing ping = new HeadPing(_havePartial);
HeadPong pong = headPongFactory.create(ping);
clearStoredProxies();
pong = reparse(pong);
assertFalse(pong.isDownloading());
}
/**
* tests requesting ranges from complete, incomplete files
* as well as requesting too big ranges to fit in packet.
*/
public void testRangesFit() throws Exception {
mockery.checking(new Expectations() {{
atLeast(1).of(downloadManager).isActivelyDownloading(with(same(_havePartial)));
will(returnValue(false));
}});
HeadPing ping = new HeadPing(new GUID(GUID.makeGuid()),_haveFull,HeadPing.INTERVALS);
HeadPing pingi = new HeadPing(new GUID(GUID.makeGuid()),_havePartial,HeadPing.INTERVALS);
HeadPong pong = headPongFactory.create(ping);
HeadPong pongi = headPongFactory.create(pingi);
clearStoredProxies();
pong = reparse(pong);
pongi = reparse(pongi);
assertTrue(pong.hasCompleteFile());
assertFalse(pongi.hasCompleteFile());
assertNull(pong.getRanges());
assertNotNull(pongi.getRanges());
PingRanker.updateContext(blankRFD, pongi);
assertTrue(blankRFD.isPartialSource());
assertEquals(pongi.getRanges(), blankRFD.getAvailableRanges());
PingRanker.updateContext(blankRFD, pong);
assertFalse(blankRFD.isPartialSource());
assertTrue(Arrays.equals(_ranges.toBytes().ints,pongi.getRanges().toBytes().ints));
}
public void testRangesDontFit() throws Exception {
mockery.checking(new Expectations() {{
atLeast(1).of(downloadManager).isActivelyDownloading(with(same(_havePartial)));
will(returnValue(false));
}});
//now make the incomplete file desc carry ranges which are too big to
//fit in a packet
_partial.setRangesByte(_rangesTooBig.toBytes());
try {
HeadPing pingi = new HeadPing(new GUID(GUID.makeGuid()),_havePartial,HeadPing.INTERVALS);
HeadPong pongi = headPongFactory.create(pingi);
clearStoredProxies();
pongi = reparse(pongi);
assertNull(pongi.getRanges());
assertLessThan(HeadPongFactoryImpl.DEFAULT_PACKET_SIZE,pongi.getPayload().length);
} finally {
_partial.setRangesByte(_ranges.toBytes());
}
}
public void testLargeRanges() throws Exception {
mockery.checking(new Expectations() {{
atLeast(1).of(downloadManager).isActivelyDownloading(with(same(_largeURN)));
will(returnValue(false));
}});
_partialLarge.setRangesByte(_rangesLarge.toBytes());
HeadPing ping = new HeadPing(new GUID(GUID.makeGuid()),_largeURN,HeadPing.INTERVALS);
HeadPong pong = headPongFactory.create(ping);
clearStoredProxies();
pong = reparse(pong);
IntervalSet large = pong.getRanges();
assertEquals(_rangesLarge, large);
}
public void testOnlyLargeRanges() throws Exception {
mockery.checking(new Expectations() {{
atLeast(1).of(downloadManager).isActivelyDownloading(with(same(_largeURN)));
will(returnValue(false));
}});
_partialLarge.setRangesByte(_rangesOnlyLarge.toBytes());
HeadPing ping = new HeadPing(new GUID(GUID.makeGuid()),_largeURN,HeadPing.INTERVALS);
HeadPong pong = headPongFactory.create(ping);
clearStoredProxies();
pong = reparse(pong);
IntervalSet large = pong.getRanges();
assertEquals(_rangesOnlyLarge, large);
}
/**
* tests various values for the queue rank
*/
public void testQueueStatusEmpty() throws Exception {
mockery.checking(new Expectations() {{
atLeast(1).of(downloadManager).isActivelyDownloading(with(same(_havePartial)));
will(returnValue(false));
}});
HeadPing ping = new HeadPing(_havePartial);
HeadPong pong = headPongFactory.create(ping);
clearStoredProxies();
pong = reparse(pong);
int allFree = pong.getQueueStatus();
assertEquals(-UploadSettings.HARD_MAX_UPLOADS.getValue(), allFree);
PingRanker.updateContext(blankRFD, pong);
assertEquals(pong.getQueueStatus(), blankRFD.getQueueStatus());
assertFalse(blankRFD.isBusy());
}
public void testQueueStatusSomeTaken() throws Exception {
mockery.checking(new Expectations() {{
atLeast(1).of(downloadManager).isActivelyDownloading(with(same(_havePartial)));
will(returnValue(false));
}});
UploadManagerStub uploadManager = (UploadManagerStub)injector.getInstance(UploadManager.class);
HeadPing ping = new HeadPing(_havePartial);
uploadManager.setUploadsInProgress(10);
HeadPong pong = headPongFactory.create(ping);
clearStoredProxies();
pong = reparse(pong);
assertEquals(-UploadSettings.HARD_MAX_UPLOADS.getValue()+10,pong.getQueueStatus());
PingRanker.updateContext(blankRFD, pong);
assertEquals(pong.getQueueStatus(), blankRFD.getQueueStatus());
assertFalse(blankRFD.isBusy());
}
public void testQueueStatusSomeQueued() throws Exception {
mockery.checking(new Expectations() {{
atLeast(1).of(downloadManager).isActivelyDownloading(with(same(_havePartial)));
will(returnValue(false));
}});
UploadManagerStub uploadManager = (UploadManagerStub)injector.getInstance(UploadManager.class);
HeadPing ping = new HeadPing(_havePartial);
uploadManager.setNumQueuedUploads(5);
HeadPong pong = headPongFactory.create(ping);
clearStoredProxies();
pong = reparse(pong);
assertEquals(5,pong.getQueueStatus());
PingRanker.updateContext(blankRFD, pong);
assertEquals(pong.getQueueStatus(), blankRFD.getQueueStatus());
assertFalse(blankRFD.isBusy());
}
public void testQueueStatusAllTakenNoneQueued() throws Exception {
mockery.checking(new Expectations() {{
atLeast(1).of(downloadManager).isActivelyDownloading(with(same(_havePartial)));
will(returnValue(false));
}});
UploadManagerStub uploadManager = (UploadManagerStub)injector.getInstance(UploadManager.class);
HeadPing ping = new HeadPing(_havePartial);
uploadManager.setUploadsInProgress(UploadSettings.HARD_MAX_UPLOADS.getValue());
uploadManager.setNumQueuedUploads(0);
HeadPong pong = headPongFactory.create(ping);
clearStoredProxies();
pong = reparse(pong);
assertEquals(0,pong.getQueueStatus());
PingRanker.updateContext(blankRFD, pong);
assertEquals(pong.getQueueStatus(), blankRFD.getQueueStatus());
assertFalse(blankRFD.isBusy());
}
public void testQueueStatusBusy() throws Exception {
mockery.checking(new Expectations() {{
atLeast(1).of(downloadManager).isActivelyDownloading(with(same(_havePartial)));
will(returnValue(false));
}});
UploadManagerStub uploadManager = (UploadManagerStub)injector.getInstance(UploadManager.class);
HeadPing ping = new HeadPing(_havePartial);
uploadManager.setUploadsInProgress(UploadSettings.HARD_MAX_UPLOADS.getValue());
uploadManager.setNumQueuedUploads(0);
HeadPong pong = headPongFactory.create(ping);
clearStoredProxies();
pong = reparse(pong);
uploadManager.setNumQueuedUploads(UploadSettings.UPLOAD_QUEUE_SIZE.getValue());
pong = reparse(headPongFactory.create(ping));
assertGreaterThanOrEquals(0x7F,pong.getQueueStatus());
PingRanker.updateContext(blankRFD, pong);
assertEquals(pong.getQueueStatus(), blankRFD.getQueueStatus());
assertTrue(blankRFD.isBusy());
}
/**
* tests handling of alternate locations.
*/
public void testAltLocsFitWithRanges() throws Exception {
mockery.checking(new Expectations() {{
atLeast(1).of(downloadManager).isActivelyDownloading(with(same(_havePartial)));
will(returnValue(false));
}});
PrivilegedAccessor.setValue(HeadPongFactoryImpl.class, "PACKET_SIZE", 600);
//add some big interval that fill most of the packet but not all
_partial.setRangesByte(_rangesMedium.toBytes());
//ping 1 should contain alternate locations.
//the second ping should be too big to contain all altlocs.
HeadPing ping1 = new HeadPing(new GUID(GUID.makeGuid()),_haveFull,HeadPing.ALT_LOCS);
HeadPing ping2 = new HeadPing(new GUID(GUID.makeGuid()),_havePartial,
HeadPing.ALT_LOCS | HeadPing.INTERVALS);
HeadPong pong1 = headPongFactory.create(ping1);
HeadPong pong2 = headPongFactory.create(ping2);
clearStoredProxies();
pong1 = reparse(pong1);
pong2 = reparse(pong2);
assertNull(pong1.getRanges());
assertNotNull(pong2.getRanges());
assertTrue(Arrays.equals(_rangesMedium.toBytes().ints,pong2.getRanges().toBytes().ints));
assertGreaterThan(pong1.getPayload().length,pong2.getPayload().length);
assertLessThan(pong1.getAltLocs().size(),pong2.getAltLocs().size());
assertLessThan(600,pong2.getPayload().length);
}
public void testAltLocsDontFitBecauseOfTooManyRanges() throws Exception {
mockery.checking(new Expectations() {{
atLeast(1).of(downloadManager).isActivelyDownloading(with(same(_havePartial)));
will(returnValue(false));
}});
PrivilegedAccessor.setValue(HeadPongFactoryImpl.class, "PACKET_SIZE", 600);
//now test if no locs will fit because of too many ranges
_partial.setRangesByte(_rangesJustFit.toBytes());
HeadPing ping2 = new HeadPing(new GUID(GUID.makeGuid()),_havePartial,
HeadPing.ALT_LOCS | HeadPing.INTERVALS);
HeadPong pong2 = headPongFactory.create(ping2);
clearStoredProxies();
pong2 = reparse(pong2);
assertNotNull(pong2.getRanges());
assertEmpty(pong2.getAltLocs());
//restore medium ranges to partial file
_partial.setRangesByte(_rangesMedium.toBytes());
}
public void testPushAltLocsRequestedButNoLocs() throws Exception {
//try with a file that doesn't have push locs
HeadPing ping1 = new HeadPing(new GUID(GUID.makeGuid()),_haveFull,HeadPing.PUSH_ALTLOCS);
assertTrue(ping1.requestsPushLocs());
HeadPong pong1 = headPongFactory.create(ping1);
clearStoredProxies();
pong1 = reparse(pong1);
assertEmpty(pong1.getPushLocs());
}
public void testPushAltLocsReturned() throws Exception {
mockery.checking(new Expectations() {{
atLeast(1).of(downloadManager).isActivelyDownloading(with(same(_havePartial)));
will(returnValue(false));
}});
HeadPing ping1 = new HeadPing(new GUID(GUID.makeGuid()),_havePartial,HeadPing.PUSH_ALTLOCS);
assertTrue(ping1.requestsPushLocs());
HeadPong pong1 = headPongFactory.create(ping1);
clearStoredProxies();
pong1 = reparse(pong1);
// this used to be done in the factory and is now handled by PingRanker,
// so simulate ping ranker here
for (PushEndpoint pushEndpoint : pong1.getPushLocs()) {
pushEndpoint.updateProxies(true);
}
assertNull(pong1.getRanges());
assertEmpty(pong1.getAltLocs());
assertNotEmpty(pong1.getPushLocs());
RemoteFileDesc dummy =
remoteFileDescFactory.createRemoteFileDesc(new ConnectableImpl("www.limewire.org", 6346, false), 10, "asdf", 10, GUID.makeGuid(), 10, 2, true,
null, UrnHelper.URN_SETS[1], false, "", -1);
Set received = pong1.getAllLocsRFD(dummy, remoteFileDescFactory);
assertEquals(1,received.size());
RemoteFileDesc rfd = (RemoteFileDesc)received.toArray()[0];
PushEndpoint point = (PushEndpoint) rfd.getAddress();
assertEquals(pushCollectionPE,point);
assertEquals(pushCollectionPE.getProxies() + " expected to have the same size as " + point.getProxies(), pushCollectionPE.getProxies().size(),point.getProxies().size());
Set parsedProxies = new IpPortSet(point.getProxies());
parsedProxies.retainAll(pushCollectionPE.getProxies());
assertEquals(pushCollectionPE.getProxies().size(),parsedProxies.size());
}
public void testPushAltLocsWantOnlyFWT() throws Exception {
mockery.checking(new Expectations() {{
atLeast(1).of(downloadManager).isActivelyDownloading(with(same(_havePartial)));
will(returnValue(false));
}});
//now ask only for fwt push locs - nothing returned
HeadPing ping1 = new HeadPing(new GUID(GUID.makeGuid()),_havePartial,HeadPing.PUSH_ALTLOCS | HeadPing.FWT_PUSH_ALTLOCS);
assertTrue(ping1.requestsFWTOnlyPushLocs());
HeadPong pong1 = headPongFactory.create(ping1);
clearStoredProxies();
pong1 = reparse(pong1);
assertEmpty(pong1.getPushLocs());
}
public void testTLSPushLocs() throws Exception {
HeadPing ping = new HeadPing(new GUID(), _tlsURN, HeadPing.PUSH_ALTLOCS);
assertTrue(ping.requestsPushLocs());
HeadPong pong = headPongFactory.create(ping);
clearStoredProxies();
pong = reparse(pong);
assertNull(pong.getRanges());
assertEmpty(pong.getAltLocs());
assertEquals(1, pong.getPushLocs().size());
Set<? extends IpPort> proxies = pong.getPushLocs().iterator().next().getProxies();
assertEquals(3, proxies.size());
// the proxies: 2.3.4.5:5;3.4.5.6:7;4.5.6.7:8
Set expectedProxies = new IpPortSet(new IpPortImpl("2.3.4.5:5"), new IpPortImpl("3.4.5.6:7"), new IpPortImpl("4.5.6.7:8"));
expectedProxies.retainAll(proxies);
assertEquals(3, expectedProxies.size());
// We expect the 3.4.5.6 & 4.5.6.7 to be the TLS ones.
int tls = 0;
IpPort nonTLS = null;
for(IpPort ipp : proxies) {
if(ipp instanceof Connectable && ((Connectable)ipp).isTLSCapable())
tls++;
else
nonTLS = ipp;
}
assertEquals(2, tls);
assertEquals("2.3.4.5", nonTLS.getAddress());
RemoteFileDesc dummy =
remoteFileDescFactory.createRemoteFileDesc(new ConnectableImpl("www.limewire.org", 6346, false), 10, "asdf", 10, GUID.makeGuid(), 10, 2, true,
null, UrnHelper.URN_SETS[1], false, "", -1);
Set<RemoteFileDesc> rfds = pong.getAllLocsRFD(dummy, remoteFileDescFactory);
assertEquals(1, rfds.size());
RemoteFileDesc rfd = rfds.iterator().next();
assertEquals(tlsCollectionPE.getClientGUID(), rfd.getClientGUID());
PushEndpoint pe = (PushEndpoint) rfd.getAddress();
assertEquals(3, pe.getProxies().size());
Set parsedProxies = new IpPortSet(pe.getProxies());
parsedProxies.retainAll(expectedProxies);
assertEquals(3, parsedProxies.size());
tls = 0;
nonTLS = null;
for(IpPort ipp : pe.getProxies()) {
if(ipp instanceof Connectable && ((Connectable)ipp).isTLSCapable())
tls++;
else
nonTLS = ipp;
}
assertEquals(2, tls);
assertEquals("2.3.4.5", nonTLS.getAddress());
}
public void testTLSPushLocsWithOldHeadPing() throws Exception {
HeadPing ping = new HeadPing(new GUID(), _tlsURN, HeadPing.PUSH_ALTLOCS);
assertTrue(ping.requestsPushLocs());
HeadPong pong = headPongFactory.create(reversion(ping, (short)1));
clearStoredProxies();
pong = reparse(pong);
assertNull(pong.getRanges());
assertEmpty(pong.getAltLocs());
assertEquals(1, pong.getPushLocs().size());
Set<? extends IpPort> proxies = pong.getPushLocs().iterator().next().getProxies();
assertEquals(3, proxies.size());
// the proxies: 2.3.4.5:5;3.4.5.6:7;4.5.6.7:8
Set expectedProxies = new IpPortSet(new IpPortImpl("2.3.4.5:5"), new IpPortImpl("3.4.5.6:7"), new IpPortImpl("4.5.6.7:8"));
expectedProxies.retainAll(proxies);
assertEquals(3, expectedProxies.size());
for(IpPort ipp : proxies) {
if(ipp instanceof Connectable && ((Connectable)ipp).isTLSCapable())
fail("tls capable!: " + ipp);
}
RemoteFileDesc dummy =
remoteFileDescFactory.createRemoteFileDesc(new ConnectableImpl("www.limewire.org", 6346, false), 10, "asdf", 10, GUID.makeGuid(), 10, 2, true,
null, UrnHelper.URN_SETS[1], false, "", -1);
Set rfds = pong.getAllLocsRFD(dummy, remoteFileDescFactory);
assertEquals(1, rfds.size());
RemoteFileDesc rfd = (RemoteFileDesc)rfds.toArray()[0];
assertEquals(tlsCollectionPE.getClientGUID(), rfd.getClientGUID());
PushEndpoint pe = (PushEndpoint) rfd.getAddress();
assertEquals(tlsCollectionPE.getClientGUID(), pe.getClientGUID());
assertEquals(3, pe.getProxies().size());
Set parsedProxies = new IpPortSet(pe.getProxies());
parsedProxies.retainAll(expectedProxies);
assertEquals(3, parsedProxies.size());
for(IpPort ipp : pe.getProxies()) {
if(ipp instanceof Connectable && ((Connectable)ipp).isTLSCapable())
fail("tls capable!: " + ipp);
}
}
public void testMixedLocs() throws Exception {
mockery.checking(new Expectations() {{
atLeast(1).of(downloadManager).isActivelyDownloading(with(same(_havePartial)));
will(returnValue(false));
}});
HeadPing ping = new HeadPing(new GUID(GUID.makeGuid()),_havePartial,
HeadPing.PUSH_ALTLOCS | HeadPing.ALT_LOCS);
HeadPong pong = headPongFactory.create(ping);
clearStoredProxies();
pong = reparse(pong);
assertNotEmpty(pong.getAltLocs());
assertNotEmpty(pong.getPushLocs());
RemoteFileDesc rfd = remoteFileDescFactory.createRemoteFileDesc(new ConnectableImpl("1.2.3.4", 1, false), 1, "filename", 1, null, 1, 1, false,
null, URN.NO_URN_SET, false, "", 1);
Set rfds = pong.getAllLocsRFD(rfd, remoteFileDescFactory);
assertEquals(pong.getAltLocs().size() + pong.getPushLocs().size(), rfds.size());
}
public void testForwardHeadPingDoesntChangeVersion() throws Exception {
HeadPing ping = new HeadPing(_tlsURN);
ping = reversion(ping, (short)(HeadPing.VERSION+5));
assertEquals(HeadPing.VERSION+5, ping.getVersion()); // control.
HeadPing forwarded = new HeadPing(ping);
assertEquals(HeadPing.VERSION+5, forwarded.getVersion());
}
private HeadPong reparse(HeadPong original) throws Exception{
MessageFactory messageFactory = injector.getInstance(MessageFactory.class);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
original.write(baos);
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
return (HeadPong) messageFactory.read(bais, Network.TCP);
}
/** Constructs a new HeadPing exactly the same, but with a different version. */
private HeadPing reversion(HeadPing ping, short version) throws Exception {
MessageFactory messageFactory = injector.getInstance(MessageFactory.class);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ping.write(baos);
byte[] out = baos.toByteArray();
ByteUtils.short2leb(version, out, 29); // location of the version of a VM
HeadPing p2 = (HeadPing)messageFactory.read(new ByteArrayInputStream(out), Network.TCP);
assertEquals(version, p2.getVersion());
return p2;
}
private void createCollections() throws Exception{
AltLocManager altLocManager = injector.getInstance(AltLocManager.class);
AlternateLocationFactory alternateLocationFactory = injector.getInstance(AlternateLocationFactory.class);
for(int i=0;i<10;i++ ) {
AlternateLocation al = alternateLocationFactory.create("1.2.3."+i+":1234",_haveFull);
altLocManager.add(al, null);
}
AlternateLocationCollection col = altLocManager.getDirect(_haveFull);
assertEquals("failed to set test up", 10, col.getAltLocsSize());
for(int i=0;i<10;i++ ) {
AlternateLocation al = alternateLocationFactory.create("1.2.3."+i+":1234",_havePartial);
altLocManager.add(al, null);
}
col = altLocManager.getDirect(_havePartial);
assertEquals("failed to set test up", 10, col.getAltLocsSize());
//add some push altlocs to the incomplete collection
GUID guid = new GUID(GUID.makeGuid());
PushAltLoc firewalled = (PushAltLoc)alternateLocationFactory.create(guid.toHexString()+";1.2.3.4:5",_havePartial);
firewalled.updateProxies(true);
pushCollectionPE = firewalled.getPushAddress();
altLocManager.add(firewalled, null);
col = altLocManager.getPushNoFWT(_havePartial);
assertEquals(1, col.getAltLocsSize());
GUID g = new GUID();
PushAltLoc tls = (PushAltLoc)alternateLocationFactory.create(g.toHexString() + ";pptls=6;2.3.4.5:5;3.4.5.6:7;4.5.6.7:8", _tlsURN);
tls.updateProxies(true);
tlsCollectionPE = tls.getPushAddress();
altLocManager.add(tls, null);
col = altLocManager.getPushNoFWT(_tlsURN);
assertEquals(1, col.getAltLocsSize());
}
}