예제 #1
0
        TestRig(string savePath, int piecelength, IPieceWriter writer, string[][] trackers, TorrentFile[] files, bool metadataMode)
        {
            this.files       = files;
            this.savePath    = savePath;
            this.piecelength = piecelength;
            this.tier        = trackers;
            MetadataMode     = metadataMode;
            var cacheDir = Path.Combine(Path.GetDirectoryName(typeof(TestRig).Assembly.Location), "test_cache_dir");

            PeerListenerFactory.Creator              = endpoint => new CustomListener();
            LocalPeerDiscoveryFactory.Creator        = port => new ManualLocalPeerListener();
            Dht.Listeners.DhtListenerFactory.Creator = endpoint => new Dht.Listeners.NullDhtListener();
            Engine = new ClientEngine(EngineSettingsBuilder.CreateForTests(
                                          allowLocalPeerDiscovery: true,
                                          dhtPort: 12345,
                                          cacheDirectory: cacheDir,
                                          listenPort: 12345
                                          ));
            if (Directory.Exists(Engine.Settings.MetadataCacheDirectory))
            {
                Directory.Delete(Engine.Settings.MetadataCacheDirectory, true);
            }
            Engine.DiskManager.ChangePieceWriter(writer);
            Writer = writer;

            RecreateManager().Wait();
            MetadataPath = Path.Combine(Engine.Settings.MetadataCacheDirectory, $"{Engine.Torrents.Single ().InfoHash.ToHex ()}.torrent");
        }
예제 #2
0
        TestRig(string savePath, int piecelength, IPieceWriter writer, string[][] trackers, TorrentFile[] files, bool metadataMode)
        {
            this.files       = files;
            this.savePath    = savePath;
            this.piecelength = piecelength;
            this.tier        = trackers;
            MetadataMode     = metadataMode;
            var cacheDir  = Path.Combine(Path.GetDirectoryName(typeof(TestRig).Assembly.Location), "test_cache_dir");
            var factories = Factories.Default
                            .WithDhtCreator(() => new ManualDhtEngine())
                            .WithDhtListenerCreator(port => new NullDhtListener())
                            .WithLocalPeerDiscoveryCreator(() => new ManualLocalPeerListener())
                            .WithPeerConnectionListenerCreator(endpoint => new CustomListener())
                            .WithTrackerCreator("custom", uri => new Tracker(new CustomTracker(uri)))
            ;

            Engine = new ClientEngine(EngineSettingsBuilder.CreateForTests(
                                          allowLocalPeerDiscovery: true,
                                          dhtEndPoint: new IPEndPoint(IPAddress.Any, 12345),
                                          cacheDirectory: cacheDir,
                                          listenEndPoint: new IPEndPoint(IPAddress.Any, 12345)
                                          ), factories);
            if (Directory.Exists(Engine.Settings.MetadataCacheDirectory))
            {
                Directory.Delete(Engine.Settings.MetadataCacheDirectory, true);
            }
            Engine.DiskManager.SetWriterAsync(writer).GetAwaiter().GetResult();
            Writer = writer;

            RecreateManager().Wait();
            MetadataPath = Path.Combine(Engine.Settings.MetadataCacheDirectory, $"{Engine.Torrents.Single ().InfoHash.ToHex ()}.torrent");
        }
        public async Task SortByLeastConnections()
        {
            var engine  = new ClientEngine(EngineSettingsBuilder.CreateForTests());
            var manager = new ConnectionManager("test", engine.Settings, engine.Factories, engine.DiskManager);

            var torrents = new[] {
                await engine.AddAsync(new MagnetLink (new InfoHash(Enumerable.Repeat((byte)0, 20).ToArray())), "tmp"),
                await engine.AddAsync(new MagnetLink (new InfoHash(Enumerable.Repeat((byte)1, 20).ToArray())), "tmp"),
                await engine.AddAsync(new MagnetLink (new InfoHash(Enumerable.Repeat((byte)2, 20).ToArray())), "tmp")
            };

            torrents[0].Peers.ConnectedPeers.Add(PeerId.CreateNull(1));
            torrents[0].Peers.ConnectedPeers.Add(PeerId.CreateNull(1));
            torrents[2].Peers.ConnectedPeers.Add(PeerId.CreateNull(1));

            foreach (var torrent in torrents)
            {
                manager.Add(torrent);
            }

            manager.TryConnect();

            Assert.AreEqual(torrents[1], manager.Torrents[0]);
            Assert.AreEqual(torrents[2], manager.Torrents[1]);
            Assert.AreEqual(torrents[0], manager.Torrents[2]);
        }
