getTrackedTorrents(){
- return torrents.values();
- }
-
- /**
+ /**
* Announce a new torrent on this tracker.
*
*
@@ -206,7 +195,7 @@ public Collection getTrackedTorrents(){
* different from the supplied Torrent object if the tracker already
* contained a torrent with the same hash.
*/
- public synchronized TrackedTorrent announce(Torrent torrent) throws IOException, NoSuchAlgorithmException {
+ public synchronized TrackedTorrent announce(TrackedTorrent torrent) {
TrackedTorrent existing = this.torrents.get(torrent.getHexInfoHash());
if (existing != null) {
@@ -215,16 +204,10 @@ public synchronized TrackedTorrent announce(Torrent torrent) throws IOException,
return existing;
}
- final TrackedTorrent result;
- if (torrent instanceof TrackedTorrent) {
- result = (TrackedTorrent) torrent;
- } else {
- result = new TrackedTorrent(torrent);
- }
- this.torrents.put(torrent.getHexInfoHash(), result);
+ this.torrents.put(torrent.getHexInfoHash(), torrent);
logger.info("Registered new torrent for '{}' with hash {}.",
torrent.getName(), torrent.getHexInfoHash());
- return result;
+ return torrent;
}
/**
diff --git a/src/test/java/com/turn/ttorrent/FileUtil.java b/src/test/java/com/turn/ttorrent/FileUtil.java
deleted file mode 100644
index 3abff5e1d..000000000
--- a/src/test/java/com/turn/ttorrent/FileUtil.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package com.turn.ttorrent;
-
-import java.io.Closeable;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-
-public class FileUtil {
-
- public static File getTempDirectory() {
- return new File(System.getProperty("java.io.tmpdir"));
- }
-
- public static void delete(File file) {
- if (file.isDirectory()) {
- File[] files = file.listFiles();
- for (File f: files) {
- delete(f);
- }
- }
- deleteFile(file);
- }
-
- private static boolean deleteFile(File file) {
- if (!file.exists()) return false;
- for (int i=0; i<10; i++) {
- if (file.delete()) return true;
- try {
- Thread.sleep(1);
- } catch (InterruptedException e) {
- //
- }
- }
- return false;
- }
-
- public static void writeFile(File file, String content) throws IOException {
- FileWriter fw = null;
- try {
- fw = new FileWriter(file);
- fw.write(content);
- } finally {
- close(fw);
- }
- }
-
- public static void close(Closeable closeable) {
- if (closeable != null) {
- try {
- closeable.close();
- } catch (IOException e) {
- //
- }
- }
- }
-}
diff --git a/src/test/java/com/turn/ttorrent/TempFiles.java b/src/test/java/com/turn/ttorrent/TempFiles.java
deleted file mode 100644
index bf0953d1a..000000000
--- a/src/test/java/com/turn/ttorrent/TempFiles.java
+++ /dev/null
@@ -1,136 +0,0 @@
-package com.turn.ttorrent;
-
-import java.io.*;
-import java.util.*;
-
-public class TempFiles {
- private static final File ourCurrentTempDir = FileUtil.getTempDirectory();
- private final File myCurrentTempDir;
-
- private static Random ourRandom;
-
- static {
- ourRandom = new Random();
- ourRandom.setSeed(System.currentTimeMillis());
- }
-
- private final List myFilesToDelete = new ArrayList();
- private final Thread myShutdownHook;
- private volatile boolean myInsideShutdownHook;
-
- public TempFiles() {
- myCurrentTempDir = ourCurrentTempDir;
- if (!myCurrentTempDir.isDirectory()) {
-
- throw new IllegalStateException("Temp directory is not a directory, was deleted by some process: " + myCurrentTempDir.getAbsolutePath() +
- "\njava.io.tmpdir: " + FileUtil.getTempDirectory());
- }
-
- myShutdownHook = new Thread(new Runnable() {
- public void run() {
- myInsideShutdownHook = true;
- cleanup();
- }
- });
- Runtime.getRuntime().addShutdownHook(myShutdownHook);
- }
-
- private File doCreateTempDir(String prefix, String suffix) throws IOException {
- prefix = prefix == null ? "" : prefix;
- suffix = suffix == null ? ".tmp" : suffix;
-
- do {
- int count = ourRandom.nextInt();
- final File f = new File(myCurrentTempDir, prefix + count + suffix);
- if (!f.exists() && f.mkdirs()) {
- return f.getCanonicalFile();
- }
- } while (true);
-
- }
- private File doCreateTempFile(String prefix, String suffix) throws IOException {
- final File file = doCreateTempDir(prefix, suffix);
- file.delete();
- file.createNewFile();
- return file;
- }
-
- public final File createTempFile(String content) throws IOException {
- File tempFile = createTempFile();
- FileUtil.writeFile(tempFile, content);
- return tempFile;
- }
-
- public final File createTempFile() throws IOException {
- File tempFile = doCreateTempFile("test", null);
- registerAsTempFile(tempFile);
- return tempFile;
- }
-
- public void registerAsTempFile(final File tempFile) {
- myFilesToDelete.add(tempFile);
- }
-
- public final File createTempFile(int size) throws IOException {
- File tempFile = createTempFile();
- int bufLen = Math.min(8 * 1024, size);
- if (bufLen == 0) return tempFile;
- final OutputStream fos = new BufferedOutputStream(new FileOutputStream(tempFile));
- try {
- byte[] buf = new byte[bufLen];
- for (int i=0; i < buf.length; i++) {
- buf[i] = (byte)Math.round(Math.random()*128);
- }
-
- int numWritten = 0;
- for (int i=0; i numWritten) {
- fos.write(buf, 0, size - numWritten);
- }
- } finally {
- fos.close();
- }
-
- return tempFile;
- }
-
- /**
- * Returns a File object for created temp directory.
- * Also stores the value into this object accessed with {@link #getCurrentTempDir()}
- *
- * @return a File object for created temp directory
- * @throws IOException if directory creation fails.
- */
- public final File createTempDir() throws IOException {
- File f = doCreateTempDir("test", "");
- registerAsTempFile(f);
- return f;
- }
-
- /**
- * Returns the current directory used by the test or null if no test is running or no directory is created yet.
- *
- * @return see above
- */
- public File getCurrentTempDir() {
- return myCurrentTempDir;
- }
-
- public void cleanup() {
- try {
- for (File file : myFilesToDelete) {
- FileUtil.delete(file);
- }
-
- myFilesToDelete.clear();
- } finally {
- if (!myInsideShutdownHook) {
- Runtime.getRuntime().removeShutdownHook(myShutdownHook);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/test/java/com/turn/ttorrent/WaitFor.java b/src/test/java/com/turn/ttorrent/WaitFor.java
deleted file mode 100644
index 41ab425ed..000000000
--- a/src/test/java/com/turn/ttorrent/WaitFor.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package com.turn.ttorrent;
-
-public abstract class WaitFor {
- private long myPollInterval = 100;
-
- protected WaitFor() {
- this(40 * 1000);
- }
-
- protected WaitFor(long timeout) {
- long started = System.currentTimeMillis();
- try {
- while(true) {
- if (condition()) return;
- if (System.currentTimeMillis() - started < timeout) {
- Thread.sleep(myPollInterval);
- } else {
- break;
- }
- }
-
- } catch (InterruptedException e) {
- //NOP
- }
- }
-
- protected WaitFor(long timeout, long pollInterval) {
- this(timeout);
- myPollInterval = pollInterval;
- }
-
- protected abstract boolean condition();
-}
diff --git a/src/test/java/com/turn/ttorrent/common/TorrentTest.java b/src/test/java/com/turn/ttorrent/common/TorrentTest.java
index 666fde629..10df101f0 100644
--- a/src/test/java/com/turn/ttorrent/common/TorrentTest.java
+++ b/src/test/java/com/turn/ttorrent/common/TorrentTest.java
@@ -1,30 +1,47 @@
package com.turn.ttorrent.common;
-import org.testng.annotations.Test;
-
import java.io.File;
-import java.io.IOException;
+import java.lang.reflect.Method;
import java.net.URI;
-import java.net.URISyntaxException;
-import java.security.NoSuchAlgorithmException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
@Test
-public class TorrentTest {
-
- public void test_create_torrent() throws URISyntaxException, IOException, NoSuchAlgorithmException, InterruptedException {
- URI announceURI = new URI("http://localhost:6969/announce");
- String createdBy = "Test";
- Torrent t = Torrent.create(new File("src/test/resources/parentFiles/file1.jar"), announceURI, createdBy);
- assertEquals(createdBy, t.getCreatedBy());
- assertEquals(announceURI, t.getAnnounceList().get(0).get(0));
- }
-
- public void load_torrent_created_by_utorrent() throws IOException, NoSuchAlgorithmException, URISyntaxException {
- Torrent t = Torrent.load(new File("src/test/resources/torrents/file1.jar.torrent"));
- assertEquals(new URI("http://localhost:6969/announce"), t.getAnnounceList().get(0).get(0));
- assertEquals("B92D38046C76D73948E14C42DF992CAF25489D08", t.getHexInfoHash());
- assertEquals("uTorrent/3130", t.getCreatedBy());
- }
+public class TorrentTest {
+
+ private static final Logger logger =
+ LoggerFactory.getLogger(TorrentTest.class);
+
+ @BeforeMethod(alwaysRun = true)
+ protected void setUp(Method testMethod) throws Exception {
+ String testName = testMethod.getDeclaringClass().getSimpleName() + "." + testMethod.getName();
+ logger.trace("Test starting: " + testName);
+ }
+
+ @AfterMethod(alwaysRun = true)
+ protected void tearDown(Method testMethod) throws Exception {
+ String testName = testMethod.getDeclaringClass().getSimpleName() + "." + testMethod.getName();
+ logger.trace("Test finished: " + testName);
+ }
+
+ public void test_create_torrent() throws Exception {
+ URI announceURI = new URI("http://localhost:6969/announce");
+ String createdBy = "Test";
+ Torrent t = Torrent.create(new File("src/test/resources/parentFiles/file1.jar"), announceURI, createdBy);
+ assertEquals(createdBy, t.getCreatedBy());
+ assertEquals(announceURI, t.getAnnounceList().get(0).get(0));
+ }
+
+ public void load_torrent_created_by_utorrent() throws Exception {
+ Torrent t = Torrent.load(new File("src/test/resources/torrents/file1.jar.torrent"));
+ assertEquals(new URI("http://localhost:6969/announce"), t.getAnnounceList().get(0).get(0));
+ assertEquals("B92D38046C76D73948E14C42DF992CAF25489D08", t.getHexInfoHash());
+ assertEquals("uTorrent/3130", t.getCreatedBy());
+ }
}
diff --git a/src/test/java/com/turn/ttorrent/testutil/TempFiles.java b/src/test/java/com/turn/ttorrent/testutil/TempFiles.java
new file mode 100644
index 000000000..9f8a06250
--- /dev/null
+++ b/src/test/java/com/turn/ttorrent/testutil/TempFiles.java
@@ -0,0 +1,137 @@
+package com.turn.ttorrent.testutil;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+import org.apache.commons.io.FileUtils;
+
+public class TempFiles {
+
+ private static final File ourCurrentTempDir = new File(FileUtils.getTempDirectory(), "ttorrent-test");
+
+ private static final Random ourRandom = new Random();
+
+ private final File myCurrentTempDir;
+ private final List myFilesToDelete = new ArrayList();
+ private final Thread myShutdownHook;
+ private volatile boolean myInsideShutdownHook;
+
+ public TempFiles() {
+ myCurrentTempDir = ourCurrentTempDir;
+ if (!myCurrentTempDir.isDirectory() && !myCurrentTempDir.mkdirs()) {
+
+ throw new IllegalStateException(
+ "Temp directory is not a directory, was deleted by some process: "
+ + myCurrentTempDir.getAbsolutePath());
+ }
+
+ myShutdownHook = new Thread(new Runnable() {
+ public void run() {
+ myInsideShutdownHook = true;
+ cleanup();
+ }
+ });
+ Runtime.getRuntime().addShutdownHook(myShutdownHook);
+ }
+
+ private File doCreateTempDir(String prefix, String suffix)
+ throws IOException {
+ prefix = prefix == null ? "" : prefix;
+ suffix = suffix == null ? ".tmp" : suffix;
+
+ do {
+ int count = ourRandom.nextInt();
+ final File f = new File(myCurrentTempDir, prefix + count + suffix);
+ if (!f.exists() && f.mkdirs()) {
+ return f.getCanonicalFile();
+ }
+ } while (true);
+
+ }
+
+ private File doCreateTempFile(String prefix, String suffix)
+ throws IOException {
+ final File file = doCreateTempDir(prefix, suffix);
+ file.delete();
+ file.createNewFile();
+ return file;
+ }
+
+ public final File createTempFile() throws IOException {
+ File tempFile = doCreateTempFile("test", null);
+ registerAsTempFile(tempFile);
+ return tempFile;
+ }
+
+ public void registerAsTempFile(final File tempFile) {
+ myFilesToDelete.add(tempFile);
+ }
+
+ public final File createTempFile(int size) throws IOException {
+ File tempFile = createTempFile();
+ int bufLen = Math.min(8 * 1024, size);
+ if (bufLen == 0) return tempFile;
+ final OutputStream fos = new BufferedOutputStream(new FileOutputStream(tempFile));
+ try {
+ byte[] buf = new byte[bufLen];
+ ourRandom.nextBytes(buf);
+
+ int numWritten = 0;
+ for (int i = 0; i < size / buf.length; i++) {
+ fos.write(buf);
+ numWritten += buf.length;
+ }
+
+ if (size > numWritten) {
+ fos.write(buf, 0, size - numWritten);
+ }
+ } finally {
+ fos.close();
+ }
+
+ return tempFile;
+ }
+
+ /**
+ * Returns a File object for created temp directory.
+ * Also stores the value into this object accessed with {@link #getCurrentTempDir()}
+ *
+ * @return a File object for created temp directory
+ * @throws IOException if directory creation fails.
+ */
+ public final File createTempDir() throws IOException {
+ File f = doCreateTempDir("test", "");
+ registerAsTempFile(f);
+ return f;
+ }
+
+ /**
+ * Returns the current directory used by the test or null if no test is running or no directory is created yet.
+ *
+ * @return see above
+ */
+ public File getCurrentTempDir() {
+ return myCurrentTempDir;
+ }
+
+ public void cleanup() {
+ try {
+ for (File file : myFilesToDelete) {
+ FileUtils.deleteQuietly(file);
+ }
+
+ myFilesToDelete.clear();
+ FileUtils.deleteQuietly(ourCurrentTempDir);
+ } finally {
+ if (!myInsideShutdownHook) {
+ Runtime.getRuntime().removeShutdownHook(myShutdownHook);
+ }
+ }
+ }
+}
diff --git a/src/test/java/com/turn/ttorrent/testutil/WaitFor.java b/src/test/java/com/turn/ttorrent/testutil/WaitFor.java
new file mode 100644
index 000000000..b8cd42c9d
--- /dev/null
+++ b/src/test/java/com/turn/ttorrent/testutil/WaitFor.java
@@ -0,0 +1,28 @@
+package com.turn.ttorrent.testutil;
+
+public abstract class WaitFor {
+
+ private static final long DEFAULT_WAIT_TIMEOUT = 40 * 1000;
+
+ private static final long DEFAULT_POLL_INTERVAL = 100;
+
+ protected WaitFor() {
+ this(DEFAULT_WAIT_TIMEOUT);
+ }
+
+ protected WaitFor(long timeout) {
+ this(timeout, DEFAULT_POLL_INTERVAL);
+ }
+
+ protected WaitFor(long timeout, long interval) {
+ long started = System.currentTimeMillis();
+ try {
+ while (!condition() && System.currentTimeMillis() - started < timeout) {
+ Thread.sleep(interval);
+ }
+ } catch (InterruptedException ignored) {
+ }
+ }
+
+ protected abstract boolean condition();
+}
diff --git a/src/test/java/com/turn/ttorrent/tracker/TrackerTest.java b/src/test/java/com/turn/ttorrent/tracker/TrackerTest.java
index 7742ea48a..3802b9938 100644
--- a/src/test/java/com/turn/ttorrent/tracker/TrackerTest.java
+++ b/src/test/java/com/turn/ttorrent/tracker/TrackerTest.java
@@ -1,260 +1,268 @@
package com.turn.ttorrent.tracker;
-import com.turn.ttorrent.TempFiles;
-import com.turn.ttorrent.WaitFor;
+import com.turn.ttorrent.testutil.TempFiles;
+import com.turn.ttorrent.testutil.WaitFor;
import com.turn.ttorrent.client.Client;
import com.turn.ttorrent.client.SharedTorrent;
import com.turn.ttorrent.common.Torrent;
-import org.apache.commons.io.FileUtils;
-import org.apache.log4j.BasicConfigurator;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
import java.io.File;
import java.io.IOException;
+import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.InetSocketAddress;
-import java.net.URISyntaxException;
import java.security.NoSuchAlgorithmException;
-import java.util.*;
+import java.util.Collection;
+import java.util.Map;
import java.util.zip.CRC32;
import java.util.zip.Checksum;
+import org.apache.commons.io.FileUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
import static org.testng.Assert.*;
@Test
-public class TrackerTest {
- private static final String TEST_RESOURCES = "src/test/resources";
- private Tracker tracker;
- private TempFiles tempFiles;
-
- @BeforeMethod
- protected void setUp() throws Exception {
- BasicConfigurator.configure();
- tempFiles = new TempFiles();
- startTracker();
- }
-
- public void test_share_and_download() throws IOException, NoSuchAlgorithmException, InterruptedException {
- final TrackedTorrent tt = this.tracker.announce(loadTorrent("file1.jar.torrent"));
- assertEquals(0, tt.getPeers().size());
-
- Client seeder = createClient(completeTorrent("file1.jar.torrent"));
-
- assertEquals(tt.getHexInfoHash(), seeder.getTorrent().getHexInfoHash());
-
- final File downloadDir = tempFiles.createTempDir();
- Client leech = createClient(incompleteTorrent("file1.jar.torrent", downloadDir));
-
- try {
- seeder.share();
-
- leech.download();
-
- waitForFileInDir(downloadDir, "file1.jar");
- assertFilesEqual(new File(TEST_RESOURCES + "/parentFiles/file1.jar"), new File(downloadDir, "file1.jar"));
- } finally {
- leech.stop(true);
- seeder.stop(true);
- }
- }
-
- public void tracker_accepts_torrent_from_seeder() throws IOException, NoSuchAlgorithmException, InterruptedException {
- final SharedTorrent torrent = completeTorrent("file1.jar.torrent");
- tracker.announce(torrent);
- Client seeder = createClient(torrent);
-
- try {
- seeder.share();
-
- waitForSeeder(seeder.getTorrent().getInfoHash());
-
- Collection trackedTorrents = this.tracker.getTrackedTorrents();
- assertEquals(1, trackedTorrents.size());
-
- TrackedTorrent trackedTorrent = trackedTorrents.iterator().next();
- Map peers = trackedTorrent.getPeers();
- assertEquals(1, peers.size());
- assertTrue(peers.values().iterator().next().isCompleted()); // seed
- assertEquals(1, trackedTorrent.seeders());
- assertEquals(0, trackedTorrent.leechers());
- } finally {
- seeder.stop(true);
- }
- }
-
- public void tracker_accepts_torrent_from_leech() throws IOException, NoSuchAlgorithmException, InterruptedException {
-
- final File downloadDir = tempFiles.createTempDir();
- final SharedTorrent torrent = incompleteTorrent("file1.jar.torrent", downloadDir);
- tracker.announce(torrent);
- Client leech = createClient(torrent);
-
- try {
- leech.download();
-
- waitForPeers(1);
-
- Collection trackedTorrents = this.tracker.getTrackedTorrents();
- assertEquals(1, trackedTorrents.size());
-
- TrackedTorrent trackedTorrent = trackedTorrents.iterator().next();
- Map peers = trackedTorrent.getPeers();
- assertEquals(1, peers.size());
- assertFalse(peers.values().iterator().next().isCompleted()); // leech
- assertEquals(0, trackedTorrent.seeders());
- assertEquals(1, trackedTorrent.leechers());
- } finally {
- leech.stop(true);
- }
- }
-
- public void tracker_accepts_torrent_from_seeder_plus_leech() throws IOException, NoSuchAlgorithmException, InterruptedException {
- assertEquals(0, this.tracker.getTrackedTorrents().size());
-
- final SharedTorrent completeTorrent = completeTorrent("file1.jar.torrent");
- tracker.announce(completeTorrent);
- Client seeder = createClient(completeTorrent);
-
- final File downloadDir = tempFiles.createTempDir();
- final SharedTorrent incompleteTorrent = incompleteTorrent("file1.jar.torrent", downloadDir);
- Client leech = createClient(incompleteTorrent);
-
- try {
- seeder.share();
- leech.download();
-
- waitForFileInDir(downloadDir, "file1.jar");
- } finally {
- seeder.stop(true);
- leech.stop(true);
- }
- }
-
- private Set listFileNames(File downloadDir) {
- if (downloadDir == null) return Collections.emptySet();
- Set names = new HashSet();
- File[] files = downloadDir.listFiles();
- if (files == null) return Collections.emptySet();
- for (File f: files) {
- names.add(f.getName());
- }
- return names;
- }
-
-
- public void large_file_download() throws IOException, URISyntaxException, NoSuchAlgorithmException, InterruptedException {
-
-
- File tempFile = tempFiles.createTempFile(201 * 1024 * 1024);
-
- Torrent torrent = Torrent.create(tempFile, this.tracker.getAnnounceUrl().toURI(), "Test");
- File torrentFile = new File(tempFile.getParentFile(), tempFile.getName() + ".torrent");
- torrent.save(torrentFile);
- tracker.announce(torrent);
-
- Client seeder = createClient(SharedTorrent.fromFile(torrentFile, tempFile.getParentFile()));
-
- final File downloadDir = tempFiles.createTempDir();
- Client leech = createClient(SharedTorrent.fromFile(torrentFile, downloadDir));
-
- try {
- seeder.share();
- leech.download();
-
- waitForFileInDir(downloadDir, tempFile.getName());
- assertFilesEqual(tempFile, new File(downloadDir, tempFile.getName()));
- } finally {
- seeder.stop(true);
- leech.stop(true);
- }
- }
-
- public void test_announce() throws IOException, NoSuchAlgorithmException {
- assertEquals(0, this.tracker.getTrackedTorrents().size());
-
- this.tracker.announce(loadTorrent("file1.jar.torrent"));
-
- assertEquals(1, this.tracker.getTrackedTorrents().size());
- }
-
- private void waitForSeeder(final byte[] torrentHash) {
- new WaitFor() {
- @Override
- protected boolean condition() {
- for (TrackedTorrent tt: TrackerTest.this.tracker.getTrackedTorrents()) {
- if (tt.seeders() == 1 && tt.getHexInfoHash().equals(Torrent.byteArrayToHexString(torrentHash))) return true;
- }
-
- return false;
- }
- };
- }
-
- private void waitForPeers(final int numPeers) {
- new WaitFor() {
- @Override
- protected boolean condition() {
- for (TrackedTorrent tt: TrackerTest.this.tracker.getTrackedTorrents()) {
- if (tt.getPeers().size() == numPeers) return true;
- }
-
- return false;
- }
- };
- }
-
- private void waitForFileInDir(final File downloadDir, final String fileName) {
- new WaitFor() {
- @Override
- protected boolean condition() {
- return new File(downloadDir, fileName).isFile();
- }
- };
-
- assertTrue(new File(downloadDir, fileName).isFile());
- }
-
- private TrackedTorrent loadTorrent(String name) throws IOException, NoSuchAlgorithmException {
- return new TrackedTorrent(Torrent.load(new File(TEST_RESOURCES + "/torrents", name), true));
- }
-
-
- @AfterMethod
- protected void tearDown() throws Exception {
- stopTracker();
- tempFiles.cleanup();
- }
-
- private void startTracker() throws IOException {
- this.tracker = new Tracker(new InetSocketAddress(6969));
- this.tracker.start();
- }
-
- private Client createClient(SharedTorrent torrent) throws IOException, NoSuchAlgorithmException, InterruptedException {
- return new Client(InetAddress.getLocalHost(), torrent);
- }
-
- private SharedTorrent completeTorrent(String name) throws IOException, NoSuchAlgorithmException {
- File torrentFile = new File(TEST_RESOURCES + "/torrents", name);
- File parentFiles = new File(TEST_RESOURCES + "/parentFiles");
- return SharedTorrent.fromFile(torrentFile, parentFiles);
- }
-
- private SharedTorrent incompleteTorrent(String name, File destDir) throws IOException, NoSuchAlgorithmException {
- File torrentFile = new File(TEST_RESOURCES + "/torrents", name);
- return SharedTorrent.fromFile(torrentFile, destDir);
- }
-
- private void stopTracker() {
- this.tracker.stop();
- }
-
- private void assertFilesEqual(File f1, File f2) throws IOException {
- assertEquals(f1.length(), f2.length(), "Files size differs");
- Checksum c1 = FileUtils.checksum(f1, new CRC32());
- Checksum c2 = FileUtils.checksum(f2, new CRC32());
- assertEquals(c1.getValue(), c2.getValue());
- }
+public class TrackerTest {
+
+ private static final Logger logger =
+ LoggerFactory.getLogger(TrackerTest.class);
+
+ private static final String TEST_RESOURCES = "src/test/resources";
+ private static final int TRACKER_PORT =
+ Integer.getInteger("ttorrent.test.tracker_port", 6969);
+
+ private Tracker tracker;
+ private TempFiles tempFiles;
+ private Torrent testTorrent;
+ private File testFile;
+
+ @BeforeMethod(alwaysRun = true)
+ protected void setUp(Method testMethod) throws Exception {
+ String testName = testMethod.getDeclaringClass().getSimpleName() + "." + testMethod.getName();
+ logger.trace("Test starting: " + testName);
+ tempFiles = new TempFiles();
+ startTracker();
+ testFile = new File(TEST_RESOURCES + "/parentFiles/file1.jar");
+ String creator = String.format("%s (ttorrent)", testName);
+ testTorrent = Torrent.create(testFile,
+ this.tracker.getAnnounceUrl().toURI(), creator);
+ }
+
+ @AfterMethod(alwaysRun = true)
+ protected void tearDown(Method testMethod) throws Exception {
+ String testName = testMethod.getDeclaringClass().getSimpleName() + "." + testMethod.getName();
+ stopTracker();
+ tempFiles.cleanup();
+ logger.trace("Test finished: " + testName);
+ }
+
+ public void test_share_and_download() throws Exception {
+ final TrackedTorrent tt = this.tracker.announce(loadTorrent());
+ assertEquals(0, tt.getPeers().size());
+
+ Client seeder = createClient(completeTorrent());
+
+ assertEquals(tt.getHexInfoHash(), seeder.getTorrent().getHexInfoHash());
+
+ final File downloadDir = tempFiles.createTempDir();
+ Client leech = createClient(incompleteTorrent(downloadDir));
+
+ try {
+ seeder.share();
+
+ leech.download();
+
+ waitForFileInDir(downloadDir, testFile.getName());
+ assertFilesEqual(testFile, new File(downloadDir, testFile.getName()));
+ } finally {
+ leech.stop(true);
+ seeder.stop(true);
+ }
+ }
+
+ public void tracker_accepts_torrent_from_seeder() throws Exception {
+ final SharedTorrent torrent = completeTorrent();
+ tracker.announce(new TrackedTorrent(torrent));
+ Client seeder = createClient(torrent);
+
+ try {
+ seeder.share();
+
+ waitForSeeder(seeder.getTorrent().getInfoHash());
+
+ Collection trackedTorrents = this.tracker.getTrackedTorrents();
+ assertEquals(1, trackedTorrents.size());
+
+ TrackedTorrent trackedTorrent = trackedTorrents.iterator().next();
+ Map peers = trackedTorrent.getPeers();
+ assertEquals(1, peers.size());
+ assertTrue(peers.values().iterator().next().isCompleted()); // seed
+ assertEquals(1, trackedTorrent.seeders());
+ assertEquals(0, trackedTorrent.leechers());
+ } finally {
+ seeder.stop(true);
+ }
+ }
+
+ public void tracker_accepts_torrent_from_leech() throws Exception {
+
+ final File downloadDir = tempFiles.createTempDir();
+ final SharedTorrent torrent = incompleteTorrent(downloadDir);
+ tracker.announce(new TrackedTorrent(torrent));
+ Client leech = createClient(torrent);
+
+ try {
+ leech.download();
+
+ waitForPeers(1);
+
+ Collection trackedTorrents = this.tracker.getTrackedTorrents();
+ assertEquals(1, trackedTorrents.size());
+
+ TrackedTorrent trackedTorrent = trackedTorrents.iterator().next();
+ Map peers = trackedTorrent.getPeers();
+ assertEquals(1, peers.size());
+ assertFalse(peers.values().iterator().next().isCompleted()); // leech
+ assertEquals(0, trackedTorrent.seeders());
+ assertEquals(1, trackedTorrent.leechers());
+ } finally {
+ leech.stop(true);
+ }
+ }
+
+ public void tracker_accepts_torrent_from_seeder_plus_leech() throws Exception {
+ assertEquals(0, this.tracker.getTrackedTorrents().size());
+
+ final SharedTorrent completeTorrent = completeTorrent();
+ tracker.announce(new TrackedTorrent(completeTorrent));
+ Client seeder = createClient(completeTorrent);
+
+ final File downloadDir = tempFiles.createTempDir();
+ final SharedTorrent incompleteTorrent = incompleteTorrent(downloadDir);
+ Client leech = createClient(incompleteTorrent);
+
+ try {
+ seeder.share();
+ leech.download();
+
+ waitForFileInDir(downloadDir, testFile.getName());
+ } finally {
+ seeder.stop(true);
+ leech.stop(true);
+ }
+ }
+
+ public void large_file_download() throws Exception {
+
+ File tempFile = tempFiles.createTempFile(201 * 1024 * 1024);
+
+ Torrent torrent = Torrent.create(tempFile, this.tracker.getAnnounceUrl().toURI(), "Test");
+ File torrentFile = new File(tempFile.getParentFile(), tempFile.getName() + ".torrent");
+ FileUtils.writeByteArrayToFile(torrentFile, torrent.getEncoded());
+ tracker.announce(new TrackedTorrent(torrent));
+
+ Client seeder = createClient(SharedTorrent.fromFile(torrentFile, tempFile.getParentFile()));
+
+ final File downloadDir = tempFiles.createTempDir();
+ Client leech = createClient(SharedTorrent.fromFile(torrentFile, downloadDir));
+
+ try {
+ seeder.share();
+ leech.download();
+
+ waitForFileInDir(downloadDir, tempFile.getName());
+ assertFilesEqual(tempFile, new File(downloadDir, tempFile.getName()));
+ } finally {
+ seeder.stop(true);
+ leech.stop(true);
+ }
+ }
+
+ public void test_announce() throws Exception {
+ assertEquals(0, this.tracker.getTrackedTorrents().size());
+
+ this.tracker.announce(loadTorrent());
+
+ assertEquals(1, this.tracker.getTrackedTorrents().size());
+ }
+
+ private void waitForSeeder(final byte[] torrentHash) {
+ new WaitFor() {
+ @Override
+ protected boolean condition() {
+ for (TrackedTorrent tt : TrackerTest.this.tracker.getTrackedTorrents()) {
+ if (tt.seeders() == 1 && tt.getHexInfoHash().equals(Torrent.byteArrayToHexString(torrentHash)))
+ return true;
+ }
+
+ return false;
+ }
+ };
+ }
+
+ private void waitForPeers(final int numPeers) {
+ new WaitFor() {
+ @Override
+ protected boolean condition() {
+ for (TrackedTorrent tt : TrackerTest.this.tracker.getTrackedTorrents()) {
+ if (tt.getPeers().size() == numPeers) return true;
+ }
+
+ return false;
+ }
+ };
+ }
+
+ private void waitForFileInDir(final File downloadDir, final String fileName) {
+ new WaitFor(120 * 1000) {
+ @Override
+ protected boolean condition() {
+ return new File(downloadDir, fileName).isFile();
+ }
+ };
+
+ assertTrue(new File(downloadDir, fileName).isFile());
+ }
+
+ private TrackedTorrent loadTorrent()
+ throws IOException, NoSuchAlgorithmException {
+ return new TrackedTorrent(testTorrent);
+ }
+
+ private void startTracker() throws IOException {
+ this.tracker = new Tracker(new InetSocketAddress(TRACKER_PORT));
+ this.tracker.start();
+ }
+
+ private Client createClient(SharedTorrent torrent)
+ throws IOException, NoSuchAlgorithmException, InterruptedException {
+ return new Client(InetAddress.getLocalHost(), torrent);
+ }
+
+ private SharedTorrent completeTorrent()
+ throws IOException, NoSuchAlgorithmException {
+ File parentFiles = new File(TEST_RESOURCES + "/parentFiles");
+ return new SharedTorrent(testTorrent, parentFiles);
+ }
+
+ private SharedTorrent incompleteTorrent(File destDir)
+ throws IOException, NoSuchAlgorithmException {
+ return new SharedTorrent(testTorrent, destDir);
+ }
+
+ private void stopTracker() {
+ this.tracker.stop();
+ }
+
+ private void assertFilesEqual(File f1, File f2) throws IOException {
+ assertEquals(f1.length(), f2.length(), "Files size differs");
+ Checksum c1 = FileUtils.checksum(f1, new CRC32());
+ Checksum c2 = FileUtils.checksum(f2, new CRC32());
+ assertEquals(c1.getValue(), c2.getValue());
+ }
}
diff --git a/src/test/resources/log4j.properties b/src/test/resources/log4j.properties
new file mode 100644
index 000000000..5fe42d854
--- /dev/null
+++ b/src/test/resources/log4j.properties
@@ -0,0 +1,9 @@
+# Set root logger level to DEBUG and its only appender to A1.
+log4j.rootLogger=DEBUG, A1
+
+# A1 is set to be a ConsoleAppender.
+log4j.appender.A1=org.apache.log4j.ConsoleAppender
+
+# A1 uses PatternLayout.
+log4j.appender.A1.layout=org.apache.log4j.PatternLayout
+log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n