package com.limegroup.gnutella.altlocs; import java.io.IOException; import java.util.Arrays; import java.util.Set; import java.util.TreeSet; import junit.framework.Test; import org.limewire.core.settings.ConnectionSettings; 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 com.google.inject.Injector; import com.limegroup.gnutella.LimeTestUtils; import com.limegroup.gnutella.PushEndpoint; import com.limegroup.gnutella.PushEndpointFactory; import com.limegroup.gnutella.RemoteFileDesc; import com.limegroup.gnutella.URN; import com.limegroup.gnutella.downloader.RemoteFileDescFactory; import com.limegroup.gnutella.helpers.AlternateLocationHelper; import com.limegroup.gnutella.helpers.UrnHelper; import com.limegroup.gnutella.http.HTTPConstants; import com.limegroup.gnutella.util.LimeTestCase; /** * This class tests the methods of the <tt>AlternateLocation</tt> class. */ public final class AlternateLocationTest extends LimeTestCase { private Injector injector; /** * Alternate locations without timestamps that are not firewalled. */ public static final String[] NON_FIREWALLED_LOCS = { "50.40.39.40:6352", "51.20.12.36:6352", "52.47.12.36:6352", "53.40.201.35:6322", "201.24.40.67:6352", "201.28.40.24:6352" }; public static final String[] FIREWALLED_LOCS = { "192.168.39.40:6352", "127.20.12.36:6352", "10.47.12.36:6352", "172.16.201.35:6322", "172.17.12.36:6332", "172.18.40.67:6352", "172.31.40.24:6352", }; private AlternateLocationHelper alternateLocationHelper; private static String HASH = "urn:sha1:PLSTHIPQGSSZTS5FJUPAKUZWUGYQYPFB"; private static final String[] equalLocs = { "200.30.1.02:6352", "200.30.1.02:6352" }; private AlternateLocationFactory alternateLocationFactory; private RemoteFileDescFactory remoteFileDescFactory; public AlternateLocationTest(String name) { super(name); } public static Test suite() { return buildTestSuite(AlternateLocationTest.class); } public static void main(String[] args) { junit.textui.TestRunner.run(suite()); } @Override public void setUp() { injector = LimeTestUtils.createInjector(); alternateLocationFactory = injector.getInstance(AlternateLocationFactory.class); ConnectionSettings.LOCAL_IS_PRIVATE.setValue(true); alternateLocationHelper = new AlternateLocationHelper(alternateLocationFactory); remoteFileDescFactory = injector.getInstance(RemoteFileDescFactory.class); } /** * Tests the constructor that creates an alternate location from a remote * file desc. */ public void testRemoteFileDescConstructor() throws Exception { PushEndpointFactory pushEndpointFactory = injector.getInstance(PushEndpointFactory.class); for(int i=0; i<UrnHelper.URNS.length; i++) { RemoteFileDesc rfd = remoteFileDescFactory.createRemoteFileDesc(new ConnectableImpl("www.limewire.org", 6346, false), 10, HTTPConstants.URI_RES_N2R+ UrnHelper.URNS[i].httpStringValue(), 10, GUID.makeGuid(), 10, 2, true, null, UrnHelper.URN_SETS[i], false, "", -1); // just make sure this doesn't throw an exception AlternateLocation loc = alternateLocationFactory.create(rfd); assertFalse(loc instanceof PushAltLoc); } PushEndpoint pe = pushEndpointFactory.createPushEndpoint(GUID.makeGuid(), IpPort.EMPTY_SET, PushEndpoint.PLAIN, 0, new ConnectableImpl("127.0.2.1", 6346, false)); RemoteFileDesc rfd = remoteFileDescFactory.createRemoteFileDesc(pe, 10, HTTPConstants.URI_RES_N2R+ UrnHelper.URNS[0].httpStringValue(), 10, pe.getClientGUID(), 10, 2, true, null, UrnHelper.URN_SETS[0], false, "", -1); alternateLocationFactory.create(rfd); try { alternateLocationFactory.create((RemoteFileDesc)null); fail("should have thrown a null pointer"); } catch(NullPointerException e) { // this is expected } IpPort ppi = new IpPortImpl("1.2.3.4",6346); Set<IpPort> proxies = new IpPortSet(); proxies.add(ppi); PushEndpoint pushEndpoint = pushEndpointFactory.createPushEndpoint(GUID.makeGuid(), proxies, PushEndpoint.PLAIN, 0, new IpPortImpl("1.2.3.4", 5)); //test an rfd with push proxies RemoteFileDesc fwalled = remoteFileDescFactory.createRemoteFileDesc(pushEndpoint, 10, HTTPConstants.URI_RES_N2R+ UrnHelper.URNS[0].httpStringValue(), 10, pushEndpoint.getClientGUID(), 10, 2, true, null, UrnHelper.URN_SETS[0], false, "", -1); AlternateLocation loc = alternateLocationFactory.create(fwalled); assertTrue(loc instanceof PushAltLoc); PushAltLoc push = (PushAltLoc)loc; assertEquals("1.2.3.4",push.getPushAddress().getAddress()); assertEquals(0, push.supportsFWTVersion()); // test rfd with push proxies, external address that can do FWT pe = pushEndpointFactory.createPushEndpoint(GUID.makeGuid(), proxies, PushEndpoint.PLAIN, 1, new IpPortImpl("1.2.3.4", 5)); RemoteFileDesc FWTed = remoteFileDescFactory.createRemoteFileDesc(pe, 10, HTTPConstants.URI_RES_N2R+ UrnHelper.URNS[0].httpStringValue(), 10, pe.getClientGUID(), 10, 2, true, null, UrnHelper.URN_SETS[0], false, "", -1); loc = alternateLocationFactory.create(FWTed); assertTrue(loc instanceof PushAltLoc); push = (PushAltLoc)loc; assertEquals("1.2.3.4",push.getPushAddress().getAddress()); assertGreaterThan(0, push.supportsFWTVersion()); assertEquals(5,push.getPushAddress().getPort()); } /** * Tests the factory method that creates a RemoteFileDesc from an alternate * location. */ public void testCreateRemoteFileDesc() throws Exception{ PushEndpointFactory pushEndpointFactory = injector.getInstance(PushEndpointFactory.class); for(int i=0; i<alternateLocationHelper.UNEQUAL_SHA1_LOCATIONS.length; i++) { DirectAltLoc al = (DirectAltLoc) alternateLocationHelper.UNEQUAL_SHA1_LOCATIONS[i]; RemoteFileDesc rfd = al.createRemoteFileDesc(10, remoteFileDescFactory); assertEquals("SHA1s should be equal", al.getSHA1Urn(), rfd.getSHA1Urn()); assertEquals("hosts should be equals",al.getHost().getAddress(), ((Connectable)rfd.getAddress()).getAddress()); assertEquals("ports should be equals",al.getHost().getPort(), al.getHost().getPort(), ((Connectable)rfd.getAddress()).getPort()); } IpPort ppi = new IpPortImpl("1.2.3.4",6346); Set<IpPort> proxies = new IpPortSet(); proxies.add(ppi); PushEndpoint pushEndpoint = pushEndpointFactory.createPushEndpoint(GUID.makeGuid(), proxies, PushEndpoint.PLAIN, 0, new IpPortImpl("1.2.3.4", 5)); //test an rfd with push proxies RemoteFileDesc fwalled = remoteFileDescFactory.createRemoteFileDesc(pushEndpoint, 10, HTTPConstants.URI_RES_N2R+ UrnHelper.URNS[0].httpStringValue(), 10, pushEndpoint.getClientGUID(), 10, 2, true, null, UrnHelper.URN_SETS[0], false, "", -1); AlternateLocation loc = alternateLocationFactory.create(fwalled); RemoteFileDesc other = loc.createRemoteFileDesc(3, remoteFileDescFactory); PushEndpoint address = (PushEndpoint) other.getAddress(); assertEquals("1.2.3.4", address.getAddress()); assertEquals(5, address.getPort()); assertEquals(fwalled.getClientGUID(),other.getClientGUID()); assertSame(fwalled.getAddress(),other.getAddress()); } public void testCloningPushLocs() throws Exception { PushEndpointFactory pushEndpointFactory = injector.getInstance(PushEndpointFactory.class); IpPort ppi = new IpPortImpl("1.2.3.4",6346); Set<IpPort> proxies = new IpPortSet(); proxies.add(ppi); PushEndpoint pushEndpoint = pushEndpointFactory.createPushEndpoint(GUID.makeGuid(), proxies, PushEndpoint.PLAIN, 0, new IpPortImpl("127.0.0.1", 6346)); //test an rfd with push proxies RemoteFileDesc fwalled = remoteFileDescFactory.createRemoteFileDesc(pushEndpoint, 10, HTTPConstants.URI_RES_N2R+ UrnHelper.URNS[0].httpStringValue(), 10, pushEndpoint.getClientGUID(), 10, 2, true, null, UrnHelper.URN_SETS[0], false, "", -1); AlternateLocation loc = alternateLocationFactory.create(fwalled); assertTrue(loc instanceof PushAltLoc); AlternateLocation loc2 = loc.createClone(); assertTrue(loc2 instanceof PushAltLoc); assertEquals(loc,loc2); } /** * Tests the location/urn constructor for success. */ public void testStringUrnConstructor() throws Exception { ConnectionSettings.LOCAL_IS_PRIVATE.setValue(false); URN urn = URN.createSHA1Urn("urn:sha1:ULSTTIPQGSSZTS5FJUPAKUZWUGYQYPTE"); // Now try the new-style values for(int i = 1; i < 254; i++) { String ip = i+"."+(i % 2)+"."+(i % 25)+"."+(i % 100); DirectAltLoc al = (DirectAltLoc) alternateLocationFactory.create(ip + ":50", urn); IpPort ep = al.getHost(); assertEquals(ip, ep.getAddress()); assertEquals(50, ep.getPort()); assertEquals(urn, al.getSHA1Urn()); } // Try without a port. for(int i = 1; i < 254; i++) { String ip = i+"."+(i % 2)+"."+(i % 25)+"."+(i % 100); DirectAltLoc al = (DirectAltLoc)alternateLocationFactory.create(ip, urn); IpPort ep = al.getHost(); assertEquals(ip, ep.getAddress()); assertEquals(6346, ep.getPort()); assertEquals(urn, al.getSHA1Urn()); } // Try with bad values. for(int i = 1; i < 254; i++) { try { String ip = i+"."+(i % 2)+"."+(i % 25)+"."+(i % 100)+".1"; alternateLocationFactory.create(ip + ":50", urn); fail("IOException expected"); } catch(IOException expected) {} } try { alternateLocationFactory.create("0.1.2.3", urn); fail("IOException expected"); } catch(IOException expected) {} try { alternateLocationFactory.create("1.2.3.4/25", urn); fail("IOException expected"); } catch(IOException expected) {} try { alternateLocationFactory.create("limewire.org", urn); fail("IOException expected"); } catch(IOException expected) {} //try some firewalled locs GUID clientGUID = new GUID(GUID.makeGuid()); String httpString=clientGUID.toHexString()+";1.2.3.4:15;1.2.3.5:16"; PushAltLoc pal = (PushAltLoc)alternateLocationFactory.create(httpString,urn); assertTrue(Arrays.equals( clientGUID.bytes(),pal.getPushAddress().getClientGUID())); assertEquals(2,pal.getPushAddress().getProxies().size()); //try some valid push proxies, some invalid ones clientGUID = new GUID(GUID.makeGuid()); httpString=clientGUID.toHexString()+";1.2.3.4:15;1.2.3.5:16"; pal = (PushAltLoc) alternateLocationFactory.create(httpString+";0.1.2.3:100000;1.2.3.6:17",urn); assertTrue(Arrays.equals( clientGUID.bytes(),pal.getPushAddress().getClientGUID())); assertEquals(3,pal.getPushAddress().getProxies().size()); //HashSets do not guarantee order so the resulting http string //may contain the proxies in different order assertNotEquals(-1,pal.httpStringValue().indexOf(clientGUID.toHexString())); assertNotEquals(-1,pal.httpStringValue().indexOf("1.2.3.4:15")); assertNotEquals(-1,pal.httpStringValue().indexOf("1.2.3.5:16")); //try some valid push proxies and an empty one clientGUID = new GUID(GUID.makeGuid()); httpString=clientGUID.toHexString()+";1.2.3.4:15;1.2.3.5:16"; pal = (PushAltLoc) alternateLocationFactory.create(httpString+";;1.2.3.6:17",urn); assertTrue(Arrays.equals( clientGUID.bytes(),pal.getPushAddress().getClientGUID())); assertEquals(3,pal.getPushAddress().getProxies().size()); //try an altloc with no push proxies clientGUID = new GUID(GUID.makeGuid()); pal = (PushAltLoc) alternateLocationFactory.create(clientGUID.toHexString()+";",urn); // try skipping invalid ip:port strings pal = (PushAltLoc) alternateLocationFactory.create( clientGUID.toHexString()+";"+ "1.2.3.4/:12",urn); assertTrue(pal.getPushAddress().getProxies().isEmpty()); //try some invalid ones try { pal = (PushAltLoc) alternateLocationFactory.create("asdf2345dgalshlh",urn); fail("created altloc from garbage"); }catch(IOException expected) {} try { pal = (PushAltLoc) alternateLocationFactory.create("",urn); fail("created altloc from empty string"); }catch(IOException expected) {} try { pal = (PushAltLoc) alternateLocationFactory.create(null,urn); fail("created altloc from null string"); }catch(IOException expected) {} } public void testDemotedEquals() throws Exception { AlternateLocation loc1 = alternateLocationFactory.create(equalLocs[0], URN.createSHA1Urn(HASH)); AbstractAlternateLocation loc2 = (AbstractAlternateLocation)alternateLocationFactory.create(equalLocs[0], URN.createSHA1Urn(HASH)); assertEquals("locations should be equal", loc1, loc2); loc2.demote(); assertEquals("locations should be equal", loc1, loc2); } public void testCompareTo() throws Exception { TreeSet<AlternateLocation> set = new TreeSet<AlternateLocation>(); AbstractAlternateLocation direct1 = (AbstractAlternateLocation) alternateLocationFactory.create(equalLocs[0], URN.createSHA1Urn(HASH)); AlternateLocation direct2 = alternateLocationFactory.create(equalLocs[0], URN.createSHA1Urn(HASH)); set.add(direct1); assertTrue(set.contains(direct2)); direct2.increment(); assertFalse(set.contains(direct2)); assertLessThan(0,direct1.compareTo(direct2)); set.remove(direct1); direct1.demote(); assertGreaterThan(0,direct1.compareTo(direct2)); direct1.promote(); assertLessThan(0,direct1.compareTo(direct2)); // try some push altlocs GUID clientGUID = new GUID(GUID.makeGuid()); String httpString=clientGUID.toHexString()+";1.2.3.4:15;1.2.3.5:16"; URN urn = URN.createSHA1Urn("urn:sha1:ULSTTIPQGSSZTS5FJUPAKUZWUGYQYPTE"); AbstractAlternateLocation push1 = (AbstractAlternateLocation) alternateLocationFactory.create(httpString,urn); AlternateLocation push2 = alternateLocationFactory.create(httpString,urn); assertTrue(push1.equals(push2)); assertEquals(0,push1.compareTo(push2)); push2.increment(); assertLessThan(0,push1.compareTo(push2)); // calling demote() does not affect push locs push1.demote(); assertLessThan(0,push1.compareTo(push2)); // comparing the two types of altlocs is predictable if their count // values are different assertGreaterThan(0,direct2.compareTo(push1)); // it is not easily predictable if they are the same assertNotEquals(0,direct2.compareTo(push2)); } /** * Test the equals method. */ public void testAlternateLocationEquals() throws Exception { for(int i=0; i<equalLocs.length; i++) { AlternateLocation curLoc = alternateLocationFactory.create(equalLocs[i], URN.createSHA1Urn(HASH)); for(int j=0; j<equalLocs.length; j++) { AlternateLocation newLoc = alternateLocationFactory.create(equalLocs[j], URN.createSHA1Urn(HASH)); assertEquals("locations should be equal", curLoc, newLoc); } } } /** * Tests the compareTo method of the AlternateLocation class. */ public void testAlternateLocationCompareTo() throws Exception { for(int i=0; i<equalLocs.length; i++) { AlternateLocation curLoc = alternateLocationFactory.create(equalLocs[i], URN.createSHA1Urn(HASH)); for(int j=0; j<equalLocs.length; j++) { AlternateLocation newLoc = alternateLocationFactory.create(equalLocs[j], URN.createSHA1Urn(HASH)); int z = curLoc.compareTo(newLoc); assertEquals("locations should be equal", 0, z); } } } /** * Test to make sure that we're handling firewalls fine -- rejecting * firewalled locations and accepting non-firewalled locations. */ public void testAlternateLocationToMakeSureItDisallowsFirewalledHosts() throws Exception { for(int i=0; i<AlternateLocationTest.FIREWALLED_LOCS.length; i++) { String loc = AlternateLocationTest.FIREWALLED_LOCS[i]; try { alternateLocationFactory.create(loc, UrnHelper.URNS[0]); fail("alt loc should not have accepted firewalled loc: "+loc); } catch(IOException e) { // this is expected } } for(int i=0; i<alternateLocationHelper.SOME_IPS.length; i++) { String loc = alternateLocationHelper.SOME_IPS[i]; alternateLocationFactory.create(loc, UrnHelper.URNS[0]); } } public void testAlternateLocationKeepsTLSInfo() throws Exception { for(int i = 0; i < alternateLocationHelper.SOME_IPS.length; i++) { AlternateLocation nonTLS = alternateLocationFactory.create(alternateLocationHelper.SOME_IPS[i], UrnHelper.SHA1, false); AlternateLocation tls = alternateLocationFactory.create(alternateLocationHelper.SOME_IPS[i], UrnHelper.SHA1, true); DirectAltLoc d1 = (DirectAltLoc)nonTLS; DirectAltLoc d2 = (DirectAltLoc)tls; IpPort p1 = d1.getHost(); IpPort p2 = d2.getHost(); if(p1 instanceof Connectable) assertFalse(((Connectable)p1).isTLSCapable()); assertInstanceof(Connectable.class, p2); assertTrue(((Connectable)p2).isTLSCapable()); } } }