예제 #4
0
        public async Task SaveRestoreState_NoTorrents()
        {
            var engine         = new ClientEngine(EngineSettingsBuilder.CreateForTests());
            var restoredEngine = await ClientEngine.RestoreStateAsync(await engine.SaveStateAsync());

            Assert.AreEqual(engine.Settings, restoredEngine.Settings);
        }
예제 #5
0
        public async Task SaveRestoreState_OneTorrentFile_NoContainingDirectory()
        {
            var pieceLength = Constants.BlockSize * 4;

            using var tmpDir = TempDir.Create();

            TestRig.CreateMultiFileTorrent(TorrentFile.Create(pieceLength, Constants.BlockSize, Constants.BlockSize * 2, Constants.BlockSize * 3), pieceLength, out BEncoding.BEncodedDictionary metadata);
            var metadataFile = Path.Combine(tmpDir.Path, "test.torrent");

            File.WriteAllBytes(metadataFile, metadata.Encode());

            var engine = new ClientEngine(EngineSettingsBuilder.CreateForTests(cacheDirectory: tmpDir.Path));
            await engine.AddStreamingAsync(metadataFile, "mySaveDirectory", new TorrentSettingsBuilder { CreateContainingDirectory = false }.ToSettings());

            var restoredEngine = await ClientEngine.RestoreStateAsync(await engine.SaveStateAsync());

            Assert.AreEqual(engine.Settings, restoredEngine.Settings);
            Assert.AreEqual(engine.Torrents[0].Torrent.Name, restoredEngine.Torrents[0].Torrent.Name);
            Assert.AreEqual(engine.Torrents[0].SavePath, restoredEngine.Torrents[0].SavePath);
            Assert.AreEqual(engine.Torrents[0].Settings, restoredEngine.Torrents[0].Settings);
            Assert.AreEqual(engine.Torrents[0].InfoHash, restoredEngine.Torrents[0].InfoHash);
            Assert.AreEqual(engine.Torrents[0].MagnetLink.ToV1String(), restoredEngine.Torrents[0].MagnetLink.ToV1String());

            Assert.AreEqual(engine.Torrents[0].Files.Count, restoredEngine.Torrents[0].Files.Count);
            for (int i = 0; i < engine.Torrents.Count; i++)
            {
                Assert.AreEqual(engine.Torrents[0].Files[i].FullPath, restoredEngine.Torrents[0].Files[i].FullPath);
                Assert.AreEqual(engine.Torrents[0].Files[i].Priority, restoredEngine.Torrents[0].Files[i].Priority);
            }
        }
예제 #6
0
        public void DownloadMetadata_SameTwice()
        {
            var link = MagnetLink.Parse("magnet:?xt=urn:btih:1234512345123451234512345123451234512345");

            using var engine = new ClientEngine(EngineSettingsBuilder.CreateForTests());
            var first = engine.DownloadMetadataAsync(link, CancellationToken.None);

            Assert.ThrowsAsync <TorrentException> (() => engine.DownloadMetadataAsync(link, CancellationToken.None));
        }
예제 #7
0
        public void DownloadMetadata_Cancelled()
        {
            var cts    = new CancellationTokenSource();
            var engine = new ClientEngine(EngineSettingsBuilder.CreateForTests());
            var task   = engine.DownloadMetadataAsync(new MagnetLink(new InfoHash(new byte[20])), cts.Token);

            cts.Cancel();
            Assert.ThrowsAsync <OperationCanceledException> (() => task);
        }
