public void JobQueuing_WithSpecifiedRangeAndOffset() { BytesRange range = BytesRangeUtils.Make(450, 830); long offset = 512; var jobs = ChunkedHttpDownloader.BuildDownloadJobQueue(_url, offset, range, DataSize, _chunksData).ToList(); Assert.That(jobs.Count, Is.EqualTo(3)); var firstJob = jobs[0]; Assert.That(firstJob.Url, Is.EqualTo("test.com/someData.4")); Assert.That(firstJob.Range.Start, Is.EqualTo(0)); Assert.That(firstJob.Range.End, Is.EqualTo(-1)); var middleJob = jobs[1]; Assert.That(middleJob.Url, Is.EqualTo("test.com/someData.5")); Assert.That(middleJob.Range.Start, Is.EqualTo(0)); Assert.That(middleJob.Range.End, Is.EqualTo(-1)); var lastJob = jobs[2]; Assert.That(lastJob.Url, Is.EqualTo("test.com/someData.6")); Assert.That(lastJob.Range.Start, Is.EqualTo(0)); Assert.That(lastJob.Range.End, Is.EqualTo(63)); }
public void JobQueuing_SinglePartScenario() { BytesRange range = BytesRangeUtils.Make(315, 380); var jobs = ChunkedHttpDownloader.BuildDownloadJobQueue(_url, 0, range, DataSize, _chunksData).ToList(); Assert.That(jobs.Count, Is.EqualTo(1)); var job = jobs[0]; Assert.That(job.Url, Is.EqualTo("test.com/someData.2")); Assert.That(job.Range.Start, Is.EqualTo(0)); Assert.That(job.Range.End, Is.EqualTo(-1).Or.EqualTo(127)); }
public void JobQueuing_WithFullRange() { BytesRange range = BytesRangeUtils.Full(); var jobs = ChunkedHttpDownloader.BuildDownloadJobQueue(_url, 0, range, DataSize, _chunksData).ToList(); int expectedJobCount = (int)(DataSize / PartSize) + 1; Assert.That(jobs.Count, Is.EqualTo(expectedJobCount)); var firstJob = jobs[0]; Assert.That(firstJob.Range.Start, Is.EqualTo(0)); Assert.That(firstJob.Range.End, Is.EqualTo(-1)); var lastJob = jobs[expectedJobCount - 1]; Assert.That(lastJob.Range.Start, Is.EqualTo(0)); Assert.That(lastJob.Range.End, Is.EqualTo(-1)); }
public override void Execute(CancellationToken cancellationToken) { base.Execute(cancellationToken); foreach (var entry in _entries) { var tempDirName = _packagePath + string.Format("{0}_{1}_{2}", entry.Name, entry.Offset, entry.Size); TemporaryDirectory.ExecuteIn(tempDirName, (tempDir) => { _logger.LogDebug(string.Format("Repairing the file {0}", entry.Name)); string packagePath = Path.Combine(tempDir.Path, ".pack" + Path.GetRandomFileName()); string unarchivePath = Path.Combine(tempDir.Path, Path.GetRandomFileName()); if (!Directory.Exists(unarchivePath)) { DirectoryOperations.CreateDirectory(unarchivePath, cancellationToken); } var downloader = new ChunkedHttpDownloader(packagePath, _resource.ResourceUrls, _resource.ChunksData, _resource.Size); long start = entry.Offset.GetValueOrDefault(); long end = (start + entry.Size.GetValueOrDefault()) - 1; // Offset by 1 to denote a byte index var range = new BytesRange(start, end); downloader.SetRange(range); var effectiveRange = downloader.CalculateContainingChunksRange(range); long totalData = effectiveRange.End == -1 ? _resource.Size - effectiveRange.Start : effectiveRange.End - effectiveRange.Start; var downloadStatus = _entryStatus[entry].DownloadStatus; var repairStatus = _entryStatus[entry].RepairStatus; downloadStatus.IsActive.Value = true; downloadStatus.TotalBytes.Value = totalData; downloadStatus.Description.Value = "Downloading broken file..."; downloadStatus.Bytes.Value = 0; downloader.DownloadProgressChanged += downloadedBytes => { downloadStatus.Bytes.Value = downloadedBytes; }; _logger.LogDebug(string.Format("Downloading the partial package with range {0}-{1}", start, end)); downloader.Download(cancellationToken); downloadStatus.IsActive.Value = false; repairStatus.IsActive.Value = true; repairStatus.Description.Value = "Reparing broken file..."; repairStatus.Progress.Value = 0.0; _logger.LogDebug("Unarchiving the package."); var unarchiver = new Pack1Unarchiver(packagePath, _meta, unarchivePath, _packagePassword, _unpackingSuffix, effectiveRange); unarchiver.UnarchiveProgressChanged += (name, isFile, unarchiveEntry, amount, entryProgress) => { repairStatus.Progress.Value = entryProgress; }; unarchiver.UnarchiveSingleFile(entry, cancellationToken); EmplaceFile(Path.Combine(unarchivePath, entry.Name + _unpackingSuffix), Path.Combine(_localData.Path, entry.Name), cancellationToken); repairStatus.IsActive.Value = false; }); } }