package com.limegroup.gnutella.library; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertTrue; import static junit.framework.Assert.fail; import static org.limewire.util.AssertComparisons.assertInstanceof; import static org.limewire.util.AssertComparisons.assertNotNull; import java.io.File; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.OutputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.EnumSet; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import org.limewire.collection.CollectionUtils; import org.limewire.core.api.Category; import org.limewire.util.FileUtils; import org.limewire.util.TestUtils; import com.limegroup.gnutella.URN; import com.limegroup.gnutella.xml.LimeXMLDocument; public class FileManagerTestUtils { public static File createNewTestFile(int size, File dir) throws Exception { return createNewExtensionTestFile(size, "tmp", dir); } public static File createNewExtensionTestFile(int size, String ext, File dir) throws Exception { return createNewNamedTestFile(size, "FileManager_unit_test", ext, dir); } public static URN getUrn(File f) throws Exception { return URN.createSHA1Urn(f); } public static void assertAddFails(String reason, FileList fileList, File... files) throws Exception { for (File file : files) { try { FileDesc fd = fileList.add(file).get(5, TimeUnit.SECONDS); fail("added: " + fd); } catch (ExecutionException expected) { assertInstanceof(FileListChangeFailedException.class, expected.getCause()); FileListChangeFailedException cause = (FileListChangeFailedException) expected.getCause(); assertEquals(FileListChangedEvent.Type.ADD_FAILED, cause.getEvent().getType()); assertEquals(file, cause.getEvent().getFile()); assertEquals(reason, cause.getReason().toString()); } } } public static void assertAdds(FileList fileList, File... files) throws Exception { for (File file : files) { assertNotNull(fileList.add(file).get(1, TimeUnit.SECONDS)); } } public static void assertAddsForSession(GnutellaFileList fileList, File... files) throws Exception { for (File file : files) { assertNotNull(fileList.addForSession(file).get(1, TimeUnit.SECONDS)); } } public static void assertFileRenames(ManagedFileList fileList, File old, File newFile) throws Exception { assertNotNull(fileList.fileRenamed(old, newFile).get(1, TimeUnit.SECONDS)); } public static void assertFileRenameFails(String reason, ManagedFileList fileList, File old, File newFile) throws Exception { FileDesc oldFd = fileList.getFileDesc(old); Future<FileDesc> future = fileList.fileRenamed(old, newFile); try { future.get(1, TimeUnit.SECONDS); fail("renamed!"); } catch (ExecutionException expected) { assertInstanceof(FileListChangeFailedException.class, expected.getCause()); FileListChangeFailedException cause = (FileListChangeFailedException) expected.getCause(); assertEquals(FileListChangedEvent.Type.CHANGE_FAILED, cause.getEvent().getType()); assertEquals(old, cause.getEvent().getOldFile()); assertEquals(newFile, cause.getEvent().getFile()); assertEquals(oldFd, cause.getEvent().getOldValue()); assertEquals(reason, cause.getReason().toString()); } } public static void assertFileChanges(ManagedFileList fileList, File file) throws Exception { assertNotNull(fileList.fileChanged(file, LimeXMLDocument.EMPTY_LIST).get(1, TimeUnit.SECONDS)); } public static void assertFileChangedFails(String reason, ManagedFileList fileList, File file) throws Exception { FileDesc oldFd = fileList.getFileDesc(file); Future<FileDesc> future = fileList.fileChanged(file, LimeXMLDocument.EMPTY_LIST); try { future.get(1, TimeUnit.SECONDS); fail("renamed!"); } catch (ExecutionException expected) { assertInstanceof(FileListChangeFailedException.class, expected.getCause()); FileListChangeFailedException cause = (FileListChangeFailedException) expected.getCause(); assertEquals(FileListChangedEvent.Type.CHANGE_FAILED, cause.getEvent().getType()); assertEquals(file, cause.getEvent().getOldFile()); assertEquals(file, cause.getEvent().getFile()); assertEquals(oldFd, cause.getEvent().getOldValue()); assertEquals(reason, cause.getReason().toString()); } } public static List<FileDesc> assertSetManagedDirectories(ManagedFileList fileList, Collection<File> dirs, Collection<File> excludeDirs) throws Exception { return assertFutureListFinishes(fileList.setManagedOptions(dirs, excludeDirs, EnumSet.allOf(Category.class)), 5, TimeUnit.SECONDS); } public static void assertContainsFiles(Iterable<FileDesc> iterable, File... expectedFiles) { assertContainsFiles(CollectionUtils.listOf(iterable), expectedFiles); } public static void assertContainsFiles(List<FileDesc> fds, File... expectedFiles) { List<File> files = new ArrayList<File>(fds.size()); for(FileDesc fd : fds) { files.add(fd.getFile()); } int i = 0; for(File file : expectedFiles) { assertTrue("did not contain file[" + i + "]: " + file, files.remove(file)); i++; } assertTrue("contained unexpected files: " + files, files.size() == 0); } public static List<FileDesc> assertAddsFolder(FileList fileList, File folder) throws Exception { return assertFutureListFinishes(fileList.addFolder(folder), 5, TimeUnit.SECONDS); } public static List<FileDesc> assertChangeExtensions(ManagedFileList fileList, String... extensions) throws Exception { return assertFutureListFinishes(fileList.setManagedExtensions(Arrays.asList(extensions)), 5, TimeUnit.SECONDS); } /** * Begins a load on FileManager and waits for the FileManager to finishing loading before * continuing. Also can specify a timeout which will throw an exception if FileManager hasn't * completed in a certain amount of time. */ public static List<FileDesc> waitForLoad(FileManager fileManager, int timeout) throws Exception { return assertLoads(fileManager.getManagedFileList(), timeout, TimeUnit.MILLISECONDS); } public static List<FileDesc> assertLoads(ManagedFileList managedList) throws Exception { return assertLoads(managedList, 5, TimeUnit.SECONDS); } public static List<FileDesc> assertLoads(ManagedFileList managedList, long timeout, TimeUnit unit) throws Exception { Future<? extends List<? extends Future<FileDesc>>> loadFuture = ((ManagedFileListImpl) managedList).loadManagedFiles(); return assertFutureListFinishes(loadFuture, timeout, unit); } public static List<FileDesc> assertFutureListFinishes(Future<? extends List<? extends Future<FileDesc>>> future, long timeout, TimeUnit unit) throws Exception { long left = unit.toNanos(timeout); long start = System.nanoTime(); List<? extends Future<FileDesc>> futures = future.get(timeout, unit); left -= System.nanoTime() - start; if(left <= 0) { throw new TimeoutException("timed out waiting for futures to load"); } else { return waitForFutures(futures, left, TimeUnit.NANOSECONDS); } } private static List<FileDesc> waitForFutures(List<? extends Future<FileDesc>> futures, long timeout, TimeUnit unit) throws Exception { List<FileDesc> fdList = new ArrayList<FileDesc>(); long left = unit.toNanos(timeout); for(Future<FileDesc> future : futures) { long start = System.nanoTime(); try { fdList.add(future.get(left, TimeUnit.NANOSECONDS)); } catch(ExecutionException ignored) {} left -= System.nanoTime() - start; if(left <= 0) { throw new TimeoutException("timed out waiting for futures to load"); } } return fdList; } // build xml string for video public static String buildVideoXMLString(String keyname) { return "<?xml version=\"1.0\"?><videos xsi:noNamespaceSchemaLocation=\"http://www.limewire.com/schemas/video.xsd\"><video " + keyname + "></video></videos>"; } public static String buildAudioXMLString(String keyname) { return "<?xml version=\"1.0\"?><audios xsi:noNamespaceSchemaLocation=\"http://www.limewire.com/schemas/audio.xsd\"><audio " + keyname + "></audio></audios>"; } public static String buildDocumentXMLString(String keyname) { return "<?xml version=\"1.0\"?><documents xsi:noNamespaceSchemaLocation=\"http://www.limewire.com/schemas/document.xsd\">" + "<document " + keyname + " /></documents>"; } /** * Helper function to create a new temporary file of the given size, * with the given name, in the given directory. */ public static File createNewNamedTestFile(int size, String name, File directory) throws Exception { return createNewNamedTestFile(size, name, "tmp", directory); } /** * Helper function to create a new temporary file of the given size, * with the given name & extension, in the given directory. */ public static File createNewNamedTestFile(int size, String name, String extension, File directory) throws Exception { if(name.length() < 3) { name = name + "___"; } File file = File.createTempFile(name, "." + extension, directory); file.deleteOnExit(); OutputStream out = new FileOutputStream(file); for (int i=0; i<size; i++) { out.write(name.charAt(i % name.length())); } out.flush(); out.close(); //Needed for comparisons between "C:\Progra~1" and "C:\Program Files". return FileUtils.getCanonicalFile(file); } public static void change(File file) throws Exception { FileWriter fw = new FileWriter(file, true); fw.write("change"); fw.flush(); fw.close(); } public static File createNewNameStoreTestFile(String name, File directory) throws Exception { String dir = "com/limegroup/gnutella/"; File f = TestUtils.getResourceFile(dir + "StoreTestFile.mp3"); assertTrue(f.exists()); File file = File.createTempFile(name, ".mp3", directory); FileUtils.copy(f, file); assertTrue(file.exists()); file.deleteOnExit(); return FileUtils.getCanonicalFile(file); } public static File createNewNameStoreTestFile2(String name, File directory) throws Exception { String dir = "com/limegroup/gnutella/"; File f = TestUtils.getResourceFile(dir + "StoreTestFile2.mp3"); assertTrue(f.exists()); File file = File.createTempFile(name, ".mp3", directory); FileUtils.copy(f, file); assertTrue(file.exists()); file.deleteOnExit(); return FileUtils.getCanonicalFile(file); } public static File createNewTestStoreFile(File dir) throws Exception{ return createNewNameStoreTestFile("FileManager_unit_store_test", dir); } public static File createNewTestStoreFile2(File dir) throws Exception { return createNewNameStoreTestFile2("FileManager_unit_store_test", dir); } /** * Same a createNewTestFile but doesn't actually allocate the requested * number of bytes on disk. Instead returns a subclass of File. */ public static File createFakeTestFile(long size, File dir) throws Exception { File real = createNewTestFile(1, dir); return new HugeFakeFile(dir, real.getName(), size); } /** * Same as createNewTestFile except that it returns a subclass of File * for which isHidden() always returns true. */ public static File createHiddenTestFile(int size, File dir) throws Exception { File real = createNewTestFile(size, dir); return new HiddenFakeFile(dir, real.getName()); } private static class HugeFakeFile extends File { private final long length; public HugeFakeFile(File dir, String name, long length) { super(dir, name); this.length = length; } @Override public long length() { return length; } @Override public File getCanonicalFile() { return this; } @Override public File getAbsoluteFile() { return this; } } private static class HiddenFakeFile extends File { public HiddenFakeFile(File dir, String name) { super(dir, name); } @Override public boolean isHidden() { return true; } @Override public File getCanonicalFile() { return this; } @Override public File getAbsoluteFile() { return this; } } }