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