예제 #8
0
        public void CacheDirectory_IsFile_UpdateSettings()
        {
            var engine    = new ClientEngine(EngineSettingsBuilder.CreateForTests());
            var tmp       = TempDir.Create();
            var cachePath = Path.Combine(tmp.Path, "test.file");

            using (var file = File.Create(cachePath)) { }
            Assert.ThrowsAsync <ArgumentException> (() => engine.UpdateSettingsAsync(new EngineSettingsBuilder {
                CacheDirectory = cachePath
            }.ToSettings()));
        }
예제 #9
0
        public async Task UsePartialFiles_InitiallyOn_ToggleOff()
        {
            var pieceLength = Constants.BlockSize * 4;
            var engine      = new ClientEngine(EngineSettingsBuilder.CreateForTests(usePartialFiles: true));
            var torrent     = TestRig.CreateMultiFileTorrent(TorrentFile.Create(pieceLength, Constants.BlockSize, Constants.BlockSize * 2, Constants.BlockSize * 3), pieceLength, out BEncoding.BEncodedDictionary _);

            var manager = await engine.AddAsync(torrent, "");

            Assert.AreNotEqual(manager.Files[0].DownloadCompleteFullPath, manager.Files[0].DownloadIncompleteFullPath);

            var settings = new EngineSettingsBuilder(engine.Settings)
            {
                UsePartialFiles = false
            }.ToSettings();
            await engine.UpdateSettingsAsync(settings);

            Assert.AreEqual(manager.Files[0].DownloadCompleteFullPath, manager.Files[0].DownloadIncompleteFullPath);
        }
        public async Task DeleteBeforeHashing()
        {
            TestWriter testWriter = null;

            using var tmpDir = TempDir.Create();
            using var engine = new ClientEngine(new EngineSettingsBuilder(EngineSettingsBuilder.CreateForTests())
            {
                AutoSaveLoadFastResume = true,
                CacheDirectory         = tmpDir.Path,
            }.ToSettings(),
                                                Factories.Default.WithPieceWriterCreator(maxOpenFiles => (testWriter = new TestWriter()))
                                                );

            var first  = new TaskCompletionSource <object> ();
            var second = new TaskCompletionSource <object> ();

            var torrent = TestRig.CreatePrivate();
            var path    = engine.Settings.GetFastResumePath(torrent.InfoHashes);

            Directory.CreateDirectory(Path.GetDirectoryName(path));
            File.WriteAllBytes(path, new FastResume(torrent.InfoHashes, new BitField(torrent.PieceCount).SetAll(true), new BitField(torrent.PieceCount)).Encode());
            var manager = await engine.AddAsync(torrent, "savedir");

            testWriter.FilesThatExist = new System.Collections.Generic.List <ITorrentManagerFile> (manager.Files);
            Assert.IsTrue(manager.HashChecked);
            manager.Engine.DiskManager.GetHashAsyncOverride = (torrent, pieceIndex, dest) => {
                first.SetResult(null);
                second.Task.Wait();
                new byte[20].CopyTo(dest.V1Hash);
                return(Task.FromResult(true));
            };
            var hashCheckTask = manager.HashCheckAsync(false);
            await first.Task.WithTimeout();

            Assert.IsFalse(File.Exists(path));

            second.SetResult(null);
            await hashCheckTask.WithTimeout();

            Assert.IsTrue(File.Exists(path));
        }
