package com.limegroup.gnutella;
import java.io.File;
import java.io.FileFilter;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import junit.framework.Test;
import com.limegroup.gnutella.altlocs.AlternateLocation;
import com.limegroup.gnutella.auth.ContentManager;
import com.limegroup.gnutella.auth.StubContentAuthority;
import com.limegroup.gnutella.auth.StubContentResponseObserver;
import com.limegroup.gnutella.downloader.VerifyingFile;
import com.limegroup.gnutella.library.LibraryData;
import com.limegroup.gnutella.messages.QueryRequest;
import com.limegroup.gnutella.messages.vendor.ContentResponse;
import com.limegroup.gnutella.routing.QueryRouteTable;
import com.limegroup.gnutella.settings.ConnectionSettings;
import com.limegroup.gnutella.settings.ContentSettings;
import com.limegroup.gnutella.settings.SearchSettings;
import com.limegroup.gnutella.settings.SharingSettings;
import com.limegroup.gnutella.stubs.ActivityCallbackStub;
import com.limegroup.gnutella.stubs.SimpleFileManager;
import com.limegroup.gnutella.util.CommonUtils;
import com.limegroup.gnutella.util.FileUtils;
import com.limegroup.gnutella.util.I18NConvert;
import com.limegroup.gnutella.util.PrivilegedAccessor;
import com.limegroup.gnutella.util.StringUtils;
public class FileManagerTest extends com.limegroup.gnutella.util.BaseTestCase {
protected static final String EXTENSION = "XYZ";
private static final int MAX_LOCATIONS = 10;
private File f1 = null;
private File f2 = null;
private File f3 = null;
private File f4 = null;
private File f5 = null;
private File f6 = null;
//changed to protected so that MetaFileManagerTest can
//use these variables as well.
protected FileManager fman = null;
protected Object loaded = new Object();
private Response[] responses;
private FileDesc[] files;
public FileManagerTest(String name) {
super(name);
}
public static Test suite() {
return buildTestSuite(FileManagerTest.class);
}
public static void globalSetUp() throws Exception {
ConnectionSettings.LOCAL_IS_PRIVATE.setValue(false);
try {
RouterService.getAcceptor().setAddress(InetAddress.getLocalHost());
} catch (UnknownHostException e) {
} catch (SecurityException e) {
}
}
public void setUp() throws Exception {
SharingSettings.EXTENSIONS_TO_SHARE.setValue(EXTENSION);
ConnectionSettings.LOCAL_IS_PRIVATE.setValue(false);
cleanFiles(_sharedDir, false);
fman = new SimpleFileManager();
// ensure each test gets a brand new content manager.
PrivilegedAccessor.setValue(RouterService.class, "contentManager", new ContentManager());
PrivilegedAccessor.setValue(RouterService.class, "callback", new FManCallback());
}
public void tearDown() {
if (f1!=null) f1.delete();
if (f2!=null) f2.delete();
if (f3!=null) f3.delete();
if (f4!=null) f4.delete();
if (f5!=null) f5.delete();
if (f6!=null) f6.delete();
}
public void testGetParentFile() throws Exception {
f1 = createNewTestFile(1);
assertEquals("getParentFile doesn't work",
new File(f1.getParentFile().getCanonicalPath()),
new File(_sharedDir.getCanonicalPath()));
}
public void testGetSharedFilesWithNoShared() throws Exception {
FileDesc[] sharedFiles = fman.getSharedFileDescriptors(_sharedDir);
assertEquals("should not be sharing any files " + Arrays.asList(sharedFiles),
0, sharedFiles.length);
}
public void testSharingWithContentManager() throws Exception {
f1 = createNewTestFile(1);
f2 = createNewTestFile(3);
f3 = createNewTestFile(11);
f4 = createNewTestFile(23);
URN u1 = getURN(f1);
URN u2 = getURN(f2);
URN u3 = getURN(f3);
ContentSettings.CONTENT_MANAGEMENT_ACTIVE.setValue(true);
ContentSettings.USER_WANTS_MANAGEMENTS.setValue(true);
ContentManager cm = RouterService.getContentManager();
cm.initialize();
// request the urn so we can use the response.
cm.request(u1, new StubContentResponseObserver(), 1000);
cm.handleContentResponse(new ContentResponse(u1, false));
waitForLoad();
assertEquals("unexpected # of shared files", 3, fman.getNumFiles());
assertEquals("unexpected size of shared files", 37, fman.getSize());
assertFalse("shouldn't be shared", fman.isFileShared(f1));
assertTrue("should be shared", fman.isFileShared(f2));
assertTrue("should be shared", fman.isFileShared(f3));
assertTrue("should be shared", fman.isFileShared(f4));
FileDesc fd2 = fman.getFileDescForFile(f2);
FileDesc fd3 = fman.getFileDescForFile(f3);
FileDesc fd4 = fman.getFileDescForFile(f4);
// test invalid content response.
fman.validate(fd2);
cm.handleContentResponse(new ContentResponse(u2, false));
assertFalse("shouldn't be shared anymore", fman.isFileShared(f2));
assertEquals("wrong # shared files", 2, fman.getNumFiles());
assertEquals("wrong shared file size", 34, fman.getSize());
// test valid content response.
fman.validate(fd3);
cm.handleContentResponse(new ContentResponse(u3, true));
assertTrue("should still be shared", fman.isFileShared(f3));
assertEquals("wrong # shared files", 2, fman.getNumFiles());
assertEquals("wrong shared file size", 34, fman.getSize());
// test valid content response.
fman.validate(fd4);
Thread.sleep(10000);
assertTrue("should still be shared", fman.isFileShared(f4));
assertEquals("wrong # shared files", 2, fman.getNumFiles());
assertEquals("wrong shared file size", 34, fman.getSize());
// Make sure adding a new file to be shared doesn't work if it
// returned bad before.
fman.addFileIfShared(f1);
assertFalse("shouldn't be shared", fman.isFileShared(f1));
}
public void testOneSharedFile() throws Exception {
f1 = createNewTestFile(1);
waitForLoad();
f2 = createNewTestFile(3);
f3 = createNewTestFile(11);
// fman should only have loaded f1
assertEquals("Unexpected number of shared files",
1, fman.getNumFiles());
assertEquals("Unexpected size of filemanager",
1, fman.getSize());
// it is important to check the query at all bounds,
// including tests for case.
responses=fman.query(QueryRequest.createQuery("unit",(byte)3));
assertEquals("Unexpected number of responses", 1, responses.length);
responses=fman.query(QueryRequest.createQuery("FileManager", (byte)3));
assertEquals("Unexpected number of responses", 1, responses.length);
responses=fman.query(QueryRequest.createQuery("test", (byte)3));
assertEquals("Unexpected number of responses", 1, responses.length);
responses=fman.query(QueryRequest.createQuery("file", (byte)3));
assertEquals("Unexpected number of responses", 1, responses.length);
responses=fman.query(QueryRequest.createQuery(
"FileManager UNIT tEsT", (byte)3));
assertEquals("Unexpected number of responses", 1, responses.length);
// should not be able to remove unshared file
assertNull("should have not been able to remove f3",
fman.removeFileIfShared(f3));
assertEquals("first file should be f1", f1, fman.get(0).getFile());
files=fman.getSharedFileDescriptors(_sharedDir);
assertEquals("unexpected length of shared files", 1, files.length);
assertEquals("files should be the same", files[0].getFile(), f1);
files=fman.getSharedFileDescriptors(_sharedDir.getParentFile());
assertEquals("file manager listed shared files in file's parent dir",
0, files.length);
}
public void testAddingOneSharedFile() throws Exception {
f1 = createNewTestFile(1);
waitForLoad();
f2 = createNewTestFile(3);
f3 = createNewTestFile(11);
FileManagerEvent result = addIfShared(new File("C:\\bad.ABCDEF"));
assertTrue(result.toString(), result.isFailedEvent());
result = addIfShared(f2);
assertTrue(result.toString(), result.isAddEvent());
assertNotNull(result.getFileDescs()[0]);
assertEquals("unexpected number of files", 2, fman.getNumFiles());
assertEquals("unexpected fman size", 4, fman.getSize());
responses=fman.query(QueryRequest.createQuery("unit", (byte)3));
assertNotEquals("responses gave same index",
responses[0].getIndex(), responses[1].getIndex() );
for (int i=0; i<responses.length; i++) {
assertTrue("responses should be expected indexes",
responses[i].getIndex()==0 || responses[i].getIndex()==1);
}
files=fman.getSharedFileDescriptors(_sharedDir);
assertEquals("unexpected files length", 2, files.length);
assertEquals("first shared file is not f1", files[0].getFile(), f1);
assertEquals("second shared file is not f2", files[1].getFile(), f2);
}
public void testRemovingOneSharedFile() throws Exception {
f1 = createNewTestFile(1);
f2 = createNewTestFile(3);
waitForLoad();
f3 = createNewTestFile(11);
//Remove file that's shared. Back to 1 file.
assertEquals(2, fman.getNumFiles());
assertNull("shouldn't have been able to remove unshared file", fman.removeFileIfShared(f3));
assertNotNull("should have been able to remove shared file", fman.removeFileIfShared(f2));
assertEquals("unexpected fman size", 1, fman.getSize());
assertEquals("unexpected number of files", 1, fman.getNumFiles());
responses=fman.query(QueryRequest.createQuery("unit", (byte)3));
assertEquals("unexpected response length", 1, responses.length);
files=fman.getSharedFileDescriptors(_sharedDir);
assertEquals("unexpected files length", 1, files.length);
assertEquals("files differ", files[0].getFile(), f1);
}
public void testAddAnotherSharedFileDifferentIndex() throws Exception {
f1 = createNewTestFile(1);
f2 = createNewTestFile(3);
waitForLoad();
f3 = createNewTestFile(11);
fman.removeFileIfShared(f2);
//Add a new second file, with new index.
FileManagerEvent result = addIfShared(f3);
assertTrue(result.toString(), result.isAddEvent());
assertNotNull(result.getFileDescs()[0]);
assertEquals("unexpected file size", 12, fman.getSize());
assertEquals("unexpedted number of files", 2, fman.getNumFiles());
responses=fman.query(QueryRequest.createQuery("unit", (byte)3));
assertEquals("unexpected response length", 2, responses.length);
assertNotEquals("unexpected response[0] index", 1, responses[0].getIndex());
assertNotEquals("unexpected response[1] index", 1, responses[1].getIndex());
fman.get(0);
fman.get(2);
assertNull("should be null (unshared)", fman.get(1));
try {
fman.get(3);
fail("should not have gotten anything");
} catch (IndexOutOfBoundsException e) { }
assertFalse("should not be valid", fman.isValidIndex(3));
assertTrue("should be valid", fman.isValidIndex(0));
assertTrue("should be valid (was at one time)", fman.isValidIndex(1));
responses=fman.query(QueryRequest.createQuery("*unit*", (byte)3));
assertEquals("unexpected responses length", 2, responses.length);
files = fman.getSharedFileDescriptors(_sharedDir);
assertEquals("unexpected files length", 2, files.length);
assertEquals("files differ", files[0].getFile(), f1);
assertEquals("files differ", files[1].getFile(), f3);
files=fman.getAllSharedFileDescriptors();
assertEquals("unexpected files length", 2, files.length);
// we don't know the order the filedescs are returned ...
if( files[0].getFile().equals(f1) ) {
assertEquals("files differ", files[0].getFile(), f1);
assertEquals("files differ", files[1].getFile(), f3);
} else {
assertEquals("files differ", files[0].getFile(), f3);
assertEquals("files differ", files[1].getFile(), f1);
}
}
public void testRenameSharedFiles() throws Exception {
f1 = createNewTestFile(1);
f2 = createNewTestFile(3);
waitForLoad();
f3 = createNewTestFile(11);
fman.removeFileIfShared(f2);
addIfShared(f3);
FileManagerEvent result = renameIfShared(f2, new File("c:\\asdfoih"));
assertTrue(result.toString(), result.isFailedEvent());
assertEquals(f2, result.getFiles()[0]);
result = renameIfShared(f1, f2);
assertTrue(result.toString(), result.isRenameEvent());
assertEquals(f1, result.getFileDescs()[0].getFile());
assertEquals(f2, result.getFileDescs()[1].getFile());
files=fman.getSharedFileDescriptors(_sharedDir);
assertEquals("unexpected files length", 2, files.length);
assertEquals("files differ", files[0].getFile(), f3);
assertEquals("files differ", files[1].getFile(), f2);
result = renameIfShared(f2, new File("C\\garbage.XSADF"));
assertTrue(result.toString(), result.isRemoveEvent());
assertEquals(f2, result.getFileDescs()[0].getFile());
files=fman.getSharedFileDescriptors(_sharedDir);
assertEquals("unexpected files length", 1, files.length);
assertEquals("files differ", files[0].getFile(), f3);
}
public void testIgnoreHugeFiles() throws Exception {
f3 = createNewTestFile(11);
waitForLoad();
f1 = createNewTestFile(1);
f2 = createNewTestFile(3);
//Try to add a huge file. (It will be ignored.)
f4 = createFakeTestFile(Integer.MAX_VALUE+1l);
FileManagerEvent result = addIfShared(f4);
assertTrue(result.toString(), result.isFailedEvent());
assertEquals(f4, result.getFiles()[0]);
assertEquals("unexpected number of files", 1, fman.getNumFiles());
assertEquals("unexpected fman size", 11, fman.getSize());
//Add really big files.
f5=createFakeTestFile(Integer.MAX_VALUE-1);
f6=createFakeTestFile(Integer.MAX_VALUE);
result = addIfShared(f5);
assertTrue(result.toString(), result.isAddEvent());
assertEquals(f5, result.getFileDescs()[0].getFile());
result = addIfShared(f6);
assertTrue(result.toString(), result.isAddEvent());
assertEquals(f6, result.getFileDescs()[0].getFile());
assertEquals("unexpected number of files", 3, fman.getNumFiles());
assertEquals("unexpected fman size", Integer.MAX_VALUE, fman.getSize());
responses=fman.query(QueryRequest.createQuery("*.*", (byte)3));
assertEquals("unexpected responses length", 3, responses.length);
assertEquals("files differ", responses[0].getName(), f3.getName());
assertEquals("files differ", responses[1].getName(), f5.getName());
assertEquals("files differ", responses[2].getName(), f6.getName());
}
/**
* Tests adding incomplete files to the FileManager.
*/
public void testAddIncompleteFile() throws Exception {
assertEquals("unexected shared files", 0, fman.getNumFiles());
assertEquals("unexpected shared incomplete", 0, fman.getNumIncompleteFiles());
assertEquals("unexpected pending", 0, fman.getNumPendingFiles());
// add one incomplete file and make sure the numbers go up.
Set urns = new HashSet();
urns.add( HugeTestUtils.URNS[0] );
fman.addIncompleteFile(new File("a"), urns, "a", 0, new VerifyingFile(0));
assertEquals("unexected shared files", 0, fman.getNumFiles());
assertEquals("unexpected shared incomplete", 1, fman.getNumIncompleteFiles());
assertEquals("unexpected pending", 0, fman.getNumPendingFiles());
// add another incomplete file with the same hash and same
// name and make sure it's not added.
fman.addIncompleteFile(new File("a"), urns, "a", 0, new VerifyingFile(0));
assertEquals("unexected shared files", 0, fman.getNumFiles());
assertEquals("unexpected shared incomplete", 1, fman.getNumIncompleteFiles());
assertEquals("unexpected pending", 0, fman.getNumPendingFiles());
// add another incomplete file with another hash, it should be added.
urns = new HashSet();
urns.add( HugeTestUtils.URNS[1] );
fman.addIncompleteFile(new File("c"), urns, "c", 0, new VerifyingFile(0));
assertEquals("unexected shared files", 0, fman.getNumFiles());
assertEquals("unexpected shared incomplete", 2, fman.getNumIncompleteFiles());
assertEquals("unexpected pending", 0, fman.getNumPendingFiles());
}
/**
* Tests the removeFileIfShared for incomplete files.
*/
public void testRemovingIncompleteFiles() {
assertEquals("unexected shared files", 0, fman.getNumFiles());
assertEquals("unexpected shared incomplete", 0, fman.getNumIncompleteFiles());
assertEquals("unexpected pending", 0, fman.getNumPendingFiles());
Set urns = new HashSet();
urns.add( HugeTestUtils.URNS[0] );
fman.addIncompleteFile(new File("a"), urns, "a", 0, new VerifyingFile(0));
urns = new HashSet();
urns.add( HugeTestUtils.URNS[1] );
fman.addIncompleteFile(new File("b"), urns, "b", 0, new VerifyingFile(0));
assertEquals("unexpected shared incomplete", 2, fman.getNumIncompleteFiles());
fman.removeFileIfShared( new File("a") );
assertEquals("unexpected shared incomplete", 1, fman.getNumIncompleteFiles());
fman.removeFileIfShared( new File("c") );
assertEquals("unexpected shared incomplete", 1, fman.getNumIncompleteFiles());
fman.removeFileIfShared( new File("b") );
assertEquals("unexpected shared incomplete", 0, fman.getNumIncompleteFiles());
}
/**
* Tests that responses are not returned for IncompleteFiles.
*/
public void testQueryRequestsDoNotReturnIncompleteFiles() {
assertEquals("unexected shared files", 0, fman.getNumFiles());
assertEquals("unexpected shared incomplete", 0, fman.getNumIncompleteFiles());
assertEquals("unexpected pending", 0, fman.getNumPendingFiles());
Set urns = new HashSet();
URN urn = HugeTestUtils.URNS[0];
urns.add( urn );
fman.addIncompleteFile(new File("sambe"), urns, "a", 0, new VerifyingFile(0));
assertEquals("unexpected shared incomplete", 1, fman.getNumIncompleteFiles());
QueryRequest qr = QueryRequest.createQuery(urn, "sambe");
Response[] hits = fman.query(qr);
assertNotNull(hits);
assertEquals("unexpected number of resp.", 0, hits.length);
}
/**
* Tests that IncompleteFileDescs are returned for FileDescForUrn only
* if there are no complete files.
*/
public void testGetFileDescForUrn() throws Exception {
assertEquals("unexected shared files", 0, fman.getNumFiles());
assertEquals("unexpected shared incomplete",
0, fman.getNumIncompleteFiles());
assertEquals("unexpected pending",
0, fman.getNumPendingFiles());
Set urns = new HashSet();
URN urn = HugeTestUtils.URNS[0];
urns.add( urn );
fman.addIncompleteFile(new File("sambe"), urns, "a", 0, new VerifyingFile(0));
assertEquals("unexpected shared incomplete", 1, fman.getNumIncompleteFiles());
// First test that we DO get this IFD.
FileDesc fd = fman.getFileDescForUrn(urn);
assertEquals( urns, fd.getUrns() );
// add a file to the library and load it up.
f3 = createNewTestFile(11);
waitForLoad();
assertEquals("unexected shared files", 1, fman.getNumFiles());
assertEquals("unexpected shared incomplete", 0, fman.getNumIncompleteFiles());
assertEquals("unexpected pending", 0, fman.getNumPendingFiles());
// ensure it got shared.
files=fman.getSharedFileDescriptors(_sharedDir);
assertEquals( f3, files[0].getFile() );
fd = fman.get(0);
urn = fd.getSHA1Urn();
urns = fd.getUrns();
// now add an ifd with those urns.
fman.addIncompleteFile(new File("sam"), urns, "b", 0, new VerifyingFile(0));
FileDesc retFD = fman.getFileDescForUrn(urn);
assertNotNull(retFD);
assertNotInstanceof(IncompleteFileDesc.class, retFD);
assertEquals(retFD, fd);
}
/**
* Tests URN requests on the FileManager.
*/
public void testUrnRequests() throws Exception {
addFilesToLibrary();
for(int i = 0; i < fman.getNumFiles(); i++) {
FileDesc fd = fman.get(i);
Response testResponse = new Response(fd);
URN urn = fd.getSHA1Urn();
assertEquals("FileDescs should match", fd,
fman.getFileDescForUrn(urn));
// first set does not include any requested types
// third includes both
Set requestedUrnSet0 = new HashSet();
Set requestedUrnSet1 = new HashSet();
Set requestedUrnSet2 = new HashSet();
Set requestedUrnSet3 = new HashSet();
requestedUrnSet1.add(UrnType.ANY_TYPE);
requestedUrnSet2.add(UrnType.SHA1);
requestedUrnSet3.add(UrnType.ANY_TYPE);
requestedUrnSet3.add(UrnType.SHA1);
Set[] requestedUrnSets = {requestedUrnSet0, requestedUrnSet1,
requestedUrnSet2, requestedUrnSet3};
Set queryUrnSet = new HashSet();
queryUrnSet.add(urn);
for(int j = 0; j < requestedUrnSets.length; j++) {
QueryRequest qr = QueryRequest.createQuery(
requestedUrnSets[j], queryUrnSet);
Response[] hits = fman.query(qr);
assertEquals("there should only be one response", 1, hits.length);
assertEquals("responses should be equal", testResponse, hits[0]);
}
}
}
/**
* Tests sending request that do not explicitly request any URNs -- traditional
* requests -- to make sure that they do return URNs in their responses.
*/
public void testThatUrnsAreReturnedWhenNotRequested() throws Exception {
addFilesToLibrary();
boolean checked = false;
for(int i = 0; i < fman.getNumFiles(); i++) {
FileDesc fd = fman.get(i);
Response testResponse = new Response(fd);
URN urn = fd.getSHA1Urn();
String name = I18NConvert.instance().getNorm(fd.getFileName());
char[] illegalChars = SearchSettings.ILLEGAL_CHARS.getValue();
Arrays.sort(illegalChars);
if (name.length() > SearchSettings.MAX_QUERY_LENGTH.getValue()
|| StringUtils.containsCharacters(name, illegalChars)) {
continue;
}
QueryRequest qr = QueryRequest.createQuery(name);
Response[] hits = fman.query(qr);
assertNotNull("didn't get a response for query " + qr, hits);
// we can only do this test on 'unique' names, so if we get more than
// one response, don't test.
if ( hits.length != 1 ) continue;
checked = true;
assertEquals("responses should be equal", testResponse, hits[0]);
Set urnSet = hits[0].getUrns();
URN[] responseUrns = (URN[])urnSet.toArray(new URN[0]);
// this is just a sanity check
assertEquals("urns should be equal for " + fd, urn, responseUrns[0]);
}
assertTrue("wasn't able to find any unique classes to check against.", checked);
}
/**
* Tests that alternate locations are returned in responses.
*/
public void testThatAlternateLocationsAreReturned() throws Exception {
addFilesToLibrary();
FileDesc[] fds = fman.getAllSharedFileDescriptors();
for(int i = 0; i < fds.length; i++) {
String urn = fds[i].getSHA1Urn().httpStringValue();
for(int j = 0; j < MAX_LOCATIONS + 5; j++) {
String loc = "http://1.2.3." + j + ":6346/uri-res/N2R?" + urn;
RouterService.getAltlocManager().add(AlternateLocation.create(loc),null);
}
}
boolean checked = false;
for(int i = 0; i < fman.getNumFiles(); i++) {
FileDesc fd = fman.get(i);
Response testResponse = new Response(fd);
String name = I18NConvert.instance().getNorm(fd.getFileName());
char[] illegalChars = SearchSettings.ILLEGAL_CHARS.getValue();
Arrays.sort(illegalChars);
if (name.length() > SearchSettings.MAX_QUERY_LENGTH.getValue()
|| StringUtils.containsCharacters(name, illegalChars)) {
continue;
}
QueryRequest qr = QueryRequest.createQuery(name);
Response[] hits = fman.query(qr);
assertNotNull("didn't get a response for query " + qr, hits);
// we can only do this test on 'unique' names, so if we get more than
// one response, don't test.
if ( hits.length != 1 ) continue;
checked = true;
assertEquals("responses should be equal", testResponse, hits[0]);
assertEquals("should have 10 other alts", 10, testResponse.getLocations().size());
assertEquals("should have equal alts",
testResponse.getLocations(), hits[0].getLocations());
}
assertTrue("wasn't able to find any unique classes to check against.", checked);
RouterService.getAltlocManager().purge();
}
/**
* tests for the QRP thats kept by the FileManager
* tests that the function getQRP of FileManager returns
* the correct table after addition, removal, and renaming
* of shared files.
*/
public void testFileManagerQRP() throws Exception {
f1 = createNewNamedTestFile(10, "hello");
f2 = createNewNamedTestFile(10, "\u5bae\u672c\u6b66\u8535\u69d8");
f3 = createNewNamedTestFile(10, "\u00e2cc\u00e8nts");
waitForLoad();
//get the QRT from the filemanager
QueryRouteTable qrt = fman.getQRT();
//test that QRT doesn't contain random keyword
QueryRequest qr = QueryRequest.createQuery("asdfasdf");
assertFalse("query should not be in qrt",
qrt.contains(qr));
//test that the qrt contains the three files
qr = get_qr(f1);
assertTrue("query not in QRT", qrt.contains(qr));
qr = get_qr(f2);
assertTrue("query not in QRT", qrt.contains(qr));
qr = get_qr(f3);
assertTrue("query not in QRT", qrt.contains(qr));
//now remove one of the files
fman.removeFileIfShared(f3);
qrt = fman.getQRT();
//make sure the removed file is no longer in qrt
assertFalse("query should not be in qrt", qrt.contains(qr));
//just check that the one of the other files is still
//in the qrt
qr = get_qr(f2);
assertTrue("query not in QRT", qrt.contains(qr));
//test rename
f4 = createNewNamedTestFile(10, "miyamoto_musashi_desu");
//check that this file doesn't hit
qr = get_qr(f4);
assertFalse("query should not be in qrt", qrt.contains(qr));
//now rename one of the files
FileManagerEvent result = renameIfShared(f2, f4);
assertTrue(result.toString(), result.isRenameEvent());
fman.renameFileIfShared(f2, f4);
qrt = fman.getQRT();
//check hit with new name
qr = get_qr(f4);
assertTrue("query not in qrt", qrt.contains(qr));
//check old name
qr = get_qr(f2);
assertFalse("query should not be in qrt", qrt.contains(qr));
}
/**
* Tests whether specially shared files are indeed shared. Also
* tests that another file in the same directory as a specially
* shared file is not shared.
*/
public void testSpecialSharing() throws Exception {
// create "shared" and "notShared" out of shared directory
File shared = createNewNamedTestFile(10, "shared", _sharedDir.getParentFile());
File notShared = createNewNamedTestFile(10, "notShared", _sharedDir.getParentFile());
getLibraryData().SPECIAL_FILES_TO_SHARE.add(shared);
waitForLoad();
// assert that "shared" and "notShared" are not in a shared directory
assertFalse(fman.isFileInCompletelySharedDirectory(shared));
assertFalse(fman.isFileInCompletelySharedDirectory(notShared));
// assert that "shared" is shared
FileDesc[] sharedFiles = fman.getAllSharedFileDescriptors();
assertNotNull("no shared files, even though just added a specially shared file", sharedFiles);
assertEquals(1, sharedFiles.length);
assertEquals(shared, sharedFiles[0].getFile());
assertEquals(sharedFiles[0], fman.getFileDescForFile(shared));
assertNull(fman.getFileDescForFile(notShared));
}
/**
* Tests {@link FileManager#addFileAlways(File)}.
* @throws Exception
*/
public void testAddFileAlways() throws Exception {
assertFalse(fman.isLoadFinished());
waitForLoad(); // ensure it's loaded with 0 files.
assertEquals(0, fman.getNumFiles());
assertTrue(fman.isLoadFinished());
// test if too large files are not shared
File tooLarge = createFakeTestFile(Integer.MAX_VALUE+1l);
FileManagerEvent result = addAlways(tooLarge);
assertTrue(result.toString(), result.isFailedEvent());
assertEquals(tooLarge, result.getFiles()[0]);
// test if files in shared directories are still shared
File test = createNewTestFile(5);
result = addAlways(test);
assertTrue(result.toString(), result.isAddEvent());
assertEquals(test, result.getFileDescs()[0].getFile());
assertEquals(1, fman.getNumFiles());
// try again, it will fail because it's already shared.
result = addAlways(test);
assertTrue(result.toString(), result.isAlreadySharedEvent());
assertEquals(test, result.getFiles()[0]);
// test that non-existent files are not shared
test = new File("non existent file").getCanonicalFile();
result = addAlways(test);
assertTrue(result.toString(), result.isFailedEvent());
assertEquals(test, result.getFiles()[0]);
// test that file in non shared directory is shared
File dir = createNewBaseDirectory("notshared");
dir.mkdir();
dir.deleteOnExit();
test = createNewNamedTestFile(500, "specially shared", dir);
result = addAlways(test);
assertTrue(result.toString(), result.isAddEvent());
assertEquals(test, result.getFileDescs()[0].getFile());
assertEquals(2, fman.getNumFiles());
// try again, it will fail because it's already shared.
result = addAlways(test);
assertTrue(result.toString(), result.isAlreadySharedEvent());
assertEquals(test, result.getFiles()[0]);
}
public void testIsFileInCompletelySharedDirectory() throws Exception {
// non existent file should not be in a shared directory
File nonexistent = new File("nonexistent");
assertFalse("File should not be in a shared directory", fman.isFileInCompletelySharedDirectory(nonexistent));
File dir = createNewBaseDirectory("notshared");
dir.mkdir();
dir.deleteOnExit();
File test = createNewNamedTestFile(10, "noshared", dir);
assertFalse("File should not be in a shared directory",fman.isFileInCompletelySharedDirectory(test));
// test for files in subdirs
File subDir = new File(_sharedDir, "newSubDir");
subDir.mkdir();
subDir.deleteOnExit();
waitForLoad();
assertTrue("Subdir should be in shared directory", fman.isFileInCompletelySharedDirectory(subDir));
test = createNewNamedTestFile(50, "subdirfile", subDir);
waitForLoad();
// test if subdir is shared
assertTrue("File in subdir should be in shared directory now", fman.isFileInCompletelySharedDirectory(test));
}
/**
* Tests {@link FileManager#addFileIfShared(File)}.
* <p>
* Basically files should be added when they are shareable.
* @throws Exception
*/
public void testAddFileIfShared() throws Exception {
// non shareable files:
// too large tested above
// non shareable extension in shared directory
SharingSettings.EXTENSIONS_TO_SHARE.setValue("abc");
waitForLoad(); // set the extensions correctly.
File nonshareable = createNewNamedTestFile(10, "nonshareable extension");
FileManagerEvent result = addIfShared(nonshareable);
assertTrue(result.toString(), result.isFailedEvent());
assertEquals(nonshareable, result.getFiles()[0]);
nonshareable.delete();
// not in shared directory and not specially shared, but valid extension
SharingSettings.EXTENSIONS_TO_SHARE.setValue(EXTENSION);
waitForLoad(); // set the new extensions
File validExt = createNewNamedTestFile(10, "valid extension", _sharedDir.getParentFile());
result = addIfShared(validExt);
assertTrue(result.toString(), result.isFailedEvent());
assertEquals(validExt, result.getFiles()[0]);
// nonexistent in shared directory
File nonexistent = new File(_sharedDir, "test." + EXTENSION);
result = addIfShared(nonexistent);
assertTrue(result.toString(), result.isFailedEvent());
assertEquals(nonexistent, result.getFiles()[0]);
// nonexistent in non shared directory
nonexistent = new File("nonexistent." + EXTENSION).getCanonicalFile();
result = addIfShared(nonexistent);
assertTrue(result.toString(), result.isFailedEvent());
assertEquals(nonexistent, result.getFiles()[0]);
// nonexistent, but specially shared
result = addAlways(nonexistent);
assertTrue(result.toString(), result.isFailedEvent());
assertEquals(nonexistent, result.getFiles()[0]);
// shareable files:
// files with shareable extension in shared directory
File shareable = createNewNamedTestFile(10, "shareable");
result = addIfShared(shareable);
assertTrue(result.toString(), result.isAddEvent());
assertEquals(shareable, result.getFileDescs()[0].getFile());
assertEquals(1, fman.getNumFiles());
assertEquals(result.getFileDescs()[0], fman.get(0));
// files with shareable extension, specially shared
File speciallyShareable = createNewNamedTestFile(10, "specially shareable", _sharedDir.getParentFile());
result = addAlways(speciallyShareable);
assertTrue(result.toString(), result.isAddEvent());
assertEquals(speciallyShareable, result.getFileDescs()[0].getFile());
assertEquals(2, fman.getNumFiles());
assertEquals(result.getFileDescs()[0], fman.get(1));
// files with non shareable extension, specially shared
SharingSettings.EXTENSIONS_TO_SHARE.setValue("abc");
File speciallyShared = createNewNamedTestFile(10, "speciall shared", _sharedDir.getParentFile());
result = addAlways(speciallyShared);
assertTrue(result.toString(), result.isAddEvent());
assertEquals(speciallyShared, result.getFileDescs()[0].getFile());
assertEquals(3, fman.getNumFiles());
assertEquals(result.getFileDescs()[0], fman.get(2));
}
/**
* Tests whether the FileManager.isSensitiveDirectory(File) function is functioning properly.
*/
public void testSensitiveDirectoryPredicate() throws Exception {
// check defensive programming
File file = null;
assertFalse("null directory should not be a sensitive directory", FileManager.isSensitiveDirectory(file));
file = new File("lksfjlsakjfsldfjak.slfkjs");
assertFalse("random file should not be a sensitive directory", FileManager.isSensitiveDirectory(file));
// check that system roots are sensitive directories
File[] faRoots = File.listRoots();
if(faRoots != null && faRoots.length > 0) {
for(int i = 0; i < faRoots.length; i++) {
assertTrue("root directory "+faRoots[i]+ " should be a sensitive directory", FileManager.isSensitiveDirectory(faRoots[i]));
}
}
// check that the user's home dir is a sensitive directory
String userHome = System.getProperty("user.home");
assertTrue("user's home directory should be a sensitive directory", FileManager.isSensitiveDirectory(new File(userHome)));
// check for OS-specific directories:
String realOS = System.getProperty("os.name");
try {
setOSName("Windows");
assertTrue("Documents and Settings should be a sensitive directory", FileManager.isSensitiveDirectory(new File("Documents and Settings")));
assertTrue("My Documents should be a sensitive directory", FileManager.isSensitiveDirectory(new File(userHome, "My Documents")));
assertTrue("Desktop should be a sensitive directory", FileManager.isSensitiveDirectory(new File(userHome, "Desktop")));
assertTrue("Program Files should be a sensitive directory", FileManager.isSensitiveDirectory(new File("Program Files")));
assertTrue("Windows should be a sensitive directory", FileManager.isSensitiveDirectory(new File("Windows")));
assertTrue("Windows should be a sensitive directory", FileManager.isSensitiveDirectory(new File("WINNT")));
setOSName("Mac OS X");
assertTrue("Users should be a sensitive directory", FileManager.isSensitiveDirectory(new File("Users")));
assertTrue("System should be a sensitive directory", FileManager.isSensitiveDirectory(new File("System")));
assertTrue("System Folder should be a sensitive directory", FileManager.isSensitiveDirectory(new File("System Folder")));
assertTrue("Previous Systems should be a sensitive directory", FileManager.isSensitiveDirectory(new File("Previous Systems")));
assertTrue("private should be a sensitive directory", FileManager.isSensitiveDirectory(new File("private")));
assertTrue("Volumes should be a sensitive directory", FileManager.isSensitiveDirectory(new File("Volumes")));
assertTrue("Desktop should be a sensitive directory", FileManager.isSensitiveDirectory(new File("Desktop")));
assertTrue("Applications should be a sensitive directory", FileManager.isSensitiveDirectory(new File("Applications")));
assertTrue("Applications (Mac OS 9) should be a sensitive directory", FileManager.isSensitiveDirectory(new File("Applications (Mac OS 9)")));
assertTrue("Network should be a sensitive directory", FileManager.isSensitiveDirectory(new File("Network")));
setOSName("Linux");
assertTrue("bin should be a sensitive directory", FileManager.isSensitiveDirectory(new File("bin")));
assertTrue("boot should be a sensitive directory", FileManager.isSensitiveDirectory(new File("boot")));
assertTrue("dev should be a sensitive directory", FileManager.isSensitiveDirectory(new File("dev")));
assertTrue("etc should be a sensitive directory", FileManager.isSensitiveDirectory(new File("etc")));
assertTrue("home should be a sensitive directory", FileManager.isSensitiveDirectory(new File("home")));
assertTrue("mnt should be a sensitive directory", FileManager.isSensitiveDirectory(new File("mnt")));
assertTrue("opt should be a sensitive directory", FileManager.isSensitiveDirectory(new File("opt")));
assertTrue("proc should be a sensitive directory", FileManager.isSensitiveDirectory(new File("proc")));
assertTrue("root should be a sensitive directory", FileManager.isSensitiveDirectory(new File("root")));
assertTrue("sbin should be a sensitive directory", FileManager.isSensitiveDirectory(new File("sbin")));
assertTrue("usr should be a sensitive directory", FileManager.isSensitiveDirectory(new File("usr")));
assertTrue("var should be a sensitive directory", FileManager.isSensitiveDirectory(new File("var")));
} finally {
// revert the os.name system property back to normal
setOSName(realOS);
}
}
/**
* Helper function to set the operating system so that multiple OSs can be partially-checked
* by testing on one platform.
*/
private static void setOSName(String name) throws Exception {
System.setProperty("os.name", name);
PrivilegedAccessor.invokeMethod(CommonUtils.class, "setOperatingSystems", null);
}
//helper function to create queryrequest with I18N
private QueryRequest get_qr(File f) {
String norm = I18NConvert.instance().getNorm(f.getName());
norm = StringUtils.replace(norm, "_", " ");
return QueryRequest.createQuery(norm);
}
private void addFilesToLibrary() throws Exception {
String dirString = "com/limegroup/gnutella";
File testDir = CommonUtils.getResourceFile(dirString);
testDir = testDir.getCanonicalFile();
assertTrue("could not find the gnutella directory",
testDir.isDirectory());
File[] testFiles = testDir.listFiles(new FileFilter() {
public boolean accept(File file) {
// use files with a $ because they'll generally
// trigger a single-response return, which is
// easier to check
return !file.isDirectory() && file.getName().indexOf("$")!=-1;
}
});
assertNotNull("no files to test against", testFiles);
assertNotEquals("no files to test against", 0, testFiles.length);
for(int i=0; i<testFiles.length; i++) {
if(!testFiles[i].isFile()) continue;
File shared = new File(
_sharedDir, testFiles[i].getName() + "." + EXTENSION);
assertTrue("unable to get file", CommonUtils.copy( testFiles[i], shared));
}
waitForLoad();
// the below test depends on the filemanager loading shared files in
// alphabetical order, and listFiles returning them in alphabetical
// order since neither of these must be true, a length check can
// suffice instead.
//for(int i=0; i<files.length; i++)
// assertEquals(files[i].getName()+".tmp",
// fman.get(i).getFile().getName());
assertEquals("unexpected number of shared files",
testFiles.length, fman.getNumFiles() );
}
/**
* Helper function to create a new temporary file of the given size,
* with the given name, in the default shared directory.
*/
protected File createNewNamedTestFile(int size, String name) throws Exception {
return createNewNamedTestFile(size, name, _sharedDir);
}
protected File createNewTestFile(int size) throws Exception {
return createNewNamedTestFile(size, "FileManager_unit_test", _sharedDir);
}
protected URN getURN(File f) throws Exception {
return URN.createSHA1Urn(f);
}
/**
* Helper function to create a new temporary file of the given size,
* with the given name, in the given directory.
*/
protected File createNewNamedTestFile(int size, String name, File directory) throws Exception {
File file = File.createTempFile(name, "." + EXTENSION, directory);
file.deleteOnExit();
OutputStream out = new FileOutputStream(file);
out.write(new byte[size]);
out.flush();
out.close();
//Needed for comparisons between "C:\Progra~1" and "C:\Program Files".
return FileUtils.getCanonicalFile(file);
}
/** Same a createNewTestFile but doesn't actually allocate the requested
* number of bytes on disk. Instead returns a subclass of File. */
File createFakeTestFile(long size) throws Exception {
File real=createNewTestFile(1);
return new HugeFakeFile(real.getParentFile(), real.getName(), size);
}
protected LibraryData getLibraryData() throws Exception {
return (LibraryData)PrivilegedAccessor.getValue(fman, "_data");
}
private static class HugeFakeFile extends File {
long length;
public HugeFakeFile(File dir, String name, long length) {
super(dir, name);
this.length=length;
}
public long length() {
return length;
}
public File getCanonicalFile() {
return this;
}
}
public class FManCallback extends ActivityCallbackStub {
public void fileManagerLoaded() {
synchronized(loaded) {
loaded.notify();
}
}
}
protected void waitForLoad() {
synchronized(loaded) {
try {
fman.loadSettings();
loaded.wait(10000);
} catch (InterruptedException e) {
//good.
}
}
}
public static class Listener implements FileEventListener {
public FileManagerEvent evt;
public synchronized void handleFileEvent(FileManagerEvent fme) {
evt = fme;
notify();
}
}
protected FileManagerEvent addIfShared(File f) throws Exception {
Listener fel = new Listener();
synchronized(fel) {
fman.addFileIfShared(f, fel);
fel.wait(5000);
}
return fel.evt;
}
protected FileManagerEvent addAlways(File f) throws Exception {
Listener fel = new Listener();
synchronized(fel) {
fman.addFileAlways(f, fel);
fel.wait(5000);
}
return fel.evt;
}
protected FileManagerEvent renameIfShared(File f1, File f2) throws Exception {
Listener fel = new Listener();
synchronized(fel) {
fman.renameFileIfShared(f1, f2, fel);
fel.wait(5000);
}
return fel.evt;
}
}