package com.limegroup.gnutella.library;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import junit.framework.Test;
import org.limewire.collection.CollectionUtils;
import org.limewire.core.settings.ConnectionSettings;
import org.limewire.core.settings.LibrarySettings;
import org.limewire.core.settings.NetworkSettings;
import org.limewire.core.settings.SearchSettings;
import org.limewire.core.settings.SpeedConstants;
import org.limewire.gnutella.tests.LimeTestUtils;
import org.limewire.io.ConnectableImpl;
import org.limewire.io.GUID;
import org.limewire.listener.EventListener;
import org.limewire.util.CommonUtils;
import org.limewire.util.FileUtils;
import org.limewire.util.TestUtils;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.limegroup.gnutella.BlockingConnectionUtils;
import com.limegroup.gnutella.ClientSideTestCase;
import com.limegroup.gnutella.DownloadServices;
import com.limegroup.gnutella.Downloader;
import com.limegroup.gnutella.RemoteFileDesc;
import com.limegroup.gnutella.Response;
import com.limegroup.gnutella.URN;
import com.limegroup.gnutella.connection.BlockingConnection;
import com.limegroup.gnutella.downloader.DownloadStateEvent;
import com.limegroup.gnutella.downloader.RemoteFileDescFactory;
import com.limegroup.gnutella.downloader.TestFile;
import com.limegroup.gnutella.downloader.TestUploader;
import com.limegroup.gnutella.messages.FeatureSearchData;
import com.limegroup.gnutella.messages.Message;
import com.limegroup.gnutella.messages.QueryReply;
import com.limegroup.gnutella.messages.QueryRequest;
import com.limegroup.gnutella.messages.QueryRequestFactory;
import com.limegroup.gnutella.messages.Message.Network;
import com.limegroup.gnutella.messages.vendor.CapabilitiesVM;
import com.limegroup.gnutella.messages.vendor.CapabilitiesVMFactory;
import com.limegroup.gnutella.messages.vendor.MessagesSupportedVendorMessage;
import com.limegroup.gnutella.xml.LimeXMLDocument;
/**
* Tests that What is new support is fully functional. We use a leaf here - we
* assume that an Ultrapeer will be equally functional.
*
*/
public class ServerSideWhatIsNewTest
extends ClientSideTestCase {
private final int PORT=6669;
private final int TIMEOUT=1000;
private File berkeley = null;
private File susheel = null;
private File tempFile1 = null;
private File tempFile2 = null;
@Inject private MessagesSupportedVendorMessage messagesSupportedVendorMessage;
@Inject private CapabilitiesVMFactory capabilitiesVMFactory;
@Inject private Library library;
@Inject @GnutellaFiles private FileView gnutellaFileView;
@Inject @IncompleteFiles private FileView incompleteFileView;
@Inject private CreationTimeCache creationTimeCache;
@Inject private QueryRequestFactory queryRequestFactory;
@Inject private Injector injector;
@Inject private DownloadServices downloadServices;
public ServerSideWhatIsNewTest(String name) {
super(name);
}
@Override
public int getNumberOfPeers() {
return 1;
}
public static Test suite() {
return buildTestSuite(ServerSideWhatIsNewTest.class);
}
public static void main(String[] args) {
junit.textui.TestRunner.run(suite());
}
@Override
public void setSettings() throws Exception {
//Setup LimeWire backend. For testing other vendors, you can skip all
//this and manually configure a client in leaf mode to listen on port
//6669, with no slots and no connections. But you need to re-enable
//the interactive prompts below.
NetworkSettings.PORT.setValue(PORT);
ConnectionSettings.DO_NOT_BOOTSTRAP.setValue(true);
ConnectionSettings.CONNECT_ON_STARTUP.setValue(false);
ConnectionSettings.LOCAL_IS_PRIVATE.setValue(false);
// Required so that the "swarmDownloadCatchesEarlyCreationTest" actually works =)
ConnectionSettings.CONNECTION_SPEED.setValue(SpeedConstants.T3_SPEED_INT);
// make sure results get through
SearchSettings.MINIMUM_SEARCH_QUALITY.setValue(-2);
}
@Override
public void setUp() throws Exception {
injector = LimeTestUtils.createInjector();
super.setUp(injector);
gnutellaFileCollection.remove(berkeleyFD);
gnutellaFileCollection.remove(susheelFD);
berkeley = new File(_scratchDir, berkeleyFD.getFileName());
CommonUtils.copyFile(berkeleyFD.getFile(), berkeley);
susheel = new File(_scratchDir, susheelFD.getFileName());
CommonUtils.copyFile(susheelFD.getFile(), susheel);
// Make sure mod times of each file are different.
berkeley.setLastModified(susheel.lastModified()-1000);
berkeleyFD = gnutellaFileCollection.add(berkeley).get(1, TimeUnit.SECONDS);
susheelFD = gnutellaFileCollection.add(susheel).get(1, TimeUnit.SECONDS);
assertNotNull(berkeleyFD);
assertNotNull(susheelFD);
exchangeCapabilitiesMessage();
}
@Override
public boolean shouldRespondToPing() {
return false;
}
public void exchangeCapabilitiesMessage() throws Exception {
//testUP = connect(rs, 6355, true);
BlockingConnection connection = testUP[0];
// send a MessagesSupportedMessage and capabilities VM
connection.send(messagesSupportedVendorMessage);
connection.send(capabilitiesVMFactory.getCapabilitiesVM());
connection.flush();
Thread.sleep(100);
// we expect to get a CVM back
Message m = null;
do {
m = connection.receive(TIMEOUT);
} while (!(m instanceof CapabilitiesVM)) ;
assertTrue(((CapabilitiesVM)m).supportsWhatIsNew());
// client side seems to follow the setup process A-OK
}
// test that the CreationTimeCache is as expected
public void testCreationTimeCacheInitialState() throws Exception {
// we should be sharing two files - two text files.
assertEquals(2, gnutellaFileView.size());
URN berkeleyURN = gnutellaFileView.getFileDesc(berkeley).getSHA1Urn();
URN susheelURN = gnutellaFileView.getFileDesc(susheel).getSHA1Urn();
Map urnToLong = creationTimeCache.getUrnToTime();
assertEquals(2, urnToLong.size());
assertNotNull(""+urnToLong, urnToLong.get(berkeleyURN));
assertNotNull(""+urnToLong, urnToLong.get(susheelURN));
Map longToUrns = creationTimeCache.getTimeToUrn();
if (longToUrns.size() == 1) {
Iterator iter = longToUrns.entrySet().iterator();
Set urnSet = (Set)((Map.Entry)iter.next()).getValue();
assertTrue(urnSet.contains(berkeleyURN));
assertTrue(urnSet.contains(susheelURN));
assertEquals(2, urnSet.size());
}
else if (longToUrns.size() == 2) {
Iterator iter = longToUrns.entrySet().iterator();
Set urnSet = (Set)((Map.Entry)iter.next()).getValue();
assertTrue(
( urnSet.contains(berkeleyURN) &&
!urnSet.contains(susheelURN) )
||
( !urnSet.contains(berkeleyURN) &&
urnSet.contains(susheelURN) )
);
assertEquals(1, urnSet.size());
urnSet = (Set)((Map.Entry)iter.next()).getValue();
assertTrue(
( urnSet.contains(berkeleyURN) &&
!urnSet.contains(susheelURN) )
||
( !urnSet.contains(berkeleyURN) &&
urnSet.contains(susheelURN) )
);
assertEquals(1, urnSet.size());
}
else assertTrue("Bad Cache!", false);
}
// make sure that a what is new query is answered correctly
public void testWhatIsNewQueryBasic() throws Exception {
BlockingConnection connection = testUP[0];
BlockingConnectionUtils.drain(connection);
QueryRequest whatIsNewQuery =
queryRequestFactory.createQueryRequest(GUID.makeGuid(), (byte)2,
QueryRequest.WHAT_IS_NEW_QUERY_STRING, "", null, null, false, Network.UNKNOWN, false,
FeatureSearchData.WHAT_IS_NEW);
whatIsNewQuery.hop();
connection.send(whatIsNewQuery);
connection.flush();
// give time to process
Thread.sleep(1000);
QueryReply reply =
BlockingConnectionUtils.getFirstInstanceOfMessageType(connection,
QueryReply.class);
assertNotNull(reply);
assertEquals(2, reply.getResultCount());
Iterator iter = reply.getResults();
Response currResp = (Response) iter.next();
assertTrue(currResp.getName().equals("berkeley.txt") ||
currResp.getName().equals("susheel.txt"));
currResp = (Response) iter.next();
assertTrue(currResp.getName().equals("berkeley.txt") ||
currResp.getName().equals("susheel.txt"));
assertFalse(iter.hasNext());
}
// make sure that a what is new query meta query is answered correctly
public void testWhatIsNewQueryMeta() throws Exception {
BlockingConnection connection = testUP[0];
BlockingConnectionUtils.drain(connection);
{
QueryRequest whatIsNewQuery =
queryRequestFactory.createQueryRequest(GUID.makeGuid(), (byte)2,
QueryRequest.WHAT_IS_NEW_QUERY_STRING, "", null, null, false, Network.UNKNOWN, false,
FeatureSearchData.WHAT_IS_NEW, false, 0 | QueryRequest.AUDIO_MASK);
whatIsNewQuery.hop();
connection.send(whatIsNewQuery);
connection.flush();
// give time to process
Thread.sleep(2000);
QueryReply reply =
BlockingConnectionUtils.getFirstInstanceOfMessageType(connection,
QueryReply.class);
assertNull(reply);
}
{
QueryRequest whatIsNewQuery =
queryRequestFactory.createQueryRequest(GUID.makeGuid(), (byte)2,
QueryRequest.WHAT_IS_NEW_QUERY_STRING, "", null, null, false, Network.UNKNOWN, false,
FeatureSearchData.WHAT_IS_NEW, false, 0 | QueryRequest.DOC_MASK);
whatIsNewQuery.hop();
connection.send(whatIsNewQuery);
connection.flush();
// give time to process
Thread.sleep(1000);
QueryReply reply =
BlockingConnectionUtils.getFirstInstanceOfMessageType(connection,
QueryReply.class);
assertNotNull(reply);
assertEquals(2, reply.getResultCount());
Iterator iter = reply.getResults();
Response currResp = (Response) iter.next();
assertTrue(currResp.getName().equals("berkeley.txt") ||
currResp.getName().equals("susheel.txt"));
currResp = (Response) iter.next();
assertTrue(currResp.getName().equals("berkeley.txt") ||
currResp.getName().equals("susheel.txt"));
assertFalse(iter.hasNext());
}
}
// test that the creation time cache handles the additional sharing of files
// fine
public void testAddSharedFiles() throws Exception {
URN berkeleyURN = gnutellaFileView.getFileDesc(berkeley).getSHA1Urn();
URN susheelURN = gnutellaFileView.getFileDesc(susheel).getSHA1Urn();
// we start with one or two timestamps
Map longToUrns = creationTimeCache.getTimeToUrn();
int startTimeStamps = longToUrns.size();
assertTrue(""+longToUrns, startTimeStamps == 1 || startTimeStamps == 2);
setupAndAddTempFiles();
URN tempFile1URN = gnutellaFileView.getFileDesc(tempFile1).getSHA1Urn();
URN tempFile2URN = gnutellaFileView.getFileDesc(tempFile2).getSHA1Urn();
Map urnToLong = creationTimeCache.getUrnToTime();
assertEquals(4, urnToLong.size());
assertNotNull(""+urnToLong, urnToLong.get(berkeleyURN));
assertNotNull(""+urnToLong, urnToLong.get(susheelURN));
assertNotNull(""+urnToLong, urnToLong.get(tempFile1URN));
assertNotNull(""+urnToLong, urnToLong.get(tempFile2URN));
// we end with 2, 3 or 4 timestamps, depending on fs performance
assertGreaterThan(startTimeStamps, longToUrns.size());
assertLessThan(5, longToUrns.size());
}
// test that after the sharing of additional files, the what is new query
// results in something else
public void testWhatIsNewQueryNewFiles() throws Exception {
setupAndAddTempFiles();
BlockingConnection connection = testUP[0];
BlockingConnectionUtils.drain(connection);
QueryRequest whatIsNewQuery =
queryRequestFactory.createQueryRequest(GUID.makeGuid(), (byte)2,
QueryRequest.WHAT_IS_NEW_QUERY_STRING, "", null, null, false, Network.UNKNOWN, false,
FeatureSearchData.WHAT_IS_NEW);
connection.send(whatIsNewQuery);
connection.flush();
// give time to process
Thread.sleep(1000);
QueryReply reply =
BlockingConnectionUtils.getFirstInstanceOfMessageType(connection,
QueryReply.class);
assertNotNull(reply);
assertEquals(3, reply.getResultCount());
boolean gotTempFile1 = false, gotTempFile2 = false;
Iterator iter = reply.getResults();
while (iter.hasNext()) {
Response currResp = (Response) iter.next();
if (currResp.getName().equals(tempFile1.getName()))
gotTempFile1 = true;
if (currResp.getName().equals(tempFile2.getName()))
gotTempFile2 = true;
}
assertTrue("file 1? " + gotTempFile1 + ", file 2? " +
gotTempFile2, gotTempFile1 && gotTempFile2);
}
// test that the fileChanged method of FM does the right thing. this isn't
// a total black box test, but hacking up the changing of ID3 data isn't
// worth the cost. this test should be good enough....
public void testFileChanged() throws Exception {
setupAndAddTempFiles();
CreationTimeCache ctCache = creationTimeCache;
URN tempFile1URN = gnutellaFileView.getFileDesc(tempFile1).getSHA1Urn();
// Long cTime = ctCache.getCreationTime(tempFile1URN);
FileWriter fw = new FileWriter(tempFile1, true);
fw.write("extra");
fw.close();
long newModified = tempFile1.lastModified()+3000;
tempFile1.setLastModified(newModified);
final FileDesc beforeChanged = gnutellaFileView.getFileDesc(tempFile1);
assertNotNull(beforeChanged);
final CountDownLatch fileChangedLatch = new CountDownLatch(2);
gnutellaFileView.addListener(new EventListener<FileViewChangeEvent>() {
public void handleEvent(FileViewChangeEvent evt) {
switch(evt.getType()) {
case FILE_ADDED:
case FILE_REMOVED:
fileChangedLatch.countDown();
}
}
});
library.fileChanged(tempFile1, LimeXMLDocument.EMPTY_LIST);
assertTrue(fileChangedLatch.await(5, TimeUnit.SECONDS));
FileDesc afterChanged = gnutellaFileView.getFileDesc(tempFile1);
assertNotNull(afterChanged);
assertNotSame(beforeChanged, afterChanged);
assertNotNull(gnutellaFileView.getFileDesc(tempFile1).getSHA1Urn());
assertNotEquals(tempFile1URN, gnutellaFileView.getFileDesc(tempFile1).getSHA1Urn());
// TODO: Before introducing FileDescs w/o URNs, it was possible to do a FILE_CHANGED
// event and map old data to new... but because views require URNs, we have
// to now remove the old FD & then later add the new one, having a time
// where nothing exists.
/// The old check here asserted the new FDs creation time was the same as the old one.
/// Can't do that anymore. :-(
// assertEquals(cTime, ctCache.getCreationTime(gnutellaFileView.getFileDesc(tempFile1).getSHA1Urn()));
assertEquals(newModified, ctCache.getCreationTime(gnutellaFileView.getFileDesc(tempFile1).getSHA1Urn()).longValue());
// now just send another What Is New query and make sure everything
// is kosher - probably overkill but whatever....
BlockingConnection connection = testUP[0];
BlockingConnectionUtils.drain(connection);
QueryRequest whatIsNewQuery =
queryRequestFactory.createQueryRequest(GUID.makeGuid(), (byte)2,
QueryRequest.WHAT_IS_NEW_QUERY_STRING, "", null, null, false, Network.UNKNOWN, false,
FeatureSearchData.WHAT_IS_NEW);
connection.send(whatIsNewQuery);
connection.flush();
// give time to process
Thread.sleep(1000);
QueryReply reply =
BlockingConnectionUtils.getFirstInstanceOfMessageType(connection,
QueryReply.class);
assertNotNull(reply);
assertEquals(3, reply.getResultCount());
boolean gotTempFile1 = false, gotTempFile2 = false;
Iterator iter = reply.getResults();
while (iter.hasNext()) {
Response currResp = (Response) iter.next();
if (currResp.getName().equals(tempFile1.getName()))
gotTempFile1 = true;
if (currResp.getName().equals(tempFile2.getName()))
gotTempFile2 = true;
}
assertTrue("file 1? " + gotTempFile1 + ", file 2? " +
gotTempFile2, gotTempFile1 && gotTempFile2);
}
// test that the fileChanged method of FM does the right thing when you
// change the file to a existing URN.
public void testFileChangedToExistingURN() throws Exception {
setupAndAddTempFiles();
CreationTimeCache ctCache = creationTimeCache;
URN tempFile1URN = gnutellaFileView.getFileDesc(tempFile1).getSHA1Urn();
// we are changing tempFile1 to become tempFile2 - but since we
// call fileChanged(), then the common URN should get tempFile1's
// cTime
// Long cTime = ctCache.getCreationTime(tempFile1URN);
byte[] contents = FileUtils.readFileFully(tempFile2);
FileOutputStream fos = new FileOutputStream(tempFile1, false);
fos.write(contents);
fos.close();
long newModified = tempFile1.lastModified()+3000;
tempFile1.setLastModified(newModified);
FileDesc beforeChanged = gnutellaFileView.getFileDesc(tempFile1);
assertNotNull(beforeChanged);
final CountDownLatch latch = new CountDownLatch(2);
gnutellaFileView.addListener(new EventListener<FileViewChangeEvent>() {
public void handleEvent(FileViewChangeEvent evt) {
switch(evt.getType()) {
case FILE_ADDED:
case FILE_REMOVED:
latch.countDown();
}
}
});
library.fileChanged(tempFile1, LimeXMLDocument.EMPTY_LIST);
assertTrue(latch.await(2, TimeUnit.SECONDS));
FileDesc afterChanged = gnutellaFileView.getFileDesc(tempFile1);
assertNotNull(afterChanged);
assertNotSame(beforeChanged, afterChanged);
assertNotNull(gnutellaFileView.getFileDesc(tempFile1).getSHA1Urn());
assertNotEquals(tempFile1URN, gnutellaFileView.getFileDesc(tempFile1).getSHA1Urn());
assertEquals(gnutellaFileView.getFileDesc(tempFile1).getSHA1Urn(), gnutellaFileView.getFileDesc(tempFile2).getSHA1Urn());
// TODO: Before introducing FileDescs w/o URNs, it was possible to do a FILE_CHANGED
// event and map old data to new... but because views require URNs, we have
// to now remove the old FD & then later add the new one, having a time
// where nothing exists.
/// The old check here asserted the new FDs creation time was the same as the old one.
/// Can't do that anymore. :-(
// assertEquals(cTime, ctCache.getCreationTime(gnutellaFileView.getFileDesc(tempFile1).getSHA1Urn()));
assertEquals(ctCache.getCreationTime(gnutellaFileView.getFileDesc(tempFile2).getSHA1Urn()),
ctCache.getCreationTime(gnutellaFileView.getFileDesc(tempFile1).getSHA1Urn()));
// now just send another What Is New query and make sure everything
// is kosher - probbably overkill but whatever....
BlockingConnection connection = testUP[0];
BlockingConnectionUtils.drain(connection);
QueryRequest whatIsNewQuery =
queryRequestFactory.createQueryRequest(GUID.makeGuid(), (byte)2,
QueryRequest.WHAT_IS_NEW_QUERY_STRING, "", null, null, false, Network.UNKNOWN, false,
FeatureSearchData.WHAT_IS_NEW);
connection.send(whatIsNewQuery);
connection.flush();
// give time to process
Thread.sleep(1000);
QueryReply reply =
BlockingConnectionUtils.getFirstInstanceOfMessageType(connection,
QueryReply.class);
assertNotNull(reply);
assertEquals("results: " + reply.getResultsAsList(), 3, reply.getResultCount());
boolean gotTempFile1 = false, gotTempFile2 = false;
Iterator iter = reply.getResults();
while (iter.hasNext()) {
Response currResp = (Response) iter.next();
if (currResp.getName().equals(tempFile1.getName()))
gotTempFile1 = true;
if (currResp.getName().equals(tempFile2.getName()))
gotTempFile2 = true;
}
assertTrue("file 1? " + gotTempFile1 + ", file 2? " +
gotTempFile2, !gotTempFile1 && gotTempFile2);
}
// test that the FileManager.removeFileIfShared method works
public void testRemoveSharedFile() throws Exception {
setupAndAddTempFiles();
assertEquals(4,gnutellaFileView.size());
// 4 shared files
assertEquals(4,gnutellaFileView.size());
// 4 different urns
{
Map urnToLong = creationTimeCache.getUrnToTime();
assertEquals(urnToLong.toString(), 4, urnToLong.size());
}
Map longToUrns = creationTimeCache.getTimeToUrn();
int startTimeStamps = longToUrns.size();
// 2,3 or 4 different creation times
{
assertGreaterThan(1,longToUrns.size());
assertLessThan(5, longToUrns.size());
}
// tempFile1 and 2 have the same URN
gnutellaFileCollection.remove(tempFile1);
{
Map urnToLong = creationTimeCache.getUrnToTime();
assertEquals(3, urnToLong.size());
}
// they may or may not have the same timestamp
assertLessThanOrEquals(startTimeStamps, longToUrns.size());
// tempFile2 should result in a removal of an URN
// as well as a timestamp
gnutellaFileCollection.remove(tempFile2);
{
Map urnToLong = creationTimeCache.getUrnToTime();
assertEquals(2, urnToLong.size());
}
assertLessThan(startTimeStamps, longToUrns.size());
}
// manually delete a file, make sure it isn't shared and that the CTC has
// the correct sizes, etc...
public void testManualFileDeleteLoadSettings() throws Exception {
setupAndAddTempFiles();
tempFile1.delete(); tempFile1 = null;
tempFile2.delete(); tempFile2 = null;
berkeley.delete(); berkeley = null;
((LibraryImpl)library).loadManagedFiles();
Thread.sleep(2000);
assertEquals("num shared files", 1, gnutellaFileView.size());
URN susheelURN = gnutellaFileView.getFileDesc(susheel).getSHA1Urn();
{
Map urnToLong = creationTimeCache.getUrnToTime();
assertEquals(""+urnToLong, 1, urnToLong.size());
assertNotNull(""+urnToLong, urnToLong.get(susheelURN));
}
{
Map longToUrns = creationTimeCache.getTimeToUrn();
assertEquals(""+longToUrns, 1, longToUrns.size());
}
}
// download a file and make sure the creation time given back is stored...
public void testDownloadCapturesCreationTime() throws Exception {
CreationTimeCache ctCache = creationTimeCache;
Map longToUrns = ctCache.getTimeToUrn();
List<FileDesc> fds = CollectionUtils.listOf(gnutellaFileView);
for (FileDesc fd : fds) {
gnutellaFileCollection.remove(fd.getFile());
}
longToUrns = ctCache.getTimeToUrn();
final int UPLOADER_PORT = 10000;
byte[] guid = GUID.makeGuid();
TestUploader uploader = injector.getInstance(TestUploader.class);
uploader.start("whatever.txt", UPLOADER_PORT, false);
Long cTime = new Long(2);
uploader.setCreationTime(cTime);
Set<URN> urns = new HashSet<URN>();
urns.add(TestFile.hash());
RemoteFileDesc rfd = injector.getInstance(RemoteFileDescFactory.class)
.createRemoteFileDesc(new ConnectableImpl("127.0.0.1", UPLOADER_PORT, false), 1, "whatever.txt", TestFile.length(), guid, 1, 3, false,
null, urns, false, "LIME", -1);
int sharedBefore = gnutellaFileView.size();
final CountDownLatch shareLatch = new CountDownLatch(1);
gnutellaFileView.addListener(new EventListener<FileViewChangeEvent>() {
public void handleEvent(FileViewChangeEvent evt) {
if (evt.getType() == FileViewChangeEvent.Type.FILE_ADDED)
shareLatch.countDown();
}
});
final CountDownLatch downloadedLatch = new CountDownLatch(1);
final Downloader downloader = downloadServices.download(new RemoteFileDesc[] { rfd }, false, new GUID(guid));
downloader.addListener(new EventListener<DownloadStateEvent>() {
@Override
public void handleEvent(DownloadStateEvent event) {
if(event.getSource().isCompleted()) {
downloadedLatch.countDown();
}
}
});
assertTrue("state: " + downloader.getState(), downloadedLatch.await(30,TimeUnit.SECONDS));
assertTrue("didn't share!", shareLatch.await(5, TimeUnit.SECONDS));
assertEquals( sharedBefore + 1, gnutellaFileCollection.size());
File newFile = new File(_savedDir, "whatever.txt");
assertTrue(newFile.getAbsolutePath()+" didn't exist", newFile.exists());
URN newFileURN = gnutellaFileView.getFileDesc(newFile).getSHA1Urn();
assertEquals(TestFile.hash(), newFileURN);
assertEquals(newFileURN.toString(), cTime, ctCache.getCreationTime(newFileURN));
Map urnToLong = ctCache.getUrnToTime();
assertEquals(""+urnToLong, sharedBefore + 1, urnToLong.size());
longToUrns = ctCache.getTimeToUrn();
assertEquals(""+longToUrns+" vs "+urnToLong, sharedBefore + 1, longToUrns.size());
}
// download a file and make sure the creation time given back is stored...
public void testSwarmDownloadCapturesOlderCreationTime() throws Exception {
CreationTimeCache ctCache = creationTimeCache;
List<FileDesc> fds = CollectionUtils.listOf(gnutellaFileView);
for (FileDesc fd : fds) {
gnutellaFileCollection.remove(fd.getFile());
}
final int UPLOADER_PORT = 20000;
byte[] guid = GUID.makeGuid();
TestUploader uploader[] = new TestUploader[4];
Long cTime[] = new Long[uploader.length];
RemoteFileDesc rfds[] = new RemoteFileDesc[uploader.length];
for (int i = 0; i < uploader.length; i++) {
uploader[i] = injector.getInstance(TestUploader.class);
uploader[i].start("anita.txt", UPLOADER_PORT+i, false);
uploader[i].setRate(50);
cTime[i] = new Long(5+i);
uploader[i].setCreationTime(cTime[i]);
Set<URN> urns = new HashSet<URN>();
urns.add(TestFile.hash());
rfds[i] = injector.getInstance(RemoteFileDescFactory.class).createRemoteFileDesc(new ConnectableImpl("127.0.0.1", UPLOADER_PORT+i, false), 1, "anita.txt",
TestFile.length(), guid, 1, 3, false, null, urns, false, "LIME", -1);
}
final CountDownLatch incompleteLatch = new CountDownLatch(1);
final CountDownLatch shareLatch = new CountDownLatch(1);
incompleteFileView.addListener(new EventListener<FileViewChangeEvent>() {
@Override
public void handleEvent(FileViewChangeEvent event) {
if(event.getType() == FileViewChangeEvent.Type.FILE_ADDED) {
incompleteLatch.countDown();
}
}
});
gnutellaFileView.addListener(new EventListener<FileViewChangeEvent>() {
public void handleEvent(FileViewChangeEvent evt) {
if (evt.getType() == FileViewChangeEvent.Type.FILE_ADDED) {
shareLatch.countDown();
}
}
});
final CountDownLatch downloadLatch = new CountDownLatch(1);
Downloader downloader = downloadServices.download(rfds, false, new GUID(guid));
downloader.addListener(new EventListener<DownloadStateEvent>() {
@Override
public void handleEvent(DownloadStateEvent event) {
if(event.getSource().isCompleted()) {
downloadLatch.countDown();
}
}
});
assertTrue("incomplete never added", incompleteLatch.await(5, TimeUnit.SECONDS));
Thread.sleep(2000);
// make sure that the partial file has a creation time - by now one of
// the downloaders must have got X-Create-Time
assertNotNull(ctCache.getCreationTime(TestFile.hash()));
assertTrue("download: " + downloader.getState(), downloadLatch.await(30, TimeUnit.SECONDS));
assertTrue("never shared", shareLatch.await(5, TimeUnit.SECONDS));
assertEquals(1, gnutellaFileView.size());
{
Map urnToLong = ctCache.getUrnToTime();
assertEquals(""+urnToLong, 1, urnToLong.size());
}
{
Map longToUrns = ctCache.getTimeToUrn();
assertEquals(""+longToUrns, 1, longToUrns.size());
}
File newFile = new File(_savedDir, "anita.txt");
assertTrue(newFile.exists());
URN newFileURN = gnutellaFileView.getFileDesc(newFile).getSHA1Urn();
assertEquals(cTime[0], ctCache.getCreationTime(newFileURN));
}
public void testInstallersNotSharedInCache() throws Exception {
// Make sure that the modified times are not the same
susheel.setLastModified(123456);
berkeley.setLastModified(123457);
CreationTimeCache ctCache = creationTimeCache;
File winInstaller = TestUtils.getResourceFile("com/limegroup/gnutella/UltrapeerRoutingTest.class");
File linInstaller = TestUtils.getResourceFile("com/limegroup/gnutella/UrnSetTest.class");
File osxInstaller = TestUtils.getResourceFile("com/limegroup/gnutella/UrnTest.class");
assertTrue("necessary resource file doesn't exist", winInstaller.exists());
assertTrue("necessary resource file doesn't exist", linInstaller.exists());
assertTrue("necessary resource file doesn't exist", osxInstaller.exists());
// Gotta make use of the force-share folder for this test
if( LibraryUtils.PROGRAM_SHARE.exists() ) {
File [] toDelete = LibraryUtils.PROGRAM_SHARE.listFiles();
for (int j = 0; j < toDelete.length; j++) {
toDelete[j].delete();
}
} else {
LibraryUtils.PROGRAM_SHARE.mkdir();
}
LibrarySettings.ALLOW_PROGRAMS.set(true);
File winDst = new File(LibraryUtils.PROGRAM_SHARE, "LimeWireWin3.69.0010.exe");
File linDst = new File(LibraryUtils.PROGRAM_SHARE, "LimeWireLinux.bin");
File osxDst = new File(LibraryUtils.PROGRAM_SHARE, "LimeWireOSX.dmg");
assertTrue(FileUtils.copy(winInstaller, winDst));
assertTrue(FileUtils.copy(linInstaller, linDst));
assertTrue(FileUtils.copy(osxInstaller, osxDst));
winDst.deleteOnExit();
linDst.deleteOnExit();
osxDst.deleteOnExit();
try {
assertNotNull(gnutellaFileCollection.add(winDst).get(5, TimeUnit.SECONDS));
assertNotNull(gnutellaFileCollection.add(linDst).get(5, TimeUnit.SECONDS));
assertNotNull(gnutellaFileCollection.add(osxDst).get(5, TimeUnit.SECONDS));
assertEquals(5, gnutellaFileCollection.size());
{
Map urnToLong = creationTimeCache.getUrnToTime();
assertEquals(2, urnToLong.size());
}
{
Map longToUrns = creationTimeCache.getTimeToUrn();
assertEquals(2, longToUrns.size());
}
// make sure the installer urns are not in the cache
{
assertTrue(winInstaller.exists());
assertNull(gnutellaFileView.getFileDesc(winInstaller));
}
{
assertTrue(winInstaller.exists());
assertNull(gnutellaFileView.getFileDesc(linInstaller));
}
{
assertTrue(winInstaller.exists());
assertNull(gnutellaFileView.getFileDesc(osxInstaller));
}
// make sure berkeley and susheel are in the cache.
{
assertTrue(berkeley.exists());
assertNotNull(ctCache.getCreationTime(gnutellaFileView.getFileDesc(berkeley).getSHA1Urn()));
}
{
assertTrue(susheel.exists());
assertNotNull(ctCache.getCreationTime(gnutellaFileView.getFileDesc(susheel).getSHA1Urn()));
}
} finally {
File [] toDelete = LibraryUtils.PROGRAM_SHARE.listFiles();
for (int j = 0; j < toDelete.length; j++) {
toDelete[j].delete();
}
LibraryUtils.PROGRAM_SHARE.delete();
LibrarySettings.ALLOW_PROGRAMS.revertToDefault();
}
}
private void setupAndAddTempFiles() throws Exception {
tempFile1 = new File(_scratchDir, "tempFile1.txt");
tempFile2 = new File(_scratchDir, "tempFile2.txt");
Map urnToLong = creationTimeCache.getUrnToTime();
long previousTime = (Long)urnToLong.get(berkeleyFD.getSHA1Urn());
previousTime = Math.max(previousTime, (Long)urnToLong.get(susheelFD.getSHA1Urn()));
FileWriter writer = new FileWriter(tempFile1);
writer.write("temp1");
writer.close();
writer = new FileWriter(tempFile2);
writer.write("temp2");
writer.close();
tempFile1.setLastModified(previousTime+1000);
assertNotEquals("couldn't set up test",tempFile1.lastModified(), previousTime);
tempFile2.setLastModified(previousTime+2000);
assertNotEquals("couldn't set up test",tempFile2.lastModified(), previousTime);
// now move them to the share dir
assertNotNull(gnutellaFileCollection.add(tempFile1).get(1, TimeUnit.SECONDS));
assertNotNull(gnutellaFileCollection.add(tempFile2).get(1, TimeUnit.SECONDS));
assertEquals("Files were not loaded by filemanager", 4, gnutellaFileCollection.size());
}
}