예제 #11
0
        public async Task SaveRestoreState_OneInMemoryTorrent(bool addStreaming)
        {
            var pieceLength = Constants.BlockSize * 4;

            using var tmpDir = TempDir.Create();

            var torrent = TestRig.CreateMultiFileTorrent(TorrentFile.Create(pieceLength, Constants.BlockSize, Constants.BlockSize * 2, Constants.BlockSize * 3), pieceLength, out BEncoding.BEncodedDictionary metadata);

            var            engine = new ClientEngine(EngineSettingsBuilder.CreateForTests(cacheDirectory: tmpDir.Path));
            TorrentManager torrentManager;

            if (addStreaming)
            {
                torrentManager = await engine.AddStreamingAsync(torrent, "mySaveDirectory", new TorrentSettingsBuilder { CreateContainingDirectory = true }.ToSettings());
            }
            else
            {
                torrentManager = await engine.AddAsync(torrent, "mySaveDirectory", new TorrentSettingsBuilder { CreateContainingDirectory = true }.ToSettings());
            }

            await torrentManager.SetFilePriorityAsync(torrentManager.Files[0], Priority.High);

            await torrentManager.MoveFileAsync(torrentManager.Files[1], Path.GetFullPath("some_fake_path.txt"));

            var restoredEngine = await ClientEngine.RestoreStateAsync(await engine.SaveStateAsync());

            Assert.AreEqual(engine.Settings, restoredEngine.Settings);
            Assert.AreEqual(engine.Torrents[0].Torrent.Name, restoredEngine.Torrents[0].Torrent.Name);
            Assert.AreEqual(engine.Torrents[0].SavePath, restoredEngine.Torrents[0].SavePath);
            Assert.AreEqual(engine.Torrents[0].Settings, restoredEngine.Torrents[0].Settings);
            Assert.AreEqual(engine.Torrents[0].InfoHash, restoredEngine.Torrents[0].InfoHash);
            Assert.AreEqual(engine.Torrents[0].MagnetLink.ToV1String(), restoredEngine.Torrents[0].MagnetLink.ToV1String());

            Assert.AreEqual(engine.Torrents[0].Files.Count, restoredEngine.Torrents[0].Files.Count);
            for (int i = 0; i < engine.Torrents.Count; i++)
            {
                Assert.AreEqual(engine.Torrents[0].Files[i].FullPath, restoredEngine.Torrents[0].Files[i].FullPath);
                Assert.AreEqual(engine.Torrents[0].Files[i].Priority, restoredEngine.Torrents[0].Files[i].Priority);
            }
        }
예제 #12
0
        public async Task SaveRestoreState_OneMagnetLink(bool addStreaming)
        {
            var engine = new ClientEngine(EngineSettingsBuilder.CreateForTests());

            if (addStreaming)
            {
                await engine.AddStreamingAsync(new MagnetLink (new InfoHash(new byte[20]), "test"), "mySaveDirectory", new TorrentSettingsBuilder { CreateContainingDirectory = false }.ToSettings());
            }
            else
            {
                await engine.AddAsync(new MagnetLink (new InfoHash(new byte[20]), "test"), "mySaveDirectory", new TorrentSettingsBuilder { CreateContainingDirectory = false }.ToSettings());
            }

            var restoredEngine = await ClientEngine.RestoreStateAsync(await engine.SaveStateAsync());

            Assert.AreEqual(engine.Settings, restoredEngine.Settings);
            Assert.AreEqual(engine.Torrents[0].SavePath, restoredEngine.Torrents[0].SavePath);
            Assert.AreEqual(engine.Torrents[0].Settings, restoredEngine.Torrents[0].Settings);
            Assert.AreEqual(engine.Torrents[0].InfoHash, restoredEngine.Torrents[0].InfoHash);
            Assert.AreEqual(engine.Torrents[0].MagnetLink.ToV1Uri(), restoredEngine.Torrents[0].MagnetLink.ToV1Uri());
            Assert.AreEqual(engine.Torrents[0].Files, restoredEngine.Torrents[0].Files);
        }
예제 #13
0
        public async Task RetainAfterSeeding()
        {
            using var tmpDir = TempDir.Create();
            using var engine = new ClientEngine(new EngineSettingsBuilder(EngineSettingsBuilder.CreateForTests())
            {
                AutoSaveLoadFastResume = true,
                CacheDirectory         = tmpDir.Path,
            }.ToSettings());

            var torrent = TestRig.CreatePrivate();
            var path    = engine.Settings.GetFastResumePath(torrent.InfoHash);

            Directory.CreateDirectory(Path.GetDirectoryName(path));
            File.WriteAllBytes(path, new FastResume(torrent.InfoHash, new BitField(torrent.Pieces.Count).SetAll(true), new BitField(torrent.Pieces.Count)).Encode().Encode());
            var manager = await engine.AddAsync(torrent, "savedir");

            Assert.IsTrue(manager.HashChecked);
            await manager.StartAsync();

            await manager.WaitForState(TorrentState.Downloading);

            Assert.IsFalse(File.Exists(path));
        }