package com.limegroup.gnutella.altlocs; import java.io.ByteArrayInputStream; import java.io.IOException; import java.net.MalformedURLException; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.StringTokenizer; import java.util.TreeSet; import java.util.Vector; import junit.framework.Test; import com.limegroup.gnutella.GUID; import com.limegroup.gnutella.HugeTestUtils; import com.limegroup.gnutella.PushEndpoint; import com.limegroup.gnutella.RemoteFileDesc; import com.limegroup.gnutella.http.HTTPConstants; import com.limegroup.gnutella.messages.QueryReply; import com.limegroup.gnutella.util.BaseTestCase; import com.limegroup.gnutella.util.FixedSizeSortedSet; import com.limegroup.gnutella.util.IpPort; import com.limegroup.gnutella.util.IpPortImpl; import com.limegroup.gnutella.util.IpPortSet; import com.limegroup.gnutella.util.NetworkUtils; import com.limegroup.gnutella.util.PrivilegedAccessor; /** * Test the public methods of the <tt>FileDesc</tt> class. */ public final class AlternateLocationCollectionTest extends BaseTestCase { private Set _urnSet; private Set _alternateLocations; private AlternateLocationCollection _alCollection; public AlternateLocationCollectionTest(String name) { super(name); } public static Test suite() { return buildTestSuite(AlternateLocationCollectionTest.class); } public static void main(String[] args) { junit.textui.TestRunner.run(suite()); } protected void setUp() { _alternateLocations = new HashSet(); for(int i=0; i<HugeTestUtils.EQUAL_SHA1_LOCATIONS.length; i++) { try { _alternateLocations.add( HugeTestUtils.create(HugeTestUtils.EQUAL_URLS[i])); } catch (IOException e) { fail("could not set up test"); } } boolean created = false; Iterator iter = _alternateLocations.iterator(); for(; iter.hasNext(); ) { AlternateLocation al = (AlternateLocation)iter.next(); if(!created) { _alCollection = AlternateLocationCollection.create(al.getSHA1Urn()); created = true; } _alCollection.add(al); } assertTrue("failed to set test up",_alCollection.getAltLocsSize()==_alternateLocations.size()); } /** * Tests that adding an <tt>AlternateLocationCollection</tt> works correctly. */ //Sumeet:TODO: This test does not test anything. We should at some point //write a common method for parsing a collection out of a HTTP header, and //then add this test and make it sensible // public void testCreateCollectionFromHttpValue() { // AlternateLocationCollection collection = // AlternateLocationCollection.create // (HugeTestUtils.EQUAL_SHA1_LOCATIONS[0].getSHA1Urn()); // AlternateLocationCollection testCollection = collection; // for(int i=0; i<HugeTestUtils.EQUAL_SHA1_LOCATIONS.length; i++) { // collection.add(HugeTestUtils.EQUAL_SHA1_LOCATIONS[i]); // } // testCollection.addAll(collection); // } /** * Tests to make sure that unequal SHA1s cannot be added to an * <tt>AlternateLocationCollection</tt>. */ public void testAddWrongLocation() { AlternateLocationCollection collection = AlternateLocationCollection.create (HugeTestUtils.UNIQUE_SHA1); for(int i=0; i<HugeTestUtils.UNEQUAL_SHA1_LOCATIONS.length; i++) { try { collection.add(HugeTestUtils.UNEQUAL_SHA1_LOCATIONS[i]); fail("should not have accepted unequal location: "+ HugeTestUtils.UNEQUAL_SHA1_LOCATIONS[i]); } catch(IllegalArgumentException e) { // this is the expected behavior } } } /** * Tests the method for adding alternate locations to this alternate * location collection. */ public void testAddAlternateLocation() { AlternateLocationCollection alc = AlternateLocationCollection.create(_alCollection.getSHA1Urn()); Iterator iter = _alternateLocations.iterator(); int i = 0; for(AlternateLocation al = (AlternateLocation)iter.next(); iter.hasNext(); al = (AlternateLocation)iter.next()) { alc.add(al); assertEquals("was not able to add as new", ++i, alc.getAltLocsSize() ); } } /** * Tests the method for checking whether or not the specified alternate * location collection has alternate locations stored. */ public void testHasAlternateLocations() { assertTrue("should have alternate locations", _alCollection.hasAlternateLocations()); AlternateLocationCollection testCollection = AlternateLocationCollection.create(_alCollection.getSHA1Urn()); assertTrue("should not have alternate locations", !testCollection.hasAlternateLocations()); } /** * Tests the method for getting the HTTP string value for the alternate * location collection. */ public void testHTTPStringValue() throws Exception { String val = _alCollection.httpStringValue(); StringTokenizer st = new StringTokenizer(val, ","); while(st.hasMoreTokens()) { String str = st.nextToken(); str = str.trim(); AlternateLocation al= AlternateLocation.create(str, _alCollection.getSHA1Urn()); assertTrue(_alCollection.contains(al)); } } /** * Tests that locations are succesfully removed only after it is demoted */ public void testCanRemoveLocation() { Iterator iter = _alternateLocations.iterator(); int total = _alCollection.getAltLocsSize(); int i = 0; for( ; iter.hasNext() ; ) { AlternateLocation al=(AlternateLocation)iter.next(); i++; assertFalse("location already demoted "+al,al.isDemoted()); boolean removed = _alCollection.remove(al);//demoted assertFalse("location removed without demoting ",removed); //make sure it's still there assertTrue("demoted location removed "+ al,_alCollection.contains(al)); removed = _alCollection.remove(al);//now it should be removed assertTrue("unable to remove al: " + al + " from collection: " + _alCollection, removed); assertEquals("size is off",total-i,_alCollection.getAltLocsSize() ); } } /** * Tests that locations cannot be readded after being removed. * TODO: check repromotion */ public void testLocationPromotionDemotionWithAddRemove() { Iterator iter = _alternateLocations.iterator(); int total = _alCollection.getAltLocsSize(); int i = 0; for( ; iter.hasNext(); ) { AlternateLocation al = (AlternateLocation)iter.next(); i++; assertFalse("location already demoted "+al,al.isDemoted()); boolean removed = _alCollection.remove(al);//demoted assertFalse("location removed without demoting ",removed); //make sure it's still there assertTrue("demoted location removed "+ al,_alCollection.contains(al)); //add it back _alCollection.add(al); assertFalse("location not promoted after add "+al,al.isDemoted()); removed = _alCollection.remove(al);//demoted again assertFalse("location removed without demoting ",removed); //make sure it's still there assertTrue("demoted location removed "+ al,_alCollection.contains(al)); removed = _alCollection.remove(al);//now it should be removed assertTrue("unable to remove al: " + al + " from collection: " + _alCollection, removed); assertEquals("size is off",total-i,_alCollection.getAltLocsSize() ); } } public void testClonedSharedLocsWork() { AlternateLocationCollection c1= AlternateLocationCollection.create(_alCollection.getSHA1Urn()); AlternateLocationCollection c2= AlternateLocationCollection.create(_alCollection.getSHA1Urn()); AlternateLocation[] alts = new AlternateLocation[5]; for(int i=0; i<5; i++) { AlternateLocation al = null; try { al= HugeTestUtils.create(HugeTestUtils.EQUAL_URLS[i]); } catch (MalformedURLException e) { fail("unable to set up test"); } catch (IOException e) { fail("unable to set up test"); } alts[i] = al; c1.add(al); } try { c1.add(HugeTestUtils.create(HugeTestUtils.UNEQUAL_URLS[2])); fail("exception should have been thrown by now"); } catch(Exception e) { //expected behaviour } //add the same elements as clones to c2 for(int i=0; i<5; i++) c2.add(alts[i].createClone()); assertEquals(c1,c2); for(int i=0; i<5; i++) c1.add(alts[i].createClone()); assertNotEquals(c1,c2);//alt locs should have changed. } public void testCollectionOrder() { AlternateLocation shouldFirst; AlternateLocation shouldSecond; AlternateLocation shouldThird; AlternateLocation shouldLast; int totalAlts = _alternateLocations.size(); Iterator iter = _alternateLocations.iterator(); for(int i=0; i<totalAlts-4; i++) { AlternateLocation loc = (AlternateLocation)iter.next(); iter.remove(); _alCollection.remove(loc);//demote _alCollection.remove(loc);//remove } assertEquals("Coll of incorrect size",4,_alCollection.getAltLocsSize()); iter = _alternateLocations.iterator(); shouldFirst = (AlternateLocation)iter.next(); shouldSecond = (AlternateLocation)iter.next(); shouldThird = (AlternateLocation)iter.next(); shouldLast = (AlternateLocation)iter.next(); _alCollection.add(shouldFirst);//count == 2, no demotion _alCollection.add(shouldSecond); _alCollection.add(shouldSecond);//count == 3 for second, no demotion _alCollection.add(shouldThird);//count == 2 _alCollection.remove(shouldThird);//count == 2, and demoteddemote _alCollection.add(shouldLast);// _alCollection.add(shouldLast);//count == 3 _alCollection.remove(shouldLast);//count == 2, and demoteddemote synchronized(_alCollection) { Iterator i = _alCollection.iterator(); AlternateLocation loc = (AlternateLocation)i.next(); assertEquals("iterator method not sorted ",loc,shouldFirst); loc = (AlternateLocation)i.next(); assertEquals("iterator method not sorted",loc,shouldSecond); loc = (AlternateLocation)i.next(); assertEquals("iterator method not sorted",loc,shouldThird); loc = (AlternateLocation)i.next(); assertEquals("iterator method not sorted",loc, shouldLast); assertFalse(i.hasNext()); } FixedSizeSortedSet set = null; try { set = (FixedSizeSortedSet) PrivilegedAccessor.getValue(_alCollection,"LOCATIONS"); } catch (NoSuchFieldException e) { fail("could not access test field"); } catch (IllegalAccessException e) { fail("could not access test field"); } assertEquals(set.first(),shouldFirst); assertEquals(set.last(), shouldLast); _alCollection.remove(shouldLast);//it's out _alCollection.remove(shouldFirst);//demoted _alCollection.remove(shouldFirst);//remove try { set = (FixedSizeSortedSet) PrivilegedAccessor.getValue(_alCollection,"LOCATIONS"); } catch (NoSuchFieldException e) { fail("could not access test field"); } catch (IllegalAccessException e) { fail("could not access test field"); } assertEquals(set.first(), shouldSecond); assertEquals(set.last(), shouldThird); } }